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

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: . 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 CreditCard* card, 164 CreditCard* card,
165 string16* cvc, 165 string16* cvc,
166 AutofillProfile* profile) { 166 AutofillProfile* profile) {
167 for (DetailOutputMap::const_iterator it = output.begin(); 167 for (DetailOutputMap::const_iterator it = output.begin();
168 it != output.end(); ++it) { 168 it != output.end(); ++it) {
169 string16 trimmed; 169 string16 trimmed;
170 TrimWhitespace(it->second, TRIM_ALL, &trimmed); 170 TrimWhitespace(it->second, TRIM_ALL, &trimmed);
171 171
172 // Special case CVC as CreditCard just swallows it. 172 // Special case CVC as CreditCard just swallows it.
173 if (it->first->type == CREDIT_CARD_VERIFICATION_CODE) { 173 if (it->first->type == CREDIT_CARD_VERIFICATION_CODE) {
174 cvc->assign(trimmed); 174 if (cvc)
175 cvc->assign(trimmed);
175 } else { 176 } else {
176 // Copy the credit card name to |profile| in addition to |card| as 177 // Copy the credit card name to |profile| in addition to |card| as
177 // wallet::Instrument requires a recipient name for its billing address. 178 // wallet::Instrument requires a recipient name for its billing address.
178 if (it->first->type == CREDIT_CARD_NAME) 179 if (profile && it->first->type == CREDIT_CARD_NAME)
179 profile->SetRawInfo(NAME_FULL, trimmed); 180 profile->SetRawInfo(NAME_FULL, trimmed);
180 181
181 if (IsCreditCardType(it->first->type)) 182 if (IsCreditCardType(it->first->type)) {
182 card->SetRawInfo(it->first->type, trimmed); 183 if (card)
183 else 184 card->SetRawInfo(it->first->type, trimmed);
185 } else if (profile) {
184 profile->SetRawInfo(it->first->type, trimmed); 186 profile->SetRawInfo(it->first->type, trimmed);
187 }
185 } 188 }
186 } 189 }
187 } 190 }
188 191
189 // Returns the containing window for the given |web_contents|. The containing 192 // Returns the containing window for the given |web_contents|. The containing
190 // window might be a browser window for a Chrome tab, or it might be a shell 193 // window might be a browser window for a Chrome tab, or it might be a shell
191 // window for a platform app. 194 // window for a platform app.
192 BaseWindow* GetBaseWindowForWebContents( 195 BaseWindow* GetBaseWindowForWebContents(
193 const content::WebContents* web_contents) { 196 const content::WebContents* web_contents) {
194 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 197 Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_email_(this)), 244 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_email_(this)),
242 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_cc_(this)), 245 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_cc_(this)),
243 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_billing_(this)), 246 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_billing_(this)),
244 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_cc_billing_(this)), 247 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_cc_billing_(this)),
245 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_shipping_(this)), 248 ALLOW_THIS_IN_INITIALIZER_LIST(suggested_shipping_(this)),
246 section_showing_popup_(SECTION_BILLING), 249 section_showing_popup_(SECTION_BILLING),
247 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), 250 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
248 metric_logger_(metric_logger), 251 metric_logger_(metric_logger),
249 initial_user_state_(AutofillMetrics::DIALOG_USER_STATE_UNKNOWN), 252 initial_user_state_(AutofillMetrics::DIALOG_USER_STATE_UNKNOWN),
250 dialog_type_(dialog_type), 253 dialog_type_(dialog_type),
251 did_submit_(false), 254 is_submitting_(false),
252 autocheckout_is_running_(false), 255 autocheckout_is_running_(false),
253 had_autocheckout_error_(false) { 256 had_autocheckout_error_(false) {
254 // TODO(estade): remove duplicates from |form|? 257 // TODO(estade): remove duplicates from |form|?
255 } 258 }
256 259
257 AutofillDialogControllerImpl::~AutofillDialogControllerImpl() { 260 AutofillDialogControllerImpl::~AutofillDialogControllerImpl() {
258 if (popup_controller_) 261 if (popup_controller_)
259 popup_controller_->Hide(); 262 popup_controller_->Hide();
260 263
261 metric_logger_.LogDialogInitialUserState(dialog_type_, initial_user_state_); 264 metric_logger_.LogDialogInitialUserState(dialog_type_, initial_user_state_);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 string16 AutofillDialogControllerImpl::UseBillingForShippingText() const { 423 string16 AutofillDialogControllerImpl::UseBillingForShippingText() const {
421 return l10n_util::GetStringUTF16( 424 return l10n_util::GetStringUTF16(
422 IDS_AUTOFILL_DIALOG_USE_BILLING_FOR_SHIPPING); 425 IDS_AUTOFILL_DIALOG_USE_BILLING_FOR_SHIPPING);
423 } 426 }
424 427
425 string16 AutofillDialogControllerImpl::CancelButtonText() const { 428 string16 AutofillDialogControllerImpl::CancelButtonText() const {
426 return l10n_util::GetStringUTF16(IDS_CANCEL); 429 return l10n_util::GetStringUTF16(IDS_CANCEL);
427 } 430 }
428 431
429 string16 AutofillDialogControllerImpl::ConfirmButtonText() const { 432 string16 AutofillDialogControllerImpl::ConfirmButtonText() const {
430 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SUBMIT_BUTTON); 433 return l10n_util::GetStringUTF16(IsSubmitPausedOn(wallet::VERIFY_CVV) ?
434 IDS_AUTOFILL_DIALOG_VERIFY_BUTTON : IDS_AUTOFILL_DIALOG_SUBMIT_BUTTON);
431 } 435 }
432 436
433 string16 AutofillDialogControllerImpl::CancelSignInText() const { 437 string16 AutofillDialogControllerImpl::CancelSignInText() const {
434 // TODO(abodenha): real strings and l10n. 438 // TODO(abodenha): real strings and l10n.
435 return ASCIIToUTF16("Don't sign in."); 439 return ASCIIToUTF16("Don't sign in.");
436 } 440 }
437 441
438 string16 AutofillDialogControllerImpl::SaveLocallyText() const { 442 string16 AutofillDialogControllerImpl::SaveLocallyText() const {
439 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SAVE_LOCALLY_CHECKBOX); 443 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SAVE_LOCALLY_CHECKBOX);
440 } 444 }
(...skipping 17 matching lines...) Expand all
458 } 462 }
459 463
460 bool AutofillDialogControllerImpl::ShouldShowSpinner() const { 464 bool AutofillDialogControllerImpl::ShouldShowSpinner() const {
461 return IsPayingWithWallet() && SignedInState() == REQUIRES_RESPONSE; 465 return IsPayingWithWallet() && SignedInState() == REQUIRES_RESPONSE;
462 } 466 }
463 467
464 string16 AutofillDialogControllerImpl::AccountChooserText() const { 468 string16 AutofillDialogControllerImpl::AccountChooserText() const {
465 if (!IsPayingWithWallet()) 469 if (!IsPayingWithWallet())
466 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PAY_WITHOUT_WALLET); 470 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PAY_WITHOUT_WALLET);
467 471
468 // TODO(dbeam): real strings and l10n.
469 if (SignedInState() == SIGNED_IN) 472 if (SignedInState() == SIGNED_IN)
470 return ASCIIToUTF16(current_username_); 473 return ASCIIToUTF16(current_username_);
471 474
472 // In this case, the account chooser should be showing the signin link. 475 // In this case, the account chooser should be showing the signin link.
473 return string16(); 476 return string16();
474 } 477 }
475 478
476 string16 AutofillDialogControllerImpl::SignInLinkText() const { 479 string16 AutofillDialogControllerImpl::SignInLinkText() const {
477 // TODO(estade): real strings and l10n. 480 // TODO(estade): real strings and l10n.
478 return ASCIIToUTF16("Sign in to use Google Wallet"); 481 return ASCIIToUTF16("Sign in to use Google Wallet");
479 } 482 }
480 483
481 bool AutofillDialogControllerImpl::ShouldOfferToSaveInChrome() const { 484 bool AutofillDialogControllerImpl::ShouldOfferToSaveInChrome() const {
482 return !IsPayingWithWallet(); 485 return !IsPayingWithWallet();
483 } 486 }
484 487
485 bool AutofillDialogControllerImpl::AutocheckoutIsRunning() const { 488 bool AutofillDialogControllerImpl::AutocheckoutIsRunning() const {
486 return autocheckout_is_running_; 489 return autocheckout_is_running_;
487 } 490 }
488 491
489 bool AutofillDialogControllerImpl::HadAutocheckoutError() const { 492 bool AutofillDialogControllerImpl::HadAutocheckoutError() const {
490 return had_autocheckout_error_; 493 return had_autocheckout_error_;
491 } 494 }
492 495
493 bool AutofillDialogControllerImpl::IsDialogButtonEnabled( 496 bool AutofillDialogControllerImpl::IsDialogButtonEnabled(
494 ui::DialogButton button) const { 497 ui::DialogButton button) const {
495 if (button == ui::DIALOG_BUTTON_OK) 498 if (button == ui::DIALOG_BUTTON_OK)
496 return !did_submit_; 499 return !is_submitting_ || IsSubmitPausedOn(wallet::VERIFY_CVV);
500
497 DCHECK_EQ(ui::DIALOG_BUTTON_CANCEL, button); 501 DCHECK_EQ(ui::DIALOG_BUTTON_CANCEL, button);
498 // TODO(ahutter): Make it possible for the user to cancel out of the dialog 502 // TODO(ahutter): Make it possible for the user to cancel out of the dialog
499 // while Autocheckout is in progress. 503 // while Autocheckout is in progress.
Dan Beam 2013/03/29 09:08:44 ^ and this TODO() is mainly why I'm avoiding chang
500 return had_autocheckout_error_ || !did_submit_; 504 return had_autocheckout_error_ || !is_submitting_ ||
505 dialog_type_ == DIALOG_TYPE_REQUEST_AUTOCOMPLETE;
501 } 506 }
502 507
503 bool AutofillDialogControllerImpl::SectionIsActive(DialogSection section) 508 bool AutofillDialogControllerImpl::SectionIsActive(DialogSection section)
504 const { 509 const {
510 if (IsSubmitPausedOn(wallet::VERIFY_CVV))
511 return section == SECTION_CC_BILLING;
512
505 if (IsPayingWithWallet()) 513 if (IsPayingWithWallet())
506 return section != SECTION_BILLING && section != SECTION_CC; 514 return section != SECTION_BILLING && section != SECTION_CC;
507 515
508 return section != SECTION_CC_BILLING; 516 return section != SECTION_CC_BILLING;
509 } 517 }
510 518
511 bool AutofillDialogControllerImpl::HasCompleteWallet() const { 519 bool AutofillDialogControllerImpl::HasCompleteWallet() const {
512 return wallet_items_.get() != NULL && 520 return wallet_items_.get() != NULL &&
513 !wallet_items_->instruments().empty() && 521 !wallet_items_->instruments().empty() &&
514 !wallet_items_->addresses().empty(); 522 !wallet_items_->addresses().empty();
515 } 523 }
516 524
525 bool AutofillDialogControllerImpl::IsSubmitPausedOn(
526 wallet::RequiredAction required_action) const {
527 return full_wallet_ && full_wallet_->HasRequiredAction(required_action);
528 }
529
517 void AutofillDialogControllerImpl::StartFetchingWalletItems() { 530 void AutofillDialogControllerImpl::StartFetchingWalletItems() {
518 DCHECK(IsPayingWithWallet()); 531 DCHECK(IsPayingWithWallet());
519 // TODO(dbeam): Add Risk capabilites once the UI supports risk challenges. 532 // TODO(dbeam): Add Risk capabilites once the UI supports risk challenges.
520 GetWalletClient()->GetWalletItems( 533 GetWalletClient()->GetWalletItems(
521 source_url_, 534 source_url_,
522 std::vector<wallet::WalletClient::RiskCapability>()); 535 std::vector<wallet::WalletClient::RiskCapability>());
523 } 536 }
524 537
525 void AutofillDialogControllerImpl::OnWalletOrSigninUpdate() { 538 void AutofillDialogControllerImpl::OnWalletOrSigninUpdate() {
526 if (wallet_items_.get()) { 539 if (wallet_items_.get()) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 case SECTION_SHIPPING: 654 case SECTION_SHIPPING:
642 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_SHIPPING); 655 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_SHIPPING);
643 default: 656 default:
644 NOTREACHED(); 657 NOTREACHED();
645 return string16(); 658 return string16();
646 } 659 }
647 } 660 }
648 661
649 string16 AutofillDialogControllerImpl::SuggestionTextForSection( 662 string16 AutofillDialogControllerImpl::SuggestionTextForSection(
650 DialogSection section) { 663 DialogSection section) {
664 string16 action_text = RequiredActionSuggestionTextForSection(section);
665 if (!action_text.empty())
666 return action_text;
667
651 // When the user has clicked 'edit', don't show a suggestion (even though 668 // When the user has clicked 'edit', don't show a suggestion (even though
652 // there is a profile selected in the model). 669 // there is a profile selected in the model).
653 if (section_editing_state_[section]) 670 if (section_editing_state_[section])
654 return string16(); 671 return string16();
655 672
656 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 673 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
657 std::string item_key = model->GetItemKeyForCheckedItem(); 674 std::string item_key = model->GetItemKeyForCheckedItem();
658 if (item_key.empty()) 675 if (item_key.empty())
659 return string16(); 676 return string16();
660 677
661 if (section == SECTION_EMAIL) 678 if (section == SECTION_EMAIL)
662 return model->GetLabelAt(model->checked_item()); 679 return model->GetLabelAt(model->checked_item());
663 680
664 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); 681 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section);
665 return wrapper->GetDisplayText(); 682 return wrapper->GetDisplayText();
666 } 683 }
667 684
685 string16 AutofillDialogControllerImpl::RequiredActionSuggestionTextForSection(
686 DialogSection section) {
687 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) {
688 const wallet::WalletItems::MaskedInstrument* current_instrument =
689 wallet_items_->GetInstrumentById(active_instrument_id_);
690 if (current_instrument)
691 return current_instrument->TypeAndLastFourDigits();
692
693 DetailOutputMap output;
694 view_->GetUserInput(section, &output);
695 CreditCard card;
696 GetBillingInfoFromOutputs(output, &card, NULL, NULL);
697 return card.TypeAndLastFourDigits();
698 }
699
700 return string16();
701 }
702
668 scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper( 703 scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper(
669 DialogSection section) { 704 DialogSection section) {
670 if (IsPayingWithWallet() && full_wallet_) { 705 if (IsPayingWithWallet() && full_wallet_ &&
706 !IsSubmitPausedOn(wallet::VERIFY_CVV)) {
671 if (section == SECTION_CC_BILLING) { 707 if (section == SECTION_CC_BILLING) {
672 return scoped_ptr<DataModelWrapper>( 708 return scoped_ptr<DataModelWrapper>(
673 new FullWalletBillingWrapper(full_wallet_.get())); 709 new FullWalletBillingWrapper(full_wallet_.get()));
674 } 710 }
675 if (section == SECTION_SHIPPING) { 711 if (section == SECTION_SHIPPING) {
676 return scoped_ptr<DataModelWrapper>( 712 return scoped_ptr<DataModelWrapper>(
677 new FullWalletShippingWrapper(full_wallet_.get())); 713 new FullWalletShippingWrapper(full_wallet_.get()));
678 } 714 }
679 } 715 }
680 716
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 std::vector<DialogNotification> 1010 std::vector<DialogNotification>
975 AutofillDialogControllerImpl::CurrentNotifications() const { 1011 AutofillDialogControllerImpl::CurrentNotifications() const {
976 std::vector<DialogNotification> notifications; 1012 std::vector<DialogNotification> notifications;
977 1013
978 if (IsPayingWithWallet()) { 1014 if (IsPayingWithWallet()) {
979 // TODO(dbeam): what about REQUIRES_PASSIVE_SIGN_IN? 1015 // TODO(dbeam): what about REQUIRES_PASSIVE_SIGN_IN?
980 if (SignedInState() == SIGNED_IN) { 1016 if (SignedInState() == SIGNED_IN) {
981 // On first run with a complete wallet profile, show a notification 1017 // On first run with a complete wallet profile, show a notification
982 // explaining where this data came from. 1018 // explaining where this data came from.
983 if (IsFirstRun() && HasCompleteWallet()) { 1019 if (IsFirstRun() && HasCompleteWallet()) {
984 notifications.push_back( 1020 notifications.push_back(DialogNotification(
985 DialogNotification( 1021 DialogNotification::EXPLANATORY_MESSAGE,
986 DialogNotification::EXPLANATORY_MESSAGE, 1022 l10n_util::GetStringUTF16(
987 l10n_util::GetStringUTF16( 1023 IDS_AUTOFILL_DIALOG_DETAILS_FROM_WALLET)));
988 IDS_AUTOFILL_DIALOG_DETAILS_FROM_WALLET)));
989 } else { 1024 } else {
990 notifications.push_back( 1025 notifications.push_back(DialogNotification(
991 DialogNotification( 1026 DialogNotification::WALLET_PROMO,
992 DialogNotification::WALLET_PROMO, 1027 l10n_util::GetStringUTF16(
993 l10n_util::GetStringUTF16( 1028 IDS_AUTOFILL_DIALOG_SAVE_DETAILS_IN_WALLET)));
994 IDS_AUTOFILL_DIALOG_SAVE_DETAILS_IN_WALLET)));
995 } 1029 }
996 } else if (IsFirstRun()) { 1030 } else if (IsFirstRun()) {
997 // If the user is not signed in, show an upsell notification on first run. 1031 // If the user is not signed in, show an upsell notification on first run.
998 notifications.push_back( 1032 notifications.push_back(DialogNotification(
999 DialogNotification( 1033 DialogNotification::WALLET_PROMO,
1000 DialogNotification::WALLET_PROMO, 1034 l10n_util::GetStringUTF16(
1001 l10n_util::GetStringUTF16( 1035 IDS_AUTOFILL_DIALOG_SIGN_IN_AND_SAVE_DETAILS)));
1002 IDS_AUTOFILL_DIALOG_SIGN_IN_AND_SAVE_DETAILS)));
1003 } 1036 }
1004 } 1037 }
1005 1038
1006 if (RequestingCreditCardInfo() && !TransmissionWillBeSecure()) { 1039 if (RequestingCreditCardInfo() && !TransmissionWillBeSecure()) {
1007 notifications.push_back( 1040 notifications.push_back(DialogNotification(
1008 DialogNotification( 1041 DialogNotification::SECURITY_WARNING,
1009 DialogNotification::SECURITY_WARNING, 1042 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECURITY_WARNING)));
1010 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECURITY_WARNING)));
1011 } 1043 }
1012 1044
1013 if (!invoked_from_same_origin_) { 1045 if (!invoked_from_same_origin_) {
1014 notifications.push_back( 1046 notifications.push_back(DialogNotification(
1015 DialogNotification( 1047 DialogNotification::SECURITY_WARNING,
1016 DialogNotification::SECURITY_WARNING, 1048 l10n_util::GetStringFUTF16(IDS_AUTOFILL_DIALOG_SITE_WARNING,
1017 l10n_util::GetStringFUTF16( 1049 UTF8ToUTF16(source_url_.host()))));
1018 IDS_AUTOFILL_DIALOG_SITE_WARNING, 1050 }
1019 UTF8ToUTF16(source_url_.host())))); 1051
1052 if (IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1053 notifications.push_back(DialogNotification(
1054 DialogNotification::REQUIRED_ACTION,
1055 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_VERIFY_CVV)));
1020 } 1056 }
1021 1057
1022 if (had_autocheckout_error_) { 1058 if (had_autocheckout_error_) {
1023 notifications.push_back( 1059 notifications.push_back(DialogNotification(
1024 DialogNotification( 1060 DialogNotification::AUTOCHECKOUT_ERROR,
1025 DialogNotification::AUTOCHECKOUT_ERROR, 1061 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_AUTOCHECKOUT_ERROR)));
1026 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_AUTOCHECKOUT_ERROR)));
1027 } 1062 }
1028 1063
1029 if (account_chooser_model_.had_wallet_error()) { 1064 if (account_chooser_model_.had_wallet_error()) {
1030 // TODO(dbeam): pass along the Wallet error or remove from the translation. 1065 // TODO(dbeam): pass along the Wallet error or remove from the translation.
1031 // TODO(dbeam): figure out a way to dismiss this error after a while. 1066 // TODO(dbeam): figure out a way to dismiss this error after a while.
1032 notifications.push_back(DialogNotification( 1067 notifications.push_back(DialogNotification(
1033 DialogNotification::WALLET_ERROR, 1068 DialogNotification::WALLET_ERROR,
1034 l10n_util::GetStringFUTF16( 1069 l10n_util::GetStringFUTF16(
1035 IDS_AUTOFILL_DIALOG_COMPLETE_WITHOUT_WALLET, 1070 IDS_AUTOFILL_DIALOG_COMPLETE_WITHOUT_WALLET,
1036 ASCIIToUTF16("Oops, [Wallet-Error].")))); 1071 ASCIIToUTF16("Oops, [Wallet-Error]."))));
1037 } 1072 }
1038 1073
1039 return notifications; 1074 return notifications;
1040 } 1075 }
1041 1076
1042 void AutofillDialogControllerImpl::StartSignInFlow() { 1077 void AutofillDialogControllerImpl::StartSignInFlow() {
1043 DCHECK(registrar_.IsEmpty()); 1078 DCHECK(registrar_.IsEmpty());
1044 1079
1045 content::Source<content::NavigationController> source(view_->ShowSignIn()); 1080 content::Source<content::NavigationController> source(view_->ShowSignIn());
1046 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, source); 1081 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, source);
1047 } 1082 }
1048 1083
1049 void AutofillDialogControllerImpl::EndSignInFlow() { 1084 void AutofillDialogControllerImpl::EndSignInFlow() {
1050 DCHECK(!registrar_.IsEmpty()); 1085 DCHECK(!registrar_.IsEmpty());
1051 registrar_.RemoveAll(); 1086 registrar_.RemoveAll();
1052 view_->HideSignIn(); 1087 view_->HideSignIn();
1053 } 1088 }
1054 1089
1055 void AutofillDialogControllerImpl::OnCancel() { 1090 void AutofillDialogControllerImpl::OnCancel() {
1056 if (!did_submit_) { 1091 // If the submit was successful, |callback_| will have already been |.Run()|
1057 metric_logger_.LogDialogUiDuration( 1092 // and nullified. If this is the case, no further actions are required. If
1058 base::Time::Now() - dialog_shown_timestamp_, 1093 // Autocheckout has an error, it's possible that the dialog will be submitted
1059 dialog_type_, 1094 // to start the flow and then cancelled to close the dialog after the error.
1060 AutofillMetrics::DIALOG_CANCELED); 1095 if (callback_.is_null())
1061 } 1096 return;
1062 1097
1063 // If Autocheckout has an error, it's possible that the dialog will be 1098 metric_logger_.LogDialogUiDuration(
1064 // submitted to start the flow and then cancelled to close the dialog after 1099 base::Time::Now() - dialog_shown_timestamp_,
1065 // the error. 1100 dialog_type_,
1066 if (!callback_.is_null()) { 1101 AutofillMetrics::DIALOG_CANCELED);
1067 callback_.Run(NULL); 1102
1068 callback_ = base::Callback<void(const FormStructure*)>(); 1103 callback_.Run(NULL);
1104 callback_ = base::Callback<void(const FormStructure*)>();
1105 }
1106
1107 void AutofillDialogControllerImpl::OnAccept() {
1108 is_submitting_ = true;
1109 view_->UpdateButtonStrip();
1110
1111 if (IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1112 DCHECK(!active_instrument_id_.empty());
1113 GetWalletClient()->AuthenticateInstrument(
1114 active_instrument_id_,
1115 UTF16ToUTF8(view_->GetCvc()),
1116 wallet_items_->obfuscated_gaia_id());
1117 } else if (IsPayingWithWallet()) {
1118 // TODO(dbeam): disallow switching payment methods while submitting.
1119 SubmitWithWallet();
1120 } else {
1121 FinishSubmit();
1069 } 1122 }
1070 } 1123 }
1071 1124
1072 void AutofillDialogControllerImpl::OnSubmit() {
1073 did_submit_ = true;
1074 metric_logger_.LogDialogUiDuration(
1075 base::Time::Now() - dialog_shown_timestamp_,
1076 dialog_type_,
1077 AutofillMetrics::DIALOG_ACCEPTED);
1078
1079 if (dialog_type_ == DIALOG_TYPE_AUTOCHECKOUT) {
1080 // Stop observing PersonalDataManager to avoid the dialog redrawing while
1081 // in an Autocheckout flow.
1082 GetManager()->RemoveObserver(this);
1083 autocheckout_is_running_ = true;
1084 autocheckout_started_timestamp_ = base::Time::Now();
1085 view_->UpdateButtonStrip();
1086 }
1087
1088 if (IsPayingWithWallet())
1089 SubmitWithWallet();
1090 else
1091 FinishSubmit();
1092 }
1093
1094 Profile* AutofillDialogControllerImpl::profile() { 1125 Profile* AutofillDialogControllerImpl::profile() {
1095 return profile_; 1126 return profile_;
1096 } 1127 }
1097 1128
1098 content::WebContents* AutofillDialogControllerImpl::web_contents() { 1129 content::WebContents* AutofillDialogControllerImpl::web_contents() {
1099 return contents_; 1130 return contents_;
1100 } 1131 }
1101 1132
1102 //////////////////////////////////////////////////////////////////////////////// 1133 ////////////////////////////////////////////////////////////////////////////////
1103 // AutofillPopupDelegate implementation. 1134 // AutofillPopupDelegate implementation.
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 void AutofillDialogControllerImpl::OnDidAuthenticateInstrument(bool success) { 1228 void AutofillDialogControllerImpl::OnDidAuthenticateInstrument(bool success) {
1198 // TODO(dbeam): use the returned full wallet. b/8332329 1229 // TODO(dbeam): use the returned full wallet. b/8332329
1199 if (success) 1230 if (success)
1200 GetFullWallet(); 1231 GetFullWallet();
1201 else 1232 else
1202 DisableWallet(); 1233 DisableWallet();
1203 } 1234 }
1204 1235
1205 void AutofillDialogControllerImpl::OnDidGetFullWallet( 1236 void AutofillDialogControllerImpl::OnDidGetFullWallet(
1206 scoped_ptr<wallet::FullWallet> full_wallet) { 1237 scoped_ptr<wallet::FullWallet> full_wallet) {
1207 // TODO(dbeam): handle more required actions.
1208 full_wallet_ = full_wallet.Pass(); 1238 full_wallet_ = full_wallet.Pass();
1209 1239
1210 if (full_wallet_->HasRequiredAction(wallet::VERIFY_CVV)) 1240 if (full_wallet_->required_actions().empty()) {
1211 DisableWallet();
1212 else
1213 FinishSubmit(); 1241 FinishSubmit();
1242 return;
1243 }
1244
1245 GenerateSuggestionsModels();
1246 view_->ModelChanged();
1247 view_->UpdateNotificationArea();
1248 view_->UpdateButtonStrip();
1214 } 1249 }
1215 1250
1216 void AutofillDialogControllerImpl::OnPassiveSigninSuccess( 1251 void AutofillDialogControllerImpl::OnPassiveSigninSuccess(
1217 const std::string& username) { 1252 const std::string& username) {
1218 DCHECK(IsPayingWithWallet()); 1253 DCHECK(IsPayingWithWallet());
1219 current_username_ = username; 1254 current_username_ = username;
1220 signin_helper_.reset(); 1255 signin_helper_.reset();
1221 wallet_items_.reset(); 1256 wallet_items_.reset();
1222 StartFetchingWalletItems(); 1257 StartFetchingWalletItems();
1223 } 1258 }
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 1420
1386 wallet::WalletClient* AutofillDialogControllerImpl::GetWalletClient() { 1421 wallet::WalletClient* AutofillDialogControllerImpl::GetWalletClient() {
1387 return &wallet_client_; 1422 return &wallet_client_;
1388 } 1423 }
1389 1424
1390 bool AutofillDialogControllerImpl::IsPayingWithWallet() const { 1425 bool AutofillDialogControllerImpl::IsPayingWithWallet() const {
1391 return account_chooser_model_.WalletIsSelected(); 1426 return account_chooser_model_.WalletIsSelected();
1392 } 1427 }
1393 1428
1394 void AutofillDialogControllerImpl::DisableWallet() { 1429 void AutofillDialogControllerImpl::DisableWallet() {
1430 is_submitting_ = false;
1431 if (view_)
1432 view_->UpdateButtonStrip();
1433
1395 signin_helper_.reset(); 1434 signin_helper_.reset();
1396 current_username_.clear(); 1435 current_username_.clear();
1397 account_chooser_model_.SetHadWalletError(); 1436 account_chooser_model_.SetHadWalletError();
1398 GetWalletClient()->CancelPendingRequests(); 1437 GetWalletClient()->CancelPendingRequests();
1438 full_wallet_.reset();
1399 } 1439 }
1400 1440
1401 void AutofillDialogControllerImpl::OnWalletSigninError() { 1441 void AutofillDialogControllerImpl::OnWalletSigninError() {
1402 signin_helper_.reset(); 1442 signin_helper_.reset();
1403 current_username_.clear(); 1443 current_username_.clear();
1404 account_chooser_model_.SetHadWalletSigninError(); 1444 account_chooser_model_.SetHadWalletSigninError();
1405 GetWalletClient()->CancelPendingRequests(); 1445 GetWalletClient()->CancelPendingRequests();
1406 } 1446 }
1407 1447
1408 bool AutofillDialogControllerImpl::IsFirstRun() const { 1448 bool AutofillDialogControllerImpl::IsFirstRun() const {
1409 PrefService* prefs = profile_->GetPrefs(); 1449 PrefService* prefs = profile_->GetPrefs();
1410 return !prefs->HasPrefPath(prefs::kAutofillDialogPayWithoutWallet); 1450 return !prefs->HasPrefPath(prefs::kAutofillDialogPayWithoutWallet);
1411 } 1451 }
1412 1452
1413 void AutofillDialogControllerImpl::GenerateSuggestionsModels() { 1453 void AutofillDialogControllerImpl::GenerateSuggestionsModels() {
1414 suggested_email_.Reset(); 1454 suggested_email_.Reset();
1415 suggested_cc_.Reset(); 1455 suggested_cc_.Reset();
1416 suggested_billing_.Reset(); 1456 suggested_billing_.Reset();
1417 suggested_cc_billing_.Reset(); 1457 suggested_cc_billing_.Reset();
1418 suggested_shipping_.Reset(); 1458 suggested_shipping_.Reset();
1419 1459
1420 if (IsPayingWithWallet()) { 1460 if (IsPayingWithWallet()) {
1421 if (wallet_items_.get()) { 1461 if (wallet_items_) {
1422 // TODO(estade): seems we need to hardcode the email address. 1462 // TODO(estade): seems we need to hardcode the email address.
1423 1463
1424 const std::vector<wallet::Address*>& addresses = 1464 const std::vector<wallet::Address*>& addresses =
1425 wallet_items_->addresses(); 1465 wallet_items_->addresses();
1426 for (size_t i = 0; i < addresses.size(); ++i) { 1466 for (size_t i = 0; i < addresses.size(); ++i) {
1427 // TODO(dbeam): respect wallet_items_->default_instrument_id(). 1467 // TODO(dbeam): respect wallet_items_->default_instrument_id().
1428 suggested_shipping_.AddKeyedItemWithSublabel( 1468 suggested_shipping_.AddKeyedItemWithSublabel(
1429 base::IntToString(i), 1469 base::IntToString(i),
1430 addresses[i]->DisplayName(), 1470 addresses[i]->DisplayName(),
1431 addresses[i]->DisplayNameDetail()); 1471 addresses[i]->DisplayNameDetail());
1432 } 1472 }
1433 1473
1434 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments = 1474 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1435 wallet_items_->instruments(); 1475 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments =
1436 for (size_t i = 0; i < instruments.size(); ++i) { 1476 wallet_items_->instruments();
1437 // TODO(dbeam): respect wallet_items_->default_address_id(). 1477 for (size_t i = 0; i < instruments.size(); ++i) {
1438 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon( 1478 // TODO(dbeam): respect wallet_items_->default_address_id().
1439 base::IntToString(i), 1479 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon(
1440 instruments[i]->DisplayName(), 1480 base::IntToString(i),
1441 instruments[i]->DisplayNameDetail(), 1481 instruments[i]->DisplayName(),
1442 instruments[i]->CardIcon()); 1482 instruments[i]->DisplayNameDetail(),
1483 instruments[i]->CardIcon());
1484 }
1443 } 1485 }
1444 } 1486 }
1445 1487
1446 suggested_cc_billing_.AddKeyedItem( 1488 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1447 std::string(), 1489 suggested_cc_billing_.AddKeyedItem(
1448 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_BILLING_DETAILS)); 1490 std::string(),
1491 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_BILLING_DETAILS));
1492 }
1449 } else { 1493 } else {
1450 PersonalDataManager* manager = GetManager(); 1494 PersonalDataManager* manager = GetManager();
1451 const std::vector<CreditCard*>& cards = manager->credit_cards(); 1495 const std::vector<CreditCard*>& cards = manager->credit_cards();
1452 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1496 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1453 for (size_t i = 0; i < cards.size(); ++i) { 1497 for (size_t i = 0; i < cards.size(); ++i) {
1454 suggested_cc_.AddKeyedItemWithIcon( 1498 suggested_cc_.AddKeyedItemWithIcon(
1455 cards[i]->guid(), 1499 cards[i]->guid(),
1456 cards[i]->Label(), 1500 cards[i]->Label(),
1457 rb.GetImageNamed(cards[i]->IconResourceId())); 1501 rb.GetImageNamed(cards[i]->IconResourceId()));
1458 } 1502 }
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 wallet_items_->obfuscated_gaia_id(), 1816 wallet_items_->obfuscated_gaia_id(),
1773 source_url_); 1817 source_url_);
1774 } else if (new_address.get()) { 1818 } else if (new_address.get()) {
1775 GetWalletClient()->SaveAddress(*new_address, source_url_); 1819 GetWalletClient()->SaveAddress(*new_address, source_url_);
1776 } else { 1820 } else {
1777 GetFullWallet(); 1821 GetFullWallet();
1778 } 1822 }
1779 } 1823 }
1780 1824
1781 void AutofillDialogControllerImpl::GetFullWallet() { 1825 void AutofillDialogControllerImpl::GetFullWallet() {
1782 DCHECK(did_submit_); 1826 DCHECK(is_submitting_);
1783 DCHECK(IsPayingWithWallet()); 1827 DCHECK(IsPayingWithWallet());
1784 DCHECK(wallet_items_); 1828 DCHECK(wallet_items_);
1785 DCHECK(!active_instrument_id_.empty()); 1829 DCHECK(!active_instrument_id_.empty());
1786 DCHECK(!active_address_id_.empty()); 1830 DCHECK(!active_address_id_.empty());
1787 1831
1788 GetWalletClient()->GetFullWallet(wallet::WalletClient::FullWalletRequest( 1832 GetWalletClient()->GetFullWallet(wallet::WalletClient::FullWalletRequest(
1789 active_instrument_id_, 1833 active_instrument_id_,
1790 active_address_id_, 1834 active_address_id_,
1791 source_url_, 1835 source_url_,
1792 wallet::Cart(base::IntToString(kCartMax), kCartCurrency), 1836 wallet::Cart(base::IntToString(kCartMax), kCartCurrency),
1793 wallet_items_->google_transaction_id(), 1837 wallet_items_->google_transaction_id(),
1794 std::vector<wallet::WalletClient::RiskCapability>())); 1838 std::vector<wallet::WalletClient::RiskCapability>()));
1795 } 1839 }
1796 1840
1797 void AutofillDialogControllerImpl::FinishSubmit() { 1841 void AutofillDialogControllerImpl::FinishSubmit() {
1798 FillOutputForSection(SECTION_EMAIL); 1842 FillOutputForSection(SECTION_EMAIL);
1799 FillOutputForSection(SECTION_CC); 1843 FillOutputForSection(SECTION_CC);
1800 FillOutputForSection(SECTION_BILLING); 1844 FillOutputForSection(SECTION_BILLING);
1801 FillOutputForSection(SECTION_CC_BILLING); 1845 FillOutputForSection(SECTION_CC_BILLING);
1846
1802 if (ShouldUseBillingForShipping()) { 1847 if (ShouldUseBillingForShipping()) {
1803 FillOutputForSectionWithComparator( 1848 FillOutputForSectionWithComparator(
1804 SECTION_BILLING, 1849 SECTION_BILLING,
1805 base::Bind(DetailInputMatchesShippingField)); 1850 base::Bind(DetailInputMatchesShippingField));
1806 FillOutputForSectionWithComparator( 1851 FillOutputForSectionWithComparator(
1807 SECTION_CC, 1852 SECTION_CC,
1808 base::Bind(DetailInputMatchesShippingField)); 1853 base::Bind(DetailInputMatchesShippingField));
1809 } else { 1854 } else {
1810 FillOutputForSection(SECTION_SHIPPING); 1855 FillOutputForSection(SECTION_SHIPPING);
1811 } 1856 }
1857
1812 callback_.Run(&form_structure_); 1858 callback_.Run(&form_structure_);
1813 callback_ = base::Callback<void(const FormStructure*)>(); 1859 callback_ = base::Callback<void(const FormStructure*)>();
1814 1860
1815 if (dialog_type_ == DIALOG_TYPE_REQUEST_AUTOCOMPLETE) { 1861 metric_logger_.LogDialogUiDuration(
1816 // This may delete us. 1862 base::Time::Now() - dialog_shown_timestamp_,
1817 Hide(); 1863 dialog_type_,
1864 AutofillMetrics::DIALOG_ACCEPTED);
1865
1866 switch (dialog_type_) {
1867 case DIALOG_TYPE_AUTOCHECKOUT:
1868 // Stop observing PersonalDataManager to avoid the dialog redrawing while
1869 // in an Autocheckout flow.
1870 GetManager()->RemoveObserver(this);
1871 autocheckout_is_running_ = true;
1872 autocheckout_started_timestamp_ = base::Time::Now();
1873 view_->UpdateButtonStrip();
1874 break;
1875
1876 case DIALOG_TYPE_REQUEST_AUTOCOMPLETE:
1877 // This may delete us.
1878 Hide();
1879 break;
1818 } 1880 }
1819 } 1881 }
1820 1882
1821 AutofillMetrics::DialogInitialUserStateMetric 1883 AutofillMetrics::DialogInitialUserStateMetric
1822 AutofillDialogControllerImpl::GetInitialUserState() const { 1884 AutofillDialogControllerImpl::GetInitialUserState() const {
1823 // Consider a user to be an Autofill user if the user has any credit cards 1885 // Consider a user to be an Autofill user if the user has any credit cards
1824 // or addresses saved. Check that the item count is greater than 1 because 1886 // or addresses saved. Check that the item count is greater than 1 because
1825 // an "empty" menu still has the "add new" menu item. 1887 // an "empty" menu still has the "add new" menu item.
1826 const bool has_autofill_profiles = 1888 const bool has_autofill_profiles =
1827 suggested_cc_.GetItemCount() > 1 || 1889 suggested_cc_.GetItemCount() > 1 ||
(...skipping 14 matching lines...) Expand all
1842 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL; 1904 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL;
1843 } 1905 }
1844 1906
1845 // Has Wallet items. 1907 // Has Wallet items.
1846 return has_autofill_profiles ? 1908 return has_autofill_profiles ?
1847 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL : 1909 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL :
1848 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL; 1910 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL;
1849 } 1911 }
1850 1912
1851 } // namespace autofill 1913 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698