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

Side by Side Diff: chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc

Issue 12893007: Implementing VERIFY_CVV required action. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixing tests Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/autofill/autofill_dialog_controller_impl.h" 5 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 CreditCard* card, 165 CreditCard* card,
166 string16* cvc, 166 string16* cvc,
167 AutofillProfile* profile) { 167 AutofillProfile* profile) {
168 for (DetailOutputMap::const_iterator it = output.begin(); 168 for (DetailOutputMap::const_iterator it = output.begin();
169 it != output.end(); ++it) { 169 it != output.end(); ++it) {
170 string16 trimmed; 170 string16 trimmed;
171 TrimWhitespace(it->second, TRIM_ALL, &trimmed); 171 TrimWhitespace(it->second, TRIM_ALL, &trimmed);
172 172
173 // Special case CVC as CreditCard just swallows it. 173 // Special case CVC as CreditCard just swallows it.
174 if (it->first->type == CREDIT_CARD_VERIFICATION_CODE) { 174 if (it->first->type == CREDIT_CARD_VERIFICATION_CODE) {
175 cvc->assign(trimmed); 175 if (cvc)
176 cvc->assign(trimmed);
176 } else { 177 } else {
177 // Copy the credit card name to |profile| in addition to |card| as 178 // Copy the credit card name to |profile| in addition to |card| as
178 // wallet::Instrument requires a recipient name for its billing address. 179 // wallet::Instrument requires a recipient name for its billing address.
179 if (it->first->type == CREDIT_CARD_NAME) 180 if (profile && it->first->type == CREDIT_CARD_NAME)
180 profile->SetRawInfo(NAME_FULL, trimmed); 181 profile->SetRawInfo(NAME_FULL, trimmed);
181 182
182 if (IsCreditCardType(it->first->type)) 183 if (IsCreditCardType(it->first->type)) {
183 card->SetRawInfo(it->first->type, trimmed); 184 if (card)
184 else 185 card->SetRawInfo(it->first->type, trimmed);
186 } else if (profile) {
185 profile->SetRawInfo(it->first->type, trimmed); 187 profile->SetRawInfo(it->first->type, trimmed);
188 }
186 } 189 }
187 } 190 }
188 } 191 }
189 192
190 // Returns the containing window for the given |web_contents|. The containing 193 // Returns the containing window for the given |web_contents|. The containing
191 // window might be a browser window for a Chrome tab, or it might be a shell 194 // window might be a browser window for a Chrome tab, or it might be a shell
192 // window for a platform app. 195 // window for a platform app.
193 BaseWindow* GetBaseWindowForWebContents( 196 BaseWindow* GetBaseWindowForWebContents(
194 const content::WebContents* web_contents) { 197 const content::WebContents* web_contents) {
195 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 198 Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_email_(this)), 245 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_email_(this)),
243 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_cc_(this)), 246 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_cc_(this)),
244 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_billing_(this)), 247 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_billing_(this)),
245 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_cc_billing_(this)), 248 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_cc_billing_(this)),
246 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_shipping_(this)), 249 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_shipping_(this)),
247 section_showing_popup_(SECTION_BILLING), 250 section_showing_popup_(SECTION_BILLING),
248 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), 251 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
249 metric_logger_(metric_logger), 252 metric_logger_(metric_logger),
250 initial_user_state_(AutofillMetrics::DIALOG_USER_STATE_UNKNOWN), 253 initial_user_state_(AutofillMetrics::DIALOG_USER_STATE_UNKNOWN),
251 dialog_type_(dialog_type), 254 dialog_type_(dialog_type),
252 did_submit_(false), 255 is_submitting_(false),
253 autocheckout_is_running_(false), 256 autocheckout_is_running_(false),
254 had_autocheckout_error_(false) { 257 had_autocheckout_error_(false) {
255 // TODO(estade): remove duplicates from |form|? 258 // TODO(estade): remove duplicates from |form|?
256 } 259 }
257 260
258 AutofillDialogControllerImpl::~AutofillDialogControllerImpl() { 261 AutofillDialogControllerImpl::~AutofillDialogControllerImpl() {
259 if (popup_controller_) 262 if (popup_controller_)
260 popup_controller_->Hide(); 263 popup_controller_->Hide();
261 264
262 metric_logger_.LogDialogInitialUserState(dialog_type_, initial_user_state_); 265 metric_logger_.LogDialogInitialUserState(dialog_type_, initial_user_state_);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 string16 AutofillDialogControllerImpl::UseBillingForShippingText() const { 424 string16 AutofillDialogControllerImpl::UseBillingForShippingText() const {
422 return l10n_util::GetStringUTF16( 425 return l10n_util::GetStringUTF16(
423 IDS_AUTOFILL_DIALOG_USE_BILLING_FOR_SHIPPING); 426 IDS_AUTOFILL_DIALOG_USE_BILLING_FOR_SHIPPING);
424 } 427 }
425 428
426 string16 AutofillDialogControllerImpl::CancelButtonText() const { 429 string16 AutofillDialogControllerImpl::CancelButtonText() const {
427 return l10n_util::GetStringUTF16(IDS_CANCEL); 430 return l10n_util::GetStringUTF16(IDS_CANCEL);
428 } 431 }
429 432
430 string16 AutofillDialogControllerImpl::ConfirmButtonText() const { 433 string16 AutofillDialogControllerImpl::ConfirmButtonText() const {
431 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SUBMIT_BUTTON); 434 return l10n_util::GetStringUTF16(IsSubmitPausedOn(wallet::VERIFY_CVV) ?
435 IDS_AUTOFILL_DIALOG_VERIFY_BUTTON : IDS_AUTOFILL_DIALOG_SUBMIT_BUTTON);
432 } 436 }
433 437
434 string16 AutofillDialogControllerImpl::CancelSignInText() const { 438 string16 AutofillDialogControllerImpl::CancelSignInText() const {
435 // TODO(abodenha): real strings and l10n. 439 // TODO(abodenha): real strings and l10n.
436 return ASCIIToUTF16("Don't sign in."); 440 return ASCIIToUTF16("Don't sign in.");
437 } 441 }
438 442
439 string16 AutofillDialogControllerImpl::SaveLocallyText() const { 443 string16 AutofillDialogControllerImpl::SaveLocallyText() const {
440 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SAVE_LOCALLY_CHECKBOX); 444 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SAVE_LOCALLY_CHECKBOX);
441 } 445 }
(...skipping 22 matching lines...) Expand all
464 } 468 }
465 469
466 bool AutofillDialogControllerImpl::ShouldShowSpinner() const { 470 bool AutofillDialogControllerImpl::ShouldShowSpinner() const {
467 return IsPayingWithWallet() && SignedInState() == REQUIRES_RESPONSE; 471 return IsPayingWithWallet() && SignedInState() == REQUIRES_RESPONSE;
468 } 472 }
469 473
470 string16 AutofillDialogControllerImpl::AccountChooserText() const { 474 string16 AutofillDialogControllerImpl::AccountChooserText() const {
471 if (!IsPayingWithWallet()) 475 if (!IsPayingWithWallet())
472 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PAY_WITHOUT_WALLET); 476 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PAY_WITHOUT_WALLET);
473 477
474 // TODO(dbeam): real strings and l10n.
475 if (SignedInState() == SIGNED_IN) 478 if (SignedInState() == SIGNED_IN)
476 return ASCIIToUTF16(current_username_); 479 return ASCIIToUTF16(current_username_);
477 480
478 // In this case, the account chooser should be showing the signin link. 481 // In this case, the account chooser should be showing the signin link.
479 return string16(); 482 return string16();
480 } 483 }
481 484
482 string16 AutofillDialogControllerImpl::SignInLinkText() const { 485 string16 AutofillDialogControllerImpl::SignInLinkText() const {
483 // TODO(estade): real strings and l10n. 486 // TODO(estade): real strings and l10n.
484 return ASCIIToUTF16("Sign in to use Google Wallet"); 487 return ASCIIToUTF16("Sign in to use Google Wallet");
485 } 488 }
486 489
487 bool AutofillDialogControllerImpl::ShouldOfferToSaveInChrome() const { 490 bool AutofillDialogControllerImpl::ShouldOfferToSaveInChrome() const {
488 return !IsPayingWithWallet(); 491 return !IsPayingWithWallet();
489 } 492 }
490 493
491 bool AutofillDialogControllerImpl::AutocheckoutIsRunning() const { 494 bool AutofillDialogControllerImpl::AutocheckoutIsRunning() const {
492 return autocheckout_is_running_; 495 return autocheckout_is_running_;
493 } 496 }
494 497
495 bool AutofillDialogControllerImpl::HadAutocheckoutError() const { 498 bool AutofillDialogControllerImpl::HadAutocheckoutError() const {
496 return had_autocheckout_error_; 499 return had_autocheckout_error_;
497 } 500 }
498 501
499 bool AutofillDialogControllerImpl::IsDialogButtonEnabled( 502 bool AutofillDialogControllerImpl::IsDialogButtonEnabled(
500 ui::DialogButton button) const { 503 ui::DialogButton button) const {
501 if (button == ui::DIALOG_BUTTON_OK) 504 if (button == ui::DIALOG_BUTTON_OK)
502 return !did_submit_; 505 return !is_submitting_ || IsSubmitPausedOn(wallet::VERIFY_CVV);
506
503 DCHECK_EQ(ui::DIALOG_BUTTON_CANCEL, button); 507 DCHECK_EQ(ui::DIALOG_BUTTON_CANCEL, button);
504 // TODO(ahutter): Make it possible for the user to cancel out of the dialog 508 // TODO(ahutter): Make it possible for the user to cancel out of the dialog
505 // while Autocheckout is in progress. 509 // while Autocheckout is in progress.
506 return had_autocheckout_error_ || !did_submit_; 510 return !callback_.is_null();
Ilya Sherman 2013/04/01 22:55:03 ... but you should keep the had_autocheckout_error
Dan Beam 2013/04/01 23:08:38 Done.
507 } 511 }
508 512
509 const std::vector<ui::Range>& AutofillDialogControllerImpl:: 513 const std::vector<ui::Range>& AutofillDialogControllerImpl::
510 LegalDocumentLinks() { 514 LegalDocumentLinks() {
511 EnsureLegalDocumentsText(); 515 EnsureLegalDocumentsText();
512 return legal_document_link_ranges_; 516 return legal_document_link_ranges_;
513 } 517 }
514 518
515 bool AutofillDialogControllerImpl::SectionIsActive(DialogSection section) 519 bool AutofillDialogControllerImpl::SectionIsActive(DialogSection section)
516 const { 520 const {
521 if (IsSubmitPausedOn(wallet::VERIFY_CVV))
522 return section == SECTION_CC_BILLING;
523
517 if (IsPayingWithWallet()) 524 if (IsPayingWithWallet())
518 return section != SECTION_BILLING && section != SECTION_CC; 525 return section != SECTION_BILLING && section != SECTION_CC;
519 526
520 return section != SECTION_CC_BILLING; 527 return section != SECTION_CC_BILLING;
521 } 528 }
522 529
523 bool AutofillDialogControllerImpl::HasCompleteWallet() const { 530 bool AutofillDialogControllerImpl::HasCompleteWallet() const {
524 return wallet_items_.get() != NULL && 531 return wallet_items_.get() != NULL &&
525 !wallet_items_->instruments().empty() && 532 !wallet_items_->instruments().empty() &&
526 !wallet_items_->addresses().empty(); 533 !wallet_items_->addresses().empty();
527 } 534 }
528 535
536 bool AutofillDialogControllerImpl::IsSubmitPausedOn(
537 wallet::RequiredAction required_action) const {
538 return full_wallet_ && full_wallet_->HasRequiredAction(required_action);
539 }
540
529 void AutofillDialogControllerImpl::StartFetchingWalletItems() { 541 void AutofillDialogControllerImpl::StartFetchingWalletItems() {
530 DCHECK(IsPayingWithWallet()); 542 DCHECK(IsPayingWithWallet());
531 // TODO(dbeam): Add Risk capabilites once the UI supports risk challenges. 543 // TODO(dbeam): Add Risk capabilites once the UI supports risk challenges.
532 GetWalletClient()->GetWalletItems( 544 GetWalletClient()->GetWalletItems(
533 source_url_, 545 source_url_,
534 std::vector<wallet::WalletClient::RiskCapability>()); 546 std::vector<wallet::WalletClient::RiskCapability>());
535 } 547 }
536 548
537 void AutofillDialogControllerImpl::OnWalletOrSigninUpdate() { 549 void AutofillDialogControllerImpl::OnWalletOrSigninUpdate() {
538 if (wallet_items_.get()) { 550 if (wallet_items_.get()) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 case SECTION_CC_BILLING: 704 case SECTION_CC_BILLING:
693 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_CC_BILLING); 705 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_CC_BILLING);
694 case SECTION_SHIPPING: 706 case SECTION_SHIPPING:
695 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_SHIPPING); 707 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_SHIPPING);
696 default: 708 default:
697 NOTREACHED(); 709 NOTREACHED();
698 return string16(); 710 return string16();
699 } 711 }
700 } 712 }
701 713
714 SuggestionState AutofillDialogControllerImpl::SuggestionStateForSection(
715 DialogSection section) {
716 return SuggestionState(SuggestionTextForSection(section),
717 SuggestionIconForSection(section),
718 ExtraSuggestionTextForSection(section),
719 ExtraSuggestionIconForSection(section),
720 EditEnabledForSection(section));
721 }
722
702 string16 AutofillDialogControllerImpl::SuggestionTextForSection( 723 string16 AutofillDialogControllerImpl::SuggestionTextForSection(
703 DialogSection section) { 724 DialogSection section) {
725 string16 action_text = RequiredActionTextForSection(section);
726 if (!action_text.empty())
727 return action_text;
728
704 // When the user has clicked 'edit', don't show a suggestion (even though 729 // When the user has clicked 'edit', don't show a suggestion (even though
705 // there is a profile selected in the model). 730 // there is a profile selected in the model).
706 if (section_editing_state_[section]) 731 if (section_editing_state_[section])
707 return string16(); 732 return string16();
708 733
709 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 734 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
710 std::string item_key = model->GetItemKeyForCheckedItem(); 735 std::string item_key = model->GetItemKeyForCheckedItem();
711 if (item_key.empty()) 736 if (item_key.empty())
712 return string16(); 737 return string16();
713 738
714 if (section == SECTION_EMAIL) 739 if (section == SECTION_EMAIL)
715 return model->GetLabelAt(model->checked_item()); 740 return model->GetLabelAt(model->checked_item());
716 741
717 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); 742 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section);
718 return wrapper->GetDisplayText(); 743 return wrapper->GetDisplayText();
719 } 744 }
720 745
746 string16 AutofillDialogControllerImpl::RequiredActionTextForSection(
747 DialogSection section) const {
748 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) {
749 const wallet::WalletItems::MaskedInstrument* current_instrument =
750 wallet_items_->GetInstrumentById(active_instrument_id_);
751 if (current_instrument)
752 return current_instrument->TypeAndLastFourDigits();
753
754 DetailOutputMap output;
755 view_->GetUserInput(section, &output);
756 CreditCard card;
757 GetBillingInfoFromOutputs(output, &card, NULL, NULL);
758 return card.TypeAndLastFourDigits();
759 }
760
761 return string16();
762 }
763
764 string16 AutofillDialogControllerImpl::ExtraSuggestionTextForSection(
765 DialogSection section) const {
766 if (section == SECTION_CC ||
767 (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV))) {
768 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC);
769 }
770
771 return string16();
772 }
773
721 scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper( 774 scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper(
722 DialogSection section) { 775 DialogSection section) {
723 if (IsPayingWithWallet() && full_wallet_) { 776 if (IsPayingWithWallet() && full_wallet_ &&
777 !IsSubmitPausedOn(wallet::VERIFY_CVV)) {
724 if (section == SECTION_CC_BILLING) { 778 if (section == SECTION_CC_BILLING) {
725 return scoped_ptr<DataModelWrapper>( 779 return scoped_ptr<DataModelWrapper>(
726 new FullWalletBillingWrapper(full_wallet_.get())); 780 new FullWalletBillingWrapper(full_wallet_.get()));
727 } 781 }
728 if (section == SECTION_SHIPPING) { 782 if (section == SECTION_SHIPPING) {
729 return scoped_ptr<DataModelWrapper>( 783 return scoped_ptr<DataModelWrapper>(
730 new FullWalletShippingWrapper(full_wallet_.get())); 784 new FullWalletShippingWrapper(full_wallet_.get()));
731 } 785 }
732 } 786 }
733 787
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 828
775 gfx::Image AutofillDialogControllerImpl::SuggestionIconForSection( 829 gfx::Image AutofillDialogControllerImpl::SuggestionIconForSection(
776 DialogSection section) { 830 DialogSection section) {
777 scoped_ptr<DataModelWrapper> model = CreateWrapper(section); 831 scoped_ptr<DataModelWrapper> model = CreateWrapper(section);
778 if (!model.get()) 832 if (!model.get())
779 return gfx::Image(); 833 return gfx::Image();
780 834
781 return model->GetIcon(); 835 return model->GetIcon();
782 } 836 }
783 837
838 gfx::Image AutofillDialogControllerImpl::ExtraSuggestionIconForSection(
839 DialogSection section) const {
840 if (section == SECTION_CC || section == SECTION_CC_BILLING)
841 return IconForField(CREDIT_CARD_VERIFICATION_CODE, string16());
842
843 return gfx::Image();
844 }
845
846 bool AutofillDialogControllerImpl::EditEnabledForSection(
847 DialogSection section) const {
848 return section != SECTION_CC_BILLING || !IsSubmitPausedOn(wallet::VERIFY_CVV);
849 }
850
784 void AutofillDialogControllerImpl::EditClickedForSection( 851 void AutofillDialogControllerImpl::EditClickedForSection(
785 DialogSection section) { 852 DialogSection section) {
786 DetailInputs* inputs = MutableRequestedFieldsForSection(section); 853 DetailInputs* inputs = MutableRequestedFieldsForSection(section);
787 scoped_ptr<DataModelWrapper> model = CreateWrapper(section); 854 scoped_ptr<DataModelWrapper> model = CreateWrapper(section);
788 model->FillInputs(inputs); 855 model->FillInputs(inputs);
789 section_editing_state_[section] = true; 856 section_editing_state_[section] = true;
790 view_->UpdateSection(section); 857 view_->UpdateSection(section);
791 } 858 }
792 859
793 void AutofillDialogControllerImpl::EditCancelledForSection( 860 void AutofillDialogControllerImpl::EditCancelledForSection(
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 std::vector<DialogNotification> 1103 std::vector<DialogNotification>
1037 AutofillDialogControllerImpl::CurrentNotifications() const { 1104 AutofillDialogControllerImpl::CurrentNotifications() const {
1038 std::vector<DialogNotification> notifications; 1105 std::vector<DialogNotification> notifications;
1039 1106
1040 if (IsPayingWithWallet()) { 1107 if (IsPayingWithWallet()) {
1041 // TODO(dbeam): what about REQUIRES_PASSIVE_SIGN_IN? 1108 // TODO(dbeam): what about REQUIRES_PASSIVE_SIGN_IN?
1042 if (SignedInState() == SIGNED_IN) { 1109 if (SignedInState() == SIGNED_IN) {
1043 // On first run with a complete wallet profile, show a notification 1110 // On first run with a complete wallet profile, show a notification
1044 // explaining where this data came from. 1111 // explaining where this data came from.
1045 if (IsFirstRun() && HasCompleteWallet()) { 1112 if (IsFirstRun() && HasCompleteWallet()) {
1046 notifications.push_back( 1113 notifications.push_back(DialogNotification(
1047 DialogNotification( 1114 DialogNotification::EXPLANATORY_MESSAGE,
1048 DialogNotification::EXPLANATORY_MESSAGE, 1115 l10n_util::GetStringUTF16(
1049 l10n_util::GetStringUTF16( 1116 IDS_AUTOFILL_DIALOG_DETAILS_FROM_WALLET)));
1050 IDS_AUTOFILL_DIALOG_DETAILS_FROM_WALLET)));
1051 } else { 1117 } else {
1052 notifications.push_back( 1118 notifications.push_back(DialogNotification(
1053 DialogNotification( 1119 DialogNotification::WALLET_PROMO,
1054 DialogNotification::WALLET_PROMO, 1120 l10n_util::GetStringUTF16(
1055 l10n_util::GetStringUTF16( 1121 IDS_AUTOFILL_DIALOG_SAVE_DETAILS_IN_WALLET)));
1056 IDS_AUTOFILL_DIALOG_SAVE_DETAILS_IN_WALLET)));
1057 } 1122 }
1058 } else if (IsFirstRun()) { 1123 } else if (IsFirstRun()) {
1059 // If the user is not signed in, show an upsell notification on first run. 1124 // If the user is not signed in, show an upsell notification on first run.
1060 notifications.push_back( 1125 notifications.push_back(DialogNotification(
1061 DialogNotification( 1126 DialogNotification::WALLET_PROMO,
1062 DialogNotification::WALLET_PROMO, 1127 l10n_util::GetStringUTF16(
1063 l10n_util::GetStringUTF16( 1128 IDS_AUTOFILL_DIALOG_SIGN_IN_AND_SAVE_DETAILS)));
1064 IDS_AUTOFILL_DIALOG_SIGN_IN_AND_SAVE_DETAILS)));
1065 } 1129 }
1066 } 1130 }
1067 1131
1068 if (RequestingCreditCardInfo() && !TransmissionWillBeSecure()) { 1132 if (RequestingCreditCardInfo() && !TransmissionWillBeSecure()) {
1069 notifications.push_back( 1133 notifications.push_back(DialogNotification(
1070 DialogNotification( 1134 DialogNotification::SECURITY_WARNING,
1071 DialogNotification::SECURITY_WARNING, 1135 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECURITY_WARNING)));
1072 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECURITY_WARNING)));
1073 } 1136 }
1074 1137
1075 if (!invoked_from_same_origin_) { 1138 if (!invoked_from_same_origin_) {
1076 notifications.push_back( 1139 notifications.push_back(DialogNotification(
1077 DialogNotification( 1140 DialogNotification::SECURITY_WARNING,
1078 DialogNotification::SECURITY_WARNING, 1141 l10n_util::GetStringFUTF16(IDS_AUTOFILL_DIALOG_SITE_WARNING,
1079 l10n_util::GetStringFUTF16( 1142 UTF8ToUTF16(source_url_.host()))));
1080 IDS_AUTOFILL_DIALOG_SITE_WARNING, 1143 }
1081 UTF8ToUTF16(source_url_.host())))); 1144
1145 if (IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1146 notifications.push_back(DialogNotification(
1147 DialogNotification::REQUIRED_ACTION,
1148 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_VERIFY_CVV)));
1082 } 1149 }
1083 1150
1084 if (had_autocheckout_error_) { 1151 if (had_autocheckout_error_) {
1085 notifications.push_back( 1152 notifications.push_back(DialogNotification(
1086 DialogNotification( 1153 DialogNotification::AUTOCHECKOUT_ERROR,
1087 DialogNotification::AUTOCHECKOUT_ERROR, 1154 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_AUTOCHECKOUT_ERROR)));
1088 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_AUTOCHECKOUT_ERROR)));
1089 } 1155 }
1090 1156
1091 if (account_chooser_model_.had_wallet_error()) { 1157 if (account_chooser_model_.had_wallet_error()) {
1092 // TODO(dbeam): pass along the Wallet error or remove from the translation. 1158 // TODO(dbeam): pass along the Wallet error or remove from the translation.
1093 // TODO(dbeam): figure out a way to dismiss this error after a while. 1159 // TODO(dbeam): figure out a way to dismiss this error after a while.
1094 notifications.push_back(DialogNotification( 1160 notifications.push_back(DialogNotification(
1095 DialogNotification::WALLET_ERROR, 1161 DialogNotification::WALLET_ERROR,
1096 l10n_util::GetStringFUTF16( 1162 l10n_util::GetStringFUTF16(
1097 IDS_AUTOFILL_DIALOG_COMPLETE_WITHOUT_WALLET, 1163 IDS_AUTOFILL_DIALOG_COMPLETE_WITHOUT_WALLET,
1098 ASCIIToUTF16("Oops, [Wallet-Error].")))); 1164 ASCIIToUTF16("Oops, [Wallet-Error]."))));
(...skipping 30 matching lines...) Expand all
1129 } 1195 }
1130 } 1196 }
1131 1197
1132 NOTREACHED(); 1198 NOTREACHED();
1133 #else 1199 #else
1134 // TODO(estade): use TabModelList? 1200 // TODO(estade): use TabModelList?
1135 #endif 1201 #endif
1136 } 1202 }
1137 1203
1138 void AutofillDialogControllerImpl::OnCancel() { 1204 void AutofillDialogControllerImpl::OnCancel() {
1139 if (!did_submit_) { 1205 // If the submit was successful, |callback_| will have already been |.Run()|
1140 metric_logger_.LogDialogUiDuration( 1206 // and nullified. If this is the case, no further actions are required. If
1141 base::Time::Now() - dialog_shown_timestamp_, 1207 // Autocheckout has an error, it's possible that the dialog will be submitted
1142 dialog_type_, 1208 // to start the flow and then cancelled to close the dialog after the error.
1143 AutofillMetrics::DIALOG_CANCELED); 1209 if (callback_.is_null())
1144 } 1210 return;
1145 1211
1146 // If Autocheckout has an error, it's possible that the dialog will be 1212 metric_logger_.LogDialogUiDuration(
1147 // submitted to start the flow and then cancelled to close the dialog after 1213 base::Time::Now() - dialog_shown_timestamp_,
1148 // the error. 1214 dialog_type_,
1149 if (!callback_.is_null()) { 1215 AutofillMetrics::DIALOG_CANCELED);
1150 callback_.Run(NULL); 1216
1151 callback_ = base::Callback<void(const FormStructure*)>(); 1217 callback_.Run(NULL);
1218 callback_ = base::Callback<void(const FormStructure*)>();
1219 }
1220
1221 void AutofillDialogControllerImpl::OnAccept() {
1222 is_submitting_ = true;
1223 view_->UpdateButtonStrip();
1224
1225 if (IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1226 DCHECK(!active_instrument_id_.empty());
1227 GetWalletClient()->AuthenticateInstrument(
1228 active_instrument_id_,
1229 UTF16ToUTF8(view_->GetCvc()),
1230 wallet_items_->obfuscated_gaia_id());
1231 } else if (IsPayingWithWallet()) {
1232 // TODO(dbeam): disallow switching payment methods while submitting.
1233 SubmitWithWallet();
1234 } else {
1235 FinishSubmit();
1152 } 1236 }
1153 } 1237 }
1154 1238
1155 void AutofillDialogControllerImpl::OnSubmit() {
1156 did_submit_ = true;
1157 metric_logger_.LogDialogUiDuration(
1158 base::Time::Now() - dialog_shown_timestamp_,
1159 dialog_type_,
1160 AutofillMetrics::DIALOG_ACCEPTED);
1161
1162 if (dialog_type_ == DIALOG_TYPE_AUTOCHECKOUT) {
1163 // Stop observing PersonalDataManager to avoid the dialog redrawing while
1164 // in an Autocheckout flow.
1165 GetManager()->RemoveObserver(this);
1166 autocheckout_is_running_ = true;
1167 autocheckout_started_timestamp_ = base::Time::Now();
1168 view_->UpdateButtonStrip();
1169 }
1170
1171 if (IsPayingWithWallet())
1172 SubmitWithWallet();
1173 else
1174 FinishSubmit();
1175 }
1176
1177 Profile* AutofillDialogControllerImpl::profile() { 1239 Profile* AutofillDialogControllerImpl::profile() {
1178 return profile_; 1240 return profile_;
1179 } 1241 }
1180 1242
1181 content::WebContents* AutofillDialogControllerImpl::web_contents() { 1243 content::WebContents* AutofillDialogControllerImpl::web_contents() {
1182 return contents_; 1244 return contents_;
1183 } 1245 }
1184 1246
1185 //////////////////////////////////////////////////////////////////////////////// 1247 ////////////////////////////////////////////////////////////////////////////////
1186 // AutofillPopupDelegate implementation. 1248 // AutofillPopupDelegate implementation.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 void AutofillDialogControllerImpl::OnDidAuthenticateInstrument(bool success) { 1341 void AutofillDialogControllerImpl::OnDidAuthenticateInstrument(bool success) {
1280 // TODO(dbeam): use the returned full wallet. b/8332329 1342 // TODO(dbeam): use the returned full wallet. b/8332329
1281 if (success) 1343 if (success)
1282 GetFullWallet(); 1344 GetFullWallet();
1283 else 1345 else
1284 DisableWallet(); 1346 DisableWallet();
1285 } 1347 }
1286 1348
1287 void AutofillDialogControllerImpl::OnDidGetFullWallet( 1349 void AutofillDialogControllerImpl::OnDidGetFullWallet(
1288 scoped_ptr<wallet::FullWallet> full_wallet) { 1350 scoped_ptr<wallet::FullWallet> full_wallet) {
1289 // TODO(dbeam): handle more required actions.
1290 full_wallet_ = full_wallet.Pass(); 1351 full_wallet_ = full_wallet.Pass();
1291 1352
1292 if (full_wallet_->HasRequiredAction(wallet::VERIFY_CVV)) 1353 if (full_wallet_->required_actions().empty()) {
1293 DisableWallet();
1294 else
1295 FinishSubmit(); 1354 FinishSubmit();
1355 return;
1356 }
1357
1358 GenerateSuggestionsModels();
1359 view_->ModelChanged();
1360 view_->UpdateNotificationArea();
1361 view_->UpdateButtonStrip();
1296 } 1362 }
1297 1363
1298 void AutofillDialogControllerImpl::OnPassiveSigninSuccess( 1364 void AutofillDialogControllerImpl::OnPassiveSigninSuccess(
1299 const std::string& username) { 1365 const std::string& username) {
1300 DCHECK(IsPayingWithWallet()); 1366 DCHECK(IsPayingWithWallet());
1301 current_username_ = username; 1367 current_username_ = username;
1302 signin_helper_.reset(); 1368 signin_helper_.reset();
1303 wallet_items_.reset(); 1369 wallet_items_.reset();
1304 StartFetchingWalletItems(); 1370 StartFetchingWalletItems();
1305 } 1371 }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 1535
1470 wallet::WalletClient* AutofillDialogControllerImpl::GetWalletClient() { 1536 wallet::WalletClient* AutofillDialogControllerImpl::GetWalletClient() {
1471 return &wallet_client_; 1537 return &wallet_client_;
1472 } 1538 }
1473 1539
1474 bool AutofillDialogControllerImpl::IsPayingWithWallet() const { 1540 bool AutofillDialogControllerImpl::IsPayingWithWallet() const {
1475 return account_chooser_model_.WalletIsSelected(); 1541 return account_chooser_model_.WalletIsSelected();
1476 } 1542 }
1477 1543
1478 void AutofillDialogControllerImpl::DisableWallet() { 1544 void AutofillDialogControllerImpl::DisableWallet() {
1545 is_submitting_ = false;
1546 if (view_)
1547 view_->UpdateButtonStrip();
1548
1479 signin_helper_.reset(); 1549 signin_helper_.reset();
1480 current_username_.clear(); 1550 current_username_.clear();
1481 account_chooser_model_.SetHadWalletError(); 1551 account_chooser_model_.SetHadWalletError();
1482 GetWalletClient()->CancelPendingRequests(); 1552 GetWalletClient()->CancelPendingRequests();
1553 full_wallet_.reset();
1483 } 1554 }
1484 1555
1485 void AutofillDialogControllerImpl::OnWalletSigninError() { 1556 void AutofillDialogControllerImpl::OnWalletSigninError() {
1486 signin_helper_.reset(); 1557 signin_helper_.reset();
1487 current_username_.clear(); 1558 current_username_.clear();
1488 account_chooser_model_.SetHadWalletSigninError(); 1559 account_chooser_model_.SetHadWalletSigninError();
1489 GetWalletClient()->CancelPendingRequests(); 1560 GetWalletClient()->CancelPendingRequests();
1490 } 1561 }
1491 1562
1492 bool AutofillDialogControllerImpl::IsFirstRun() const { 1563 bool AutofillDialogControllerImpl::IsFirstRun() const {
1493 PrefService* prefs = profile_->GetPrefs(); 1564 PrefService* prefs = profile_->GetPrefs();
1494 return !prefs->HasPrefPath(prefs::kAutofillDialogPayWithoutWallet); 1565 return !prefs->HasPrefPath(prefs::kAutofillDialogPayWithoutWallet);
1495 } 1566 }
1496 1567
1497 void AutofillDialogControllerImpl::GenerateSuggestionsModels() { 1568 void AutofillDialogControllerImpl::GenerateSuggestionsModels() {
1498 suggested_email_.Reset(); 1569 suggested_email_.Reset();
1499 suggested_cc_.Reset(); 1570 suggested_cc_.Reset();
1500 suggested_billing_.Reset(); 1571 suggested_billing_.Reset();
1501 suggested_cc_billing_.Reset(); 1572 suggested_cc_billing_.Reset();
1502 suggested_shipping_.Reset(); 1573 suggested_shipping_.Reset();
1503 1574
1504 if (IsPayingWithWallet()) { 1575 if (IsPayingWithWallet()) {
1505 if (wallet_items_.get()) { 1576 if (wallet_items_) {
1506 // TODO(estade): seems we need to hardcode the email address. 1577 // TODO(estade): seems we need to hardcode the email address.
1507 1578
1508 const std::vector<wallet::Address*>& addresses = 1579 const std::vector<wallet::Address*>& addresses =
1509 wallet_items_->addresses(); 1580 wallet_items_->addresses();
1510 for (size_t i = 0; i < addresses.size(); ++i) { 1581 for (size_t i = 0; i < addresses.size(); ++i) {
1511 // TODO(dbeam): respect wallet_items_->default_instrument_id(). 1582 // TODO(dbeam): respect wallet_items_->default_instrument_id().
1512 suggested_shipping_.AddKeyedItemWithSublabel( 1583 suggested_shipping_.AddKeyedItemWithSublabel(
1513 base::IntToString(i), 1584 base::IntToString(i),
1514 addresses[i]->DisplayName(), 1585 addresses[i]->DisplayName(),
1515 addresses[i]->DisplayNameDetail()); 1586 addresses[i]->DisplayNameDetail());
1516 } 1587 }
1517 1588
1518 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments = 1589 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1519 wallet_items_->instruments(); 1590 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments =
1520 for (size_t i = 0; i < instruments.size(); ++i) { 1591 wallet_items_->instruments();
1521 // TODO(dbeam): respect wallet_items_->default_address_id(). 1592 for (size_t i = 0; i < instruments.size(); ++i) {
1522 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon( 1593 // TODO(dbeam): respect wallet_items_->default_address_id().
1523 base::IntToString(i), 1594 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon(
1524 instruments[i]->DisplayName(), 1595 base::IntToString(i),
1525 instruments[i]->DisplayNameDetail(), 1596 instruments[i]->DisplayName(),
1526 instruments[i]->CardIcon()); 1597 instruments[i]->DisplayNameDetail(),
1598 instruments[i]->CardIcon());
1599 }
1527 } 1600 }
1528 } 1601 }
1529 1602
1530 suggested_cc_billing_.AddKeyedItem( 1603 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1531 std::string(), 1604 suggested_cc_billing_.AddKeyedItem(
1532 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_BILLING_DETAILS)); 1605 std::string(),
1606 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_BILLING_DETAILS));
1607 }
1533 } else { 1608 } else {
1534 PersonalDataManager* manager = GetManager(); 1609 PersonalDataManager* manager = GetManager();
1535 const std::vector<CreditCard*>& cards = manager->credit_cards(); 1610 const std::vector<CreditCard*>& cards = manager->credit_cards();
1536 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1611 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1537 for (size_t i = 0; i < cards.size(); ++i) { 1612 for (size_t i = 0; i < cards.size(); ++i) {
1538 suggested_cc_.AddKeyedItemWithIcon( 1613 suggested_cc_.AddKeyedItemWithIcon(
1539 cards[i]->guid(), 1614 cards[i]->guid(),
1540 cards[i]->Label(), 1615 cards[i]->Label(),
1541 rb.GetImageNamed(cards[i]->IconResourceId())); 1616 rb.GetImageNamed(cards[i]->IconResourceId()));
1542 } 1617 }
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1856 wallet_items_->obfuscated_gaia_id(), 1931 wallet_items_->obfuscated_gaia_id(),
1857 source_url_); 1932 source_url_);
1858 } else if (new_address.get()) { 1933 } else if (new_address.get()) {
1859 GetWalletClient()->SaveAddress(*new_address, source_url_); 1934 GetWalletClient()->SaveAddress(*new_address, source_url_);
1860 } else { 1935 } else {
1861 GetFullWallet(); 1936 GetFullWallet();
1862 } 1937 }
1863 } 1938 }
1864 1939
1865 void AutofillDialogControllerImpl::GetFullWallet() { 1940 void AutofillDialogControllerImpl::GetFullWallet() {
1866 DCHECK(did_submit_); 1941 DCHECK(is_submitting_);
1867 DCHECK(IsPayingWithWallet()); 1942 DCHECK(IsPayingWithWallet());
1868 DCHECK(wallet_items_); 1943 DCHECK(wallet_items_);
1869 DCHECK(!active_instrument_id_.empty()); 1944 DCHECK(!active_instrument_id_.empty());
1870 DCHECK(!active_address_id_.empty()); 1945 DCHECK(!active_address_id_.empty());
1871 1946
1872 GetWalletClient()->GetFullWallet(wallet::WalletClient::FullWalletRequest( 1947 GetWalletClient()->GetFullWallet(wallet::WalletClient::FullWalletRequest(
1873 active_instrument_id_, 1948 active_instrument_id_,
1874 active_address_id_, 1949 active_address_id_,
1875 source_url_, 1950 source_url_,
1876 wallet::Cart(base::IntToString(kCartMax), kCartCurrency), 1951 wallet::Cart(base::IntToString(kCartMax), kCartCurrency),
1877 wallet_items_->google_transaction_id(), 1952 wallet_items_->google_transaction_id(),
1878 std::vector<wallet::WalletClient::RiskCapability>())); 1953 std::vector<wallet::WalletClient::RiskCapability>()));
1879 } 1954 }
1880 1955
1881 void AutofillDialogControllerImpl::FinishSubmit() { 1956 void AutofillDialogControllerImpl::FinishSubmit() {
1882 FillOutputForSection(SECTION_EMAIL); 1957 FillOutputForSection(SECTION_EMAIL);
1883 FillOutputForSection(SECTION_CC); 1958 FillOutputForSection(SECTION_CC);
1884 FillOutputForSection(SECTION_BILLING); 1959 FillOutputForSection(SECTION_BILLING);
1885 FillOutputForSection(SECTION_CC_BILLING); 1960 FillOutputForSection(SECTION_CC_BILLING);
1961
1886 if (ShouldUseBillingForShipping()) { 1962 if (ShouldUseBillingForShipping()) {
1887 FillOutputForSectionWithComparator( 1963 FillOutputForSectionWithComparator(
1888 SECTION_BILLING, 1964 SECTION_BILLING,
1889 base::Bind(DetailInputMatchesShippingField)); 1965 base::Bind(DetailInputMatchesShippingField));
1890 FillOutputForSectionWithComparator( 1966 FillOutputForSectionWithComparator(
1891 SECTION_CC, 1967 SECTION_CC,
1892 base::Bind(DetailInputMatchesShippingField)); 1968 base::Bind(DetailInputMatchesShippingField));
1893 } else { 1969 } else {
1894 FillOutputForSection(SECTION_SHIPPING); 1970 FillOutputForSection(SECTION_SHIPPING);
1895 } 1971 }
1972
1896 callback_.Run(&form_structure_); 1973 callback_.Run(&form_structure_);
1897 callback_ = base::Callback<void(const FormStructure*)>(); 1974 callback_ = base::Callback<void(const FormStructure*)>();
1898 1975
1899 if (dialog_type_ == DIALOG_TYPE_REQUEST_AUTOCOMPLETE) { 1976 metric_logger_.LogDialogUiDuration(
1900 // This may delete us. 1977 base::Time::Now() - dialog_shown_timestamp_,
1901 Hide(); 1978 dialog_type_,
1979 AutofillMetrics::DIALOG_ACCEPTED);
1980
1981 switch (dialog_type_) {
1982 case DIALOG_TYPE_AUTOCHECKOUT:
1983 // Stop observing PersonalDataManager to avoid the dialog redrawing while
1984 // in an Autocheckout flow.
1985 GetManager()->RemoveObserver(this);
1986 autocheckout_is_running_ = true;
1987 autocheckout_started_timestamp_ = base::Time::Now();
1988 view_->UpdateButtonStrip();
1989 break;
1990
1991 case DIALOG_TYPE_REQUEST_AUTOCOMPLETE:
1992 // This may delete us.
1993 Hide();
1994 break;
1902 } 1995 }
1903 } 1996 }
1904 1997
1905 AutofillMetrics::DialogInitialUserStateMetric 1998 AutofillMetrics::DialogInitialUserStateMetric
1906 AutofillDialogControllerImpl::GetInitialUserState() const { 1999 AutofillDialogControllerImpl::GetInitialUserState() const {
1907 // Consider a user to be an Autofill user if the user has any credit cards 2000 // Consider a user to be an Autofill user if the user has any credit cards
1908 // or addresses saved. Check that the item count is greater than 1 because 2001 // or addresses saved. Check that the item count is greater than 1 because
1909 // an "empty" menu still has the "add new" menu item. 2002 // an "empty" menu still has the "add new" menu item.
1910 const bool has_autofill_profiles = 2003 const bool has_autofill_profiles =
1911 suggested_cc_.GetItemCount() > 1 || 2004 suggested_cc_.GetItemCount() > 1 ||
(...skipping 14 matching lines...) Expand all
1926 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL; 2019 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL;
1927 } 2020 }
1928 2021
1929 // Has Wallet items. 2022 // Has Wallet items.
1930 return has_autofill_profiles ? 2023 return has_autofill_profiles ?
1931 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL : 2024 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL :
1932 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL; 2025 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL;
1933 } 2026 }
1934 2027
1935 } // namespace autofill 2028 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698