• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  * Copyright (C) 2011 Ericsson AB. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "modules/mediastream/MediaStreamTrack.h"
28 
29 #include "bindings/v8/ExceptionMessages.h"
30 #include "core/dom/ExceptionCode.h"
31 #include "core/dom/ExecutionContext.h"
32 #include "modules/mediastream/MediaStream.h"
33 #include "modules/mediastream/MediaStreamTrackSourcesCallback.h"
34 #include "modules/mediastream/MediaStreamTrackSourcesRequestImpl.h"
35 #include "platform/mediastream/MediaStreamCenter.h"
36 #include "platform/mediastream/MediaStreamComponent.h"
37 #include "public/platform/WebSourceInfo.h"
38 
39 namespace WebCore {
40 
create(ExecutionContext * context,MediaStreamComponent * component)41 PassRefPtrWillBeRawPtr<MediaStreamTrack> MediaStreamTrack::create(ExecutionContext* context, MediaStreamComponent* component)
42 {
43     RefPtrWillBeRawPtr<MediaStreamTrack> track = adoptRefWillBeRefCountedGarbageCollected(new MediaStreamTrack(context, component));
44     track->suspendIfNeeded();
45     return track.release();
46 }
47 
MediaStreamTrack(ExecutionContext * context,MediaStreamComponent * component)48 MediaStreamTrack::MediaStreamTrack(ExecutionContext* context, MediaStreamComponent* component)
49     : ActiveDOMObject(context)
50     , m_readyState(MediaStreamSource::ReadyStateLive)
51     , m_isIteratingRegisteredMediaStreams(false)
52     , m_stopped(false)
53     , m_component(component)
54 {
55     ScriptWrappable::init(this);
56     m_component->source()->addObserver(this);
57 }
58 
~MediaStreamTrack()59 MediaStreamTrack::~MediaStreamTrack()
60 {
61     m_component->source()->removeObserver(this);
62 }
63 
kind() const64 String MediaStreamTrack::kind() const
65 {
66     DEFINE_STATIC_LOCAL(String, audioKind, ("audio"));
67     DEFINE_STATIC_LOCAL(String, videoKind, ("video"));
68 
69     switch (m_component->source()->type()) {
70     case MediaStreamSource::TypeAudio:
71         return audioKind;
72     case MediaStreamSource::TypeVideo:
73         return videoKind;
74     }
75 
76     ASSERT_NOT_REACHED();
77     return audioKind;
78 }
79 
id() const80 String MediaStreamTrack::id() const
81 {
82     return m_component->id();
83 }
84 
label() const85 String MediaStreamTrack::label() const
86 {
87     return m_component->source()->name();
88 }
89 
enabled() const90 bool MediaStreamTrack::enabled() const
91 {
92     return m_component->enabled();
93 }
94 
setEnabled(bool enabled)95 void MediaStreamTrack::setEnabled(bool enabled)
96 {
97     if (enabled == m_component->enabled())
98         return;
99 
100     m_component->setEnabled(enabled);
101 
102     if (!ended())
103         MediaStreamCenter::instance().didSetMediaStreamTrackEnabled(m_component.get());
104 }
105 
readyState() const106 String MediaStreamTrack::readyState() const
107 {
108     if (ended())
109         return "ended";
110 
111     switch (m_readyState) {
112     case MediaStreamSource::ReadyStateLive:
113         return "live";
114     case MediaStreamSource::ReadyStateMuted:
115         return "muted";
116     case MediaStreamSource::ReadyStateEnded:
117         return "ended";
118     }
119 
120     ASSERT_NOT_REACHED();
121     return String();
122 }
123 
getSources(ExecutionContext * context,PassOwnPtr<MediaStreamTrackSourcesCallback> callback,ExceptionState & exceptionState)124 void MediaStreamTrack::getSources(ExecutionContext* context, PassOwnPtr<MediaStreamTrackSourcesCallback> callback, ExceptionState& exceptionState)
125 {
126     RefPtrWillBeRawPtr<MediaStreamTrackSourcesRequest> request = MediaStreamTrackSourcesRequestImpl::create(context->securityOrigin()->toString(), callback);
127     if (!MediaStreamCenter::instance().getMediaStreamTrackSources(request.release()))
128         exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::failedToExecute("getSources", "MediaStreamTrack", "Functionality not implemented yet"));
129 }
130 
stopTrack(ExceptionState & exceptionState)131 void MediaStreamTrack::stopTrack(ExceptionState& exceptionState)
132 {
133     if (ended())
134         return;
135 
136     m_readyState = MediaStreamSource::ReadyStateEnded;
137     MediaStreamCenter::instance().didStopMediaStreamTrack(component());
138     dispatchEvent(Event::create(EventTypeNames::ended));
139     propagateTrackEnded();
140 }
141 
clone(ExecutionContext * context)142 PassRefPtrWillBeRawPtr<MediaStreamTrack> MediaStreamTrack::clone(ExecutionContext* context)
143 {
144     RefPtr<MediaStreamComponent> clonedComponent = MediaStreamComponent::create(component()->source());
145     RefPtrWillBeRawPtr<MediaStreamTrack> clonedTrack = MediaStreamTrack::create(context, clonedComponent.get());
146     MediaStreamCenter::instance().didCreateMediaStreamTrack(clonedComponent.get());
147     return clonedTrack.release();
148 }
149 
ended() const150 bool MediaStreamTrack::ended() const
151 {
152     return m_stopped || (m_readyState == MediaStreamSource::ReadyStateEnded);
153 }
154 
sourceChangedState()155 void MediaStreamTrack::sourceChangedState()
156 {
157     if (ended())
158         return;
159 
160     m_readyState = m_component->source()->readyState();
161     switch (m_readyState) {
162     case MediaStreamSource::ReadyStateLive:
163         dispatchEvent(Event::create(EventTypeNames::unmute));
164         break;
165     case MediaStreamSource::ReadyStateMuted:
166         dispatchEvent(Event::create(EventTypeNames::mute));
167         break;
168     case MediaStreamSource::ReadyStateEnded:
169         dispatchEvent(Event::create(EventTypeNames::ended));
170         propagateTrackEnded();
171         break;
172     }
173 }
174 
propagateTrackEnded()175 void MediaStreamTrack::propagateTrackEnded()
176 {
177     RELEASE_ASSERT(!m_isIteratingRegisteredMediaStreams);
178     m_isIteratingRegisteredMediaStreams = true;
179     for (WillBeHeapHashSet<RawPtrWillBeMember<MediaStream> >::iterator iter = m_registeredMediaStreams.begin(); iter != m_registeredMediaStreams.end(); ++iter)
180         (*iter)->trackEnded();
181     m_isIteratingRegisteredMediaStreams = false;
182 }
183 
component()184 MediaStreamComponent* MediaStreamTrack::component()
185 {
186     return m_component.get();
187 }
188 
stop()189 void MediaStreamTrack::stop()
190 {
191     m_stopped = true;
192 }
193 
createWebAudioSource()194 PassOwnPtr<AudioSourceProvider> MediaStreamTrack::createWebAudioSource()
195 {
196     return MediaStreamCenter::instance().createWebAudioSourceFromMediaStreamTrack(component());
197 }
198 
registerMediaStream(MediaStream * mediaStream)199 void MediaStreamTrack::registerMediaStream(MediaStream* mediaStream)
200 {
201     RELEASE_ASSERT(!m_isIteratingRegisteredMediaStreams);
202     RELEASE_ASSERT(!m_registeredMediaStreams.contains(mediaStream));
203     m_registeredMediaStreams.add(mediaStream);
204 }
205 
unregisterMediaStream(MediaStream * mediaStream)206 void MediaStreamTrack::unregisterMediaStream(MediaStream* mediaStream)
207 {
208     RELEASE_ASSERT(!m_isIteratingRegisteredMediaStreams);
209     WillBeHeapHashSet<RawPtrWillBeMember<MediaStream> >::iterator iter = m_registeredMediaStreams.find(mediaStream);
210     RELEASE_ASSERT(iter != m_registeredMediaStreams.end());
211     m_registeredMediaStreams.remove(iter);
212 }
213 
interfaceName() const214 const AtomicString& MediaStreamTrack::interfaceName() const
215 {
216     return EventTargetNames::MediaStreamTrack;
217 }
218 
executionContext() const219 ExecutionContext* MediaStreamTrack::executionContext() const
220 {
221     return ActiveDOMObject::executionContext();
222 }
223 
trace(Visitor * visitor)224 void MediaStreamTrack::trace(Visitor* visitor)
225 {
226     visitor->trace(m_registeredMediaStreams);
227     EventTargetWithInlineData::trace(visitor);
228 }
229 
230 } // namespace WebCore
231