Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / mediastream / MediaStreamTrack.cpp
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/core/v8/ExceptionMessages.h"
30 #include "core/dom/Document.h"
31 #include "core/dom/ExceptionCode.h"
32 #include "core/dom/ExecutionContext.h"
33 #include "core/events/Event.h"
34 #include "modules/mediastream/MediaStream.h"
35 #include "modules/mediastream/MediaStreamTrackSourcesCallback.h"
36 #include "modules/mediastream/MediaStreamTrackSourcesRequestImpl.h"
37 #include "modules/mediastream/UserMediaController.h"
38 #include "platform/mediastream/MediaStreamCenter.h"
39 #include "platform/mediastream/MediaStreamComponent.h"
40 #include "public/platform/WebSourceInfo.h"
41
42 namespace blink {
43
44 MediaStreamTrack* MediaStreamTrack::create(ExecutionContext* context, MediaStreamComponent* component)
45 {
46     MediaStreamTrack* track = new MediaStreamTrack(context, component);
47     track->suspendIfNeeded();
48     return track;
49 }
50
51 MediaStreamTrack::MediaStreamTrack(ExecutionContext* context, MediaStreamComponent* component)
52     : ActiveDOMObject(context)
53     , m_readyState(MediaStreamSource::ReadyStateLive)
54     , m_isIteratingRegisteredMediaStreams(false)
55     , m_stopped(false)
56     , m_component(component)
57 {
58     m_component->source()->addObserver(this);
59 }
60
61 MediaStreamTrack::~MediaStreamTrack()
62 {
63     m_component->source()->removeObserver(this);
64 }
65
66 String MediaStreamTrack::kind() const
67 {
68     DEFINE_STATIC_LOCAL(String, audioKind, ("audio"));
69     DEFINE_STATIC_LOCAL(String, videoKind, ("video"));
70
71     switch (m_component->source()->type()) {
72     case MediaStreamSource::TypeAudio:
73         return audioKind;
74     case MediaStreamSource::TypeVideo:
75         return videoKind;
76     }
77
78     ASSERT_NOT_REACHED();
79     return audioKind;
80 }
81
82 String MediaStreamTrack::id() const
83 {
84     return m_component->id();
85 }
86
87 String MediaStreamTrack::label() const
88 {
89     return m_component->source()->name();
90 }
91
92 bool MediaStreamTrack::enabled() const
93 {
94     return m_component->enabled();
95 }
96
97 void MediaStreamTrack::setEnabled(bool enabled)
98 {
99     if (enabled == m_component->enabled())
100         return;
101
102     m_component->setEnabled(enabled);
103
104     if (!ended())
105         MediaStreamCenter::instance().didSetMediaStreamTrackEnabled(m_component.get());
106 }
107
108 bool MediaStreamTrack::muted() const
109 {
110     return m_component->muted();
111 }
112
113 bool MediaStreamTrack::remote() const
114 {
115     return m_component->source()->remote();
116 }
117
118 bool MediaStreamTrack::readonly() const
119 {
120     return m_component->source()->readonly();
121 }
122
123 String MediaStreamTrack::readyState() const
124 {
125     if (ended())
126         return "ended";
127
128     switch (m_readyState) {
129     case MediaStreamSource::ReadyStateLive:
130         return "live";
131     case MediaStreamSource::ReadyStateMuted:
132         return "muted";
133     case MediaStreamSource::ReadyStateEnded:
134         return "ended";
135     }
136
137     ASSERT_NOT_REACHED();
138     return String();
139 }
140
141 void MediaStreamTrack::getSources(ExecutionContext* context, MediaStreamTrackSourcesCallback* callback, ExceptionState& exceptionState)
142 {
143     LocalFrame* frame = toDocument(context)->frame();
144     UserMediaController* userMedia = UserMediaController::from(frame);
145     if (!userMedia) {
146         exceptionState.throwDOMException(NotSupportedError, "No sources controller available; is this a detached window?");
147         return;
148     }
149     MediaStreamTrackSourcesRequest* request = MediaStreamTrackSourcesRequestImpl::create(*context, callback);
150     userMedia->requestSources(request);
151 }
152
153 void MediaStreamTrack::stopTrack(ExceptionState& exceptionState)
154 {
155     if (ended())
156         return;
157
158     m_readyState = MediaStreamSource::ReadyStateEnded;
159     MediaStreamCenter::instance().didStopMediaStreamTrack(component());
160     dispatchEvent(Event::create(EventTypeNames::ended));
161     propagateTrackEnded();
162 }
163
164 MediaStreamTrack* MediaStreamTrack::clone(ExecutionContext* context)
165 {
166     RefPtr<MediaStreamComponent> clonedComponent = MediaStreamComponent::create(component()->source());
167     MediaStreamTrack* clonedTrack = MediaStreamTrack::create(context, clonedComponent.get());
168     MediaStreamCenter::instance().didCreateMediaStreamTrack(clonedComponent.get());
169     return clonedTrack;
170 }
171
172 bool MediaStreamTrack::ended() const
173 {
174     return m_stopped || (m_readyState == MediaStreamSource::ReadyStateEnded);
175 }
176
177 void MediaStreamTrack::sourceChangedState()
178 {
179     if (ended())
180         return;
181
182     m_readyState = m_component->source()->readyState();
183     switch (m_readyState) {
184     case MediaStreamSource::ReadyStateLive:
185         m_component->setMuted(false);
186         dispatchEvent(Event::create(EventTypeNames::unmute));
187         break;
188     case MediaStreamSource::ReadyStateMuted:
189         m_component->setMuted(true);
190         dispatchEvent(Event::create(EventTypeNames::mute));
191         break;
192     case MediaStreamSource::ReadyStateEnded:
193         dispatchEvent(Event::create(EventTypeNames::ended));
194         propagateTrackEnded();
195         break;
196     }
197 }
198
199 void MediaStreamTrack::propagateTrackEnded()
200 {
201     RELEASE_ASSERT(!m_isIteratingRegisteredMediaStreams);
202     m_isIteratingRegisteredMediaStreams = true;
203     for (HeapHashSet<Member<MediaStream> >::iterator iter = m_registeredMediaStreams.begin(); iter != m_registeredMediaStreams.end(); ++iter)
204         (*iter)->trackEnded();
205     m_isIteratingRegisteredMediaStreams = false;
206 }
207
208 MediaStreamComponent* MediaStreamTrack::component()
209 {
210     return m_component.get();
211 }
212
213 void MediaStreamTrack::stop()
214 {
215     m_stopped = true;
216 }
217
218 PassOwnPtr<AudioSourceProvider> MediaStreamTrack::createWebAudioSource()
219 {
220     return MediaStreamCenter::instance().createWebAudioSourceFromMediaStreamTrack(component());
221 }
222
223 void MediaStreamTrack::registerMediaStream(MediaStream* mediaStream)
224 {
225     RELEASE_ASSERT(!m_isIteratingRegisteredMediaStreams);
226     RELEASE_ASSERT(!m_registeredMediaStreams.contains(mediaStream));
227     m_registeredMediaStreams.add(mediaStream);
228 }
229
230 void MediaStreamTrack::unregisterMediaStream(MediaStream* mediaStream)
231 {
232     RELEASE_ASSERT(!m_isIteratingRegisteredMediaStreams);
233     HeapHashSet<Member<MediaStream> >::iterator iter = m_registeredMediaStreams.find(mediaStream);
234     RELEASE_ASSERT(iter != m_registeredMediaStreams.end());
235     m_registeredMediaStreams.remove(iter);
236 }
237
238 const AtomicString& MediaStreamTrack::interfaceName() const
239 {
240     return EventTargetNames::MediaStreamTrack;
241 }
242
243 ExecutionContext* MediaStreamTrack::executionContext() const
244 {
245     return ActiveDOMObject::executionContext();
246 }
247
248 void MediaStreamTrack::trace(Visitor* visitor)
249 {
250     visitor->trace(m_registeredMediaStreams);
251     EventTargetWithInlineData::trace(visitor);
252 }
253
254 } // namespace blink