// 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
