blob: d18a0a0a42cbba4261ac5590f6eb0a5d604ec7fc [file] [log] [blame]
// 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