Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / pepper_media_device_manager.cc
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_frame_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   // 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;
24 }
25
26 }  // namespace
27
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();
36 }
37
38 PepperMediaDeviceManager::PepperMediaDeviceManager(RenderFrame* render_frame)
39     : RenderFrameObserver(render_frame),
40       RenderFrameObserverTracker<PepperMediaDeviceManager>(render_frame),
41       next_id_(1) {}
42
43 PepperMediaDeviceManager::~PepperMediaDeviceManager() {
44   DCHECK(enumerate_callbacks_.empty());
45   DCHECK(open_callbacks_.empty());
46 }
47
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_++;
54
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
69
70   return request_id;
71 }
72
73 void PepperMediaDeviceManager::StopEnumerateDevices(int request_id) {
74   enumerate_callbacks_.erase(request_id);
75
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
85 }
86
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
96 }
97
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_++;
104
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
119
120   return request_id;
121 }
122
123 void PepperMediaDeviceManager::CancelOpenDevice(int request_id) {
124   open_callbacks_.erase(request_id);
125
126 #if defined(ENABLE_WEBRTC)
127   GetMediaStreamDispatcher()->CancelOpenDevice(request_id, AsWeakPtr());
128 #endif
129 }
130
131 void PepperMediaDeviceManager::CloseDevice(const std::string& label) {
132 #if defined(ENABLE_WEBRTC)
133   GetMediaStreamDispatcher()->CloseDevice(label);
134 #endif
135 }
136
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;
148   }
149 #else
150   return 0;
151 #endif
152 }
153
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) {}
159
160 void PepperMediaDeviceManager::OnStreamGenerationFailed(
161     int request_id,
162     content::MediaStreamRequestResult result) {}
163
164 void PepperMediaDeviceManager::OnDeviceStopped(
165     const std::string& label,
166     const StreamDeviceInfo& device_info) {}
167
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;
176   }
177
178   EnumerateDevicesCallback callback = iter->second;
179
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));
186   }
187   callback.Run(request_id, devices);
188 }
189
190 void PepperMediaDeviceManager::OnDeviceOpened(
191     int request_id,
192     const std::string& label,
193     const StreamDeviceInfo& device_info) {
194   NotifyDeviceOpened(request_id, true, label);
195 }
196
197 void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id) {
198   NotifyDeviceOpened(request_id, false, std::string());
199 }
200
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;
214   }
215 }
216
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;
230   }
231 }
232
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;
240   }
241
242   OpenDeviceCallback callback = iter->second;
243   open_callbacks_.erase(iter);
244
245   callback.Run(request_id, succeeded, label);
246 }
247
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;
255 }
256
257 }  // namespace content