Home | History | Annotate | Download | only in mediastream
      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/ExceptionState.h"
     30 #include "core/dom/Event.h"
     31 #include "core/dom/ExceptionCode.h"
     32 #include "core/dom/ScriptExecutionContext.h"
     33 #include "core/platform/mediastream/MediaStreamCenter.h"
     34 #include "core/platform/mediastream/MediaStreamComponent.h"
     35 #include "modules/mediastream/MediaStreamTrackSourcesCallback.h"
     36 #include "modules/mediastream/MediaStreamTrackSourcesRequest.h"
     37 #include "public/platform/WebSourceInfo.h"
     38 
     39 namespace WebCore {
     40 
     41 PassRefPtr<MediaStreamTrack> MediaStreamTrack::create(ScriptExecutionContext* 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(ScriptExecutionContext* context, MediaStreamComponent* component)
     49     : ActiveDOMObject(context)
     50     , m_stopped(false)
     51     , m_component(component)
     52 {
     53     ScriptWrappable::init(this);
     54     m_component->source()->addObserver(this);
     55 }
     56 
     57 MediaStreamTrack::~MediaStreamTrack()
     58 {
     59     m_component->source()->removeObserver(this);
     60 }
     61 
     62 String MediaStreamTrack::kind() const
     63 {
     64     DEFINE_STATIC_LOCAL(String, audioKind, ("audio"));
     65     DEFINE_STATIC_LOCAL(String, videoKind, ("video"));
     66 
     67     switch (m_component->source()->type()) {
     68     case MediaStreamSource::TypeAudio:
     69         return audioKind;
     70     case MediaStreamSource::TypeVideo:
     71         return videoKind;
     72     }
     73 
     74     ASSERT_NOT_REACHED();
     75     return audioKind;
     76 }
     77 
     78 String MediaStreamTrack::id() const
     79 {
     80     return m_component->id();
     81 }
     82 
     83 String MediaStreamTrack::label() const
     84 {
     85     return m_component->source()->name();
     86 }
     87 
     88 bool MediaStreamTrack::enabled() const
     89 {
     90     return m_component->enabled();
     91 }
     92 
     93 void MediaStreamTrack::setEnabled(bool enabled)
     94 {
     95     if (m_stopped || enabled == m_component->enabled())
     96         return;
     97 
     98     m_component->setEnabled(enabled);
     99 
    100     if (m_component->stream()->ended())
    101         return;
    102 
    103     MediaStreamCenter::instance().didSetMediaStreamTrackEnabled(m_component->stream(), m_component.get());
    104 }
    105 
    106 String MediaStreamTrack::readyState() const
    107 {
    108     if (m_stopped)
    109         return "ended";
    110 
    111     switch (m_component->source()->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(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrackSourcesCallback> callback, ExceptionState& es)
    125 {
    126     RefPtr<MediaStreamTrackSourcesRequest> request = MediaStreamTrackSourcesRequest::create(context, callback);
    127     bool ok = MediaStreamCenter::instance().getMediaStreamTrackSources(request.release());
    128     if (!ok)
    129         es.throwDOMException(NotSupportedError);
    130 }
    131 
    132 bool MediaStreamTrack::ended() const
    133 {
    134     return m_stopped || (m_component->source()->readyState() == MediaStreamSource::ReadyStateEnded);
    135 }
    136 
    137 void MediaStreamTrack::sourceChangedState()
    138 {
    139     if (m_stopped)
    140         return;
    141 
    142     switch (m_component->source()->readyState()) {
    143     case MediaStreamSource::ReadyStateLive:
    144         dispatchEvent(Event::create(eventNames().unmuteEvent, false, false));
    145         break;
    146     case MediaStreamSource::ReadyStateMuted:
    147         dispatchEvent(Event::create(eventNames().muteEvent, false, false));
    148         break;
    149     case MediaStreamSource::ReadyStateEnded:
    150         dispatchEvent(Event::create(eventNames().endedEvent, false, false));
    151         didEndTrack();
    152         break;
    153     }
    154 }
    155 
    156 void MediaStreamTrack::didEndTrack()
    157 {
    158     MediaStreamDescriptorClient* client = m_component->stream()->client();
    159     if (!client)
    160         return;
    161 
    162     client->trackEnded();
    163 }
    164 
    165 MediaStreamComponent* MediaStreamTrack::component()
    166 {
    167     return m_component.get();
    168 }
    169 
    170 void MediaStreamTrack::stop()
    171 {
    172     m_stopped = true;
    173 }
    174 
    175 const AtomicString& MediaStreamTrack::interfaceName() const
    176 {
    177     return eventNames().interfaceForMediaStreamTrack;
    178 }
    179 
    180 ScriptExecutionContext* MediaStreamTrack::scriptExecutionContext() const
    181 {
    182     return ActiveDOMObject::scriptExecutionContext();
    183 }
    184 
    185 EventTargetData* MediaStreamTrack::eventTargetData()
    186 {
    187     return &m_eventTargetData;
    188 }
    189 
    190 EventTargetData* MediaStreamTrack::ensureEventTargetData()
    191 {
    192     return &m_eventTargetData;
    193 }
    194 
    195 } // namespace WebCore
    196