Home | History | Annotate | Download | only in autofill
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
      6 
      7 #include "base/strings/string_split.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "chrome/browser/browser_process.h"
     10 #include "components/autofill/core/browser/address_i18n.h"
     11 #include "components/autofill/core/browser/autofill_profile.h"
     12 #include "components/autofill/core/browser/credit_card.h"
     13 #include "components/autofill/core/browser/field_types.h"
     14 #include "grit/components_strings.h"
     15 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h"
     16 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_field.h"
     17 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui.h"
     18 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui_component.h"
     19 #include "ui/base/l10n/l10n_util.h"
     20 
     21 namespace autofill {
     22 namespace i18ninput {
     23 
     24 namespace {
     25 
     26 using base::UTF16ToUTF8;
     27 using ::i18n::addressinput::AddressData;
     28 using ::i18n::addressinput::AddressField;
     29 using ::i18n::addressinput::AddressUiComponent;
     30 
     31 DetailInput::Length LengthFromHint(AddressUiComponent::LengthHint hint) {
     32   if (hint == AddressUiComponent::HINT_SHORT)
     33     return DetailInput::SHORT;
     34   DCHECK_EQ(hint, AddressUiComponent::HINT_LONG);
     35   return DetailInput::LONG;
     36 }
     37 
     38 }  // namespace
     39 
     40 void BuildAddressInputs(common::AddressType address_type,
     41                         const std::string& country_code,
     42                         DetailInputs* inputs,
     43                         std::string* language_code) {
     44   std::vector<AddressUiComponent> components(
     45       ::i18n::addressinput::BuildComponents(
     46           country_code, g_browser_process->GetApplicationLocale(),
     47           language_code));
     48 
     49   const bool billing = address_type == common::ADDRESS_TYPE_BILLING;
     50 
     51   for (size_t i = 0; i < components.size(); ++i) {
     52     const AddressUiComponent& component = components[i];
     53     if (component.field == ::i18n::addressinput::ORGANIZATION) {
     54       // TODO(dbeam): figure out when we actually need this.
     55       continue;
     56     }
     57 
     58     ServerFieldType server_type = TypeForField(component.field, address_type);
     59     DetailInput::Length length = LengthFromHint(component.length_hint);
     60     base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id);
     61     DetailInput input = { length, server_type, placeholder };
     62     inputs->push_back(input);
     63   }
     64 
     65   ServerFieldType server_type =
     66       billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY;
     67   base::string16 placeholder_text =
     68       l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COUNTRY);
     69   DetailInput input = { DetailInput::LONG, server_type, placeholder_text };
     70   inputs->push_back(input);
     71 }
     72 
     73 bool CardHasCompleteAndVerifiedData(const CreditCard& card) {
     74   if (!card.IsVerified())
     75     return false;
     76 
     77   const ServerFieldType required_fields[] = {
     78       CREDIT_CARD_NUMBER,
     79       CREDIT_CARD_EXP_MONTH,
     80       CREDIT_CARD_EXP_4_DIGIT_YEAR,
     81   };
     82 
     83   for (size_t i = 0; i < arraysize(required_fields); ++i) {
     84     if (card.GetRawInfo(required_fields[i]).empty())
     85       return false;
     86   }
     87 
     88   return true;
     89 }
     90 
     91 bool AddressHasCompleteAndVerifiedData(const AutofillProfile& profile,
     92                                        const std::string& app_locale) {
     93   if (!profile.IsVerified())
     94     return false;
     95 
     96   if (!i18n::CreateAddressDataFromAutofillProfile(profile, app_locale)->
     97           HasAllRequiredFields()) {
     98     return false;
     99   }
    100 
    101   const ServerFieldType more_required_fields[] = {
    102       NAME_FULL,
    103       PHONE_HOME_WHOLE_NUMBER
    104   };
    105 
    106   for (size_t i = 0; i < arraysize(more_required_fields); ++i) {
    107     if (profile.GetRawInfo(more_required_fields[i]).empty())
    108       return false;
    109   }
    110 
    111   return true;
    112 }
    113 
    114 ServerFieldType TypeForField(AddressField address_field,
    115                              common::AddressType address_type) {
    116   bool billing = address_type == common::ADDRESS_TYPE_BILLING;
    117   switch (address_field) {
    118     case ::i18n::addressinput::COUNTRY:
    119       return billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY;
    120     case ::i18n::addressinput::ADMIN_AREA:
    121       return billing ? ADDRESS_BILLING_STATE : ADDRESS_HOME_STATE;
    122     case ::i18n::addressinput::LOCALITY:
    123       return billing ? ADDRESS_BILLING_CITY : ADDRESS_HOME_CITY;
    124     case ::i18n::addressinput::DEPENDENT_LOCALITY:
    125       return billing ? ADDRESS_BILLING_DEPENDENT_LOCALITY :
    126                        ADDRESS_HOME_DEPENDENT_LOCALITY;
    127     case ::i18n::addressinput::POSTAL_CODE:
    128       return billing ? ADDRESS_BILLING_ZIP : ADDRESS_HOME_ZIP;
    129     case ::i18n::addressinput::SORTING_CODE:
    130       return billing ? ADDRESS_BILLING_SORTING_CODE : ADDRESS_HOME_SORTING_CODE;
    131     case ::i18n::addressinput::STREET_ADDRESS:
    132       return billing ? ADDRESS_BILLING_STREET_ADDRESS :
    133                        ADDRESS_HOME_STREET_ADDRESS;
    134     case ::i18n::addressinput::RECIPIENT:
    135       return billing ? NAME_BILLING_FULL : NAME_FULL;
    136     case ::i18n::addressinput::ORGANIZATION:
    137       return COMPANY_NAME;
    138   }
    139   NOTREACHED();
    140   return UNKNOWN_TYPE;
    141 }
    142 
    143 bool FieldForType(ServerFieldType server_type,
    144                   ::i18n::addressinput::AddressField* field) {
    145   switch (server_type) {
    146     case ADDRESS_BILLING_COUNTRY:
    147     case ADDRESS_HOME_COUNTRY:
    148       if (field)
    149         *field = ::i18n::addressinput::COUNTRY;
    150       return true;
    151     case ADDRESS_BILLING_STATE:
    152     case ADDRESS_HOME_STATE:
    153       if (field)
    154         *field = ::i18n::addressinput::ADMIN_AREA;
    155       return true;
    156     case ADDRESS_BILLING_CITY:
    157     case ADDRESS_HOME_CITY:
    158       if (field)
    159         *field = ::i18n::addressinput::LOCALITY;
    160       return true;
    161     case ADDRESS_BILLING_DEPENDENT_LOCALITY:
    162     case ADDRESS_HOME_DEPENDENT_LOCALITY:
    163       if (field)
    164         *field = ::i18n::addressinput::DEPENDENT_LOCALITY;
    165       return true;
    166     case ADDRESS_BILLING_SORTING_CODE:
    167     case ADDRESS_HOME_SORTING_CODE:
    168       if (field)
    169         *field = ::i18n::addressinput::SORTING_CODE;
    170       return true;
    171     case ADDRESS_BILLING_ZIP:
    172     case ADDRESS_HOME_ZIP:
    173       if (field)
    174         *field = ::i18n::addressinput::POSTAL_CODE;
    175       return true;
    176     case ADDRESS_BILLING_STREET_ADDRESS:
    177     case ADDRESS_BILLING_LINE1:
    178     case ADDRESS_BILLING_LINE2:
    179     case ADDRESS_HOME_STREET_ADDRESS:
    180     case ADDRESS_HOME_LINE1:
    181     case ADDRESS_HOME_LINE2:
    182       if (field)
    183         *field = ::i18n::addressinput::STREET_ADDRESS;
    184       return true;
    185     case COMPANY_NAME:
    186       if (field)
    187         *field = ::i18n::addressinput::ORGANIZATION;
    188       return true;
    189     case NAME_BILLING_FULL:
    190     case NAME_FULL:
    191       if (field)
    192         *field = ::i18n::addressinput::RECIPIENT;
    193       return true;
    194     default:
    195       return false;
    196   }
    197 }
    198 
    199 }  // namespace i18ninput
    200 }  // namespace autofill
    201