1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Copyright (c) 2013 Intel Corporation. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
6 #include "xwalk/runtime/browser/media/media_capture_devices_dispatcher.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "content/public/browser/media_devices_monitor.h"
10 #include "content/public/common/media_stream_request.h"
12 using content::BrowserThread;
13 using content::MediaStreamDevices;
17 const content::MediaStreamDevice* FindDefaultDeviceWithId(
18 const content::MediaStreamDevices& devices,
19 const std::string& device_id) {
20 if (devices.empty()) {
23 content::MediaStreamDevices::const_iterator iter = devices.begin();
24 for (; iter != devices.end(); ++iter) {
25 if (iter->id == device_id) {
30 return &(*devices.begin());
36 XWalkMediaCaptureDevicesDispatcher*
37 XWalkMediaCaptureDevicesDispatcher::GetInstance() {
38 return Singleton<XWalkMediaCaptureDevicesDispatcher>::get();
41 void XWalkMediaCaptureDevicesDispatcher::RunRequestMediaAccessPermission(
42 content::WebContents* web_contents,
43 const content::MediaStreamRequest& request,
44 const content::MediaResponseCallback& callback) {
46 content::MediaStreamDevices devices;
47 // Based on chrome/browser/media/media_stream_devices_controller.cc.
48 bool microphone_requested =
49 (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE);
50 bool webcam_requested =
51 (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE);
52 if (microphone_requested || webcam_requested) {
53 switch (request.request_type) {
54 case content::MEDIA_OPEN_DEVICE:
56 // // For open device request pick the desired device or fall back to the
57 // // first available of the given type.
58 // XWalkMediaCaptureDevicesDispatcher::GetInstance()->GetRequestedDevice(
59 // request.requested_device_id,
60 // microphone_requested,
64 case content::MEDIA_DEVICE_ACCESS:
65 case content::MEDIA_GENERATE_STREAM:
66 case content::MEDIA_ENUMERATE_DEVICES:
67 // Get the default devices for the request.
68 XWalkMediaCaptureDevicesDispatcher::GetInstance()->GetRequestedDevice(
76 callback.Run(devices, scoped_ptr<content::MediaStreamUI>());
79 XWalkMediaCaptureDevicesDispatcher::XWalkMediaCaptureDevicesDispatcher()
80 : devices_enumerated_(false) {}
82 XWalkMediaCaptureDevicesDispatcher::~XWalkMediaCaptureDevicesDispatcher() {}
84 void XWalkMediaCaptureDevicesDispatcher::AddObserver(Observer* observer) {
85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
86 if (!observers_.HasObserver(observer))
87 observers_.AddObserver(observer);
90 void XWalkMediaCaptureDevicesDispatcher::RemoveObserver(Observer* observer) {
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
92 observers_.RemoveObserver(observer);
95 const MediaStreamDevices&
96 XWalkMediaCaptureDevicesDispatcher::GetAudioCaptureDevices() {
97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
98 if (!devices_enumerated_) {
99 content::EnsureMonitorCaptureDevices();
100 devices_enumerated_ = true;
102 return audio_devices_;
105 const MediaStreamDevices&
106 XWalkMediaCaptureDevicesDispatcher::GetVideoCaptureDevices() {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
108 if (!devices_enumerated_) {
109 content::EnsureMonitorCaptureDevices();
110 devices_enumerated_ = true;
112 return video_devices_;
115 void XWalkMediaCaptureDevicesDispatcher::GetRequestedDevice(
116 const std::string& requested_device_id,
119 content::MediaStreamDevices* devices) {
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
121 DCHECK(audio || video);
124 const content::MediaStreamDevices& audio_devices = GetAudioCaptureDevices();
125 const content::MediaStreamDevice* const device =
126 FindDefaultDeviceWithId(audio_devices, requested_device_id);
128 devices->push_back(*device);
131 const content::MediaStreamDevices& video_devices = GetVideoCaptureDevices();
132 const content::MediaStreamDevice* const device =
133 FindDefaultDeviceWithId(video_devices, requested_device_id);
135 devices->push_back(*device);
139 void XWalkMediaCaptureDevicesDispatcher::OnAudioCaptureDevicesChanged(
140 const content::MediaStreamDevices& devices) {
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
142 BrowserThread::PostTask(
143 BrowserThread::UI, FROM_HERE,
145 &XWalkMediaCaptureDevicesDispatcher::UpdateAudioDevicesOnUIThread,
146 base::Unretained(this), devices));
149 void XWalkMediaCaptureDevicesDispatcher::OnVideoCaptureDevicesChanged(
150 const content::MediaStreamDevices& devices) {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
152 BrowserThread::PostTask(
153 BrowserThread::UI, FROM_HERE,
155 &XWalkMediaCaptureDevicesDispatcher::UpdateVideoDevicesOnUIThread,
156 base::Unretained(this), devices));
159 void XWalkMediaCaptureDevicesDispatcher::OnMediaRequestStateChanged(
160 int render_process_id,
163 const content::MediaStreamDevice& device,
164 content::MediaRequestState state) {
165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
166 BrowserThread::PostTask(
167 BrowserThread::UI, FROM_HERE,
169 &XWalkMediaCaptureDevicesDispatcher::UpdateMediaReqStateOnUIThread,
170 base::Unretained(this), render_process_id, render_view_id, device,
174 void XWalkMediaCaptureDevicesDispatcher::UpdateAudioDevicesOnUIThread(
175 const content::MediaStreamDevices& devices) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
177 devices_enumerated_ = true;
178 audio_devices_ = devices;
179 FOR_EACH_OBSERVER(Observer, observers_,
180 OnUpdateAudioDevices(audio_devices_));
183 void XWalkMediaCaptureDevicesDispatcher::UpdateVideoDevicesOnUIThread(
184 const content::MediaStreamDevices& devices) {
185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
186 devices_enumerated_ = true;
187 video_devices_ = devices;
188 FOR_EACH_OBSERVER(Observer, observers_,
189 OnUpdateVideoDevices(video_devices_));
192 void XWalkMediaCaptureDevicesDispatcher::UpdateMediaReqStateOnUIThread(
193 int render_process_id,
195 const content::MediaStreamDevice& device,
196 content::MediaRequestState state) {
197 FOR_EACH_OBSERVER(Observer, observers_,
198 OnRequestUpdate(render_process_id,