chromium/chrome/browser/ui/content_settings/content_setting_bubble_model.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/lazy_instance.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#include "base/notreached.h"
#include "base/scoped_observation.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/chrome_content_settings_utils.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/content_settings/mixed_content_settings_tab_helper.h"
#include "chrome/browser/content_settings/page_specific_content_settings_delegate.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/download/download_request_limiter.h"
#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
#include "chrome/browser/media/webrtc/permission_bubble_media_access_handler.h"
#include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h"
#include "chrome/browser/permissions/quiet_notification_permission_ui_config.h"
#include "chrome/browser/permissions/system/system_permission_settings.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
#include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/url_identity.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "components/blocked_content/popup_blocker_tab_helper.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
#include "components/content_settings/common/content_settings_agent.mojom.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_constraints.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/content_settings_utils.h"
#include "components/custom_handlers/protocol_handler_registry.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/permissions/constants.h"
#include "components/permissions/permission_decision_auto_blocker.h"
#include "components/permissions/permission_request_manager.h"
#include "components/permissions/permission_uma_util.h"
#include "components/permissions/permission_util.h"
#include "components/permissions/permissions_client.h"
#include "components/strings/grit/components_strings.h"
#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
#include "components/subresource_filter/core/browser/subresource_filter_constants.h"
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
#include "components/url_formatter/elide_url.h"
#include "components/vector_icons/vector_icons.h"
#include "content/public/browser/page.h"
#include "content/public/browser/permission_controller.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/weak_document_ptr.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/device/public/cpp/device_features.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/loader/network_utils.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/window_open_disposition.h"
#include "ui/base/window_open_disposition_utils.h"
#include "ui/events/event.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/resources/grit/ui_resources.h"

#if BUILDFLAG(IS_MAC)
#include "base/apple/bundle_locations.h"
#include "base/mac/mac_util.h"
#include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h"
#include "chrome/browser/web_applications/os_integration/mac/web_app_shortcut_mac.h"
#include "chrome/browser/web_applications/web_app_tab_helper.h"
#endif

UserMetricsAction;
WebContents;
PageSpecificContentSettings;
SettingInfo;
SettingSource;
SessionModel;

namespace {
ContentSettingBubbleAction;

void RecordActionHistogram(ContentSettingsType type,
                           ContentSettingBubbleAction action) {}

QuietUiReason;

const std::u16string& GetDefaultDisplayURLForTesting() {}

// An override display URL in content setting bubble UI for testing.
std::optional<bool> g_display_url_override_for_testing =;

// Returns a boolean indicating whether the setting should be managed by the
// user (i.e. it is not controlled by policy). Also takes a (nullable) out-param
// which is populated by the actual setting for the given URL.
bool GetSettingManagedByUser(const GURL& url,
                             ContentSettingsType type,
                             Profile* profile,
                             ContentSetting* out_setting) {}

ContentSettingBubbleModel::ListItem CreateUrlListItem(int32_t id,
                                                      const GURL& url) {}

struct ContentSettingsTypeIdEntry {};

int GetIdForContentType(const ContentSettingsTypeIdEntry* entries,
                        size_t num_entries,
                        ContentSettingsType type) {}

void SetAllowRunningInsecureContent(
    MixedContentSettingsTabHelper* mixed_content_settings,
    content::RenderFrameHost* frame) {}

constexpr UrlIdentity::TypeSet allowed_types =;
constexpr UrlIdentity::FormatOptions options;

std::u16string GetUrlForDisplay(Profile* profile, const GURL& url) {}

}  // namespace

// static
base::AutoReset<std::optional<bool>>
ContentSettingBubbleModel::CreateScopedDisplayURLOverrideForTesting() {}

// ContentSettingSimpleBubbleModel ---------------------------------------------
ContentSettingBubbleModel::ListItem::ListItem(const gfx::VectorIcon* image,
                                              const std::u16string& title,
                                              const std::u16string& description,
                                              bool has_link,
                                              bool has_blocked_badge,
                                              int32_t item_id)
    :{}

ContentSettingBubbleModel::ListItem::ListItem(const ListItem& other) = default;
ContentSettingBubbleModel::ListItem&
ContentSettingBubbleModel::ListItem::operator=(const ListItem& other) = default;

ContentSettingSimpleBubbleModel::ContentSettingSimpleBubbleModel(
    Delegate* delegate,
    WebContents* web_contents,
    ContentSettingsType content_type)
    :{}

ContentSettingSimpleBubbleModel*
ContentSettingSimpleBubbleModel::AsSimpleBubbleModel() {}

void ContentSettingSimpleBubbleModel::SetTitle() {}

void ContentSettingSimpleBubbleModel::SetMessage() {}

void ContentSettingSimpleBubbleModel::SetManageText() {}

void ContentSettingSimpleBubbleModel::OnManageButtonClicked() {}

void ContentSettingSimpleBubbleModel::SetCustomLink() {}

void ContentSettingSimpleBubbleModel::OnCustomLinkClicked() {}

// ContentSettingMixedScriptBubbleModel ----------------------------------------

class ContentSettingMixedScriptBubbleModel
    : public ContentSettingSimpleBubbleModel {};

ContentSettingMixedScriptBubbleModel::ContentSettingMixedScriptBubbleModel(
    Delegate* delegate,
    WebContents* web_contents)
    :{}

void ContentSettingMixedScriptBubbleModel::OnLearnMoreClicked() {}

void ContentSettingMixedScriptBubbleModel::OnCustomLinkClicked() {}

// Don't set any manage text since none is displayed.
void ContentSettingMixedScriptBubbleModel::SetManageText() {}

// ContentSettingRPHBubbleModel ------------------------------------------------

namespace {

// These states must match the order of appearance of the radio buttons
// in the XIB file for the Mac port.
enum RPHState {};

}  // namespace

ContentSettingRPHBubbleModel::ContentSettingRPHBubbleModel(
    Delegate* delegate,
    WebContents* web_contents,
    custom_handlers::ProtocolHandlerRegistry* registry)
    :{}

ContentSettingRPHBubbleModel::~ContentSettingRPHBubbleModel() = default;

void ContentSettingRPHBubbleModel::CommitChanges() {}

void ContentSettingRPHBubbleModel::RegisterProtocolHandler() {}

void ContentSettingRPHBubbleModel::UnregisterProtocolHandler() {}

void ContentSettingRPHBubbleModel::IgnoreProtocolHandler() {}

void ContentSettingRPHBubbleModel::ClearOrSetPreviousHandler() {}

void ContentSettingRPHBubbleModel::PerformActionForSelectedItem() {}

// ContentSettingSingleRadioGroup ----------------------------------------------

ContentSettingSingleRadioGroup::ContentSettingSingleRadioGroup(
    Delegate* delegate,
    WebContents* web_contents,
    ContentSettingsType content_type)
    :{}

ContentSettingSingleRadioGroup::~ContentSettingSingleRadioGroup() = default;

void ContentSettingSingleRadioGroup::CommitChanges() {}

bool ContentSettingSingleRadioGroup::settings_changed() const {}

// Initialize the radio group by setting the appropriate labels for the
// content type and setting the default value based on the content setting.
void ContentSettingSingleRadioGroup::SetRadioGroup() {}

void ContentSettingSingleRadioGroup::SetNarrowestContentSetting(
    ContentSetting setting) {}

// ContentSettingStorageAccessBubbleModel --------------------------------------

ContentSettingStorageAccessBubbleModel::ContentSettingStorageAccessBubbleModel(
    Delegate* delegate,
    WebContents* web_contents)
    :{}

ContentSettingStorageAccessBubbleModel::
    ~ContentSettingStorageAccessBubbleModel() = default;

void ContentSettingStorageAccessBubbleModel::CommitChanges() {}

void ContentSettingStorageAccessBubbleModel::OnSiteRowClicked(
    const net::SchemefulSite& site,
    bool is_allowed) {}

void ContentSettingStorageAccessBubbleModel::OnManageButtonClicked() {}

// ContentSettingCookiesBubbleModel --------------------------------------------

class ContentSettingCookiesBubbleModel : public ContentSettingSingleRadioGroup {};

ContentSettingCookiesBubbleModel::ContentSettingCookiesBubbleModel(
    Delegate* delegate,
    WebContents* web_contents)
    :{}

ContentSettingCookiesBubbleModel::~ContentSettingCookiesBubbleModel() = default;

void ContentSettingCookiesBubbleModel::CommitChanges() {}

void ContentSettingCookiesBubbleModel::OnManageButtonClicked() {}

// ContentSettingPopupBubbleModel ----------------------------------------------

class ContentSettingPopupBubbleModel
    : public ContentSettingSingleRadioGroup,
      public blocked_content::UrlListManager::Observer {};

ContentSettingPopupBubbleModel::ContentSettingPopupBubbleModel(
    Delegate* delegate,
    WebContents* web_contents)
    :{}

void ContentSettingPopupBubbleModel::BlockedUrlAdded(int32_t id,
                                                     const GURL& url) {}

void ContentSettingPopupBubbleModel::OnListItemClicked(int index,
                                                       const ui::Event& event) {}

void ContentSettingPopupBubbleModel::CommitChanges() {}

ContentSettingPopupBubbleModel::~ContentSettingPopupBubbleModel() = default;

// ContentSettingMediaStreamBubbleModel ----------------------------------------

ContentSettingMediaStreamBubbleModel::ContentSettingMediaStreamBubbleModel(
    Delegate* delegate,
    WebContents* web_contents)
    :{}

ContentSettingMediaStreamBubbleModel::~ContentSettingMediaStreamBubbleModel() =
    default;

void ContentSettingMediaStreamBubbleModel::CommitChanges() {}

ContentSettingMediaStreamBubbleModel*
ContentSettingMediaStreamBubbleModel::AsMediaStreamBubbleModel() {}

void ContentSettingMediaStreamBubbleModel::OnManageButtonClicked() {}

void ContentSettingMediaStreamBubbleModel::OnDoneButtonClicked() {}

bool ContentSettingMediaStreamBubbleModel::MicrophoneAccessed() const {}

bool ContentSettingMediaStreamBubbleModel::CameraAccessed() const {}

bool ContentSettingMediaStreamBubbleModel::MicrophoneBlocked() const {}

bool ContentSettingMediaStreamBubbleModel::CameraBlocked() const {}

void ContentSettingMediaStreamBubbleModel::SetIsUserModifiable() {}

void ContentSettingMediaStreamBubbleModel::SetTitle() {}

void ContentSettingMediaStreamBubbleModel::SetMessage() {}

void ContentSettingMediaStreamBubbleModel::SetRadioGroup() {}

void ContentSettingMediaStreamBubbleModel::UpdateSettings(
    ContentSetting setting) {}

#if BUILDFLAG(IS_MAC)
void ContentSettingMediaStreamBubbleModel::
    InitializeSystemMediaPermissionBubble() {
  DCHECK(CameraAccessed() || MicrophoneAccessed());
  base::RecordAction(
      base::UserMetricsAction("Media.ShowSystemMediaPermissionBubble"));
  int title_id = 0;
  if (MicrophoneAccessed() && CameraAccessed() &&
      (system_media_permissions::CheckSystemVideoCapturePermission() ==
           system_media_permissions::SystemPermission::kDenied ||
       system_media_permissions::CheckSystemAudioCapturePermission() ==
           system_media_permissions::SystemPermission::kDenied)) {
    title_id = IDS_CAMERA_MIC_TURNED_OFF_IN_MACOS;
    AddListItem(ContentSettingBubbleModel::ListItem(
        &vector_icons::kVideocamIcon, l10n_util::GetStringUTF16(IDS_CAMERA),
        l10n_util::GetStringUTF16(IDS_TURNED_OFF), false, true, 0));
    AddListItem(ContentSettingBubbleModel::ListItem(
        &vector_icons::kMicIcon, l10n_util::GetStringUTF16(IDS_MIC),
        l10n_util::GetStringUTF16(IDS_TURNED_OFF), false, true, 1));
  } else if (CameraAccessed() &&
             system_media_permissions::CheckSystemVideoCapturePermission() ==
                 system_media_permissions::SystemPermission::kDenied) {
    title_id = IDS_CAMERA_TURNED_OFF_IN_MACOS;
    AddListItem(ContentSettingBubbleModel::ListItem(
        &vector_icons::kVideocamIcon, l10n_util::GetStringUTF16(IDS_CAMERA),
        l10n_util::GetStringUTF16(IDS_TURNED_OFF), false, true, 0));
  } else if (MicrophoneAccessed() &&
             system_media_permissions::CheckSystemAudioCapturePermission() ==
                 system_media_permissions::SystemPermission::kDenied) {
    title_id = IDS_MIC_TURNED_OFF_IN_MACOS;
    AddListItem(ContentSettingBubbleModel::ListItem(
        &vector_icons::kMicIcon, l10n_util::GetStringUTF16(IDS_MIC),
        l10n_util::GetStringUTF16(IDS_TURNED_OFF), false, true, 1));
  }

  set_title(l10n_util::GetStringUTF16(title_id));
  set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kNone);
  SetCustomLink();
  set_done_button_text(l10n_util::GetStringUTF16(IDS_OPEN_SETTINGS_LINK));
}
#endif  // BUILDFLAG(IS_MAC)

bool ContentSettingMediaStreamBubbleModel::ShouldShowSystemMediaPermissions() {}

void ContentSettingMediaStreamBubbleModel::SetManageText() {}

void ContentSettingMediaStreamBubbleModel::SetCustomLink() {}

// ContentSettingGeolocationBubbleModel --------------------------------------

ContentSettingGeolocationBubbleModel::ContentSettingGeolocationBubbleModel(
    Delegate* delegate,
    content::WebContents* web_contents)
    :{}

ContentSettingGeolocationBubbleModel::~ContentSettingGeolocationBubbleModel() =
    default;

void ContentSettingGeolocationBubbleModel::OnDoneButtonClicked() {}

void ContentSettingGeolocationBubbleModel::OnManageButtonClicked() {}

void ContentSettingGeolocationBubbleModel::CommitChanges() {}

void ContentSettingGeolocationBubbleModel::
    InitializeSystemGeolocationPermissionBubble() {}

void ContentSettingGeolocationBubbleModel::SetCustomLink() {}

// ContentSettingNotificationsBubbleModel ------------------------------------

#if BUILDFLAG(IS_MAC)
ContentSettingNotificationsBubbleModel::ContentSettingNotificationsBubbleModel(
    Delegate* delegate,
    content::WebContents* web_contents)
    : ContentSettingSimpleBubbleModel(delegate,
                                      web_contents,
                                      ContentSettingsType::NOTIFICATIONS) {
  set_title(l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_TURNED_OFF_IN_MACOS));
  AddListItem(ContentSettingBubbleModel::ListItem(
      &vector_icons::kNotificationsOffChromeRefreshIcon,
      l10n_util::GetStringUTF16(IDS_NOTIFICATIONS),
      l10n_util::GetStringUTF16(IDS_TURNED_OFF), /*has_link=*/false,
      /*has_blocked_badge=*/false, 0));
  set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kNone);
  set_done_button_text(l10n_util::GetStringUTF16(IDS_OPEN_SETTINGS_LINK));
}

ContentSettingNotificationsBubbleModel::
    ~ContentSettingNotificationsBubbleModel() = default;

void ContentSettingNotificationsBubbleModel::OnDoneButtonClicked() {
  std::string bundle_identifier = base::apple::MainBundleIdentifier();
  if (std::optional<webapps::AppId> app_id =
          web_app::WebAppTabHelper::GetAppIdForNotificationAttribution(
              web_contents());
      app_id.has_value()) {
    bundle_identifier = web_app::GetBundleIdentifierForShim(*app_id);
  }
  base::mac::OpenSystemSettingsPane(
      base::mac::SystemSettingsPane::kNotifications, bundle_identifier);
}
#endif

// ContentSettingSubresourceFilterBubbleModel ----------------------------------

ContentSettingSubresourceFilterBubbleModel::
    ContentSettingSubresourceFilterBubbleModel(Delegate* delegate,
                                               WebContents* web_contents)
    :{}

ContentSettingSubresourceFilterBubbleModel::
    ~ContentSettingSubresourceFilterBubbleModel() = default;

void ContentSettingSubresourceFilterBubbleModel::SetTitle() {}

void ContentSettingSubresourceFilterBubbleModel::SetManageText() {}

void ContentSettingSubresourceFilterBubbleModel::SetMessage() {}

void ContentSettingSubresourceFilterBubbleModel::OnManageCheckboxChecked(
    bool is_checked) {}

void ContentSettingSubresourceFilterBubbleModel::OnLearnMoreClicked() {}

void ContentSettingSubresourceFilterBubbleModel::CommitChanges() {}

ContentSettingSubresourceFilterBubbleModel*
ContentSettingSubresourceFilterBubbleModel::AsSubresourceFilterBubbleModel() {}

// ContentSettingDownloadsBubbleModel ------------------------------------------

ContentSettingDownloadsBubbleModel::ContentSettingDownloadsBubbleModel(
    Delegate* delegate,
    WebContents* web_contents)
    :{}

ContentSettingDownloadsBubbleModel::~ContentSettingDownloadsBubbleModel() =
    default;

void ContentSettingDownloadsBubbleModel::CommitChanges() {}

ContentSettingDownloadsBubbleModel*
ContentSettingDownloadsBubbleModel::AsDownloadsBubbleModel() {}

// Initialize the radio group by setting the appropriate labels for the
// content type and setting the default value based on the content setting.
void ContentSettingDownloadsBubbleModel::SetRadioGroup() {}

void ContentSettingDownloadsBubbleModel::SetTitle() {}

void ContentSettingDownloadsBubbleModel::SetManageText() {}

void ContentSettingDownloadsBubbleModel::OnManageButtonClicked() {}

// ContentSettingFramebustBlockBubbleModel -------------------------------------
ContentSettingFramebustBlockBubbleModel::
    ContentSettingFramebustBlockBubbleModel(Delegate* delegate,
                                            WebContents* web_contents)
    :{}

ContentSettingFramebustBlockBubbleModel::
    ~ContentSettingFramebustBlockBubbleModel() = default;

void ContentSettingFramebustBlockBubbleModel::OnListItemClicked(
    int index,
    const ui::Event& event) {}

ContentSettingFramebustBlockBubbleModel*
ContentSettingFramebustBlockBubbleModel::AsFramebustBlockBubbleModel() {}

void ContentSettingFramebustBlockBubbleModel::BlockedUrlAdded(
    int32_t id,
    const GURL& blocked_url) {}

// ContentSettingQuietRequestBubbleModel ----------------------------------
ContentSettingQuietRequestBubbleModel::ContentSettingQuietRequestBubbleModel(
    Delegate* delegate,
    WebContents* web_contents)
    :{}

ContentSettingQuietRequestBubbleModel::
    ~ContentSettingQuietRequestBubbleModel() = default;

ContentSettingQuietRequestBubbleModel*
ContentSettingQuietRequestBubbleModel::AsQuietRequestBubbleModel() {}

void ContentSettingQuietRequestBubbleModel::OnManageButtonClicked() {}

void ContentSettingQuietRequestBubbleModel::OnLearnMoreClicked() {}

void ContentSettingQuietRequestBubbleModel::OnDoneButtonClicked() {}

void ContentSettingQuietRequestBubbleModel::OnCancelButtonClicked() {}

// ContentSettingBubbleModel ---------------------------------------------------

// This class must be placed last because it needs the definition of the other
// classes declared in this file.

const int ContentSettingBubbleModel::kAllowButtonIndex =;

// static
std::unique_ptr<ContentSettingBubbleModel>
ContentSettingBubbleModel::CreateContentSettingBubbleModel(
    Delegate* delegate,
    WebContents* web_contents,
    ContentSettingsType content_type) {}

ContentSettingBubbleModel::ContentSettingBubbleModel(Delegate* delegate,
                                                     WebContents* web_contents)
    :{}

ContentSettingBubbleModel::~ContentSettingBubbleModel() = default;

ContentSettingBubbleModel::RadioGroup::RadioGroup() = default;

ContentSettingBubbleModel::RadioGroup::~RadioGroup() = default;

ContentSettingBubbleModel::MediaMenu::MediaMenu() = default;

ContentSettingBubbleModel::MediaMenu::MediaMenu(const MediaMenu& other) =
    default;

ContentSettingBubbleModel::MediaMenu::~MediaMenu() = default;

ContentSettingBubbleModel::BubbleContent::BubbleContent() = default;

ContentSettingBubbleModel::BubbleContent::~BubbleContent() = default;

ContentSettingSimpleBubbleModel*
ContentSettingBubbleModel::AsSimpleBubbleModel() {}

ContentSettingMediaStreamBubbleModel*
ContentSettingBubbleModel::AsMediaStreamBubbleModel() {}

ContentSettingQuietRequestBubbleModel*
ContentSettingBubbleModel::AsQuietRequestBubbleModel() {}

ContentSettingSubresourceFilterBubbleModel*
ContentSettingBubbleModel::AsSubresourceFilterBubbleModel() {}

ContentSettingDownloadsBubbleModel*
ContentSettingBubbleModel::AsDownloadsBubbleModel() {}

ContentSettingFramebustBlockBubbleModel*
ContentSettingBubbleModel::AsFramebustBlockBubbleModel() {}

Profile* ContentSettingBubbleModel::GetProfile() const {}

void ContentSettingBubbleModel::AddListItem(const ListItem& item) {}

void ContentSettingBubbleModel::RemoveListItem(int index) {}