// Copyright 2022 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/ash/arc/arc_vm_data_migration_confirmation_dialog.h"
#include "ash/components/arc/arc_prefs.h"
#include "ash/components/arc/arc_util.h"
#include "ash/components/arc/vector_icons/vector_icons.h"
#include "ash/style/ash_color_id.h"
#include "ash/style/ash_color_provider.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/chrome_typography.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/image_model.h"
#include "ui/base/mojom/dialog_button.mojom.h"
#include "ui/base/mojom/ui_base_types.mojom-shared.h"
#include "ui/color/color_id.h"
#include "ui/gfx/font.h"
#include "ui/gfx/geometry/insets_outsets_base.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/style/typography.h"
#include "ui/views/style/typography_provider.h"
#include "ui/views/view.h"
#include "ui/views/view_class_properties.h"
namespace arc {
namespace {
constexpr char kInternalName[] = "ArcVmDataMigrationConfirmationDialog";
constexpr int kDialogCornerRadius = 12;
void ReportConfirmationDialogShown(int days_until_deadline) {
base::UmaHistogramExactLinear(
"Arc.VmDataMigration.RemainingDays.ConfirmationDialogShown",
days_until_deadline, kArcVmDataMigrationNumberOfDismissibleDays);
}
void ReportConfirmationDialogButtonClicked(int days_until_deadline,
bool accepted) {
base::UmaHistogramExactLinear(
base::StringPrintf("Arc.VmDataMigration.RemainingDays.%s",
accepted ? "ConfirmationDialogAccepted"
: "ConfirmationDialogCanceled"),
days_until_deadline, kArcVmDataMigrationNumberOfDismissibleDays);
}
} // namespace
ArcVmDataMigrationConfirmationDialog::ArcVmDataMigrationConfirmationDialog(
PrefService* prefs,
ArcVmDataMigrationConfirmationCallback callback)
: callback_(std::move(callback)) {
DCHECK(prefs);
set_internal_name(kInternalName);
const int days_until_deadline = GetDaysUntilArcVmDataMigrationDeadline(prefs);
ReportConfirmationDialogShown(days_until_deadline);
if (ArcVmDataMigrationShouldBeDismissible(days_until_deadline)) {
SetButtons(static_cast<int>(ui::mojom::DialogButton::kOk) |
static_cast<int>(ui::mojom::DialogButton::kCancel));
SetButtonLabel(
ui::mojom::DialogButton::kOk,
l10n_util::GetStringUTF16(
IDS_ARC_VM_DATA_MIGRATION_DIALOG_UPDATE_NOW_BUTTON_LABEL));
SetButtonLabel(ui::mojom::DialogButton::kCancel,
l10n_util::GetStringUTF16(
IDS_ARC_VM_DATA_MIGRATION_DIALOG_SKIP_BUTTON_LABEL));
SetAcceptCallback(
base::BindOnce(&ArcVmDataMigrationConfirmationDialog::OnButtonClicked,
weak_ptr_factory_.GetWeakPtr(), days_until_deadline,
true /* accepted */));
SetCancelCallback(
base::BindOnce(&ArcVmDataMigrationConfirmationDialog::OnButtonClicked,
weak_ptr_factory_.GetWeakPtr(), days_until_deadline,
false /* accepted */));
} else {
SetButtons(static_cast<int>(ui::mojom::DialogButton::kOk));
SetButtonLabel(ui::mojom::DialogButton::kOk,
l10n_util::GetStringUTF16(
IDS_ARC_VM_DATA_MIGRATION_DIALOG_UPDATE_BUTTON_LABEL));
SetAcceptCallback(
base::BindOnce(&ArcVmDataMigrationConfirmationDialog::OnButtonClicked,
weak_ptr_factory_.GetWeakPtr(), days_until_deadline,
true /* accepted */));
}
InitializeView(days_until_deadline);
// Not system modal so that the user can interact with apps before restart.
SetModalType(ui::mojom::ModalType::kNone);
SetOwnedByWidget(true);
SetShowCloseButton(false);
const auto* layout_provider = ChromeLayoutProvider::Get();
DCHECK(layout_provider);
set_fixed_width(layout_provider->GetDistanceMetric(
ChromeDistanceMetric::DISTANCE_LARGE_MODAL_DIALOG_PREFERRED_WIDTH));
set_use_round_corners(true);
set_corner_radius(kDialogCornerRadius);
set_margins(layout_provider->GetDialogInsetsForContentType(
views::DialogContentType::kControl, views::DialogContentType::kControl));
}
ArcVmDataMigrationConfirmationDialog::~ArcVmDataMigrationConfirmationDialog() =
default;
void ArcVmDataMigrationConfirmationDialog::InitializeView(
int days_until_deadline) {
auto view = std::make_unique<views::View>();
const auto* layout_provider = ChromeLayoutProvider::Get();
DCHECK(layout_provider);
auto layout = std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical,
layout_provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG));
view->SetLayoutManager(std::move(layout));
view->AddChildView(
views::Builder<views::ImageView>()
.SetImage(ui::ImageModel::FromVectorIcon(
kSaveIcon, ash::AshColorProvider::Get()->GetContentLayerColor(
ash::AshColorProvider::ContentLayerType::
kIconColorProminent)))
.SetHorizontalAlignment(views::ImageView::Alignment::kLeading)
.Build());
view->AddChildView(
views::Builder<views::Label>()
.SetProperty(
views::kMarginsKey,
gfx::Insets::TLBR(layout_provider->GetDistanceMetric(
views::DISTANCE_UNRELATED_CONTROL_VERTICAL),
0, 0, 0))
.SetText(
l10n_util::GetStringUTF16(IDS_ARC_VM_DATA_MIGRATION_DIALOG_TITLE))
.SetTextContext(views::style::CONTEXT_DIALOG_TITLE)
.SetFontList(views::TypographyProvider::Get()
.GetFont(views::style::CONTEXT_DIALOG_TITLE,
views::style::STYLE_PRIMARY)
.DeriveWithWeight(gfx::Font::Weight::BOLD))
.SetHorizontalAlignment(gfx::ALIGN_LEFT)
.SetMultiLine(true)
.Build());
view->AddChildView(
views::Builder<views::Label>()
.SetProperty(
views::kMarginsKey,
gfx::Insets::TLBR(layout_provider->GetDistanceMetric(
views::DISTANCE_UNRELATED_CONTROL_VERTICAL),
0, 0, 0))
.SetText(l10n_util::GetStringUTF16(
IDS_ARC_VM_DATA_MIGRATION_DIALOG_SAVE_WORK_MESSAGE))
.SetTextContext(views::style::CONTEXT_DIALOG_BODY_TEXT)
.SetTextStyle(views::style::STYLE_PRIMARY)
.SetHorizontalAlignment(gfx::ALIGN_LEFT)
.SetMultiLine(true)
.Build());
view->AddChildView(
views::Builder<views::Label>()
.SetText(l10n_util::GetPluralStringFUTF16(
IDS_ARC_VM_DATA_MIGRATION_DIALOG_DAYS_UNTIL_DEADLINE,
days_until_deadline))
.SetTextContext(views::style::CONTEXT_DIALOG_BODY_TEXT)
.SetTextStyle(ChromeTextStyle::STYLE_RED)
.SetHorizontalAlignment(gfx::ALIGN_LEFT)
.SetMultiLine(true)
.Build());
SetContentsView(std::move(view));
}
void ArcVmDataMigrationConfirmationDialog::OnButtonClicked(
int days_until_deadline,
bool accepted) {
DCHECK(!callback_.is_null());
ReportConfirmationDialogButtonClicked(days_until_deadline, accepted);
std::move(callback_).Run(accepted);
}
void ShowArcVmDataMigrationConfirmationDialog(
PrefService* prefs,
ArcVmDataMigrationConfirmationCallback callback) {
views::DialogDelegate::CreateDialogWidget(
std::make_unique<ArcVmDataMigrationConfirmationDialog>(
prefs, std::move(callback)),
nullptr /* context */, nullptr /* parent */)
->Show();
}
} // namespace arc