| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/app_list/arc/arc_data_removal_dialog.h" |
| |
| #include "base/macros.h" |
| #include "chrome/browser/ash/arc/session/arc_session_manager.h" |
| #include "chrome/browser/ash/arc/session/arc_session_manager_observer.h" |
| #include "chrome/browser/ui/app_list/app_service/app_service_app_icon_loader.h" |
| #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" |
| #include "chrome/browser/ui/browser_dialogs.h" |
| #include "chrome/browser/ui/views/chrome_layout_provider.h" |
| #include "chrome/grit/generated_resources.h" |
| #include "components/constrained_window/constrained_window_views.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/metadata/metadata_header_macros.h" |
| #include "ui/base/metadata/metadata_impl_macros.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/base/ui_base_types.h" |
| #include "ui/gfx/geometry/insets.h" |
| #include "ui/views/controls/image_view.h" |
| #include "ui/views/controls/label.h" |
| #include "ui/views/layout/box_layout.h" |
| #include "ui/views/layout/layout_provider.h" |
| #include "ui/views/view.h" |
| #include "ui/views/widget/widget.h" |
| #include "ui/views/window/dialog_delegate.h" |
| |
| namespace arc { |
| |
| namespace { |
| |
| constexpr int kArcAppIconSize = 48; |
| |
| // This dialog is shown when ARC++ comes into the state when normal |
| // functionality could not be possible without resetting whole container by data |
| // removal. It provides an option for the user to remove data and restart the |
| // ARC++ or keep current data. Following is known case: |
| // * Child user failed to transit from/to regular state. |
| class DataRemovalConfirmationDialog : public views::DialogDelegateView, |
| public AppIconLoaderDelegate, |
| public ArcSessionManagerObserver { |
| public: |
| METADATA_HEADER(DataRemovalConfirmationDialog); |
| DataRemovalConfirmationDialog( |
| Profile* profile, |
| DataRemovalConfirmationCallback confirm_data_removal); |
| DataRemovalConfirmationDialog(const DataRemovalConfirmationDialog&) = delete; |
| DataRemovalConfirmationDialog& operator=( |
| const DataRemovalConfirmationDialog&) = delete; |
| ~DataRemovalConfirmationDialog() override; |
| |
| // AppIconLoaderDelegate: |
| void OnAppImageUpdated(const std::string& app_id, |
| const gfx::ImageSkia& image) override; |
| |
| // ArcSessionManagerObserver: |
| void OnArcPlayStoreEnabledChanged(bool enabled) override; |
| |
| private: |
| // UI hierarchy owned. |
| views::ImageView* icon_view_ = nullptr; |
| |
| std::unique_ptr<AppServiceAppIconLoader> icon_loader_; |
| |
| Profile* const profile_; |
| |
| DataRemovalConfirmationCallback confirm_callback_; |
| }; |
| |
| DataRemovalConfirmationDialog* g_current_data_removal_confirmation = nullptr; |
| |
| DataRemovalConfirmationDialog::DataRemovalConfirmationDialog( |
| Profile* profile, |
| DataRemovalConfirmationCallback confirm_callback) |
| : profile_(profile), confirm_callback_(std::move(confirm_callback)) { |
| SetTitle(l10n_util::GetStringUTF16(IDS_ARC_DATA_REMOVAL_CONFIRMATION_TITLE)); |
| SetButtonLabel( |
| ui::DIALOG_BUTTON_OK, |
| l10n_util::GetStringUTF16(IDS_ARC_DATA_REMOVAL_CONFIRMATION_OK_BUTTON)); |
| |
| auto run_callback = [](DataRemovalConfirmationDialog* dialog, bool accept) { |
| std::move(dialog->confirm_callback_).Run(accept); |
| }; |
| SetAcceptCallback(base::BindOnce(run_callback, base::Unretained(this), true)); |
| SetCancelCallback( |
| base::BindOnce(run_callback, base::Unretained(this), false)); |
| |
| SetModalType(ui::MODAL_TYPE_WINDOW); |
| set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( |
| views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH)); |
| |
| ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); |
| |
| std::unique_ptr<views::BoxLayout> layout = std::make_unique<views::BoxLayout>( |
| views::BoxLayout::Orientation::kHorizontal, |
| provider->GetDialogInsetsForContentType(views::DialogContentType::kText, |
| views::DialogContentType::kText), |
| provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL)); |
| layout->set_cross_axis_alignment( |
| views::BoxLayout::CrossAxisAlignment::kStart); |
| SetLayoutManager(std::move(layout)); |
| |
| auto icon_view = std::make_unique<views::ImageView>(); |
| icon_view->SetPreferredSize(gfx::Size(kArcAppIconSize, kArcAppIconSize)); |
| icon_view_ = AddChildView(std::move(icon_view)); |
| |
| // UI hierarchy owned. |
| auto label = std::make_unique<views::Label>( |
| l10n_util::GetStringUTF16(IDS_ARC_DATA_REMOVAL_CONFIRMATION_HEADING), |
| views::style::CONTEXT_DIALOG_BODY_TEXT); |
| label->SetMultiLine(true); |
| label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| AddChildView(std::move(label)); |
| |
| icon_loader_ = std::make_unique<AppServiceAppIconLoader>( |
| profile_, kArcAppIconSize, this); |
| icon_loader_->FetchImage(kPlayStoreAppId); |
| chrome::RecordDialogCreation( |
| chrome::DialogIdentifier::ARC_DATA_REMOVAL_CONFIRMATION); |
| |
| ArcSessionManager::Get()->AddObserver(this); |
| |
| constrained_window::CreateBrowserModalDialogViews(this, nullptr)->Show(); |
| } |
| |
| DataRemovalConfirmationDialog::~DataRemovalConfirmationDialog() { |
| ArcSessionManager::Get()->RemoveObserver(this); |
| |
| DCHECK_EQ(g_current_data_removal_confirmation, this); |
| g_current_data_removal_confirmation = nullptr; |
| } |
| |
| void DataRemovalConfirmationDialog::OnAppImageUpdated( |
| const std::string& app_id, |
| const gfx::ImageSkia& image) { |
| DCHECK(!image.isNull()); |
| DCHECK_EQ(image.width(), kArcAppIconSize); |
| DCHECK_EQ(image.height(), kArcAppIconSize); |
| icon_view_->SetImageSize(image.size()); |
| icon_view_->SetImage(image); |
| } |
| |
| void DataRemovalConfirmationDialog::OnArcPlayStoreEnabledChanged(bool enabled) { |
| // Close dialog on ARC++ OptOut. In this case data is automatically removed |
| // and current dialog is no longer needed. |
| if (enabled) |
| return; |
| CancelDialog(); |
| } |
| |
| BEGIN_METADATA(DataRemovalConfirmationDialog, views::DialogDelegateView) |
| END_METADATA |
| |
| } // namespace |
| |
| void ShowDataRemovalConfirmationDialog( |
| Profile* profile, |
| DataRemovalConfirmationCallback callback) { |
| if (!g_current_data_removal_confirmation) |
| g_current_data_removal_confirmation = |
| new DataRemovalConfirmationDialog(profile, std::move(callback)); |
| } |
| |
| bool IsDataRemovalConfirmationDialogOpenForTesting() { |
| return g_current_data_removal_confirmation != nullptr; |
| } |
| |
| void CloseDataRemovalConfirmationDialogForTesting(bool confirm) { |
| DCHECK(g_current_data_removal_confirmation); |
| if (confirm) { |
| g_current_data_removal_confirmation->AcceptDialog(); |
| } else { |
| g_current_data_removal_confirmation->CancelDialog(); |
| } |
| } |
| |
| } // namespace arc |