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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/payments/AddressEditor.java

Issue 2680143002: Use dropdown list for admin areas in pr form. (Closed)
Patch Set: Touch ups Created 3 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 package org.chromium.chrome.browser.payments; 5 package org.chromium.chrome.browser.payments;
6 6
7 import android.os.Handler; 7 import android.os.Handler;
8 import android.telephony.PhoneNumberUtils; 8 import android.telephony.PhoneNumberUtils;
9 import android.util.Pair; 9 import android.util.Pair;
10 10
11 import org.chromium.base.Callback; 11 import org.chromium.base.Callback;
12 import org.chromium.chrome.R; 12 import org.chromium.chrome.R;
13 import org.chromium.chrome.browser.autofill.PersonalDataManager; 13 import org.chromium.chrome.browser.autofill.PersonalDataManager;
14 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; 14 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
15 import org.chromium.chrome.browser.autofill.PersonalDataManager.GetSubKeysReques tDelegate;
15 import org.chromium.chrome.browser.payments.ui.EditorFieldModel; 16 import org.chromium.chrome.browser.payments.ui.EditorFieldModel;
16 import org.chromium.chrome.browser.payments.ui.EditorFieldModel.EditorFieldValid ator; 17 import org.chromium.chrome.browser.payments.ui.EditorFieldModel.EditorFieldValid ator;
17 import org.chromium.chrome.browser.payments.ui.EditorModel; 18 import org.chromium.chrome.browser.payments.ui.EditorModel;
18 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge; 19 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge;
19 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.Ad dressField; 20 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.Ad dressField;
20 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.Ad dressUiComponent; 21 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.Ad dressUiComponent;
21 22
22 import java.util.HashMap; 23 import java.util.HashMap;
23 import java.util.HashSet; 24 import java.util.HashSet;
24 import java.util.List; 25 import java.util.List;
25 import java.util.Locale; 26 import java.util.Locale;
26 import java.util.Map; 27 import java.util.Map;
27 import java.util.Set; 28 import java.util.Set;
28 29
29 import javax.annotation.Nullable; 30 import javax.annotation.Nullable;
30 31
31 /** 32 /**
32 * An address editor. Can be used for either shipping or billing address editing . 33 * An address editor. Can be used for either shipping or billing address editing .
33 */ 34 */
34 public class AddressEditor extends EditorBase<AutofillAddress> { 35 public class AddressEditor
36 extends EditorBase<AutofillAddress> implements GetSubKeysRequestDelegate {
35 private final Handler mHandler = new Handler(); 37 private final Handler mHandler = new Handler();
36 private final Map<Integer, EditorFieldModel> mAddressFields = new HashMap<>( ); 38 private final Map<Integer, EditorFieldModel> mAddressFields = new HashMap<>( );
37 private final Set<CharSequence> mPhoneNumbers = new HashSet<>(); 39 private final Set<CharSequence> mPhoneNumbers = new HashSet<>();
38 @Nullable private AutofillProfileBridge mAutofillProfileBridge; 40 @Nullable
39 @Nullable private EditorFieldModel mCountryField; 41 private AutofillProfileBridge mAutofillProfileBridge;
40 @Nullable private EditorFieldModel mPhoneField; 42 @Nullable
41 @Nullable private EditorFieldValidator mPhoneValidator; 43 private EditorFieldModel mCountryField;
42 @Nullable private List<AddressUiComponent> mAddressUiComponents; 44 @Nullable
45 private EditorFieldModel mPhoneField;
46 @Nullable
47 private EditorFieldValidator mPhoneValidator;
48 @Nullable
49 private List<AddressUiComponent> mAddressUiComponents;
50 private boolean mAdminAreasLoaded;
51 private boolean mOnCountryChange;
52 private Pair<String, Runnable> mEventData;
53 private AutofillProfile mProfile;
54 private EditorModel mEditor;
43 55
44 /** 56 /**
45 * Adds the given phone number to the autocomplete set, if it's valid. 57 * Adds the given phone number to the autocomplete set, if it's valid.
46 * 58 *
47 * @param phoneNumber The phone number to possibly add. 59 * @param phoneNumber The phone number to possibly add.
48 */ 60 */
49 public void addPhoneNumberIfValid(@Nullable CharSequence phoneNumber) { 61 public void addPhoneNumberIfValid(@Nullable CharSequence phoneNumber) {
50 if (getPhoneValidator().isValid(phoneNumber)) mPhoneNumbers.add(phoneNum ber); 62 if (getPhoneValidator().isValid(phoneNumber)) mPhoneNumbers.add(phoneNum ber);
51 } 63 }
52 64
(...skipping 12 matching lines...) Expand all
65 public void edit( 77 public void edit(
66 @Nullable final AutofillAddress toEdit, final Callback<AutofillAddre ss> callback) { 78 @Nullable final AutofillAddress toEdit, final Callback<AutofillAddre ss> callback) {
67 super.edit(toEdit, callback); 79 super.edit(toEdit, callback);
68 80
69 if (mAutofillProfileBridge == null) mAutofillProfileBridge = new Autofil lProfileBridge(); 81 if (mAutofillProfileBridge == null) mAutofillProfileBridge = new Autofil lProfileBridge();
70 82
71 // If |toEdit| is null, we're creating a new autofill profile with the c ountry code of the 83 // If |toEdit| is null, we're creating a new autofill profile with the c ountry code of the
72 // default locale on this device. 84 // default locale on this device.
73 boolean isNewAddress = toEdit == null; 85 boolean isNewAddress = toEdit == null;
74 86
75 // Ensure that |address| and |profile| are always not null. 87 // Ensure that |address| and |mProfile| are always not null.
76 final AutofillAddress address = 88 final AutofillAddress address =
77 isNewAddress ? new AutofillAddress(mContext, new AutofillProfile ()) : toEdit; 89 isNewAddress ? new AutofillAddress(mContext, new AutofillProfile ()) : toEdit;
78 final AutofillProfile profile = address.getProfile(); 90 mProfile = address.getProfile();
79 91
80 // The title of the editor depends on whether we're adding a new address or editing an 92 // The title of the editor depends on whether we're adding a new address or editing an
81 // existing address. 93 // existing address.
82 final EditorModel editor = 94 mEditor =
83 new EditorModel(isNewAddress 95 new EditorModel(isNewAddress ? mContext.getString(R.string.autof ill_create_profile)
84 ? mContext.getString(R.string.autofill_create_profile) 96 : toEdit.getEditTitle());
85 : toEdit.getEditTitle());
86 97
87 // The country dropdown is always present on the editor. 98 // The country dropdown is always present on the editor.
88 if (mCountryField == null) { 99 if (mCountryField == null) {
89 mCountryField = EditorFieldModel.createDropdown( 100 mCountryField = EditorFieldModel.createDropdown(
90 mContext.getString(R.string.autofill_profile_editor_country) , 101 mContext.getString(R.string.autofill_profile_editor_country) ,
91 AutofillProfileBridge.getSupportedCountries(), 102 AutofillProfileBridge.getSupportedCountries(), null /* hint */);
92 null /* hint */);
93 } 103 }
94 104
95 // Changing the country will update which fields are in the model. The a ctual fields are not 105 // Changing the country will update which fields are in the model. The a ctual fields are not
96 // discarded, so their contents are preserved. 106 // discarded, so their contents are preserved.
97 mCountryField.setDropdownCallback(new Callback<Pair<String, Runnable>>() { 107 mCountryField.setDropdownCallback(new Callback<Pair<String, Runnable>>() {
98 @Override 108 @Override
99 public void onResult(Pair<String, Runnable> eventData) { 109 public void onResult(Pair<String, Runnable> eventData) {
100 editor.removeAllFields(); 110 mEditor.removeAllFields();
101 editor.addField(mCountryField); 111 mEventData = eventData;
102 addAddressTextFieldsToEditor(editor, eventData.first, 112 mOnCountryChange = true;
103 Locale.getDefault().getLanguage()); 113 loadAdminAreas();
104 editor.addField(mPhoneField);
105
106 // Notify EditorView that the fields in the model have changed. EditorView should
107 // re-read the model and update the UI accordingly.
108 mHandler.post(eventData.second);
109 } 114 }
110 }); 115 });
111 116
112 // Country dropdown is cached, so the selected item needs to be updated for the new profile 117 // Country dropdown is cached, so the selected item needs to be updated for the new profile
113 // that's being edited. This will not fire the dropdown callback. 118 // that's being edited. This will not fire the dropdown callback.
114 mCountryField.setValue(AutofillAddress.getCountryCode(profile)); 119 mCountryField.setValue(AutofillAddress.getCountryCode(mProfile));
115 editor.addField(mCountryField);
116 120
117 // There's a finite number of fields for address editing. Changing the c ountry will re-order 121 // There's a finite number of fields for address editing. Changing the c ountry will re-order
118 // and relabel the fields. The meaning of each field remains the same. 122 // and relabel the fields. The meaning of each field remains the same.
119 if (mAddressFields.isEmpty()) { 123 if (mAddressFields.isEmpty()) {
120 // City, dependent locality, and organization don't have any special formatting hints. 124 // City, dependent locality, and organization don't have any special formatting hints.
121 mAddressFields.put(AddressField.LOCALITY, EditorFieldModel.createTex tInput()); 125 mAddressFields.put(AddressField.LOCALITY, EditorFieldModel.createTex tInput());
122 mAddressFields.put(AddressField.DEPENDENT_LOCALITY, EditorFieldModel .createTextInput()); 126 mAddressFields.put(AddressField.DEPENDENT_LOCALITY, EditorFieldModel .createTextInput());
123 mAddressFields.put(AddressField.ORGANIZATION, EditorFieldModel.creat eTextInput()); 127 mAddressFields.put(AddressField.ORGANIZATION, EditorFieldModel.creat eTextInput());
124 128
125 // State should be formatted in all capitals.
126 mAddressFields.put(AddressField.ADMIN_AREA, EditorFieldModel.createT extInput(
127 EditorFieldModel.INPUT_TYPE_HINT_REGION));
128
129 // Sorting code and postal code (a.k.a. ZIP code) should show both l etters and digits on 129 // Sorting code and postal code (a.k.a. ZIP code) should show both l etters and digits on
130 // the keyboard, if possible. 130 // the keyboard, if possible.
131 mAddressFields.put(AddressField.SORTING_CODE, EditorFieldModel.creat eTextInput( 131 mAddressFields.put(AddressField.SORTING_CODE,
132 EditorFieldModel.INPUT_TYPE_HINT_ALPHA_NUMERIC)); 132 EditorFieldModel.createTextInput(
133 mAddressFields.put(AddressField.POSTAL_CODE, EditorFieldModel.create TextInput( 133 EditorFieldModel.INPUT_TYPE_HINT_ALPHA_NUMERIC));
134 EditorFieldModel.INPUT_TYPE_HINT_ALPHA_NUMERIC)); 134 mAddressFields.put(AddressField.POSTAL_CODE,
135 EditorFieldModel.createTextInput(
136 EditorFieldModel.INPUT_TYPE_HINT_ALPHA_NUMERIC));
135 137
136 // Street line field can contain \n to indicate line breaks. 138 // Street line field can contain \n to indicate line breaks.
137 mAddressFields.put(AddressField.STREET_ADDRESS, EditorFieldModel.cre ateTextInput( 139 mAddressFields.put(AddressField.STREET_ADDRESS,
138 EditorFieldModel.INPUT_TYPE_HINT_STREET_LINES)); 140 EditorFieldModel.createTextInput(
141 EditorFieldModel.INPUT_TYPE_HINT_STREET_LINES));
139 142
140 // Android has special formatting rules for names. 143 // Android has special formatting rules for names.
141 mAddressFields.put(AddressField.RECIPIENT, EditorFieldModel.createTe xtInput( 144 mAddressFields.put(AddressField.RECIPIENT,
142 EditorFieldModel.INPUT_TYPE_HINT_PERSON_NAME)); 145 EditorFieldModel.createTextInput(EditorFieldModel.INPUT_TYPE _HINT_PERSON_NAME));
143 } 146 }
144 147
145 // Address fields are cached, so their values need to be updated for eve ry new profile
146 // that's being edited.
147 for (Map.Entry<Integer, EditorFieldModel> entry : mAddressFields.entrySe t()) {
148 entry.getValue().setValue(AutofillAddress.getProfileField(profile, e ntry.getKey()));
149 }
150
151 // Both country code and language code dictate which fields should be ad ded to the editor.
152 // For example, "US" will not add dependent locality to the editor. A "J P" address will
153 // start with a person's full name or a with a prefecture name, dependin g on whether the
154 // language code is "ja-Latn" or "ja".
155 addAddressTextFieldsToEditor(editor, profile.getCountryCode(), profile.g etLanguageCode());
156
157 // Phone number is present and required for all countries. 148 // Phone number is present and required for all countries.
158 if (mPhoneField == null) { 149 if (mPhoneField == null) {
159 mPhoneField = EditorFieldModel.createTextInput(EditorFieldModel.INPU T_TYPE_HINT_PHONE, 150 mPhoneField = EditorFieldModel.createTextInput(EditorFieldModel.INPU T_TYPE_HINT_PHONE,
160 mContext.getString(R.string.autofill_profile_editor_phone_nu mber), 151 mContext.getString(R.string.autofill_profile_editor_phone_nu mber),
161 mPhoneNumbers, getPhoneValidator(), null, 152 mPhoneNumbers, getPhoneValidator(), null,
162 mContext.getString(R.string.payments_field_required_validati on_message), 153 mContext.getString(R.string.payments_field_required_validati on_message),
163 mContext.getString(R.string.payments_phone_invalid_validatio n_message), null); 154 mContext.getString(R.string.payments_phone_invalid_validatio n_message), null);
164 } 155 }
165 156
166 // Phone number field is cached, so its value needs to be updated for ev ery new profile 157 // Phone number field is cached, so its value needs to be updated for ev ery new profile
167 // that's being edited. 158 // that's being edited.
168 mPhoneField.setValue(profile.getPhoneNumber()); 159 mPhoneField.setValue(mProfile.getPhoneNumber());
169 editor.addField(mPhoneField);
170 160
171 // If the user clicks [Cancel], send |toEdit| address back to the caller , which was the 161 // If the user clicks [Cancel], send |toEdit| address back to the caller , which was the
172 // original state (could be null, a complete address, a partial address) . 162 // original state (could be null, a complete address, a partial address) .
173 editor.setCancelCallback(new Runnable() { 163 mEditor.setCancelCallback(new Runnable() {
174 @Override 164 @Override
175 public void run() { 165 public void run() {
166 mAdminAreasLoaded = true;
167 PersonalDataManager.getInstance().cancelPendingGetSubKeys();
176 callback.onResult(toEdit); 168 callback.onResult(toEdit);
177 } 169 }
178 }); 170 });
179 171
180 // If the user clicks [Done], save changes on disk, mark the address "co mplete," and send it 172 // If the user clicks [Done], save changes on disk, mark the address "co mplete," and send it
181 // back to the caller. 173 // back to the caller.
182 editor.setDoneCallback(new Runnable() { 174 mEditor.setDoneCallback(new Runnable() {
183 @Override 175 @Override
184 public void run() { 176 public void run() {
185 commitChanges(profile); 177 mAdminAreasLoaded = true;
186 address.completeAddress(profile); 178 PersonalDataManager.getInstance().cancelPendingGetSubKeys();
179 commitChanges(mProfile);
180 address.completeAddress(mProfile);
187 callback.onResult(address); 181 callback.onResult(address);
188 } 182 }
189 }); 183 });
190 184
191 mEditorView.show(editor); 185 mOnCountryChange = false;
186 loadAdminAreas();
192 } 187 }
193 188
194 /** Saves the edited profile on disk. */ 189 /** Saves the edited profile on disk. */
195 private void commitChanges(AutofillProfile profile) { 190 private void commitChanges(AutofillProfile profile) {
196 // Country code and phone number are always required and are always coll ected from the 191 // Country code and phone number are always required and are always coll ected from the
197 // editor model. 192 // editor model.
198 profile.setCountryCode(mCountryField.getValue().toString()); 193 profile.setCountryCode(mCountryField.getValue().toString());
199 profile.setPhoneNumber(mPhoneField.getValue().toString()); 194 profile.setPhoneNumber(mPhoneField.getValue().toString());
200 195
201 // Autofill profile bridge normalizes the language code for the autofill profile. 196 // Autofill profile bridge normalizes the language code for the autofill profile.
(...skipping 11 matching lines...) Expand all
213 208
214 // Clear the fields that are hidden from the user interface, so 209 // Clear the fields that are hidden from the user interface, so
215 // AutofillAddress.toPaymentAddress() will send them to the renderer as empty strings. 210 // AutofillAddress.toPaymentAddress() will send them to the renderer as empty strings.
216 for (Map.Entry<Integer, EditorFieldModel> entry : mAddressFields.entrySe t()) { 211 for (Map.Entry<Integer, EditorFieldModel> entry : mAddressFields.entrySe t()) {
217 if (!visibleFields.contains(entry.getKey())) { 212 if (!visibleFields.contains(entry.getKey())) {
218 setProfileField(profile, entry.getKey(), ""); 213 setProfileField(profile, entry.getKey(), "");
219 } 214 }
220 } 215 }
221 216
222 // Save the edited autofill profile locally. 217 // Save the edited autofill profile locally.
223 profile.setGUID(PersonalDataManager.getInstance().setProfileToLocal(prof ile)); 218 profile.setGUID(PersonalDataManager.getInstance().setProfileToLocal(mPro file));
224 profile.setIsLocal(true); 219 profile.setIsLocal(true);
225 } 220 }
226 221
227 /** Writes the given value into the specified autofill profile field. */ 222 /** Writes the given value into the specified autofill profile field. */
228 private static void setProfileField( 223 private static void setProfileField(
229 AutofillProfile profile, int field, @Nullable CharSequence value) { 224 AutofillProfile profile, int field, @Nullable CharSequence value) {
230 assert profile != null; 225 assert profile != null;
231 switch (field) { 226 switch (field) {
232 case AddressField.COUNTRY: 227 case AddressField.COUNTRY:
233 profile.setCountryCode(ensureNotNull(value)); 228 profile.setCountryCode(ensureNotNull(value));
(...skipping 24 matching lines...) Expand all
258 return; 253 return;
259 } 254 }
260 255
261 assert false; 256 assert false;
262 } 257 }
263 258
264 private static String ensureNotNull(@Nullable CharSequence value) { 259 private static String ensureNotNull(@Nullable CharSequence value) {
265 return value == null ? "" : value.toString(); 260 return value == null ? "" : value.toString();
266 } 261 }
267 262
263 private void setAddressFieldValuesFromCache() {
264 // Address fields are cached, so their values need to be updated for eve ry new profile
265 // that's being edited.
266 for (Map.Entry<Integer, EditorFieldModel> entry : mAddressFields.entrySe t()) {
267 entry.getValue().setValue(AutofillAddress.getProfileField(mProfile, entry.getKey()));
268 }
269 }
270 /* Callback of the sub keys request that is called when the sub keys are loa ded.
271 Here the sub keys are admin areas (sub keys of the region=country.) */
272 @Override
273 public void onSubKeysReceived(String[] adminAreas) {
274 if (mAdminAreasLoaded) return;
275
276 mAdminAreasLoaded = true;
277
278 // If can't get admin areas from server or there is no admin area on the
279 // server, then use text field. Otherwise, use drop down list.
280 if (adminAreas == null || adminAreas.length == 0) {
281 mAddressFields.put(AddressField.ADMIN_AREA, EditorFieldModel.createT extInput());
282 } else {
283 mAddressFields.put(AddressField.ADMIN_AREA, EditorFieldModel.createD ropdown());
284 }
285
286 /* Admin Areas need to be fetched in two cases.
287 1. Initial loading of the form.
288 2. When the selected country is changed in the form.
289 mOnCountryChange is true iff it's the 2nd case. */
290 if (mOnCountryChange) {
291 // Both country code and language code dictate which fields should b e added to the
292 // editor.
293 // For example, "US" will not add dependent locality to the editor. A "JP" address will
294 // start with a person's full name or a with a prefecture name, depe nding on whether the
295 // language code is "ja-Latn" or "ja".
296 addAddressFieldsToEditor(
297 mEventData.first, Locale.getDefault().getLanguage(), adminAr eas);
298 // Notify EditorView that the fields in the model have changed. Edit orView should
299 // re-read the model and update the UI accordingly.
300 mHandler.post(mEventData.second);
301 } else {
302 // This should be called when all required fields are put in mAddres sField.
303 setAddressFieldValuesFromCache();
304 addAddressFieldsToEditor(
305 mProfile.getCountryCode(), mProfile.getLanguageCode(), admin Areas);
306 mEditorView.show(mEditor);
307 }
308 }
309
310 /** Requests the list of admin areas. */
311 public void loadAdminAreas() {
312 String countryCode = mOnCountryChange ? mEventData.first : mProfile.getC ountryCode();
313
314 // Used to check if the callback is called (for time-out).
315 mAdminAreasLoaded = false;
316
317 // In each rule, admin area keys are saved under sub keys of country.
318 PersonalDataManager.getInstance().loadRulesForSubKeys(countryCode);
319 PersonalDataManager.getInstance().getRegionSubKeys(countryCode, this);
320 onAdminAreasLoading();
321 }
322
323 /* In case the the admin areas are not loaded yet, starts a timer to cancel the request. */
324 public void onAdminAreasLoading() {
sebsg 2017/02/28 16:13:59 General question. Is it possible to query two diff
Parastoo 2017/03/21 14:30:44 Done.
325 if (!mAdminAreasLoaded) {
326 new Handler().postDelayed(new Runnable() {
327 @Override
328 public void run() {
329 if (!mAdminAreasLoaded) onSubKeysReceived(null);
330 PersonalDataManager.getInstance().cancelPendingGetSubKeys();
sebsg 2017/02/28 16:13:59 You also only need to call this if the rules are n
Parastoo 2017/03/21 14:30:44 Done.
331 }
332 }, PersonalDataManager.getLoadingTimeoutMS());
333 }
334 }
335
268 /** 336 /**
269 * Adds text fields to the editor model based on the country and language co de of the profile 337 * Adds fields to the editor model based on the country and language code of
270 * that's being edited. 338 * the profile that's being edited.
271 */ 339 */
272 private void addAddressTextFieldsToEditor( 340 private void addAddressFieldsToEditor(
273 EditorModel container, String countryCode, String languageCode) { 341 String countryCode, String languageCode, String[] adminAreas) {
274 mAddressUiComponents = mAutofillProfileBridge.getAddressUiComponents(cou ntryCode, 342 mAddressUiComponents =
275 languageCode); 343 mAutofillProfileBridge.getAddressUiComponents(countryCode, langu ageCode);
276 344 // In terms of order, country must be the first field.
sebsg 2017/02/28 16:13:59 nit: Country must be filled first.
Parastoo 2017/03/21 14:30:44 This means that in terms of order of appearance, c
345 mEditor.addField(mCountryField);
277 for (int i = 0; i < mAddressUiComponents.size(); i++) { 346 for (int i = 0; i < mAddressUiComponents.size(); i++) {
278 AddressUiComponent component = mAddressUiComponents.get(i); 347 AddressUiComponent component = mAddressUiComponents.get(i);
279 348
280 // The country field is a dropdown, so there's no need to add a text field for it.
281 if (component.id == AddressField.COUNTRY) continue;
282
283 EditorFieldModel field = mAddressFields.get(component.id); 349 EditorFieldModel field = mAddressFields.get(component.id);
284 // Labels depend on country, e.g., state is called province in some countries. These are 350 // Labels depend on country, e.g., state is called province in some countries. These are
285 // already localized. 351 // already localized.
286 field.setLabel(component.label); 352 field.setLabel(component.label);
287 field.setIsFullLine(component.isFullLine); 353 field.setIsFullLine(component.isFullLine);
288 354
355 if (component.id == AddressField.ADMIN_AREA && field.isDropdownField ()) {
356 field.setDropdownKeyValues(
357 mAutofillProfileBridge.getAdminAreaDropdownList(adminAre as));
358 }
359
289 // Libaddressinput formats do not always require the full name (RECI PIENT), but 360 // Libaddressinput formats do not always require the full name (RECI PIENT), but
290 // PaymentRequest does. 361 // PaymentRequest does.
291 if (component.isRequired || component.id == AddressField.RECIPIENT) { 362 if (component.isRequired || component.id == AddressField.RECIPIENT) {
292 field.setRequiredErrorMessage(mContext.getString( 363 field.setRequiredErrorMessage(
293 R.string.payments_field_required_validation_message)); 364 mContext.getString(R.string.payments_field_required_vali dation_message));
294 } else { 365 } else {
295 field.setRequiredErrorMessage(null); 366 field.setRequiredErrorMessage(null);
296 } 367 }
297 368 mEditor.addField(field);
298 container.addField(field);
299 } 369 }
370 // In terms of order, phone number must be the last field.
sebsg 2017/02/28 16:13:59 nit: Phone number must be the last field.
Parastoo 2017/03/21 14:30:44 Done.
371 mEditor.addField(mPhoneField);
300 } 372 }
301 373
302 private EditorFieldValidator getPhoneValidator() { 374 private EditorFieldValidator getPhoneValidator() {
303 if (mPhoneValidator == null) { 375 if (mPhoneValidator == null) {
304 mPhoneValidator = new EditorFieldValidator() { 376 mPhoneValidator = new EditorFieldValidator() {
305 @Override 377 @Override
306 public boolean isValid(@Nullable CharSequence value) { 378 public boolean isValid(@Nullable CharSequence value) {
307 return value != null 379 return value != null
308 && PhoneNumberUtils.isGlobalPhoneNumber( 380 && PhoneNumberUtils.isGlobalPhoneNumber(
309 PhoneNumberUtils.stripSeparators(value.toStr ing())); 381 PhoneNumberUtils.stripSeparators(value.to String()));
310 } 382 }
311 383
312 @Override 384 @Override
313 public boolean isLengthMaximum(@Nullable CharSequence value) { 385 public boolean isLengthMaximum(@Nullable CharSequence value) {
314 return false; 386 return false;
315 } 387 }
316 }; 388 };
317 } 389 }
318 return mPhoneValidator; 390 return mPhoneValidator;
319 } 391 }
320 } 392 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698