Upstream version 7.36.149.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/v8/ExceptionMessages.h"
30 #include "core/dom/ExceptionCode.h"
31 #include "core/dom/ExecutionContext.h"
32 #include "core/events/Event.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
41 PassRefPtr<MediaStreamTrack> MediaStreamTrack::create(ExecutionContext* context, MediaStreamComponent* component)
42 {
43     RefPtr<MediaStreamTrack> track = adoptRef(new MediaStreamTrack(context, component));
44     track->suspendIfNeeded();
45     return track.release();
46 }
47
48 MediaStreamTrack::MediaStreamTrack(ExecutionContext* context, MediaStreamComponent* component)
49     : ActiveDOMObject(context)
50     , m_readyState(MediaStreamSource::ReadyStateLive)
51     , m_isIteratingObservers(false)
52     , m_stopped(false)
53     , m_component(component)
54 {
55     ScriptWrappable::init(this);
56     m_component->source()->addObserver(this);
57 }
58
59 MediaStreamTrack::~MediaStreamTrack()
60 {
61     m_component->source()->removeObserver(this);
62 }
63
64 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
80 String MediaStreamTrack::id() const
81 {
82     return m_component->id();
83 }
84
85 String MediaStreamTrack::label() const
86 {
87     return m_component->source()->name();
88 }
89
90 bool MediaStreamTrack::enabled() const
91 {
92     return m_component->enabled();
93 }
94
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
106 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
124 void MediaStreamTrack::getSources(ExecutionContext* context, PassOwnPtr<MediaStreamTrackSourcesCallback> callback, ExceptionState& exceptionState)
125 {
126     RefPtr<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
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
142 PassRefPtr<MediaStreamTrack> MediaStreamTrack::clone(ExecutionContext* context)
143 {
144     RefPtr<MediaStreamComponent> clonedComponent = MediaStreamComponent::create(component()->source());
145     RefPtr<MediaStreamTrack> clonedTrack = MediaStreamTrack::create(context, clonedComponent.get());
146     MediaStreamCenter::instance().didCreateMediaStreamTrack(clonedComponent.get());
147     return clonedTrack.release();
148 }
149
150 bool MediaStreamTrack::ended() const
151 {
152     return m_stopped || (m_readyState == MediaStreamSource::ReadyStateEnded);
153 }
154
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
175 void MediaStreamTrack::propagateTrackEnded()
176 {
177     RELEASE_ASSERT(!m_isIteratingObservers);
178     m_isIteratingObservers = true;
179     for (Vector<Observer*>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter)
180         (*iter)->trackEnded();
181     m_isIteratingObservers = false;
182 }
183
184 MediaStreamComponent* MediaStreamTrack::component()
185 {
186     return m_component.get();
187 }
188
189 void MediaStreamTrack::stop()
190 {
191     m_stopped = true;
192 }
193
194 PassOwnPtr<AudioSourceProvider> MediaStreamTrack::createWebAudioSource()
195 {
196     return MediaStreamCenter::instance().createWebAudioSourceFromMediaStreamTrack(component());
197 }
198
199 void MediaStreamTrack::addObserver(MediaStreamTrack::Observer* observer)
200 {
201     RELEASE_ASSERT(!m_isIteratingObservers);
202     m_observers.append(observer);
203 }
204
205 void MediaStreamTrack::removeObserver(MediaStreamTrack::Observer* observer)
206 {
207     RELEASE_ASSERT(!m_isIteratingObservers);
208     size_t pos = m_observers.find(observer);
209     RELEASE_ASSERT(pos != kNotFound);
210     m_observers.remove(pos);
211 }
212
213 const AtomicString& MediaStreamTrack::interfaceName() const
214 {
215     return EventTargetNames::MediaStreamTrack;
216 }
217
218 ExecutionContext* MediaStreamTrack::executionContext() const
219 {
220     return ActiveDOMObject::executionContext();
221 }
222
223 } // namespace WebCore