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/logging.h"
8 #include "content/renderer/media/media_stream_dispatcher.h"
9 #include "content/renderer/render_frame_impl.h"
10 #include "ppapi/shared_impl/ppb_device_ref_shared.h"
16 ppapi::DeviceRefData
FromStreamDeviceInfo(const StreamDeviceInfo
& info
) {
17 ppapi::DeviceRefData data
;
18 data
.id
= info
.device
.id
;
19 // Some Flash content can't handle an empty string, so stick a space in to
20 // make them happy. See crbug.com/408404.
21 data
.name
= info
.device
.name
.empty() ? std::string(" ") : info
.device
.name
;
22 data
.type
= PepperMediaDeviceManager::FromMediaStreamType(info
.device
.type
);
28 base::WeakPtr
<PepperMediaDeviceManager
>
29 PepperMediaDeviceManager::GetForRenderFrame(
30 RenderFrame
* render_frame
) {
31 PepperMediaDeviceManager
* handler
=
32 PepperMediaDeviceManager::Get(render_frame
);
34 handler
= new PepperMediaDeviceManager(render_frame
);
35 return handler
->AsWeakPtr();
38 PepperMediaDeviceManager::PepperMediaDeviceManager(RenderFrame
* render_frame
)
39 : RenderFrameObserver(render_frame
),
40 RenderFrameObserverTracker
<PepperMediaDeviceManager
>(render_frame
),
43 PepperMediaDeviceManager::~PepperMediaDeviceManager() {
44 DCHECK(enumerate_callbacks_
.empty());
45 DCHECK(open_callbacks_
.empty());
48 int PepperMediaDeviceManager::EnumerateDevices(
49 PP_DeviceType_Dev type
,
50 const GURL
& document_url
,
51 const EnumerateDevicesCallback
& callback
) {
52 enumerate_callbacks_
[next_id_
] = callback
;
53 int request_id
= next_id_
++;
55 #if defined(ENABLE_WEBRTC)
56 GetMediaStreamDispatcher()->EnumerateDevices(
59 PepperMediaDeviceManager::FromPepperDeviceType(type
),
60 document_url
.GetOrigin());
62 base::MessageLoop::current()->PostTask(
64 base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated
,
67 StreamDeviceInfoArray()));
73 void PepperMediaDeviceManager::StopEnumerateDevices(int request_id
) {
74 enumerate_callbacks_
.erase(request_id
);
76 #if defined(ENABLE_WEBRTC)
77 // Need to post task since this function might be called inside the callback
78 // of EnumerateDevices.
79 base::MessageLoop::current()->PostTask(
81 base::Bind(&PepperMediaDeviceManager::StopEnumerateDevicesDelayed
,
87 void PepperMediaDeviceManager::StopEnumerateDevicesDelayed(int request_id
) {
88 #if defined(ENABLE_WEBRTC)
89 // This method is being invoked by the message loop at some unknown
90 // point-in-time after StopEnumerateDevices(). Therefore, check that
91 // render_frame() is not NULL, in order to guarantee
92 // GetMediaStreamDispatcher() won't return NULL.
94 GetMediaStreamDispatcher()->StopEnumerateDevices(request_id
, AsWeakPtr());
98 int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type
,
99 const std::string
& device_id
,
100 const GURL
& document_url
,
101 const OpenDeviceCallback
& callback
) {
102 open_callbacks_
[next_id_
] = callback
;
103 int request_id
= next_id_
++;
105 #if defined(ENABLE_WEBRTC)
106 GetMediaStreamDispatcher()->OpenDevice(
110 PepperMediaDeviceManager::FromPepperDeviceType(type
),
111 document_url
.GetOrigin());
113 base::MessageLoop::current()->PostTask(
115 base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed
,
123 void PepperMediaDeviceManager::CancelOpenDevice(int request_id
) {
124 open_callbacks_
.erase(request_id
);
126 #if defined(ENABLE_WEBRTC)
127 GetMediaStreamDispatcher()->CancelOpenDevice(request_id
, AsWeakPtr());
131 void PepperMediaDeviceManager::CloseDevice(const std::string
& label
) {
132 #if defined(ENABLE_WEBRTC)
133 GetMediaStreamDispatcher()->CloseDevice(label
);
137 int PepperMediaDeviceManager::GetSessionID(PP_DeviceType_Dev type
,
138 const std::string
& label
) {
139 #if defined(ENABLE_WEBRTC)
141 case PP_DEVICETYPE_DEV_AUDIOCAPTURE
:
142 return GetMediaStreamDispatcher()->audio_session_id(label
, 0);
143 case PP_DEVICETYPE_DEV_VIDEOCAPTURE
:
144 return GetMediaStreamDispatcher()->video_session_id(label
, 0);
154 void PepperMediaDeviceManager::OnStreamGenerated(
156 const std::string
& label
,
157 const StreamDeviceInfoArray
& audio_device_array
,
158 const StreamDeviceInfoArray
& video_device_array
) {}
160 void PepperMediaDeviceManager::OnStreamGenerationFailed(
162 content::MediaStreamRequestResult result
) {}
164 void PepperMediaDeviceManager::OnDeviceStopped(
165 const std::string
& label
,
166 const StreamDeviceInfo
& device_info
) {}
168 void PepperMediaDeviceManager::OnDevicesEnumerated(
170 const StreamDeviceInfoArray
& device_array
) {
171 EnumerateCallbackMap::iterator iter
= enumerate_callbacks_
.find(request_id
);
172 if (iter
== enumerate_callbacks_
.end()) {
173 // This might be enumerated result sent before StopEnumerateDevices is
174 // called since EnumerateDevices is persistent request.
178 EnumerateDevicesCallback callback
= iter
->second
;
180 std::vector
<ppapi::DeviceRefData
> devices
;
181 devices
.reserve(device_array
.size());
182 for (StreamDeviceInfoArray::const_iterator info
= device_array
.begin();
183 info
!= device_array
.end();
185 devices
.push_back(FromStreamDeviceInfo(*info
));
187 callback
.Run(request_id
, devices
);
190 void PepperMediaDeviceManager::OnDeviceOpened(
192 const std::string
& label
,
193 const StreamDeviceInfo
& device_info
) {
194 NotifyDeviceOpened(request_id
, true, label
);
197 void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id
) {
198 NotifyDeviceOpened(request_id
, false, std::string());
202 MediaStreamType
PepperMediaDeviceManager::FromPepperDeviceType(
203 PP_DeviceType_Dev type
) {
205 case PP_DEVICETYPE_DEV_INVALID
:
206 return MEDIA_NO_SERVICE
;
207 case PP_DEVICETYPE_DEV_AUDIOCAPTURE
:
208 return MEDIA_DEVICE_AUDIO_CAPTURE
;
209 case PP_DEVICETYPE_DEV_VIDEOCAPTURE
:
210 return MEDIA_DEVICE_VIDEO_CAPTURE
;
213 return MEDIA_NO_SERVICE
;
218 PP_DeviceType_Dev
PepperMediaDeviceManager::FromMediaStreamType(
219 MediaStreamType type
) {
221 case MEDIA_NO_SERVICE
:
222 return PP_DEVICETYPE_DEV_INVALID
;
223 case MEDIA_DEVICE_AUDIO_CAPTURE
:
224 return PP_DEVICETYPE_DEV_AUDIOCAPTURE
;
225 case MEDIA_DEVICE_VIDEO_CAPTURE
:
226 return PP_DEVICETYPE_DEV_VIDEOCAPTURE
;
229 return PP_DEVICETYPE_DEV_INVALID
;
233 void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id
,
235 const std::string
& label
) {
236 OpenCallbackMap::iterator iter
= open_callbacks_
.find(request_id
);
237 if (iter
== open_callbacks_
.end()) {
238 // The callback may have been unregistered.
242 OpenDeviceCallback callback
= iter
->second
;
243 open_callbacks_
.erase(iter
);
245 callback
.Run(request_id
, succeeded
, label
);
248 MediaStreamDispatcher
* PepperMediaDeviceManager::GetMediaStreamDispatcher()
250 DCHECK(render_frame());
251 MediaStreamDispatcher
* const dispatcher
=
252 static_cast<RenderFrameImpl
*>(render_frame())->GetMediaStreamDispatcher();
257 } // namespace content