Upstream version 9.38.198.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   data.name = info.device.name;
20   data.type = PepperMediaDeviceManager::FromMediaStreamType(info.device.type);
21   return data;
22 }
23
24 }  // namespace
25
26 PepperMediaDeviceManager* PepperMediaDeviceManager::GetForRenderFrame(
27     RenderFrame* render_frame) {
28   PepperMediaDeviceManager* handler =
29       PepperMediaDeviceManager::Get(render_frame);
30   if (!handler)
31     handler = new PepperMediaDeviceManager(render_frame);
32   return handler;
33 }
34
35 PepperMediaDeviceManager::PepperMediaDeviceManager(RenderFrame* render_frame)
36     : RenderFrameObserver(render_frame),
37       RenderFrameObserverTracker<PepperMediaDeviceManager>(render_frame),
38       next_id_(1) {}
39
40 PepperMediaDeviceManager::~PepperMediaDeviceManager() {
41   DCHECK(enumerate_callbacks_.empty());
42   DCHECK(open_callbacks_.empty());
43 }
44
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   GetMediaStreamDispatcher()->EnumerateDevices(
54       request_id,
55       AsWeakPtr(),
56       PepperMediaDeviceManager::FromPepperDeviceType(type),
57       document_url.GetOrigin());
58 #else
59   base::MessageLoop::current()->PostTask(
60       FROM_HERE,
61       base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated,
62                  AsWeakPtr(),
63                  request_id,
64                  StreamDeviceInfoArray()));
65 #endif
66
67   return request_id;
68 }
69
70 void PepperMediaDeviceManager::StopEnumerateDevices(int request_id) {
71   enumerate_callbacks_.erase(request_id);
72
73 #if defined(ENABLE_WEBRTC)
74   // Need to post task since this function might be called inside the callback
75   // of EnumerateDevices.
76   base::MessageLoop::current()->PostTask(
77       FROM_HERE,
78       base::Bind(&PepperMediaDeviceManager::StopEnumerateDevicesDelayed,
79                  AsWeakPtr(),
80                  request_id));
81 #endif
82 }
83
84 void PepperMediaDeviceManager::StopEnumerateDevicesDelayed(int request_id) {
85 #if defined(ENABLE_WEBRTC)
86   // This method is being invoked by the message loop at some unknown
87   // point-in-time after StopEnumerateDevices().  Therefore, check that
88   // render_frame() is not NULL, in order to guarantee
89   // GetMediaStreamDispatcher() won't return NULL.
90   if (render_frame())
91     GetMediaStreamDispatcher()->StopEnumerateDevices(request_id, AsWeakPtr());
92 #endif
93 }
94
95 int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type,
96                                          const std::string& device_id,
97                                          const GURL& document_url,
98                                          const OpenDeviceCallback& callback) {
99   open_callbacks_[next_id_] = callback;
100   int request_id = next_id_++;
101
102 #if defined(ENABLE_WEBRTC)
103   GetMediaStreamDispatcher()->OpenDevice(
104       request_id,
105       AsWeakPtr(),
106       device_id,
107       PepperMediaDeviceManager::FromPepperDeviceType(type),
108       document_url.GetOrigin());
109 #else
110   base::MessageLoop::current()->PostTask(
111       FROM_HERE,
112       base::Bind(&PepperMediaDeviceManager::OnDeviceOpenFailed,
113                  AsWeakPtr(),
114                  request_id));
115 #endif
116
117   return request_id;
118 }
119
120 void PepperMediaDeviceManager::CancelOpenDevice(int request_id) {
121   open_callbacks_.erase(request_id);
122
123 #if defined(ENABLE_WEBRTC)
124   GetMediaStreamDispatcher()->CancelOpenDevice(request_id, AsWeakPtr());
125 #endif
126 }
127
128 void PepperMediaDeviceManager::CloseDevice(const std::string& label) {
129 #if defined(ENABLE_WEBRTC)
130   GetMediaStreamDispatcher()->CloseDevice(label);
131 #endif
132 }
133
134 int PepperMediaDeviceManager::GetSessionID(PP_DeviceType_Dev type,
135                                            const std::string& label) {
136 #if defined(ENABLE_WEBRTC)
137   switch (type) {
138     case PP_DEVICETYPE_DEV_AUDIOCAPTURE:
139       return GetMediaStreamDispatcher()->audio_session_id(label, 0);
140     case PP_DEVICETYPE_DEV_VIDEOCAPTURE:
141       return GetMediaStreamDispatcher()->video_session_id(label, 0);
142     default:
143       NOTREACHED();
144       return 0;
145   }
146 #else
147   return 0;
148 #endif
149 }
150
151 void PepperMediaDeviceManager::OnStreamGenerated(
152     int request_id,
153     const std::string& label,
154     const StreamDeviceInfoArray& audio_device_array,
155     const StreamDeviceInfoArray& video_device_array) {}
156
157 void PepperMediaDeviceManager::OnStreamGenerationFailed(
158     int request_id,
159     content::MediaStreamRequestResult result) {}
160
161 void PepperMediaDeviceManager::OnDeviceStopped(
162     const std::string& label,
163     const StreamDeviceInfo& device_info) {}
164
165 void PepperMediaDeviceManager::OnDevicesEnumerated(
166     int request_id,
167     const StreamDeviceInfoArray& device_array) {
168   EnumerateCallbackMap::iterator iter = enumerate_callbacks_.find(request_id);
169   if (iter == enumerate_callbacks_.end()) {
170     // This might be enumerated result sent before StopEnumerateDevices is
171     // called since EnumerateDevices is persistent request.
172     return;
173   }
174
175   EnumerateDevicesCallback callback = iter->second;
176
177   std::vector<ppapi::DeviceRefData> devices;
178   devices.reserve(device_array.size());
179   for (StreamDeviceInfoArray::const_iterator info = device_array.begin();
180        info != device_array.end();
181        ++info) {
182     devices.push_back(FromStreamDeviceInfo(*info));
183   }
184   callback.Run(request_id, devices);
185 }
186
187 void PepperMediaDeviceManager::OnDeviceOpened(
188     int request_id,
189     const std::string& label,
190     const StreamDeviceInfo& device_info) {
191   NotifyDeviceOpened(request_id, true, label);
192 }
193
194 void PepperMediaDeviceManager::OnDeviceOpenFailed(int request_id) {
195   NotifyDeviceOpened(request_id, false, std::string());
196 }
197
198 // static
199 MediaStreamType PepperMediaDeviceManager::FromPepperDeviceType(
200     PP_DeviceType_Dev type) {
201   switch (type) {
202     case PP_DEVICETYPE_DEV_INVALID:
203       return MEDIA_NO_SERVICE;
204     case PP_DEVICETYPE_DEV_AUDIOCAPTURE:
205       return MEDIA_DEVICE_AUDIO_CAPTURE;
206     case PP_DEVICETYPE_DEV_VIDEOCAPTURE:
207       return MEDIA_DEVICE_VIDEO_CAPTURE;
208     default:
209       NOTREACHED();
210       return MEDIA_NO_SERVICE;
211   }
212 }
213
214 // static
215 PP_DeviceType_Dev PepperMediaDeviceManager::FromMediaStreamType(
216     MediaStreamType type) {
217   switch (type) {
218     case MEDIA_NO_SERVICE:
219       return PP_DEVICETYPE_DEV_INVALID;
220     case MEDIA_DEVICE_AUDIO_CAPTURE:
221       return PP_DEVICETYPE_DEV_AUDIOCAPTURE;
222     case MEDIA_DEVICE_VIDEO_CAPTURE:
223       return PP_DEVICETYPE_DEV_VIDEOCAPTURE;
224     default:
225       NOTREACHED();
226       return PP_DEVICETYPE_DEV_INVALID;
227   }
228 }
229
230 void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id,
231                                                   bool succeeded,
232                                                   const std::string& label) {
233   OpenCallbackMap::iterator iter = open_callbacks_.find(request_id);
234   if (iter == open_callbacks_.end()) {
235     // The callback may have been unregistered.
236     return;
237   }
238
239   OpenDeviceCallback callback = iter->second;
240   open_callbacks_.erase(iter);
241
242   callback.Run(request_id, succeeded, label);
243 }
244
245 MediaStreamDispatcher* PepperMediaDeviceManager::GetMediaStreamDispatcher()
246     const {
247   DCHECK(render_frame());
248   MediaStreamDispatcher* const dispatcher =
249       static_cast<RenderFrameImpl*>(render_frame())->GetMediaStreamDispatcher();
250   DCHECK(dispatcher);
251   return dispatcher;
252 }
253
254 }  // namespace content