#include "chrome/browser/permissions/chrome_permissions_client.h"
#include <optional>
#include <vector>
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/callback_helpers.h"
#include "base/no_destructor.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/ash/shimless_rma/chrome_shimless_rma_delegate.h"
#include "chrome/browser/bluetooth/bluetooth_chooser_context_factory.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/engagement/important_sites_util.h"
#include "chrome/browser/metrics/ukm_background_recorder_service.h"
#include "chrome/browser/permissions/adaptive_quiet_notification_permission_ui_enabler.h"
#include "chrome/browser/permissions/contextual_notification_permission_ui_selector.h"
#include "chrome/browser/permissions/origin_keyed_permission_action_service_factory.h"
#include "chrome/browser/permissions/permission_actions_history_factory.h"
#include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h"
#include "chrome/browser/permissions/permission_revocation_request.h"
#include "chrome/browser/permissions/prediction_based_permission_ui_selector.h"
#include "chrome/browser/permissions/pref_based_quiet_permission_ui_selector.h"
#include "chrome/browser/permissions/quiet_notification_permission_ui_config.h"
#include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
#include "chrome/browser/subresource_filter/subresource_filter_profile_context_factory.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/hats/hats_service.h"
#include "chrome/browser/ui/hats/hats_service_factory.h"
#include "chrome/browser/ui/hats/survey_config.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/content_settings/core/browser/content_settings_type_set.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/google/core/common/google_util.h"
#include "components/permissions/constants.h"
#include "components/permissions/contexts/bluetooth_chooser_context.h"
#include "components/permissions/features.h"
#include "components/permissions/permission_hats_trigger_helper.h"
#include "components/permissions/permission_request.h"
#include "components/permissions/permission_uma_util.h"
#include "components/permissions/permission_util.h"
#include "components/permissions/request_type.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/tracking_protection_settings.h"
#include "components/site_engagement/content/site_engagement_service.h"
#include "components/subresource_filter/content/browser/subresource_filter_content_settings_manager.h"
#include "components/subresource_filter/content/browser/subresource_filter_profile_context.h"
#include "components/unified_consent/pref_names.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/web_contents.h"
#include "extensions/buildflags/buildflags.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "url/origin.h"
#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/android/resource_mapper.h"
#include "chrome/browser/android/search_permissions/search_permissions_service.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/permissions/permission_blocked_message_delegate_android.h"
#include "chrome/browser/permissions/permission_infobar_delegate_android.h"
#include "chrome/browser/permissions/permission_update_message_controller_android.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/permissions/permission_request_manager.h"
#else
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/permission_bubble/permission_prompt.h"
#include "components/vector_icons/vector_icons.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_features.h"
#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_data.h"
#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
#include "chromeos/ash/components/browser_context_helper/browser_context_types.h"
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h"
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/constants.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h"
#endif
namespace {
#if BUILDFLAG(IS_ANDROID)
bool ShouldUseQuietUI(content::WebContents* web_contents,
ContentSettingsType type) {
auto* manager =
permissions::PermissionRequestManager::FromWebContents(web_contents);
if (type != ContentSettingsType::NOTIFICATIONS &&
type != ContentSettingsType::GEOLOCATION) {
return false;
}
return manager->ShouldCurrentRequestUseQuietUI();
}
#endif
}
ChromePermissionsClient* ChromePermissionsClient::GetInstance() { … }
HostContentSettingsMap* ChromePermissionsClient::GetSettingsMap(
content::BrowserContext* browser_context) { … }
scoped_refptr<content_settings::CookieSettings>
ChromePermissionsClient::GetCookieSettings(
content::BrowserContext* browser_context) { … }
privacy_sandbox::TrackingProtectionSettings*
ChromePermissionsClient::GetTrackingProtectionSettings(
content::BrowserContext* browser_context) { … }
bool ChromePermissionsClient::IsSubresourceFilterActivated(
content::BrowserContext* browser_context,
const GURL& url) { … }
permissions::ObjectPermissionContextBase*
ChromePermissionsClient::GetChooserContext(
content::BrowserContext* browser_context,
ContentSettingsType type) { … }
permissions::OriginKeyedPermissionActionService*
ChromePermissionsClient::GetOriginKeyedPermissionActionService(
content::BrowserContext* browser_context) { … }
permissions::PermissionActionsHistory*
ChromePermissionsClient::GetPermissionActionsHistory(
content::BrowserContext* browser_context) { … }
permissions::PermissionDecisionAutoBlocker*
ChromePermissionsClient::GetPermissionDecisionAutoBlocker(
content::BrowserContext* browser_context) { … }
double ChromePermissionsClient::GetSiteEngagementScore(
content::BrowserContext* browser_context,
const GURL& origin) { … }
void ChromePermissionsClient::AreSitesImportant(
content::BrowserContext* browser_context,
std::vector<std::pair<url::Origin, bool>>* origins) { … }
bool ChromePermissionsClient::IsCookieDeletionDisabled(
content::BrowserContext* browser_context,
const GURL& origin) { … }
void ChromePermissionsClient::GetUkmSourceId(
ContentSettingsType permission_type,
content::BrowserContext* browser_context,
content::WebContents* web_contents,
const GURL& requesting_origin,
GetUkmSourceIdCallback callback) { … }
permissions::IconId ChromePermissionsClient::GetOverrideIconId(
permissions::RequestType request_type) { … }
void ChromePermissionsClient::TriggerPromptHatsSurveyIfEnabled(
content::WebContents* web_contents,
permissions::RequestType request_type,
std::optional<permissions::PermissionAction> action,
permissions::PermissionPromptDisposition prompt_disposition,
permissions::PermissionPromptDispositionReason prompt_disposition_reason,
permissions::PermissionRequestGestureType gesture_type,
std::optional<base::TimeDelta> prompt_display_duration,
bool is_post_prompt,
const GURL& gurl,
std::optional<permissions::feature_params::PermissionElementPromptPosition>
pepc_prompt_position,
ContentSetting initial_permission_status,
base::OnceCallback<void()> hats_shown_callback) { … }
#if !BUILDFLAG(IS_ANDROID)
permissions::PermissionIgnoredReason
ChromePermissionsClient::DetermineIgnoreReason(
content::WebContents* web_contents) { … }
#endif
std::vector<std::unique_ptr<permissions::PermissionUiSelector>>
ChromePermissionsClient::CreatePermissionUiSelectors(
content::BrowserContext* browser_context) { … }
void ChromePermissionsClient::OnPromptResolved(
permissions::RequestType request_type,
permissions::PermissionAction action,
const GURL& origin,
permissions::PermissionPromptDisposition prompt_disposition,
permissions::PermissionPromptDispositionReason prompt_disposition_reason,
permissions::PermissionRequestGestureType gesture_type,
std::optional<QuietUiReason> quiet_ui_reason,
base::TimeDelta prompt_display_duration,
std::optional<permissions::feature_params::PermissionElementPromptPosition>
pepc_prompt_position,
ContentSetting initial_permission_status,
content::WebContents* web_contents) { … }
std::optional<bool>
ChromePermissionsClient::HadThreeConsecutiveNotificationPermissionDenies(
content::BrowserContext* browser_context) { … }
std::optional<bool> ChromePermissionsClient::HasPreviouslyAutoRevokedPermission(
content::BrowserContext* browser_context,
const GURL& origin,
ContentSettingsType permission) { … }
std::optional<url::Origin> ChromePermissionsClient::GetAutoApprovalOrigin(
content::BrowserContext* browser_context) { … }
std::optional<permissions::PermissionAction>
ChromePermissionsClient::GetAutoApprovalStatus(
content::BrowserContext* browser_context,
const GURL& origin) { … }
bool ChromePermissionsClient::CanBypassEmbeddingOriginCheck(
const GURL& requesting_origin,
const GURL& embedding_origin) { … }
std::optional<GURL> ChromePermissionsClient::OverrideCanonicalOrigin(
const GURL& requesting_origin,
const GURL& embedding_origin) { … }
bool ChromePermissionsClient::DoURLsMatchNewTabPage(
const GURL& requesting_origin,
const GURL& embedding_origin) { … }
#if BUILDFLAG(IS_ANDROID)
bool ChromePermissionsClient::IsDseOrigin(
content::BrowserContext* browser_context,
const url::Origin& origin) {
SearchPermissionsService* search_helper =
SearchPermissionsService::Factory::GetForBrowserContext(browser_context);
return search_helper && search_helper->IsDseOrigin(origin);
}
infobars::InfoBarManager* ChromePermissionsClient::GetInfoBarManager(
content::WebContents* web_contents) {
return infobars::ContentInfoBarManager::FromWebContents(web_contents);
}
infobars::InfoBar* ChromePermissionsClient::MaybeCreateInfoBar(
content::WebContents* web_contents,
ContentSettingsType type,
base::WeakPtr<permissions::PermissionPromptAndroid> prompt) {
infobars::ContentInfoBarManager* infobar_manager =
infobars::ContentInfoBarManager::FromWebContents(web_contents);
if (infobar_manager && ShouldUseQuietUI(web_contents, type)) {
return PermissionInfoBarDelegate::Create(std::move(prompt),
infobar_manager);
}
return nullptr;
}
std::unique_ptr<ChromePermissionsClient::PermissionMessageDelegate>
ChromePermissionsClient::MaybeCreateMessageUI(
content::WebContents* web_contents,
ContentSettingsType type,
base::WeakPtr<permissions::PermissionPromptAndroid> prompt) {
if (ShouldUseQuietUI(web_contents, type)) {
auto delegate =
std::make_unique<PermissionBlockedMessageDelegate::Delegate>(
std::move(prompt));
return std::make_unique<PermissionBlockedMessageDelegate>(
web_contents, std::move(delegate));
}
return {};
}
void ChromePermissionsClient::RepromptForAndroidPermissions(
content::WebContents* web_contents,
const std::vector<ContentSettingsType>& content_settings_types,
const std::vector<ContentSettingsType>& filtered_content_settings_types,
const std::vector<std::string>& required_permissions,
const std::vector<std::string>& optional_permissions,
PermissionsUpdatedCallback callback) {
PermissionUpdateMessageController::CreateForWebContents(web_contents);
PermissionUpdateMessageController::FromWebContents(web_contents)
->ShowMessage(content_settings_types, filtered_content_settings_types,
required_permissions, optional_permissions,
std::move(callback));
}
int ChromePermissionsClient::MapToJavaDrawableId(int resource_id) {
return ResourceMapper::MapToJavaDrawableId(resource_id);
}
favicon::FaviconService* ChromePermissionsClient::GetFaviconService(
content::BrowserContext* browser_context) {
return FaviconServiceFactory::GetForProfile(
Profile::FromBrowserContext(browser_context),
ServiceAccessType::EXPLICIT_ACCESS);
}
#else
std::unique_ptr<permissions::PermissionPrompt>
ChromePermissionsClient::CreatePrompt(
content::WebContents* web_contents,
permissions::PermissionPrompt::Delegate* delegate) { … }
#endif
bool ChromePermissionsClient::HasDevicePermission(
ContentSettingsType type) const { … }
bool ChromePermissionsClient::CanRequestDevicePermission(
ContentSettingsType type) const { … }