Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/MediaTrackList.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim:set ts=2 sw=2 et tw=78: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "MediaTrack.h"
8
#include "MediaTrackList.h"
9
#include "mozilla/AsyncEventDispatcher.h"
10
#include "mozilla/dom/HTMLMediaElement.h"
11
#include "mozilla/dom/AudioTrack.h"
12
#include "mozilla/dom/VideoStreamTrack.h"
13
#include "mozilla/dom/VideoTrack.h"
14
#include "mozilla/dom/TrackEvent.h"
15
#include "nsThreadUtils.h"
16
17
namespace mozilla {
18
namespace dom {
19
20
MediaTrackList::MediaTrackList(nsPIDOMWindowInner* aOwnerWindow,
21
                               HTMLMediaElement* aMediaElement)
22
  : DOMEventTargetHelper(aOwnerWindow)
23
  , mMediaElement(aMediaElement)
24
0
{
25
0
}
26
27
MediaTrackList::~MediaTrackList()
28
0
{
29
0
}
30
31
NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaTrackList,
32
                                   DOMEventTargetHelper,
33
                                   mTracks,
34
                                   mMediaElement)
35
36
NS_IMPL_ADDREF_INHERITED(MediaTrackList, DOMEventTargetHelper)
37
NS_IMPL_RELEASE_INHERITED(MediaTrackList, DOMEventTargetHelper)
38
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaTrackList)
39
0
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
40
41
MediaTrack*
42
MediaTrackList::operator[](uint32_t aIndex)
43
0
{
44
0
  return mTracks.ElementAt(aIndex);
45
0
}
46
47
MediaTrack*
48
MediaTrackList::IndexedGetter(uint32_t aIndex, bool& aFound)
49
0
{
50
0
  aFound = aIndex < mTracks.Length();
51
0
  if (!aFound) {
52
0
    return nullptr;
53
0
  }
54
0
  return mTracks[aIndex];
55
0
}
56
57
MediaTrack*
58
MediaTrackList::GetTrackById(const nsAString& aId)
59
0
{
60
0
  for (uint32_t i = 0; i < mTracks.Length(); ++i) {
61
0
    if (aId.Equals(mTracks[i]->GetId())) {
62
0
      return mTracks[i];
63
0
    }
64
0
  }
65
0
  return nullptr;
66
0
}
67
68
void
69
MediaTrackList::AddTrack(MediaTrack* aTrack)
70
0
{
71
0
  MOZ_ASSERT(aTrack->GetOwnerGlobal() == GetOwnerGlobal(),
72
0
             "Where is this track from?");
73
0
  mTracks.AppendElement(aTrack);
74
0
  aTrack->SetTrackList(this);
75
0
  CreateAndDispatchTrackEventRunner(aTrack, NS_LITERAL_STRING("addtrack"));
76
0
77
0
  if ((!aTrack->AsAudioTrack() || !aTrack->AsAudioTrack()->Enabled()) &&
78
0
      (!aTrack->AsVideoTrack() || !aTrack->AsVideoTrack()->Selected())) {
79
0
    // Track not enabled, no need to notify media element.
80
0
    return;
81
0
  }
82
0
83
0
  if (HTMLMediaElement* element = GetMediaElement()) {
84
0
    element->NotifyMediaTrackEnabled(aTrack);
85
0
  }
86
0
}
87
88
void
89
MediaTrackList::RemoveTrack(const RefPtr<MediaTrack>& aTrack)
90
0
{
91
0
  mTracks.RemoveElement(aTrack);
92
0
  aTrack->SetEnabledInternal(false, MediaTrack::FIRE_NO_EVENTS);
93
0
  aTrack->SetTrackList(nullptr);
94
0
  CreateAndDispatchTrackEventRunner(aTrack, NS_LITERAL_STRING("removetrack"));
95
0
}
96
97
void
98
MediaTrackList::RemoveTracks()
99
0
{
100
0
  while (!mTracks.IsEmpty()) {
101
0
    RefPtr<MediaTrack> track = mTracks.LastElement();
102
0
    RemoveTrack(track);
103
0
  }
104
0
}
105
106
already_AddRefed<AudioTrack>
107
MediaTrackList::CreateAudioTrack(nsIGlobalObject* aOwnerGlobal,
108
                                 const nsAString& aId,
109
                                 const nsAString& aKind,
110
                                 const nsAString& aLabel,
111
                                 const nsAString& aLanguage,
112
                                 bool aEnabled)
113
0
{
114
0
  RefPtr<AudioTrack> track = new AudioTrack(aOwnerGlobal,
115
0
                                            aId, aKind, aLabel, aLanguage,
116
0
                                            aEnabled);
117
0
  return track.forget();
118
0
}
119
120
already_AddRefed<VideoTrack>
121
MediaTrackList::CreateVideoTrack(nsIGlobalObject* aOwnerGlobal,
122
                                 const nsAString& aId,
123
                                 const nsAString& aKind,
124
                                 const nsAString& aLabel,
125
                                 const nsAString& aLanguage,
126
                                 VideoStreamTrack* aVideoTrack)
127
0
{
128
0
  RefPtr<VideoTrack> track = new VideoTrack(aOwnerGlobal, aId, aKind, aLabel,
129
0
                                            aLanguage, aVideoTrack);
130
0
  return track.forget();
131
0
}
132
133
void
134
MediaTrackList::EmptyTracks()
135
0
{
136
0
  for (uint32_t i = 0; i < mTracks.Length(); ++i) {
137
0
    mTracks[i]->SetEnabledInternal(false, MediaTrack::FIRE_NO_EVENTS);
138
0
    mTracks[i]->SetTrackList(nullptr);
139
0
  }
140
0
  mTracks.Clear();
141
0
}
142
143
void
144
MediaTrackList::CreateAndDispatchChangeEvent()
145
0
{
146
0
  RefPtr<AsyncEventDispatcher> asyncDispatcher =
147
0
    new AsyncEventDispatcher(this,
148
0
                             NS_LITERAL_STRING("change"),
149
0
                             CanBubble::eNo);
150
0
  asyncDispatcher->PostDOMEvent();
151
0
}
152
153
void
154
MediaTrackList::CreateAndDispatchTrackEventRunner(MediaTrack* aTrack,
155
                                                  const nsAString& aEventName)
156
0
{
157
0
  TrackEventInit eventInit;
158
0
159
0
  if (aTrack->AsAudioTrack()) {
160
0
    eventInit.mTrack.SetValue().SetAsAudioTrack() = aTrack->AsAudioTrack();
161
0
  } else if (aTrack->AsVideoTrack()) {
162
0
    eventInit.mTrack.SetValue().SetAsVideoTrack() = aTrack->AsVideoTrack();
163
0
  }
164
0
165
0
  RefPtr<TrackEvent> event =
166
0
    TrackEvent::Constructor(this, aEventName, eventInit);
167
0
168
0
  RefPtr<AsyncEventDispatcher> asyncDispatcher =
169
0
    new AsyncEventDispatcher(this, event);
170
0
  asyncDispatcher->PostDOMEvent();
171
0
}
172
173
} // namespace dom
174
} // namespace mozilla