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/ExceptionMessages.h"
     30 #include "core/dom/ExceptionCode.h"
     31 #include "core/dom/ExecutionContext.h"
     32 #include "core/events/Event.h"
     33 #include "core/platform/mediastream/MediaStreamCenter.h"
     34 #include "modules/mediastream/MediaStreamTrackSourcesCallback.h"
     35 #include "modules/mediastream/MediaStreamTrackSourcesRequest.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_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(ExecutionContext* context, PassOwnPtr<MediaStreamTrackSourcesCallback> callback, ExceptionState& exceptionState)
    125 {
    126     RefPtr<MediaStreamTrackSourcesRequest> request = MediaStreamTrackSourcesRequest::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     if (!MediaStreamCenter::instance().didStopMediaStreamTrack(component()))
    137         exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::failedToExecute("stop", "MediaStreamTrack", "Functionality not implemented yet"));
    138 }
    139 
    140 bool MediaStreamTrack::ended() const
    141 {
    142     return m_stopped || (m_component->source()->readyState() == MediaStreamSource::ReadyStateEnded);
    143 }
    144 
    145 void MediaStreamTrack::sourceChangedState()
    146 {
    147     if (m_stopped)
    148         return;
    149 
    150     switch (m_component->source()->readyState()) {
    151     case MediaStreamSource::ReadyStateLive:
    152         dispatchEvent(Event::create(EventTypeNames::unmute));
    153         break;
    154     case MediaStreamSource::ReadyStateMuted:
    155         dispatchEvent(Event::create(EventTypeNames::mute));
    156         break;
    157     case MediaStreamSource::ReadyStateEnded:
    158         dispatchEvent(Event::create(EventTypeNames::ended));
    159         didEndTrack();
    160         break;
    161     }
    162 }
    163 
    164 void MediaStreamTrack::didEndTrack()
    165 {
    166     MediaStreamDescriptor* stream = m_component->stream();
    167     if (!stream)
    168         return;
    169 
    170     MediaStreamDescriptorClient* client = stream->client();
    171     if (!client)
    172         return;
    173 
    174     client->trackEnded();
    175 }
    176 
    177 MediaStreamComponent* MediaStreamTrack::component()
    178 {
    179     return m_component.get();
    180 }
    181 
    182 void MediaStreamTrack::stop()
    183 {
    184     m_stopped = true;
    185 }
    186 
    187 const AtomicString& MediaStreamTrack::interfaceName() const
    188 {
    189     return EventTargetNames::MediaStreamTrack;
    190 }
    191 
    192 ExecutionContext* MediaStreamTrack::executionContext() const
    193 {
    194     return ActiveDOMObject::executionContext();
    195 }
    196 
    197 } // namespace WebCore
    198