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.
5 #include "content/renderer/pepper/pepper_media_device_manager.h"
7 #include "base/location.h"
8 #include "base/logging.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "content/renderer/media/media_stream_dispatcher.h"
12 #include "content/renderer/render_frame_impl.h"
13 #include "ppapi/shared_impl/ppb_device_ref_shared.h"
19 ppapi::DeviceRefData
FromStreamDeviceInfo(const StreamDeviceInfo
& info
) {
20 ppapi::DeviceRefData data
;
21 data
.id
= info
.device
.id
;
22 // Some Flash content can't handle an empty string, so stick a space in to
23 // make them happy. See crbug.com/408404.
24 data
.name
= info
.device
.name
.empty() ? std::string(" ") : info
.device
.name
;
25 data
.type
= PepperMediaDeviceManager::FromMediaStreamType(info
.device
.type
);
31 base::WeakPtr
<PepperMediaDeviceManager
>
32 PepperMediaDeviceManager::GetForRenderFrame(
33 RenderFrame
* render_frame
) {
34 PepperMediaDeviceManager
* handler
=
35 PepperMediaDeviceManager::Get(render_frame
);
37 handler
= new PepperMediaDeviceManager(render_frame
);
38 return handler
->AsWeakPtr();
41 PepperMediaDeviceManager::PepperMediaDeviceManager(RenderFrame
* render_frame
)
42 : RenderFrameObserver(render_frame
),
43 RenderFrameObserverTracker
<PepperMediaDeviceManager
>(render_frame
),
46 PepperMediaDeviceManager::~PepperMediaDeviceManager() {
47 DCHECK(enumerate_callbacks_
.empty());
48 DCHECK(open_callbacks_
.empty());
51 int PepperMediaDeviceManager::EnumerateDevices(
52 PP_DeviceType_Dev type
,
53 const GURL
& document_url
,
54 const EnumerateDevicesCallback
& callback
) {
55 enumerate_callbacks_
[next_id_
] = callback
;
56 int request_id
= next_id_
++;
58 #if defined(ENABLE_WEBRTC)
59 GetMediaStreamDispatcher()->EnumerateDevices(
62 PepperMediaDeviceManager::FromPepperDeviceType(type
),
63 document_url
.GetOrigin());
65 base::MessageLoop::current()->PostTask(
67 base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated
,
70 StreamDeviceInfoArray()));
76 void PepperMediaDeviceManager::StopEnumerateDevices(int request_id
) {
77 enumerate_callbacks_
.erase(request_id
);
79 #if defined(ENABLE_WEBRTC)
80 // Need to post task since this function might be called inside the callback
81 // of EnumerateDevices.
82 base::ThreadTaskRunnerHandle::Get()->PostTask(
84 base::Bind(&PepperMediaDeviceManager::StopEnumerateDevicesDelayed
,
85 AsWeakPtr(), request_id
));
89 void PepperMediaDeviceManager::StopEnumerateDevicesDelayed(int request_id
) {
90 #if defined(ENABLE_WEBRTC)
91 // This method is being invoked by the message loop at some unknown
92 // point-in-time after StopEnumerateDevices(). Therefore, check that
93 // render_frame() is not NULL, in order to guarantee
94 // GetMediaStreamDispatcher() won't return NULL.
96 GetMediaStreamDispatcher()->StopEnumerateDevices(request_id
, AsWeakPtr());
100 int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type
,
101 const std::string
& device_id
,
102 const GURL
& document_url
,
103 const OpenDeviceCallback
& callback
) {
104 open_callbacks_
[next_id_
] = callback
;
105 int request_id
= next_id_
++;
107 #if defined(ENABLE_WEBRTC)
108 GetMediaStreamDispatcher()->OpenDevice(
112 PepperMediaDeviceManager::FromPepperDeviceType(type
),
113 document_url
.GetOrigin());
115 base::MessageLoop::current()->PostTask(
117 base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed
,
125 void PepperMediaDeviceManager::CancelOpenDevice(int request_id
) {
126 open_callbacks_
.erase(request_id
);
128 #if defined(ENABLE_WEBRTC)
129 GetMediaStreamDispatcher()->CancelOpenDevice(request_id
, AsWeakPtr());
133 void PepperMediaDeviceManager::CloseDevice(const std::string
& label
) {
134 #if defined(ENABLE_WEBRTC)
135 GetMediaStreamDispatcher()->CloseDevice(label
);
139 int PepperMediaDeviceManager::GetSessionID(PP_DeviceType_Dev type
,
140 const std::string
& label
) {
141 #if defined(ENABLE_WEBRTC)
143 case PP_DEVICETYPE_DEV_AUDIOCAPTURE
:
144 return GetMediaStreamDispatcher()->audio_session_id(label
, 0);
145 case PP_DEVICETYPE_DEV_VIDEOCAPTURE
:
146 return GetMediaStreamDispatcher()->video_session_id(label
, 0);
156 void PepperMediaDeviceManager::OnStreamGenerated(
158 const std::string
& label
,
159 const StreamDeviceInfoArray
& audio_device_array
,
160 const StreamDeviceInfoArray
& video_device_array
) {}
162 void PepperMediaDeviceManager::OnStreamGenerationFailed(
164 content::MediaStreamRequestResult result
) {}
166 void PepperMediaDeviceManager::OnDeviceStopped(
167 const std::string
& label
,
168 const StreamDeviceInfo
& device_info
) {}
170 void PepperMediaDeviceManager::OnDevicesEnumerated(
172 const StreamDeviceInfoArray
& device_array
) {
173 EnumerateCallbackMap::iterator iter
= enumerate_callbacks_
.find(request_id
);
174 if (iter
== enumerate_callbacks_
.end()) {
175 // This might be enumerated result sent before StopEnumerateDevices is
176 // called since EnumerateDevices is persistent request.
180 EnumerateDevicesCallback callback
= iter
->second
;
182 std::vector
<ppapi::DeviceRefData
> devices
;
183 devices
.reserve(device_array
.size());
184 for (StreamDeviceInfoArray::const_iterator info
= device_array
.begin();
185 info
!= device_array
.end();
187 devices
.push_back(FromStreamDeviceInfo(*info
));
189 callback
.Run(request_id
, devices
);
192 void PepperMediaDeviceManager::OnDeviceOpened(
194 const std::string
& label
,
195 const StreamDeviceInfo
& device_info
) {
196 NotifyDeviceOpened(request_id
, true, label
);
199 void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id
) {
200 NotifyDeviceOpened(request_id
, false, std::string());
204 MediaStreamType
PepperMediaDeviceManager::FromPepperDeviceType(
205 PP_DeviceType_Dev type
) {
207 case PP_DEVICETYPE_DEV_INVALID
:
208 return MEDIA_NO_SERVICE
;
209 case PP_DEVICETYPE_DEV_AUDIOCAPTURE
:
210 return MEDIA_DEVICE_AUDIO_CAPTURE
;
211 case PP_DEVICETYPE_DEV_VIDEOCAPTURE
:
212 return MEDIA_DEVICE_VIDEO_CAPTURE
;
215 return MEDIA_NO_SERVICE
;
220 PP_DeviceType_Dev
PepperMediaDeviceManager::FromMediaStreamType(
221 MediaStreamType type
) {
223 case MEDIA_NO_SERVICE
:
224 return PP_DEVICETYPE_DEV_INVALID
;
225 case MEDIA_DEVICE_AUDIO_CAPTURE
:
226 return PP_DEVICETYPE_DEV_AUDIOCAPTURE
;
227 case MEDIA_DEVICE_VIDEO_CAPTURE
:
228 return PP_DEVICETYPE_DEV_VIDEOCAPTURE
;
231 return PP_DEVICETYPE_DEV_INVALID
;
235 void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id
,
237 const std::string
& label
) {
238 OpenCallbackMap::iterator iter
= open_callbacks_
.find(request_id
);
239 if (iter
== open_callbacks_
.end()) {
240 // The callback may have been unregistered.
244 OpenDeviceCallback callback
= iter
->second
;
245 open_callbacks_
.erase(iter
);
247 callback
.Run(request_id
, succeeded
, label
);
250 MediaStreamDispatcher
* PepperMediaDeviceManager::GetMediaStreamDispatcher()
252 DCHECK(render_frame());
253 MediaStreamDispatcher
* const dispatcher
=
254 static_cast<RenderFrameImpl
*>(render_frame())->GetMediaStreamDispatcher();
259 } // namespace content