Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: chrome/browser/ui/views/autofill/save_card_bubble_views.cc

Issue 2955963002: Update Chrome Upstream flow to reflect new UI mocks (Closed)
Patch Set: Code review changes Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" 5 #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 SaveCardBubbleController* controller) 56 SaveCardBubbleController* controller)
57 : LocationBarBubbleDelegateView(anchor_view, web_contents), 57 : LocationBarBubbleDelegateView(anchor_view, web_contents),
58 controller_(controller) { 58 controller_(controller) {
59 DCHECK(controller); 59 DCHECK(controller);
60 views::BubbleDialogDelegateView::CreateBubble(this); 60 views::BubbleDialogDelegateView::CreateBubble(this);
61 chrome::RecordDialogCreation(chrome::DialogIdentifier::SAVE_CARD); 61 chrome::RecordDialogCreation(chrome::DialogIdentifier::SAVE_CARD);
62 } 62 }
63 63
64 SaveCardBubbleViews::~SaveCardBubbleViews() {} 64 SaveCardBubbleViews::~SaveCardBubbleViews() {}
65 65
66 SaveCardBubbleViews::CurrentFlowStep SaveCardBubbleViews::GetCurrentFlowStep()
67 const {
68 // No legal messages means this is not upload save.
69 if (controller_->GetLegalMessageLines().empty())
70 return LOCAL_SAVE_ONLY_STEP;
71 // If we're not requesting CVC, this is the only step on the upload path.
72 if (!controller_->ShouldRequestCvcFromUser())
73 return UPLOAD_SAVE_ONLY_STEP;
74 // Must be on the CVC fix flow on the upload path.
75 if (view_stack_->size() == 1)
76 return UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD;
77 if (view_stack_->size() == 2)
78 return UPLOAD_SAVE_CVC_FIX_FLOW_STEP_2_REQUEST_CVC;
79 // CVC fix flow should never have more than 3 views on the stack.
80 NOTREACHED();
81 return UNKNOWN_STEP;
82 }
83
66 void SaveCardBubbleViews::Show(DisplayReason reason) { 84 void SaveCardBubbleViews::Show(DisplayReason reason) {
67 ShowForReason(reason); 85 ShowForReason(reason);
68 } 86 }
69 87
70 void SaveCardBubbleViews::Hide() { 88 void SaveCardBubbleViews::Hide() {
71 controller_ = nullptr; 89 controller_ = nullptr;
72 CloseBubble(); 90 CloseBubble();
73 } 91 }
74 92
75 views::View* SaveCardBubbleViews::CreateExtraView() { 93 views::View* SaveCardBubbleViews::CreateExtraView() {
94 if (GetCurrentFlowStep() != LOCAL_SAVE_ONLY_STEP)
95 return nullptr;
96 // Learn More link is only shown on local save bubble.
76 DCHECK(!learn_more_link_); 97 DCHECK(!learn_more_link_);
77 learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); 98 learn_more_link_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
78 learn_more_link_->SetUnderline(false); 99 learn_more_link_->SetUnderline(false);
79 learn_more_link_->set_listener(this); 100 learn_more_link_->set_listener(this);
80 return learn_more_link_; 101 return learn_more_link_;
81 } 102 }
82 103
104 int SaveCardBubbleViews::GetDialogButtons() const {
105 if (GetCurrentFlowStep() == LOCAL_SAVE_ONLY_STEP)
106 return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
107 // For upload save, don't show the "No thanks" cancel option; use the
108 // top-right [X] close button for that.
109 return ui::DIALOG_BUTTON_OK;
110 }
111
83 views::View* SaveCardBubbleViews::CreateFootnoteView() { 112 views::View* SaveCardBubbleViews::CreateFootnoteView() {
84 if (controller_->GetLegalMessageLines().empty()) 113 if (controller_->GetLegalMessageLines().empty())
85 return nullptr; 114 return nullptr;
86 115
87 // Use BoxLayout to provide insets around the label. 116 // Use BoxLayout to provide insets around the label.
88 View* view = new View(); 117 footnote_view_ = new View();
89 view->SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical)); 118 footnote_view_->SetLayoutManager(
119 new views::BoxLayout(views::BoxLayout::kVertical));
90 120
91 // Add a StyledLabel for each line of the legal message. 121 // Add a StyledLabel for each line of the legal message.
92 for (const LegalMessageLine& line : controller_->GetLegalMessageLines()) 122 for (const LegalMessageLine& line : controller_->GetLegalMessageLines())
93 view->AddChildView(CreateLegalMessageLineLabel(line, this).release()); 123 footnote_view_->AddChildView(
124 CreateLegalMessageLineLabel(line, this).release());
94 125
95 return view; 126 // If on the first step of the 2-step upload flow, hide the footer area until
127 // it's time to actually accept the dialog and ToS.
128 if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD)
129 footnote_view_->SetVisible(false);
130
131 return footnote_view_;
96 } 132 }
97 133
98 bool SaveCardBubbleViews::Accept() { 134 bool SaveCardBubbleViews::Accept() {
99 // The main content ViewStack for local save and happy-path upload save should 135 // The main content ViewStack for local save and happy-path upload save should
100 // only ever have 1 View on it. Upload save can have a second View if CVC 136 // only ever have 1 View on it. Upload save can have a second View if CVC
101 // needs to be requested. Assert that the ViewStack has no more than 2 Views 137 // needs to be requested. Assert that the ViewStack has no more than 2 Views
102 // and that if it *does* have 2, it's because CVC is being requested. 138 // and that if it *does* have 2, it's because CVC is being requested.
103 DCHECK_LE(view_stack_->size(), 2U); 139 DCHECK_LE(view_stack_->size(), 2U);
104 DCHECK(view_stack_->size() == 1 || controller_->ShouldRequestCvcFromUser()); 140 DCHECK(view_stack_->size() == 1 || controller_->ShouldRequestCvcFromUser());
105 if (controller_->ShouldRequestCvcFromUser() && view_stack_->size() == 1) { 141 if (GetCurrentFlowStep() == UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD) {
106 // If user accepted upload but more info is needed, push the next view onto 142 // If user accepted upload but more info is needed, push the next view onto
107 // the stack. 143 // the stack and update the bubble.
144 DCHECK(controller_);
145 controller_->SetShowUploadConfirmTitle(true);
146 GetWidget()->UpdateWindowTitle();
108 view_stack_->Push(CreateRequestCvcView(), /*animate=*/true); 147 view_stack_->Push(CreateRequestCvcView(), /*animate=*/true);
109 // Disable the Save button until a valid CVC is entered: 148 // Disable the Save button until a valid CVC is entered:
110 GetDialogClientView()->UpdateDialogButtons(); 149 GetDialogClientView()->UpdateDialogButtons();
150 // Make the legal messaging footer appear:
151 DCHECK(footnote_view_);
152 footnote_view_->SetVisible(true);
111 // Resize the bubble if it's grown larger: 153 // Resize the bubble if it's grown larger:
112 SizeToContents(); 154 SizeToContents();
113 return false; 155 return false;
114 } 156 }
115 // Otherwise, close the bubble as normal. 157 // Otherwise, close the bubble as normal.
116 if (controller_) 158 if (controller_)
117 controller_->OnSaveButton(cvc_textfield_ ? cvc_textfield_->text() 159 controller_->OnSaveButton(cvc_textfield_ ? cvc_textfield_->text()
118 : base::string16()); 160 : base::string16());
119 return true; 161 return true;
120 } 162 }
121 163
122 bool SaveCardBubbleViews::Cancel() { 164 bool SaveCardBubbleViews::Cancel() {
123 if (controller_) 165 if (controller_)
124 controller_->OnCancelButton(); 166 controller_->OnCancelButton();
125 return true; 167 return true;
126 } 168 }
127 169
128 bool SaveCardBubbleViews::Close() { 170 bool SaveCardBubbleViews::Close() {
129 // Cancel is logged as a different user action than closing, so override 171 // Cancel is logged as a different user action than closing, so override
130 // Close() to prevent the superclass' implementation from calling Cancel(). 172 // Close() to prevent the superclass' implementation from calling Cancel().
131 // Return true to indicate that the bubble can be closed. 173 // Return true to indicate that the bubble can be closed.
132 return true; 174 return true;
133 } 175 }
134 176
135 base::string16 SaveCardBubbleViews::GetDialogButtonLabel( 177 base::string16 SaveCardBubbleViews::GetDialogButtonLabel(
136 ui::DialogButton button) const { 178 ui::DialogButton button) const {
137 return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK 179 switch (GetCurrentFlowStep()) {
138 ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT 180 // Local save has two buttons:
139 : IDS_NO_THANKS); 181 case LOCAL_SAVE_ONLY_STEP:
182 return l10n_util::GetStringUTF16(
183 button == ui::DIALOG_BUTTON_OK ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT
184 : IDS_NO_THANKS);
185 // Upload save has one button but it can say three different things:
186 case UPLOAD_SAVE_ONLY_STEP:
187 DCHECK(button == ui::DIALOG_BUTTON_OK);
188 return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT);
189 case UPLOAD_SAVE_CVC_FIX_FLOW_STEP_1_OFFER_UPLOAD:
190 DCHECK(button == ui::DIALOG_BUTTON_OK);
191 return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_NEXT);
192 case UPLOAD_SAVE_CVC_FIX_FLOW_STEP_2_REQUEST_CVC:
193 DCHECK(button == ui::DIALOG_BUTTON_OK);
194 return l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_CONFIRM);
195 default:
196 NOTREACHED();
197 return base::string16();
198 }
140 } 199 }
141 200
142 gfx::Size SaveCardBubbleViews::CalculatePreferredSize() const { 201 gfx::Size SaveCardBubbleViews::CalculatePreferredSize() const {
143 return gfx::Size(kBubbleWidth, GetHeightForWidth(kBubbleWidth)); 202 return gfx::Size(kBubbleWidth, GetHeightForWidth(kBubbleWidth));
144 } 203 }
145 204
205 bool SaveCardBubbleViews::ShouldShowCloseButton() const {
206 // Local save should have a [No thanks] button, but Upload save should surface
207 // the top-right [X] close button instead.
208 return GetCurrentFlowStep() != LOCAL_SAVE_ONLY_STEP;
209 }
210
146 base::string16 SaveCardBubbleViews::GetWindowTitle() const { 211 base::string16 SaveCardBubbleViews::GetWindowTitle() const {
147 return controller_ ? controller_->GetWindowTitle() : base::string16(); 212 return controller_ ? controller_->GetWindowTitle() : base::string16();
148 } 213 }
149 214
150 void SaveCardBubbleViews::WindowClosing() { 215 void SaveCardBubbleViews::WindowClosing() {
151 if (controller_) 216 if (controller_)
152 controller_->OnBubbleClosed(); 217 controller_->OnBubbleClosed();
153 } 218 }
154 219
155 void SaveCardBubbleViews::LinkClicked(views::Link* source, int event_flags) { 220 void SaveCardBubbleViews::LinkClicked(views::Link* source, int event_flags) {
(...skipping 30 matching lines...) Expand all
186 251
187 // Create view containing everything except for the footnote. 252 // Create view containing everything except for the footnote.
188 std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() { 253 std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() {
189 auto view = base::MakeUnique<views::View>(); 254 auto view = base::MakeUnique<views::View>();
190 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); 255 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
191 256
192 view->SetLayoutManager(new views::BoxLayout( 257 view->SetLayoutManager(new views::BoxLayout(
193 views::BoxLayout::kVertical, gfx::Insets(), 258 views::BoxLayout::kVertical, gfx::Insets(),
194 provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); 259 provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL)));
195 260
261 // If applicable, add the upload explanation label.
262 base::string16 explanation = controller_->GetExplanatoryMessage();
263 if (!explanation.empty()) {
264 views::Label* explanation_label = new views::Label(explanation);
265 explanation_label->SetMultiLine(true);
266 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
267 view->AddChildView(explanation_label);
268 }
269
196 // Add the card type icon, last four digits and expiration date. 270 // Add the card type icon, last four digits and expiration date.
197 views::View* description_view = new views::View(); 271 views::View* description_view = new views::View();
198 description_view->SetLayoutManager(new views::BoxLayout( 272 description_view->SetLayoutManager(new views::BoxLayout(
199 views::BoxLayout::kHorizontal, gfx::Insets(), 273 views::BoxLayout::kHorizontal, gfx::Insets(),
200 provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL))); 274 provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL)));
201 view->AddChildView(description_view); 275 view->AddChildView(description_view);
202 276
203 const CreditCard& card = controller_->GetCard(); 277 const CreditCard& card = controller_->GetCard();
204 views::ImageView* card_type_icon = new views::ImageView(); 278 views::ImageView* card_type_icon = new views::ImageView();
205 card_type_icon->SetImage( 279 card_type_icon->SetImage(
206 ResourceBundle::GetSharedInstance() 280 ResourceBundle::GetSharedInstance()
207 .GetImageNamed(CreditCard::IconResourceId(card.network())) 281 .GetImageNamed(CreditCard::IconResourceId(card.network()))
208 .AsImageSkia()); 282 .AsImageSkia());
209 card_type_icon->SetTooltipText(card.NetworkForDisplay()); 283 card_type_icon->SetTooltipText(card.NetworkForDisplay());
210 card_type_icon->SetBorder( 284 card_type_icon->SetBorder(
211 views::CreateSolidBorder(1, SkColorSetA(SK_ColorBLACK, 10))); 285 views::CreateSolidBorder(1, SkColorSetA(SK_ColorBLACK, 10)));
212 description_view->AddChildView(card_type_icon); 286 description_view->AddChildView(card_type_icon);
213 287
214 description_view->AddChildView(new views::Label( 288 description_view->AddChildView(new views::Label(
215 base::string16(kMidlineEllipsis) + card.LastFourDigits())); 289 base::string16(kMidlineEllipsis) + card.LastFourDigits()));
216 description_view->AddChildView( 290 description_view->AddChildView(
217 new views::Label(card.AbbreviatedExpirationDateForDisplay())); 291 new views::Label(card.AbbreviatedExpirationDateForDisplay()));
218 292
219 // Optionally add label that will contain an explanation for upload.
220 base::string16 explanation = controller_->GetExplanatoryMessage();
221 if (!explanation.empty()) {
222 views::Label* explanation_label = new views::Label(explanation);
223 explanation_label->SetMultiLine(true);
224 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
225 view->AddChildView(explanation_label);
226 }
227
228 return view; 293 return view;
229 } 294 }
230 295
231 std::unique_ptr<views::View> SaveCardBubbleViews::CreateRequestCvcView() { 296 std::unique_ptr<views::View> SaveCardBubbleViews::CreateRequestCvcView() {
232 auto request_cvc_view = base::MakeUnique<views::View>(); 297 auto request_cvc_view = base::MakeUnique<views::View>();
298 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
299
300 request_cvc_view->SetLayoutManager(new views::BoxLayout(
301 views::BoxLayout::kVertical, gfx::Insets(),
302 provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL)));
233 request_cvc_view->SetBackground(views::CreateThemedSolidBackground( 303 request_cvc_view->SetBackground(views::CreateThemedSolidBackground(
234 request_cvc_view.get(), ui::NativeTheme::kColorId_BubbleBackground)); 304 request_cvc_view.get(), ui::NativeTheme::kColorId_BubbleBackground));
305
306 views::Label* explanation_label = new views::Label(l10n_util::GetStringUTF16(
307 IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC_EXPLANATION));
308 explanation_label->SetMultiLine(true);
309 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
310 request_cvc_view->AddChildView(explanation_label);
311
312 views::View* cvc_entry_view = new views::View();
235 views::BoxLayout* layout = 313 views::BoxLayout* layout =
236 new views::BoxLayout(views::BoxLayout::kHorizontal, gfx::Insets(), 314 new views::BoxLayout(views::BoxLayout::kHorizontal, gfx::Insets(),
237 ChromeLayoutProvider::Get()->GetDistanceMetric( 315 ChromeLayoutProvider::Get()->GetDistanceMetric(
Mathieu 2017/06/27 21:12:06 use |provider| here?
Jared Saul 2017/06/27 21:45:55 Good catch; done.
238 views::DISTANCE_RELATED_BUTTON_HORIZONTAL)); 316 views::DISTANCE_RELATED_BUTTON_HORIZONTAL));
239 layout->set_cross_axis_alignment( 317 layout->set_cross_axis_alignment(
240 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); 318 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
241 request_cvc_view->SetLayoutManager(layout); 319 cvc_entry_view->SetLayoutManager(layout);
242 320
243 DCHECK(!cvc_textfield_); 321 DCHECK(!cvc_textfield_);
244 cvc_textfield_ = CreateCvcTextfield(); 322 cvc_textfield_ = CreateCvcTextfield();
245 cvc_textfield_->set_controller(this); 323 cvc_textfield_->set_controller(this);
246 request_cvc_view->AddChildView(cvc_textfield_); 324 cvc_entry_view->AddChildView(cvc_textfield_);
247 325
248 views::ImageView* cvc_image = new views::ImageView(); 326 views::ImageView* cvc_image = new views::ImageView();
249 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 327 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
250 cvc_image->SetImage( 328 cvc_image->SetImage(
251 rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId())); 329 rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId()));
252 request_cvc_view->AddChildView(cvc_image); 330 cvc_entry_view->AddChildView(cvc_image);
253 331
254 request_cvc_view->AddChildView(new views::Label( 332 request_cvc_view->AddChildView(cvc_entry_view);
255 l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC)));
256
257 return request_cvc_view; 333 return request_cvc_view;
258 } 334 }
259 335
260 bool SaveCardBubbleViews::IsDialogButtonEnabled(ui::DialogButton button) const { 336 bool SaveCardBubbleViews::IsDialogButtonEnabled(ui::DialogButton button) const {
261 if (button == ui::DIALOG_BUTTON_CANCEL) 337 if (button == ui::DIALOG_BUTTON_CANCEL)
262 return true; 338 return true;
263 339
264 DCHECK_EQ(ui::DIALOG_BUTTON_OK, button); 340 DCHECK_EQ(ui::DIALOG_BUTTON_OK, button);
265 return !cvc_textfield_ || 341 return !cvc_textfield_ ||
266 controller_->InputCvcIsValid(cvc_textfield_->text()); 342 controller_->InputCvcIsValid(cvc_textfield_->text());
267 } 343 }
268 344
269 void SaveCardBubbleViews::ContentsChanged(views::Textfield* sender, 345 void SaveCardBubbleViews::ContentsChanged(views::Textfield* sender,
270 const base::string16& new_contents) { 346 const base::string16& new_contents) {
271 DCHECK_EQ(cvc_textfield_, sender); 347 DCHECK_EQ(cvc_textfield_, sender);
272 GetDialogClientView()->UpdateDialogButtons(); 348 GetDialogClientView()->UpdateDialogButtons();
273 } 349 }
274 350
275 void SaveCardBubbleViews::Init() { 351 void SaveCardBubbleViews::Init() {
276 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical)); 352 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical));
277 view_stack_ = new ViewStack(); 353 view_stack_ = new ViewStack();
278 view_stack_->SetBackground(views::CreateThemedSolidBackground( 354 view_stack_->SetBackground(views::CreateThemedSolidBackground(
279 view_stack_, ui::NativeTheme::kColorId_BubbleBackground)); 355 view_stack_, ui::NativeTheme::kColorId_BubbleBackground));
280 view_stack_->Push(CreateMainContentView(), /*animate=*/false); 356 view_stack_->Push(CreateMainContentView(), /*animate=*/false);
281 AddChildView(view_stack_); 357 AddChildView(view_stack_);
282 } 358 }
283 359
284 } // namespace autofill 360 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698