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
FromStreamDeviceInfo(const StreamDeviceInfo & info)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
GetForRenderView(RenderView * render_view)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
PepperMediaDeviceManager(RenderView * render_view)35 PepperMediaDeviceManager::PepperMediaDeviceManager(RenderView* render_view)
36 : RenderViewObserver(render_view),
37 RenderViewObserverTracker<PepperMediaDeviceManager>(render_view),
38 next_id_(1) {}
39
~PepperMediaDeviceManager()40 PepperMediaDeviceManager::~PepperMediaDeviceManager() {
41 DCHECK(enumerate_callbacks_.empty());
42 DCHECK(open_callbacks_.empty());
43 }
44
EnumerateDevices(PP_DeviceType_Dev type,const GURL & document_url,const EnumerateDevicesCallback & callback)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
StopEnumerateDevices(int request_id)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
OpenDevice(PP_DeviceType_Dev type,const std::string & device_id,const GURL & document_url,const OpenDeviceCallback & callback)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
CancelOpenDevice(int request_id)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
CloseDevice(const std::string & label)120 void PepperMediaDeviceManager::CloseDevice(const std::string& label) {
121 #if defined(ENABLE_WEBRTC)
122 GetRenderViewImpl()->media_stream_dispatcher()->CloseDevice(label);
123 #endif
124 }
125
GetSessionID(PP_DeviceType_Dev type,const std::string & label)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
OnStreamGenerated(int request_id,const std::string & label,const StreamDeviceInfoArray & audio_device_array,const StreamDeviceInfoArray & video_device_array)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
OnStreamGenerationFailed(int request_id,content::MediaStreamRequestResult result)151 void PepperMediaDeviceManager::OnStreamGenerationFailed(
152 int request_id,
153 content::MediaStreamRequestResult result) {}
154
OnDeviceStopped(const std::string & label,const StreamDeviceInfo & device_info)155 void PepperMediaDeviceManager::OnDeviceStopped(
156 const std::string& label,
157 const StreamDeviceInfo& device_info) {}
158
OnDevicesEnumerated(int request_id,const StreamDeviceInfoArray & device_array)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
OnDeviceOpened(int request_id,const std::string & label,const StreamDeviceInfo & device_info)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
OnDeviceOpenFailed(int request_id)188 void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id) {
189 NotifyDeviceOpened(request_id, false, std::string());
190 }
191
192 // static
FromPepperDeviceType(PP_DeviceType_Dev type)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
FromMediaStreamType(MediaStreamType type)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
NotifyDeviceOpened(int request_id,bool succeeded,const std::string & label)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
GetRenderViewImpl()239 RenderViewImpl* PepperMediaDeviceManager::GetRenderViewImpl() {
240 return static_cast<RenderViewImpl*>(render_view());
241 }
242
243 } // namespace content
244