Home | History | Annotate | Download | only in media
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/renderer/media/media_stream_center.h"
      6 
      7 #include <string>
      8 
      9 #include "base/command_line.h"
     10 #include "base/logging.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/strings/string_number_conversions.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "content/common/media/media_stream_messages.h"
     15 #include "content/public/common/content_switches.h"
     16 #include "content/public/renderer/render_thread.h"
     17 #include "content/renderer/media/media_stream_dependency_factory.h"
     18 #include "content/renderer/media/media_stream_extra_data.h"
     19 #include "content/renderer/media/media_stream_source_extra_data.h"
     20 #include "content/renderer/media/media_stream_track_extra_data.h"
     21 #include "content/renderer/render_view_impl.h"
     22 #include "third_party/WebKit/public/platform/WebMediaStream.h"
     23 #include "third_party/WebKit/public/platform/WebMediaStreamCenterClient.h"
     24 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
     25 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
     26 #include "third_party/WebKit/public/platform/WebMediaStreamTrackSourcesRequest.h"
     27 #include "third_party/WebKit/public/platform/WebSourceInfo.h"
     28 #include "third_party/WebKit/public/platform/WebVector.h"
     29 #include "third_party/WebKit/public/web/WebFrame.h"
     30 #include "third_party/libjingle/source/talk/app/webrtc/jsep.h"
     31 
     32 using blink::WebFrame;
     33 using blink::WebView;
     34 
     35 namespace content {
     36 
     37 MediaStreamCenter::MediaStreamCenter(blink::WebMediaStreamCenterClient* client,
     38                                      MediaStreamDependencyFactory* factory)
     39     : rtc_factory_(factory), next_request_id_(0) {}
     40 
     41 MediaStreamCenter::~MediaStreamCenter() {}
     42 
     43 bool MediaStreamCenter::getMediaStreamTrackSources(
     44     const blink::WebMediaStreamTrackSourcesRequest& request) {
     45   if (!CommandLine::ForCurrentProcess()->HasSwitch(
     46       switches::kDisableDeviceEnumeration)) {
     47     int request_id = next_request_id_++;
     48     requests_.insert(std::make_pair(request_id, request));
     49     RenderThread::Get()->Send(new MediaStreamHostMsg_GetSources(
     50         request_id, GURL(request.origin().utf8())));
     51     return true;
     52   }
     53   return false;
     54 }
     55 
     56 void MediaStreamCenter::didCreateMediaStreamTrack(
     57     const blink::WebMediaStreamTrack& track) {
     58   if (!rtc_factory_)
     59     return;
     60   rtc_factory_->CreateNativeMediaStreamTrack(track);
     61 }
     62 
     63 void MediaStreamCenter::didEnableMediaStreamTrack(
     64     const blink::WebMediaStreamTrack& track) {
     65   webrtc::MediaStreamTrackInterface* native_track =
     66       MediaStreamDependencyFactory::GetNativeMediaStreamTrack(track);
     67   if (native_track)
     68     native_track->set_enabled(true);
     69 }
     70 
     71 void MediaStreamCenter::didDisableMediaStreamTrack(
     72     const blink::WebMediaStreamTrack& track) {
     73   webrtc::MediaStreamTrackInterface* native_track =
     74       MediaStreamDependencyFactory::GetNativeMediaStreamTrack(track);
     75   if (native_track)
     76     native_track->set_enabled(false);
     77 }
     78 
     79 bool MediaStreamCenter::didStopMediaStreamTrack(
     80     const blink::WebMediaStreamTrack& track) {
     81   DVLOG(1) << "MediaStreamCenter::didStopMediaStreamTrack";
     82   blink::WebMediaStreamSource source = track.source();
     83   MediaStreamSourceExtraData* extra_data =
     84       static_cast<MediaStreamSourceExtraData*>(source.extraData());
     85   if (!extra_data) {
     86     DVLOG(1) << "didStopMediaStreamTrack called on a remote track.";
     87     return false;
     88   }
     89 
     90   extra_data->OnLocalSourceStop();
     91   return true;
     92 }
     93 
     94 void MediaStreamCenter::didStopLocalMediaStream(
     95     const blink::WebMediaStream& stream) {
     96   DVLOG(1) << "MediaStreamCenter::didStopLocalMediaStream";
     97   MediaStreamExtraData* extra_data =
     98       static_cast<MediaStreamExtraData*>(stream.extraData());
     99   if (!extra_data) {
    100     NOTREACHED();
    101     return;
    102   }
    103 
    104   // TODO(perkj): MediaStream::Stop is being deprecated. But for the moment we
    105   // need to support the old behavior and the new. Since we only create one
    106   // source object per actual device- we need to fake stopping a
    107   // MediaStreamTrack by disabling it if the same device is used as source by
    108   // multiple tracks. Note that disabling a track here, don't affect the
    109   // enabled property in JS.
    110   blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
    111   stream.audioTracks(audio_tracks);
    112   for (size_t i = 0; i < audio_tracks.size(); ++i)
    113     didDisableMediaStreamTrack(audio_tracks[i]);
    114 
    115   blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
    116   stream.videoTracks(video_tracks);
    117   for (size_t i = 0; i < video_tracks.size(); ++i)
    118     didDisableMediaStreamTrack(video_tracks[i]);
    119 
    120   extra_data->OnLocalStreamStop();
    121 }
    122 
    123 void MediaStreamCenter::didCreateMediaStream(
    124     blink::WebMediaStream& stream) {
    125   if (!rtc_factory_)
    126     return;
    127   rtc_factory_->CreateNativeLocalMediaStream(&stream);
    128 }
    129 
    130 bool MediaStreamCenter::didAddMediaStreamTrack(
    131     const blink::WebMediaStream& stream,
    132     const blink::WebMediaStreamTrack& track) {
    133   if (!rtc_factory_)
    134     return false;
    135 
    136   return rtc_factory_->AddNativeMediaStreamTrack(stream, track);
    137 }
    138 
    139 bool MediaStreamCenter::didRemoveMediaStreamTrack(
    140     const blink::WebMediaStream& stream,
    141     const blink::WebMediaStreamTrack& track) {
    142   if (!rtc_factory_)
    143     return false;
    144 
    145   return rtc_factory_->RemoveNativeMediaStreamTrack(stream, track);
    146 }
    147 
    148 bool MediaStreamCenter::OnControlMessageReceived(const IPC::Message& message) {
    149   bool handled = true;
    150   IPC_BEGIN_MESSAGE_MAP(MediaStreamCenter, message)
    151     IPC_MESSAGE_HANDLER(MediaStreamMsg_GetSourcesACK,
    152                         OnGetSourcesComplete)
    153     IPC_MESSAGE_UNHANDLED(handled = false)
    154   IPC_END_MESSAGE_MAP()
    155   return handled;
    156 }
    157 
    158 void MediaStreamCenter::OnGetSourcesComplete(
    159     int request_id,
    160     const content::StreamDeviceInfoArray& devices) {
    161   RequestMap::iterator request_it = requests_.find(request_id);
    162   DCHECK(request_it != requests_.end());
    163 
    164   blink::WebVector<blink::WebSourceInfo> sourceInfos(devices.size());
    165   for (size_t i = 0; i < devices.size(); ++i) {
    166     const MediaStreamDevice& device = devices[i].device;
    167     DCHECK(device.type == MEDIA_DEVICE_AUDIO_CAPTURE ||
    168            device.type == MEDIA_DEVICE_VIDEO_CAPTURE);
    169     blink::WebSourceInfo::VideoFacingMode video_facing;
    170     switch (device.video_facing) {
    171       case MEDIA_VIDEO_FACING_USER:
    172         video_facing = blink::WebSourceInfo::VideoFacingModeUser;
    173         break;
    174       case MEDIA_VIDEO_FACING_ENVIRONMENT:
    175         video_facing = blink::WebSourceInfo::VideoFacingModeEnvironment;
    176         break;
    177       default:
    178         video_facing = blink::WebSourceInfo::VideoFacingModeNone;
    179     }
    180 
    181     sourceInfos[i]
    182         .initialize(blink::WebString::fromUTF8(device.id),
    183                     device.type == MEDIA_DEVICE_AUDIO_CAPTURE
    184                         ? blink::WebSourceInfo::SourceKindAudio
    185                         : blink::WebSourceInfo::SourceKindVideo,
    186                     blink::WebString::fromUTF8(device.name),
    187                     video_facing);
    188   }
    189   request_it->second.requestSucceeded(sourceInfos);
    190 }
    191 
    192 }  // namespace content
    193