#ifdef UNSAFE_BUFFERS_BUILD
#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() { … }
std::optional<bool> g_display_url_override_for_testing = …;
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) { … }
}
base::AutoReset<std::optional<bool>>
ContentSettingBubbleModel::CreateScopedDisplayURLOverrideForTesting() { … }
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() { … }
class ContentSettingMixedScriptBubbleModel
: public ContentSettingSimpleBubbleModel { … };
ContentSettingMixedScriptBubbleModel::ContentSettingMixedScriptBubbleModel(
Delegate* delegate,
WebContents* web_contents)
: … { … }
void ContentSettingMixedScriptBubbleModel::OnLearnMoreClicked() { … }
void ContentSettingMixedScriptBubbleModel::OnCustomLinkClicked() { … }
void ContentSettingMixedScriptBubbleModel::SetManageText() { … }
namespace {
enum RPHState { … };
}
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(
Delegate* delegate,
WebContents* web_contents,
ContentSettingsType content_type)
: … { … }
ContentSettingSingleRadioGroup::~ContentSettingSingleRadioGroup() = default;
void ContentSettingSingleRadioGroup::CommitChanges() { … }
bool ContentSettingSingleRadioGroup::settings_changed() const { … }
void ContentSettingSingleRadioGroup::SetRadioGroup() { … }
void ContentSettingSingleRadioGroup::SetNarrowestContentSetting(
ContentSetting setting) { … }
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() { … }
class ContentSettingCookiesBubbleModel : public ContentSettingSingleRadioGroup { … };
ContentSettingCookiesBubbleModel::ContentSettingCookiesBubbleModel(
Delegate* delegate,
WebContents* web_contents)
: … { … }
ContentSettingCookiesBubbleModel::~ContentSettingCookiesBubbleModel() = default;
void ContentSettingCookiesBubbleModel::CommitChanges() { … }
void ContentSettingCookiesBubbleModel::OnManageButtonClicked() { … }
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(
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
bool ContentSettingMediaStreamBubbleModel::ShouldShowSystemMediaPermissions() { … }
void ContentSettingMediaStreamBubbleModel::SetManageText() { … }
void ContentSettingMediaStreamBubbleModel::SetCustomLink() { … }
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() { … }
#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), false,
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(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(
Delegate* delegate,
WebContents* web_contents)
: … { … }
ContentSettingDownloadsBubbleModel::~ContentSettingDownloadsBubbleModel() =
default;
void ContentSettingDownloadsBubbleModel::CommitChanges() { … }
ContentSettingDownloadsBubbleModel*
ContentSettingDownloadsBubbleModel::AsDownloadsBubbleModel() { … }
void ContentSettingDownloadsBubbleModel::SetRadioGroup() { … }
void ContentSettingDownloadsBubbleModel::SetTitle() { … }
void ContentSettingDownloadsBubbleModel::SetManageText() { … }
void ContentSettingDownloadsBubbleModel::OnManageButtonClicked() { … }
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(
Delegate* delegate,
WebContents* web_contents)
: … { … }
ContentSettingQuietRequestBubbleModel::
~ContentSettingQuietRequestBubbleModel() = default;
ContentSettingQuietRequestBubbleModel*
ContentSettingQuietRequestBubbleModel::AsQuietRequestBubbleModel() { … }
void ContentSettingQuietRequestBubbleModel::OnManageButtonClicked() { … }
void ContentSettingQuietRequestBubbleModel::OnLearnMoreClicked() { … }
void ContentSettingQuietRequestBubbleModel::OnDoneButtonClicked() { … }
void ContentSettingQuietRequestBubbleModel::OnCancelButtonClicked() { … }
const int ContentSettingBubbleModel::kAllowButtonIndex = …;
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) { … }