blob: defc1abb6d6dd8741961851155a1d31e9a1e3966 [file] [log] [blame]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/shell/browser/shell_permission_manager.h"
#include "base/command_line.h"
#include "base/functional/callback.h"
#include "components/permissions/permission_util.h"
#include "content/public/browser/permission_controller.h"
#include "content/public/browser/permission_result.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_switches.h"
#include "content/shell/common/shell_switches.h"
#include "media/base/media_switches.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "url/origin.h"
using blink::PermissionType;
namespace content {
namespace {
bool IsAllowlistedPermissionType(PermissionType permission) {
switch (permission) {
case PermissionType::GEOLOCATION:
case PermissionType::SENSORS:
case PermissionType::PAYMENT_HANDLER:
case PermissionType::WAKE_LOCK_SCREEN:
// Background Sync and Background Fetch browser tests require
// permission to be granted by default.
case PermissionType::BACKGROUND_SYNC:
case PermissionType::BACKGROUND_FETCH:
case PermissionType::PERIODIC_BACKGROUND_SYNC:
case PermissionType::IDLE_DETECTION:
// WebNFC browser tests require permission to be granted by default.
case PermissionType::NFC:
return true;
case PermissionType::MIDI:
if (base::FeatureList::IsEnabled(blink::features::kBlockMidiByDefault)) {
return false;
}
return true;
case PermissionType::MIDI_SYSEX:
case PermissionType::NOTIFICATIONS:
case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
case PermissionType::DURABLE_STORAGE:
case PermissionType::AUDIO_CAPTURE:
case PermissionType::VIDEO_CAPTURE:
case PermissionType::CLIPBOARD_READ_WRITE:
case PermissionType::CLIPBOARD_SANITIZED_WRITE:
case PermissionType::NUM:
case PermissionType::WAKE_LOCK_SYSTEM:
case PermissionType::HAND_TRACKING:
case PermissionType::VR:
case PermissionType::AR:
case PermissionType::STORAGE_ACCESS_GRANT:
case PermissionType::CAMERA_PAN_TILT_ZOOM:
case PermissionType::WINDOW_MANAGEMENT:
case PermissionType::LOCAL_FONTS:
case PermissionType::DISPLAY_CAPTURE:
case PermissionType::TOP_LEVEL_STORAGE_ACCESS:
case PermissionType::CAPTURED_SURFACE_CONTROL:
case PermissionType::SMART_CARD:
case PermissionType::WEB_PRINTING:
case PermissionType::SPEAKER_SELECTION:
case PermissionType::KEYBOARD_LOCK:
case PermissionType::POINTER_LOCK:
case PermissionType::AUTOMATIC_FULLSCREEN:
case PermissionType::WEB_APP_INSTALLATION:
case PermissionType::LOCAL_NETWORK_ACCESS:
return false;
}
NOTREACHED();
}
} // namespace
ShellPermissionManager::ShellPermissionManager() = default;
ShellPermissionManager::~ShellPermissionManager() = default;
void ShellPermissionManager::RequestPermissions(
RenderFrameHost* render_frame_host,
const PermissionRequestDescription& request_description,
base::OnceCallback<void(const std::vector<PermissionResult>&)> callback) {
if (render_frame_host->IsNestedWithinFencedFrame()) {
std::move(callback).Run(std::vector<PermissionResult>(
request_description.permissions.size(),
PermissionResult(blink::mojom::PermissionStatus::DENIED,
PermissionStatusSource::FENCED_FRAME)));
return;
}
std::vector<PermissionResult> result;
for (const auto& permission : request_description.permissions) {
result.emplace_back(
IsAllowlistedPermissionType(
blink::PermissionDescriptorToPermissionType(permission))
? blink::mojom::PermissionStatus::GRANTED
: blink::mojom::PermissionStatus::DENIED);
}
std::move(callback).Run(result);
}
void ShellPermissionManager::ResetPermission(
PermissionType permission,
const GURL& requesting_origin,
const GURL& embedding_origin) {
}
void ShellPermissionManager::RequestPermissionsFromCurrentDocument(
content::RenderFrameHost* render_frame_host,
const PermissionRequestDescription& request_description,
base::OnceCallback<void(const std::vector<PermissionResult>&)> callback) {
if (render_frame_host->IsNestedWithinFencedFrame()) {
std::move(callback).Run(std::vector<PermissionResult>(
request_description.permissions.size(),
PermissionResult(blink::mojom::PermissionStatus::DENIED)));
return;
}
std::vector<PermissionResult> result;
for (const auto& permission : request_description.permissions) {
result.emplace_back(
IsAllowlistedPermissionType(
blink::PermissionDescriptorToPermissionType(permission))
? blink::mojom::PermissionStatus::GRANTED
: blink::mojom::PermissionStatus::DENIED);
}
std::move(callback).Run(result);
}
blink::mojom::PermissionStatus ShellPermissionManager::GetPermissionStatus(
const blink::mojom::PermissionDescriptorPtr& permission_descriptor,
const GURL& requesting_origin,
const GURL& embedding_origin) {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
const auto permission_type =
blink::PermissionDescriptorToPermissionType(permission_descriptor);
if ((permission_type == PermissionType::AUDIO_CAPTURE ||
permission_type == PermissionType::VIDEO_CAPTURE) &&
command_line->HasSwitch(switches::kUseFakeDeviceForMediaStream) &&
command_line->HasSwitch(switches::kUseFakeUIForMediaStream) &&
command_line->GetSwitchValueASCII(
switches::kUseFakeDeviceForMediaStream) != "deny") {
return blink::mojom::PermissionStatus::GRANTED;
}
return IsAllowlistedPermissionType(permission_type)
? blink::mojom::PermissionStatus::GRANTED
: blink::mojom::PermissionStatus::DENIED;
}
PermissionResult
ShellPermissionManager::GetPermissionResultForOriginWithoutContext(
const blink::mojom::PermissionDescriptorPtr& permission_descriptor,
const url::Origin& requesting_origin,
const url::Origin& embedding_origin) {
blink::mojom::PermissionStatus status =
GetPermissionStatus(permission_descriptor, requesting_origin.GetURL(),
embedding_origin.GetURL());
return PermissionResult(status);
}
PermissionResult ShellPermissionManager::GetPermissionResultForCurrentDocument(
const blink::mojom::PermissionDescriptorPtr& permission_descriptor,
content::RenderFrameHost* render_frame_host,
bool should_include_device_status) {
if (render_frame_host->IsNestedWithinFencedFrame())
return PermissionResult(blink::mojom::PermissionStatus::DENIED);
return PermissionResult(GetPermissionStatus(
permission_descriptor,
permissions::PermissionUtil::GetLastCommittedOriginAsURL(
render_frame_host),
permissions::PermissionUtil::GetLastCommittedOriginAsURL(
render_frame_host->GetMainFrame())));
}
PermissionResult ShellPermissionManager::GetPermissionResultForWorker(
const blink::mojom::PermissionDescriptorPtr& permission_descriptor,
content::RenderProcessHost* render_process_host,
const GURL& worker_origin) {
return PermissionResult(
GetPermissionStatus(permission_descriptor, worker_origin, worker_origin));
}
PermissionResult
ShellPermissionManager::GetPermissionResultForEmbeddedRequester(
const blink::mojom::PermissionDescriptorPtr& permission_descriptor,
content::RenderFrameHost* render_frame_host,
const url::Origin& overridden_origin) {
if (render_frame_host->IsNestedWithinFencedFrame()) {
return PermissionResult(blink::mojom::PermissionStatus::DENIED);
}
return PermissionResult(GetPermissionStatus(
permission_descriptor, overridden_origin.GetURL(),
permissions::PermissionUtil::GetLastCommittedOriginAsURL(
render_frame_host->GetMainFrame())));
}
} // namespace content