Commit 35d6e5bb authored by siyua's avatar siyua Committed by Commit Bot

Adding Legal Message to Migration Dialogs

1) Added legal message (clickable) to the offer dialog.

2) Added a Close Button which will be shown when the
user clicks save button and the migration process lasts for more than
5 secs.

3) Modified ChromeAutofillClient to enable passing legal message
to the LocalCardMigrationDialogControllerImpl.

4) Adjusted format/style of the dialog contents according to the mock:
go/autofill-paradise.

5) Added an experiment flag (disabled by default) to control whether we want to show migration
feedback to the user.

Bug: 852904
Cq-Include-Trybots: luci.chromium.try:ios-simulator-cronet;luci.chromium.try:ios-simulator-full-configs
Change-Id: Ic0ca348fc689486a21d53a76921ee5954cb08295
Reviewed-on: https://chromium-review.googlesource.com/1192688
Commit-Queue: Siyu An <siyua@chromium.org>
Reviewed-by: default avatarMathieu Perreault <mathp@chromium.org>
Reviewed-by: default avatarBret Sepulveda <bsep@chromium.org>
Reviewed-by: default avatarFabio Tirelo <ftirelo@chromium.org>
Reviewed-by: default avatarTao Bai <michaelbai@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587886}
parent d977bcbb
...@@ -268,6 +268,7 @@ void AwAutofillClient::ShowLocalCardMigrationDialog( ...@@ -268,6 +268,7 @@ void AwAutofillClient::ShowLocalCardMigrationDialog(
} }
void AwAutofillClient::ConfirmMigrateLocalCardToCloud( void AwAutofillClient::ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<autofill::MigratableCreditCard>& migratable_credit_cards, std::vector<autofill::MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) { base::OnceClosure start_migrating_cards_closure) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
......
...@@ -76,6 +76,7 @@ class AwAutofillClient : public autofill::AutofillClient, ...@@ -76,6 +76,7 @@ class AwAutofillClient : public autofill::AutofillClient,
void ShowLocalCardMigrationDialog( void ShowLocalCardMigrationDialog(
base::OnceClosure show_migration_dialog_closure) override; base::OnceClosure show_migration_dialog_closure) override;
void ConfirmMigrateLocalCardToCloud( void ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<autofill::MigratableCreditCard>& migratable_credit_cards, std::vector<autofill::MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) override; base::OnceClosure start_migrating_cards_closure) override;
void ConfirmSaveAutofillProfile(const autofill::AutofillProfile& profile, void ConfirmSaveAutofillProfile(const autofill::AutofillProfile& profile,
......
...@@ -217,6 +217,7 @@ void ChromeAutofillClient::ShowLocalCardMigrationDialog( ...@@ -217,6 +217,7 @@ void ChromeAutofillClient::ShowLocalCardMigrationDialog(
} }
void ChromeAutofillClient::ConfirmMigrateLocalCardToCloud( void ChromeAutofillClient::ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<MigratableCreditCard>& migratable_credit_cards, std::vector<MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) { base::OnceClosure start_migrating_cards_closure) {
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
...@@ -228,6 +229,7 @@ void ChromeAutofillClient::ConfirmMigrateLocalCardToCloud( ...@@ -228,6 +229,7 @@ void ChromeAutofillClient::ConfirmMigrateLocalCardToCloud(
controller->SetViewState(LocalCardMigrationDialogState::kOffered); controller->SetViewState(LocalCardMigrationDialogState::kOffered);
controller->SetCardList(migratable_credit_cards); controller->SetCardList(migratable_credit_cards);
controller->ShowDialog( controller->ShowDialog(
std::move(legal_message),
CreateLocalCardMigrationDialogView(controller, web_contents()), CreateLocalCardMigrationDialogView(controller, web_contents()),
std::move(start_migrating_cards_closure)); std::move(start_migrating_cards_closure));
#endif #endif
......
...@@ -66,6 +66,7 @@ class ChromeAutofillClient ...@@ -66,6 +66,7 @@ class ChromeAutofillClient
void ShowLocalCardMigrationDialog( void ShowLocalCardMigrationDialog(
base::OnceClosure show_migration_dialog_closure) override; base::OnceClosure show_migration_dialog_closure) override;
void ConfirmMigrateLocalCardToCloud( void ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<MigratableCreditCard>& migratable_credit_cards, std::vector<MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) override; base::OnceClosure start_migrating_cards_closure) override;
void ConfirmSaveAutofillProfile(const AutofillProfile& profile, void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
......
...@@ -36,11 +36,18 @@ LocalCardMigrationDialogControllerImpl:: ...@@ -36,11 +36,18 @@ LocalCardMigrationDialogControllerImpl::
} }
void LocalCardMigrationDialogControllerImpl::ShowDialog( void LocalCardMigrationDialogControllerImpl::ShowDialog(
std::unique_ptr<base::DictionaryValue> legal_message,
LocalCardMigrationDialog* local_card_migration_dialog, LocalCardMigrationDialog* local_card_migration_dialog,
base::OnceClosure user_accepted_migration_closure) { base::OnceClosure user_accepted_migration_closure) {
if (local_card_migration_dialog_) if (local_card_migration_dialog_)
local_card_migration_dialog_->CloseDialog(); local_card_migration_dialog_->CloseDialog();
if (!LegalMessageLine::Parse(*legal_message, &legal_message_lines_,
/*escape_apostrophes=*/true)) {
// TODO(crbug/867194): Add metric.
return;
}
local_card_migration_dialog_ = local_card_migration_dialog; local_card_migration_dialog_ = local_card_migration_dialog;
local_card_migration_dialog_->ShowDialog( local_card_migration_dialog_->ShowDialog(
std::move(user_accepted_migration_closure)); std::move(user_accepted_migration_closure));
...@@ -66,6 +73,11 @@ void LocalCardMigrationDialogControllerImpl::SetCardList( ...@@ -66,6 +73,11 @@ void LocalCardMigrationDialogControllerImpl::SetCardList(
migratable_credit_cards_ = migratable_credit_cards; migratable_credit_cards_ = migratable_credit_cards;
} }
const LegalMessageLines&
LocalCardMigrationDialogControllerImpl::GetLegalMessageLines() const {
return legal_message_lines_;
}
void LocalCardMigrationDialogControllerImpl::OnCardSelected(int index) { void LocalCardMigrationDialogControllerImpl::OnCardSelected(int index) {
migratable_credit_cards_[index].ToggleChosen(); migratable_credit_cards_[index].ToggleChosen();
} }
......
...@@ -25,7 +25,8 @@ class LocalCardMigrationDialogControllerImpl ...@@ -25,7 +25,8 @@ class LocalCardMigrationDialogControllerImpl
public: public:
~LocalCardMigrationDialogControllerImpl() override; ~LocalCardMigrationDialogControllerImpl() override;
void ShowDialog(LocalCardMigrationDialog* local_card_migration_Dialog, void ShowDialog(std::unique_ptr<base::DictionaryValue> legal_message,
LocalCardMigrationDialog* local_card_migration_Dialog,
base::OnceClosure user_accepted_migration_closure_); base::OnceClosure user_accepted_migration_closure_);
// LocalCardMigrationDialogController: // LocalCardMigrationDialogController:
...@@ -33,6 +34,7 @@ class LocalCardMigrationDialogControllerImpl ...@@ -33,6 +34,7 @@ class LocalCardMigrationDialogControllerImpl
void SetViewState(LocalCardMigrationDialogState view_state) override; void SetViewState(LocalCardMigrationDialogState view_state) override;
const std::vector<MigratableCreditCard>& GetCardList() const override; const std::vector<MigratableCreditCard>& GetCardList() const override;
void SetCardList(std::vector<MigratableCreditCard>& card_list) override; void SetCardList(std::vector<MigratableCreditCard>& card_list) override;
const LegalMessageLines& GetLegalMessageLines() const override;
void OnCardSelected(int index) override; void OnCardSelected(int index) override;
void OnDialogClosed() override; void OnDialogClosed() override;
...@@ -48,6 +50,8 @@ class LocalCardMigrationDialogControllerImpl ...@@ -48,6 +50,8 @@ class LocalCardMigrationDialogControllerImpl
LocalCardMigrationDialogState view_state_; LocalCardMigrationDialogState view_state_;
LegalMessageLines legal_message_lines_;
// TODO(crbug.com/867194): Currently we will not handle the case of local // TODO(crbug.com/867194): Currently we will not handle the case of local
// cards added/deleted during migration. migratable_credit_cards_ are local // cards added/deleted during migration. migratable_credit_cards_ are local
// cards presented when the user accepts the intermediate bubble. // cards presented when the user accepts the intermediate bubble.
......
...@@ -26,6 +26,7 @@ enum DialogViewId : int { ...@@ -26,6 +26,7 @@ enum DialogViewId : int {
OK_BUTTON, // Can say [Save], [Next], [Confirm], OK_BUTTON, // Can say [Save], [Next], [Confirm],
// or [Done] depending on context // or [Done] depending on context
CANCEL_BUTTON, // Typically says [No thanks] CANCEL_BUTTON, // Typically says [No thanks]
CLOSE_BUTTON, // Typically says [Close]
MANAGE_CARDS_BUTTON, // Typicall says [Manage cards] MANAGE_CARDS_BUTTON, // Typicall says [Manage cards]
// The following are views::Link objects (clickable). // The following are views::Link objects (clickable).
......
...@@ -6,8 +6,12 @@ ...@@ -6,8 +6,12 @@
#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_VIEW_H_
#include "base/macros.h" #include "base/macros.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/autofill/local_card_migration_dialog.h" #include "chrome/browser/ui/autofill/local_card_migration_dialog.h"
#include "chrome/browser/ui/views/autofill/dialog_view_ids.h"
#include "chrome/browser/ui/views/autofill/view_util.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
#include "ui/views/controls/styled_label_listener.h"
#include "ui/views/view.h" #include "ui/views/view.h"
#include "ui/views/widget/widget_observer.h" #include "ui/views/widget/widget_observer.h"
#include "ui/views/window/dialog_delegate.h" #include "ui/views/window/dialog_delegate.h"
...@@ -28,6 +32,7 @@ class MigratableCardView; ...@@ -28,6 +32,7 @@ class MigratableCardView;
class LocalCardMigrationDialogView : public LocalCardMigrationDialog, class LocalCardMigrationDialogView : public LocalCardMigrationDialog,
public views::ButtonListener, public views::ButtonListener,
public views::StyledLabelListener,
public views::DialogDelegateView, public views::DialogDelegateView,
public views::WidgetObserver { public views::WidgetObserver {
public: public:
...@@ -44,6 +49,7 @@ class LocalCardMigrationDialogView : public LocalCardMigrationDialog, ...@@ -44,6 +49,7 @@ class LocalCardMigrationDialogView : public LocalCardMigrationDialog,
gfx::Size CalculatePreferredSize() const override; gfx::Size CalculatePreferredSize() const override;
ui::ModalType GetModalType() const override; ui::ModalType GetModalType() const override;
void AddedToWidget() override; void AddedToWidget() override;
views::View* CreateExtraView() override;
bool ShouldShowCloseButton() const override; bool ShouldShowCloseButton() const override;
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override; base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
bool IsDialogButtonEnabled(ui::DialogButton button) const override; bool IsDialogButtonEnabled(ui::DialogButton button) const override;
...@@ -56,6 +62,11 @@ class LocalCardMigrationDialogView : public LocalCardMigrationDialog, ...@@ -56,6 +62,11 @@ class LocalCardMigrationDialogView : public LocalCardMigrationDialog,
// views::ButtonListener // views::ButtonListener
void ButtonPressed(views::Button* sender, const ui::Event& event) override; void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// views::StyledLabelListener:
void StyledLabelLinkClicked(views::StyledLabel* label,
const gfx::Range& range,
int event_flags) override;
private: private:
void Init(); void Init();
base::string16 GetDialogTitle() const; base::string16 GetDialogTitle() const;
...@@ -66,25 +77,33 @@ class LocalCardMigrationDialogView : public LocalCardMigrationDialog, ...@@ -66,25 +77,33 @@ class LocalCardMigrationDialogView : public LocalCardMigrationDialog,
void OnSaveButtonClicked(); void OnSaveButtonClicked();
void OnCancelButtonClicked(); void OnCancelButtonClicked();
void OnViewCardsButtonClicked(); void OnViewCardsButtonClicked();
void OpenUrl(const GURL& url);
void SetMigrationIsPending(bool is_pending); void SetMigrationIsPending(bool is_pending);
void ShowCloseButton();
LocalCardMigrationDialogController* controller_; LocalCardMigrationDialogController* controller_;
content::WebContents* web_contents_; content::WebContents* web_contents_;
// Contains title, explanation and card scroll bar view. std::unique_ptr<views::Label> title_;
views::View* content_container_ = nullptr;
views::Label* title_ = nullptr;
views::Label* explanation_text_ = nullptr; std::unique_ptr<views::Label> explanation_text_;
// A list of MigratableCardView. // A list of MigratableCardView.
views::View* card_list_view_ = nullptr; std::unique_ptr<views::View> card_list_view_;
// Separates the card scroll bar view and the legal message. // Separates the card scroll bar view and the legal message.
views::Separator* separator_ = nullptr; std::unique_ptr<views::Separator> separator_;
// The button displays "Close". If clicked, will close the dialog
// in pending state.
std::unique_ptr<views::View> close_migration_dialog_button_;
// Timer that will call ShowCloseButton() after the migration process
// has started and is pending for acertain amount of time which can be
// configured through Finch.
base::OneShotTimer show_close_button_timer_;
std::unique_ptr<LegalMessageView> legal_message_container_;
// Whether the uploading is in progress and results are // Whether the uploading is in progress and results are
// pending. // pending.
......
...@@ -71,10 +71,13 @@ void MigratableCardView::Init( ...@@ -71,10 +71,13 @@ void MigratableCardView::Init(
views::BoxLayout::kHorizontal, gfx::Insets(), views::BoxLayout::kHorizontal, gfx::Insets(),
provider->GetDistanceMetric(DISTANCE_RELATED_CONTROL_HORIZONTAL_SMALL))); provider->GetDistanceMetric(DISTANCE_RELATED_CONTROL_HORIZONTAL_SMALL)));
checkbox_ = new views::Checkbox(base::string16()); checkbox_ = new views::Checkbox(base::string16(), listener);
checkbox_->SetChecked(migratable_credit_card.is_chosen()); checkbox_->SetChecked(migratable_credit_card.is_chosen());
checkbox_->set_tag(card_index); checkbox_->set_tag(card_index);
checkbox_->SetVisible(true); checkbox_->SetVisible(true);
// TODO(crbug/867194): Currently the ink drop animation circle is cut by the
// border of scroll bar view. Find a way to adjust the format.
checkbox_->SetInkDropMode(views::InkDropHostView::InkDropMode::OFF);
AddChildView(checkbox_); AddChildView(checkbox_);
constexpr int kMigrationResultImageSize = 16; constexpr int kMigrationResultImageSize = 16;
...@@ -107,7 +110,8 @@ void MigratableCardView::Init( ...@@ -107,7 +110,8 @@ void MigratableCardView::Init(
std::unique_ptr<views::Label> card_expiration = std::unique_ptr<views::Label> card_expiration =
std::make_unique<views::Label>(migratable_credit_card.credit_card() std::make_unique<views::Label>(migratable_credit_card.credit_card()
.AbbreviatedExpirationDateForDisplay(), .AbbreviatedExpirationDateForDisplay(),
views::style::CONTEXT_LABEL); views::style::CONTEXT_LABEL,
ChromeTextStyle::STYLE_SECONDARY);
AddChildView(card_expiration.release()); AddChildView(card_expiration.release());
delete_card_from_local_button_ = views::CreateVectorImageButton(listener); delete_card_from_local_button_ = views::CreateVectorImageButton(listener);
......
...@@ -41,23 +41,7 @@ ...@@ -41,23 +41,7 @@
namespace autofill { namespace autofill {
namespace { namespace {
const int kTooltipIconSize = 12; const int kTooltipIconSize = 12;
std::unique_ptr<views::StyledLabel> CreateLegalMessageLineLabel(
const LegalMessageLine& line,
views::StyledLabelListener* listener) {
std::unique_ptr<views::StyledLabel> label(
new views::StyledLabel(line.text(), listener));
label->SetTextContext(CONTEXT_BODY_TEXT_LARGE);
label->SetDefaultTextStyle(ChromeTextStyle::STYLE_SECONDARY);
for (const LegalMessageLine::Link& link : line.links()) {
label->AddStyleRange(link.range,
views::StyledLabel::RangeStyleInfo::CreateForLink());
}
return label;
}
} // namespace } // namespace
SaveCardOfferBubbleViews::SaveCardOfferBubbleViews( SaveCardOfferBubbleViews::SaveCardOfferBubbleViews(
...@@ -65,25 +49,17 @@ SaveCardOfferBubbleViews::SaveCardOfferBubbleViews( ...@@ -65,25 +49,17 @@ SaveCardOfferBubbleViews::SaveCardOfferBubbleViews(
const gfx::Point& anchor_point, const gfx::Point& anchor_point,
content::WebContents* web_contents, content::WebContents* web_contents,
SaveCardBubbleController* controller) SaveCardBubbleController* controller)
: SaveCardBubbleViews(anchor_view, anchor_point, web_contents, controller) { : SaveCardBubbleViews(anchor_view, anchor_point, web_contents, controller),
} web_contents_(web_contents) {}
views::View* SaveCardOfferBubbleViews::CreateFootnoteView() { views::View* SaveCardOfferBubbleViews::CreateFootnoteView() {
if (controller()->GetLegalMessageLines().empty()) if (controller()->GetLegalMessageLines().empty())
return nullptr; return nullptr;
// Use BoxLayout to provide insets around the label. footnote_view_ =
views::View* footnote_view_ = new View(); new LegalMessageView(controller()->GetLegalMessageLines(), this);
footnote_view_->SetLayoutManager(
std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical));
footnote_view_->set_id(DialogViewId::FOOTNOTE_VIEW); footnote_view_->set_id(DialogViewId::FOOTNOTE_VIEW);
// Add a StyledLabel for each line of the legal message.
for (const LegalMessageLine& line : controller()->GetLegalMessageLines()) {
footnote_view_->AddChildView(
CreateLegalMessageLineLabel(line, this).release());
}
SetFootnoteViewForTesting(footnote_view_); SetFootnoteViewForTesting(footnote_view_);
return footnote_view_; return footnote_view_;
} }
...@@ -125,25 +101,7 @@ void SaveCardOfferBubbleViews::StyledLabelLinkClicked(views::StyledLabel* label, ...@@ -125,25 +101,7 @@ void SaveCardOfferBubbleViews::StyledLabelLinkClicked(views::StyledLabel* label,
if (!controller()) if (!controller())
return; return;
// Index of |label| within its parent's view hierarchy is the same as the footnote_view_->OnLinkClicked(label, range, web_contents_);
// legal message line index. DCHECK this assumption to guard against future
// layout changes.
DCHECK_EQ(static_cast<size_t>(label->parent()->child_count()),
controller()->GetLegalMessageLines().size());
const auto& links =
controller()
->GetLegalMessageLines()[label->parent()->GetIndexOf(label)]
.links();
for (const LegalMessageLine::Link& link : links) {
if (link.range == range) {
controller()->OnLegalMessageLinkClicked(link.url);
return;
}
}
// |range| was not found.
NOTREACHED();
} }
void SaveCardOfferBubbleViews::ContentsChanged( void SaveCardOfferBubbleViews::ContentsChanged(
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h"
#include "chrome/browser/ui/views/autofill/view_util.h"
#include "ui/views/controls/styled_label_listener.h" #include "ui/views/controls/styled_label_listener.h"
#include "ui/views/controls/textfield/textfield_controller.h" #include "ui/views/controls/textfield/textfield_controller.h"
...@@ -50,8 +51,12 @@ class SaveCardOfferBubbleViews : public SaveCardBubbleViews, ...@@ -50,8 +51,12 @@ class SaveCardOfferBubbleViews : public SaveCardBubbleViews,
~SaveCardOfferBubbleViews() override; ~SaveCardOfferBubbleViews() override;
content::WebContents* web_contents_;
views::Textfield* cardholder_name_textfield_ = nullptr; views::Textfield* cardholder_name_textfield_ = nullptr;
LegalMessageView* footnote_view_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(SaveCardOfferBubbleViews); DISALLOW_COPY_AND_ASSIGN(SaveCardOfferBubbleViews);
}; };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/chrome_typography.h"
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/color_palette.h" #include "ui/gfx/color_palette.h"
...@@ -20,7 +21,9 @@ ...@@ -20,7 +21,9 @@
#include "ui/views/controls/image_view.h" #include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h" #include "ui/views/controls/label.h"
#include "ui/views/controls/separator.h" #include "ui/views/controls/separator.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/controls/textfield/textfield.h" #include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/grid_layout.h" #include "ui/views/layout/grid_layout.h"
#include "ui/views/layout/layout_provider.h" #include "ui/views/layout/layout_provider.h"
#include "ui/views/style/typography.h" #include "ui/views/style/typography.h"
...@@ -96,6 +99,8 @@ TitleWithIconAndSeparatorView::TitleWithIconAndSeparatorView( ...@@ -96,6 +99,8 @@ TitleWithIconAndSeparatorView::TitleWithIconAndSeparatorView(
/*right=*/separator_horizontal_padding)); /*right=*/separator_horizontal_padding));
} }
TitleWithIconAndSeparatorView::~TitleWithIconAndSeparatorView() {}
gfx::Size TitleWithIconAndSeparatorView::GetMinimumSize() const { gfx::Size TitleWithIconAndSeparatorView::GetMinimumSize() const {
// View::GetMinumumSize() defaults to GridLayout::GetPreferredSize(), but that // View::GetMinumumSize() defaults to GridLayout::GetPreferredSize(), but that
// gives a larger frame width, so the dialog will become wider than it should. // gives a larger frame width, so the dialog will become wider than it should.
...@@ -112,4 +117,55 @@ views::Textfield* CreateCvcTextfield() { ...@@ -112,4 +117,55 @@ views::Textfield* CreateCvcTextfield() {
return textfield; return textfield;
} }
LegalMessageView::LegalMessageView(const LegalMessageLines& legal_message_lines,
views::StyledLabelListener* listener)
: legal_message_lines_(legal_message_lines) {
SetLayoutManager(
std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical));
for (const LegalMessageLine& line : legal_message_lines) {
AddChildView(CreateLegalMessageLineLabel(line, listener).release());
}
}
LegalMessageView::~LegalMessageView() {}
std::unique_ptr<views::StyledLabel>
LegalMessageView::CreateLegalMessageLineLabel(
const LegalMessageLine& line,
views::StyledLabelListener* listener) {
std::unique_ptr<views::StyledLabel> label(
new views::StyledLabel(line.text(), listener));
label->SetTextContext(CONTEXT_BODY_TEXT_LARGE);
label->SetDefaultTextStyle(ChromeTextStyle::STYLE_SECONDARY);
for (const LegalMessageLine::Link& link : line.links()) {
label->AddStyleRange(link.range,
views::StyledLabel::RangeStyleInfo::CreateForLink());
}
return label;
}
void LegalMessageView::OnLinkClicked(views::StyledLabel* label,
const gfx::Range& range,
content::WebContents* web_contents) {
// Index of |label| within its parent's view hierarchy is the same as the
// legal message line index. DCHECK this assumption to guard against future
// layout changes.
DCHECK_EQ(static_cast<size_t>(label->parent()->child_count()),
legal_message_lines_.size());
const std::vector<LegalMessageLine::Link>& links =
legal_message_lines_[label->parent()->GetIndexOf(label)].links();
for (const LegalMessageLine::Link& link : links) {
if (link.range == range) {
web_contents->OpenURL(content::OpenURLParams(
link.url, content::Referrer(),
WindowOpenDisposition::NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK,
/*is_renderer_initiated=*/false));
return;
}
}
// |range| was not found.
NOTREACHED();
}
} // namespace autofill } // namespace autofill
...@@ -6,9 +6,13 @@ ...@@ -6,9 +6,13 @@
#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_VIEW_UTIL_H_ #define CHROME_BROWSER_UI_VIEWS_AUTOFILL_VIEW_UTIL_H_
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "components/autofill/core/browser/legal_message_line.h"
#include "content/public/browser/web_contents.h"
#include "ui/views/controls/styled_label_listener.h"
#include "ui/views/view.h" #include "ui/views/view.h"
namespace views { namespace views {
class StyledLabel;
class Textfield; class Textfield;
} // namespace views } // namespace views
...@@ -20,7 +24,7 @@ namespace autofill { ...@@ -20,7 +24,7 @@ namespace autofill {
class TitleWithIconAndSeparatorView : public views::View { class TitleWithIconAndSeparatorView : public views::View {
public: public:
explicit TitleWithIconAndSeparatorView(const base::string16& window_title); explicit TitleWithIconAndSeparatorView(const base::string16& window_title);
~TitleWithIconAndSeparatorView() override = default; ~TitleWithIconAndSeparatorView() override;
private: private:
// views::View: // views::View:
...@@ -30,6 +34,26 @@ class TitleWithIconAndSeparatorView : public views::View { ...@@ -30,6 +34,26 @@ class TitleWithIconAndSeparatorView : public views::View {
// Creates and returns a small Textfield intended to be used for CVC entry. // Creates and returns a small Textfield intended to be used for CVC entry.
views::Textfield* CreateCvcTextfield(); views::Textfield* CreateCvcTextfield();
// Defines a view with legal message. This class handles the legal message
// parsing and the links clicking events.
class LegalMessageView : public views::View {
public:
explicit LegalMessageView(const LegalMessageLines& legal_message_lines,
views::StyledLabelListener* listener);
~LegalMessageView() override;
void OnLinkClicked(views::StyledLabel* label,
const gfx::Range& range,
content::WebContents* web_contents);
private:
std::unique_ptr<views::StyledLabel> CreateLegalMessageLineLabel(
const LegalMessageLine& line,
views::StyledLabelListener* listener);
LegalMessageLines legal_message_lines_;
};
} // namespace autofill } // namespace autofill
#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_VIEW_UTIL_H_ #endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_VIEW_UTIL_H_
...@@ -144,9 +144,11 @@ class AutofillClient : public RiskDataLoader { ...@@ -144,9 +144,11 @@ class AutofillClient : public RiskDataLoader {
virtual void ShowLocalCardMigrationDialog( virtual void ShowLocalCardMigrationDialog(
base::OnceClosure show_migration_dialog_closure) = 0; base::OnceClosure show_migration_dialog_closure) = 0;
// Runs |closure| if the user would like the selected // Shows a dialog with the given |legal_message|. Runs |closure| if
// |migratable_credit_cards| to be uploaded to cloud. // the user would like the selected |migratable_credit_cards| to be
// uploaded to cloud.
virtual void ConfirmMigrateLocalCardToCloud( virtual void ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<MigratableCreditCard>& migratable_credit_cards, std::vector<MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) = 0; base::OnceClosure start_migrating_cards_closure) = 0;
......
...@@ -208,7 +208,7 @@ void LocalCardMigrationManager::ShowMainMigrationDialog() { ...@@ -208,7 +208,7 @@ void LocalCardMigrationManager::ShowMainMigrationDialog() {
user_accepted_main_migration_dialog_ = false; user_accepted_main_migration_dialog_ = false;
// Pops up a larger, modal dialog showing the local cards to be uploaded. // Pops up a larger, modal dialog showing the local cards to be uploaded.
client_->ConfirmMigrateLocalCardToCloud( client_->ConfirmMigrateLocalCardToCloud(
migratable_credit_cards_, std::move(legal_message_), migratable_credit_cards_,
base::BindOnce( base::BindOnce(
&LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog, &LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
......
...@@ -77,6 +77,7 @@ void TestAutofillClient::ShowLocalCardMigrationDialog( ...@@ -77,6 +77,7 @@ void TestAutofillClient::ShowLocalCardMigrationDialog(
} }
void TestAutofillClient::ConfirmMigrateLocalCardToCloud( void TestAutofillClient::ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<MigratableCreditCard>& migratable_credit_cards, std::vector<MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) { base::OnceClosure start_migrating_cards_closure) {
std::move(start_migrating_cards_closure).Run(); std::move(start_migrating_cards_closure).Run();
......
...@@ -45,6 +45,7 @@ class TestAutofillClient : public AutofillClient { ...@@ -45,6 +45,7 @@ class TestAutofillClient : public AutofillClient {
void ShowLocalCardMigrationDialog( void ShowLocalCardMigrationDialog(
base::OnceClosure show_migration_dialog_closure) override; base::OnceClosure show_migration_dialog_closure) override;
void ConfirmMigrateLocalCardToCloud( void ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<MigratableCreditCard>& migratable_credit_cards, std::vector<MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) override; base::OnceClosure start_migrating_cards_closure) override;
void ConfirmSaveAutofillProfile(const AutofillProfile& profile, void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "components/autofill/core/browser/legal_message_line.h"
namespace autofill { namespace autofill {
...@@ -30,6 +31,7 @@ class LocalCardMigrationDialogController { ...@@ -30,6 +31,7 @@ class LocalCardMigrationDialogController {
// TODO(crbug.com/867194): Ensure this would not be called when migration is // TODO(crbug.com/867194): Ensure this would not be called when migration is
// happending. // happending.
virtual void SetCardList(std::vector<MigratableCreditCard>& card_list) = 0; virtual void SetCardList(std::vector<MigratableCreditCard>& card_list) = 0;
virtual const LegalMessageLines& GetLegalMessageLines() const = 0;
virtual void OnCardSelected(int index) = 0; virtual void OnCardSelected(int index) = 0;
virtual void OnDialogClosed() = 0; virtual void OnDialogClosed() = 0;
......
...@@ -102,6 +102,11 @@ const base::Feature kAutofillEnforceMinRequiredFieldsForUpload{ ...@@ -102,6 +102,11 @@ const base::Feature kAutofillEnforceMinRequiredFieldsForUpload{
const base::Feature kAutofillExpandedPopupViews{ const base::Feature kAutofillExpandedPopupViews{
"AutofillExpandedPopupViews", base::FEATURE_DISABLED_BY_DEFAULT}; "AutofillExpandedPopupViews", base::FEATURE_DISABLED_BY_DEFAULT};
// Controls whether Autofill Local Card Migration will show result dialogs.
const base::Feature kAutofillLocalCardMigrationShowFeedback{
"AutofillLocalCardMigrationShowFeedback",
base::FEATURE_DISABLED_BY_DEFAULT};
// Controls whether the manual fill fallback will be present. // Controls whether the manual fill fallback will be present.
const base::Feature kAutofillManualFallback{"AutofillManualFallback", const base::Feature kAutofillManualFallback{"AutofillManualFallback",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
...@@ -258,6 +263,9 @@ const base::Feature kAutomaticPasswordGeneration = { ...@@ -258,6 +263,9 @@ const base::Feature kAutomaticPasswordGeneration = {
const base::Feature kSingleClickAutofill{"SingleClickAutofill", const base::Feature kSingleClickAutofill{"SingleClickAutofill",
base::FEATURE_ENABLED_BY_DEFAULT}; base::FEATURE_ENABLED_BY_DEFAULT};
const char kAutofillLocalCardMigrationCloseButtonDelay[] =
"show_close_migration_dialog_button_delay";
const char kAutofillCreditCardLocalCardMigrationParameterName[] = "variant"; const char kAutofillCreditCardLocalCardMigrationParameterName[] = "variant";
const char kAutofillCreditCardLocalCardMigrationParameterWithoutSettingsPage[] = const char kAutofillCreditCardLocalCardMigrationParameterWithoutSettingsPage[] =
...@@ -293,6 +301,14 @@ LocalCardMigrationExperimentalFlag GetLocalCardMigrationExperimentalFlag() { ...@@ -293,6 +301,14 @@ LocalCardMigrationExperimentalFlag GetLocalCardMigrationExperimentalFlag() {
return LocalCardMigrationExperimentalFlag::kMigrationIncludeSettingsPage; return LocalCardMigrationExperimentalFlag::kMigrationIncludeSettingsPage;
} }
base::TimeDelta GetTimeoutForMigrationPromptFeedbackCloseButton() {
constexpr int show_close_button_timeout_in_seconds = 5;
return base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
kAutofillCreditCardLocalCardMigration,
kAutofillLocalCardMigrationCloseButtonDelay,
show_close_button_timeout_in_seconds));
}
bool IsAutofillUpstreamAlwaysRequestCardholderNameExperimentEnabled() { bool IsAutofillUpstreamAlwaysRequestCardholderNameExperimentEnabled() {
return base::FeatureList::IsEnabled( return base::FeatureList::IsEnabled(
features::kAutofillUpstreamAlwaysRequestCardholderName); features::kAutofillUpstreamAlwaysRequestCardholderName);
......
...@@ -39,6 +39,7 @@ extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics; ...@@ -39,6 +39,7 @@ extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery; extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload; extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload;
extern const base::Feature kAutofillExpandedPopupViews; extern const base::Feature kAutofillExpandedPopupViews;
extern const base::Feature kAutofillLocalCardMigrationShowFeedback;
extern const base::Feature kAutofillManualFallback; extern const base::Feature kAutofillManualFallback;
extern const base::Feature kAutofillPreferServerNamePredictions; extern const base::Feature kAutofillPreferServerNamePredictions;
extern const base::Feature kAutofillNoLocalSaveOnUploadSuccess; extern const base::Feature kAutofillNoLocalSaveOnUploadSuccess;
...@@ -76,6 +77,7 @@ extern const base::Feature kAutomaticPasswordGeneration; ...@@ -76,6 +77,7 @@ extern const base::Feature kAutomaticPasswordGeneration;
extern const base::Feature kSingleClickAutofill; extern const base::Feature kSingleClickAutofill;
extern const base::Feature kAutofillCreditCardLocalCardMigration; extern const base::Feature kAutofillCreditCardLocalCardMigration;
extern const char kAutofillCreditCardLastUsedDateShowExpirationDateKey[]; extern const char kAutofillCreditCardLastUsedDateShowExpirationDateKey[];
extern const char kAutofillLocalCardMigrationCloseButtonDelay[];
extern const char kAutofillCreditCardLocalCardMigrationParameterName[]; extern const char kAutofillCreditCardLocalCardMigrationParameterName[];
extern const char kAutofillUpstreamMaxMinutesSinceAutofillProfileUseKey[]; extern const char kAutofillUpstreamMaxMinutesSinceAutofillProfileUseKey[];
extern const char kCreditCardSigninPromoImpressionLimitParamKey[]; extern const char kCreditCardSigninPromoImpressionLimitParamKey[];
...@@ -106,6 +108,10 @@ enum class LocalCardMigrationExperimentalFlag { ...@@ -106,6 +108,10 @@ enum class LocalCardMigrationExperimentalFlag {
// settings page migration. // settings page migration.
LocalCardMigrationExperimentalFlag GetLocalCardMigrationExperimentalFlag(); LocalCardMigrationExperimentalFlag GetLocalCardMigrationExperimentalFlag();
// Returns the time delay for the local card migration dialog to show the close
// button.
base::TimeDelta GetTimeoutForMigrationPromptFeedbackCloseButton();
// For testing purposes; not to be launched. When enabled, Chrome Upstream // For testing purposes; not to be launched. When enabled, Chrome Upstream
// always requests that the user enters/confirms cardholder name in the // always requests that the user enters/confirms cardholder name in the
// offer-to-save dialog, regardless of if it was present or if the user is a // offer-to-save dialog, regardless of if it was present or if the user is a
......
...@@ -59,6 +59,7 @@ class ChromeAutofillClientIOS : public AutofillClient { ...@@ -59,6 +59,7 @@ class ChromeAutofillClientIOS : public AutofillClient {
void ShowLocalCardMigrationDialog( void ShowLocalCardMigrationDialog(
base::OnceClosure show_migration_dialog_closure) override; base::OnceClosure show_migration_dialog_closure) override;
void ConfirmMigrateLocalCardToCloud( void ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<MigratableCreditCard>& migratable_credit_cards, std::vector<MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) override; base::OnceClosure start_migrating_cards_closure) override;
void ConfirmSaveAutofillProfile(const AutofillProfile& profile, void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
......
...@@ -176,6 +176,7 @@ void ChromeAutofillClientIOS::ShowLocalCardMigrationDialog( ...@@ -176,6 +176,7 @@ void ChromeAutofillClientIOS::ShowLocalCardMigrationDialog(
} }
void ChromeAutofillClientIOS::ConfirmMigrateLocalCardToCloud( void ChromeAutofillClientIOS::ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<MigratableCreditCard>& migratable_credit_cards, std::vector<MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) { base::OnceClosure start_migrating_cards_closure) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
......
...@@ -52,6 +52,7 @@ class WebViewAutofillClientIOS : public AutofillClient { ...@@ -52,6 +52,7 @@ class WebViewAutofillClientIOS : public AutofillClient {
void ShowLocalCardMigrationDialog( void ShowLocalCardMigrationDialog(
base::OnceClosure show_migration_dialog_closure) override; base::OnceClosure show_migration_dialog_closure) override;
void ConfirmMigrateLocalCardToCloud( void ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<MigratableCreditCard>& migratable_credit_cards, std::vector<MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) override; base::OnceClosure start_migrating_cards_closure) override;
void ConfirmSaveAutofillProfile(const AutofillProfile& profile, void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
......
...@@ -97,6 +97,7 @@ void WebViewAutofillClientIOS::ShowLocalCardMigrationDialog( ...@@ -97,6 +97,7 @@ void WebViewAutofillClientIOS::ShowLocalCardMigrationDialog(
} }
void WebViewAutofillClientIOS::ConfirmMigrateLocalCardToCloud( void WebViewAutofillClientIOS::ConfirmMigrateLocalCardToCloud(
std::unique_ptr<base::DictionaryValue> legal_message,
std::vector<MigratableCreditCard>& migratable_credit_cards, std::vector<MigratableCreditCard>& migratable_credit_cards,
base::OnceClosure start_migrating_cards_closure) { base::OnceClosure start_migrating_cards_closure) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
......
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