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

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

Issue 34393006: Refactor MediaStreamManager to never output real device id. It now always output sourceId in the fo… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix broken video_capture_host unittests. Addressed justinlinlins comments. Created 7 years, 1 month 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 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 std::string MediaStreamManager::MakeMediaAccessRequest( 200 std::string MediaStreamManager::MakeMediaAccessRequest(
201 int render_process_id, 201 int render_process_id,
202 int render_view_id, 202 int render_view_id,
203 int page_request_id, 203 int page_request_id,
204 const StreamOptions& options, 204 const StreamOptions& options,
205 const GURL& security_origin, 205 const GURL& security_origin,
206 const MediaRequestResponseCallback& callback) { 206 const MediaRequestResponseCallback& callback) {
207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
208 // Create a new request based on options. 208 // Create a new request based on options.
209 MediaStreamRequest stream_request( 209 MediaStreamRequest stream_request(
210 render_process_id, render_view_id, page_request_id, std::string(), 210 render_process_id, render_view_id, page_request_id,
211 security_origin, MEDIA_DEVICE_ACCESS, std::string(), std::string(), 211 security_origin, MEDIA_DEVICE_ACCESS, std::string(), std::string(),
212 options.audio_type, options.video_type); 212 options.audio_type, options.video_type);
213 DeviceRequest* request = new DeviceRequest(NULL, stream_request, 213 DeviceRequest* request = new DeviceRequest(NULL, stream_request,
214 render_process_id, render_view_id); 214 render_process_id, render_view_id);
215 const std::string& label = AddRequest(request); 215 const std::string& label = AddRequest(request);
216 216
217 request->callback = callback; 217 request->callback = callback;
218 218 BrowserThread::PostTask(
219 HandleRequest(label); 219 BrowserThread::IO, FROM_HERE,
220 220 base::Bind(&MediaStreamManager::HandleRequest,
221 base::Unretained(this), label));
221 return label; 222 return label;
222 } 223 }
223 224
224 std::string MediaStreamManager::GenerateStream( 225 std::string MediaStreamManager::GenerateStream(
225 MediaStreamRequester* requester, 226 MediaStreamRequester* requester,
226 int render_process_id, 227 int render_process_id,
227 int render_view_id, 228 int render_view_id,
228 int page_request_id, 229 int page_request_id,
229 const StreamOptions& options, 230 const StreamOptions& options,
230 const GURL& security_origin) { 231 const GURL& security_origin) {
231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
232 if (CommandLine::ForCurrentProcess()->HasSwitch( 233 if (CommandLine::ForCurrentProcess()->HasSwitch(
233 switches::kUseFakeDeviceForMediaStream)) { 234 switches::kUseFakeDeviceForMediaStream)) {
234 UseFakeDevice(); 235 UseFakeDevice();
235 } 236 }
236 if (CommandLine::ForCurrentProcess()->HasSwitch( 237 if (CommandLine::ForCurrentProcess()->HasSwitch(
237 switches::kUseFakeUIForMediaStream)) { 238 switches::kUseFakeUIForMediaStream)) {
238 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>()); 239 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>());
239 } 240 }
240 241
241 int target_render_process_id = render_process_id;
242 int target_render_view_id = render_view_id;
243 std::string tab_capture_device_id;
244
245 // Customize options for a WebContents based capture.
246 if (options.audio_type == MEDIA_TAB_AUDIO_CAPTURE ||
247 options.video_type == MEDIA_TAB_VIDEO_CAPTURE) {
248 // TODO(justinlin): Can't plumb audio mirroring using stream type right
249 // now, so plumbing by device_id. Will revisit once it's refactored.
250 // http://crbug.com/163100
251 tab_capture_device_id =
252 WebContentsCaptureUtil::AppendWebContentsDeviceScheme(
253 !options.video_device_id.empty() ?
254 options.video_device_id : options.audio_device_id);
255
256 bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget(
257 tab_capture_device_id, &target_render_process_id,
258 &target_render_view_id);
259 if (!has_valid_device_id ||
260 (options.audio_type != MEDIA_TAB_AUDIO_CAPTURE &&
261 options.audio_type != MEDIA_NO_SERVICE) ||
262 (options.video_type != MEDIA_TAB_VIDEO_CAPTURE &&
263 options.video_type != MEDIA_NO_SERVICE)) {
264 LOG(ERROR) << "Invalid request.";
265 return std::string();
266 }
267 }
268
269 std::string translated_audio_device_id;
270 std::string translated_video_device_id;
271 if (options.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE) {
272 bool found_match = TranslateGUIDToRawId(
273 MEDIA_DEVICE_AUDIO_CAPTURE, security_origin, options.audio_device_id,
274 &translated_audio_device_id);
275 DCHECK(found_match || translated_audio_device_id.empty());
276 }
277
278 if (options.video_type == MEDIA_DEVICE_VIDEO_CAPTURE) {
279 bool found_match = TranslateGUIDToRawId(
280 MEDIA_DEVICE_VIDEO_CAPTURE, security_origin, options.video_device_id,
281 &translated_video_device_id);
282 DCHECK(found_match || translated_video_device_id.empty());
283 }
284
285 if (options.video_type == MEDIA_DESKTOP_VIDEO_CAPTURE ||
286 options.audio_type == MEDIA_LOOPBACK_AUDIO_CAPTURE) {
287 // For screen capture we only support two valid combinations:
288 // (1) screen video capture only, or
289 // (2) screen video capture with loopback audio capture.
290 if (options.video_type != MEDIA_DESKTOP_VIDEO_CAPTURE ||
291 (options.audio_type != MEDIA_NO_SERVICE &&
292 options.audio_type != MEDIA_LOOPBACK_AUDIO_CAPTURE)) {
293 // TODO(sergeyu): Surface error message to the calling JS code.
294 LOG(ERROR) << "Invalid screen capture request.";
295 return std::string();
296 }
297 translated_video_device_id = options.video_device_id;
298 }
299
300 // Create a new request based on options. 242 // Create a new request based on options.
301 MediaStreamRequest stream_request( 243 MediaStreamRequest stream_request(
302 target_render_process_id, target_render_view_id, page_request_id, 244 render_process_id, render_view_id, page_request_id,
303 tab_capture_device_id, security_origin, MEDIA_GENERATE_STREAM, 245 security_origin, MEDIA_GENERATE_STREAM,
304 translated_audio_device_id, translated_video_device_id, 246 options.audio_device_id, options.video_device_id,
305 options.audio_type, options.video_type); 247 options.audio_type, options.video_type);
306 DeviceRequest* request = new DeviceRequest(requester, stream_request, 248 DeviceRequest* request = new DeviceRequest(requester, stream_request,
307 render_process_id, 249 render_process_id,
308 render_view_id); 250 render_view_id);
309 const std::string& label = AddRequest(request); 251 const std::string& label = AddRequest(request);
310 HandleRequest(label); 252
253 // Need to post a task since the requester won't have label till
254 // this function returns.
255 BrowserThread::PostTask(
256 BrowserThread::IO, FROM_HERE,
257 base::Bind(&MediaStreamManager::HandleRequest,
258 base::Unretained(this), label));
311 return label; 259 return label;
312 } 260 }
313 261
314 void MediaStreamManager::CancelRequest(const std::string& label) { 262 void MediaStreamManager::CancelRequest(const std::string& label) {
315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
316 264
265 BrowserThread::PostTask(
266 BrowserThread::IO, FROM_HERE,
267 base::Bind(&MediaStreamManager::DoCancelRequest,
268 base::Unretained(this), label));
269 }
270
271 void MediaStreamManager::DoCancelRequest(const std::string& label) {
317 DeviceRequests::iterator request_it = requests_.find(label); 272 DeviceRequests::iterator request_it = requests_.find(label);
318 if (request_it == requests_.end()) { 273 if (request_it == requests_.end()) {
319 NOTREACHED(); 274 NOTREACHED();
320 return; 275 return;
321 } 276 }
322 scoped_ptr<DeviceRequest> request(request_it->second);
323 RemoveRequest(request_it);
324 277
278 DeviceRequest* request(request_it->second);
325 if (request->request.request_type == MEDIA_ENUMERATE_DEVICES) { 279 if (request->request.request_type == MEDIA_ENUMERATE_DEVICES) {
280 DeleteRequest(request_it);
326 return; 281 return;
327 } 282 }
328 283
329 // This is a request for opening one or more devices. 284 // This is a request for opening one or more devices.
330 for (StreamDeviceInfoArray::iterator device_it = request->devices.begin(); 285 for (StreamDeviceInfoArray::iterator device_it = request->devices.begin();
331 device_it != request->devices.end(); ++device_it) { 286 device_it != request->devices.end(); ++device_it) {
332 // If we have not yet requested the device to be opened - just ignore it. 287 // If we have not yet requested the device to be opened - just ignore it.
333 if (request->state(device_it->device.type) != MEDIA_REQUEST_STATE_OPENING 288 if (request->state(device_it->device.type) != MEDIA_REQUEST_STATE_OPENING
334 && 289 &&
335 request->state(device_it->device.type) != MEDIA_REQUEST_STATE_DONE) { 290 request->state(device_it->device.type) != MEDIA_REQUEST_STATE_DONE) {
336 continue; 291 continue;
337 } 292 }
338 // Stop the opening/opened devices of the requests. 293 // Stop the opening/opened devices of the requests.
339 StopDevice(*device_it); 294 StopDevice(*device_it);
340 } 295 }
341 296
342 // Cancel the request if still pending at UI side. 297 // Cancel the request if still pending at UI side.
343 request->SetState(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_CLOSING); 298 request->SetState(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_CLOSING);
299 DeleteRequest(request_it);
344 } 300 }
345 301
346 void MediaStreamManager::CancelAllRequests(int render_process_id) { 302 void MediaStreamManager::CancelAllRequests(int render_process_id) {
347 DeviceRequests::iterator request_it = requests_.begin(); 303 DeviceRequests::iterator request_it = requests_.begin();
348 while (request_it != requests_.end()) { 304 while (request_it != requests_.end()) {
349 if (request_it->second->requesting_process_id != render_process_id) { 305 if (request_it->second->requesting_process_id != render_process_id) {
350 ++request_it; 306 ++request_it;
351 continue; 307 continue;
352 } 308 }
353 309
354 std::string label = request_it->first; 310 std::string label = request_it->first;
355 ++request_it; 311 ++request_it;
356 CancelRequest(label); 312 BrowserThread::PostTask(
313 BrowserThread::IO, FROM_HERE,
314 base::Bind(&MediaStreamManager::DoCancelRequest,
315 base::Unretained(this), label));
357 } 316 }
358 } 317 }
359 318
360 void MediaStreamManager::StopStreamDevice(int render_process_id, 319 void MediaStreamManager::StopStreamDevice(int render_process_id,
361 int render_view_id, 320 int render_view_id,
362 const std::string& device_id) { 321 const std::string& device_id) {
363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 322 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
364 DVLOG(1) << "StopStreamDevice({render_view_id = " << render_view_id << "} " 323 DVLOG(1) << "StopStreamDevice({render_view_id = " << render_view_id << "} "
365 << ", {device_id = " << device_id << "})"; 324 << ", {device_id = " << device_id << "})";
325 BrowserThread::PostTask(
326 BrowserThread::IO, FROM_HERE,
327 base::Bind(&MediaStreamManager::DoStopStreamDevice,
328 base::Unretained(this), render_process_id, render_view_id,
329 device_id));
330 }
366 331
332 void MediaStreamManager::DoStopStreamDevice(int render_process_id,
333 int render_view_id,
334 const std::string& device_id) {
367 // Find all requests for this |render_process_id| and |render_view_id| of type 335 // Find all requests for this |render_process_id| and |render_view_id| of type
368 // MEDIA_GENERATE_STREAM that has requested to use |device_id|. 336 // MEDIA_GENERATE_STREAM that has requested to use |device_id|.
369 DeviceRequests::iterator request_it = requests_.begin(); 337 DeviceRequests::iterator request_it = requests_.begin();
370 while (request_it != requests_.end()) { 338 while (request_it != requests_.end()) {
371 DeviceRequest* request = request_it->second; 339 DeviceRequest* request = request_it->second;
372 const MediaStreamRequest& ms_request = request->request; 340 const MediaStreamRequest& ms_request = request->request;
373 if (request->requesting_process_id != render_process_id || 341 if (request->requesting_process_id != render_process_id ||
374 request->requesting_view_id != render_view_id || 342 request->requesting_view_id != render_view_id ||
375 ms_request.request_type != MEDIA_GENERATE_STREAM) { 343 ms_request.request_type != MEDIA_GENERATE_STREAM) {
376 ++request_it; 344 ++request_it;
(...skipping 11 matching lines...) Expand all
388 device_it = devices->erase(device_it); 356 device_it = devices->erase(device_it);
389 } else { 357 } else {
390 ++device_it; 358 ++device_it;
391 } 359 }
392 } 360 }
393 361
394 // If this request doesn't have any active devices, remove the request. 362 // If this request doesn't have any active devices, remove the request.
395 if (devices->empty()) { 363 if (devices->empty()) {
396 DeviceRequests::iterator del_itor(request_it); 364 DeviceRequests::iterator del_itor(request_it);
397 ++request_it; 365 ++request_it;
398 scoped_ptr<DeviceRequest> request(del_itor->second); 366 DeleteRequest(del_itor);
399 RemoveRequest(del_itor);
400 } else { 367 } else {
401 ++request_it; 368 ++request_it;
402 } 369 }
403 } 370 }
404 } 371 }
405 372
406 void MediaStreamManager::StopDevice(const StreamDeviceInfo& device_info) { 373 void MediaStreamManager::StopDevice(const StreamDeviceInfo& device_info) {
407 DVLOG(1) << "StopDevice(" 374 DVLOG(1) << "StopDevice("
408 << "{device_info.session_id = " << device_info.session_id << "} " 375 << "{device_info.session_id = " << device_info.session_id << "} "
409 << "{device_id = " << device_info.device.id << "})"; 376 << "{device_id = " << device_info.device.id << "})";
(...skipping 30 matching lines...) Expand all
440 // starts monitoring devices. 407 // starts monitoring devices.
441 if (!requester) { 408 if (!requester) {
442 if (!monitoring_started_) 409 if (!monitoring_started_)
443 StartMonitoring(); 410 StartMonitoring();
444 411
445 return std::string(); 412 return std::string();
446 } 413 }
447 414
448 // Create a new request. 415 // Create a new request.
449 StreamOptions options; 416 StreamOptions options;
450 EnumerationCache* cache = NULL;
451 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { 417 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) {
452 options.audio_type = type; 418 options.audio_type = type;
453 cache = &audio_enumeration_cache_;
454 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { 419 } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) {
455 options.video_type = type; 420 options.video_type = type;
456 cache = &video_enumeration_cache_;
457 } else { 421 } else {
458 NOTREACHED(); 422 NOTREACHED();
459 return std::string(); 423 return std::string();
460 } 424 }
461 425
462 MediaStreamRequest stream_request( 426 MediaStreamRequest stream_request(
463 render_process_id, render_view_id, page_request_id, std::string(), 427 render_process_id, render_view_id, page_request_id,
464 security_origin, MEDIA_ENUMERATE_DEVICES, std::string(), std::string(), 428 security_origin, MEDIA_ENUMERATE_DEVICES, std::string(), std::string(),
465 options.audio_type, options.video_type); 429 options.audio_type, options.video_type);
466 DeviceRequest* request = new DeviceRequest(requester, stream_request, 430 DeviceRequest* request = new DeviceRequest(requester, stream_request,
467 render_process_id, 431 render_process_id,
468 render_view_id); 432 render_view_id);
469 const std::string& label = AddRequest(request); 433 const std::string& label = AddRequest(request);
434 BrowserThread::PostTask(
435 BrowserThread::IO, FROM_HERE,
436 base::Bind(&MediaStreamManager::DoEnumerateDevices,
437 base::Unretained(this), label));
438
439 return label;
440 }
441
442 void MediaStreamManager::DoEnumerateDevices(const std::string& label) {
443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
444 DeviceRequest* request = requests_[label];
445
446 const MediaStreamType type =
447 request->request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE ?
tommi (sloooow) - chröme 2013/10/28 13:48:23 Looks like we're assuming that audio_type will eit
perkj_chrome 2013/10/29 08:52:17 Yes- you can apparently only enumerate one type at
tommi (sloooow) - chröme 2013/10/29 17:21:16 My concern is that there are several other possibl
448 MEDIA_DEVICE_AUDIO_CAPTURE : MEDIA_DEVICE_VIDEO_CAPTURE;
449
450 EnumerationCache* cache =
451 request->request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE ?
tommi (sloooow) - chröme 2013/10/28 13:48:23 nit: Could you check |type| here instead? (since y
perkj_chrome 2013/10/29 08:52:17 Done.
452 &audio_enumeration_cache_ : &video_enumeration_cache_;
470 453
471 if (cache->valid) { 454 if (cache->valid) {
472 // Cached device list of this type exists. Just send it out. 455 // Cached device list of this type exists. Just send it out.
473 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED); 456 request->SetState(type, MEDIA_REQUEST_STATE_REQUESTED);
474 457 request->devices = cache->devices;
475 // Need to post a task since the requester won't have label till 458 FinalizeEnumerateDevices(label, request);
476 // this function returns.
477 BrowserThread::PostTask(
478 BrowserThread::IO, FROM_HERE,
479 base::Bind(&MediaStreamManager::SendCachedDeviceList,
480 base::Unretained(this), cache, label));
481 } else { 459 } else {
482 StartEnumeration(request); 460 StartEnumeration(request);
483 } 461 }
484
485 return label;
486 } 462 }
487 463
488 std::string MediaStreamManager::OpenDevice( 464 std::string MediaStreamManager::OpenDevice(
489 MediaStreamRequester* requester, 465 MediaStreamRequester* requester,
490 int render_process_id, 466 int render_process_id,
491 int render_view_id, 467 int render_view_id,
492 int page_request_id, 468 int page_request_id,
493 const std::string& device_id, 469 const std::string& device_id,
494 MediaStreamType type, 470 MediaStreamType type,
495 const GURL& security_origin) { 471 const GURL& security_origin) {
496 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 472 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
497 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || 473 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
498 type == MEDIA_DEVICE_VIDEO_CAPTURE); 474 type == MEDIA_DEVICE_VIDEO_CAPTURE);
499 475
500 // Create a new request. 476 // Create a new request.
501 StreamOptions options; 477 StreamOptions options;
502 if (IsAudioMediaType(type)) { 478 if (IsAudioMediaType(type)) {
503 options.audio_type = type; 479 options.audio_type = type;
Jói 2013/10/28 11:48:17 This and next line are indented one space too much
perkj_chrome 2013/10/29 08:52:17 Done.
504 options.audio_device_id = device_id; 480 options.audio_device_id = device_id;
505 } else if (IsVideoMediaType(type)) { 481 } else if (IsVideoMediaType(type)) {
506 options.video_type = type; 482 options.video_type = type;
507 options.video_device_id = device_id; 483 options.video_device_id = device_id;
508 } else { 484 } else {
509 NOTREACHED(); 485 NOTREACHED();
510 return std::string(); 486 return std::string();
511 } 487 }
512 488
513 MediaStreamRequest stream_request( 489 MediaStreamRequest stream_request(
514 render_process_id, render_view_id, page_request_id, std::string(), 490 render_process_id, render_view_id, page_request_id,
515 security_origin, MEDIA_OPEN_DEVICE, options.audio_device_id, 491 security_origin, MEDIA_OPEN_DEVICE, options.audio_device_id,
516 options.video_device_id, options.audio_type, options.video_type); 492 options.video_device_id, options.audio_type, options.video_type);
517 DeviceRequest* request = new DeviceRequest(requester, stream_request, 493 DeviceRequest* request = new DeviceRequest(requester, stream_request,
518 render_process_id, 494 render_process_id,
519 render_view_id); 495 render_view_id);
520 const std::string& label = AddRequest(request); 496 const std::string& label = AddRequest(request);
521 StartEnumeration(request); 497 BrowserThread::PostTask(
498 BrowserThread::IO, FROM_HERE,
499 base::Bind(&MediaStreamManager::HandleRequest,
500 base::Unretained(this), label));
522 501
523 return label; 502 return label;
524 } 503 }
525 504
526 void MediaStreamManager::SendCachedDeviceList(
527 EnumerationCache* cache,
528 const std::string& label) {
529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
530 if (cache->valid) {
531 DeviceRequests::iterator it = requests_.find(label);
532 if (it != requests_.end()) {
533 it->second->requester->DevicesEnumerated(label, cache->devices);
534 }
535 }
536 }
537
538 void MediaStreamManager::StartMonitoring() { 505 void MediaStreamManager::StartMonitoring() {
539 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 506 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
540 if (!base::SystemMonitor::Get()) 507 if (!base::SystemMonitor::Get())
541 return; 508 return;
542 509
543 if (!monitoring_started_) { 510 if (!monitoring_started_) {
544 monitoring_started_ = true; 511 monitoring_started_ = true;
545 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); 512 base::SystemMonitor::Get()->AddDevicesChangedObserver(this);
546 513
547 // Enumerate both the audio and video devices to cache the device lists 514 // Enumerate both the audio and video devices to cache the device lists
548 // and send them to media observer. 515 // and send them to media observer.
549 ++active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_CAPTURE]; 516 ++active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_CAPTURE];
550 audio_input_device_manager_->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE); 517 audio_input_device_manager_->EnumerateDevices(MEDIA_DEVICE_AUDIO_CAPTURE);
551 ++active_enumeration_ref_count_[MEDIA_DEVICE_VIDEO_CAPTURE]; 518 ++active_enumeration_ref_count_[MEDIA_DEVICE_VIDEO_CAPTURE];
552 video_capture_manager_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE); 519 video_capture_manager_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
553 } 520 }
554 } 521 }
555 522
556 void MediaStreamManager::StopMonitoring() { 523 void MediaStreamManager::StopMonitoring() {
557 DCHECK_EQ(base::MessageLoop::current(), io_loop_); 524 DCHECK_EQ(base::MessageLoop::current(), io_loop_);
558 if (monitoring_started_) { 525 if (monitoring_started_) {
559 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); 526 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this);
560 monitoring_started_ = false; 527 monitoring_started_ = false;
561 ClearEnumerationCache(&audio_enumeration_cache_); 528 ClearEnumerationCache(&audio_enumeration_cache_);
562 ClearEnumerationCache(&video_enumeration_cache_); 529 ClearEnumerationCache(&video_enumeration_cache_);
563 } 530 }
564 } 531 }
565 532
566 bool MediaStreamManager::TranslateGUIDToRawId(MediaStreamType stream_type, 533 bool MediaStreamManager::TransLateRequestedSourceIdToDeviceId(
Jói 2013/10/28 11:48:17 TransLate -> Translate
perkj_chrome 2013/10/29 08:52:17 Done.
567 const GURL& security_origin, 534 MediaStreamRequest* request) {
568 const std::string& device_guid, 535 // If a specific device has been requested we need to find the real device id.
569 std::string* raw_device_id) { 536 if (request->audio_type == MEDIA_DEVICE_AUDIO_CAPTURE &&
537 !request->requested_audio_device_id.empty()) {
538 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_AUDIO_CAPTURE,
539 request->security_origin,
540 request->requested_audio_device_id,
541 &request->requested_audio_device_id)) {
542 // TODO(perkj): gUM should support mandatory and optional constraints.
tommi (sloooow) - chröme 2013/10/28 13:48:23 nit: case of gUM is inconsistent on the next line
perkj_chrome 2013/10/29 08:52:17 Done.
543 // Ie - if the sourceId is optional but it does not match - guM should
544 // not fail. For now we treat sourceId as a mandatory constraint.
545 return false;
546 }
547 }
548
549 if (request->video_type == MEDIA_DEVICE_VIDEO_CAPTURE &&
550 !request->requested_video_device_id.empty()) {
551 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_VIDEO_CAPTURE,
552 request->security_origin,
553 request->requested_video_device_id,
554 &request->requested_video_device_id)) {
555 // TODO(perkj): guM should support mandatory and optional constraints.
556 // Ie - if the sourceId is optional but it does not match - guM should
557 // not fail. For now we treat sourceId as a mandatory constraint.
558 return false;
559 }
560 }
561 DVLOG(1) << "Requested audio device " << request->requested_audio_device_id;
562 DVLOG(1) << "Requested video device " << request->requested_video_device_id;
563 return true;
564 }
565
566
567 bool MediaStreamManager::TranslateSourceIdToDeviceId(
568 MediaStreamType stream_type,
569 const GURL& security_origin,
570 const std::string& source_id,
571 std::string* device_id) {
570 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || 572 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ||
571 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); 573 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE);
572 if (device_guid.empty()) 574 if (source_id.empty())
tommi (sloooow) - chröme 2013/10/28 13:48:23 should this perhaps be a DCHECK? It seems like th
perkj_chrome 2013/10/29 08:52:17 Done.
573 return false; 575 return false;
574 576
575 EnumerationCache* cache = 577 EnumerationCache* cache =
576 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? 578 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ?
577 &audio_enumeration_cache_ : &video_enumeration_cache_; 579 &audio_enumeration_cache_ : &video_enumeration_cache_;
578 580
579 // If device monitoring hasn't started, the |device_guid| is not valid. 581 // If device monitoring hasn't started, the |device_guid| is not valid.
580 if (!cache->valid) 582 if (!cache->valid)
581 return false; 583 return false;
582 584
583 for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin(); 585 for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin();
584 it != cache->devices.end(); 586 it != cache->devices.end();
585 ++it) { 587 ++it) {
586 if (content::DoesMediaDeviceIDMatchHMAC( 588 if (content::DoesMediaDeviceIDMatchHMAC(
587 security_origin, device_guid, it->device.id)) { 589 security_origin, source_id, it->device.id)) {
tommi (sloooow) - chröme 2013/10/28 13:48:23 Looks like indentation was fine before.
perkj_chrome 2013/10/29 08:52:17 Done.
588 *raw_device_id = it->device.id; 590 *device_id = it->device.id;
589 return true; 591 return true;
590 } 592 }
591 } 593 }
592 return false; 594 return false;
593 } 595 }
594 596
595 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { 597 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) {
596 DCHECK_EQ(base::MessageLoop::current(), io_loop_); 598 DCHECK_EQ(base::MessageLoop::current(), io_loop_);
597 cache->valid = false; 599 cache->valid = false;
598 } 600 }
(...skipping 27 matching lines...) Expand all
626 std::string unique_label; 628 std::string unique_label;
627 do { 629 do {
628 unique_label = RandomLabel(); 630 unique_label = RandomLabel();
629 } while (requests_.find(unique_label) != requests_.end()); 631 } while (requests_.find(unique_label) != requests_.end());
630 632
631 requests_.insert(std::make_pair(unique_label, request)); 633 requests_.insert(std::make_pair(unique_label, request));
632 634
633 return unique_label; 635 return unique_label;
634 } 636 }
635 637
636 void MediaStreamManager::RemoveRequest(DeviceRequests::iterator it) { 638 void MediaStreamManager::DeleteRequest(DeviceRequests::iterator it) {
639 scoped_ptr<DeviceRequest> request(it->second);
tommi (sloooow) - chröme 2013/10/28 13:48:23 This is fine as is but I wonder if it would it mak
perkj_chrome 2013/10/29 08:52:17 nope- does not work as discussed.
637 requests_.erase(it); 640 requests_.erase(it);
638 } 641 }
639 642
640 void MediaStreamManager::PostRequestToUI(const std::string& label) { 643 void MediaStreamManager::PostRequestToUI(const std::string& label) {
641 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 644 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
642 DeviceRequest* request = requests_[label]; 645 DeviceRequest* request = requests_[label];
643 646
644 if (use_fake_ui_) { 647 if (use_fake_ui_) {
645 if (!fake_ui_) 648 if (!fake_ui_)
646 fake_ui_.reset(new FakeMediaStreamUIProxy()); 649 fake_ui_.reset(new FakeMediaStreamUIProxy());
(...skipping 30 matching lines...) Expand all
677 void MediaStreamManager::HandleRequest(const std::string& label) { 680 void MediaStreamManager::HandleRequest(const std::string& label) {
678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
679 DeviceRequest* request = requests_[label]; 682 DeviceRequest* request = requests_[label];
680 683
681 const MediaStreamType audio_type = request->request.audio_type; 684 const MediaStreamType audio_type = request->request.audio_type;
682 const MediaStreamType video_type = request->request.video_type; 685 const MediaStreamType video_type = request->request.video_type;
683 686
684 bool is_web_contents_capture = 687 bool is_web_contents_capture =
685 audio_type == MEDIA_TAB_AUDIO_CAPTURE || 688 audio_type == MEDIA_TAB_AUDIO_CAPTURE ||
686 video_type == MEDIA_TAB_VIDEO_CAPTURE; 689 video_type == MEDIA_TAB_VIDEO_CAPTURE;
690 if (is_web_contents_capture && !SetupTabCaptureRequest(request)) {
691 FinalizeRequestFailed(label);
692 return;
693 }
687 694
688 bool is_screen_capture = 695 bool is_screen_capture =
689 video_type == MEDIA_DESKTOP_VIDEO_CAPTURE; 696 video_type == MEDIA_DESKTOP_VIDEO_CAPTURE;
697 if (is_screen_capture && !SetupScreenCaptureRequest(request)) {
698 FinalizeRequestFailed(label);
699 return;
700 }
690 701
691 if (!is_web_contents_capture && 702 if (!is_web_contents_capture &&
692 !is_screen_capture && 703 !is_screen_capture &&
693 ((IsAudioMediaType(audio_type) && !audio_enumeration_cache_.valid) || 704 ((IsAudioMediaType(audio_type) && !audio_enumeration_cache_.valid) ||
694 (IsVideoMediaType(video_type) && !video_enumeration_cache_.valid))) { 705 (IsVideoMediaType(video_type) && !video_enumeration_cache_.valid))) {
695 // Enumerate the devices if there is no valid device lists to be used. 706 // Enumerate the devices if there is no valid device lists to be used.
696 StartEnumeration(request); 707 StartEnumeration(request);
697 return; 708 return;
698 } 709 }
699 710
711 // If a specific device has been requested we need to find the real device id.
712 if (!TransLateRequestedSourceIdToDeviceId(&request->request)) {
713 FinalizeRequestFailed(label);
714 return;
715 }
716
700 // No need to do new device enumerations, post the request to UI 717 // No need to do new device enumerations, post the request to UI
701 // immediately. 718 // immediately.
702 if (IsAudioMediaType(audio_type)) 719 if (IsAudioMediaType(audio_type))
703 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); 720 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL);
704 if (IsVideoMediaType(video_type)) 721 if (IsVideoMediaType(video_type))
705 request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); 722 request->SetState(video_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL);
706 723
707 PostRequestToUI(label); 724 PostRequestToUI(label);
708 } 725 }
709 726
727 bool MediaStreamManager::SetupTabCaptureRequest(DeviceRequest* request) {
728 DCHECK(request->request.audio_type == MEDIA_TAB_AUDIO_CAPTURE ||
729 request->request.video_type == MEDIA_TAB_VIDEO_CAPTURE);
730
731 MediaStreamRequest* ms_request = &request->request;
732 // Customize options for a WebContents based capture.
733 int target_render_process_id = 0;
734 int target_render_view_id = 0;
735
736 // TODO(justinlin): Can't plumb audio mirroring using stream type right
737 // now, so plumbing by device_id. Will revisit once it's refactored.
738 // http://crbug.com/163100
739 std::string tab_capture_device_id =
740 WebContentsCaptureUtil::AppendWebContentsDeviceScheme(
741 !ms_request->requested_video_device_id.empty() ?
742 ms_request->requested_video_device_id :
743 ms_request->requested_audio_device_id);
744
745 bool has_valid_device_id = WebContentsCaptureUtil::ExtractTabCaptureTarget(
746 tab_capture_device_id, &target_render_process_id,
747 &target_render_view_id);
748 if (!has_valid_device_id ||
749 (ms_request->audio_type != MEDIA_TAB_AUDIO_CAPTURE &&
750 ms_request->audio_type != MEDIA_NO_SERVICE) ||
751 (ms_request->video_type != MEDIA_TAB_VIDEO_CAPTURE &&
752 ms_request->video_type != MEDIA_NO_SERVICE)) {
753 return false;
754 }
755 ms_request->tab_capture_device_id = tab_capture_device_id;
756 ms_request->render_process_id = target_render_process_id;
757 ms_request->render_view_id = target_render_view_id;
758 DVLOG(3) << "SetupTabCaptureRequest "
759 << ", {tab_capture_device_id = " << tab_capture_device_id << "}"
760 << ", {target_render_process_id = " << target_render_process_id
761 << "}"
762 << ", {target_render_view_id = " << target_render_view_id << "}";
763 return true;
764 }
765
766 bool MediaStreamManager::SetupScreenCaptureRequest(DeviceRequest* request) {
767 DCHECK(request->request.audio_type == MEDIA_DESKTOP_VIDEO_CAPTURE ||
768 request->request.video_type == MEDIA_LOOPBACK_AUDIO_CAPTURE);
769 const MediaStreamRequest& ms_request = request->request;
770
771 // For screen capture we only support two valid combinations:
772 // (1) screen video capture only, or
773 // (2) screen video capture with loopback audio capture.
774 if (ms_request.video_type != MEDIA_DESKTOP_VIDEO_CAPTURE ||
775 (ms_request.audio_type != MEDIA_NO_SERVICE &&
776 ms_request.audio_type != MEDIA_LOOPBACK_AUDIO_CAPTURE)) {
777 // TODO(sergeyu): Surface error message to the calling JS code.
778 LOG(ERROR) << "Invalid screen capture request.";
779 return false;
780 }
781 return true;
782 }
783
784 bool MediaStreamManager::FindRequestedDeviceInfo(
785 const std::string& source_id,
786 int render_process_id,
787 int render_view_id,
788 MediaStreamRequestType type,
789 StreamDeviceInfo* device_info) {
790 for (DeviceRequests::const_iterator it = requests_.begin();
791 it != requests_.end() ; ++it) {
792 const DeviceRequest* request = it->second;
793 if (request->request.render_process_id ==render_process_id &&
tommi (sloooow) - chröme 2013/10/28 13:48:23 spaces
perkj_chrome 2013/10/29 08:52:17 Done.
794 request->request.render_view_id == render_view_id &&
795 request->request.request_type == type) {
796 for (StreamDeviceInfoArray::const_iterator device_it =
797 request->devices.begin();
798 device_it != request->devices.end(); ++device_it) {
799 if (source_id == device_it->device.id) {
800 if (device_info)
801 *device_info = *device_it;
no longer working on chromium 2013/10/28 09:13:29 Is allowed to have device_info to be NULL? If not,
tommi (sloooow) - chröme 2013/10/28 13:48:23 If it's not allowed to be NULL, no need to DCHECK
perkj_chrome 2013/10/29 08:52:17 Done.
perkj_chrome 2013/10/29 08:52:17 Done.
802 return true;
803 }
804 }
805 }
806 }
807 return false;
808 }
809
710 bool MediaStreamManager::FindExistingRequestedDeviceInfo( 810 bool MediaStreamManager::FindExistingRequestedDeviceInfo(
tommi (sloooow) - chröme 2013/10/28 13:48:23 return const MediaStreamType*?
perkj_chrome 2013/10/29 08:52:17 This function returns two things- device_info and
711 int render_process_id, 811 int render_process_id,
712 int render_view_id, 812 int render_view_id,
813 GURL security_origin,
no longer working on chromium 2013/10/28 09:13:29 nit, const GURL& security_origin,
perkj_chrome 2013/10/29 08:52:17 Done.
713 MediaStreamRequestType type, 814 MediaStreamRequestType type,
714 const std::string& device_id, 815 const std::string& device_id,
816 MediaStreamType device_type,
715 StreamDeviceInfo* device_info, 817 StreamDeviceInfo* device_info,
716 MediaRequestState* request_state) const { 818 MediaRequestState* request_state) const {
717 DCHECK(device_info); 819 DCHECK(device_info);
718 DCHECK(request_state); 820 DCHECK(request_state);
821
822 std::string source_id = content::GetHMACForMediaDeviceID(
823 security_origin,
824 device_id);
825
719 for (DeviceRequests::const_iterator it = requests_.begin(); 826 for (DeviceRequests::const_iterator it = requests_.begin();
720 it != requests_.end() ; ++it) { 827 it != requests_.end() ; ++it) {
721 const DeviceRequest* request = it->second; 828 const DeviceRequest* request = it->second;
722 if (request->requesting_process_id ==render_process_id && 829 if (request->requesting_process_id ==render_process_id &&
723 request->requesting_view_id == render_view_id && 830 request->requesting_view_id == render_view_id &&
724 request->request.request_type == type) { 831 request->request.request_type == type) {
725 for (StreamDeviceInfoArray::const_iterator device_it = 832 for (StreamDeviceInfoArray::const_iterator device_it =
726 request->devices.begin(); 833 request->devices.begin();
727 device_it != request->devices.end(); ++device_it) { 834 device_it != request->devices.end(); ++device_it) {
728 if (device_it->device.id == device_id) { 835 if (device_it->device.id == source_id &&
836 device_it->device.type == device_type) {
729 *device_info = *device_it; 837 *device_info = *device_it;
730 *request_state = request->state(device_it->device.type); 838 *request_state = request->state(device_it->device.type);
731 return true; 839 return true;
732 } 840 }
733 } 841 }
734 } 842 }
735 } 843 }
736 return false; 844 return false;
737 } 845 }
738 846
847 void MediaStreamManager::FinalizeGenerateStream(const std::string& label,
848 DeviceRequest* request) {
849 const StreamDeviceInfoArray& requested_devices = request->devices;
850
851 // Partition the array of devices into audio vs video.
852 StreamDeviceInfoArray audio_devices, video_devices;
853 for (StreamDeviceInfoArray::const_iterator device_it =
854 requested_devices.begin();
tommi (sloooow) - chröme 2013/10/28 13:48:23 fix indentation
perkj_chrome 2013/10/29 08:52:17 Done.
855 device_it != requested_devices.end(); ++device_it) {
856 if (IsAudioMediaType(device_it->device.type)) {
857 audio_devices.push_back(*device_it);
858 } else if (IsVideoMediaType(device_it->device.type)) {
859 video_devices.push_back(*device_it);
860 } else {
861 NOTREACHED();
862 }
863 }
864
865 request->requester->StreamGenerated(label, audio_devices, video_devices);
866 }
867
868 void MediaStreamManager::FinalizeRequestFailed(
869 const std::string& label) {
870 DeviceRequests::iterator request_it = requests_.find(label);
871 if (request_it == requests_.end())
872 return;
873
874 DeviceRequest* request(request_it->second);
875 if (request->requester)
876 request->requester->StreamGenerationFailed(label);
877
878 if (request->request.request_type == MEDIA_DEVICE_ACCESS &&
879 !request->callback.is_null()) {
880 request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass());
881 }
882
883 DeleteRequest(request_it);
884 }
885
886 void MediaStreamManager::FinalizeOpenDevice(const std::string& label,
887 DeviceRequest* request) {
888 const StreamDeviceInfoArray& requested_devices = request->devices;
889 request->requester->DeviceOpened(label, requested_devices.front());
890 }
891
892 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label,
893 DeviceRequest* request) {
894 for (StreamDeviceInfoArray::iterator it = request->devices.begin();
895 it != request->devices.end(); ++it) {
896 it->device.id = content::GetHMACForMediaDeviceID(
897 request->request.security_origin, it->device.id);
898 }
899 request->requester->DevicesEnumerated(label, request->devices);
900 }
901
902 void MediaStreamManager::FinalizeMediaAccessRequest(
903 const std::string& label,
904 const MediaStreamDevices& devices) {
905 DeviceRequests::iterator request_it = requests_.find(label);
906 if (request_it == requests_.end())
907 return;
908 DeviceRequest* request(request_it->second);
no longer working on chromium 2013/10/28 09:13:29 nit, move this declaration below the empty line.
perkj_chrome 2013/10/29 08:52:17 rewritten a bit now.
909
910 if (!request->callback.is_null())
911 request->callback.Run(devices, request->ui_proxy.Pass());
912
913 // Delete the request since it is done.
914 DeleteRequest(request_it);
915 }
916
739 void MediaStreamManager::InitializeDeviceManagersOnIOThread() { 917 void MediaStreamManager::InitializeDeviceManagersOnIOThread() {
740 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 918 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
741 if (device_thread_) 919 if (device_thread_)
742 return; 920 return;
743 921
744 device_thread_.reset(new base::Thread("MediaStreamDeviceThread")); 922 device_thread_.reset(new base::Thread("MediaStreamDeviceThread"));
745 #if defined(OS_WIN) 923 #if defined(OS_WIN)
746 device_thread_->init_com_with_mta(true); 924 device_thread_->init_com_with_mta(true);
747 #endif 925 #endif
748 CHECK(device_thread_->Start()); 926 CHECK(device_thread_->Start());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 request->SetState(device_it->device.type, MEDIA_REQUEST_STATE_DONE); 961 request->SetState(device_it->device.type, MEDIA_REQUEST_STATE_DONE);
784 962
785 if (IsAudioMediaType(device_it->device.type)) { 963 if (IsAudioMediaType(device_it->device.type)) {
786 // Store the native audio parameters in the device struct. 964 // Store the native audio parameters in the device struct.
787 // TODO(xians): Handle the tab capture sample rate/channel layout 965 // TODO(xians): Handle the tab capture sample rate/channel layout
788 // in AudioInputDeviceManager::Open(). 966 // in AudioInputDeviceManager::Open().
789 if (device_it->device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { 967 if (device_it->device.type != content::MEDIA_TAB_AUDIO_CAPTURE) {
790 const StreamDeviceInfo* info = 968 const StreamDeviceInfo* info =
791 audio_input_device_manager_->GetOpenedDeviceInfoById( 969 audio_input_device_manager_->GetOpenedDeviceInfoById(
792 device_it->session_id); 970 device_it->session_id);
793 DCHECK_EQ(info->device.id, device_it->device.id);
794 device_it->device.input = info->device.input; 971 device_it->device.input = info->device.input;
795 device_it->device.matched_output = info->device.matched_output; 972 device_it->device.matched_output = info->device.matched_output;
796 } 973 }
797 } 974 }
798 if (RequestDone(*request)) 975 if (RequestDone(*request))
799 HandleRequestDone(label, request); 976 HandleRequestDone(label, request);
800 break; 977 break;
801 } 978 }
802 } 979 }
803 } 980 }
804 } 981 }
805 982
806 void MediaStreamManager::HandleRequestDone(const std::string& label, 983 void MediaStreamManager::HandleRequestDone(const std::string& label,
807 DeviceRequest* request) { 984 DeviceRequest* request) {
808 DCHECK(RequestDone(*request)); 985 DCHECK(RequestDone(*request));
809 DVLOG(1) << "HandleRequestDone(" 986 DVLOG(1) << "HandleRequestDone("
810 << ", {label = " << label << "})"; 987 << ", {label = " << label << "})";
811 988
812 const StreamDeviceInfoArray& requested_devices = request->devices;
813 switch (request->request.request_type) { 989 switch (request->request.request_type) {
814 case MEDIA_OPEN_DEVICE: 990 case MEDIA_OPEN_DEVICE:
815 request->requester->DeviceOpened(label, requested_devices.front()); 991 FinalizeOpenDevice(label, request);
816 break; 992 break;
817 case MEDIA_GENERATE_STREAM: { 993 case MEDIA_GENERATE_STREAM: {
818 // Partition the array of devices into audio vs video. 994 FinalizeGenerateStream(label, request);
819 StreamDeviceInfoArray audio_devices, video_devices;
820 for (StreamDeviceInfoArray::const_iterator device_it =
821 requested_devices.begin();
822 device_it != requested_devices.end(); ++device_it) {
823 if (IsAudioMediaType(device_it->device.type)) {
824 audio_devices.push_back(*device_it);
825 } else if (IsVideoMediaType(device_it->device.type)) {
826 video_devices.push_back(*device_it);
827 } else {
828 NOTREACHED();
829 }
830 }
831
832 request->requester->StreamGenerated(label, audio_devices, video_devices);
833 break; 995 break;
834 } 996 }
835 default: 997 default:
836 NOTREACHED(); 998 NOTREACHED();
837 break; 999 break;
838 } 1000 }
839 1001
840 if (request->ui_proxy.get()) { 1002 if (request->ui_proxy.get()) {
841 request->ui_proxy->OnStarted( 1003 request->ui_proxy->OnStarted(
842 base::Bind(&MediaStreamManager::StopStreamFromUI, 1004 base::Bind(&MediaStreamManager::StopStreamFromUI,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 if (it->second->request.request_type != MEDIA_ENUMERATE_DEVICES) 1044 if (it->second->request.request_type != MEDIA_ENUMERATE_DEVICES)
883 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); 1045 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL);
884 label_list.push_back(it->first); 1046 label_list.push_back(it->first);
885 } 1047 }
886 } 1048 }
887 for (std::list<std::string>::iterator it = label_list.begin(); 1049 for (std::list<std::string>::iterator it = label_list.begin();
888 it != label_list.end(); ++it) { 1050 it != label_list.end(); ++it) {
889 DeviceRequest* request = requests_[*it]; 1051 DeviceRequest* request = requests_[*it];
890 switch (request->request.request_type) { 1052 switch (request->request.request_type) {
891 case MEDIA_ENUMERATE_DEVICES: 1053 case MEDIA_ENUMERATE_DEVICES:
892 if (need_update_clients && request->requester) 1054 if (need_update_clients && request->requester) {
893 request->requester->DevicesEnumerated(*it, devices); 1055 request->devices = devices;
1056 FinalizeEnumerateDevices(*it, request);
1057 }
894 break; 1058 break;
895 default: 1059 default:
896 if (request->state(request->request.audio_type) == 1060 if (request->state(request->request.audio_type) ==
897 MEDIA_REQUEST_STATE_REQUESTED || 1061 MEDIA_REQUEST_STATE_REQUESTED ||
898 request->state(request->request.video_type) == 1062 request->state(request->request.video_type) ==
899 MEDIA_REQUEST_STATE_REQUESTED) { 1063 MEDIA_REQUEST_STATE_REQUESTED) {
900 // We are doing enumeration for other type of media, wait until it is 1064 // We are doing enumeration for other type of media, wait until it is
901 // all done before posting the request to UI because UI needs 1065 // all done before posting the request to UI because UI needs
902 // the device lists to handle the request. 1066 // the device lists to handle the request.
903 break; 1067 break;
904 } 1068 }
905 1069
906 // Post the request to UI for permission approval. 1070 // Continue to handle the request.
907 PostRequestToUI(*it); 1071 HandleRequest(*it);
908 break; 1072 break;
909 } 1073 }
910 } 1074 }
911 label_list.clear(); 1075 label_list.clear();
912 --active_enumeration_ref_count_[stream_type]; 1076 --active_enumeration_ref_count_[stream_type];
913 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); 1077 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0);
914 } 1078 }
915 1079
916 void MediaStreamManager::Error(MediaStreamType stream_type,
917 int capture_session_id,
918 MediaStreamProviderError error) {
919 // Find the device for the error call.
920 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
921 DVLOG(1) << "Error("
922 << "{stream_type = " << stream_type << "} ,"
923 << "{capture_session_id = " << capture_session_id << "})";
924
925
926 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end();
927 ++it) {
928 StreamDeviceInfoArray& devices = it->second->devices;
929
930 // TODO(miu): BUG. It's possible for the audio (or video) device array in
931 // the "requester" to become out-of-sync with the order of devices we have
932 // here. See http://crbug.com/147650
933 int audio_device_idx = -1;
934 int video_device_idx = -1;
935 for (StreamDeviceInfoArray::iterator device_it = devices.begin();
936 device_it != devices.end(); ++device_it) {
937 if (IsAudioMediaType(device_it->device.type)) {
938 ++audio_device_idx;
939 } else if (IsVideoMediaType(device_it->device.type)) {
940 ++video_device_idx;
941 } else {
942 NOTREACHED();
943 continue;
944 }
945 if (device_it->device.type != stream_type ||
946 device_it->session_id != capture_session_id) {
947 continue;
948 }
949 // We've found the failing device. Find the error case:
950 // An error should only be reported to the MediaStreamManager if
951 // the request has not been fulfilled yet.
952 DCHECK(it->second->state(stream_type) != MEDIA_REQUEST_STATE_DONE);
953 if (it->second->state(stream_type) != MEDIA_REQUEST_STATE_DONE) {
954 // Request is not done, devices are not opened in this case.
955 if (devices.size() <= 1) {
956 scoped_ptr<DeviceRequest> request(it->second);
957 // 1. Device not opened and no other devices for this request ->
958 // signal stream error and remove the request.
959 if (request->requester)
960 request->requester->StreamGenerationFailed(it->first);
961
962 RemoveRequest(it);
963 } else {
964 // 2. Not opened but other devices exists for this request -> remove
965 // device from list, but don't signal an error.
966 devices.erase(device_it); // NOTE: This invalidates device_it!
967 it->second->SetState(stream_type, MEDIA_REQUEST_STATE_ERROR);
968 DVLOG(1) << "Error("
969 << ", {capture_session_id = " << capture_session_id << "})";
970 }
971 }
972 if (RequestDone(*it->second))
973 HandleRequestDone(it->first, it->second);
974 break;
975 }
976 }
977 }
978
979 void MediaStreamManager::HandleAccessRequestResponse( 1080 void MediaStreamManager::HandleAccessRequestResponse(
980 const std::string& label, 1081 const std::string& label,
981 const MediaStreamDevices& devices) { 1082 const MediaStreamDevices& devices) {
982 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1083 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
983 DVLOG(1) << "HandleAccessRequestResponse(" 1084 DVLOG(1) << "HandleAccessRequestResponse("
984 << ", {label = " << label << "})"; 1085 << ", {label = " << label << "})";
985 1086
986 DeviceRequests::iterator request_it = requests_.find(label); 1087 DeviceRequests::iterator request_it = requests_.find(label);
987 if (request_it == requests_.end()) { 1088 if (request_it == requests_.end()) {
988 return; 1089 return;
989 } 1090 }
990 1091
1092 DeviceRequest* request = request_it->second;
1093 if (request->request.request_type == MEDIA_DEVICE_ACCESS) {
1094 FinalizeMediaAccessRequest(label, devices);
1095 return;
1096 }
1097
991 // Handle the case when the request was denied. 1098 // Handle the case when the request was denied.
992 if (devices.empty()) { 1099 if (devices.empty()) {
993 // Notify the users about the request result. 1100 FinalizeRequestFailed(label);
994 scoped_ptr<DeviceRequest> request(request_it->second);
995 if (request->requester)
996 request->requester->StreamGenerationFailed(label);
997
998 if (request->request.request_type == MEDIA_DEVICE_ACCESS &&
999 !request->callback.is_null()) {
1000 request->callback.Run(MediaStreamDevices(), request->ui_proxy.Pass());
1001 }
1002
1003 RemoveRequest(request_it);
1004 return;
1005 }
1006
1007 if (request_it->second->request.request_type == MEDIA_DEVICE_ACCESS) {
1008 scoped_ptr<DeviceRequest> request(request_it->second);
1009 if (!request->callback.is_null())
1010 request->callback.Run(devices, request->ui_proxy.Pass());
1011
1012 // Delete the request since it is done.
1013 RemoveRequest(request_it);
1014 return; 1101 return;
1015 } 1102 }
1016 1103
1017 // Process all newly-accepted devices for this request. 1104 // Process all newly-accepted devices for this request.
1018 DeviceRequest* request = request_it->second;
1019 bool found_audio = false; 1105 bool found_audio = false;
1020 bool found_video = false; 1106 bool found_video = false;
1021 for (MediaStreamDevices::const_iterator device_it = devices.begin(); 1107 for (MediaStreamDevices::const_iterator device_it = devices.begin();
1022 device_it != devices.end(); ++device_it) { 1108 device_it != devices.end(); ++device_it) {
1023 StreamDeviceInfo device_info; 1109 StreamDeviceInfo device_info;
1024 device_info.device = *device_it; 1110 device_info.device = *device_it;
1025 1111
1026 // TODO(justinlin): Nicer way to do this? 1112 // TODO(justinlin): Nicer way to do this?
1027 // Re-append the device's id since we lost it when posting request to UI. 1113 // Re-append the device's id since we lost it when posting request to UI.
1028 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE || 1114 if (device_info.device.type == content::MEDIA_TAB_VIDEO_CAPTURE ||
(...skipping 20 matching lines...) Expand all
1049 if (device_info.device.type == request->request.audio_type) { 1135 if (device_info.device.type == request->request.audio_type) {
1050 found_audio = true; 1136 found_audio = true;
1051 } else if (device_info.device.type == request->request.video_type) { 1137 } else if (device_info.device.type == request->request.video_type) {
1052 found_video = true; 1138 found_video = true;
1053 } 1139 }
1054 1140
1055 // If this is request for a new MediaStream, a device is only opened once 1141 // If this is request for a new MediaStream, a device is only opened once
1056 // per render view. This is so that the permission to use a device can be 1142 // per render view. This is so that the permission to use a device can be
1057 // revoked by a single call to StopStreamDevice regardless of how many 1143 // revoked by a single call to StopStreamDevice regardless of how many
1058 // MediaStreams it is being used in. 1144 // MediaStreams it is being used in.
1059
1060 if (request->request.request_type == MEDIA_GENERATE_STREAM) { 1145 if (request->request.request_type == MEDIA_GENERATE_STREAM) {
1061 MediaRequestState state; 1146 MediaRequestState state;
1062 if (FindExistingRequestedDeviceInfo(request->requesting_process_id, 1147 if (FindExistingRequestedDeviceInfo(request->requesting_process_id,
1063 request->requesting_view_id, 1148 request->requesting_view_id,
1149 request->request.security_origin,
1064 request->request.request_type, 1150 request->request.request_type,
1065 device_it->id, 1151 device_info.device.id,
1152 device_info.device.type,
1066 &device_info, 1153 &device_info,
1067 &state)) { 1154 &state)) {
1068 request->devices.push_back(device_info); 1155 request->devices.push_back(device_info);
1069 request->SetState(device_info.device.type, state); 1156 request->SetState(device_info.device.type, state);
1070 DVLOG(1) << "HandleAccessRequestResponse - device already opened " 1157 DVLOG(1) << "HandleAccessRequestResponse - device already opened "
1071 << ", {label = " << label << "}" 1158 << ", {label = " << label << "}"
1072 << ", device_id = " << device_it->id << "}"; 1159 << ", device_id = " << device_it->id << "}";
1073 continue; 1160 continue;
1074 } 1161 }
1075 } 1162 }
1076 device_info.session_id = 1163 device_info.session_id =
1077 GetDeviceManager(device_info.device.type)->Open(device_info); 1164 GetDeviceManager(device_info.device.type)->Open(device_info);
1165 device_info.device.id = content::GetHMACForMediaDeviceID(
1166 request->request.security_origin,
1167 device_info.device.id);
1078 request->devices.push_back(device_info); 1168 request->devices.push_back(device_info);
1169
1079 request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING); 1170 request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING);
1080 DVLOG(1) << "HandleAccessRequestResponse - opening device " 1171 DVLOG(1) << "HandleAccessRequestResponse - opening device "
1081 << ", {label = " << label << "}" 1172 << ", {label = " << label << "}"
1082 << ", {device_id = " << device_it->id << "}" 1173 << ", {device_id = " << device_info.device.id << "}"
1083 << ", {session_id = " << device_info.session_id << "}"; 1174 << ", {session_id = " << device_info.session_id << "}";
1084 } 1175 }
1085 1176
1086 // Check whether we've received all stream types requested. 1177 // Check whether we've received all stream types requested.
1087 if (!found_audio && IsAudioMediaType(request->request.audio_type)) { 1178 if (!found_audio && IsAudioMediaType(request->request.audio_type)) {
1088 request->SetState(request->request.audio_type, MEDIA_REQUEST_STATE_ERROR); 1179 request->SetState(request->request.audio_type, MEDIA_REQUEST_STATE_ERROR);
1089 DVLOG(1) << "Set no audio found label " << label; 1180 DVLOG(1) << "Set no audio found label " << label;
1090 } 1181 }
1091 1182
1092 if (!found_video && IsVideoMediaType(request->request.video_type)) 1183 if (!found_video && IsVideoMediaType(request->request.video_type))
(...skipping 25 matching lines...) Expand all
1118 audio_input_device_manager()->UseFakeDevice(); 1209 audio_input_device_manager()->UseFakeDevice();
1119 } 1210 }
1120 1211
1121 void MediaStreamManager::UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui) { 1212 void MediaStreamManager::UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui) {
1122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1123 use_fake_ui_ = true; 1214 use_fake_ui_ = true;
1124 fake_ui_ = fake_ui.Pass(); 1215 fake_ui_ = fake_ui.Pass();
1125 } 1216 }
1126 1217
1127 void MediaStreamManager::WillDestroyCurrentMessageLoop() { 1218 void MediaStreamManager::WillDestroyCurrentMessageLoop() {
1219 DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()";
1128 DCHECK_EQ(base::MessageLoop::current(), io_loop_); 1220 DCHECK_EQ(base::MessageLoop::current(), io_loop_);
1129 DCHECK(requests_.empty()); 1221 DCHECK(requests_.empty());
1130 if (device_thread_) { 1222 if (device_thread_) {
1131 StopMonitoring(); 1223 StopMonitoring();
1132 1224
1133 video_capture_manager_->Unregister(); 1225 video_capture_manager_->Unregister();
1134 audio_input_device_manager_->Unregister(); 1226 audio_input_device_manager_->Unregister();
1135 device_thread_.reset(); 1227 device_thread_.reset();
1136 } 1228 }
1137 1229
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 } 1311 }
1220 1312
1221 // Always do enumeration even though some enumeration is in progress, 1313 // Always do enumeration even though some enumeration is in progress,
1222 // because those enumeration commands could be sent before these devices 1314 // because those enumeration commands could be sent before these devices
1223 // change. 1315 // change.
1224 ++active_enumeration_ref_count_[stream_type]; 1316 ++active_enumeration_ref_count_[stream_type];
1225 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); 1317 GetDeviceManager(stream_type)->EnumerateDevices(stream_type);
1226 } 1318 }
1227 1319
1228 } // namespace content 1320 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698