Commit 5e3b0a50 authored by nancy's avatar nancy Committed by Commit Bot

Add "learn more" link for the uninstall dialog.

Add "Learn more" link for the PWAs unisntall dialog per UX deck:
https://docs.google.com/presentation/d/1jfyLf21naKDQwe07jkhgqtI8Fd2Z88W93l1F1q3FyhY/edit#slide=id.g6e0ab3bcaa_0_0
https://docs.google.com/presentation/d/1jfyLf21naKDQwe07jkhgqtI8Fd2Z88W93l1F1q3FyhY/edit#slide=id.g7d0934dbfa_0_0

Mock dialog:
https://photos.app.goo.gl/AtQfZr9RYKH5HsMi9

Move OnDialogCancelled and OnDialogAccepted to keep the consistent order
as the definition in *.h file.

BUG=1010303

Change-Id: I5c955940643c3753e68fca6aa9a3d07aed226615
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2106986
Commit-Queue: Nancy Wang <nancylingwang@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751612}
parent 2635ca2c
......@@ -10637,12 +10637,16 @@ Please help our engineers fix this problem. Tell us what happened right before y
<!-- App uninstall prompt for non-Google -->
<message name="IDS_APP_UNINSTALL_PROMPT_REMOVE_DATA_CHECKBOX_FOR_NON_GOOGLE" desc="Checkbox text to ask the user whether they want to remove associated data at uninstall time. Only used when uninstalling an app associated with a particular website.">
Also clear browsing data (<ph name="URL">$1<ex>pinterest.com</ex></ph>) which will sign you out of <ph name="DOMAIN">$2<ex>Pinterest.com</ex></ph>.
Also clear browsing data (<ph name="URL">$1<ex>pinterest.com</ex></ph>) which will sign you out of <ph name="DOMAIN">$2<ex>Pinterest.com</ex></ph>. <ph name="LEARN_MORE">$3<ex>Learn more</ex></ph>
</message>
<!-- App uninstall prompt for Google -->
<message name="IDS_APP_UNINSTALL_PROMPT_REMOVE_DATA_CHECKBOX_FOR_GOOGLE" desc="Checkbox text to ask the user whether they want to remove associated data at uninstall time for Google hostnames. Only used when uninstalling an app associated with a Google hostname.">
Also clear browsing data (<ph name="URL">$1<ex>www.google.com</ex></ph>) which may sign you out of Google.com.
Also clear browsing data (<ph name="URL">$1<ex>www.google.com</ex></ph>) which may sign you out of Google.com. <ph name="LEARN_MORE">$2<ex>Learn more</ex></ph>
</message>
<message name="IDS_APP_UNINSTALL_PROMPT_LEARN_MORE" desc="The label that the user can click to learn more about removing associated data at uninstall time.">
Learn more
</message>
<!-- Speech On-Device API -->
......
865617cd36d305958a8fdcc5dfd10b9a5b8b84df
\ No newline at end of file
f0d698f753f21286e49fa170e4f6c67b325fde7c
\ No newline at end of file
865617cd36d305958a8fdcc5dfd10b9a5b8b84df
\ No newline at end of file
b5a3bf700452a0046e6ea796752319a93094885c
\ No newline at end of file
af4f462fec2194b11bcd777b8867f7e9c2a61fad
\ No newline at end of file
......@@ -11,6 +11,8 @@
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/chrome_typography.h"
#include "chrome/browser/web_applications/web_app_provider.h"
......@@ -30,6 +32,7 @@
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/layout/box_layout.h"
#if defined(OS_CHROMEOS)
......@@ -67,6 +70,7 @@ AppUninstallDialogView::AppUninstallDialogView(
apps::UninstallDialog* uninstall_dialog)
: apps::UninstallDialog::UiBase(uninstall_dialog),
AppDialogView(app_name, image),
profile_(profile),
app_type_(app_type) {
DialogDelegate::SetCloseCallback(base::BindOnce(
&AppUninstallDialogView::OnDialogCancelled, base::Unretained(this)));
......@@ -91,21 +95,6 @@ AppUninstallDialogView* AppUninstallDialogView::GetActiveViewForTesting() {
return g_app_uninstall_dialog_view;
}
void AppUninstallDialogView::OnDialogCancelled() {
uninstall_dialog()->OnDialogClosed(false /* uninstall */,
false /* clear_site_data */,
false /* report_abuse */);
}
void AppUninstallDialogView::OnDialogAccepted() {
const bool clear_site_data =
clear_site_data_checkbox_ && clear_site_data_checkbox_->GetChecked();
const bool report_abuse_checkbox =
report_abuse_checkbox_ && report_abuse_checkbox_->GetChecked();
uninstall_dialog()->OnDialogClosed(true /* uninstall */, clear_site_data,
report_abuse_checkbox);
}
ui::ModalType AppUninstallDialogView::GetModalType() const {
return ui::MODAL_TYPE_WINDOW;
}
......@@ -190,32 +179,83 @@ void AppUninstallDialogView::InitializeView(Profile* profile,
}
void AppUninstallDialogView::InitializeCheckbox(const GURL& app_launch_url) {
std::unique_ptr<views::Checkbox> clear_site_data_checkbox;
std::unique_ptr<views::StyledLabel> checkbox_label;
std::vector<base::string16> replacements;
size_t offset;
base::string16 learn_more_text =
l10n_util::GetStringUTF16(IDS_APP_UNINSTALL_PROMPT_LEARN_MORE);
replacements.push_back(url_formatter::FormatUrlForSecurityDisplay(
app_launch_url, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC));
if (google_util::IsGoogleHostname(app_launch_url.host_piece(),
google_util::ALLOW_SUBDOMAIN)) {
clear_site_data_checkbox =
std::make_unique<views::Checkbox>(l10n_util::GetStringFUTF16(
replacements.push_back(learn_more_text);
std::vector<size_t> offsets;
checkbox_label = std::make_unique<views::StyledLabel>(
l10n_util::GetStringFUTF16(
IDS_APP_UNINSTALL_PROMPT_REMOVE_DATA_CHECKBOX_FOR_GOOGLE,
url_formatter::FormatUrlForSecurityDisplay(
app_launch_url,
url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)));
replacements, &offsets),
this);
DCHECK_EQ(replacements.size(), offsets.size());
offset = offsets[offsets.size() - 1];
} else {
auto domain = net::registry_controlled_domains::GetDomainAndRegistry(
app_launch_url.host_piece(),
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
DCHECK(!domain.empty());
domain[0] = base::ToUpperASCII(domain[0]);
clear_site_data_checkbox =
std::make_unique<views::Checkbox>(l10n_util::GetStringFUTF16(
replacements.push_back(base::ASCIIToUTF16(domain));
replacements.push_back(learn_more_text);
std::vector<size_t> offsets;
checkbox_label = std::make_unique<views::StyledLabel>(
l10n_util::GetStringFUTF16(
IDS_APP_UNINSTALL_PROMPT_REMOVE_DATA_CHECKBOX_FOR_NON_GOOGLE,
url_formatter::FormatUrlForSecurityDisplay(
app_launch_url,
url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC),
base::ASCIIToUTF16(domain)));
replacements, &offsets),
this);
DCHECK_EQ(replacements.size(), offsets.size());
offset = offsets[offsets.size() - 1];
}
clear_site_data_checkbox->SetMultiLine(true);
clear_site_data_checkbox_ = AddChildView(std::move(clear_site_data_checkbox));
checkbox_label->AddStyleRange(
gfx::Range(offset, offset + learn_more_text.length()),
views::StyledLabel::RangeStyleInfo::CreateForLink());
views::StyledLabel::RangeStyleInfo checkbox_style;
checkbox_style.text_style = views::style::STYLE_PRIMARY;
gfx::Range before_link_range(0, offset);
checkbox_label->AddStyleRange(before_link_range, checkbox_style);
// Shift the text down to align with the checkbox.
checkbox_label->SetBorder(views::CreateEmptyBorder(3, 0, 0, 0));
auto clear_site_data_checkbox =
std::make_unique<views::Checkbox>(base::string16());
clear_site_data_checkbox->SetAssociatedLabel(checkbox_label.get());
// Create a view to hold the checkbox and the text.
auto checkbox_view = std::make_unique<views::View>();
views::GridLayout* checkbox_layout =
checkbox_view->SetLayoutManager(std::make_unique<views::GridLayout>());
const int kReportColumnSetId = 0;
views::ColumnSet* cs = checkbox_layout->AddColumnSet(kReportColumnSetId);
cs->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING,
views::GridLayout::kFixedSize, views::GridLayout::USE_PREF, 0,
0);
cs->AddPaddingColumn(views::GridLayout::kFixedSize,
ChromeLayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_RELATED_LABEL_HORIZONTAL));
cs->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1.0,
views::GridLayout::USE_PREF, 0, 0);
checkbox_layout->StartRow(views::GridLayout::kFixedSize, kReportColumnSetId);
clear_site_data_checkbox_ =
checkbox_layout->AddView(std::move(clear_site_data_checkbox));
checkbox_layout->AddView(std::move(checkbox_label));
AddChildView(std::move(checkbox_view));
}
void AppUninstallDialogView::InitializeViewForExtension(
......@@ -287,3 +327,27 @@ void AppUninstallDialogView::InitializeViewForCrostiniApp(
label->SetAllowCharacterBreak(true);
}
#endif
void AppUninstallDialogView::StyledLabelLinkClicked(views::StyledLabel* label,
const gfx::Range& range,
int event_flags) {
NavigateParams params(
profile_, GURL("https://support.google.com/chromebook/?p=uninstallpwa"),
ui::PAGE_TRANSITION_LINK);
Navigate(&params);
}
void AppUninstallDialogView::OnDialogCancelled() {
uninstall_dialog()->OnDialogClosed(false /* uninstall */,
false /* clear_site_data */,
false /* report_abuse */);
}
void AppUninstallDialogView::OnDialogAccepted() {
const bool clear_site_data =
clear_site_data_checkbox_ && clear_site_data_checkbox_->GetChecked();
const bool report_abuse_checkbox =
report_abuse_checkbox_ && report_abuse_checkbox_->GetChecked();
uninstall_dialog()->OnDialogClosed(true /* uninstall */, clear_site_data,
report_abuse_checkbox);
}
......@@ -12,6 +12,7 @@
#include "chrome/browser/ui/views/apps/app_dialog/app_dialog_view.h"
#include "chrome/services/app_service/public/mojom/types.mojom-forward.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/styled_label_listener.h"
class Profile;
......@@ -23,24 +24,13 @@ namespace gfx {
class ImageSkia;
}
// Currently, app uninstallation on Chrome OS invokes a specific dialog per app
// type:
// - Chrome Apps / PWAs:
// https://cs.chromium.org/chromium/src/chrome/browser/ui/app_list/extension_uninstaller.h?q=extensionuninstaller&sq=package:chromium&l=17
// - ARC apps:
// https://cs.chromium.org/chromium/src/chrome/browser/ui/app_list/arc/arc_app_dialog.h?q=arcappunin&sq=package:chromium&l=21
// - Crostini:
// https://cs.chromium.org/chromium/src/chrome/browser/chromeos/crostini/crostini_util.h?type=cs&q=crostiniuninstall&sq=package:chromium&g=0&l=131
//
// There are 3 separate views for app uninstalling, which are subtly different
// from each other.
//
// This class combines the above three specific dialogs, and generates the
// correct UI based on the app type. Once the user has confirmed the uninstall,
// this class calls the parent class apps::UninstallDialog::UiBase to notify
// AppService, which transfers control to the publisher to uninstall the app.
// This class generates the unified uninstall dialog based on the app type. Once
// the user has confirmed the uninstall, this class calls the parent class
// apps::UninstallDialog::UiBase to notify AppService, which transfers control
// to the publisher to uninstall the app.
class AppUninstallDialogView : public apps::UninstallDialog::UiBase,
public AppDialogView {
public AppDialogView,
public views::StyledLabelListener {
public:
AppUninstallDialogView(Profile* profile,
apps::mojom::AppType app_type,
......@@ -71,9 +61,16 @@ class AppUninstallDialogView : public apps::UninstallDialog::UiBase,
const std::string& app_id);
#endif
// views::StyledLabelListener methods.
void StyledLabelLinkClicked(views::StyledLabel* label,
const gfx::Range& range,
int event_flags) override;
void OnDialogCancelled();
void OnDialogAccepted();
Profile* profile_;
// The type of apps, e.g. Extension-backed app, Android app.
apps::mojom::AppType app_type_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment