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

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

Issue 483523006: Check all settings when checking mic and camera access (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review fixes. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/media/media_stream_manager.h" 5 #include "content/browser/renderer_host/media/media_stream_manager.h"
6 6
7 #include <list> 7 #include <list>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 13 matching lines...) Expand all
24 #include "content/browser/renderer_host/media/media_stream_requester.h" 24 #include "content/browser/renderer_host/media/media_stream_requester.h"
25 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" 25 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
26 #include "content/browser/renderer_host/media/video_capture_manager.h" 26 #include "content/browser/renderer_host/media/video_capture_manager.h"
27 #include "content/browser/renderer_host/render_process_host_impl.h" 27 #include "content/browser/renderer_host/render_process_host_impl.h"
28 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/content_browser_client.h" 29 #include "content/public/browser/content_browser_client.h"
30 #include "content/public/browser/media_device_id.h" 30 #include "content/public/browser/media_device_id.h"
31 #include "content/public/browser/media_observer.h" 31 #include "content/public/browser/media_observer.h"
32 #include "content/public/browser/media_request_state.h" 32 #include "content/public/browser/media_request_state.h"
33 #include "content/public/browser/render_process_host.h" 33 #include "content/public/browser/render_process_host.h"
34 #include "content/public/common/content_client.h"
34 #include "content/public/common/content_switches.h" 35 #include "content/public/common/content_switches.h"
35 #include "content/public/common/media_stream_request.h" 36 #include "content/public/common/media_stream_request.h"
36 #include "media/audio/audio_manager_base.h" 37 #include "media/audio/audio_manager_base.h"
37 #include "media/audio/audio_parameters.h" 38 #include "media/audio/audio_parameters.h"
38 #include "media/base/channel_layout.h" 39 #include "media/base/channel_layout.h"
39 #include "media/base/media_switches.h" 40 #include "media/base/media_switches.h"
40 #include "media/video/capture/video_capture_device_factory.h" 41 #include "media/video/capture/video_capture_device_factory.h"
41 #include "url/gurl.h" 42 #include "url/gurl.h"
42 43
43 #if defined(OS_WIN) 44 #if defined(OS_WIN)
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 // several subclasses of DeviceRequest and move some of the responsibility of 192 // several subclasses of DeviceRequest and move some of the responsibility of
192 // the MediaStreamManager to the subclasses to get rid of the way too many if 193 // the MediaStreamManager to the subclasses to get rid of the way too many if
193 // statements in MediaStreamManager. 194 // statements in MediaStreamManager.
194 class MediaStreamManager::DeviceRequest { 195 class MediaStreamManager::DeviceRequest {
195 public: 196 public:
196 DeviceRequest(MediaStreamRequester* requester, 197 DeviceRequest(MediaStreamRequester* requester,
197 int requesting_process_id, 198 int requesting_process_id,
198 int requesting_frame_id, 199 int requesting_frame_id,
199 int page_request_id, 200 int page_request_id,
200 const GURL& security_origin, 201 const GURL& security_origin,
201 bool have_permission,
202 bool user_gesture, 202 bool user_gesture,
203 MediaStreamRequestType request_type, 203 MediaStreamRequestType request_type,
204 const StreamOptions& options, 204 const StreamOptions& options,
205 const ResourceContext::SaltCallback& salt_callback) 205 const ResourceContext::SaltCallback& salt_callback)
206 : requester(requester), 206 : requester(requester),
207 requesting_process_id(requesting_process_id), 207 requesting_process_id(requesting_process_id),
208 requesting_frame_id(requesting_frame_id), 208 requesting_frame_id(requesting_frame_id),
209 page_request_id(page_request_id), 209 page_request_id(page_request_id),
210 security_origin(security_origin), 210 security_origin(security_origin),
211 have_permission(have_permission),
212 user_gesture(user_gesture), 211 user_gesture(user_gesture),
213 request_type(request_type), 212 request_type(request_type),
214 options(options), 213 options(options),
215 salt_callback(salt_callback), 214 salt_callback(salt_callback),
216 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), 215 state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED),
217 audio_type_(MEDIA_NO_SERVICE), 216 audio_type_(MEDIA_NO_SERVICE),
218 video_type_(MEDIA_NO_SERVICE) { 217 video_type_(MEDIA_NO_SERVICE) {
219 } 218 }
220 219
221 ~DeviceRequest() {} 220 ~DeviceRequest() {}
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 // will receive a handle to the MediaStream. This may be different from 317 // will receive a handle to the MediaStream. This may be different from
319 // MediaStreamRequest::render_frame_id which in the tab capture case 318 // MediaStreamRequest::render_frame_id which in the tab capture case
320 // specifies the target renderer from which audio and video is captured. 319 // specifies the target renderer from which audio and video is captured.
321 const int requesting_frame_id; 320 const int requesting_frame_id;
322 321
323 // An ID the render frame provided to identify this request. 322 // An ID the render frame provided to identify this request.
324 const int page_request_id; 323 const int page_request_id;
325 324
326 const GURL security_origin; 325 const GURL security_origin;
327 326
328 // This is used when enumerating devices; if we don't have device access
329 // permission, we remove the device label.
330 bool have_permission;
331
332 const bool user_gesture; 327 const bool user_gesture;
333 328
334 const MediaStreamRequestType request_type; 329 const MediaStreamRequestType request_type;
335 330
336 const StreamOptions options; 331 const StreamOptions options;
337 332
338 ResourceContext::SaltCallback salt_callback; 333 ResourceContext::SaltCallback salt_callback;
339 334
340 StreamDeviceInfoArray devices; 335 StreamDeviceInfoArray devices;
341 336
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 const MediaRequestResponseCallback& callback) { 421 const MediaRequestResponseCallback& callback) {
427 DCHECK_CURRENTLY_ON(BrowserThread::IO); 422 DCHECK_CURRENTLY_ON(BrowserThread::IO);
428 423
429 // TODO(perkj): The argument list with NULL parameters to DeviceRequest 424 // TODO(perkj): The argument list with NULL parameters to DeviceRequest
430 // suggests that this is the wrong design. Can this be refactored? 425 // suggests that this is the wrong design. Can this be refactored?
431 DeviceRequest* request = new DeviceRequest(NULL, 426 DeviceRequest* request = new DeviceRequest(NULL,
432 render_process_id, 427 render_process_id,
433 render_frame_id, 428 render_frame_id,
434 page_request_id, 429 page_request_id,
435 security_origin, 430 security_origin,
436 true,
437 false, // user gesture 431 false, // user gesture
438 MEDIA_DEVICE_ACCESS, 432 MEDIA_DEVICE_ACCESS,
439 options, 433 options,
440 base::Bind(&ReturnEmptySalt)); 434 base::Bind(&ReturnEmptySalt));
441 435
442 const std::string& label = AddRequest(request); 436 const std::string& label = AddRequest(request);
443 437
444 request->callback = callback; 438 request->callback = callback;
445 // Post a task and handle the request asynchronously. The reason is that the 439 // Post a task and handle the request asynchronously. The reason is that the
446 // requester won't have a label for the request until this function returns 440 // requester won't have a label for the request until this function returns
(...skipping 20 matching lines...) Expand all
467 if (CommandLine::ForCurrentProcess()->HasSwitch( 461 if (CommandLine::ForCurrentProcess()->HasSwitch(
468 switches::kUseFakeUIForMediaStream)) { 462 switches::kUseFakeUIForMediaStream)) {
469 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>()); 463 UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy>());
470 } 464 }
471 465
472 DeviceRequest* request = new DeviceRequest(requester, 466 DeviceRequest* request = new DeviceRequest(requester,
473 render_process_id, 467 render_process_id,
474 render_frame_id, 468 render_frame_id,
475 page_request_id, 469 page_request_id,
476 security_origin, 470 security_origin,
477 true,
478 user_gesture, 471 user_gesture,
479 MEDIA_GENERATE_STREAM, 472 MEDIA_GENERATE_STREAM,
480 options, 473 options,
481 sc); 474 sc);
482 475
483 const std::string& label = AddRequest(request); 476 const std::string& label = AddRequest(request);
484 477
485 // 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
486 // 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
487 // 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
650 } 643 }
651 } 644 }
652 645
653 std::string MediaStreamManager::EnumerateDevices( 646 std::string MediaStreamManager::EnumerateDevices(
654 MediaStreamRequester* requester, 647 MediaStreamRequester* requester,
655 int render_process_id, 648 int render_process_id,
656 int render_frame_id, 649 int render_frame_id,
657 const ResourceContext::SaltCallback& sc, 650 const ResourceContext::SaltCallback& sc,
658 int page_request_id, 651 int page_request_id,
659 MediaStreamType type, 652 MediaStreamType type,
660 const GURL& security_origin, 653 const GURL& security_origin) {
661 bool have_permission) {
662 DCHECK_CURRENTLY_ON(BrowserThread::IO); 654 DCHECK_CURRENTLY_ON(BrowserThread::IO);
663 DCHECK(requester); 655 DCHECK(requester);
664 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || 656 DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
665 type == MEDIA_DEVICE_VIDEO_CAPTURE || 657 type == MEDIA_DEVICE_VIDEO_CAPTURE ||
666 type == MEDIA_DEVICE_AUDIO_OUTPUT); 658 type == MEDIA_DEVICE_AUDIO_OUTPUT);
667 659
668 DeviceRequest* request = new DeviceRequest(requester, 660 DeviceRequest* request = new DeviceRequest(requester,
669 render_process_id, 661 render_process_id,
670 render_frame_id, 662 render_frame_id,
671 page_request_id, 663 page_request_id,
672 security_origin, 664 security_origin,
673 have_permission,
674 false, // user gesture 665 false, // user gesture
675 MEDIA_ENUMERATE_DEVICES, 666 MEDIA_ENUMERATE_DEVICES,
676 StreamOptions(), 667 StreamOptions(),
677 sc); 668 sc);
678 if (IsAudioInputMediaType(type) || type == MEDIA_DEVICE_AUDIO_OUTPUT) 669 if (IsAudioInputMediaType(type) || type == MEDIA_DEVICE_AUDIO_OUTPUT)
679 request->SetAudioType(type); 670 request->SetAudioType(type);
680 else if (IsVideoMediaType(type)) 671 else if (IsVideoMediaType(type))
681 request->SetVideoType(type); 672 request->SetVideoType(type);
682 673
683 const std::string& label = AddRequest(request); 674 const std::string& label = AddRequest(request);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 options.mandatory_video.push_back( 801 options.mandatory_video.push_back(
811 StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id)); 802 StreamOptions::Constraint(kMediaStreamSourceInfoId, device_id));
812 } else { 803 } else {
813 NOTREACHED(); 804 NOTREACHED();
814 } 805 }
815 DeviceRequest* request = new DeviceRequest(requester, 806 DeviceRequest* request = new DeviceRequest(requester,
816 render_process_id, 807 render_process_id,
817 render_frame_id, 808 render_frame_id,
818 page_request_id, 809 page_request_id,
819 security_origin, 810 security_origin,
820 true,
821 false, // user gesture 811 false, // user gesture
822 MEDIA_OPEN_DEVICE, 812 MEDIA_OPEN_DEVICE,
823 options, 813 options,
824 sc); 814 sc);
825 815
826 const std::string& label = AddRequest(request); 816 const std::string& label = AddRequest(request);
827 // Post a task and handle the request asynchronously. The reason is that the 817 // Post a task and handle the request asynchronously. The reason is that the
828 // requester won't have a label for the request until this function returns 818 // requester won't have a label for the request until this function returns
829 // and thus can not handle a response. Using base::Unretained is safe since 819 // and thus can not handle a response. Using base::Unretained is safe since
830 // MediaStreamManager is deleted on the UI thread, after the IO thread has 820 // MediaStreamManager is deleted on the UI thread, after the IO thread has
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 const StreamDeviceInfoArray& requested_devices = request->devices; 1450 const StreamDeviceInfoArray& requested_devices = request->devices;
1461 request->requester->DeviceOpened(request->requesting_frame_id, 1451 request->requester->DeviceOpened(request->requesting_frame_id,
1462 request->page_request_id, 1452 request->page_request_id,
1463 label, requested_devices.front()); 1453 label, requested_devices.front());
1464 } 1454 }
1465 1455
1466 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label, 1456 void MediaStreamManager::FinalizeEnumerateDevices(const std::string& label,
1467 DeviceRequest* request) { 1457 DeviceRequest* request) {
1468 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1458 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1469 DCHECK_EQ(request->request_type, MEDIA_ENUMERATE_DEVICES); 1459 DCHECK_EQ(request->request_type, MEDIA_ENUMERATE_DEVICES);
1460 DCHECK(((request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE ||
1461 request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT) &&
1462 request->video_type() == MEDIA_NO_SERVICE) ||
1463 (request->audio_type() == MEDIA_NO_SERVICE &&
1464 request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE));
1470 1465
1471 if (request->security_origin.is_valid()) { 1466 if (request->security_origin.is_valid()) {
1472 for (StreamDeviceInfoArray::iterator it = request->devices.begin(); 1467 for (StreamDeviceInfoArray::iterator it = request->devices.begin();
1473 it != request->devices.end(); ++it) { 1468 it != request->devices.end(); ++it) {
1474 TranslateDeviceIdToSourceId(request, &it->device); 1469 TranslateDeviceIdToSourceId(request, &it->device);
1475 } 1470 }
1476 } else { 1471 } else {
1477 request->devices.clear(); 1472 request->devices.clear();
1478 } 1473 }
1479 1474
1480 if (!request->have_permission) 1475 // Output label permissions are based on input permission.
1476 MediaStreamType type =
1477 request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE ||
1478 request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT
1479 ? MEDIA_DEVICE_AUDIO_CAPTURE
1480 : MEDIA_DEVICE_VIDEO_CAPTURE;
1481
1482 BrowserThread::PostTaskAndReplyWithResult(
1483 BrowserThread::UI,
1484 FROM_HERE,
1485 base::Bind(&MediaStreamManager::CheckMediaAccessOnUI,
1486 base::Unretained(this),
1487 request->requesting_process_id,
1488 request->security_origin,
1489 type),
1490 base::Bind(&MediaStreamManager::HandleCheckMediaAccessResponse,
1491 base::Unretained(this),
1492 label));
1493 }
1494
1495 bool MediaStreamManager::CheckMediaAccessOnUI(int render_process_id,
perkj_chrome 2014/08/29 09:38:10 CheckMediaAccessPermissionsOnUi?
Henrik Grunell 2014/08/29 11:20:08 Yes, that's good. Even ...OnUIThread() so that it'
1496 const GURL& security_origin,
1497 MediaStreamType type) {
1498 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1499
1500 RenderProcessHost* host =
1501 RenderProcessHost::FromID(render_process_id);
1502 if (!host) {
1503 // This can happen if the renderer goes away during the lifetime of a
1504 // request.
1505 return false;
1506 }
1507 content::BrowserContext* context = host->GetBrowserContext();
1508 DCHECK(context);
1509 return GetContentClient()->browser()->CheckMediaAccessPermission(
1510 context,
1511 security_origin,
1512 type);
1513 }
1514
1515 void MediaStreamManager::HandleCheckMediaAccessResponse(
1516 const std::string& label,
1517 bool have_access) {
1518 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1519
1520 DeviceRequest* request = FindRequest(label);
1521 if (!request) {
1522 // This can happen if the request was cancelled.
1523 DVLOG(1) << "The request with label " << label << " does not exist.";
1524 return;
1525 }
1526
1527 if (!have_access)
1481 ClearDeviceLabels(&request->devices); 1528 ClearDeviceLabels(&request->devices);
1482 1529
1483 request->requester->DevicesEnumerated( 1530 request->requester->DevicesEnumerated(
1484 request->requesting_frame_id, 1531 request->requesting_frame_id,
1485 request->page_request_id, 1532 request->page_request_id,
1486 label, 1533 label,
1487 request->devices); 1534 request->devices);
1488 1535
1489 // TODO(tommi): 1536 // TODO(tommi):
perkj_chrome 2014/08/29 09:38:10 Not this cl maybe, but is this todo still relevant
Henrik Grunell 2014/08/29 11:20:08 I think we still should separate the notification
1490 // Ideally enumeration requests should be deleted once they have been served 1537 // Ideally enumeration requests should be deleted once they have been served
1491 // (as any request). However, this implementation mixes requests and 1538 // (as any request). However, this implementation mixes requests and
1492 // notifications together so enumeration requests are kept open by some 1539 // notifications together so enumeration requests are kept open by some
1493 // implementations (only Pepper?) and enumerations are done again when 1540 // implementations (only Pepper?) and enumerations are done again when
1494 // device notifications are fired. 1541 // device notifications are fired.
1495 // Implementations that just want to request the device list and be done 1542 // Implementations that just want to request the device list and be done
1496 // (e.g. DeviceRequestMessageFilter), they must (confusingly) call 1543 // (e.g. DeviceRequestMessageFilter), they must (confusingly) call
1497 // CancelRequest() after the request has been fulfilled. This is not 1544 // CancelRequest() after the request has been fulfilled. This is not
1498 // obvious, not consistent in this class (see e.g. FinalizeMediaAccessRequest) 1545 // obvious, not consistent in this class (see e.g. FinalizeMediaAccessRequest)
1499 // and can lead to subtle bugs (requests not deleted at all deleted too 1546 // and can lead to subtle bugs (requests not deleted at all deleted too
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
2039 if (it->device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { 2086 if (it->device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
2040 video_capture_manager_->SetDesktopCaptureWindowId(it->session_id, 2087 video_capture_manager_->SetDesktopCaptureWindowId(it->session_id,
2041 window_id); 2088 window_id);
2042 break; 2089 break;
2043 } 2090 }
2044 } 2091 }
2045 } 2092 }
2046 } 2093 }
2047 2094
2048 } // namespace content 2095 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698