Chromium Code Reviews| 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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 } | 154 } |
| 155 } | 155 } |
| 156 return output_string; | 156 return output_string; |
| 157 } | 157 } |
| 158 | 158 |
| 159 // Needed for MediaStreamManager::GenerateStream below. | 159 // Needed for MediaStreamManager::GenerateStream below. |
| 160 std::string ReturnEmptySalt() { | 160 std::string ReturnEmptySalt() { |
| 161 return std::string(); | 161 return std::string(); |
| 162 } | 162 } |
| 163 | 163 |
| 164 // Clears the MediaStreamDevice.name from all devices in |device_list|. | |
|
mcasas
2014/05/27 12:08:23
s/|device_list|/|devices|/
Henrik Grunell
2014/05/27 15:33:54
Done.
| |
| 165 static void ClearDeviceLabels(content::StreamDeviceInfoArray* devices) { | |
| 166 for (content::StreamDeviceInfoArray::iterator device_itr = devices->begin(); | |
| 167 device_itr != devices->end(); | |
| 168 ++device_itr) { | |
| 169 device_itr->device.name.clear(); | |
| 170 } | |
| 171 } | |
| 172 | |
| 164 } // namespace | 173 } // namespace |
| 165 | 174 |
| 166 | 175 |
| 167 // MediaStreamManager::DeviceRequest represents a request to either enumerate | 176 // MediaStreamManager::DeviceRequest represents a request to either enumerate |
| 168 // available devices or open one or more devices. | 177 // available devices or open one or more devices. |
| 169 // TODO(perkj): MediaStreamManager still needs refactoring. I propose we create | 178 // TODO(perkj): MediaStreamManager still needs refactoring. I propose we create |
| 170 // several subclasses of DeviceRequest and move some of the responsibility of | 179 // several subclasses of DeviceRequest and move some of the responsibility of |
| 171 // the MediaStreamManager to the subclasses to get rid of the way too many if | 180 // the MediaStreamManager to the subclasses to get rid of the way too many if |
| 172 // statements in MediaStreamManager. | 181 // statements in MediaStreamManager. |
| 173 class MediaStreamManager::DeviceRequest { | 182 class MediaStreamManager::DeviceRequest { |
| 174 public: | 183 public: |
| 175 DeviceRequest(MediaStreamRequester* requester, | 184 DeviceRequest(MediaStreamRequester* requester, |
| 176 int requesting_process_id, | 185 int requesting_process_id, |
| 177 int requesting_view_id, | 186 int requesting_view_id, |
| 178 int page_request_id, | 187 int page_request_id, |
| 179 const GURL& security_origin, | 188 const GURL& security_origin, |
| 189 ResourceContext* resource_context, | |
| 180 bool user_gesture, | 190 bool user_gesture, |
| 181 MediaStreamRequestType request_type, | 191 MediaStreamRequestType request_type, |
| 182 const StreamOptions& options, | 192 const StreamOptions& options, |
| 183 const ResourceContext::SaltCallback& salt_callback) | 193 const ResourceContext::SaltCallback& salt_callback) |
| 184 : requester(requester), | 194 : requester(requester), |
| 185 requesting_process_id(requesting_process_id), | 195 requesting_process_id(requesting_process_id), |
| 186 requesting_view_id(requesting_view_id), | 196 requesting_view_id(requesting_view_id), |
| 187 page_request_id(page_request_id), | 197 page_request_id(page_request_id), |
| 188 security_origin(security_origin), | 198 security_origin(security_origin), |
| 199 resource_context(resource_context), | |
| 189 user_gesture(user_gesture), | 200 user_gesture(user_gesture), |
| 190 request_type(request_type), | 201 request_type(request_type), |
| 191 options(options), | 202 options(options), |
| 192 salt_callback(salt_callback), | 203 salt_callback(salt_callback), |
| 193 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), | 204 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), |
| 194 audio_type_(MEDIA_NO_SERVICE), | 205 audio_type_(MEDIA_NO_SERVICE), |
| 195 video_type_(MEDIA_NO_SERVICE) { | 206 video_type_(MEDIA_NO_SERVICE) { |
| 196 } | 207 } |
| 197 | 208 |
| 198 ~DeviceRequest() {} | 209 ~DeviceRequest() {} |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 // will receive a handle to the MediaStream. This may be different from | 311 // will receive a handle to the MediaStream. This may be different from |
| 301 // MediaStreamRequest::render_view_id which in the tab capture case | 312 // MediaStreamRequest::render_view_id which in the tab capture case |
| 302 // specifies the target renderer from which audio and video is captured. | 313 // specifies the target renderer from which audio and video is captured. |
| 303 const int requesting_view_id; | 314 const int requesting_view_id; |
| 304 | 315 |
| 305 // An ID the render view provided to identify this request. | 316 // An ID the render view provided to identify this request. |
| 306 const int page_request_id; | 317 const int page_request_id; |
| 307 | 318 |
| 308 const GURL security_origin; | 319 const GURL security_origin; |
| 309 | 320 |
| 321 // This is used when enumerating devices for checking if we have device | |
| 322 // permission, and if not remove the device label. | |
| 323 ResourceContext* resource_context; | |
| 324 | |
| 310 const bool user_gesture; | 325 const bool user_gesture; |
| 311 | 326 |
| 312 const MediaStreamRequestType request_type; | 327 const MediaStreamRequestType request_type; |
| 313 | 328 |
| 314 const StreamOptions options; | 329 const StreamOptions options; |
| 315 | 330 |
| 316 ResourceContext::SaltCallback salt_callback; | 331 ResourceContext::SaltCallback salt_callback; |
| 317 | 332 |
| 318 StreamDeviceInfoArray devices; | 333 StreamDeviceInfoArray devices; |
| 319 | 334 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 const MediaRequestResponseCallback& callback) { | 419 const MediaRequestResponseCallback& callback) { |
| 405 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 420 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 406 | 421 |
| 407 // TODO(perkj): The argument list with NULL parameters to DeviceRequest | 422 // TODO(perkj): The argument list with NULL parameters to DeviceRequest |
| 408 // suggests that this is the wrong design. Can this be refactored? | 423 // suggests that this is the wrong design. Can this be refactored? |
| 409 DeviceRequest* request = new DeviceRequest(NULL, | 424 DeviceRequest* request = new DeviceRequest(NULL, |
| 410 render_process_id, | 425 render_process_id, |
| 411 render_view_id, | 426 render_view_id, |
| 412 page_request_id, | 427 page_request_id, |
| 413 security_origin, | 428 security_origin, |
| 429 NULL, | |
| 414 false, // user gesture | 430 false, // user gesture |
| 415 MEDIA_DEVICE_ACCESS, | 431 MEDIA_DEVICE_ACCESS, |
| 416 options, | 432 options, |
| 417 base::Bind(&ReturnEmptySalt)); | 433 base::Bind(&ReturnEmptySalt)); |
| 418 | 434 |
| 419 const std::string& label = AddRequest(request); | 435 const std::string& label = AddRequest(request); |
| 420 | 436 |
| 421 request->callback = callback; | 437 request->callback = callback; |
| 422 // Post a task and handle the request asynchronously. The reason is that the | 438 // Post a task and handle the request asynchronously. The reason is that the |
| 423 // requester won't have a label for the request until this function returns | 439 // requester won't have a label for the request until this function returns |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 444 if (CommandLine::ForCurrentProcess()->HasSwitch( | 460 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 445 switches::kUseFakeUIForMediaStream)) { | 461 switches::kUseFakeUIForMediaStream)) { |
| 446 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>()); | 462 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>()); |
| 447 } | 463 } |
| 448 | 464 |
| 449 DeviceRequest* request = new DeviceRequest(requester, | 465 DeviceRequest* request = new DeviceRequest(requester, |
| 450 render_process_id, | 466 render_process_id, |
| 451 render_view_id, | 467 render_view_id, |
| 452 page_request_id, | 468 page_request_id, |
| 453 security_origin, | 469 security_origin, |
| 470 NULL, | |
| 454 user_gesture, | 471 user_gesture, |
| 455 MEDIA_GENERATE_STREAM, | 472 MEDIA_GENERATE_STREAM, |
| 456 options, | 473 options, |
| 457 sc); | 474 sc); |
| 458 | 475 |
| 459 const std::string& label = AddRequest(request); | 476 const std::string& label = AddRequest(request); |
| 460 | 477 |
| 461 // Post a task and handle the request asynchronously. The reason is that the | 478 // Post a task and handle the request asynchronously. The reason is that the |
| 462 // requester won't have a label for the request until this function returns | 479 // requester won't have a label for the request until this function returns |
| 463 // and thus can not handle a response. Using base::Unretained is safe since | 480 // and thus can not handle a response. Using base::Unretained is safe since |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 626 } | 643 } |
| 627 } | 644 } |
| 628 | 645 |
| 629 std::string MediaStreamManager::EnumerateDevices( | 646 std::string MediaStreamManager::EnumerateDevices( |
| 630 MediaStreamRequester* requester, | 647 MediaStreamRequester* requester, |
| 631 int render_process_id, | 648 int render_process_id, |
| 632 int render_view_id, | 649 int render_view_id, |
| 633 const ResourceContext::SaltCallback& sc, | 650 const ResourceContext::SaltCallback& sc, |
| 634 int page_request_id, | 651 int page_request_id, |
| 635 MediaStreamType type, | 652 MediaStreamType type, |
| 636 const GURL& security_origin) { | 653 const GURL& security_origin, |
| 654 ResourceContext* resource_context) { | |
| 637 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 655 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 638 DCHECK(requester); | 656 DCHECK(requester); |
| 639 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 657 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || |
| 640 type == MEDIA_DEVICE_VIDEO_CAPTURE); | 658 type == MEDIA_DEVICE_VIDEO_CAPTURE); |
| 641 | 659 |
| 642 DeviceRequest* request = new DeviceRequest(requester, | 660 DeviceRequest* request = new DeviceRequest(requester, |
| 643 render_process_id, | 661 render_process_id, |
| 644 render_view_id, | 662 render_view_id, |
| 645 page_request_id, | 663 page_request_id, |
| 646 security_origin, | 664 security_origin, |
| 665 resource_context, | |
|
perkj_chrome
2014/05/27 11:57:23
This is not safe. Why not check the permissions an
Henrik Grunell
2014/05/27 15:33:54
Done.
| |
| 647 false, // user gesture | 666 false, // user gesture |
| 648 MEDIA_ENUMERATE_DEVICES, | 667 MEDIA_ENUMERATE_DEVICES, |
| 649 StreamOptions(), | 668 StreamOptions(), |
| 650 sc); | 669 sc); |
| 651 if (IsAudioMediaType(type)) | 670 if (IsAudioMediaType(type)) |
| 652 request->SetAudioType(type); | 671 request->SetAudioType(type); |
| 653 else if (IsVideoMediaType(type)) | 672 else if (IsVideoMediaType(type)) |
| 654 request->SetVideoType(type); | 673 request->SetVideoType(type); |
| 655 | 674 |
| 656 const std::string& label = AddRequest(request); | 675 const std::string& label = AddRequest(request); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 668 | 687 |
| 669 void MediaStreamManager::DoEnumerateDevices(const std::string& label) { | 688 void MediaStreamManager::DoEnumerateDevices(const std::string& label) { |
| 670 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 689 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 671 DeviceRequest* request = FindRequest(label); | 690 DeviceRequest* request = FindRequest(label); |
| 672 if (!request) | 691 if (!request) |
| 673 return; // This can happen if the request has been canceled. | 692 return; // This can happen if the request has been canceled. |
| 674 | 693 |
| 675 MediaStreamType type; | 694 MediaStreamType type; |
| 676 EnumerationCache* cache; | 695 EnumerationCache* cache; |
| 677 if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE) { | 696 if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE) { |
| 678 DCHECK_EQ(MEDIA_NO_SERVICE, request->video_type()); | 697 DCHECK_EQ(MEDIA_NO_SERVICE, request->video_type()); |
|
mcasas
2014/05/27 12:08:23
I know this is not your code, but does this mean
Henrik Grunell
2014/05/27 15:33:54
AFAIK only one type per request. Agree on the adde
| |
| 679 type = MEDIA_DEVICE_AUDIO_CAPTURE; | 698 type = MEDIA_DEVICE_AUDIO_CAPTURE; |
| 680 cache = &audio_enumeration_cache_; | 699 cache = &audio_enumeration_cache_; |
| 681 } else { | 700 } else { |
| 682 DCHECK_EQ(MEDIA_DEVICE_VIDEO_CAPTURE, request->video_type()); | 701 DCHECK_EQ(MEDIA_DEVICE_VIDEO_CAPTURE, request->video_type()); |
| 683 type = MEDIA_DEVICE_VIDEO_CAPTURE; | 702 type = MEDIA_DEVICE_VIDEO_CAPTURE; |
| 684 cache = &video_enumeration_cache_; | 703 cache = &video_enumeration_cache_; |
| 685 } | 704 } |
| 686 | 705 |
| 687 if (!EnumerationRequired(cache, type)) { | 706 if (!EnumerationRequired(cache, type)) { |
| 688 // Cached device list of this type exists. Just send it out. | 707 // Cached device list of this type exists. Just send it out. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 717 options.mandatory_video.push_back( | 736 options.mandatory_video.push_back( |
| 718 StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id)); | 737 StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id)); |
| 719 } else { | 738 } else { |
| 720 NOTREACHED(); | 739 NOTREACHED(); |
| 721 } | 740 } |
| 722 DeviceRequest* request = new DeviceRequest(requester, | 741 DeviceRequest* request = new DeviceRequest(requester, |
| 723 render_process_id, | 742 render_process_id, |
| 724 render_view_id, | 743 render_view_id, |
| 725 page_request_id, | 744 page_request_id, |
| 726 security_origin, | 745 security_origin, |
| 746 NULL, | |
| 727 false, // user gesture | 747 false, // user gesture |
| 728 MEDIA_OPEN_DEVICE, | 748 MEDIA_OPEN_DEVICE, |
| 729 options, | 749 options, |
| 730 sc); | 750 sc); |
| 731 | 751 |
| 732 const std::string& label = AddRequest(request); | 752 const std::string& label = AddRequest(request); |
| 733 // Post a task and handle the request asynchronously. The reason is that the | 753 // Post a task and handle the request asynchronously. The reason is that the |
| 734 // requester won't have a label for the request until this function returns | 754 // requester won't have a label for the request until this function returns |
| 735 // and thus can not handle a response. Using base::Unretained is safe since | 755 // and thus can not handle a response. Using base::Unretained is safe since |
| 736 // MediaStreamManager is deleted on the UI thread, after the IO thread has | 756 // MediaStreamManager is deleted on the UI thread, after the IO thread has |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1358 const StreamDeviceInfoArray& requested_devices = request->devices; | 1378 const StreamDeviceInfoArray& requested_devices = request->devices; |
| 1359 request->requester->DeviceOpened(request->requesting_view_id, | 1379 request->requester->DeviceOpened(request->requesting_view_id, |
| 1360 request->page_request_id, | 1380 request->page_request_id, |
| 1361 label, requested_devices.front()); | 1381 label, requested_devices.front()); |
| 1362 } | 1382 } |
| 1363 | 1383 |
| 1364 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, | 1384 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, |
| 1365 DeviceRequest* request) { | 1385 DeviceRequest* request) { |
| 1366 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1386 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1367 DCHECK_EQ(request->request_type, MEDIA_ENUMERATE_DEVICES); | 1387 DCHECK_EQ(request->request_type, MEDIA_ENUMERATE_DEVICES); |
| 1388 DCHECK(request->resource_context); | |
| 1368 | 1389 |
|
mcasas
2014/05/27 12:08:23
DCHECK(request->state(type), MEDIA_REQUEST_STATE_D
Henrik Grunell
2014/05/27 15:33:54
According to xians@, no.
| |
| 1369 if (request->security_origin.is_valid()) { | 1390 if (request->security_origin.is_valid()) { |
| 1370 for (StreamDeviceInfoArray::iterator it = request->devices.begin(); | 1391 for (StreamDeviceInfoArray::iterator it = request->devices.begin(); |
| 1371 it != request->devices.end(); ++it) { | 1392 it != request->devices.end(); ++it) { |
| 1372 TranslateDeviceIdToSourceId(request, &it->device); | 1393 TranslateDeviceIdToSourceId(request, &it->device); |
| 1373 } | 1394 } |
| 1374 } else { | 1395 } else { |
| 1375 request->devices.clear(); | 1396 request->devices.clear(); |
| 1376 } | 1397 } |
| 1377 | 1398 |
| 1399 // Query for mic and camera permissions. | |
|
mcasas
2014/05/27 12:08:23
This might sound silly, but aren't we querying for
Henrik Grunell
2014/05/27 15:33:54
Changed based on other comment to check permission
| |
| 1400 bool visible_labels = request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE ? | |
| 1401 request->resource_context->AllowMicAccess(request->security_origin) : | |
| 1402 request->resource_context->AllowCameraAccess(request->security_origin); | |
| 1403 if (!visible_labels) | |
| 1404 ClearDeviceLabels(&request->devices); | |
|
perkj_chrome
2014/05/27 11:57:23
Is this ok with Pepper?
Henrik Grunell
2014/05/27 15:33:54
Still no clear answer from them. I'll let someone
| |
| 1405 | |
| 1378 request->requester->DevicesEnumerated( | 1406 request->requester->DevicesEnumerated( |
| 1379 request->requesting_view_id, | 1407 request->requesting_view_id, |
| 1380 request->page_request_id, | 1408 request->page_request_id, |
| 1381 label, | 1409 label, |
| 1382 request->devices); | 1410 request->devices); |
| 1383 | 1411 |
| 1384 // TODO(tommi): | 1412 // TODO(tommi): |
| 1385 // Ideally enumeration requests should be deleted once they have been served | 1413 // Ideally enumeration requests should be deleted once they have been served |
| 1386 // (as any request). However, this implementation mixes requests and | 1414 // (as any request). However, this implementation mixes requests and |
| 1387 // notifications together so enumeration requests are kept open by some | 1415 // notifications together so enumeration requests are kept open by some |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1927 if (it->device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { | 1955 if (it->device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| 1928 video_capture_manager_->SetDesktopCaptureWindowId(it->session_id, | 1956 video_capture_manager_->SetDesktopCaptureWindowId(it->session_id, |
| 1929 window_id); | 1957 window_id); |
| 1930 break; | 1958 break; |
| 1931 } | 1959 } |
| 1932 } | 1960 } |
| 1933 } | 1961 } |
| 1934 } | 1962 } |
| 1935 | 1963 |
| 1936 } // namespace content | 1964 } // namespace content |
| OLD | NEW |