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