| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/views/permissions/embedded_permission_prompt.h" |
| |
| #include "base/memory/raw_ptr.h" |
| #include "chrome/browser/content_settings/chrome_content_settings_utils.h" |
| #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/views/permissions/embedded_permission_prompt_ask_view.h" |
| #include "chrome/browser/ui/views/permissions/embedded_permission_prompt_base_view.h" |
| #include "chrome/browser/ui/views/permissions/embedded_permission_prompt_content_scrim_view.h" |
| #include "chrome/browser/ui/views/permissions/embedded_permission_prompt_policy_view.h" |
| #include "chrome/browser/ui/views/permissions/embedded_permission_prompt_previously_denied_view.h" |
| #include "chrome/browser/ui/views/permissions/embedded_permission_prompt_previously_granted_view.h" |
| #include "chrome/browser/ui/views/permissions/embedded_permission_prompt_show_system_prompt_view.h" |
| #include "chrome/browser/ui/views/permissions/embedded_permission_prompt_system_settings_view.h" |
| #include "components/content_settings/core/common/content_settings.h" |
| #include "components/content_settings/core/common/content_settings_types.h" |
| #include "content/public/browser/web_contents.h" |
| |
| #if BUILDFLAG(IS_MAC) |
| #include "base/mac/mac_util.h" |
| #include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h" |
| #endif |
| |
| namespace { |
| |
| using content_settings::SettingSource; |
| |
| bool CanGroupVariants(EmbeddedPermissionPrompt::Variant a, |
| EmbeddedPermissionPrompt::Variant b) { |
| // Ask and PreviouslyDenied are a special case and can be grouped together. |
| if ((a == EmbeddedPermissionPrompt::Variant::kPreviouslyDenied && |
| b == EmbeddedPermissionPrompt::Variant::kAsk) || |
| (a == EmbeddedPermissionPrompt::Variant::kAsk && |
| b == EmbeddedPermissionPrompt::Variant::kPreviouslyDenied)) { |
| return true; |
| } |
| |
| return (a == b); |
| } |
| |
| bool IsPermissionSetByAdministator(ContentSetting setting, |
| const content_settings::SettingInfo& info) { |
| return ((setting == ContentSetting::CONTENT_SETTING_BLOCK || |
| setting == ContentSetting::CONTENT_SETTING_ALLOW) && |
| (info.source == SettingSource::kPolicy || |
| info.source == SettingSource::kSupervised)); |
| } |
| |
| #if BUILDFLAG(IS_MAC) |
| void OpenCameraSystemSettingsOnMacOS() { |
| if (system_media_permissions::CheckSystemVideoCapturePermission() == |
| system_media_permissions::SystemPermission::kDenied) { |
| base::mac::OpenSystemSettingsPane( |
| base::mac::SystemSettingsPane::kPrivacySecurity_Camera); |
| } |
| } |
| |
| void OpenMicSystemSettingsOnMacOS() { |
| if (system_media_permissions::CheckSystemAudioCapturePermission() == |
| system_media_permissions::SystemPermission::kDenied) { |
| base::mac::OpenSystemSettingsPane( |
| base::mac::SystemSettingsPane::kPrivacySecurity_Microphone); |
| } |
| } |
| |
| bool ShouldShowSystemSettingsViewOnMacOS(ContentSettingsType type) { |
| return (type == ContentSettingsType::MEDIASTREAM_MIC && |
| system_media_permissions::CheckSystemAudioCapturePermission() == |
| system_media_permissions::SystemPermission::kDenied) || |
| (type == ContentSettingsType::MEDIASTREAM_CAMERA && |
| system_media_permissions::CheckSystemVideoCapturePermission() == |
| system_media_permissions::SystemPermission::kDenied); |
| } |
| |
| bool ShouldShowOSPromptViewOnMacOS(ContentSettingsType type) { |
| return (type == ContentSettingsType::MEDIASTREAM_MIC && |
| system_media_permissions::CheckSystemAudioCapturePermission() == |
| system_media_permissions::SystemPermission::kNotDetermined) || |
| (type == ContentSettingsType::MEDIASTREAM_CAMERA && |
| system_media_permissions::CheckSystemVideoCapturePermission() == |
| system_media_permissions::SystemPermission::kNotDetermined); |
| } |
| #endif |
| |
| permissions::ElementAnchoredBubbleVariant GetVariant( |
| EmbeddedPermissionPrompt::Variant variant) { |
| switch (variant) { |
| case EmbeddedPermissionPrompt::Variant::kUninitialized: |
| return permissions::ElementAnchoredBubbleVariant::UNINITIALIZED; |
| case EmbeddedPermissionPrompt::Variant::kAdministratorGranted: |
| return permissions::ElementAnchoredBubbleVariant::ADMINISTRATOR_GRANTED; |
| case EmbeddedPermissionPrompt::Variant::kPreviouslyGranted: |
| return permissions::ElementAnchoredBubbleVariant::PREVIOUSLY_GRANTED; |
| case EmbeddedPermissionPrompt::Variant::kOsSystemSettings: |
| return permissions::ElementAnchoredBubbleVariant::OS_SYSTEM_SETTINGS; |
| case EmbeddedPermissionPrompt::Variant::kOsPrompt: |
| return permissions::ElementAnchoredBubbleVariant::OS_PROMPT; |
| case EmbeddedPermissionPrompt::Variant::kAsk: |
| return permissions::ElementAnchoredBubbleVariant::ASK; |
| case EmbeddedPermissionPrompt::Variant::kPreviouslyDenied: |
| return permissions::ElementAnchoredBubbleVariant::PREVIOUSLY_DENIED; |
| case EmbeddedPermissionPrompt::Variant::kAdministratorDenied: |
| return permissions::ElementAnchoredBubbleVariant::ADMINISTRATOR_DENIED; |
| } |
| |
| NOTREACHED(); |
| return permissions::ElementAnchoredBubbleVariant::UNINITIALIZED; |
| } |
| } // namespace |
| |
| EmbeddedPermissionPrompt::EmbeddedPermissionPrompt( |
| Browser* browser, |
| content::WebContents* web_contents, |
| permissions::PermissionPrompt::Delegate* delegate) |
| : PermissionPromptDesktop(browser, web_contents, delegate), |
| delegate_(delegate) { |
| CloseCurrentViewAndMaybeShowNext(/*first_prompt=*/true); |
| } |
| |
| EmbeddedPermissionPrompt::~EmbeddedPermissionPrompt() { |
| CloseView(); |
| } |
| |
| // static |
| EmbeddedPermissionPrompt::Variant |
| EmbeddedPermissionPrompt::DeterminePromptVariant( |
| ContentSetting setting, |
| const content_settings::SettingInfo& info, |
| ContentSettingsType type) { |
| // If the administrator blocked the permission, there is nothing the user can |
| // do. Presenting them with a different screen in unproductive. |
| if (IsPermissionSetByAdministator(setting, info) && |
| setting == CONTENT_SETTING_BLOCK) { |
| return Variant::kAdministratorDenied; |
| } |
| |
| // Determine if we can directly show one of the OS views. The "System |
| // Settings" view is higher priority then all the other remaining options, |
| // whereas the "OS Prompt" view is only higher priority then the views that |
| // are associated with a site-level allowed state. |
| // TODO(crbug.com/40275129): Handle going to Windows settings. |
| #if BUILDFLAG(IS_MAC) |
| if (ShouldShowSystemSettingsViewOnMacOS(type)) { |
| return Variant::kOsSystemSettings; |
| } |
| |
| if (setting == CONTENT_SETTING_ALLOW && ShouldShowOSPromptViewOnMacOS(type)) { |
| return Variant::kOsPrompt; |
| } |
| #endif |
| |
| if (IsPermissionSetByAdministator(setting, info)) { |
| return Variant::kAdministratorGranted; |
| } |
| |
| switch (setting) { |
| case CONTENT_SETTING_ASK: |
| return Variant::kAsk; |
| case CONTENT_SETTING_ALLOW: |
| return Variant::kPreviouslyGranted; |
| case CONTENT_SETTING_BLOCK: |
| return Variant::kPreviouslyDenied; |
| default: |
| break; |
| } |
| |
| return Variant::kUninitialized; |
| } |
| |
| void EmbeddedPermissionPrompt::CloseCurrentViewAndMaybeShowNext( |
| bool first_prompt) { |
| if (!first_prompt) { |
| CloseView(); |
| } |
| |
| auto* map = HostContentSettingsMapFactory::GetForProfile( |
| Profile::FromBrowserContext(web_contents()->GetBrowserContext())); |
| content_settings::SettingInfo info; |
| |
| for (const auto& request : delegate()->Requests()) { |
| ContentSettingsType type = request->GetContentSettingsType(); |
| ContentSetting setting = |
| map->GetContentSetting(delegate()->GetRequestingOrigin(), |
| delegate()->GetEmbeddingOrigin(), type, &info); |
| Variant current_request_variant = |
| DeterminePromptVariant(setting, info, type); |
| PrioritizeAndMergeNewVariant(current_request_variant, type); |
| } |
| |
| RebuildRequests(); |
| |
| EmbeddedPermissionPromptBaseView* prompt_view = nullptr; |
| |
| switch (embedded_prompt_variant_) { |
| case Variant::kAsk: |
| prompt_view = new EmbeddedPermissionPromptAskView( |
| browser(), weak_factory_.GetWeakPtr()); |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleVariantUMA( |
| delegate()->Requests(), |
| permissions::ElementAnchoredBubbleVariant::ASK); |
| break; |
| case Variant::kPreviouslyGranted: |
| if (first_prompt) { |
| prompt_view = new EmbeddedPermissionPromptPreviouslyGrantedView( |
| browser(), weak_factory_.GetWeakPtr()); |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleVariantUMA( |
| delegate()->Requests(), |
| permissions::ElementAnchoredBubbleVariant::PREVIOUSLY_GRANTED); |
| } else { |
| delegate()->FinalizeCurrentRequests(); |
| return; |
| } |
| break; |
| case Variant::kPreviouslyDenied: |
| prompt_view = new EmbeddedPermissionPromptPreviouslyDeniedView( |
| browser(), weak_factory_.GetWeakPtr()); |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleVariantUMA( |
| delegate()->Requests(), |
| permissions::ElementAnchoredBubbleVariant::PREVIOUSLY_DENIED); |
| break; |
| case Variant::kOsPrompt: |
| prompt_view = new EmbeddedPermissionPromptShowSystemPromptView( |
| browser(), weak_factory_.GetWeakPtr()); |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleVariantUMA( |
| delegate()->Requests(), |
| permissions::ElementAnchoredBubbleVariant::OS_PROMPT); |
| current_variant_first_display_time_ = base::Time::Now(); |
| // This view has no buttons, so the OS level prompt should be triggered at the |
| // same time as the |EmbeddedPermissionPromptShowSystemPromptView|. |
| #if BUILDFLAG(IS_MAC) |
| PromptForOsPermission(); |
| #endif |
| break; |
| case Variant::kOsSystemSettings: |
| prompt_view = new EmbeddedPermissionPromptSystemSettingsView( |
| browser(), weak_factory_.GetWeakPtr()); |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleVariantUMA( |
| delegate()->Requests(), |
| permissions::ElementAnchoredBubbleVariant::OS_SYSTEM_SETTINGS); |
| current_variant_first_display_time_ = base::Time::Now(); |
| break; |
| case Variant::kAdministratorGranted: |
| prompt_view = new EmbeddedPermissionPromptPolicyView( |
| browser(), weak_factory_.GetWeakPtr(), |
| /*is_permission_allowed=*/true); |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleVariantUMA( |
| delegate()->Requests(), |
| permissions::ElementAnchoredBubbleVariant::ADMINISTRATOR_GRANTED); |
| break; |
| case Variant::kAdministratorDenied: |
| prompt_view = new EmbeddedPermissionPromptPolicyView( |
| browser(), weak_factory_.GetWeakPtr(), |
| /*is_permission_allowed=*/false); |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleVariantUMA( |
| delegate()->Requests(), |
| permissions::ElementAnchoredBubbleVariant::ADMINISTRATOR_DENIED); |
| break; |
| case Variant::kUninitialized: |
| NOTREACHED(); |
| } |
| |
| if (prompt_view) { |
| prompt_view_tracker_.SetView(prompt_view); |
| content_scrim_widget_ = |
| EmbeddedPermissionPromptContentScrimView::CreateScrimWidget( |
| weak_factory_.GetWeakPtr(), |
| SkColorSetA(gfx::kGoogleGrey700, SK_AlphaOPAQUE * 0.5f)); |
| prompt_view->UpdateAnchor(content_scrim_widget_.get()); |
| prompt_view->Show(); |
| } |
| } |
| |
| EmbeddedPermissionPrompt::TabSwitchingBehavior |
| EmbeddedPermissionPrompt::GetTabSwitchingBehavior() { |
| return TabSwitchingBehavior::kDestroyPromptButKeepRequestPending; |
| } |
| |
| void EmbeddedPermissionPrompt::RecordOsMetrics( |
| permissions::OsScreenAction action) { |
| permissions::OsScreen screen; |
| |
| switch (embedded_prompt_variant_) { |
| case Variant::kOsPrompt: |
| screen = permissions::OsScreen::OS_PROMPT; |
| break; |
| case Variant::kOsSystemSettings: |
| screen = permissions::OsScreen::OS_SYSTEM_SETTINGS; |
| break; |
| default: |
| return; |
| } |
| |
| base::TimeDelta time_to_decision = |
| base::Time::Now() - current_variant_first_display_time_; |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleOsMetrics( |
| delegate()->Requests(), screen, action, time_to_decision); |
| } |
| |
| permissions::PermissionPromptDisposition |
| EmbeddedPermissionPrompt::GetPromptDisposition() const { |
| return permissions::PermissionPromptDisposition::ELEMENT_ANCHORED_BUBBLE; |
| } |
| |
| bool EmbeddedPermissionPrompt::ShouldFinalizeRequestAfterDecided() const { |
| return false; |
| } |
| |
| void EmbeddedPermissionPrompt::PrecalculateVariantsForMetrics() { |
| if (embedded_prompt_variant_ == Variant::kUninitialized) { |
| return; |
| } |
| |
| site_level_prompt_variant_ = embedded_prompt_variant_; |
| |
| #if BUILDFLAG(IS_MAC) |
| if (os_prompt_variant_ == Variant::kUninitialized) { |
| for (const auto& request : delegate()->Requests()) { |
| if (ShouldShowOSPromptViewOnMacOS(request->GetContentSettingsType())) { |
| os_prompt_variant_ = Variant::kOsPrompt; |
| break; |
| } |
| } |
| } |
| |
| if (os_system_settings_variant_ == Variant::kUninitialized) { |
| for (const auto& request : delegate()->Requests()) { |
| if (ShouldShowSystemSettingsViewOnMacOS( |
| request->GetContentSettingsType())) { |
| os_system_settings_variant_ = Variant::kOsSystemSettings; |
| break; |
| } |
| } |
| } |
| #endif // BUILDFLAG(IS_MAC) |
| } |
| |
| std::vector<permissions::ElementAnchoredBubbleVariant> |
| EmbeddedPermissionPrompt::GetPromptVariants() const { |
| std::vector<permissions::ElementAnchoredBubbleVariant> variants; |
| |
| // Current prompt variant when the user takes an action on a site level |
| // prompt. |
| if (embedded_prompt_variant_ != Variant::kUninitialized) { |
| variants.push_back(GetVariant(embedded_prompt_variant_)); |
| } |
| |
| #if BUILDFLAG(IS_MAC) |
| if (os_prompt_variant_ != Variant::kUninitialized) { |
| variants.push_back(GetVariant(os_prompt_variant_)); |
| } |
| if (os_system_settings_variant_ != Variant::kUninitialized) { |
| variants.push_back(GetVariant(os_system_settings_variant_)); |
| } |
| #endif // BUILDFLAG(IS_MAC) |
| |
| return variants; |
| } |
| |
| void EmbeddedPermissionPrompt::Allow() { |
| PrecalculateVariantsForMetrics(); |
| delegate_->Accept(); |
| CloseCurrentViewAndMaybeShowNext(/*first_prompt=*/false); |
| } |
| |
| void EmbeddedPermissionPrompt::AllowThisTime() { |
| PrecalculateVariantsForMetrics(); |
| delegate_->AcceptThisTime(); |
| CloseCurrentViewAndMaybeShowNext(/*first_prompt=*/false); |
| } |
| |
| void EmbeddedPermissionPrompt::Dismiss() { |
| PrecalculateVariantsForMetrics(); |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleDismiss( |
| delegate()->Requests(), permissions::DismissedReason::DISMISSED_X_BUTTON); |
| |
| RecordOsMetrics(permissions::OsScreenAction::DISMISSED_X_BUTTON); |
| |
| delegate_->Dismiss(); |
| delegate_->FinalizeCurrentRequests(); |
| } |
| |
| void EmbeddedPermissionPrompt::Acknowledge() { |
| // TOOO(crbug.com/1462930): Find how to distinguish between a dismiss and an |
| // acknowledge. |
| CloseView(); |
| delegate_->FinalizeCurrentRequests(); |
| } |
| |
| void EmbeddedPermissionPrompt::StopAllowing() { |
| PrecalculateVariantsForMetrics(); |
| delegate_->Deny(); |
| delegate_->FinalizeCurrentRequests(); |
| } |
| |
| void EmbeddedPermissionPrompt::ShowSystemSettings() { |
| const auto& requests = delegate()->Requests(); |
| CHECK_GT(requests.size(), 0U); |
| // TODO(crbug.com/40275129) Chrome always shows the first permission in a group, |
| // as it is not possible to open multiple System Setting pages. Figure out a |
| // better way to handle this scenario. |
| #if BUILDFLAG(IS_MAC) |
| RecordOsMetrics(permissions::OsScreenAction::SYSTEM_SETTINGS); |
| |
| if (requests_[0]->request_type() == permissions::RequestType::kCameraStream) { |
| OpenCameraSystemSettingsOnMacOS(); |
| } else if (requests_[0]->request_type() == |
| permissions::RequestType::kMicStream) { |
| OpenMicSystemSettingsOnMacOS(); |
| } |
| |
| #endif |
| } |
| |
| base::WeakPtr<permissions::PermissionPrompt::Delegate> |
| EmbeddedPermissionPrompt::GetPermissionPromptDelegate() const { |
| return delegate_->GetWeakPtr(); |
| } |
| |
| const std::vector<raw_ptr<permissions::PermissionRequest, VectorExperimental>>& |
| EmbeddedPermissionPrompt::Requests() const { |
| return requests_; |
| } |
| |
| void EmbeddedPermissionPrompt::DismissScrim() { |
| permissions::PermissionUmaUtil::RecordElementAnchoredBubbleDismiss( |
| delegate()->Requests(), permissions::DismissedReason::DISMISSED_SCRIM); |
| |
| if (embedded_prompt_variant_ == Variant::kOsPrompt) { |
| RecordOsMetrics(permissions::OsScreenAction::DISMISSED_SCRIM); |
| } |
| |
| if (embedded_prompt_variant_ == Variant::kOsSystemSettings) { |
| RecordOsMetrics(permissions::OsScreenAction::DISMISSED_SCRIM); |
| } |
| |
| CloseView(); |
| PrecalculateVariantsForMetrics(); |
| delegate_->Dismiss(); |
| delegate_->FinalizeCurrentRequests(); |
| } |
| |
| void EmbeddedPermissionPrompt::PromptForOsPermission() { |
| #if BUILDFLAG(IS_MAC) |
| // We currently support <=2 grouped permissions. |
| CHECK_LE(prompt_types_.size(), 2U); |
| |
| for (const auto prompt : prompt_types_) { |
| RequestMacOSMediaSystemPermission(prompt, prompt_types_.size() == 2U); |
| } |
| #endif |
| } |
| |
| #if BUILDFLAG(IS_MAC) |
| void EmbeddedPermissionPrompt::OnRequestSystemMediaPermissionResponse( |
| const ContentSettingsType request_type, |
| bool grouped_permissions) { |
| system_media_permissions::SystemPermission permission, |
| other_permission = |
| system_media_permissions::SystemPermission::kNotDetermined; |
| |
| if (request_type == ContentSettingsType::MEDIASTREAM_MIC) { |
| permission = system_media_permissions::CheckSystemAudioCapturePermission(); |
| other_permission = |
| grouped_permissions |
| ? system_media_permissions::CheckSystemVideoCapturePermission() |
| : system_media_permissions::SystemPermission::kNotDetermined; |
| } |
| |
| if (request_type == ContentSettingsType::MEDIASTREAM_CAMERA) { |
| permission = system_media_permissions::CheckSystemVideoCapturePermission(); |
| other_permission = |
| grouped_permissions |
| ? system_media_permissions::CheckSystemAudioCapturePermission() |
| : system_media_permissions::SystemPermission::kNotDetermined; |
| } |
| |
| switch (permission) { |
| case system_media_permissions::SystemPermission::kRestricted: |
| case system_media_permissions::SystemPermission::kDenied: |
| case system_media_permissions::SystemPermission::kAllowed: |
| // Do not finalize request until all the necessary system permissions are |
| // granted. |
| if (!grouped_permissions || |
| other_permission != |
| system_media_permissions::SystemPermission::kNotDetermined) { |
| CloseView(); |
| delegate_->FinalizeCurrentRequests(); |
| } |
| break; |
| default: |
| NOTREACHED(); |
| } |
| } |
| |
| // TODO: Refactor this logic for PEPC and other permission prompts, to avoid |
| // code duplication. |
| void EmbeddedPermissionPrompt::RequestMacOSMediaSystemPermission( |
| const ContentSettingsType request_type, |
| bool grouped_permissions) { |
| if (request_type == ContentSettingsType::MEDIASTREAM_MIC) { |
| system_media_permissions::RequestSystemAudioCapturePermission( |
| base::BindOnce( |
| &EmbeddedPermissionPrompt::OnRequestSystemMediaPermissionResponse, |
| weak_factory_.GetWeakPtr(), request_type, grouped_permissions)); |
| return; |
| } |
| |
| if (request_type == ContentSettingsType::MEDIASTREAM_CAMERA) { |
| system_media_permissions::RequestSystemVideoCapturePermission( |
| base::BindOnce( |
| &EmbeddedPermissionPrompt::OnRequestSystemMediaPermissionResponse, |
| weak_factory_.GetWeakPtr(), request_type, grouped_permissions)); |
| return; |
| } |
| } |
| #endif |
| |
| void EmbeddedPermissionPrompt::PrioritizeAndMergeNewVariant( |
| EmbeddedPermissionPrompt::Variant new_variant, |
| ContentSettingsType new_type) { |
| // The new variant can be grouped with the already existing one. |
| if (CanGroupVariants(embedded_prompt_variant_, new_variant)) { |
| prompt_types_.insert(new_type); |
| embedded_prompt_variant_ = std::max(embedded_prompt_variant_, new_variant); |
| return; |
| } |
| |
| // The existing variant is higher priority than the new one. |
| if (embedded_prompt_variant_ > new_variant) { |
| return; |
| } |
| |
| // The new variant has higher priority than the existing one. |
| prompt_types_.clear(); |
| prompt_types_.insert(new_type); |
| embedded_prompt_variant_ = new_variant; |
| } |
| |
| void EmbeddedPermissionPrompt::RebuildRequests() { |
| if (requests_.size() != prompt_types_.size()) { |
| const auto& requests = delegate()->Requests(); |
| for (permissions::PermissionRequest* request : requests) { |
| if (prompt_types_.contains(request->GetContentSettingsType())) { |
| requests_.push_back(request); |
| } |
| } |
| } |
| } |
| |
| void EmbeddedPermissionPrompt::CloseView() { |
| if (auto* prompt_view = static_cast<EmbeddedPermissionPromptBaseView*>( |
| prompt_view_tracker_.view())) { |
| prompt_view->PrepareToClose(); |
| prompt_view->GetWidget()->Close(); |
| prompt_view_tracker_.SetView(nullptr); |
| |
| requests_.clear(); |
| prompt_types_.clear(); |
| embedded_prompt_variant_ = Variant::kUninitialized; |
| } |
| |
| if (content_scrim_widget_) { |
| content_scrim_widget_->Close(); |
| content_scrim_widget_.reset(); |
| } |
| } |