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

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

Issue 12208070: allow wallet items to appear in requestAutocomplete UI (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: relative Created 7 years, 10 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <string> 7 #include <string>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/string_number_conversions.h"
10 #include "base/string_split.h" 11 #include "base/string_split.h"
11 #include "base/string_util.h" 12 #include "base/string_util.h"
12 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/autofill/autofill_country.h" 14 #include "chrome/browser/autofill/autofill_country.h"
14 #include "chrome/browser/autofill/autofill_manager.h" 15 #include "chrome/browser/autofill/autofill_manager.h"
15 #include "chrome/browser/autofill/autofill_type.h" 16 #include "chrome/browser/autofill/autofill_type.h"
16 #include "chrome/browser/autofill/personal_data_manager.h" 17 #include "chrome/browser/autofill/personal_data_manager.h"
17 #include "chrome/browser/autofill/personal_data_manager_factory.h" 18 #include "chrome/browser/autofill/personal_data_manager_factory.h"
18 #include "chrome/browser/autofill/validation.h" 19 #include "chrome/browser/autofill/validation.h"
19 #include "chrome/browser/autofill/wallet/full_wallet.h" 20 #include "chrome/browser/autofill/wallet/full_wallet.h"
20 #include "chrome/browser/autofill/wallet/wallet_items.h" 21 #include "chrome/browser/autofill/wallet/wallet_items.h"
21 #include "chrome/browser/autofill/wallet/wallet_service_url.h" 22 #include "chrome/browser/autofill/wallet/wallet_service_url.h"
22 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/autofill/autofill_dialog_view.h" 24 #include "chrome/browser/ui/autofill/autofill_dialog_view.h"
25 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
24 #include "chrome/common/form_data.h" 26 #include "chrome/common/form_data.h"
25 #include "content/public/browser/navigation_controller.h" 27 #include "content/public/browser/navigation_controller.h"
26 #include "content/public/browser/navigation_details.h" 28 #include "content/public/browser/navigation_details.h"
27 #include "content/public/browser/navigation_entry.h" 29 #include "content/public/browser/navigation_entry.h"
28 #include "content/public/browser/notification_service.h" 30 #include "content/public/browser/notification_service.h"
29 #include "content/public/browser/notification_types.h" 31 #include "content/public/browser/notification_types.h"
30 #include "content/public/browser/web_contents.h" 32 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/url_constants.h" 33 #include "content/public/common/url_constants.h"
32 #include "grit/chromium_strings.h" 34 #include "grit/chromium_strings.h"
33 #include "grit/generated_resources.h" 35 #include "grit/generated_resources.h"
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 // When the user has clicked 'edit', don't show a suggestion (even though 375 // When the user has clicked 'edit', don't show a suggestion (even though
374 // there is a profile selected in the model). 376 // there is a profile selected in the model).
375 if (section_editing_state_[section]) 377 if (section_editing_state_[section])
376 return string16(); 378 return string16();
377 379
378 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 380 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
379 std::string item_key = model->GetItemKeyAt(model->checked_item()); 381 std::string item_key = model->GetItemKeyAt(model->checked_item());
380 if (item_key.empty()) 382 if (item_key.empty())
381 return string16(); 383 return string16();
382 384
385 // TODO(estade): fix this.
386 if (CanPayWithWallet())
387 return string16();
388
383 if (section == SECTION_EMAIL) 389 if (section == SECTION_EMAIL)
384 return model->GetLabelAt(model->checked_item()); 390 return model->GetLabelAt(model->checked_item());
385 391
386 if (section == SECTION_CC) { 392 if (section == SECTION_CC) {
387 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key); 393 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key);
388 return card->TypeAndLastFourDigits(); 394 return card->TypeAndLastFourDigits();
389 } 395 }
390 396
391 const std::string app_locale = AutofillCountry::ApplicationLocale(); 397 scoped_ptr<DataModelWrapper> wrapper(CreateWrapper(section));
392 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key);
393 string16 comma = ASCIIToUTF16(", "); 398 string16 comma = ASCIIToUTF16(", ");
394 string16 label = profile->GetInfo(NAME_FULL, app_locale) + 399 string16 label = wrapper->GetInfo(NAME_FULL) +
ahutter 2013/02/12 15:46:42 Are we sure this way of displaying addresses local
Evan Stade 2013/02/12 18:10:22 it definitely doesn't. https://code.google.com/p/c
395 comma + profile->GetInfo(ADDRESS_HOME_LINE1, app_locale); 400 comma + wrapper->GetInfo(ADDRESS_HOME_LINE1);
396 string16 address2 = profile->GetInfo(ADDRESS_HOME_LINE2, app_locale); 401 string16 address2 = wrapper->GetInfo(ADDRESS_HOME_LINE2);
397 if (!address2.empty()) 402 if (!address2.empty())
398 label += comma + address2; 403 label += comma + address2;
399 label += ASCIIToUTF16("\n") + 404 label += ASCIIToUTF16("\n") +
400 profile->GetInfo(ADDRESS_HOME_CITY, app_locale) + comma + 405 wrapper->GetInfo(ADDRESS_HOME_CITY) + comma +
401 profile->GetInfo(ADDRESS_HOME_STATE, app_locale) + ASCIIToUTF16(" ") + 406 wrapper->GetInfo(ADDRESS_HOME_STATE) + ASCIIToUTF16(" ") +
402 profile->GetInfo(ADDRESS_HOME_ZIP, app_locale); 407 wrapper->GetInfo(ADDRESS_HOME_ZIP);
403 return label; 408 return label;
404 } 409 }
405 410
411 DataModelWrapper* AutofillDialogControllerImpl::CreateWrapper(
412 DialogSection section) {
413 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
414 std::string item_key = model->GetItemKeyAt(model->checked_item());
415 if (item_key.empty())
416 return NULL;
417
418 if (CanPayWithWallet()) {
419 int index;
420 if (!base::StringToInt(item_key, &index))
421 NOTREACHED();
422
423 if (section == SECTION_CC)
424 return new WalletInstrumentWrapper(wallet_items_->instruments()[index]);
425
426 return new WalletAddressWrapper(wallet_items_->addresses()[index]);
427 }
428
429 if (section == SECTION_CC) {
430 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key);
431 DCHECK(card);
432 return new AutofillCreditCardWrapper(card);
433 }
434
435 // Calculate the variant by looking at how many items come from the same
436 // FormGroup. TODO(estade): add a test for this.
437 size_t variant = 0;
438 for (int i = model->checked_item() - 1; i >= 0; --i) {
439 if (model->GetItemKeyAt(i) == item_key)
440 variant++;
441 else
442 break;
443 }
444
445 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key);
446 DCHECK(profile);
447 return new AutofillDataModelWrapper(profile, variant);
448 }
449
406 gfx::Image AutofillDialogControllerImpl::SuggestionIconForSection( 450 gfx::Image AutofillDialogControllerImpl::SuggestionIconForSection(
407 DialogSection section) { 451 DialogSection section) {
408 if (section != SECTION_CC) 452 if (section != SECTION_CC)
409 return gfx::Image(); 453 return gfx::Image();
410 454
411 std::string item_key = 455 scoped_ptr<DataModelWrapper> model(CreateWrapper(section));
412 suggested_cc_.GetItemKeyAt(suggested_cc_.checked_item()); 456 if (!model.get())
413 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 457 return gfx::Image();
414 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key); 458
415 return rb.GetImageNamed(card->IconResourceId()); 459 return model->GetIcon();
416 } 460 }
417 461
418 void AutofillDialogControllerImpl::EditClickedForSection( 462 void AutofillDialogControllerImpl::EditClickedForSection(
419 DialogSection section) { 463 DialogSection section) {
420 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 464 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
421 DetailInputs* inputs = MutableRequestedFieldsForSection(section); 465 DetailInputs* inputs = MutableRequestedFieldsForSection(section);
422 466
423 if (section == SECTION_EMAIL) { 467 if (section == SECTION_EMAIL) {
424 // TODO(estade): shouldn't need to make this check. 468 // TODO(estade): shouldn't need to make this check.
425 if (inputs->empty()) 469 if (inputs->empty())
426 return; 470 return;
427 471
428 (*inputs)[0].autofilled_value = model->GetLabelAt(model->checked_item()); 472 (*inputs)[0].autofilled_value = model->GetLabelAt(model->checked_item());
429 } else { 473 } else {
430 std::string guid = model->GetItemKeyAt(model->checked_item()); 474 scoped_ptr<DataModelWrapper> model(CreateWrapper(section));
431 DCHECK(!guid.empty()); 475 model->FillInputs(inputs);
432
433 FormGroup* form_group = section == SECTION_CC ?
434 static_cast<FormGroup*>(GetManager()->GetCreditCardByGUID(guid)) :
435 static_cast<FormGroup*>(GetManager()->GetProfileByGUID(guid));
436 DCHECK(form_group);
437 FillInputFromFormGroup(form_group, inputs);
438 } 476 }
439 477
440 section_editing_state_[section] = true; 478 section_editing_state_[section] = true;
441 view_->UpdateSection(section); 479 view_->UpdateSection(section);
442 } 480 }
443 481
444 bool AutofillDialogControllerImpl::InputIsValid(AutofillFieldType type, 482 bool AutofillDialogControllerImpl::InputIsValid(AutofillFieldType type,
445 const string16& value) { 483 const string16& value) {
446 // TODO(groby): Add the missing checks. 484 // TODO(groby): Add the missing checks.
447 switch (type) { 485 switch (type) {
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 WalletRequestCompleted(true); 732 WalletRequestCompleted(true);
695 } 733 }
696 734
697 void AutofillDialogControllerImpl::OnDidGetWalletItems( 735 void AutofillDialogControllerImpl::OnDidGetWalletItems(
698 scoped_ptr<wallet::WalletItems> wallet_items) { 736 scoped_ptr<wallet::WalletItems> wallet_items) {
699 bool items_changed = !wallet_items_ || *wallet_items != *wallet_items_; 737 bool items_changed = !wallet_items_ || *wallet_items != *wallet_items_;
700 wallet_items_ = wallet_items.Pass(); 738 wallet_items_ = wallet_items.Pass();
701 WalletRequestCompleted(true); 739 WalletRequestCompleted(true);
702 740
703 if (items_changed) { 741 if (items_changed) {
742 GenerateSuggestionsModels();
743 view_->ModelChanged();
704 view_->UpdateAccountChooser(); 744 view_->UpdateAccountChooser();
705 view_->UpdateNotificationArea(); 745 view_->UpdateNotificationArea();
706 } 746 }
707 } 747 }
708 748
709 void AutofillDialogControllerImpl::OnDidSaveAddress( 749 void AutofillDialogControllerImpl::OnDidSaveAddress(
710 const std::string& address_id) { 750 const std::string& address_id) {
711 NOTIMPLEMENTED() << " address_id=" << address_id; 751 NOTIMPLEMENTED() << " address_id=" << address_id;
712 WalletRequestCompleted(true); 752 WalletRequestCompleted(true);
713 } 753 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 } 844 }
805 845
806 wallet_client_.GetWalletItems(this); 846 wallet_client_.GetWalletItems(this);
807 refresh_wallet_items_queued_ = false; 847 refresh_wallet_items_queued_ = false;
808 } 848 }
809 849
810 void AutofillDialogControllerImpl::WalletRequestCompleted(bool success) { 850 void AutofillDialogControllerImpl::WalletRequestCompleted(bool success) {
811 if (!success) { 851 if (!success) {
812 had_wallet_error_ = true; 852 had_wallet_error_ = true;
813 wallet_items_.reset(); 853 wallet_items_.reset();
854 GenerateSuggestionsModels();
855 view_->ModelChanged();
814 view_->UpdateAccountChooser(); 856 view_->UpdateAccountChooser();
815 view_->UpdateNotificationArea(); 857 view_->UpdateNotificationArea();
816 return; 858 return;
817 } 859 }
818 860
819 if (refresh_wallet_items_queued_) 861 if (refresh_wallet_items_queued_)
820 ScheduleRefreshWalletItems(); 862 ScheduleRefreshWalletItems();
821 } 863 }
822 864
823 void AutofillDialogControllerImpl::GenerateSuggestionsModels() { 865 void AutofillDialogControllerImpl::GenerateSuggestionsModels() {
824 suggested_cc_.Reset(); 866 suggested_cc_.Reset();
825 suggested_billing_.Reset(); 867 suggested_billing_.Reset();
826 suggested_email_.Reset(); 868 suggested_email_.Reset();
827 suggested_shipping_.Reset(); 869 suggested_shipping_.Reset();
828 870
829 PersonalDataManager* manager = GetManager(); 871 if (CanPayWithWallet()) {
830 const std::vector<CreditCard*>& cards = manager->credit_cards(); 872 if (wallet_items_.get()) {
831 for (size_t i = 0; i < cards.size(); ++i) { 873 // TODO(estade): seems we need to hardcode the email address.
832 suggested_cc_.AddKeyedItem(cards[i]->guid(), cards[i]->Label()); 874 // TODO(estade): CC and billing need to be combined into one section,
833 } 875 // and suggestions added here.
834 // TODO(estade): real strings and i18n. 876 const std::vector<wallet::Address*>& addresses =
835 suggested_cc_.AddKeyedItem("", ASCIIToUTF16("Enter new card")); 877 wallet_items_->addresses();
836 878 for (size_t i = 0; i < addresses.size(); ++i) {
837 const std::vector<AutofillProfile*>& profiles = manager->GetProfiles(); 879 suggested_shipping_.AddKeyedItem(base::IntToString(i),
838 const std::string app_locale = AutofillCountry::ApplicationLocale(); 880 addresses[i]->DisplayName());
839 for (size_t i = 0; i < profiles.size(); ++i) { 881 }
840 if (!IsCompleteProfile(*profiles[i])) 882 }
841 continue; 883 } else {
842 884 PersonalDataManager* manager = GetManager();
843 // Add all email addresses. 885 const std::vector<CreditCard*>& cards = manager->credit_cards();
844 std::vector<string16> values; 886 for (size_t i = 0; i < cards.size(); ++i) {
845 profiles[i]->GetMultiInfo(EMAIL_ADDRESS, app_locale, &values); 887 suggested_cc_.AddKeyedItem(cards[i]->guid(), cards[i]->Label());
846 for (size_t j = 0; j < values.size(); ++j) {
847 if (!values[j].empty())
848 suggested_email_.AddKeyedItem(profiles[i]->guid(), values[j]);
849 } 888 }
850 889
851 // Don't add variants for addresses: the email variants are handled above, 890 const std::vector<AutofillProfile*>& profiles = manager->GetProfiles();
852 // name is part of credit card and we'll just ignore phone number variants. 891 const std::string app_locale = AutofillCountry::ApplicationLocale();
853 suggested_billing_.AddKeyedItem(profiles[i]->guid(), profiles[i]->Label()); 892 for (size_t i = 0; i < profiles.size(); ++i) {
854 suggested_shipping_.AddKeyedItem(profiles[i]->guid(), profiles[i]->Label()); 893 if (!IsCompleteProfile(*profiles[i]))
894 continue;
895
896 // Add all email addresses.
897 std::vector<string16> values;
898 profiles[i]->GetMultiInfo(EMAIL_ADDRESS, app_locale, &values);
899 for (size_t j = 0; j < values.size(); ++j) {
900 if (!values[j].empty())
901 suggested_email_.AddKeyedItem(profiles[i]->guid(), values[j]);
902 }
903
904 // Don't add variants for addresses: the email variants are handled above,
905 // name is part of credit card and we'll just ignore phone number
906 // variants.
907 suggested_billing_.AddKeyedItem(profiles[i]->guid(),
908 profiles[i]->Label());
909 suggested_shipping_.AddKeyedItem(profiles[i]->guid(),
910 profiles[i]->Label());
911 }
855 } 912 }
856 913
857 // TODO(estade): real strings and i18n. 914 // TODO(estade): real strings and i18n.
915 suggested_cc_.AddKeyedItem("", ASCIIToUTF16("Enter new card"));
858 suggested_billing_.AddKeyedItem("", ASCIIToUTF16("Enter new billing")); 916 suggested_billing_.AddKeyedItem("", ASCIIToUTF16("Enter new billing"));
859 suggested_email_.AddKeyedItem("", ASCIIToUTF16("Enter new email")); 917 suggested_email_.AddKeyedItem("", ASCIIToUTF16("Enter new email"));
860 suggested_shipping_.AddKeyedItem("", ASCIIToUTF16("Enter new shipping")); 918 suggested_shipping_.AddKeyedItem("", ASCIIToUTF16("Enter new shipping"));
861 } 919 }
862 920
863 bool AutofillDialogControllerImpl::IsCompleteProfile( 921 bool AutofillDialogControllerImpl::IsCompleteProfile(
864 const AutofillProfile& profile) { 922 const AutofillProfile& profile) {
865 const std::string app_locale = AutofillCountry::ApplicationLocale(); 923 const std::string app_locale = AutofillCountry::ApplicationLocale();
866 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) { 924 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) {
867 if (profile.GetInfo(requested_shipping_fields_[i].type, 925 if (profile.GetInfo(requested_shipping_fields_[i].type,
868 app_locale).empty()) { 926 app_locale).empty()) {
869 return false; 927 return false;
870 } 928 }
871 } 929 }
872 930
873 return true; 931 return true;
874 } 932 }
875 933
876 void AutofillDialogControllerImpl::FillOutputForSectionWithComparator( 934 void AutofillDialogControllerImpl::FillOutputForSectionWithComparator(
877 DialogSection section, 935 DialogSection section,
878 const InputFieldComparator& compare) { 936 const InputFieldComparator& compare) {
879 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 937 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
880 std::string guid = model->GetItemKeyAt(model->checked_item()); 938 std::string item_key = model->GetItemKeyAt(model->checked_item());
881 PersonalDataManager* manager = GetManager(); 939 PersonalDataManager* manager = GetManager();
882 if (!guid.empty() && !section_editing_state_[section]) { 940 if (!item_key.empty() && !section_editing_state_[section]) {
883 FormGroup* form_group = section == SECTION_CC ? 941 scoped_ptr<DataModelWrapper> model(CreateWrapper(section));
884 static_cast<FormGroup*>(manager->GetCreditCardByGUID(guid)) : 942 // Only fill in data that is associated with this section.
885 static_cast<FormGroup*>(manager->GetProfileByGUID(guid)); 943 const DetailInputs& inputs = RequestedFieldsForSection(section);
886 DCHECK(form_group); 944 model->FillFormStructure(inputs, compare, &form_structure_);
887
888 // Calculate the variant by looking at how many items come from the same
889 // FormGroup. TODO(estade): add a test for this.
890 size_t variant = 0;
891 for (int i = model->checked_item() - 1; i >= 0; --i) {
892 if (model->GetItemKeyAt(i) == guid)
893 variant++;
894 else
895 break;
896 }
897
898 FillFormStructureForSection(*form_group, variant, section, compare);
899 945
900 // CVC needs special-casing because the CreditCard class doesn't store 946 // CVC needs special-casing because the CreditCard class doesn't store
901 // or handle them. 947 // or handle them.
902 if (section == SECTION_CC) 948 if (section == SECTION_CC)
903 SetCvcResult(view_->GetCvc()); 949 SetCvcResult(view_->GetCvc());
904 } else { 950 } else {
905 // The user manually input data. 951 // The user manually input data.
906 DetailOutputMap output; 952 DetailOutputMap output;
907 view_->GetUserInput(section, &output); 953 view_->GetUserInput(section, &output);
908 954
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 DialogSection section) { 1054 DialogSection section) {
1009 return const_cast<DetailInputs*>(&RequestedFieldsForSection(section)); 1055 return const_cast<DetailInputs*>(&RequestedFieldsForSection(section));
1010 } 1056 }
1011 1057
1012 void AutofillDialogControllerImpl::HidePopup() { 1058 void AutofillDialogControllerImpl::HidePopup() {
1013 if (popup_controller_) 1059 if (popup_controller_)
1014 popup_controller_->Hide(); 1060 popup_controller_->Hide();
1015 } 1061 }
1016 1062
1017 } // namespace autofill 1063 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/browser/ui/autofill/autofill_dialog_controller_impl.h ('k') | chrome/browser/ui/autofill/autofill_dialog_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698