// Copyright 2017 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/browser/devtools/protocol/browser_handler.h"

#include <string.h>

#include <algorithm>
#include <memory>
#include <optional>
#include <string>

#include "base/command_line.h"
#include "base/containers/map_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/immediate_crash.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_samples.h"
#include "base/metrics/statistics_recorder.h"
#include "base/notreached.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/types/expected_macros.h"
#include "build/build_config.h"
#include "build/util/chromium_git_revision.h"
#include "components/download/public/common/download_item.h"
#include "content/browser/devtools/browser_devtools_agent_host.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/devtools_manager.h"
#include "content/browser/devtools/protocol/devtools_download_manager_delegate.h"
#include "content/browser/global_privacy_control_util.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "net/base/filename_util.h"
#include "third_party/blink/public/common/global_privacy_control/global_privacy_control_util.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "url/gurl.h"
#include "v8/include/v8-version-string.h"

using blink::PermissionType;

namespace content {
namespace protocol {

namespace {

base::expected<std::optional<url::Origin>, Response> ParseOriginString(
    base::optional_ref<const std::string> origin_string) {
  if (!origin_string.has_value()) {
    return std::nullopt;
  }

  url::Origin origin = url::Origin::Create(GURL(origin_string.value()));
  if (origin.opaque()) {
    return base::unexpected(Response::InvalidParams(
        "Permission can't be granted to opaque origins."));
  }

  return origin;
}

}  // namespace

BrowserHandler::BrowserHandler(bool allow_set_download_behavior)
    : DevToolsDomainHandler(Browser::Metainfo::domainName),
      download_events_enabled_(false),
      allow_set_download_behavior_(allow_set_download_behavior) {}

BrowserHandler::~BrowserHandler() = default;

Response BrowserHandler::Disable() {
  // TODO: this leaks context ids for all contexts with overridden permissions.
  for (auto& browser_context_id : contexts_with_overridden_permissions_) {
    content::BrowserContext* browser_context = nullptr;
    std::string error;
    std::optional<std::string> context_id =
        browser_context_id == ""
            ? std::nullopt
            : std::optional<std::string>(browser_context_id);
    FindBrowserContext(context_id, &browser_context);
    if (browser_context) {
      PermissionControllerImpl* permission_controller =
          PermissionControllerImpl::FromBrowserContext(browser_context);
      permission_controller->ResetPermissionOverrides(base::DoNothing());
    }
  }
  contexts_with_overridden_permissions_.clear();

  // TODO: this leaks context ids for all contexts with overridden downloads.
  for (auto& browser_context_id : contexts_with_overridden_downloads_) {
    content::BrowserContext* browser_context = nullptr;
    std::string error;
    std::optional<std::string> context_id =
        browser_context_id == ""
            ? std::nullopt
            : std::optional<std::string>(browser_context_id);
    FindBrowserContext(context_id, &browser_context);
    if (browser_context) {
      auto* delegate =
          DevToolsDownloadManagerDelegate::GetInstance(browser_context);
      if (delegate) {
        delegate->set_download_behavior(
            DevToolsDownloadManagerDelegate::DownloadBehavior::DEFAULT);
      }
    }
  }
  contexts_with_overridden_downloads_.clear();
  SetDownloadEventsEnabled(false);
  histograms_snapshots_.clear();

  if (session()->GetAgentHost()->GetType() == DevToolsAgentHost::kTypeBrowser) {
    ResetGlobalPrivacyControlDevToolsOverride();
  }

  return Response::Success();
}

void BrowserHandler::Wire(UberDispatcher* dispatcher) {
  frontend_ = std::make_unique<Browser::Frontend>(dispatcher->channel());
  Browser::Dispatcher::wire(dispatcher, this);
}

Response BrowserHandler::GetVersion(std::string* protocol_version,
                                    std::string* product,
                                    std::string* revision,
                                    std::string* user_agent,
                                    std::string* js_version) {
  *protocol_version = DevToolsAgentHost::GetProtocolVersion();
  *revision = CHROMIUM_GIT_REVISION;
  *product = GetContentClient()->browser()->GetProduct();
  *user_agent = GetContentClient()->browser()->GetUserAgent();
  *js_version = V8_VERSION_STRING;
  return Response::Success();
}

namespace {
// Parses PermissionDescriptors (|descriptor|) into their appropriate
// PermissionType |permission_type| by duplicating the logic in the methods
// //third_party/blink/renderer/modules/permissions:permissions
// ::ParsePermission and
// //content/browser/permissions:permission_service_impl
// ::PermissionDescriptorToPermissionType, producing an error in
// |error_message| as necessary.
// TODO(crbug.com/40638575): De-duplicate this logic.
Response PermissionDescriptorToPermissionType(
    std::unique_ptr<protocol::Browser::PermissionDescriptor> descriptor,
    PermissionType* permission_type) {
  const std::string name = descriptor->GetName();

  if (name == "geolocation") {
    *permission_type = PermissionType::GEOLOCATION;
  } else if (name == "camera") {
    if (descriptor->GetPanTiltZoom(false))
      *permission_type = PermissionType::CAMERA_PAN_TILT_ZOOM;
    else
      *permission_type = PermissionType::VIDEO_CAPTURE;
  } else if (name == "microphone") {
    *permission_type = PermissionType::AUDIO_CAPTURE;
  } else if (name == "notifications") {
    *permission_type = PermissionType::NOTIFICATIONS;
  } else if (name == "persistent-storage") {
    *permission_type = PermissionType::PERSISTENT_STORAGE;
  } else if (name == "push") {
    if (!descriptor->GetUserVisibleOnly(false)) {
      return Response::InvalidParams(
          "Push Permission without userVisibleOnly:true isn't supported");
    }
    *permission_type = PermissionType::NOTIFICATIONS;
  } else if (name == "midi") {
    if (descriptor->GetSysex(false))
      *permission_type = PermissionType::MIDI_SYSEX;
    else
      *permission_type = PermissionType::MIDI;
  } else if (name == "background-sync") {
    *permission_type = PermissionType::BACKGROUND_SYNC;
  } else if (name == "ambient-light-sensor" || name == "accelerometer" ||
             name == "gyroscope" || name == "magnetometer") {
    *permission_type = PermissionType::SENSORS;
  } else if (name == "clipboard-read") {
    *permission_type = PermissionType::CLIPBOARD_READ_WRITE;
  } else if (name == "clipboard-write") {
    if (descriptor->GetAllowWithoutSanitization(false))
      *permission_type = PermissionType::CLIPBOARD_READ_WRITE;
    else
      *permission_type = PermissionType::CLIPBOARD_SANITIZED_WRITE;
  } else if (name == "payment-handler") {
    *permission_type = PermissionType::PAYMENT_HANDLER;
  } else if (name == "background-fetch") {
    *permission_type = PermissionType::BACKGROUND_FETCH;
  } else if (name == "idle-detection") {
    *permission_type = PermissionType::IDLE_DETECTION;
  } else if (name == "periodic-background-sync") {
    *permission_type = PermissionType::PERIODIC_BACKGROUND_SYNC;
  } else if (name == "screen-wake-lock") {
    *permission_type = PermissionType::WAKE_LOCK_SCREEN;
  } else if (name == "system-wake-lock") {
    *permission_type = PermissionType::WAKE_LOCK_SYSTEM;
  } else if (name == "nfc") {
    *permission_type = PermissionType::NFC;
  } else if (name == "window-management") {
    *permission_type = PermissionType::WINDOW_MANAGEMENT;
  } else if (name == "local-fonts") {
    *permission_type = PermissionType::LOCAL_FONTS;
  } else if (name == "display-capture") {
    *permission_type = PermissionType::DISPLAY_CAPTURE;
  } else if (name == "storage-access") {
    *permission_type = PermissionType::STORAGE_ACCESS_GRANT;
  } else if (name == "top-level-storage-access") {
    *permission_type = PermissionType::TOP_LEVEL_STORAGE_ACCESS;
  } else if (name == "captured-surface-control") {
    *permission_type = PermissionType::CAPTURED_SURFACE_CONTROL;
  } else if (name == "speaker-selection") {
    *permission_type = PermissionType::SPEAKER_SELECTION;
  } else if (name == "keyboard-lock") {
    *permission_type = PermissionType::KEYBOARD_LOCK;
  } else if (name == "pointer-lock") {
    *permission_type = PermissionType::POINTER_LOCK;
  } else if (name == "fullscreen") {
    if (!descriptor->GetAllowWithoutGesture(false)) {
      // There is no PermissionType for fullscreen with user gesture.
      return Response::InvalidParams(
          "Fullscreen Permission only supports allowWithoutGesture:true");
    }
    *permission_type = PermissionType::AUTOMATIC_FULLSCREEN;
  } else if (name == "web-app-installation") {
    *permission_type = PermissionType::WEB_APP_INSTALLATION;
  } else if (name == "local-network-access") {
    *permission_type = PermissionType::LOCAL_NETWORK_ACCESS;
  } else if (name == "local-network") {
    *permission_type = PermissionType::LOCAL_NETWORK;
  } else if (name == "loopback-network") {
    *permission_type = PermissionType::LOOPBACK_NETWORK;
  } else {
    return Response::InvalidParams("Invalid PermissionDescriptor name: " +
                                   name);
  }

  return Response::Success();
}

Response FromProtocolPermissionType(
    const protocol::Browser::PermissionType& type,
    PermissionType* out_type) {
  // Please keep this in the same order as blink::PermissionType enum in
  // third_party/blink/public/common/permissions/permission_utils.h
  if (type == protocol::Browser::PermissionTypeEnum::MidiSysex) {
    *out_type = PermissionType::MIDI_SYSEX;
  } else if (type == protocol::Browser::PermissionTypeEnum::Notifications) {
    *out_type = PermissionType::NOTIFICATIONS;
  } else if (type == protocol::Browser::PermissionTypeEnum::Geolocation) {
    *out_type = PermissionType::GEOLOCATION;
  } else if (type ==
             protocol::Browser::PermissionTypeEnum::ProtectedMediaIdentifier) {
    *out_type = PermissionType::PROTECTED_MEDIA_IDENTIFIER;
  } else if (type == protocol::Browser::PermissionTypeEnum::Midi) {
    *out_type = PermissionType::MIDI;
  } else if (type == protocol::Browser::PermissionTypeEnum::DurableStorage) {
    *out_type = PermissionType::PERSISTENT_STORAGE;
  } else if (type == protocol::Browser::PermissionTypeEnum::AudioCapture) {
    *out_type = PermissionType::AUDIO_CAPTURE;
  } else if (type == protocol::Browser::PermissionTypeEnum::VideoCapture) {
    *out_type = PermissionType::VIDEO_CAPTURE;
  } else if (type == protocol::Browser::PermissionTypeEnum::BackgroundSync) {
    *out_type = PermissionType::BACKGROUND_SYNC;
  } else if (type == protocol::Browser::PermissionTypeEnum::Sensors) {
    *out_type = PermissionType::SENSORS;
  } else if (type == protocol::Browser::PermissionTypeEnum::PaymentHandler) {
    *out_type = PermissionType::PAYMENT_HANDLER;
  } else if (type == protocol::Browser::PermissionTypeEnum::BackgroundFetch) {
    *out_type = PermissionType::BACKGROUND_FETCH;
  } else if (type == protocol::Browser::PermissionTypeEnum::IdleDetection) {
    *out_type = PermissionType::IDLE_DETECTION;
  } else if (type ==
             protocol::Browser::PermissionTypeEnum::PeriodicBackgroundSync) {
    *out_type = PermissionType::PERIODIC_BACKGROUND_SYNC;
  } else if (type == protocol::Browser::PermissionTypeEnum::WakeLockScreen) {
    *out_type = PermissionType::WAKE_LOCK_SCREEN;
  } else if (type == protocol::Browser::PermissionTypeEnum::WakeLockSystem) {
    *out_type = PermissionType::WAKE_LOCK_SYSTEM;
  } else if (type == protocol::Browser::PermissionTypeEnum::Nfc) {
    *out_type = PermissionType::NFC;
  } else if (type ==
             protocol::Browser::PermissionTypeEnum::ClipboardReadWrite) {
    *out_type = PermissionType::CLIPBOARD_READ_WRITE;
  } else if (type ==
             protocol::Browser::PermissionTypeEnum::ClipboardSanitizedWrite) {
    *out_type = PermissionType::CLIPBOARD_SANITIZED_WRITE;
  } else if (type == protocol::Browser::PermissionTypeEnum::Vr) {
    *out_type = PermissionType::VR;
  } else if (type == protocol::Browser::PermissionTypeEnum::Ar) {
    *out_type = PermissionType::AR;
  } else if (type == protocol::Browser::PermissionTypeEnum::StorageAccess) {
    *out_type = PermissionType::STORAGE_ACCESS_GRANT;
  } else if (type == protocol::Browser::PermissionTypeEnum::CameraPanTiltZoom) {
    *out_type = PermissionType::CAMERA_PAN_TILT_ZOOM;
  } else if (type == protocol::Browser::PermissionTypeEnum::WindowManagement) {
    *out_type = PermissionType::WINDOW_MANAGEMENT;
  } else if (type == protocol::Browser::PermissionTypeEnum::LocalFonts) {
    *out_type = PermissionType::LOCAL_FONTS;
  } else if (type == protocol::Browser::PermissionTypeEnum::DisplayCapture) {
    *out_type = PermissionType::DISPLAY_CAPTURE;
  } else if (type ==
             protocol::Browser::PermissionTypeEnum::TopLevelStorageAccess) {
    *out_type = PermissionType::TOP_LEVEL_STORAGE_ACCESS;
  } else if (type ==
             protocol::Browser::PermissionTypeEnum::CapturedSurfaceControl) {
    *out_type = PermissionType::CAPTURED_SURFACE_CONTROL;
  } else if (type == protocol::Browser::PermissionTypeEnum::SmartCard) {
    *out_type = PermissionType::SMART_CARD;
  } else if (type == protocol::Browser::PermissionTypeEnum::WebPrinting) {
    *out_type = PermissionType::WEB_PRINTING;
  } else if (type == protocol::Browser::PermissionTypeEnum::SpeakerSelection) {
    *out_type = PermissionType::SPEAKER_SELECTION;
  } else if (type == protocol::Browser::PermissionTypeEnum::KeyboardLock) {
    *out_type = PermissionType::KEYBOARD_LOCK;
  } else if (type == protocol::Browser::PermissionTypeEnum::PointerLock) {
    *out_type = PermissionType::POINTER_LOCK;
  } else if (type ==
             protocol::Browser::PermissionTypeEnum::AutomaticFullscreen) {
    *out_type = PermissionType::AUTOMATIC_FULLSCREEN;
  } else if (type == protocol::Browser::PermissionTypeEnum::HandTracking) {
    *out_type = PermissionType::HAND_TRACKING;
  } else if (type ==
             protocol::Browser::PermissionTypeEnum::WebAppInstallation) {
    *out_type = PermissionType::WEB_APP_INSTALLATION;
  } else if (type ==
             protocol::Browser::PermissionTypeEnum::LocalNetworkAccess) {
    *out_type = PermissionType::LOCAL_NETWORK_ACCESS;
  } else if (type == protocol::Browser::PermissionTypeEnum::LocalNetwork) {
    *out_type = PermissionType::LOCAL_NETWORK;
  } else if (type == protocol::Browser::PermissionTypeEnum::LoopbackNetwork) {
    *out_type = PermissionType::LOOPBACK_NETWORK;
  } else {
    return Response::InvalidParams("Unknown permission type: " + type);
  }

  return Response::Success();
}

Response PermissionSettingToPermissionStatus(
    const protocol::Browser::PermissionSetting& setting,
    blink::mojom::PermissionStatus* out_status) {
  if (setting == protocol::Browser::PermissionSettingEnum::Granted) {
    *out_status = blink::mojom::PermissionStatus::GRANTED;
  } else if (setting == protocol::Browser::PermissionSettingEnum::Denied) {
    *out_status = blink::mojom::PermissionStatus::DENIED;
  } else if (setting == protocol::Browser::PermissionSettingEnum::Prompt) {
    *out_status = blink::mojom::PermissionStatus::ASK;
  } else {
    return Response::InvalidParams("Unknown permission setting: " + setting);
  }
  return Response::Success();
}

}  // namespace

// static
Response BrowserHandler::FindBrowserContext(
    const std::optional<std::string>& browser_context_id,
    BrowserContext** browser_context) {
  DevToolsManagerDelegate* delegate =
      DevToolsManager::GetInstance()->delegate();
  if (!delegate)
    return Response::ServerError(
        "Browser context management is not supported.");
  if (!browser_context_id.has_value()) {
    *browser_context = delegate->GetDefaultBrowserContext();
    if (!*browser_context) {
      return Response::ServerError(
          "Browser context management is not supported.");
    }
    return Response::Success();
  }
  *browser_context = delegate->GetBrowserContext(browser_context_id.value());
  if (!*browser_context) {
    return Response::InvalidParams("Failed to find browser context for id " +
                                   browser_context_id.value());
  }
  return Response::Success();
}

// static
std::vector<BrowserHandler*> BrowserHandler::ForAgentHost(
    DevToolsAgentHostImpl* host) {
  return host->HandlersByName<BrowserHandler>(Browser::Metainfo::domainName);
}

void BrowserHandler::SetPermission(
    std::unique_ptr<protocol::Browser::PermissionDescriptor> permission,
    const protocol::Browser::PermissionSetting& setting,
    std::optional<std::string> origin,
    std::optional<std::string> embedded_origin,
    std::optional<std::string> browser_context_id,
    std::unique_ptr<protocol::Browser::Backend::SetPermissionCallback>
        callback) {
  BrowserContext* browser_context = nullptr;
  Response response = FindBrowserContext(browser_context_id, &browser_context);
  if (!response.IsSuccess()) {
    callback->sendFailure(response);
    return;
  }

  PermissionType type;
  Response parse_response =
      PermissionDescriptorToPermissionType(std::move(permission), &type);
  if (!parse_response.IsSuccess()) {
    callback->sendFailure(parse_response);
    return;
  }

  blink::mojom::PermissionStatus permission_status;
  Response setting_response =
      PermissionSettingToPermissionStatus(setting, &permission_status);
  if (!setting_response.IsSuccess()) {
    callback->sendFailure(setting_response);
    return;
  }

  PermissionControllerImpl* permission_controller =
      PermissionControllerImpl::FromBrowserContext(browser_context);

  std::optional<url::Origin> overridden_embedding_origin;
  std::optional<url::Origin> overridden_requesting_origin;
  if (origin.has_value()) {
    ASSIGN_OR_RETURN(
        overridden_embedding_origin, ParseOriginString(origin),
        [&callback](Response response) { callback->sendFailure(response); });

    // Only consider `embedded_origin` if `origin` is valid and non-nullopt. Use
    // `origin` as `overridden_requesting_origin`, if `embedded_origin` is
    // nullopt.
    ASSIGN_OR_RETURN(
        overridden_requesting_origin, ParseOriginString(embedded_origin),
        [&callback](Response response) { callback->sendFailure(response); });
    if (!overridden_requesting_origin) {
      overridden_requesting_origin = overridden_embedding_origin;
    }
  }

  permission_controller->SetPermissionOverride(
      overridden_requesting_origin, overridden_embedding_origin, type,
      permission_status,
      base::BindOnce(
          [](base::WeakPtr<BrowserHandler> browser_handler,
             std::optional<std::string> browser_context_id,
             std::unique_ptr<protocol::Browser::Backend::SetPermissionCallback>
                 callback,
             PermissionType type,
             PermissionControllerImpl::OverrideStatus status) {
            if (status ==
                PermissionControllerImpl::OverrideStatus::kOverrideSet) {
              if (browser_handler) {
                browser_handler->UpdateContextsWithOverriddenPermissions(
                    browser_context_id);
              }
              callback->sendSuccess();
            } else {
              callback->sendFailure(Response::InvalidParams(
                  "Permission can't be granted in current context."));
            }
          },
          weak_ptr_factory_.GetWeakPtr(), browser_context_id,
          std::move(callback), type));
}

void BrowserHandler::GrantPermissions(
    std::unique_ptr<protocol::Array<protocol::Browser::PermissionType>>
        permissions,
    std::optional<std::string> origin,
    std::optional<std::string> browser_context_id,
    std::unique_ptr<protocol::Browser::Backend::GrantPermissionsCallback>
        callback) {
  BrowserContext* browser_context = nullptr;
  Response response = FindBrowserContext(browser_context_id, &browser_context);
  if (!response.IsSuccess()) {
    callback->sendFailure(response);
    return;
  }

  std::vector<PermissionType> internal_permissions;
  internal_permissions.reserve(permissions->size());
  for (const protocol::Browser::PermissionType& t : *permissions) {
    PermissionType type;
    Response type_response = FromProtocolPermissionType(t, &type);
    if (!type_response.IsSuccess()) {
      callback->sendFailure(type_response);
      return;
    }
    internal_permissions.push_back(type);
  }

  PermissionControllerImpl* permission_controller =
      PermissionControllerImpl::FromBrowserContext(browser_context);
  std::optional<url::Origin> overridden_origin;
  if (origin.has_value()) {
    overridden_origin = url::Origin::Create(GURL(origin.value()));
    if (overridden_origin->opaque()) {
      callback->sendFailure(Response::InvalidParams(
          "Permission can't be granted to opaque origins."));
      return;
    }
  }

  permission_controller->GrantPermissionOverrides(
      overridden_origin, overridden_origin, internal_permissions,
      base::BindOnce(
          [](base::WeakPtr<BrowserHandler> browser_handler,
             std::optional<std::string> browser_context_id,
             std::unique_ptr<
                 protocol::Browser::Backend::GrantPermissionsCallback> callback,
             PermissionControllerImpl::OverrideStatus status) {
            if (status ==
                PermissionControllerImpl::OverrideStatus::kOverrideSet) {
              if (browser_handler) {
                browser_handler->UpdateContextsWithOverriddenPermissions(
                    browser_context_id);
              }
              callback->sendSuccess();
            } else {
              callback->sendFailure(Response::InvalidParams(
                  "Permission can't be granted in current context."));
            }
          },
          weak_ptr_factory_.GetWeakPtr(), browser_context_id,
          std::move(callback)));
}

void BrowserHandler::ResetPermissions(
    std::optional<std::string> browser_context_id,
    std::unique_ptr<protocol::Browser::Backend::ResetPermissionsCallback>
        callback) {
  BrowserContext* browser_context = nullptr;
  Response response = FindBrowserContext(browser_context_id, &browser_context);
  if (!response.IsSuccess()) {
    callback->sendFailure(response);
    return;
  }
  PermissionControllerImpl* permission_controller =
      PermissionControllerImpl::FromBrowserContext(browser_context);
  permission_controller->ResetPermissionOverrides(base::BindOnce(
      &protocol::Browser::Backend::ResetPermissionsCallback::sendSuccess,
      std::move(callback)));
  contexts_with_overridden_permissions_.erase(browser_context_id.value_or(""));
}

void BrowserHandler::UpdateContextsWithOverriddenPermissions(
    base::optional_ref<const std::string> browser_context_id) {
  contexts_with_overridden_permissions_.insert(
      browser_context_id.has_value() ? browser_context_id.value() : "");
}

Response BrowserHandler::SetDownloadBehavior(
    const std::string& behavior,
    std::optional<std::string> browser_context_id,
    std::optional<std::string> download_path,
    std::optional<bool> events_enabled) {
  BrowserContext* browser_context = nullptr;
  Response response = FindBrowserContext(browser_context_id, &browser_context);
  if (!response.IsSuccess())
    return response;
  response = DoSetDownloadBehavior(behavior, browser_context,
                                   std::move(download_path));
  if (!response.IsSuccess())
    return response;

  SetDownloadEventsEnabled(events_enabled.value_or(false));
  return response;
}

Response BrowserHandler::DoSetDownloadBehavior(
    const std::string& behavior,
    BrowserContext* browser_context,
    std::optional<std::string> download_path) {
  if (!allow_set_download_behavior_)
    return Response::ServerError("Not allowed");
  if (behavior == Browser::SetDownloadBehavior::BehaviorEnum::Allow &&
      !download_path.has_value()) {
    return Response::InvalidParams("downloadPath not provided");
  }
  DevToolsManagerDelegate* manager_delegate =
      DevToolsManager::GetInstance()->delegate();
  if (!manager_delegate) {
    return Response::ServerError(
        "Browser context management is not supported.");
  }

  auto* delegate =
      DevToolsDownloadManagerDelegate::GetOrCreateInstance(browser_context);
  if (behavior == Browser::SetDownloadBehavior::BehaviorEnum::Allow) {
    delegate->set_download_behavior(
        DevToolsDownloadManagerDelegate::DownloadBehavior::ALLOW);
    delegate->set_download_path(download_path.value());
  } else if (behavior ==
             Browser::SetDownloadBehavior::BehaviorEnum::AllowAndName) {
    delegate->set_download_behavior(
        DevToolsDownloadManagerDelegate::DownloadBehavior::ALLOW_AND_NAME);
    delegate->set_download_path(download_path.value());
  } else if (behavior == Browser::SetDownloadBehavior::BehaviorEnum::Deny) {
    delegate->set_download_behavior(
        DevToolsDownloadManagerDelegate::DownloadBehavior::DENY);
  } else {
    delegate->set_download_behavior(
        DevToolsDownloadManagerDelegate::DownloadBehavior::DEFAULT);
  }
  contexts_with_overridden_downloads_.insert(
      manager_delegate->GetDefaultBrowserContext() == browser_context
          ? ""
          : browser_context->UniqueId());

  return Response::Success();
}

Response BrowserHandler::CancelDownload(
    const std::string& guid,
    std::optional<std::string> browser_context_id) {
  BrowserContext* browser_context = nullptr;
  Response response = FindBrowserContext(browser_context_id, &browser_context);
  if (!response.IsSuccess())
    return response;
  auto* delegate =
      DevToolsDownloadManagerDelegate::GetOrCreateInstance(browser_context);
  auto* download_item = delegate->GetDownloadByGuid(guid);
  if (!download_item)
    return Response::InvalidParams("No download item found for the given GUID");
  // DownloadItem::Cancel is implemented in a soft way, where there would be no
  // error triggered if the state is not suitable for cancallation (e.g.
  // already cancelled or finished).
  download_item->Cancel(true);
  return Response::Success();
}

Response BrowserHandler::GetHistograms(
    const std::optional<std::string> in_query,
    const std::optional<bool> in_delta,
    std::unique_ptr<Array<Browser::Histogram>>* const out_histograms) {
  DCHECK(out_histograms);
  bool get_deltas = in_delta.value_or(false);
  *out_histograms = std::make_unique<Array<Browser::Histogram>>();
  for (base::HistogramBase* const h :
       base::StatisticsRecorder::Sort(base::StatisticsRecorder::WithName(
           base::StatisticsRecorder::GetHistograms(), in_query.value_or("")))) {
    DCHECK(h);
    (*out_histograms)->emplace_back(GetHistogramData(*h, get_deltas));
  }

  return Response::Success();
}

Response BrowserHandler::GetHistogram(
    const std::string& in_name,
    const std::optional<bool> in_delta,
    std::unique_ptr<Browser::Histogram>* const out_histogram) {
  // Get histogram by name.
  base::HistogramBase* const in_histogram =
      base::StatisticsRecorder::FindHistogram(in_name);
  if (!in_histogram)
    return Response::InvalidParams("Cannot find histogram: " + in_name);

  DCHECK(out_histogram);
  *out_histogram = GetHistogramData(*in_histogram, in_delta.value_or(false));

  return Response::Success();
}

Response BrowserHandler::GetBrowserCommandLine(
    std::unique_ptr<protocol::Array<std::string>>* arguments) {
  *arguments = std::make_unique<protocol::Array<std::string>>();
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  // The commandline is potentially sensitive, only return it if it
  // contains kEnableAutomation.
  if (command_line->HasSwitch(switches::kEnableAutomation)) {
    for (const auto& arg : command_line->argv()) {
#if BUILDFLAG(IS_WIN)
      (*arguments)->emplace_back(base::WideToUTF8(arg));
#else
      (*arguments)->emplace_back(arg);
#endif
    }
    return Response::Success();
  } else {
    return Response::ServerError(
        "Command line not returned because --enable-automation not set.");
  }
}

Response BrowserHandler::Crash() {
  base::ImmediateCrash();
}

Response BrowserHandler::CrashGpuProcess() {
  auto* host = GpuProcessHost::Get();
  if (host) {
    host->gpu_service()->Crash();
  }
  return Response::Success();
}

Response BrowserHandler::GetGlobalPrivacyControl(bool* out_gpc) {
  if (!blink::IsGlobalPrivacyControlFeatureEnabled()) {
    return Response::ServerError("Global Privacy Control is disabled.");
  }
  if (session()->GetAgentHost()->GetType() != DevToolsAgentHost::kTypeBrowser) {
    return Response::ServerError("Browser agent host required");
  }
  *out_gpc = IsGlobalPrivacyControlSettingEnabled();
  return Response::Success();
}

Response BrowserHandler::SetGlobalPrivacyControl(bool in_gpc, bool* out_gpc) {
  if (!blink::IsGlobalPrivacyControlFeatureEnabled()) {
    return Response::ServerError("Global Privacy Control is disabled.");
  }
  if (session()->GetAgentHost()->GetType() != DevToolsAgentHost::kTypeBrowser) {
    return Response::ServerError("Browser agent host required");
  }
  UpdateGlobalPrivacyControlDevToolsOverride(in_gpc);
  *out_gpc = IsGlobalPrivacyControlSettingEnabled();
  return Response::Success();
}

void BrowserHandler::OnDownloadUpdated(download::DownloadItem* item) {
  std::string state;
  std::optional<std::string> maybe_file_path;
  switch (item->GetState()) {
    case download::DownloadItem::IN_PROGRESS:
      state = Browser::DownloadProgress::StateEnum::InProgress;
      break;
    case download::DownloadItem::COMPLETE:
      state = Browser::DownloadProgress::StateEnum::Completed;
      {
        base::FilePath target_file_path = item->GetTargetFilePath();
        if (!target_file_path.empty()) {
#if BUILDFLAG(IS_WIN)
          // On Windows, the target file path is a wide string.
          maybe_file_path = base::WideToUTF8(target_file_path.value());
#else
          maybe_file_path = target_file_path.value();
#endif
        }
      }
      break;
    case download::DownloadItem::CANCELLED:
    case download::DownloadItem::INTERRUPTED:
      state = Browser::DownloadProgress::StateEnum::Canceled;
      break;
    case download::DownloadItem::MAX_DOWNLOAD_STATE:
      NOTREACHED();
  }
  frontend_->DownloadProgress(item->GetGuid(), item->GetTotalBytes(),
                              item->GetReceivedBytes(), state, maybe_file_path);
  if (state != Browser::DownloadProgress::StateEnum::InProgress) {
    item->RemoveObserver(this);
    pending_downloads_.erase(item);
  }
}

void BrowserHandler::OnDownloadDestroyed(download::DownloadItem* item) {
  pending_downloads_.erase(item);
}

void BrowserHandler::DownloadWillBegin(FrameTreeNode* ftn,
                                       download::DownloadItem* item) {
  if (!download_events_enabled_)
    return;
  const std::u16string likely_filename = net::GetSuggestedFilename(
      item->GetURL(), item->GetContentDisposition(), std::string(),
      item->GetSuggestedFilename(), item->GetMimeType(), "download");

  frontend_->DownloadWillBegin(
      ftn->current_frame_host()->devtools_frame_token().ToString(),
      item->GetGuid(), item->GetURL().spec(),
      base::UTF16ToUTF8(likely_filename));
  item->AddObserver(this);
  pending_downloads_.insert(item);
}

void BrowserHandler::SetDownloadEventsEnabled(bool enabled) {
  if (!enabled) {
    for (download::DownloadItem* item : pending_downloads_) {
      item->RemoveObserver(this);
    }
    pending_downloads_.clear();
  }
  download_events_enabled_ = enabled;
}

std::unique_ptr<Browser::Histogram> BrowserHandler::GetHistogramData(
    const base::HistogramBase& histogram,
    bool get_delta) {
  std::unique_ptr<base::HistogramSamples> data = histogram.SnapshotSamples();
  std::unique_ptr<base::HistogramSamples> previous_data;
  if (get_delta) {
    auto it = histograms_snapshots_.find(histogram.histogram_name());
    if (it != histograms_snapshots_.end()) {
      previous_data = std::move(it->second);
      data->Subtract(*previous_data);
    }
  }

  auto out_buckets = std::make_unique<Array<Browser::Bucket>>();
  for (const std::unique_ptr<base::SampleCountIterator> it = data->Iterator();
       !it->Done(); it->Next()) {
    base::HistogramBase::Count32 count;
    base::HistogramBase::Sample32 low;
    int64_t high;
    it->Get(&low, &high, &count);
    out_buckets->emplace_back(Browser::Bucket::Create()
                                  .SetLow(low)
                                  .SetHigh(high)
                                  .SetCount(count)
                                  .Build());
  }

  auto result = Browser::Histogram::Create()
                    .SetName(std::string(histogram.histogram_name()))
                    .SetSum(data->sum())
                    .SetCount(data->TotalCount())
                    .SetBuckets(std::move(out_buckets))
                    .Build();

  // Keep track of the data we returned for future delta requests.
  if (get_delta) {
    if (previous_data) {
      // If we had subtracted previous data, re-add it to get the full snapshot.
      data->Add(*previous_data);
    }
    base::InsertOrAssign(histograms_snapshots_, histogram.histogram_name(),
                         std::move(data));
  }

  return result;
}

}  // namespace protocol
}  // namespace content
