Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: content/browser/renderer_host/media/media_stream_manager.cc

Issue 10912004: Begin adding support for tab mirroring via the MediaStream audio/video capturing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add MediaStreamDispatcher IPC glue (and unittests) for new GenerateStreamForDevice() API. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/media/media_stream_manager.h" 5 #include "content/browser/renderer_host/media/media_stream_manager.h"
6 6
7 #include <list> 7 #include <list>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/rand_util.h" 12 #include "base/rand_util.h"
13 #include "base/win/scoped_com_initializer.h" 13 #include "base/win/scoped_com_initializer.h"
14 #include "content/browser/browser_main_loop.h"
14 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 15 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
15 #include "content/browser/renderer_host/media/media_stream_device_settings.h" 16 #include "content/browser/renderer_host/media/media_stream_device_settings.h"
16 #include "content/browser/renderer_host/media/media_stream_requester.h" 17 #include "content/browser/renderer_host/media/media_stream_requester.h"
17 #include "content/browser/renderer_host/media/video_capture_manager.h" 18 #include "content/browser/renderer_host/media/video_capture_manager.h"
18 #include "content/common/media/media_stream_options.h" 19 #include "content/common/media/media_stream_options.h"
19 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/content_browser_client.h" 21 #include "content/public/browser/content_browser_client.h"
21 #include "content/public/browser/media_observer.h" 22 #include "content/public/browser/media_observer.h"
22 #include "googleurl/src/gurl.h" 23 #include "googleurl/src/gurl.h"
23 24
(...skipping 16 matching lines...) Expand all
40 for (size_t i = 0; i < label.size(); ++i) { 41 for (size_t i = 0; i < label.size(); ++i) {
41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); 42 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1);
42 label[i] = kAlphabet[random_char]; 43 label[i] = kAlphabet[random_char];
43 } 44 }
44 return label; 45 return label;
45 } 46 }
46 47
47 // Helper to verify if a media stream type is part of options or not. 48 // Helper to verify if a media stream type is part of options or not.
48 static bool Requested(const StreamOptions& options, 49 static bool Requested(const StreamOptions& options,
49 MediaStreamType stream_type) { 50 MediaStreamType stream_type) {
50 return (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && 51 return (options.audio_type == stream_type ||
51 options.video) || 52 options.video_type == stream_type);
52 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE &&
53 options.audio);
54 } 53 }
55 54
56 DeviceThread::DeviceThread(const char* name) 55 DeviceThread::DeviceThread(const char* name)
57 : base::Thread(name) { 56 : base::Thread(name) {
58 } 57 }
59 58
60 DeviceThread::~DeviceThread() { 59 DeviceThread::~DeviceThread() {
61 Stop(); 60 Stop();
62 } 61 }
63 62
(...skipping 19 matching lines...) Expand all
83 }; 82 };
84 83
85 enum RequestType { 84 enum RequestType {
86 GENERATE_STREAM = 0, 85 GENERATE_STREAM = 0,
87 ENUMERATE_DEVICES, 86 ENUMERATE_DEVICES,
88 OPEN_DEVICE 87 OPEN_DEVICE
89 }; 88 };
90 89
91 DeviceRequest() 90 DeviceRequest()
92 : requester(NULL), 91 : requester(NULL),
93 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), 92 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED),
94 type(GENERATE_STREAM), 93 type(GENERATE_STREAM),
95 render_process_id(-1), 94 render_process_id(-1),
96 render_view_id(-1) { 95 render_view_id(-1) {
97 options.audio = false;
98 options.video = false;
99 } 96 }
100 97
101 DeviceRequest(MediaStreamRequester* requester, 98 DeviceRequest(MediaStreamRequester* requester,
102 const StreamOptions& request_options, 99 const StreamOptions& request_options,
103 int render_process_id, 100 int render_process_id,
104 int render_view_id, 101 int render_view_id,
105 const GURL& request_security_origin) 102 const GURL& request_security_origin)
106 : requester(requester), 103 : requester(requester),
107 options(request_options), 104 options(request_options),
108 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), 105 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED),
109 type(GENERATE_STREAM), 106 type(GENERATE_STREAM),
110 render_process_id(render_process_id), 107 render_process_id(render_process_id),
111 render_view_id(render_view_id), 108 render_view_id(render_view_id),
112 security_origin(request_security_origin) { 109 security_origin(request_security_origin) {
113 DCHECK(requester); 110 DCHECK(requester);
114 } 111 }
115 112
116 ~DeviceRequest() {} 113 ~DeviceRequest() {}
117 114
118 MediaStreamRequester* requester; 115 MediaStreamRequester* requester;
119 StreamOptions options; 116 StreamOptions options;
120 std::vector<RequestState> state; 117 std::vector<RequestState> state;
121 RequestType type; 118 RequestType type;
122 int render_process_id; 119 int render_process_id;
123 int render_view_id; 120 int render_view_id;
124 GURL security_origin; 121 GURL security_origin;
125 std::string requested_device_id; 122 std::string requested_device_id;
126 StreamDeviceInfoArray audio_devices; 123 StreamDeviceInfoArray devices;
127 StreamDeviceInfoArray video_devices;
128 }; 124 };
129 125
130 MediaStreamManager::EnumerationCache::EnumerationCache() 126 MediaStreamManager::EnumerationCache::EnumerationCache()
131 : valid(false) { 127 : valid(false) {
132 } 128 }
133 129
134 MediaStreamManager::EnumerationCache::~EnumerationCache() { 130 MediaStreamManager::EnumerationCache::~EnumerationCache() {
135 } 131 }
136 132
137 MediaStreamManager::MediaStreamManager( 133 MediaStreamManager::MediaStreamManager()
138 AudioInputDeviceManager* audio_input_device_manager,
139 VideoCaptureManager* video_capture_manager)
140 : ALLOW_THIS_IN_INITIALIZER_LIST( 134 : ALLOW_THIS_IN_INITIALIZER_LIST(
141 device_settings_(new MediaStreamDeviceSettings(this))), 135 device_settings_(new MediaStreamDeviceSettings(this))),
142 audio_input_device_manager_(audio_input_device_manager), 136 audio_manager_(NULL),
143 video_capture_manager_(video_capture_manager),
144 monitoring_started_(false), 137 monitoring_started_(false),
145 io_loop_(NULL) { 138 io_loop_(NULL) {
146 memset(active_enumeration_ref_count_, 0, 139 memset(active_enumeration_ref_count_, 0,
147 sizeof(active_enumeration_ref_count_)); 140 sizeof(active_enumeration_ref_count_));
148 } 141 }
149 142
150 MediaStreamManager::~MediaStreamManager() { 143 MediaStreamManager::~MediaStreamManager() {
151 DCHECK(requests_.empty()); 144 DCHECK(requests_.empty());
152 DCHECK(!device_thread_.get()); 145 DCHECK(!device_thread_.get());
153 DCHECK(!io_loop_); 146 DCHECK(!io_loop_);
154 } 147 }
155 148
156 VideoCaptureManager* MediaStreamManager::video_capture_manager() {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
158 DCHECK(video_capture_manager_);
159 EnsureDeviceThreadAndListener();
160 return video_capture_manager_;
161 }
162
163 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() {
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
165 DCHECK(audio_input_device_manager_);
166 EnsureDeviceThreadAndListener();
167 return audio_input_device_manager_;
168 }
169
170 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, 149 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester,
171 int render_process_id, 150 int render_process_id,
172 int render_view_id, 151 int render_view_id,
173 const StreamOptions& options, 152 const StreamOptions& options,
174 const GURL& security_origin, 153 const GURL& security_origin,
175 std::string* label) { 154 std::string* label) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
177 156
178 // Create a new request based on options. 157 // Create a new request based on options.
179 DeviceRequest new_request(requester, options, 158 DeviceRequest new_request(requester, options,
180 render_process_id, 159 render_process_id,
181 render_view_id, 160 render_view_id,
182 security_origin); 161 security_origin);
183 StartEnumeration(&new_request, label); 162 StartEnumeration(&new_request, label);
184 163
185 // Get user confirmation to use capture devices. 164 // Get user confirmation to use capture devices.
186 device_settings_->RequestCaptureDeviceUsage(*label, 165 device_settings_->RequestCaptureDeviceUsage(*label,
187 render_process_id, 166 render_process_id,
188 render_view_id, 167 render_view_id,
189 options, 168 options,
190 security_origin); 169 security_origin);
191 } 170 }
192 171
172 void MediaStreamManager::GenerateStreamForDevice(
173 MediaStreamRequester* requester, int render_process_id, int render_view_id,
174 const StreamOptions& options, const std::string& device_id,
175 const GURL& security_origin, std::string* label) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
177
178 // Create a new request based on options.
179 AddRequest(DeviceRequest(requester, options,
180 render_process_id, render_view_id,
181 security_origin),
182 label);
183 DeviceRequest& request = requests_[*label];
184
185 // Get user confirmation to use the capture device.
186 device_settings_->RequestCaptureDeviceUsage(*label,
187 render_process_id,
188 render_view_id,
189 options,
190 security_origin);
191 // TODO(miu): We should ask the device manager whether a device with id
192 // |device_id| actually exists. Note that no such MediaStreamProvider API for
193 // this currently exists. Also, we don't have a user-friendly device name for
194 // the infobar UI.
195 if (content::IsAudioMediaType(options.audio_type)) {
196 request.state[options.audio_type] = DeviceRequest::STATE_PENDING_APPROVAL;
197 device_settings_->AvailableDevices(
198 *label, options.audio_type, StreamDeviceInfoArray(
199 1, StreamDeviceInfo(options.audio_type, device_id, device_id,
200 false)));
201 }
202 if (content::IsVideoMediaType(options.video_type)) {
203 request.state[options.video_type] = DeviceRequest::STATE_PENDING_APPROVAL;
204 device_settings_->AvailableDevices(
205 *label, options.video_type, StreamDeviceInfoArray(
206 1, StreamDeviceInfo(options.video_type, device_id, device_id,
207 false)));
208 }
209 }
210
193 void MediaStreamManager::CancelGenerateStream(const std::string& label) { 211 void MediaStreamManager::CancelGenerateStream(const std::string& label) {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
195 213
196 DeviceRequests::iterator it = requests_.find(label); 214 DeviceRequests::iterator it = requests_.find(label);
197 if (it != requests_.end()) { 215 if (it != requests_.end()) {
198 // The request isn't complete. 216 // The request isn't complete.
199 if (!RequestDone(it->second)) { 217 if (!RequestDone(it->second)) {
200 DeviceRequest* request = &(it->second); 218 DeviceRequest& request = it->second;
201 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == 219 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
202 DeviceRequest::STATE_OPENING) { 220 ++i) {
203 for (StreamDeviceInfoArray::iterator it = 221 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
204 request->audio_devices.begin(); it != request->audio_devices.end(); 222 if (request.state[stream_type] != DeviceRequest::STATE_OPENING) {
205 ++it) { 223 continue;
206 audio_input_device_manager()->Close(it->session_id);
207 } 224 }
208 } 225 for (StreamDeviceInfoArray::const_iterator device_it =
209 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == 226 request.devices.begin();
210 DeviceRequest::STATE_OPENING) { 227 device_it != request.devices.end(); ++device_it) {
211 for (StreamDeviceInfoArray::iterator it = 228 if (device_it->stream_type == stream_type) {
212 request->video_devices.begin(); it != request->video_devices.end(); 229 GetDeviceManager(stream_type)->Close(device_it->session_id);
213 ++it) { 230 }
214 video_capture_manager()->Close(it->session_id);
215 } 231 }
216 } 232 }
217 requests_.erase(it); 233 requests_.erase(it);
218 } else { 234 } else {
219 StopGeneratedStream(label); 235 StopGeneratedStream(label);
220 } 236 }
221 device_settings_->RemovePendingCaptureRequest(label); 237 device_settings_->RemovePendingCaptureRequest(label);
222 } 238 }
223 } 239 }
224 240
225 void MediaStreamManager::StopGeneratedStream(const std::string& label) { 241 void MediaStreamManager::StopGeneratedStream(const std::string& label) {
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
227 // Find the request and close all open devices for the request. 243 // Find the request and close all open devices for the request.
228 DeviceRequests::iterator it = requests_.find(label); 244 DeviceRequests::iterator it = requests_.find(label);
229 if (it != requests_.end()) { 245 if (it != requests_.end()) {
230 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { 246 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) {
231 StopEnumerateDevices(label); 247 StopEnumerateDevices(label);
232 return; 248 return;
233 } 249 }
234 for (StreamDeviceInfoArray::iterator audio_it = 250 for (StreamDeviceInfoArray::const_iterator device_it =
235 it->second.audio_devices.begin(); 251 it->second.devices.begin();
236 audio_it != it->second.audio_devices.end(); ++audio_it) { 252 device_it != it->second.devices.end(); ++device_it) {
237 audio_input_device_manager()->Close(audio_it->session_id); 253 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id);
238 }
239 for (StreamDeviceInfoArray::iterator video_it =
240 it->second.video_devices.begin();
241 video_it != it->second.video_devices.end(); ++video_it) {
242 video_capture_manager()->Close(video_it->session_id);
243 } 254 }
244 if (it->second.type == DeviceRequest::GENERATE_STREAM && 255 if (it->second.type == DeviceRequest::GENERATE_STREAM &&
245 RequestDone(it->second)) { 256 RequestDone(it->second)) {
246 NotifyObserverDevicesClosed(&(it->second)); 257 NotifyObserverDevicesClosed(&(it->second));
247 } 258 }
248 requests_.erase(it); 259 requests_.erase(it);
249 } 260 }
250 } 261 }
251 262
252 void MediaStreamManager::EnumerateDevices( 263 void MediaStreamManager::EnumerateDevices(
253 MediaStreamRequester* requester, 264 MediaStreamRequester* requester,
254 int render_process_id, 265 int render_process_id,
255 int render_view_id, 266 int render_view_id,
256 MediaStreamType type, 267 MediaStreamType type,
257 const GURL& security_origin, 268 const GURL& security_origin,
258 std::string* label) { 269 std::string* label) {
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
260 DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || 271 DCHECK(type == content::MEDIA_AUDIO_DEVICE_CAPTURE ||
261 type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); 272 type == content::MEDIA_VIDEO_DEVICE_CAPTURE);
262 273
263 // Create a new request. 274 // Create a new request.
264 StreamOptions options; 275 StreamOptions options;
265 EnumerationCache* cache = NULL; 276 EnumerationCache* cache = NULL;
266 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 277 if (type == content::MEDIA_AUDIO_DEVICE_CAPTURE) {
267 options.audio = true; 278 options.audio_type = type;
268 cache = &audio_enumeration_cache_; 279 cache = &audio_enumeration_cache_;
280 } else if (type == content::MEDIA_VIDEO_DEVICE_CAPTURE) {
281 options.video_type = type;
282 cache = &video_enumeration_cache_;
269 } else { 283 } else {
270 options.video = true; 284 NOTREACHED();
271 cache = &video_enumeration_cache_;
272 } 285 }
wjia(left Chromium) 2012/09/07 14:11:36 Based on the DCHECK at the beginning of this funct
miu 2012/09/07 23:14:28 (This was just left over from an earlier revision
273 286
274 DeviceRequest new_request(requester, options, 287 DeviceRequest new_request(requester, options,
275 render_process_id, 288 render_process_id,
276 render_view_id, 289 render_view_id,
277 security_origin); 290 security_origin);
278 new_request.type = DeviceRequest::ENUMERATE_DEVICES; 291 new_request.type = DeviceRequest::ENUMERATE_DEVICES;
279 292
280 if (cache->valid) { 293 if (cache && cache->valid) {
281 // Cached device list of this type exists. Just send it out. 294 // Cached device list of this type exists. Just send it out.
282 new_request.state[type] = DeviceRequest::STATE_REQUESTED; 295 new_request.state[type] = DeviceRequest::STATE_REQUESTED;
283 AddRequest(&new_request, label); 296 AddRequest(new_request, label);
284 // Need to post a task since the requester won't have label till 297 // Need to post a task since the requester won't have label till
285 // this function returns. 298 // this function returns.
286 BrowserThread::PostTask(BrowserThread::IO, 299 BrowserThread::PostTask(BrowserThread::IO,
287 FROM_HERE, 300 FROM_HERE,
288 base::Bind(&MediaStreamManager::SendCachedDeviceList, 301 base::Bind(&MediaStreamManager::SendCachedDeviceList,
289 base::Unretained(this), cache, *label)); 302 base::Unretained(this), cache, *label));
290 } else { 303 } else {
291 StartEnumeration(&new_request, label); 304 StartEnumeration(&new_request, label);
292 StartMonitoring(); 305 if (cache) {
306 StartMonitoring();
307 }
293 } 308 }
294 } 309 }
295 310
296 void MediaStreamManager::StopEnumerateDevices(const std::string& label) { 311 void MediaStreamManager::StopEnumerateDevices(const std::string& label) {
297 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
298 313
299 DeviceRequests::iterator it = requests_.find(label); 314 DeviceRequests::iterator it = requests_.find(label);
300 if (it != requests_.end()) { 315 if (it != requests_.end()) {
301 DCHECK_EQ(it->second.type, DeviceRequest::ENUMERATE_DEVICES); 316 DCHECK_EQ(it->second.type, DeviceRequest::ENUMERATE_DEVICES);
302 requests_.erase(it); 317 requests_.erase(it);
303 if (!HasEnumerationRequest()) { 318 if (!HasEnumerationRequest()) {
304 StopMonitoring(); 319 StopMonitoring();
305 } 320 }
306 } 321 }
307 } 322 }
308 323
309 void MediaStreamManager::OpenDevice( 324 void MediaStreamManager::OpenDevice(
310 MediaStreamRequester* requester, 325 MediaStreamRequester* requester,
311 int render_process_id, 326 int render_process_id,
312 int render_view_id, 327 int render_view_id,
313 const std::string& device_id, 328 const std::string& device_id,
314 MediaStreamType type, 329 MediaStreamType type,
315 const GURL& security_origin, 330 const GURL& security_origin,
316 std::string* label) { 331 std::string* label) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
333 DCHECK(type == content::MEDIA_AUDIO_DEVICE_CAPTURE ||
334 type == content::MEDIA_VIDEO_DEVICE_CAPTURE);
wjia(left Chromium) 2012/09/07 14:11:36 Thanks for adding DCHECK!
318 335
319 // Create a new request. 336 // Create a new request.
320 StreamOptions options; 337 StreamOptions options;
321 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 338 if (content::IsAudioMediaType(type)) {
322 options.audio = true; 339 options.audio_type = type;
323 else 340 } else if (content::IsVideoMediaType(type)) {
324 options.video = true; 341 options.video_type = type;
342 } else {
wjia(left Chromium) 2012/09/07 14:11:36 NOTREACHED() for this branch?
miu 2012/09/07 23:14:28 Done.
343 LOG(FATAL) << "Cannot handle request for MediaStreamType " << type;
344 return;
345 }
325 346
326 DeviceRequest new_request(requester, options, 347 DeviceRequest new_request(requester, options,
327 render_process_id, 348 render_process_id,
328 render_view_id, 349 render_view_id,
329 security_origin); 350 security_origin);
330 new_request.type = DeviceRequest::OPEN_DEVICE; 351 new_request.type = DeviceRequest::OPEN_DEVICE;
331 new_request.requested_device_id = device_id; 352 new_request.requested_device_id = device_id;
332 353
333 StartEnumeration(&new_request, label); 354 StartEnumeration(&new_request, label);
334 } 355 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { 387 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) {
367 DCHECK_EQ(MessageLoop::current(), io_loop_); 388 DCHECK_EQ(MessageLoop::current(), io_loop_);
368 cache->valid = false; 389 cache->valid = false;
369 } 390 }
370 391
371 void MediaStreamManager::StartEnumeration( 392 void MediaStreamManager::StartEnumeration(
372 DeviceRequest* new_request, 393 DeviceRequest* new_request,
373 std::string* label) { 394 std::string* label) {
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
375 396
376 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 397 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
377 if (Requested(new_request->options, stream_type)) { 398 ++i) {
378 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; 399 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
379 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 400 if (Requested(new_request->options, stream_type)) {
380 if (!active_enumeration_ref_count_[stream_type]) { 401 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED;
381 ++active_enumeration_ref_count_[stream_type]; 402 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
382 GetDeviceManager(stream_type)->EnumerateDevices(); 403 if (active_enumeration_ref_count_[stream_type] == 0) {
383 } 404 ++active_enumeration_ref_count_[stream_type];
384 } 405 GetDeviceManager(stream_type)->EnumerateDevices();
385 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 406 }
386 if (Requested(new_request->options, stream_type)) {
387 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED;
388 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
389 if (!active_enumeration_ref_count_[stream_type]) {
390 ++active_enumeration_ref_count_[stream_type];
391 GetDeviceManager(stream_type)->EnumerateDevices();
392 } 407 }
393 } 408 }
394 409
395 AddRequest(new_request, label); 410 AddRequest(*new_request, label);
396 } 411 }
397 412
398 void MediaStreamManager::AddRequest( 413 void MediaStreamManager::AddRequest(
399 DeviceRequest* new_request, 414 const DeviceRequest& new_request,
400 std::string* label) { 415 std::string* label) {
401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 416 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
402 417
403 // Create a label for this request and verify it is unique. 418 // Create a label for this request and verify it is unique.
404 std::string request_label; 419 std::string request_label;
405 do { 420 do {
406 request_label = RandomLabel(); 421 request_label = RandomLabel();
407 } while (requests_.find(request_label) != requests_.end()); 422 } while (requests_.find(request_label) != requests_.end());
408 423
409 requests_.insert(std::make_pair(request_label, *new_request)); 424 requests_.insert(std::make_pair(request_label, new_request));
410 425
411 (*label) = request_label; 426 (*label) = request_label;
412 } 427 }
413 428
414 void MediaStreamManager::EnsureDeviceThreadAndListener() { 429 void MediaStreamManager::EnsureDeviceManagerStarted(
430 MediaStreamType stream_type) {
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 431 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
416 if (device_thread_.get())
417 return;
418 432
419 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); 433 if (!device_thread_.get()) {
420 CHECK(device_thread_->Start()); 434 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread"));
435 CHECK(device_thread_->Start());
436 }
421 437
422 audio_input_device_manager_->Register(this, 438 if (!device_manager_[stream_type]) {
423 device_thread_->message_loop_proxy()); 439 switch (stream_type) {
424 video_capture_manager_->Register(this, device_thread_->message_loop_proxy()); 440 case content::MEDIA_AUDIO_DEVICE_CAPTURE:
441 case content::MEDIA_TAB_AUDIO_CAPTURE:
442 if (!audio_manager_) {
443 audio_manager_ = content::BrowserMainLoop::GetAudioManager();
wjia(left Chromium) 2012/09/07 14:11:36 Injecting an audio_manager in ctor can remove the
miu 2012/09/07 23:14:28 Done.
444 }
445 device_manager_[stream_type] =
446 new media_stream::AudioInputDeviceManager(audio_manager_,
447 stream_type);
448 break;
449 case content::MEDIA_VIDEO_DEVICE_CAPTURE:
450 case content::MEDIA_TAB_VIDEO_CAPTURE:
451 device_manager_[stream_type] =
452 new media_stream::VideoCaptureManager(stream_type);
453 break;
454 default:
455 LOG(FATAL) << "Cannot create device manager for invalid or "
456 << "unsupported MediaStreamType " << stream_type;
457 return;
458 }
459 device_manager_[stream_type]->Register(
460 this, device_thread_->message_loop_proxy());
461 }
425 462
426 // We want to be notified of IO message loop destruction to delete the thread 463 // We want to be notified of IO message loop destruction to delete the thread
427 // and the device managers. 464 // and the device managers.
428 io_loop_ = MessageLoop::current(); 465 if (!io_loop_) {
429 io_loop_->AddDestructionObserver(this); 466 io_loop_ = MessageLoop::current();
467 io_loop_->AddDestructionObserver(this);
468 }
430 } 469 }
431 470
432 void MediaStreamManager::Opened(MediaStreamType stream_type, 471 void MediaStreamManager::Opened(MediaStreamType stream_type,
433 int capture_session_id) { 472 int capture_session_id) {
434 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
435 474
436 // Find the request containing this device and mark it as used. 475 // Find the request containing this device and mark it as used.
437 DeviceRequest* request = NULL; 476 DeviceRequest* request = NULL;
438 StreamDeviceInfoArray* devices = NULL; 477 StreamDeviceInfoArray* devices = NULL;
439 std::string label; 478 std::string label;
440 for (DeviceRequests::iterator request_it = requests_.begin(); 479 for (DeviceRequests::iterator request_it = requests_.begin();
441 request_it != requests_.end() && request == NULL; ++request_it) { 480 request_it != requests_.end() && request == NULL; ++request_it) {
442 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 481 devices = &(request_it->second.devices);
443 devices = &(request_it->second.audio_devices);
444 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
445 devices = &(request_it->second.video_devices);
446 } else {
447 NOTREACHED();
448 }
449
450 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 482 for (StreamDeviceInfoArray::iterator device_it = devices->begin();
451 device_it != devices->end(); ++device_it) { 483 device_it != devices->end(); ++device_it) {
452 if (device_it->session_id == capture_session_id) { 484 if (device_it->stream_type == stream_type &&
485 device_it->session_id == capture_session_id) {
453 // We've found the request. 486 // We've found the request.
454 device_it->in_use = true; 487 device_it->in_use = true;
455 label = request_it->first; 488 label = request_it->first;
456 request = &(request_it->second); 489 request = &(request_it->second);
457 break; 490 break;
458 } 491 }
459 } 492 }
460 } 493 }
461 if (request == NULL) { 494 if (request == NULL) {
462 // The request doesn't exist. 495 // The request doesn't exist.
463 return; 496 return;
464 } 497 }
465 498
466 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); 499 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED);
467 500
468 // Check if all devices for this stream type are opened. Update the state if 501 // Check if all devices for this stream type are opened. Update the state if
469 // they are. 502 // they are.
470 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 503 for (StreamDeviceInfoArray::iterator device_it = devices->begin();
471 device_it != devices->end(); ++device_it) { 504 device_it != devices->end(); ++device_it) {
505 if (device_it->stream_type != stream_type)
506 continue;
472 if (device_it->in_use == false) { 507 if (device_it->in_use == false) {
473 // Wait for more devices to be opened before we're done. 508 // Wait for more devices to be opened before we're done.
474 return; 509 return;
475 } 510 }
476 } 511 }
477 request->state[stream_type] = DeviceRequest::STATE_DONE; 512 request->state[stream_type] = DeviceRequest::STATE_DONE;
478 513
479 if (!RequestDone(*request)) { 514 if (!RequestDone(*request)) {
480 // This stream_type is done, but not the other type. 515 // This stream_type is done, but not the other type.
481 return; 516 return;
482 } 517 }
483 518
519 // Partition the array of devices into audio vs video.
wjia(left Chromium) 2012/09/07 14:11:36 This portion of code (partitioning the devices int
miu 2012/09/07 23:14:28 Done.
520 StreamDeviceInfoArray audio_devices, video_devices;
521 for (StreamDeviceInfoArray::const_iterator device_it = devices->begin();
522 device_it != devices->end(); ++device_it) {
523 if (content::IsAudioMediaType(device_it->stream_type)) {
524 audio_devices.push_back(*device_it);
525 } else if (content::IsVideoMediaType(device_it->stream_type)) {
526 video_devices.push_back(*device_it);
527 } else {
528 NOTREACHED();
529 }
530 }
531
484 switch (request->type) { 532 switch (request->type) {
485 case DeviceRequest::OPEN_DEVICE: 533 case DeviceRequest::OPEN_DEVICE:
486 request->requester->DeviceOpened(label, (*devices)[0]); 534 if (content::IsAudioMediaType(stream_type)) {
535 request->requester->DeviceOpened(label, audio_devices.front());
536 } else if (content::IsVideoMediaType(stream_type)) {
537 request->requester->DeviceOpened(label, video_devices.front());
538 } else {
539 NOTREACHED();
540 }
wjia(left Chromium) 2012/09/07 14:11:36 This change is not needed for DeviceRequest::OPEN_
miu 2012/09/07 23:14:28 Done.
487 break; 541 break;
488 case DeviceRequest::GENERATE_STREAM: 542 case DeviceRequest::GENERATE_STREAM:
489 request->requester->StreamGenerated(label, request->audio_devices, 543 request->requester->StreamGenerated(label, audio_devices, video_devices);
490 request->video_devices);
491 NotifyObserverDevicesOpened(request); 544 NotifyObserverDevicesOpened(request);
492 break; 545 break;
493 default: 546 default:
494 NOTREACHED(); 547 NOTREACHED();
548 break;
495 } 549 }
496 } 550 }
497 551
498 void MediaStreamManager::Closed(MediaStreamType stream_type, 552 void MediaStreamManager::Closed(MediaStreamType stream_type,
499 int capture_session_id) { 553 int capture_session_id) {
500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 554 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
501 } 555 }
502 556
503 void MediaStreamManager::DevicesEnumerated( 557 void MediaStreamManager::DevicesEnumerated(
504 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { 558 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) {
505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 559 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
506 560
507 // Only cache device list when there is EnumerateDevices request, since 561 // Only cache the device list when there is an EnumerateDevices request, since
508 // other requests don't turn on device monitoring. 562 // other requests don't turn on device monitoring.
509 bool need_update_clients = false; 563 bool need_update_clients = false;
510 EnumerationCache* cache = 564 EnumerationCache* cache =
511 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? 565 (stream_type == content::MEDIA_AUDIO_DEVICE_CAPTURE ?
512 &audio_enumeration_cache_ : &video_enumeration_cache_); 566 &audio_enumeration_cache_ : &video_enumeration_cache_);
513 if (HasEnumerationRequest(stream_type) && 567 if (HasEnumerationRequest(stream_type) &&
514 (!cache->valid || 568 (!cache->valid ||
515 devices.size() != cache->devices.size() || 569 devices.size() != cache->devices.size() ||
516 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), 570 !std::equal(devices.begin(), devices.end(), cache->devices.begin(),
517 media_stream::StreamDeviceInfo::IsEqual))) { 571 media_stream::StreamDeviceInfo::IsEqual))) {
518 cache->valid = true; 572 cache->valid = true;
519 cache->devices = devices; 573 cache->devices = devices;
520 need_update_clients = true; 574 need_update_clients = true;
521 } 575 }
(...skipping 14 matching lines...) Expand all
536 } 590 }
537 for (std::list<std::string>::iterator it = label_list.begin(); 591 for (std::list<std::string>::iterator it = label_list.begin();
538 it != label_list.end(); ++it) { 592 it != label_list.end(); ++it) {
539 DeviceRequest& request = requests_[*it]; 593 DeviceRequest& request = requests_[*it];
540 switch (request.type) { 594 switch (request.type) {
541 case DeviceRequest::ENUMERATE_DEVICES: 595 case DeviceRequest::ENUMERATE_DEVICES:
542 if (need_update_clients) 596 if (need_update_clients)
543 request.requester->DevicesEnumerated(*it, devices); 597 request.requester->DevicesEnumerated(*it, devices);
544 break; 598 break;
545 case DeviceRequest::OPEN_DEVICE: 599 case DeviceRequest::OPEN_DEVICE:
600 DCHECK(!request.requested_device_id.empty());
546 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 601 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
547 device_it != devices.end(); device_it++) { 602 device_it != devices.end(); ++device_it) {
548 if (request.requested_device_id == device_it->device_id) { 603 if (request.requested_device_id == device_it->device_id) {
549 StreamDeviceInfo device = *device_it; 604 StreamDeviceInfo device = *device_it;
550 device.in_use = false; 605 device.in_use = false;
551 device.session_id = 606 device.session_id =
552 GetDeviceManager(device_it->stream_type)->Open(device); 607 GetDeviceManager(device_it->stream_type)->Open(device);
553 request.state[device_it->stream_type] = 608 request.state[device_it->stream_type] =
554 DeviceRequest::STATE_OPENING; 609 DeviceRequest::STATE_OPENING;
555 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) 610 request.devices.push_back(device);
556 request.audio_devices.push_back(device);
557 else
558 request.video_devices.push_back(device);
559 break; 611 break;
560 } 612 }
561 } 613 }
562 break; 614 break;
563 default: 615 default:
564 device_settings_->AvailableDevices(*it, stream_type, devices); 616 device_settings_->AvailableDevices(*it, stream_type, devices);
617 break;
565 } 618 }
566 } 619 }
567 label_list.clear(); 620 label_list.clear();
568 --active_enumeration_ref_count_[stream_type]; 621 --active_enumeration_ref_count_[stream_type];
569 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 622 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
570 } 623 }
571 624
572 void MediaStreamManager::Error(MediaStreamType stream_type, 625 void MediaStreamManager::Error(MediaStreamType stream_type,
573 int capture_session_id, 626 int capture_session_id,
574 MediaStreamProviderError error) { 627 MediaStreamProviderError error) {
575 // Find the device for the error call. 628 // Find the device for the error call.
576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
630
577 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); 631 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end();
578 ++it) { 632 ++it) {
579 StreamDeviceInfoArray* devices = NULL; 633 StreamDeviceInfoArray& devices = it->second.devices;
580 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
581 devices = &(it->second.audio_devices);
582 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
583 devices = &(it->second.video_devices);
584 } else {
585 NOTREACHED();
586 }
587 634
588 int device_idx = 0; 635 int audio_device_idx = -1;
589 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); 636 int video_device_idx = -1;
590 device_it != devices->end(); ++device_it, ++device_idx) { 637 for (StreamDeviceInfoArray::iterator device_it = devices.begin();
591 if (device_it->session_id == capture_session_id) { 638 device_it != devices.end(); ++device_it) {
592 // We've found the failing device. Find the error case: 639 if (content::IsAudioMediaType(device_it->stream_type)) {
593 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { 640 ++audio_device_idx;
594 // 1. Already opened -> signal device failure and close device. 641 } else if (content::IsVideoMediaType(device_it->stream_type)) {
595 // Use device_idx to signal which of the devices encountered an 642 ++video_device_idx;
596 // error. 643 } else {
597 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 644 NOTREACHED();
598 it->second.requester->AudioDeviceFailed(it->first, device_idx); 645 continue;
599 } else if (stream_type == 646 }
600 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 647 if (device_it->stream_type != stream_type ||
601 it->second.requester->VideoDeviceFailed(it->first, device_idx); 648 device_it->session_id != capture_session_id) {
602 } 649 continue;
603 GetDeviceManager(stream_type)->Close(capture_session_id); 650 }
604 // We don't erase the devices here so that we can update the UI 651 // We've found the failing device. Find the error case:
605 // properly in StopGeneratedStream(). 652 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) {
606 it->second.state[stream_type] = DeviceRequest::STATE_ERROR; 653 // 1. Already opened -> signal device failure and close device.
654 // Use device_idx to signal which of the devices encountered an
655 // error.
656 if (content::IsAudioMediaType(stream_type)) {
657 it->second.requester->AudioDeviceFailed(it->first, audio_device_idx);
658 } else if (content::IsVideoMediaType(stream_type)) {
659 it->second.requester->VideoDeviceFailed(it->first, video_device_idx);
607 } else { 660 } else {
608 // Request is not done, devices are not opened in this case. 661 NOTREACHED();
609 if ((it->second.audio_devices.size() + 662 return;
610 it->second.video_devices.size()) <= 1) {
611 // 2. Device not opened and no other devices for this request ->
612 // signal stream error and remove the request.
613 it->second.requester->StreamGenerationFailed(it->first);
614 requests_.erase(it);
615 } else {
616 // 3. Not opened but other devices exists for this request -> remove
617 // device from list, but don't signal an error.
618 devices->erase(device_it);
619 }
620 } 663 }
621 return; 664 GetDeviceManager(stream_type)->Close(capture_session_id);
665 // We don't erase the devices here so that we can update the UI
666 // properly in StopGeneratedStream().
667 it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
668 } else {
669 // Request is not done, devices are not opened in this case.
670 if (devices.size() <= 1) {
671 // 2. Device not opened and no other devices for this request ->
672 // signal stream error and remove the request.
673 it->second.requester->StreamGenerationFailed(it->first);
674 requests_.erase(it);
675 } else {
676 // 3. Not opened but other devices exists for this request -> remove
677 // device from list, but don't signal an error.
678 devices.erase(device_it); // NOTE: This invalidates device_it!
679 }
622 } 680 }
681 return;
623 } 682 }
624 } 683 }
625 } 684 }
626 685
627 void MediaStreamManager::DevicesAccepted(const std::string& label, 686 void MediaStreamManager::DevicesAccepted(const std::string& label,
628 const StreamDeviceInfoArray& devices) { 687 const StreamDeviceInfoArray& devices) {
629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 688 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
630 DeviceRequests::iterator request_it = requests_.find(label); 689 DeviceRequests::iterator request_it = requests_.find(label);
631 if (request_it != requests_.end()) { 690 if (request_it == requests_.end())
632 if (devices.empty()) { 691 return;
633 // No available devices or user didn't accept device usage. 692
634 request_it->second.requester->StreamGenerationFailed(request_it->first); 693 DeviceRequest& request = request_it->second;
635 requests_.erase(request_it); 694
636 return; 695 if (devices.empty()) {
696 // No available devices or user didn't accept device usage.
697 request.requester->StreamGenerationFailed(request_it->first);
698 requests_.erase(request_it);
699 return;
700 }
701
702 // Process all newly-accepted devices for this request.
703 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin();
704 device_it != devices.end(); ++device_it) {
705 StreamDeviceInfo device_info = *device_it; // Make a copy.
706
707 // Set in_use to false to be able to track if this device has been
708 // opened. in_use might be true if the device type can be used in more
709 // than one session.
710 DCHECK_EQ(request.state[device_it->stream_type],
711 DeviceRequest::STATE_PENDING_APPROVAL);
712 device_info.in_use = false;
713 device_info.session_id =
714 GetDeviceManager(device_info.stream_type)->Open(device_info);
715 request.state[device_it->stream_type] = DeviceRequest::STATE_OPENING;
716 request.devices.push_back(device_info);
717 }
718
719 // Check whether we've received all stream types requested.
720 bool found_audio = false, found_video = false;
721 for (StreamDeviceInfoArray::const_iterator i = request.devices.begin();
722 i != request.devices.end(); ++i) {
wjia(left Chromium) 2012/09/07 14:11:36 This for loop can be merged with for loop above.
miu 2012/09/07 23:14:28 Done.
723 if (i->stream_type == request.options.audio_type) {
724 found_audio = true;
725 } else if (i->stream_type == request.options.video_type) {
726 found_video = true;
727 } else {
728 NOTREACHED();
637 } 729 }
638 730 }
639 // Loop through all device types for this request. 731 if (request.options.audio_type != content::MEDIA_NO_SERVICE &&
640 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); 732 !found_audio) {
641 device_it != devices.end(); ++device_it) { 733 request.state[request.options.audio_type] = DeviceRequest::STATE_ERROR;
642 StreamDeviceInfo device_info = *device_it; 734 }
643 735 if (request.options.video_type != content::MEDIA_NO_SERVICE &&
644 // Set in_use to false to be able to track if this device has been 736 !found_video) {
645 // opened. in_use might be true if the device type can be used in more 737 request.state[request.options.video_type] = DeviceRequest::STATE_ERROR;
646 // than one session.
647 DCHECK_EQ(request_it->second.state[device_it->stream_type],
648 DeviceRequest::STATE_PENDING_APPROVAL);
649 device_info.in_use = false;
650 device_info.session_id =
651 GetDeviceManager(device_info.stream_type)->Open(device_info);
652 request_it->second.state[device_it->stream_type] =
653 DeviceRequest::STATE_OPENING;
654 if (device_info.stream_type ==
655 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) {
656 request_it->second.audio_devices.push_back(device_info);
657 } else if (device_info.stream_type ==
658 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
659 request_it->second.video_devices.push_back(device_info);
660 } else {
661 NOTREACHED();
662 }
663 }
664 // Check if we received all stream types requested.
665 MediaStreamType stream_type =
666 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
667 if (Requested(request_it->second.options, stream_type) &&
668 request_it->second.audio_devices.size() == 0) {
669 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
670 }
671 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE;
672 if (Requested(request_it->second.options, stream_type) &&
673 request_it->second.video_devices.size() == 0) {
674 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR;
675 }
676 return;
677 } 738 }
678 } 739 }
679 740
680 void MediaStreamManager::SettingsError(const std::string& label) { 741 void MediaStreamManager::SettingsError(const std::string& label) {
681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 742 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
682 // Erase this request and report an error. 743 // Erase this request and report an error.
683 DeviceRequests::iterator it = requests_.find(label); 744 DeviceRequests::iterator it = requests_.find(label);
684 if (it != requests_.end()) { 745 if (it != requests_.end()) {
685 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); 746 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM);
686 it->second.requester->StreamGenerationFailed(label); 747 it->second.requester->StreamGenerationFailed(label);
687 requests_.erase(it); 748 requests_.erase(it);
688 return; 749 return;
689 } 750 }
690 } 751 }
691 752
753 void MediaStreamManager::SetAudioManager(media::AudioManager* audio_manager) {
754 LOG_IF(FATAL, (audio_manager_ != NULL) && (audio_manager_ != audio_manager))
755 << "Cannot override AudioManager after it has been set.";
756 audio_manager_ = audio_manager;
757 }
758
692 void MediaStreamManager::UseFakeDevice() { 759 void MediaStreamManager::UseFakeDevice() {
693 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 760 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
694 video_capture_manager()->UseFakeDevice(); 761 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
762 ++i) {
763 const MediaStreamType stream_type = static_cast<MediaStreamType>(i);
764 if (content::IsVideoMediaType(stream_type)) {
765 GetVideoCaptureManager(stream_type)->UseFakeDevice();
766 }
767 }
695 device_settings_->UseFakeUI(); 768 device_settings_->UseFakeUI();
696 } 769 }
697 770
698 void MediaStreamManager::WillDestroyCurrentMessageLoop() { 771 void MediaStreamManager::WillDestroyCurrentMessageLoop() {
699 DCHECK_EQ(MessageLoop::current(), io_loop_); 772 DCHECK_EQ(MessageLoop::current(), io_loop_);
700 DCHECK(requests_.empty()); 773 DCHECK(requests_.empty());
701 if (device_thread_.get()) { 774 if (device_thread_.get()) {
702 StopMonitoring(); 775 StopMonitoring();
703 776
704 video_capture_manager_->Unregister(); 777 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
705 audio_input_device_manager_->Unregister(); 778 ++i) {
779 if (device_manager_[i]) {
780 device_manager_[i]->Unregister();
781 }
782 }
783
706 device_thread_.reset(); 784 device_thread_.reset();
707 } 785 }
708 786
709 audio_input_device_manager_ = NULL; 787 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES;
710 video_capture_manager_ = NULL; 788 ++i) {
789 device_manager_[i] = NULL;
790 }
711 io_loop_ = NULL; 791 io_loop_ = NULL;
712 device_settings_.reset(); 792 device_settings_.reset();
713 } 793 }
714 794
715 void MediaStreamManager::NotifyObserverDevicesOpened(DeviceRequest* request) { 795 void MediaStreamManager::NotifyObserverDevicesOpened(DeviceRequest* request) {
716 content::MediaObserver* media_observer = 796 content::MediaObserver* media_observer =
717 content::GetContentClient()->browser()->GetMediaObserver(); 797 content::GetContentClient()->browser()->GetMediaObserver();
718 content::MediaStreamDevices opened_devices; 798 content::MediaStreamDevices opened_devices;
719 DevicesFromRequest(request, &opened_devices); 799 DevicesFromRequest(request, &opened_devices);
720 DCHECK(!opened_devices.empty()); 800 DCHECK(!opened_devices.empty());
721 media_observer->OnCaptureDevicesOpened(request->render_process_id, 801 media_observer->OnCaptureDevicesOpened(request->render_process_id,
722 request->render_view_id, 802 request->render_view_id,
723 opened_devices); 803 opened_devices);
724 } 804 }
725 805
726 void MediaStreamManager::NotifyObserverDevicesClosed(DeviceRequest* request) { 806 void MediaStreamManager::NotifyObserverDevicesClosed(DeviceRequest* request) {
727 content::MediaObserver* media_observer = 807 content::MediaObserver* media_observer =
728 content::GetContentClient()->browser()->GetMediaObserver(); 808 content::GetContentClient()->browser()->GetMediaObserver();
729 content::MediaStreamDevices closed_devices; 809 content::MediaStreamDevices closed_devices;
730 DevicesFromRequest(request, &closed_devices); 810 DevicesFromRequest(request, &closed_devices);
731 if (closed_devices.empty()) 811 if (closed_devices.empty())
732 return; 812 return;
733 media_observer->OnCaptureDevicesClosed(request->render_process_id, 813 media_observer->OnCaptureDevicesClosed(request->render_process_id,
734 request->render_view_id, 814 request->render_view_id,
735 closed_devices); 815 closed_devices);
736 } 816 }
737 817
738 void MediaStreamManager::DevicesFromRequest( 818 void MediaStreamManager::DevicesFromRequest(
739 DeviceRequest* request, content::MediaStreamDevices* devices) { 819 DeviceRequest* request, content::MediaStreamDevices* devices) {
740 StreamDeviceInfoArray::const_iterator it = request->audio_devices.begin(); 820 for (StreamDeviceInfoArray::const_iterator it = request->devices.begin();
741 for (; it != request->audio_devices.end(); ++it) { 821 it != request->devices.end(); ++it) {
742 devices->push_back( 822 devices->push_back(content::MediaStreamDevice(
743 content::MediaStreamDevice( 823 it->stream_type, it->device_id, it->name));
744 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE,
745 it->device_id,
746 it->name));
747 }
748 for (it = request->video_devices.begin(); it != request->video_devices.end();
749 ++it) {
750 devices->push_back(
751 content::MediaStreamDevice(
752 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
753 it->device_id,
754 it->name));
755 } 824 }
756 } 825 }
757 826
758 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { 827 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const {
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 828 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
760 // Check if all devices are opened.
761 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE;
762 if (Requested(request.options, stream_type)) {
763 if (request.state[stream_type] != DeviceRequest::STATE_DONE &&
764 request.state[stream_type] != DeviceRequest::STATE_ERROR) {
765 return false;
766 }
767 829
768 for (StreamDeviceInfoArray::const_iterator it = 830 const bool requested_audio =
769 request.audio_devices.begin(); it != request.audio_devices.end(); 831 content::IsAudioMediaType(request.options.audio_type);
770 ++it) { 832 const bool requested_video =
771 if (it->in_use == false) { 833 content::IsVideoMediaType(request.options.video_type);
772 return false; 834
773 } 835 const bool audio_done =
774 } 836 !requested_audio ||
837 request.state[request.options.audio_type] == DeviceRequest::STATE_DONE ||
838 request.state[request.options.audio_type] == DeviceRequest::STATE_ERROR;
839 if (!audio_done) {
840 return false;
775 } 841 }
776 842
777 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 843 const bool video_done =
778 if (Requested(request.options, stream_type)) { 844 !requested_video ||
779 if (request.state[stream_type] != DeviceRequest::STATE_DONE && 845 request.state[request.options.video_type] == DeviceRequest::STATE_DONE ||
780 request.state[stream_type] != DeviceRequest::STATE_ERROR) { 846 request.state[request.options.video_type] == DeviceRequest::STATE_ERROR;
847 if (!video_done) {
848 return false;
849 }
850
851 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin();
852 it != request.devices.end(); ++it) {
853 if ((!requested_audio && content::IsAudioMediaType(it->stream_type)) ||
854 (!requested_video && content::IsVideoMediaType(it->stream_type))) {
wjia(left Chromium) 2012/09/07 14:11:36 This won't happen since the "request" only accepts
miu 2012/09/07 23:14:28 Done.
855 continue;
856 }
857 if (it->in_use == false) {
781 return false; 858 return false;
782 } 859 }
783
784 for (StreamDeviceInfoArray::const_iterator it =
785 request.video_devices.begin(); it != request.video_devices.end();
786 ++it) {
787 if (it->in_use == false) {
788 return false;
789 }
790 }
791 } 860 }
792 861
793 return true; 862 return true;
794 } 863 }
795 864
796 // Called to get media capture device manager of specified type.
797 MediaStreamProvider* MediaStreamManager::GetDeviceManager( 865 MediaStreamProvider* MediaStreamManager::GetDeviceManager(
798 MediaStreamType stream_type) { 866 MediaStreamType stream_type) {
799 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { 867 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
800 return video_capture_manager(); 868 EnsureDeviceManagerStarted(stream_type);
801 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { 869 return device_manager_[stream_type];
802 return audio_input_device_manager(); 870 }
803 } 871
804 NOTREACHED(); 872 VideoCaptureManager* MediaStreamManager::GetVideoCaptureManager(
805 return NULL; 873 MediaStreamType stream_type) {
874 DCHECK(content::IsVideoMediaType(stream_type));
875 return reinterpret_cast<VideoCaptureManager*>(GetDeviceManager(stream_type));
876 }
877
878 AudioInputDeviceManager* MediaStreamManager::GetAudioInputDeviceManager(
879 MediaStreamType stream_type) {
880 DCHECK(content::IsAudioMediaType(stream_type));
881 return reinterpret_cast<AudioInputDeviceManager*>(
882 GetDeviceManager(stream_type));
806 } 883 }
807 884
808 void MediaStreamManager::OnDevicesChanged( 885 void MediaStreamManager::OnDevicesChanged(
809 base::SystemMonitor::DeviceType device_type) { 886 base::SystemMonitor::DeviceType device_type) {
810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 887 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
888
889 // NOTE: This method is only called in response to physical audio/video device
890 // changes (from the operating system).
891
811 MediaStreamType stream_type; 892 MediaStreamType stream_type;
812 EnumerationCache* cache; 893 EnumerationCache* cache;
813 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { 894 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) {
814 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; 895 stream_type = content::MEDIA_AUDIO_DEVICE_CAPTURE;
815 cache = &audio_enumeration_cache_; 896 cache = &audio_enumeration_cache_;
816 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { 897 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) {
817 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; 898 stream_type = content::MEDIA_VIDEO_DEVICE_CAPTURE;
818 cache = &video_enumeration_cache_; 899 cache = &video_enumeration_cache_;
819 } else { 900 } else {
820 return; // Uninteresting device change. 901 return; // Uninteresting device change.
821 } 902 }
822 903
823 if (!HasEnumerationRequest(stream_type)) { 904 if (!HasEnumerationRequest(stream_type)) {
824 // There is no request for that type, No need to enumerate devices. 905 // There is no request for that type, No need to enumerate devices.
825 // Therefore, invalidate the cache of that type. 906 // Therefore, invalidate the cache of that type.
826 ClearEnumerationCache(cache); 907 ClearEnumerationCache(cache);
827 return; 908 return;
(...skipping 24 matching lines...) Expand all
852 it != requests_.end(); ++it) { 933 it != requests_.end(); ++it) {
853 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && 934 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES &&
854 Requested(it->second.options, stream_type)) { 935 Requested(it->second.options, stream_type)) {
855 return true; 936 return true;
856 } 937 }
857 } 938 }
858 return false; 939 return false;
859 } 940 }
860 941
861 } // namespace media_stream 942 } // namespace media_stream
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698