| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/media/media_devices_permission_checker.h" |
| |
| #include <utility> |
| #include <vector> |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "content/browser/frame_host/render_frame_host_delegate.h" |
| #include "content/browser/frame_host/render_frame_host_impl.h" |
| #include "content/common/media/media_devices.h" |
| #include "content/public/browser/browser_context.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/common/content_switches.h" |
| #include "url/gurl.h" |
| #include "url/origin.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| MediaDevicesManager::BoolDeviceTypes DoCheckPermissionsOnUIThread( |
| MediaDevicesManager::BoolDeviceTypes requested_device_types, |
| int render_process_id, |
| int render_frame_id, |
| const url::Origin& security_origin) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| RenderFrameHostImpl* frame_host = |
| RenderFrameHostImpl::FromID(render_process_id, render_frame_id); |
| |
| // If there is no |frame_host|, return false for all permissions. |
| if (!frame_host) |
| return MediaDevicesManager::BoolDeviceTypes(); |
| |
| RenderFrameHostDelegate* delegate = frame_host->delegate(); |
| GURL origin = security_origin.GetURL(); |
| |
| // Currently, the MEDIA_DEVICE_AUDIO_CAPTURE permission is used for |
| // both audio input and output. |
| // TODO(guidou): use specific permission for audio output when it becomes |
| // available. See http://crbug.com/556542. |
| bool has_audio_permission = |
| (requested_device_types[MEDIA_DEVICE_TYPE_AUDIO_INPUT] || |
| requested_device_types[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT]) && |
| delegate->CheckMediaAccessPermission(origin, MEDIA_DEVICE_AUDIO_CAPTURE); |
| |
| MediaDevicesManager::BoolDeviceTypes result; |
| result[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = has_audio_permission; |
| result[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = has_audio_permission; |
| result[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = |
| requested_device_types[MEDIA_DEVICE_TYPE_VIDEO_INPUT] && |
| delegate->CheckMediaAccessPermission(origin, MEDIA_DEVICE_VIDEO_CAPTURE); |
| |
| return result; |
| } |
| |
| bool CheckSinglePermissionOnUIThread(MediaDeviceType device_type, |
| int render_process_id, |
| int render_frame_id, |
| const url::Origin& security_origin) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| MediaDevicesManager::BoolDeviceTypes requested; |
| requested[device_type] = true; |
| MediaDevicesManager::BoolDeviceTypes result = DoCheckPermissionsOnUIThread( |
| requested, render_process_id, render_frame_id, security_origin); |
| return result[device_type]; |
| } |
| |
| } // namespace |
| |
| MediaDevicesPermissionChecker::MediaDevicesPermissionChecker() |
| : use_override_(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kUseFakeUIForMediaStream)), |
| override_value_( |
| base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| switches::kUseFakeUIForMediaStream) != "deny") {} |
| |
| MediaDevicesPermissionChecker::MediaDevicesPermissionChecker( |
| bool override_value) |
| : use_override_(true), override_value_(override_value) {} |
| |
| bool MediaDevicesPermissionChecker::CheckPermissionOnUIThread( |
| MediaDeviceType device_type, |
| int render_process_id, |
| int render_frame_id, |
| const url::Origin& security_origin) const { |
| if (use_override_) |
| return override_value_; |
| |
| return CheckSinglePermissionOnUIThread(device_type, render_process_id, |
| render_frame_id, security_origin); |
| } |
| |
| void MediaDevicesPermissionChecker::CheckPermission( |
| MediaDeviceType device_type, |
| int render_process_id, |
| int render_frame_id, |
| const url::Origin& security_origin, |
| const base::Callback<void(bool)>& callback) const { |
| if (use_override_) { |
| callback.Run(override_value_); |
| return; |
| } |
| |
| BrowserThread::PostTaskAndReplyWithResult( |
| BrowserThread::UI, FROM_HERE, |
| base::Bind(&CheckSinglePermissionOnUIThread, device_type, |
| render_process_id, render_frame_id, security_origin), |
| callback); |
| } |
| |
| MediaDevicesManager::BoolDeviceTypes |
| MediaDevicesPermissionChecker::CheckPermissionsOnUIThread( |
| MediaDevicesManager::BoolDeviceTypes requested_device_types, |
| int render_process_id, |
| int render_frame_id, |
| const url::Origin& security_origin) const { |
| if (use_override_) { |
| MediaDevicesManager::BoolDeviceTypes result; |
| result.fill(override_value_); |
| return result; |
| } |
| |
| return DoCheckPermissionsOnUIThread(requested_device_types, render_process_id, |
| render_frame_id, security_origin); |
| } |
| |
| void MediaDevicesPermissionChecker::CheckPermissions( |
| MediaDevicesManager::BoolDeviceTypes requested, |
| int render_process_id, |
| int render_frame_id, |
| const url::Origin& security_origin, |
| const base::Callback<void(const MediaDevicesManager::BoolDeviceTypes&)>& |
| callback) const { |
| if (use_override_) { |
| MediaDevicesManager::BoolDeviceTypes result; |
| result.fill(override_value_); |
| callback.Run(result); |
| return; |
| } |
| |
| BrowserThread::PostTaskAndReplyWithResult( |
| BrowserThread::UI, FROM_HERE, |
| base::Bind(&DoCheckPermissionsOnUIThread, requested, render_process_id, |
| render_frame_id, security_origin), |
| callback); |
| } |
| |
| } // namespace content |