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

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

Issue 2883273005: Use ViewStack to convert card upload request CVC experiment to 2-step flow (Closed)
Patch Set: Created 3 years, 7 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"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 #include "chrome/browser/ui/browser_dialogs.h" 12 #include "chrome/browser/ui/browser_dialogs.h"
13 #include "chrome/browser/ui/views/autofill/view_util.h" 13 #include "chrome/browser/ui/views/autofill/view_util.h"
14 #include "chrome/browser/ui/views/payments/view_stack.h"
Mathieu 2017/05/17 23:53:01 no need
Jared Saul 2017/05/18 17:01:23 Done.
14 #include "components/autofill/core/browser/credit_card.h" 15 #include "components/autofill/core/browser/credit_card.h"
15 #include "components/autofill/core/browser/legal_message_line.h" 16 #include "components/autofill/core/browser/legal_message_line.h"
16 #include "components/autofill/core/browser/ui/save_card_bubble_controller.h" 17 #include "components/autofill/core/browser/ui/save_card_bubble_controller.h"
17 #include "components/strings/grit/components_strings.h" 18 #include "components/strings/grit/components_strings.h"
18 #include "ui/base/l10n/l10n_util.h" 19 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/resource/resource_bundle.h" 20 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/views/border.h" 21 #include "ui/views/border.h"
21 #include "ui/views/bubble/bubble_frame_view.h" 22 #include "ui/views/bubble/bubble_frame_view.h"
22 #include "ui/views/controls/button/blue_button.h" 23 #include "ui/views/controls/button/blue_button.h"
23 #include "ui/views/controls/button/label_button.h" 24 #include "ui/views/controls/button/label_button.h"
(...skipping 24 matching lines...) Expand all
48 return label; 49 return label;
49 } 50 }
50 51
51 } // namespace 52 } // namespace
52 53
53 SaveCardBubbleViews::SaveCardBubbleViews(views::View* anchor_view, 54 SaveCardBubbleViews::SaveCardBubbleViews(views::View* anchor_view,
54 content::WebContents* web_contents, 55 content::WebContents* web_contents,
55 SaveCardBubbleController* controller) 56 SaveCardBubbleController* controller)
56 : LocationBarBubbleDelegateView(anchor_view, web_contents), 57 : LocationBarBubbleDelegateView(anchor_view, web_contents),
57 controller_(controller), 58 controller_(controller),
58 cvc_textfield_(nullptr), 59 learn_more_link_(nullptr),
Mathieu 2017/05/17 23:53:01 feel free to initialize this and cvc_textfield_ =
Jared Saul 2017/05/18 17:01:23 Done.
59 learn_more_link_(nullptr) { 60 cvc_textfield_(nullptr) {
60 DCHECK(controller); 61 DCHECK(controller);
61 views::BubbleDialogDelegateView::CreateBubble(this); 62 views::BubbleDialogDelegateView::CreateBubble(this);
62 chrome::RecordDialogCreation(chrome::DialogIdentifier::SAVE_CARD); 63 chrome::RecordDialogCreation(chrome::DialogIdentifier::SAVE_CARD);
63 } 64 }
64 65
65 SaveCardBubbleViews::~SaveCardBubbleViews() {} 66 SaveCardBubbleViews::~SaveCardBubbleViews() {}
66 67
67 void SaveCardBubbleViews::Show(DisplayReason reason) { 68 void SaveCardBubbleViews::Show(DisplayReason reason) {
68 ShowForReason(reason); 69 ShowForReason(reason);
69 } 70 }
(...skipping 21 matching lines...) Expand all
91 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 92 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
92 93
93 // Add a StyledLabel for each line of the legal message. 94 // Add a StyledLabel for each line of the legal message.
94 for (const LegalMessageLine& line : controller_->GetLegalMessageLines()) 95 for (const LegalMessageLine& line : controller_->GetLegalMessageLines())
95 view->AddChildView(CreateLegalMessageLineLabel(line, this).release()); 96 view->AddChildView(CreateLegalMessageLineLabel(line, this).release());
96 97
97 return view; 98 return view;
98 } 99 }
99 100
100 bool SaveCardBubbleViews::Accept() { 101 bool SaveCardBubbleViews::Accept() {
102 // If upload save and more info is needed, push the next view onto the stack.
103 if (controller_->ShouldRequestCvcFromUser() && view_stack_->size() == 1) {
anthonyvd 2017/05/18 12:01:01 Can this be reached if IsUploading is false? If so
Jared Saul 2017/05/18 17:01:23 Always having the view stack exist fixes this, tha
104 CreateAndAddRequestCvcViewToViewStack();
105 GetDialogClientView()->UpdateDialogButtons();
106 // Resize the bubble if it's grown larger:
107 SizeToContents();
108 return false;
109 }
110 // Otherwise, close the bubble as normal.
101 if (controller_) 111 if (controller_)
102 controller_->OnSaveButton(cvc_textfield_ ? cvc_textfield_->text() 112 controller_->OnSaveButton(cvc_textfield_ ? cvc_textfield_->text()
103 : base::string16()); 113 : base::string16());
104 return true; 114 return true;
105 } 115 }
106 116
107 bool SaveCardBubbleViews::Cancel() { 117 bool SaveCardBubbleViews::Cancel() {
108 if (controller_) 118 if (controller_)
109 controller_->OnCancelButton(); 119 controller_->OnCancelButton();
110 return true; 120 return true;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 } 185 }
176 } 186 }
177 187
178 // |range| was not found. 188 // |range| was not found.
179 NOTREACHED(); 189 NOTREACHED();
180 } 190 }
181 191
182 // Create view containing everything except for the footnote. 192 // Create view containing everything except for the footnote.
183 std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() { 193 std::unique_ptr<views::View> SaveCardBubbleViews::CreateMainContentView() {
184 std::unique_ptr<View> view(new View()); 194 std::unique_ptr<View> view(new View());
195 view->set_background(views::Background::CreateSolidBackground(SK_ColorWHITE));
185 view->SetLayoutManager( 196 view->SetLayoutManager(
186 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 197 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0,
187 views::kUnrelatedControlVerticalSpacing)); 198 views::kUnrelatedControlVerticalSpacing));
188 199
189 // Add the card type icon, last four digits and expiration date. 200 // Add the card type icon, last four digits and expiration date.
190 views::View* description_view = new views::View(); 201 views::View* description_view = new views::View();
191 description_view->SetLayoutManager(new views::BoxLayout( 202 description_view->SetLayoutManager(new views::BoxLayout(
192 views::BoxLayout::kHorizontal, 0, 0, views::kRelatedButtonHSpacing)); 203 views::BoxLayout::kHorizontal, 0, 0, views::kRelatedButtonHSpacing));
193 view->AddChildView(description_view); 204 view->AddChildView(description_view);
194 205
195 const CreditCard& card = controller_->GetCard(); 206 const CreditCard& card = controller_->GetCard();
196 views::ImageView* card_type_icon = new views::ImageView(); 207 views::ImageView* card_type_icon = new views::ImageView();
197 card_type_icon->SetImage( 208 card_type_icon->SetImage(
198 ResourceBundle::GetSharedInstance() 209 ResourceBundle::GetSharedInstance()
199 .GetImageNamed(CreditCard::IconResourceId(card.network())) 210 .GetImageNamed(CreditCard::IconResourceId(card.network()))
200 .AsImageSkia()); 211 .AsImageSkia());
201 card_type_icon->SetTooltipText(card.NetworkForDisplay()); 212 card_type_icon->SetTooltipText(card.NetworkForDisplay());
202 card_type_icon->SetBorder( 213 card_type_icon->SetBorder(
203 views::CreateSolidBorder(1, SkColorSetA(SK_ColorBLACK, 10))); 214 views::CreateSolidBorder(1, SkColorSetA(SK_ColorBLACK, 10)));
204 description_view->AddChildView(card_type_icon); 215 description_view->AddChildView(card_type_icon);
205 216
206 description_view->AddChildView(new views::Label( 217 description_view->AddChildView(new views::Label(
207 base::string16(kMidlineEllipsis) + card.LastFourDigits())); 218 base::string16(kMidlineEllipsis) + card.LastFourDigits()));
208 description_view->AddChildView( 219 description_view->AddChildView(
209 new views::Label(card.AbbreviatedExpirationDateForDisplay())); 220 new views::Label(card.AbbreviatedExpirationDateForDisplay()));
210 221
211 // Optionally add CVC request field if CVC was missing.
212 if (controller_->ShouldRequestCvcFromUser())
213 view->AddChildView(CreateRequestCvcView().release());
214
215 // Optionally add label that will contain an explanation for upload. 222 // Optionally add label that will contain an explanation for upload.
216 base::string16 explanation = controller_->GetExplanatoryMessage(); 223 base::string16 explanation = controller_->GetExplanatoryMessage();
217 if (!explanation.empty()) { 224 if (!explanation.empty()) {
218 views::Label* explanation_label = new views::Label(explanation); 225 views::Label* explanation_label = new views::Label(explanation);
219 explanation_label->SetMultiLine(true); 226 explanation_label->SetMultiLine(true);
220 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 227 explanation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
221 view->AddChildView(explanation_label); 228 view->AddChildView(explanation_label);
222 } 229 }
223 230
224 return view; 231 return view;
225 } 232 }
226 233
227 std::unique_ptr<views::View> SaveCardBubbleViews::CreateRequestCvcView() { 234 void SaveCardBubbleViews::CreateAndAddRequestCvcViewToViewStack() {
Mathieu 2017/05/17 23:53:01 I would have this return std::unique_ptr<views::Vi
Jared Saul 2017/05/18 17:01:23 Done.
228 std::unique_ptr<View> request_cvc_view = base::MakeUnique<views::View>(); 235 std::unique_ptr<View> overall_view(new View());
Mathieu 2017/05/17 23:53:01 = base::MakeUnique<views::View>();
Jared Saul 2017/05/18 17:01:23 Done.
236 overall_view->set_background(
237 views::Background::CreateSolidBackground(SK_ColorWHITE));
238 overall_view->SetLayoutManager(
239 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0,
240 views::kUnrelatedControlVerticalSpacing));
241 views::View* request_cvc_view = new views::View();
Mathieu 2017/05/17 23:53:01 same base::MakeUnique<...>() and .release() later
Jared Saul 2017/05/18 17:01:23 Done.
242 request_cvc_view->set_background(
Mathieu 2017/05/17 23:53:01 need?
Jared Saul 2017/05/18 17:01:23 Seems so--without it, upon switching to ViewStack
anthonyvd 2017/05/18 17:22:59 Ah yeah, this is probably because the ViewStack pa
Jared Saul 2017/05/18 17:34:34 You mean in ViewStack's code? Or do you have a su
anthonyvd 2017/05/18 21:08:41 Sorry, yes I meant in ViewStack's code :)
243 views::Background::CreateSolidBackground(SK_ColorWHITE));
229 request_cvc_view->SetLayoutManager(new views::BoxLayout( 244 request_cvc_view->SetLayoutManager(new views::BoxLayout(
230 views::BoxLayout::kHorizontal, 0, 0, views::kRelatedButtonHSpacing)); 245 views::BoxLayout::kHorizontal, 0, 0, views::kRelatedButtonHSpacing));
231 246
232 DCHECK(!cvc_textfield_); 247 DCHECK(!cvc_textfield_);
233 cvc_textfield_ = CreateCvcTextfield(); 248 cvc_textfield_ = CreateCvcTextfield();
234 cvc_textfield_->set_controller(this); 249 cvc_textfield_->set_controller(this);
235 request_cvc_view->AddChildView(cvc_textfield_); 250 request_cvc_view->AddChildView(cvc_textfield_);
236 251
237 views::ImageView* cvc_image = new views::ImageView(); 252 views::ImageView* cvc_image = new views::ImageView();
238 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 253 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
239 cvc_image->SetImage( 254 cvc_image->SetImage(
240 rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId())); 255 rb.GetImageSkiaNamed(controller_->GetCvcImageResourceId()));
241 request_cvc_view->AddChildView(cvc_image); 256 request_cvc_view->AddChildView(cvc_image);
242 257
243 request_cvc_view->AddChildView(new views::Label( 258 request_cvc_view->AddChildView(new views::Label(
244 l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC))); 259 l10n_util::GetStringUTF16(IDS_AUTOFILL_SAVE_CARD_PROMPT_ENTER_CVC)));
245 return request_cvc_view; 260
261 overall_view->AddChildView(request_cvc_view);
262 view_stack_->Push(std::move(overall_view), true);
246 } 263 }
247 264
248 bool SaveCardBubbleViews::IsDialogButtonEnabled(ui::DialogButton button) const { 265 bool SaveCardBubbleViews::IsDialogButtonEnabled(ui::DialogButton button) const {
249 if (button == ui::DIALOG_BUTTON_CANCEL) 266 if (button == ui::DIALOG_BUTTON_CANCEL)
250 return true; 267 return true;
251 268
252 DCHECK_EQ(ui::DIALOG_BUTTON_OK, button); 269 DCHECK_EQ(ui::DIALOG_BUTTON_OK, button);
253 return !cvc_textfield_ || 270 return !cvc_textfield_ ||
254 controller_->InputCvcIsValid(cvc_textfield_->text()); 271 controller_->InputCvcIsValid(cvc_textfield_->text());
255 } 272 }
256 273
257 void SaveCardBubbleViews::ContentsChanged(views::Textfield* sender, 274 void SaveCardBubbleViews::ContentsChanged(views::Textfield* sender,
258 const base::string16& new_contents) { 275 const base::string16& new_contents) {
259 DCHECK_EQ(cvc_textfield_, sender); 276 DCHECK_EQ(cvc_textfield_, sender);
260 GetDialogClientView()->UpdateDialogButtons(); 277 GetDialogClientView()->UpdateDialogButtons();
261 } 278 }
262 279
280 bool SaveCardBubbleViews::IsUploading() {
281 return !controller_->GetLegalMessageLines().empty();
282 }
283
263 void SaveCardBubbleViews::Init() { 284 void SaveCardBubbleViews::Init() {
264 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); 285 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
265 AddChildView(CreateMainContentView().release()); 286 if (IsUploading()) {
287 view_stack_ = base::MakeUnique<ViewStack>();
anthonyvd 2017/05/18 12:01:01 If you own the view, you must call set_owned_by_cl
Jared Saul 2017/05/18 17:01:23 Thanks for the heads-up. I tried the raw pointer
288 view_stack_->Push(CreateMainContentView(), false);
Mathieu 2017/05/17 23:53:01 Why not do this in all cases? Would simplify the c
Mathieu 2017/05/17 23:53:01 /*animate=*/false
anthonyvd 2017/05/18 12:01:01 Yep, this and what's in the else block should be e
Jared Saul 2017/05/18 17:01:23 Good idea! Done.
289 AddChildView(view_stack_.get());
290 } else {
291 AddChildView(CreateMainContentView().release());
292 }
266 } 293 }
267 294
268 } // namespace autofill 295 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698