| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/pepper/pepper_media_device_manager.h" | 5 #include "content/renderer/pepper/pepper_media_device_manager.h" |
| 6 | 6 |
| 7 #include "base/location.h" | 7 #include "base/location.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
| 10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
| 11 #include "content/renderer/media/media_devices_event_dispatcher.h" |
| 11 #include "content/renderer/media/media_stream_dispatcher.h" | 12 #include "content/renderer/media/media_stream_dispatcher.h" |
| 12 #include "content/renderer/render_frame_impl.h" | 13 #include "content/renderer/render_frame_impl.h" |
| 13 #include "ppapi/shared_impl/ppb_device_ref_shared.h" | 14 #include "ppapi/shared_impl/ppb_device_ref_shared.h" |
| 15 #include "services/service_manager/public/cpp/interface_provider.h" |
| 14 | 16 |
| 15 namespace content { | 17 namespace content { |
| 16 | 18 |
| 17 namespace { | 19 namespace { |
| 18 | 20 |
| 19 ppapi::DeviceRefData FromStreamDeviceInfo(const StreamDeviceInfo& info) { | 21 PP_DeviceType_Dev FromMediaDeviceType(MediaDeviceType type) { |
| 22 switch (type) { |
| 23 case MEDIA_DEVICE_TYPE_AUDIO_INPUT: |
| 24 return PP_DEVICETYPE_DEV_AUDIOCAPTURE; |
| 25 case MEDIA_DEVICE_TYPE_VIDEO_INPUT: |
| 26 return PP_DEVICETYPE_DEV_VIDEOCAPTURE; |
| 27 default: |
| 28 NOTREACHED(); |
| 29 return PP_DEVICETYPE_DEV_INVALID; |
| 30 } |
| 31 } |
| 32 |
| 33 MediaDeviceType ToMediaDeviceType(PP_DeviceType_Dev type) { |
| 34 switch (type) { |
| 35 case PP_DEVICETYPE_DEV_AUDIOCAPTURE: |
| 36 return MEDIA_DEVICE_TYPE_AUDIO_INPUT; |
| 37 case PP_DEVICETYPE_DEV_VIDEOCAPTURE: |
| 38 return MEDIA_DEVICE_TYPE_VIDEO_INPUT; |
| 39 default: |
| 40 NOTREACHED(); |
| 41 return MEDIA_DEVICE_TYPE_AUDIO_OUTPUT; |
| 42 } |
| 43 } |
| 44 |
| 45 ppapi::DeviceRefData FromMediaDeviceInfo(MediaDeviceType type, |
| 46 const MediaDeviceInfo& info) { |
| 20 ppapi::DeviceRefData data; | 47 ppapi::DeviceRefData data; |
| 21 data.id = info.device.id; | 48 data.id = info.device_id; |
| 22 // Some Flash content can't handle an empty string, so stick a space in to | 49 // Some Flash content can't handle an empty string, so stick a space in to |
| 23 // make them happy. See crbug.com/408404. | 50 // make them happy. See crbug.com/408404. |
| 24 data.name = info.device.name.empty() ? std::string(" ") : info.device.name; | 51 data.name = info.label.empty() ? std::string(" ") : info.label; |
| 25 data.type = PepperMediaDeviceManager::FromMediaStreamType(info.device.type); | 52 data.type = FromMediaDeviceType(type); |
| 26 return data; | 53 return data; |
| 27 } | 54 } |
| 28 | 55 |
| 29 } // namespace | 56 } // namespace |
| 30 | 57 |
| 31 base::WeakPtr<PepperMediaDeviceManager> | 58 base::WeakPtr<PepperMediaDeviceManager> |
| 32 PepperMediaDeviceManager::GetForRenderFrame( | 59 PepperMediaDeviceManager::GetForRenderFrame( |
| 33 RenderFrame* render_frame) { | 60 RenderFrame* render_frame) { |
| 34 PepperMediaDeviceManager* handler = | 61 PepperMediaDeviceManager* handler = |
| 35 PepperMediaDeviceManager::Get(render_frame); | 62 PepperMediaDeviceManager::Get(render_frame); |
| 36 if (!handler) | 63 if (!handler) |
| 37 handler = new PepperMediaDeviceManager(render_frame); | 64 handler = new PepperMediaDeviceManager(render_frame); |
| 38 return handler->AsWeakPtr(); | 65 return handler->AsWeakPtr(); |
| 39 } | 66 } |
| 40 | 67 |
| 41 PepperMediaDeviceManager::PepperMediaDeviceManager(RenderFrame* render_frame) | 68 PepperMediaDeviceManager::PepperMediaDeviceManager(RenderFrame* render_frame) |
| 42 : RenderFrameObserver(render_frame), | 69 : RenderFrameObserver(render_frame), |
| 43 RenderFrameObserverTracker<PepperMediaDeviceManager>(render_frame), | 70 RenderFrameObserverTracker<PepperMediaDeviceManager>(render_frame), |
| 44 next_id_(1) {} | 71 next_id_(1) {} |
| 45 | 72 |
| 46 PepperMediaDeviceManager::~PepperMediaDeviceManager() { | 73 PepperMediaDeviceManager::~PepperMediaDeviceManager() { |
| 47 DCHECK(enumerate_callbacks_.empty()); | |
| 48 DCHECK(open_callbacks_.empty()); | 74 DCHECK(open_callbacks_.empty()); |
| 49 } | 75 } |
| 50 | 76 |
| 51 int PepperMediaDeviceManager::EnumerateDevices( | 77 void PepperMediaDeviceManager::EnumerateDevices( |
| 52 PP_DeviceType_Dev type, | 78 PP_DeviceType_Dev type, |
| 53 const GURL& document_url, | 79 const GURL& document_url, |
| 54 const EnumerateDevicesCallback& callback) { | 80 const DevicesCallback& callback) { |
| 55 enumerate_callbacks_[next_id_] = callback; | |
| 56 int request_id = next_id_++; | |
| 57 | |
| 58 #if defined(ENABLE_WEBRTC) | 81 #if defined(ENABLE_WEBRTC) |
| 59 GetMediaStreamDispatcher()->EnumerateDevices( | 82 bool request_audio_input = type == PP_DEVICETYPE_DEV_AUDIOCAPTURE; |
| 60 request_id, AsWeakPtr(), | 83 bool request_video_input = type == PP_DEVICETYPE_DEV_VIDEOCAPTURE; |
| 61 PepperMediaDeviceManager::FromPepperDeviceType(type), | 84 GetMediaDevicesDispatcher()->EnumerateDevices( |
| 62 url::Origin(document_url.GetOrigin())); | 85 request_audio_input, request_video_input, false /* audio_output */, |
| 86 url::Origin(document_url.GetOrigin()), |
| 87 base::Bind(&PepperMediaDeviceManager::DevicesEnumerated, AsWeakPtr(), |
| 88 callback, ToMediaDeviceType(type))); |
| 63 #else | 89 #else |
| 64 base::ThreadTaskRunnerHandle::Get()->PostTask( | 90 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 65 FROM_HERE, base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated, | |
| 66 AsWeakPtr(), request_id, StreamDeviceInfoArray())); | |
| 67 #endif | |
| 68 | |
| 69 return request_id; | |
| 70 } | |
| 71 | |
| 72 void PepperMediaDeviceManager::StopEnumerateDevices(int request_id) { | |
| 73 enumerate_callbacks_.erase(request_id); | |
| 74 | |
| 75 #if defined(ENABLE_WEBRTC) | |
| 76 // Need to post task since this function might be called inside the callback | |
| 77 // of EnumerateDevices. | |
| 78 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 79 FROM_HERE, | 91 FROM_HERE, |
| 80 base::Bind(&PepperMediaDeviceManager::StopEnumerateDevicesDelayed, | 92 base::Bind(&PepperMediaDeviceManager::DevicesEnumerated, AsWeakPtr(), |
| 81 AsWeakPtr(), request_id)); | 93 callback, ToMediaDeviceType(type), MediaDeviceInfoArray())); |
| 82 #endif | 94 #endif |
| 83 } | 95 } |
| 84 | 96 |
| 85 void PepperMediaDeviceManager::StopEnumerateDevicesDelayed(int request_id) { | 97 uint32_t PepperMediaDeviceManager::StartMonitoringDevices( |
| 98 PP_DeviceType_Dev type, |
| 99 const GURL& document_url, |
| 100 const DevicesCallback& callback) { |
| 86 #if defined(ENABLE_WEBRTC) | 101 #if defined(ENABLE_WEBRTC) |
| 87 // This method is being invoked by the message loop at some unknown | 102 base::WeakPtr<MediaDevicesEventDispatcher> event_dispatcher = |
| 88 // point-in-time after StopEnumerateDevices(). Therefore, check that | 103 MediaDevicesEventDispatcher::GetForRenderFrame(render_frame()); |
| 89 // render_frame() is not NULL, in order to guarantee | 104 return event_dispatcher->SubscribeDeviceChangeNotifications( |
| 90 // GetMediaStreamDispatcher() won't return NULL. | 105 ToMediaDeviceType(type), url::Origin(document_url.GetOrigin()), |
| 91 if (render_frame()) | 106 base::Bind(&PepperMediaDeviceManager::DevicesChanged, AsWeakPtr(), |
| 92 GetMediaStreamDispatcher()->StopEnumerateDevices(request_id, AsWeakPtr()); | 107 callback)); |
| 108 #else |
| 109 return 0; |
| 93 #endif | 110 #endif |
| 94 } | 111 } |
| 95 | 112 |
| 113 void PepperMediaDeviceManager::StopMonitoringDevices(PP_DeviceType_Dev type, |
| 114 uint32_t subscription_id) { |
| 115 #if defined(ENABLE_WEBRTC) |
| 116 base::WeakPtr<MediaDevicesEventDispatcher> event_dispatcher = |
| 117 MediaDevicesEventDispatcher::GetForRenderFrame(render_frame()); |
| 118 event_dispatcher->UnsubscribeDeviceChangeNotifications( |
| 119 ToMediaDeviceType(type), subscription_id); |
| 120 #endif |
| 121 } |
| 122 |
| 96 int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type, | 123 int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type, |
| 97 const std::string& device_id, | 124 const std::string& device_id, |
| 98 const GURL& document_url, | 125 const GURL& document_url, |
| 99 const OpenDeviceCallback& callback) { | 126 const OpenDeviceCallback& callback) { |
| 100 open_callbacks_[next_id_] = callback; | 127 open_callbacks_[next_id_] = callback; |
| 101 int request_id = next_id_++; | 128 int request_id = next_id_++; |
| 102 | 129 |
| 103 #if defined(ENABLE_WEBRTC) | 130 #if defined(ENABLE_WEBRTC) |
| 104 GetMediaStreamDispatcher()->OpenDevice( | 131 GetMediaStreamDispatcher()->OpenDevice( |
| 105 request_id, AsWeakPtr(), device_id, | 132 request_id, AsWeakPtr(), device_id, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 int request_id, | 182 int request_id, |
| 156 content::MediaStreamRequestResult result) {} | 183 content::MediaStreamRequestResult result) {} |
| 157 | 184 |
| 158 void PepperMediaDeviceManager::OnDeviceStopped( | 185 void PepperMediaDeviceManager::OnDeviceStopped( |
| 159 const std::string& label, | 186 const std::string& label, |
| 160 const StreamDeviceInfo& device_info) {} | 187 const StreamDeviceInfo& device_info) {} |
| 161 | 188 |
| 162 void PepperMediaDeviceManager::OnDevicesEnumerated( | 189 void PepperMediaDeviceManager::OnDevicesEnumerated( |
| 163 int request_id, | 190 int request_id, |
| 164 const StreamDeviceInfoArray& device_array) { | 191 const StreamDeviceInfoArray& device_array) { |
| 165 EnumerateCallbackMap::iterator iter = enumerate_callbacks_.find(request_id); | 192 NOTREACHED(); |
| 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 = device_array.begin(); | |
| 177 info != device_array.end(); | |
| 178 ++info) { | |
| 179 devices.push_back(FromStreamDeviceInfo(*info)); | |
| 180 } | |
| 181 callback.Run(request_id, devices); | |
| 182 } | 193 } |
| 183 | 194 |
| 184 void PepperMediaDeviceManager::OnDeviceOpened( | 195 void PepperMediaDeviceManager::OnDeviceOpened( |
| 185 int request_id, | 196 int request_id, |
| 186 const std::string& label, | 197 const std::string& label, |
| 187 const StreamDeviceInfo& device_info) { | 198 const StreamDeviceInfo& device_info) { |
| 188 NotifyDeviceOpened(request_id, true, label); | 199 NotifyDeviceOpened(request_id, true, label); |
| 189 } | 200 } |
| 190 | 201 |
| 191 void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id) { | 202 void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 203 case PP_DEVICETYPE_DEV_AUDIOCAPTURE: | 214 case PP_DEVICETYPE_DEV_AUDIOCAPTURE: |
| 204 return MEDIA_DEVICE_AUDIO_CAPTURE; | 215 return MEDIA_DEVICE_AUDIO_CAPTURE; |
| 205 case PP_DEVICETYPE_DEV_VIDEOCAPTURE: | 216 case PP_DEVICETYPE_DEV_VIDEOCAPTURE: |
| 206 return MEDIA_DEVICE_VIDEO_CAPTURE; | 217 return MEDIA_DEVICE_VIDEO_CAPTURE; |
| 207 default: | 218 default: |
| 208 NOTREACHED(); | 219 NOTREACHED(); |
| 209 return MEDIA_NO_SERVICE; | 220 return MEDIA_NO_SERVICE; |
| 210 } | 221 } |
| 211 } | 222 } |
| 212 | 223 |
| 213 // static | |
| 214 PP_DeviceType_Dev PepperMediaDeviceManager::FromMediaStreamType( | |
| 215 MediaStreamType type) { | |
| 216 switch (type) { | |
| 217 case MEDIA_NO_SERVICE: | |
| 218 return PP_DEVICETYPE_DEV_INVALID; | |
| 219 case MEDIA_DEVICE_AUDIO_CAPTURE: | |
| 220 return PP_DEVICETYPE_DEV_AUDIOCAPTURE; | |
| 221 case MEDIA_DEVICE_VIDEO_CAPTURE: | |
| 222 return PP_DEVICETYPE_DEV_VIDEOCAPTURE; | |
| 223 default: | |
| 224 NOTREACHED(); | |
| 225 return PP_DEVICETYPE_DEV_INVALID; | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id, | 224 void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id, |
| 230 bool succeeded, | 225 bool succeeded, |
| 231 const std::string& label) { | 226 const std::string& label) { |
| 232 OpenCallbackMap::iterator iter = open_callbacks_.find(request_id); | 227 OpenCallbackMap::iterator iter = open_callbacks_.find(request_id); |
| 233 if (iter == open_callbacks_.end()) { | 228 if (iter == open_callbacks_.end()) { |
| 234 // The callback may have been unregistered. | 229 // The callback may have been unregistered. |
| 235 return; | 230 return; |
| 236 } | 231 } |
| 237 | 232 |
| 238 OpenDeviceCallback callback = iter->second; | 233 OpenDeviceCallback callback = iter->second; |
| 239 open_callbacks_.erase(iter); | 234 open_callbacks_.erase(iter); |
| 240 | 235 |
| 241 callback.Run(request_id, succeeded, label); | 236 callback.Run(request_id, succeeded, label); |
| 242 } | 237 } |
| 243 | 238 |
| 239 void PepperMediaDeviceManager::DevicesEnumerated( |
| 240 const DevicesCallback& client_callback, |
| 241 MediaDeviceType type, |
| 242 const std::vector<MediaDeviceInfoArray>& enumeration) { |
| 243 DevicesChanged(client_callback, type, enumeration[type]); |
| 244 } |
| 245 |
| 246 void PepperMediaDeviceManager::DevicesChanged( |
| 247 const DevicesCallback& client_callback, |
| 248 MediaDeviceType type, |
| 249 const MediaDeviceInfoArray& device_infos) { |
| 250 std::vector<ppapi::DeviceRefData> devices; |
| 251 devices.reserve(device_infos.size()); |
| 252 for (const auto& device_info : device_infos) |
| 253 devices.push_back(FromMediaDeviceInfo(type, device_info)); |
| 254 |
| 255 client_callback.Run(devices); |
| 256 } |
| 257 |
| 244 MediaStreamDispatcher* PepperMediaDeviceManager::GetMediaStreamDispatcher() | 258 MediaStreamDispatcher* PepperMediaDeviceManager::GetMediaStreamDispatcher() |
| 245 const { | 259 const { |
| 246 DCHECK(render_frame()); | 260 DCHECK(render_frame()); |
| 247 MediaStreamDispatcher* const dispatcher = | 261 MediaStreamDispatcher* const dispatcher = |
| 248 static_cast<RenderFrameImpl*>(render_frame())->GetMediaStreamDispatcher(); | 262 static_cast<RenderFrameImpl*>(render_frame())->GetMediaStreamDispatcher(); |
| 249 DCHECK(dispatcher); | 263 DCHECK(dispatcher); |
| 250 return dispatcher; | 264 return dispatcher; |
| 251 } | 265 } |
| 252 | 266 |
| 267 const ::mojom::MediaDevicesDispatcherHostPtr& |
| 268 PepperMediaDeviceManager::GetMediaDevicesDispatcher() { |
| 269 if (!media_devices_dispatcher_) { |
| 270 DCHECK(render_frame()); |
| 271 render_frame()->GetRemoteInterfaces()->GetInterface( |
| 272 mojo::GetProxy(&media_devices_dispatcher_)); |
| 273 } |
| 274 |
| 275 return media_devices_dispatcher_; |
| 276 } |
| 277 |
| 253 void PepperMediaDeviceManager::OnDestruct() { | 278 void PepperMediaDeviceManager::OnDestruct() { |
| 254 delete this; | 279 delete this; |
| 255 } | 280 } |
| 256 | 281 |
| 257 } // namespace content | 282 } // namespace content |
| OLD | NEW |