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