OLD | NEW |
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 MediaStreamType stream_type) { | 62 MediaStreamType stream_type) { |
63 return (request.audio_type == stream_type || | 63 return (request.audio_type == stream_type || |
64 request.video_type == stream_type); | 64 request.video_type == stream_type); |
65 } | 65 } |
66 | 66 |
67 class MediaStreamManager::DeviceRequest { | 67 class MediaStreamManager::DeviceRequest { |
68 public: | 68 public: |
69 DeviceRequest(MediaStreamRequester* requester, | 69 DeviceRequest(MediaStreamRequester* requester, |
70 const MediaStreamRequest& request, | 70 const MediaStreamRequest& request, |
71 int requesting_process_id, | 71 int requesting_process_id, |
72 int requesting_view_id) | 72 int requesting_view_id, |
| 73 ResourceContext* resource_context) |
73 : requester(requester), | 74 : requester(requester), |
74 request(request), | 75 request(request), |
75 requesting_process_id(requesting_process_id), | 76 requesting_process_id(requesting_process_id), |
76 requesting_view_id(requesting_view_id), | 77 requesting_view_id(requesting_view_id), |
| 78 resource_context(resource_context), |
77 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED) { | 79 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED) { |
78 } | 80 } |
79 | 81 |
80 ~DeviceRequest() {} | 82 ~DeviceRequest() {} |
81 | 83 |
82 // Update the request state and notify observers. | 84 // Update the request state and notify observers. |
83 void SetState(MediaStreamType stream_type, MediaRequestState new_state) { | 85 void SetState(MediaStreamType stream_type, MediaRequestState new_state) { |
84 if (stream_type == NUM_MEDIA_TYPES) { | 86 if (stream_type == NUM_MEDIA_TYPES) { |
85 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { | 87 for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) { |
86 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); | 88 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 // MediaStreamRequest::render_process_id which in the tab capture case | 128 // MediaStreamRequest::render_process_id which in the tab capture case |
127 // specifies the target renderer from which audio and video is captured. | 129 // specifies the target renderer from which audio and video is captured. |
128 const int requesting_process_id; | 130 const int requesting_process_id; |
129 | 131 |
130 // The render view id that requested this stream to be generated and that | 132 // The render view id that requested this stream to be generated and that |
131 // will receive a handle to the MediaStream. This may be different from | 133 // will receive a handle to the MediaStream. This may be different from |
132 // MediaStreamRequest::render_view_id which in the tab capture case | 134 // MediaStreamRequest::render_view_id which in the tab capture case |
133 // specifies the target renderer from which audio and video is captured. | 135 // specifies the target renderer from which audio and video is captured. |
134 const int requesting_view_id; | 136 const int requesting_view_id; |
135 | 137 |
| 138 ResourceContext* resource_context; |
| 139 |
136 StreamDeviceInfoArray devices; | 140 StreamDeviceInfoArray devices; |
137 | 141 |
138 // Callback to the requester which audio/video devices have been selected. | 142 // Callback to the requester which audio/video devices have been selected. |
139 // It can be null if the requester has no interest to know the result. | 143 // It can be null if the requester has no interest to know the result. |
140 // Currently it is only used by |DEVICE_ACCESS| type. | 144 // Currently it is only used by |DEVICE_ACCESS| type. |
141 MediaStreamManager::MediaRequestResponseCallback callback; | 145 MediaStreamManager::MediaRequestResponseCallback callback; |
142 | 146 |
143 scoped_ptr<MediaStreamUIProxy> ui_proxy; | 147 scoped_ptr<MediaStreamUIProxy> ui_proxy; |
144 | 148 |
145 private: | 149 private: |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 int page_request_id, | 208 int page_request_id, |
205 const StreamOptions& options, | 209 const StreamOptions& options, |
206 const GURL& security_origin, | 210 const GURL& security_origin, |
207 const MediaRequestResponseCallback& callback) { | 211 const MediaRequestResponseCallback& callback) { |
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
209 // Create a new request based on options. | 213 // Create a new request based on options. |
210 MediaStreamRequest stream_request( | 214 MediaStreamRequest stream_request( |
211 render_process_id, render_view_id, page_request_id, | 215 render_process_id, render_view_id, page_request_id, |
212 security_origin, MEDIA_DEVICE_ACCESS, std::string(), std::string(), | 216 security_origin, MEDIA_DEVICE_ACCESS, std::string(), std::string(), |
213 options.audio_type, options.video_type); | 217 options.audio_type, options.video_type); |
| 218 // TODO(perkj): The argument list with NULL parameters to DeviceRequest |
| 219 // suggests that this is the wrong design. Can this be refactored? |
214 DeviceRequest* request = new DeviceRequest(NULL, stream_request, | 220 DeviceRequest* request = new DeviceRequest(NULL, stream_request, |
215 render_process_id, render_view_id); | 221 render_process_id, render_view_id, |
| 222 NULL); |
216 const std::string& label = AddRequest(request); | 223 const std::string& label = AddRequest(request); |
217 | 224 |
218 request->callback = callback; | 225 request->callback = callback; |
219 // Post a task and handle the request asynchronously. The reason is that the | 226 // Post a task and handle the request asynchronously. The reason is that the |
220 // requester won't have a label for the request until this function returns | 227 // requester won't have a label for the request until this function returns |
221 // and thus can not handle a response. Using base::Unretained is safe since | 228 // and thus can not handle a response. Using base::Unretained is safe since |
222 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 229 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
223 // been stopped. | 230 // been stopped. |
224 BrowserThread::PostTask( | 231 BrowserThread::PostTask( |
225 BrowserThread::IO, FROM_HERE, | 232 BrowserThread::IO, FROM_HERE, |
226 base::Bind(&MediaStreamManager::SetupRequest, | 233 base::Bind(&MediaStreamManager::SetupRequest, |
227 base::Unretained(this), label)); | 234 base::Unretained(this), label)); |
228 return label; | 235 return label; |
229 } | 236 } |
230 | 237 |
231 std::string MediaStreamManager::GenerateStream(MediaStreamRequester* requester, | 238 std::string MediaStreamManager::GenerateStream(MediaStreamRequester* requester, |
232 int render_process_id, | 239 int render_process_id, |
233 int render_view_id, | 240 int render_view_id, |
| 241 ResourceContext* rc, |
234 int page_request_id, | 242 int page_request_id, |
235 const StreamOptions& options, | 243 const StreamOptions& options, |
236 const GURL& security_origin) { | 244 const GURL& security_origin) { |
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
238 DVLOG(1) << "GenerateStream()"; | 246 DVLOG(1) << "GenerateStream()"; |
239 if (CommandLine::ForCurrentProcess()->HasSwitch( | 247 if (CommandLine::ForCurrentProcess()->HasSwitch( |
240 switches::kUseFakeDeviceForMediaStream)) { | 248 switches::kUseFakeDeviceForMediaStream)) { |
241 UseFakeDevice(); | 249 UseFakeDevice(); |
242 } | 250 } |
243 if (CommandLine::ForCurrentProcess()->HasSwitch( | 251 if (CommandLine::ForCurrentProcess()->HasSwitch( |
244 switches::kUseFakeUIForMediaStream)) { | 252 switches::kUseFakeUIForMediaStream)) { |
245 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>()); | 253 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>()); |
246 } | 254 } |
247 | 255 |
248 // Create a new request based on options. | 256 // Create a new request based on options. |
249 MediaStreamRequest stream_request( | 257 MediaStreamRequest stream_request( |
250 render_process_id, render_view_id, page_request_id, | 258 render_process_id, render_view_id, page_request_id, |
251 security_origin, MEDIA_GENERATE_STREAM, | 259 security_origin, MEDIA_GENERATE_STREAM, |
252 options.audio_device_id, options.video_device_id, | 260 options.audio_device_id, options.video_device_id, |
253 options.audio_type, options.video_type); | 261 options.audio_type, options.video_type); |
254 DeviceRequest* request = new DeviceRequest(requester, stream_request, | 262 DeviceRequest* request = new DeviceRequest(requester, stream_request, |
255 render_process_id, | 263 render_process_id, |
256 render_view_id); | 264 render_view_id, |
| 265 rc); |
257 const std::string& label = AddRequest(request); | 266 const std::string& label = AddRequest(request); |
258 | 267 |
259 // Post a task and handle the request asynchronously. The reason is that the | 268 // Post a task and handle the request asynchronously. The reason is that the |
260 // requester won't have a label for the request until this function returns | 269 // requester won't have a label for the request until this function returns |
261 // and thus can not handle a response. Using base::Unretained is safe since | 270 // and thus can not handle a response. Using base::Unretained is safe since |
262 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 271 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
263 // been stopped. | 272 // been stopped. |
264 BrowserThread::PostTask( | 273 BrowserThread::PostTask( |
265 BrowserThread::IO, FROM_HERE, | 274 BrowserThread::IO, FROM_HERE, |
266 base::Bind(&MediaStreamManager::SetupRequest, | 275 base::Bind(&MediaStreamManager::SetupRequest, |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 request_it->second->SetState(type, MEDIA_REQUEST_STATE_CLOSING); | 401 request_it->second->SetState(type, MEDIA_REQUEST_STATE_CLOSING); |
393 } | 402 } |
394 } | 403 } |
395 } | 404 } |
396 } | 405 } |
397 | 406 |
398 std::string MediaStreamManager::EnumerateDevices( | 407 std::string MediaStreamManager::EnumerateDevices( |
399 MediaStreamRequester* requester, | 408 MediaStreamRequester* requester, |
400 int render_process_id, | 409 int render_process_id, |
401 int render_view_id, | 410 int render_view_id, |
| 411 ResourceContext* rc, |
402 int page_request_id, | 412 int page_request_id, |
403 MediaStreamType type, | 413 MediaStreamType type, |
404 const GURL& security_origin) { | 414 const GURL& security_origin) { |
405 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
406 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 416 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
407 type == MEDIA_DEVICE_VIDEO_CAPTURE); | 417 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
408 | 418 |
409 // When the requester is NULL, the request is made by the UI to ensure MSM | 419 // When the requester is NULL, the request is made by the UI to ensure MSM |
410 // starts monitoring devices. | 420 // starts monitoring devices. |
411 if (!requester) { | 421 if (!requester) { |
(...skipping 12 matching lines...) Expand all Loading... |
424 } else { | 434 } else { |
425 NOTREACHED(); | 435 NOTREACHED(); |
426 return std::string(); | 436 return std::string(); |
427 } | 437 } |
428 | 438 |
429 MediaStreamRequest stream_request( | 439 MediaStreamRequest stream_request( |
430 render_process_id, render_view_id, page_request_id, | 440 render_process_id, render_view_id, page_request_id, |
431 security_origin, MEDIA_ENUMERATE_DEVICES, std::string(), std::string(), | 441 security_origin, MEDIA_ENUMERATE_DEVICES, std::string(), std::string(), |
432 options.audio_type, options.video_type); | 442 options.audio_type, options.video_type); |
433 DeviceRequest* request = new DeviceRequest(requester, stream_request, | 443 DeviceRequest* request = new DeviceRequest(requester, stream_request, |
434 render_process_id, | 444 render_process_id, render_view_id, |
435 render_view_id); | 445 rc); |
436 const std::string& label = AddRequest(request); | 446 const std::string& label = AddRequest(request); |
437 // Post a task and handle the request asynchronously. The reason is that the | 447 // Post a task and handle the request asynchronously. The reason is that the |
438 // requester won't have a label for the request until this function returns | 448 // requester won't have a label for the request until this function returns |
439 // and thus can not handle a response. Using base::Unretained is safe since | 449 // and thus can not handle a response. Using base::Unretained is safe since |
440 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 450 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
441 // been stopped. | 451 // been stopped. |
442 BrowserThread::PostTask( | 452 BrowserThread::PostTask( |
443 BrowserThread::IO, FROM_HERE, | 453 BrowserThread::IO, FROM_HERE, |
444 base::Bind(&MediaStreamManager::DoEnumerateDevices, | 454 base::Bind(&MediaStreamManager::DoEnumerateDevices, |
445 base::Unretained(this), label)); | 455 base::Unretained(this), label)); |
(...skipping 27 matching lines...) Expand all Loading... |
473 } else { | 483 } else { |
474 StartEnumeration(request); | 484 StartEnumeration(request); |
475 } | 485 } |
476 DVLOG(1) << "Enumerate Devices ({label = " << label << "})"; | 486 DVLOG(1) << "Enumerate Devices ({label = " << label << "})"; |
477 } | 487 } |
478 | 488 |
479 std::string MediaStreamManager::OpenDevice( | 489 std::string MediaStreamManager::OpenDevice( |
480 MediaStreamRequester* requester, | 490 MediaStreamRequester* requester, |
481 int render_process_id, | 491 int render_process_id, |
482 int render_view_id, | 492 int render_view_id, |
| 493 ResourceContext* rc, |
483 int page_request_id, | 494 int page_request_id, |
484 const std::string& device_id, | 495 const std::string& device_id, |
485 MediaStreamType type, | 496 MediaStreamType type, |
486 const GURL& security_origin) { | 497 const GURL& security_origin) { |
487 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 498 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
488 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 499 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
489 type == MEDIA_DEVICE_VIDEO_CAPTURE); | 500 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
490 | 501 |
491 // Create a new request. | 502 // Create a new request. |
492 StreamOptions options; | 503 StreamOptions options; |
493 if (IsAudioMediaType(type)) { | 504 if (IsAudioMediaType(type)) { |
494 options.audio_type = type; | 505 options.audio_type = type; |
495 options.audio_device_id = device_id; | 506 options.audio_device_id = device_id; |
496 } else if (IsVideoMediaType(type)) { | 507 } else if (IsVideoMediaType(type)) { |
497 options.video_type = type; | 508 options.video_type = type; |
498 options.video_device_id = device_id; | 509 options.video_device_id = device_id; |
499 } else { | 510 } else { |
500 NOTREACHED(); | 511 NOTREACHED(); |
501 return std::string(); | 512 return std::string(); |
502 } | 513 } |
503 | 514 |
504 MediaStreamRequest stream_request( | 515 MediaStreamRequest stream_request( |
505 render_process_id, render_view_id, page_request_id, | 516 render_process_id, render_view_id, page_request_id, |
506 security_origin, MEDIA_OPEN_DEVICE, options.audio_device_id, | 517 security_origin, MEDIA_OPEN_DEVICE, options.audio_device_id, |
507 options.video_device_id, options.audio_type, options.video_type); | 518 options.video_device_id, options.audio_type, options.video_type); |
508 DeviceRequest* request = new DeviceRequest(requester, stream_request, | 519 DeviceRequest* request = new DeviceRequest(requester, stream_request, |
509 render_process_id, | 520 render_process_id, render_view_id, |
510 render_view_id); | 521 rc); |
511 const std::string& label = AddRequest(request); | 522 const std::string& label = AddRequest(request); |
512 // Post a task and handle the request asynchronously. The reason is that the | 523 // Post a task and handle the request asynchronously. The reason is that the |
513 // requester won't have a label for the request until this function returns | 524 // requester won't have a label for the request until this function returns |
514 // and thus can not handle a response. Using base::Unretained is safe since | 525 // and thus can not handle a response. Using base::Unretained is safe since |
515 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 526 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
516 // been stopped. | 527 // been stopped. |
517 BrowserThread::PostTask( | 528 BrowserThread::PostTask( |
518 BrowserThread::IO, FROM_HERE, | 529 BrowserThread::IO, FROM_HERE, |
519 base::Bind(&MediaStreamManager::SetupRequest, | 530 base::Bind(&MediaStreamManager::SetupRequest, |
520 base::Unretained(this), label)); | 531 base::Unretained(this), label)); |
(...skipping 29 matching lines...) Expand all Loading... |
550 | 561 |
551 void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) { | 562 void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) { |
552 std::vector<int> session_ids; | 563 std::vector<int> session_ids; |
553 for (DeviceRequests::const_iterator it = requests_.begin(); | 564 for (DeviceRequests::const_iterator it = requests_.begin(); |
554 it != requests_.end() ; ++it) { | 565 it != requests_.end() ; ++it) { |
555 const DeviceRequest* request = it->second; | 566 const DeviceRequest* request = it->second; |
556 for (StreamDeviceInfoArray::const_iterator device_it = | 567 for (StreamDeviceInfoArray::const_iterator device_it = |
557 request->devices.begin(); | 568 request->devices.begin(); |
558 device_it != request->devices.end(); ++device_it) { | 569 device_it != request->devices.end(); ++device_it) { |
559 std::string source_id = content::GetHMACForMediaDeviceID( | 570 std::string source_id = content::GetHMACForMediaDeviceID( |
| 571 request->resource_context, |
560 request->request.security_origin, | 572 request->request.security_origin, |
561 device.id); | 573 device.id); |
562 if (device_it->device.id == source_id && | 574 if (device_it->device.id == source_id && |
563 device_it->device.type == device.type) { | 575 device_it->device.type == device.type) { |
564 session_ids.push_back(device_it->session_id); | 576 session_ids.push_back(device_it->session_id); |
565 if (it->second->requester) { | 577 if (it->second->requester) { |
566 it->second->requester->DeviceStopped( | 578 it->second->requester->DeviceStopped( |
567 it->second->requesting_view_id, | 579 it->second->requesting_view_id, |
568 it->first, | 580 it->first, |
569 *device_it); | 581 *device_it); |
(...skipping 29 matching lines...) Expand all Loading... |
599 DCHECK_EQ(base::MessageLoop::current(), io_loop_); | 611 DCHECK_EQ(base::MessageLoop::current(), io_loop_); |
600 if (monitoring_started_) { | 612 if (monitoring_started_) { |
601 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); | 613 base::SystemMonitor::Get()->RemoveDevicesChangedObserver(this); |
602 monitoring_started_ = false; | 614 monitoring_started_ = false; |
603 ClearEnumerationCache(&audio_enumeration_cache_); | 615 ClearEnumerationCache(&audio_enumeration_cache_); |
604 ClearEnumerationCache(&video_enumeration_cache_); | 616 ClearEnumerationCache(&video_enumeration_cache_); |
605 } | 617 } |
606 } | 618 } |
607 | 619 |
608 bool MediaStreamManager::TranslateRequestedSourceIdToDeviceId( | 620 bool MediaStreamManager::TranslateRequestedSourceIdToDeviceId( |
609 MediaStreamRequest* request) { | 621 DeviceRequest* request) { |
| 622 MediaStreamRequest* ms_request = &request->request; |
610 // If a specific device has been requested we need to find the real device id. | 623 // If a specific device has been requested we need to find the real device id. |
611 if (request->audio_type == MEDIA_DEVICE_AUDIO_CAPTURE && | 624 if (ms_request->audio_type == MEDIA_DEVICE_AUDIO_CAPTURE && |
612 !request->requested_audio_device_id.empty()) { | 625 !ms_request->requested_audio_device_id.empty()) { |
613 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_AUDIO_CAPTURE, | 626 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_AUDIO_CAPTURE, |
614 request->security_origin, | 627 request->resource_context, |
615 request->requested_audio_device_id, | 628 ms_request->security_origin, |
616 &request->requested_audio_device_id)) { | 629 ms_request->requested_audio_device_id, |
| 630 &ms_request->requested_audio_device_id)) { |
617 // TODO(perkj): gUM should support mandatory and optional constraints. | 631 // TODO(perkj): gUM should support mandatory and optional constraints. |
618 // Ie - if the sourceId is optional but it does not match - gUM should | 632 // Ie - if the sourceId is optional but it does not match - gUM should |
619 // not fail. For now we treat sourceId as a mandatory constraint. | 633 // not fail. For now we treat sourceId as a mandatory constraint. |
620 LOG(ERROR) << "Requested device does not exist."; | 634 LOG(ERROR) << "Requested device does not exist."; |
621 return false; | 635 return false; |
622 } | 636 } |
623 } | 637 } |
624 | 638 |
625 if (request->video_type == MEDIA_DEVICE_VIDEO_CAPTURE && | 639 if (ms_request->video_type == MEDIA_DEVICE_VIDEO_CAPTURE && |
626 !request->requested_video_device_id.empty()) { | 640 !ms_request->requested_video_device_id.empty()) { |
627 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_VIDEO_CAPTURE, | 641 if (!TranslateSourceIdToDeviceId(MEDIA_DEVICE_VIDEO_CAPTURE, |
628 request->security_origin, | 642 request->resource_context, |
629 request->requested_video_device_id, | 643 ms_request->security_origin, |
630 &request->requested_video_device_id)) { | 644 ms_request->requested_video_device_id, |
| 645 &ms_request->requested_video_device_id)) { |
631 // TODO(perkj): guM should support mandatory and optional constraints. | 646 // TODO(perkj): guM should support mandatory and optional constraints. |
632 // Ie - if the sourceId is optional but it does not match - guM should | 647 // Ie - if the sourceId is optional but it does not match - guM should |
633 // not fail. For now we treat sourceId as a mandatory constraint. | 648 // not fail. For now we treat sourceId as a mandatory constraint. |
634 LOG(ERROR) << "Requested device does not exist."; | 649 LOG(ERROR) << "Requested device does not exist."; |
635 return false; | 650 return false; |
636 } | 651 } |
637 } | 652 } |
638 DVLOG(3) << "Requested audio device " << request->requested_audio_device_id | 653 DVLOG(3) << "Requested audio device " |
639 << " video device " << request->requested_video_device_id; | 654 << ms_request->requested_audio_device_id |
| 655 << "Requested video device " |
| 656 << ms_request->requested_video_device_id; |
640 return true; | 657 return true; |
641 } | 658 } |
642 | 659 |
643 void MediaStreamManager::TranslateDeviceIdToSourceId( | 660 void MediaStreamManager::TranslateDeviceIdToSourceId( |
644 const MediaStreamRequest& request, | 661 DeviceRequest* request, |
645 MediaStreamDevice* device) { | 662 MediaStreamDevice* device) { |
646 if (request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE || | 663 if (request->request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE || |
647 request.video_type == MEDIA_DEVICE_VIDEO_CAPTURE) { | 664 request->request.video_type == MEDIA_DEVICE_VIDEO_CAPTURE) { |
648 device->id = content::GetHMACForMediaDeviceID(request.security_origin, | 665 device->id = content::GetHMACForMediaDeviceID( |
649 device->id); | 666 request->resource_context, |
| 667 request->request.security_origin, |
| 668 device->id); |
650 } | 669 } |
651 } | 670 } |
652 | 671 |
653 bool MediaStreamManager::TranslateSourceIdToDeviceId( | 672 bool MediaStreamManager::TranslateSourceIdToDeviceId( |
654 MediaStreamType stream_type, | 673 MediaStreamType stream_type, |
| 674 ResourceContext* rc, |
655 const GURL& security_origin, | 675 const GURL& security_origin, |
656 const std::string& source_id, | 676 const std::string& source_id, |
657 std::string* device_id) { | 677 std::string* device_id) { |
658 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || | 678 DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || |
659 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); | 679 stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); |
660 DCHECK(!source_id.empty()); | 680 DCHECK(!source_id.empty()); |
661 | 681 |
662 EnumerationCache* cache = | 682 EnumerationCache* cache = |
663 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | 683 stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? |
664 &audio_enumeration_cache_ : &video_enumeration_cache_; | 684 &audio_enumeration_cache_ : &video_enumeration_cache_; |
665 | 685 |
666 // If device monitoring hasn't started, the |device_guid| is not valid. | 686 // If device monitoring hasn't started, the |device_guid| is not valid. |
667 if (!cache->valid) | 687 if (!cache->valid) |
668 return false; | 688 return false; |
669 | 689 |
670 for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin(); | 690 for (StreamDeviceInfoArray::const_iterator it = cache->devices.begin(); |
671 it != cache->devices.end(); | 691 it != cache->devices.end(); |
672 ++it) { | 692 ++it) { |
673 if (content::DoesMediaDeviceIDMatchHMAC(security_origin, source_id, | 693 if (content::DoesMediaDeviceIDMatchHMAC(rc, security_origin, source_id, |
674 it->device.id)) { | 694 it->device.id)) { |
675 *device_id = it->device.id; | 695 *device_id = it->device.id; |
676 return true; | 696 return true; |
677 } | 697 } |
678 } | 698 } |
679 return false; | 699 return false; |
680 } | 700 } |
681 | 701 |
682 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 702 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { |
683 DCHECK_EQ(base::MessageLoop::current(), io_loop_); | 703 DCHECK_EQ(base::MessageLoop::current(), io_loop_); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 DeviceRequests::iterator it = requests_.find(label); | 750 DeviceRequests::iterator it = requests_.find(label); |
731 scoped_ptr<DeviceRequest> request(it->second); | 751 scoped_ptr<DeviceRequest> request(it->second); |
732 requests_.erase(it); | 752 requests_.erase(it); |
733 } | 753 } |
734 | 754 |
735 void MediaStreamManager::PostRequestToUI(const std::string& label, | 755 void MediaStreamManager::PostRequestToUI(const std::string& label, |
736 DeviceRequest* request) { | 756 DeviceRequest* request) { |
737 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 757 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
738 DVLOG(1) << "PostRequestToUI({label= " << label << "})"; | 758 DVLOG(1) << "PostRequestToUI({label= " << label << "})"; |
739 // If a specific device has been requested we need to find the real device id. | 759 // If a specific device has been requested we need to find the real device id. |
740 if (!TranslateRequestedSourceIdToDeviceId(&request->request)) { | 760 if (!TranslateRequestedSourceIdToDeviceId(request)) { |
741 FinalizeRequestFailed(label, request); | 761 FinalizeRequestFailed(label, request); |
742 return; | 762 return; |
743 } | 763 } |
744 | 764 |
745 const MediaStreamType audio_type = request->request.audio_type; | 765 const MediaStreamType audio_type = request->request.audio_type; |
746 const MediaStreamType video_type = request->request.video_type; | 766 const MediaStreamType video_type = request->request.video_type; |
747 | 767 |
748 // Post the request to UI and set the state. | 768 // Post the request to UI and set the state. |
749 if (IsAudioMediaType(audio_type)) | 769 if (IsAudioMediaType(audio_type)) |
750 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); | 770 request->SetState(audio_type, MEDIA_REQUEST_STATE_PENDING_APPROVAL); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 | 907 |
888 StreamDeviceInfoArray MediaStreamManager::GetDevicesOpenedByRequest( | 908 StreamDeviceInfoArray MediaStreamManager::GetDevicesOpenedByRequest( |
889 const std::string& label) const { | 909 const std::string& label) const { |
890 DeviceRequest* request = FindRequest(label); | 910 DeviceRequest* request = FindRequest(label); |
891 if (!request) | 911 if (!request) |
892 return StreamDeviceInfoArray(); | 912 return StreamDeviceInfoArray(); |
893 return request->devices; | 913 return request->devices; |
894 } | 914 } |
895 | 915 |
896 bool MediaStreamManager::FindExistingRequestedDeviceInfo( | 916 bool MediaStreamManager::FindExistingRequestedDeviceInfo( |
897 int render_process_id, | 917 const DeviceRequest& new_request, |
898 int render_view_id, | 918 const MediaStreamDevice& new_device_info, |
899 const GURL& security_origin, | 919 StreamDeviceInfo* existing_device_info, |
900 MediaStreamRequestType type, | 920 MediaRequestState* existing_request_state) const { |
901 const std::string& device_id, | 921 DCHECK(existing_device_info); |
902 MediaStreamType device_type, | 922 DCHECK(existing_request_state); |
903 StreamDeviceInfo* device_info, | 923 |
904 MediaRequestState* request_state) const { | 924 const MediaStreamRequest& new_ms_request = new_request.request; |
905 DCHECK(device_info); | |
906 DCHECK(request_state); | |
907 | 925 |
908 std::string source_id = content::GetHMACForMediaDeviceID( | 926 std::string source_id = content::GetHMACForMediaDeviceID( |
909 security_origin, | 927 new_request.resource_context, |
910 device_id); | 928 new_ms_request.security_origin, |
| 929 new_device_info.id); |
911 | 930 |
912 for (DeviceRequests::const_iterator it = requests_.begin(); | 931 for (DeviceRequests::const_iterator it = requests_.begin(); |
913 it != requests_.end() ; ++it) { | 932 it != requests_.end() ; ++it) { |
914 const DeviceRequest* request = it->second; | 933 const DeviceRequest* request = it->second; |
915 if (request->requesting_process_id == render_process_id && | 934 if (request->requesting_process_id == new_request.requesting_process_id && |
916 request->requesting_view_id == render_view_id && | 935 request->requesting_view_id == new_request.requesting_view_id && |
917 request->request.request_type == type) { | 936 request->request.request_type == new_ms_request.request_type) { |
918 for (StreamDeviceInfoArray::const_iterator device_it = | 937 for (StreamDeviceInfoArray::const_iterator device_it = |
919 request->devices.begin(); | 938 request->devices.begin(); |
920 device_it != request->devices.end(); ++device_it) { | 939 device_it != request->devices.end(); ++device_it) { |
921 if (device_it->device.id == source_id && | 940 if (device_it->device.id == source_id && |
922 device_it->device.type == device_type) { | 941 device_it->device.type == new_device_info.type) { |
923 *device_info = *device_it; | 942 *existing_device_info = *device_it; |
924 *request_state = request->state(device_it->device.type); | 943 *existing_request_state = request->state(device_it->device.type); |
925 return true; | 944 return true; |
926 } | 945 } |
927 } | 946 } |
928 } | 947 } |
929 } | 948 } |
930 return false; | 949 return false; |
931 } | 950 } |
932 | 951 |
933 void MediaStreamManager::FinalizeGenerateStream(const std::string& label, | 952 void MediaStreamManager::FinalizeGenerateStream(const std::string& label, |
934 DeviceRequest* request) { | 953 DeviceRequest* request) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 } | 992 } |
974 | 993 |
975 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, | 994 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, |
976 DeviceRequest* request) { | 995 DeviceRequest* request) { |
977 if (!request->request.security_origin.is_valid()) { | 996 if (!request->request.security_origin.is_valid()) { |
978 request->requester->DevicesEnumerated(label, StreamDeviceInfoArray()); | 997 request->requester->DevicesEnumerated(label, StreamDeviceInfoArray()); |
979 return; | 998 return; |
980 } | 999 } |
981 for (StreamDeviceInfoArray::iterator it = request->devices.begin(); | 1000 for (StreamDeviceInfoArray::iterator it = request->devices.begin(); |
982 it != request->devices.end(); ++it) { | 1001 it != request->devices.end(); ++it) { |
983 TranslateDeviceIdToSourceId(request->request, &it->device); | 1002 TranslateDeviceIdToSourceId(request, &it->device); |
984 } | 1003 } |
985 request->requester->DevicesEnumerated(label, request->devices); | 1004 request->requester->DevicesEnumerated(label, request->devices); |
986 } | 1005 } |
987 | 1006 |
988 void MediaStreamManager::FinalizeMediaAccessRequest( | 1007 void MediaStreamManager::FinalizeMediaAccessRequest( |
989 const std::string& label, | 1008 const std::string& label, |
990 DeviceRequest* request, | 1009 DeviceRequest* request, |
991 const MediaStreamDevices& devices) { | 1010 const MediaStreamDevices& devices) { |
992 if (!request->callback.is_null()) | 1011 if (!request->callback.is_null()) |
993 request->callback.Run(devices, request->ui_proxy.Pass()); | 1012 request->callback.Run(devices, request->ui_proxy.Pass()); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1227 } else if (device_info.device.type == request->request.video_type) { | 1246 } else if (device_info.device.type == request->request.video_type) { |
1228 found_video = true; | 1247 found_video = true; |
1229 } | 1248 } |
1230 | 1249 |
1231 // If this is request for a new MediaStream, a device is only opened once | 1250 // If this is request for a new MediaStream, a device is only opened once |
1232 // per render view. This is so that the permission to use a device can be | 1251 // per render view. This is so that the permission to use a device can be |
1233 // revoked by a single call to StopStreamDevice regardless of how many | 1252 // revoked by a single call to StopStreamDevice regardless of how many |
1234 // MediaStreams it is being used in. | 1253 // MediaStreams it is being used in. |
1235 if (request->request.request_type == MEDIA_GENERATE_STREAM) { | 1254 if (request->request.request_type == MEDIA_GENERATE_STREAM) { |
1236 MediaRequestState state; | 1255 MediaRequestState state; |
1237 if (FindExistingRequestedDeviceInfo(request->requesting_process_id, | 1256 if (FindExistingRequestedDeviceInfo(*request, |
1238 request->requesting_view_id, | 1257 device_info.device, |
1239 request->request.security_origin, | |
1240 request->request.request_type, | |
1241 device_info.device.id, | |
1242 device_info.device.type, | |
1243 &device_info, | 1258 &device_info, |
1244 &state)) { | 1259 &state)) { |
1245 request->devices.push_back(device_info); | 1260 request->devices.push_back(device_info); |
1246 request->SetState(device_info.device.type, state); | 1261 request->SetState(device_info.device.type, state); |
1247 DVLOG(1) << "HandleAccessRequestResponse - device already opened " | 1262 DVLOG(1) << "HandleAccessRequestResponse - device already opened " |
1248 << ", {label = " << label << "}" | 1263 << ", {label = " << label << "}" |
1249 << ", device_id = " << device_it->id << "}"; | 1264 << ", device_id = " << device_it->id << "}"; |
1250 continue; | 1265 continue; |
1251 } | 1266 } |
1252 } | 1267 } |
1253 device_info.session_id = | 1268 device_info.session_id = |
1254 GetDeviceManager(device_info.device.type)->Open(device_info); | 1269 GetDeviceManager(device_info.device.type)->Open(device_info); |
1255 TranslateDeviceIdToSourceId(request->request, &device_info.device); | 1270 TranslateDeviceIdToSourceId(request, &device_info.device); |
1256 request->devices.push_back(device_info); | 1271 request->devices.push_back(device_info); |
1257 | 1272 |
1258 request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING); | 1273 request->SetState(device_info.device.type, MEDIA_REQUEST_STATE_OPENING); |
1259 DVLOG(1) << "HandleAccessRequestResponse - opening device " | 1274 DVLOG(1) << "HandleAccessRequestResponse - opening device " |
1260 << ", {label = " << label << "}" | 1275 << ", {label = " << label << "}" |
1261 << ", {device_id = " << device_info.device.id << "}" | 1276 << ", {device_id = " << device_info.device.id << "}" |
1262 << ", {session_id = " << device_info.session_id << "}"; | 1277 << ", {session_id = " << device_info.session_id << "}"; |
1263 } | 1278 } |
1264 | 1279 |
1265 // Check whether we've received all stream types requested. | 1280 // Check whether we've received all stream types requested. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1403 } | 1418 } |
1404 | 1419 |
1405 // Always do enumeration even though some enumeration is in progress, | 1420 // Always do enumeration even though some enumeration is in progress, |
1406 // because those enumeration commands could be sent before these devices | 1421 // because those enumeration commands could be sent before these devices |
1407 // change. | 1422 // change. |
1408 ++active_enumeration_ref_count_[stream_type]; | 1423 ++active_enumeration_ref_count_[stream_type]; |
1409 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); | 1424 GetDeviceManager(stream_type)->EnumerateDevices(stream_type); |
1410 } | 1425 } |
1411 | 1426 |
1412 } // namespace content | 1427 } // namespace content |
OLD | NEW |