Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / renderer / pepper / pepper_media_device_manager.cc
blob676b2fb44b931b0da3b0f01a89dc5404953cafe6
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"
12 namespace content {
14 namespace {
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);
23 return data;
26 } // namespace
28 base::WeakPtr<PepperMediaDeviceManager>
29 PepperMediaDeviceManager::GetForRenderFrame(
30 RenderFrame* render_frame) {
31 PepperMediaDeviceManager* handler =
32 PepperMediaDeviceManager::Get(render_frame);
33 if (!handler)
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),
41 next_id_(1) {}
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(
57 request_id,
58 AsWeakPtr(),
59 PepperMediaDeviceManager::FromPepperDeviceType(type),
60 document_url.GetOrigin());
61 #else
62 base::MessageLoop::current()->PostTask(
63 FROM_HERE,
64 base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated,
65 AsWeakPtr(),
66 request_id,
67 StreamDeviceInfoArray()));
68 #endif
70 return request_id;
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(
80 FROM_HERE,
81 base::Bind(&PepperMediaDeviceManager::StopEnumerateDevicesDelayed,
82 AsWeakPtr(),
83 request_id));
84 #endif
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.
93 if (render_frame())
94 GetMediaStreamDispatcher()->StopEnumerateDevices(request_id, AsWeakPtr());
95 #endif
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(
107 request_id,
108 AsWeakPtr(),
109 device_id,
110 PepperMediaDeviceManager::FromPepperDeviceType(type),
111 document_url.GetOrigin());
112 #else
113 base::MessageLoop::current()->PostTask(
114 FROM_HERE,
115 base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed,
116 AsWeakPtr(),
117 request_id));
118 #endif
120 return request_id;
123 void PepperMediaDeviceManager::CancelOpenDevice(int request_id) {
124 open_callbacks_.erase(request_id);
126 #if defined(ENABLE_WEBRTC)
127 GetMediaStreamDispatcher()->CancelOpenDevice(request_id, AsWeakPtr());
128 #endif
131 void PepperMediaDeviceManager::CloseDevice(const std::string& label) {
132 #if defined(ENABLE_WEBRTC)
133 GetMediaStreamDispatcher()->CloseDevice(label);
134 #endif
137 int PepperMediaDeviceManager::GetSessionID(PP_DeviceType_Dev type,
138 const std::string& label) {
139 #if defined(ENABLE_WEBRTC)
140 switch (type) {
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);
145 default:
146 NOTREACHED();
147 return 0;
149 #else
150 return 0;
151 #endif
154 void PepperMediaDeviceManager::OnStreamGenerated(
155 int request_id,
156 const std::string& label,
157 const StreamDeviceInfoArray& audio_device_array,
158 const StreamDeviceInfoArray& video_device_array) {}
160 void PepperMediaDeviceManager::OnStreamGenerationFailed(
161 int request_id,
162 content::MediaStreamRequestResult result) {}
164 void PepperMediaDeviceManager::OnDeviceStopped(
165 const std::string& label,
166 const StreamDeviceInfo& device_info) {}
168 void PepperMediaDeviceManager::OnDevicesEnumerated(
169 int request_id,
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.
175 return;
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();
184 ++info) {
185 devices.push_back(FromStreamDeviceInfo(*info));
187 callback.Run(request_id, devices);
190 void PepperMediaDeviceManager::OnDeviceOpened(
191 int request_id,
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());
201 // static
202 MediaStreamType PepperMediaDeviceManager::FromPepperDeviceType(
203 PP_DeviceType_Dev type) {
204 switch (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;
211 default:
212 NOTREACHED();
213 return MEDIA_NO_SERVICE;
217 // static
218 PP_DeviceType_Dev PepperMediaDeviceManager::FromMediaStreamType(
219 MediaStreamType type) {
220 switch (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;
227 default:
228 NOTREACHED();
229 return PP_DEVICETYPE_DEV_INVALID;
233 void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id,
234 bool succeeded,
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.
239 return;
242 OpenDeviceCallback callback = iter->second;
243 open_callbacks_.erase(iter);
245 callback.Run(request_id, succeeded, label);
248 MediaStreamDispatcher* PepperMediaDeviceManager::GetMediaStreamDispatcher()
249 const {
250 DCHECK(render_frame());
251 MediaStreamDispatcher* const dispatcher =
252 static_cast<RenderFrameImpl*>(render_frame())->GetMediaStreamDispatcher();
253 DCHECK(dispatcher);
254 return dispatcher;
257 } // namespace content