| 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 |