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 
     41 PepperMediaDeviceManager::~PepperMediaDeviceManager() {
     42   DCHECK(enumerate_callbacks_.empty());
     43   DCHECK(open_callbacks_.empty());
     44 }
     45 
     46 int PepperMediaDeviceManager::EnumerateDevices(
     47     PP_DeviceType_Dev type,
     48     const GURL& document_url,
     49     const EnumerateDevicesCallback& callback) {
     50   enumerate_callbacks_[next_id_] = callback;
     51   int request_id = next_id_++;
     52 
     53 #if defined(ENABLE_WEBRTC)
     54   GetRenderViewImpl()->media_stream_dispatcher()->EnumerateDevices(
     55       request_id, AsWeakPtr(),
     56       PepperMediaDeviceManager::FromPepperDeviceType(type),
     57       document_url.GetOrigin());
     58 #else
     59   base::MessageLoop::current()->PostTask(
     60       FROM_HERE,
     61       base::Bind(
     62           &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(
     87     PP_DeviceType_Dev type,
     88     const std::string& device_id,
     89     const GURL& document_url,
     90     const OpenDeviceCallback& callback) {
     91   open_callbacks_[next_id_] = callback;
     92   int request_id = next_id_++;
     93 
     94 #if defined(ENABLE_WEBRTC)
     95   GetRenderViewImpl()->media_stream_dispatcher()->
     96       OpenDevice(
     97           request_id,
     98           AsWeakPtr(),
     99           device_id,
    100           PepperMediaDeviceManager::FromPepperDeviceType(type),
    101           document_url.GetOrigin());
    102 #else
    103   base::MessageLoop::current()->PostTask(
    104       FROM_HERE,
    105       base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed,
    106                  AsWeakPtr(),
    107                  request_id));
    108 #endif
    109 
    110   return request_id;
    111 }
    112 
    113 void PepperMediaDeviceManager::CancelOpenDevice(int request_id) {
    114   open_callbacks_.erase(request_id);
    115 
    116 #if defined(ENABLE_WEBRTC)
    117   GetRenderViewImpl()->media_stream_dispatcher()->CancelOpenDevice(
    118       request_id, AsWeakPtr());
    119 #endif
    120 }
    121 
    122 void PepperMediaDeviceManager::CloseDevice(const std::string& label) {
    123 #if defined(ENABLE_WEBRTC)
    124   GetRenderViewImpl()->media_stream_dispatcher()->CloseDevice(label);
    125 #endif
    126 }
    127 
    128 int PepperMediaDeviceManager::GetSessionID(PP_DeviceType_Dev type,
    129                                            const std::string& label) {
    130 #if defined(ENABLE_WEBRTC)
    131   switch (type) {
    132     case PP_DEVICETYPE_DEV_AUDIOCAPTURE:
    133       return GetRenderViewImpl()->media_stream_dispatcher()->audio_session_id(
    134           label, 0);
    135     case PP_DEVICETYPE_DEV_VIDEOCAPTURE:
    136       return GetRenderViewImpl()->media_stream_dispatcher()->video_session_id(
    137           label, 0);
    138     default:
    139       NOTREACHED();
    140       return 0;
    141   }
    142 #else
    143   return 0;
    144 #endif
    145 }
    146 
    147 void PepperMediaDeviceManager::OnStreamGenerated(
    148     int request_id,
    149     const std::string& label,
    150     const StreamDeviceInfoArray& audio_device_array,
    151     const StreamDeviceInfoArray& video_device_array) {
    152 }
    153 
    154 void PepperMediaDeviceManager::OnStreamGenerationFailed(int request_id) {
    155 }
    156 
    157 void PepperMediaDeviceManager::OnDeviceStopped(
    158     const std::string& label,
    159     const StreamDeviceInfo& device_info) {
    160 }
    161 
    162 void PepperMediaDeviceManager::OnDevicesEnumerated(
    163     int request_id,
    164     const StreamDeviceInfoArray& device_array) {
    165   EnumerateCallbackMap::iterator iter = enumerate_callbacks_.find(request_id);
    166   if (iter == enumerate_callbacks_.end()) {
    167     // This might be enumerated result sent before StopEnumerateDevices is
    168     // called since EnumerateDevices is persistent request.
    169     return;
    170   }
    171 
    172   EnumerateDevicesCallback callback = iter->second;
    173 
    174   std::vector<ppapi::DeviceRefData> devices;
    175   devices.reserve(device_array.size());
    176   for (StreamDeviceInfoArray::const_iterator info =
    177       device_array.begin(); info != device_array.end(); ++info) {
    178     devices.push_back(FromStreamDeviceInfo(*info));
    179   }
    180   callback.Run(request_id, devices);
    181 }
    182 
    183 void PepperMediaDeviceManager::OnDeviceOpened(
    184     int request_id,
    185     const std::string& label,
    186     const StreamDeviceInfo& device_info) {
    187   NotifyDeviceOpened(request_id, true, label);
    188 }
    189 
    190 void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id) {
    191   NotifyDeviceOpened(request_id, false, std::string());
    192 }
    193 
    194 // static
    195 MediaStreamType PepperMediaDeviceManager::FromPepperDeviceType(
    196     PP_DeviceType_Dev type) {
    197   switch (type) {
    198     case PP_DEVICETYPE_DEV_INVALID:
    199       return MEDIA_NO_SERVICE;
    200     case PP_DEVICETYPE_DEV_AUDIOCAPTURE:
    201       return MEDIA_DEVICE_AUDIO_CAPTURE;
    202     case PP_DEVICETYPE_DEV_VIDEOCAPTURE:
    203       return MEDIA_DEVICE_VIDEO_CAPTURE;
    204     default:
    205       NOTREACHED();
    206       return MEDIA_NO_SERVICE;
    207   }
    208 }
    209 
    210 // static
    211 PP_DeviceType_Dev PepperMediaDeviceManager::FromMediaStreamType(
    212     MediaStreamType type) {
    213   switch (type) {
    214     case MEDIA_NO_SERVICE:
    215       return PP_DEVICETYPE_DEV_INVALID;
    216     case MEDIA_DEVICE_AUDIO_CAPTURE:
    217       return PP_DEVICETYPE_DEV_AUDIOCAPTURE;
    218     case MEDIA_DEVICE_VIDEO_CAPTURE:
    219       return PP_DEVICETYPE_DEV_VIDEOCAPTURE;
    220     default:
    221       NOTREACHED();
    222       return PP_DEVICETYPE_DEV_INVALID;
    223   }
    224 }
    225 
    226 void PepperMediaDeviceManager::NotifyDeviceOpened(
    227     int request_id,
    228     bool succeeded,
    229     const std::string& label) {
    230   OpenCallbackMap::iterator iter = open_callbacks_.find(request_id);
    231   if (iter == open_callbacks_.end()) {
    232     // The callback may have been unregistered.
    233     return;
    234   }
    235 
    236   OpenDeviceCallback callback = iter->second;
    237   open_callbacks_.erase(iter);
    238 
    239   callback.Run(request_id, succeeded, label);
    240 }
    241 
    242 RenderViewImpl* PepperMediaDeviceManager::GetRenderViewImpl() {
    243   return static_cast<RenderViewImpl*>(render_view());
    244 }
    245 
    246 }  // namespace content
    247