Home | History | Annotate | Download | only in pepper
      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/pepper/pepper_media_device_manager.h"
      6 
      7 #include "base/logging.h"
      8 #include "content/renderer/media/media_stream_dispatcher.h"
      9 #include "content/renderer/render_view_impl.h"
     10 #include "ppapi/shared_impl/ppb_device_ref_shared.h"
     11 
     12 namespace content {
     13 
     14 namespace {
     15 
     16 ppapi::DeviceRefData FromStreamDeviceInfo(const StreamDeviceInfo& info) {
     17   ppapi::DeviceRefData data;
     18   data.id = info.device.id;
     19   data.name = info.device.name;
     20   data.type = PepperMediaDeviceManager::FromMediaStreamType(info.device.type);
     21   return data;
     22 }
     23 
     24 }  // namespace
     25 
     26 PepperMediaDeviceManager* PepperMediaDeviceManager::GetForRenderView(
     27     RenderView* render_view) {
     28   PepperMediaDeviceManager* handler =
     29       PepperMediaDeviceManager::Get(render_view);
     30   if (!handler)
     31     handler = new PepperMediaDeviceManager(render_view);
     32   return handler;
     33 }
     34 
     35 PepperMediaDeviceManager::PepperMediaDeviceManager(RenderView* render_view)
     36     : RenderViewObserver(render_view),
     37       RenderViewObserverTracker<PepperMediaDeviceManager>(render_view),
     38       next_id_(1) {}
     39 
     40 PepperMediaDeviceManager::~PepperMediaDeviceManager() {
     41   DCHECK(enumerate_callbacks_.empty());
     42   DCHECK(open_callbacks_.empty());
     43 }
     44 
     45 int PepperMediaDeviceManager::EnumerateDevices(
     46     PP_DeviceType_Dev type,
     47     const GURL& document_url,
     48     const EnumerateDevicesCallback& callback) {
     49   enumerate_callbacks_[next_id_] = callback;
     50   int request_id = next_id_++;
     51 
     52 #if defined(ENABLE_WEBRTC)
     53   GetRenderViewImpl()->media_stream_dispatcher()->EnumerateDevices(
     54       request_id,
     55       AsWeakPtr(),
     56       PepperMediaDeviceManager::FromPepperDeviceType(type),
     57       document_url.GetOrigin(),
     58       false);
     59 #else
     60   base::MessageLoop::current()->PostTask(
     61       FROM_HERE,
     62       base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated,
     63                  AsWeakPtr(),
     64                  request_id,
     65                  StreamDeviceInfoArray()));
     66 #endif
     67 
     68   return request_id;
     69 }
     70 
     71 void PepperMediaDeviceManager::StopEnumerateDevices(int request_id) {
     72   enumerate_callbacks_.erase(request_id);
     73 
     74 #if defined(ENABLE_WEBRTC)
     75   // Need to post task since this function might be called inside the callback
     76   // of EnumerateDevices.
     77   base::MessageLoop::current()->PostTask(
     78       FROM_HERE,
     79       base::Bind(&MediaStreamDispatcher::StopEnumerateDevices,
     80                  GetRenderViewImpl()->media_stream_dispatcher()->AsWeakPtr(),
     81                  request_id,
     82                  AsWeakPtr()));
     83 #endif
     84 }
     85 
     86 int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type,
     87                                          const std::string& device_id,
     88                                          const GURL& document_url,
     89                                          const OpenDeviceCallback& callback) {
     90   open_callbacks_[next_id_] = callback;
     91   int request_id = next_id_++;
     92 
     93 #if defined(ENABLE_WEBRTC)
     94   GetRenderViewImpl()->media_stream_dispatcher()->OpenDevice(
     95       request_id,
     96       AsWeakPtr(),
     97       device_id,
     98       PepperMediaDeviceManager::FromPepperDeviceType(type),
     99       document_url.GetOrigin());
    100 #else
    101   base::MessageLoop::current()->PostTask(
    102       FROM_HERE,
    103       base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed,
    104                  AsWeakPtr(),
    105                  request_id));
    106 #endif
    107 
    108   return request_id;
    109 }
    110 
    111 void PepperMediaDeviceManager::CancelOpenDevice(int request_id) {
    112   open_callbacks_.erase(request_id);
    113 
    114 #if defined(ENABLE_WEBRTC)
    115   GetRenderViewImpl()->media_stream_dispatcher()->CancelOpenDevice(request_id,
    116                                                                    AsWeakPtr());
    117 #endif
    118 }
    119 
    120 void PepperMediaDeviceManager::CloseDevice(const std::string& label) {
    121 #if defined(ENABLE_WEBRTC)
    122   GetRenderViewImpl()->media_stream_dispatcher()->CloseDevice(label);
    123 #endif
    124 }
    125 
    126 int PepperMediaDeviceManager::GetSessionID(PP_DeviceType_Dev type,
    127                                            const std::string& label) {
    128 #if defined(ENABLE_WEBRTC)
    129   switch (type) {
    130     case PP_DEVICETYPE_DEV_AUDIOCAPTURE:
    131       return GetRenderViewImpl()->media_stream_dispatcher()->audio_session_id(
    132           label, 0);
    133     case PP_DEVICETYPE_DEV_VIDEOCAPTURE:
    134       return GetRenderViewImpl()->media_stream_dispatcher()->video_session_id(
    135           label, 0);
    136     default:
    137       NOTREACHED();
    138       return 0;
    139   }
    140 #else
    141   return 0;
    142 #endif
    143 }
    144 
    145 void PepperMediaDeviceManager::OnStreamGenerated(
    146     int request_id,
    147     const std::string& label,
    148     const StreamDeviceInfoArray& audio_device_array,
    149     const StreamDeviceInfoArray& video_device_array) {}
    150 
    151 void PepperMediaDeviceManager::OnStreamGenerationFailed(
    152     int request_id,
    153     content::MediaStreamRequestResult result) {}
    154 
    155 void PepperMediaDeviceManager::OnDeviceStopped(
    156     const std::string& label,
    157     const StreamDeviceInfo& device_info) {}
    158 
    159 void PepperMediaDeviceManager::OnDevicesEnumerated(
    160     int request_id,
    161     const StreamDeviceInfoArray& device_array) {
    162   EnumerateCallbackMap::iterator iter = enumerate_callbacks_.find(request_id);
    163   if (iter == enumerate_callbacks_.end()) {
    164     // This might be enumerated result sent before StopEnumerateDevices is
    165     // called since EnumerateDevices is persistent request.
    166     return;
    167   }
    168 
    169   EnumerateDevicesCallback callback = iter->second;
    170 
    171   std::vector<ppapi::DeviceRefData> devices;
    172   devices.reserve(device_array.size());
    173   for (StreamDeviceInfoArray::const_iterator info = device_array.begin();
    174        info != device_array.end();
    175        ++info) {
    176     devices.push_back(FromStreamDeviceInfo(*info));
    177   }
    178   callback.Run(request_id, devices);
    179 }
    180 
    181 void PepperMediaDeviceManager::OnDeviceOpened(
    182     int request_id,
    183     const std::string& label,
    184     const StreamDeviceInfo& device_info) {
    185   NotifyDeviceOpened(request_id, true, label);
    186 }
    187 
    188 void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id) {
    189   NotifyDeviceOpened(request_id, false, std::string());
    190 }
    191 
    192 // static
    193 MediaStreamType PepperMediaDeviceManager::FromPepperDeviceType(
    194     PP_DeviceType_Dev type) {
    195   switch (type) {
    196     case PP_DEVICETYPE_DEV_INVALID:
    197       return MEDIA_NO_SERVICE;
    198     case PP_DEVICETYPE_DEV_AUDIOCAPTURE:
    199       return MEDIA_DEVICE_AUDIO_CAPTURE;
    200     case PP_DEVICETYPE_DEV_VIDEOCAPTURE:
    201       return MEDIA_DEVICE_VIDEO_CAPTURE;
    202     default:
    203       NOTREACHED();
    204       return MEDIA_NO_SERVICE;
    205   }
    206 }
    207 
    208 // static
    209 PP_DeviceType_Dev PepperMediaDeviceManager::FromMediaStreamType(
    210     MediaStreamType type) {
    211   switch (type) {
    212     case MEDIA_NO_SERVICE:
    213       return PP_DEVICETYPE_DEV_INVALID;
    214     case MEDIA_DEVICE_AUDIO_CAPTURE:
    215       return PP_DEVICETYPE_DEV_AUDIOCAPTURE;
    216     case MEDIA_DEVICE_VIDEO_CAPTURE:
    217       return PP_DEVICETYPE_DEV_VIDEOCAPTURE;
    218     default:
    219       NOTREACHED();
    220       return PP_DEVICETYPE_DEV_INVALID;
    221   }
    222 }
    223 
    224 void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id,
    225                                                   bool succeeded,
    226                                                   const std::string& label) {
    227   OpenCallbackMap::iterator iter = open_callbacks_.find(request_id);
    228   if (iter == open_callbacks_.end()) {
    229     // The callback may have been unregistered.
    230     return;
    231   }
    232 
    233   OpenDeviceCallback callback = iter->second;
    234   open_callbacks_.erase(iter);
    235 
    236   callback.Run(request_id, succeeded, label);
    237 }
    238 
    239 RenderViewImpl* PepperMediaDeviceManager::GetRenderViewImpl() {
    240   return static_cast<RenderViewImpl*>(render_view());
    241 }
    242 
    243 }  // namespace content
    244