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

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

Issue 2109573002: Revert of Refactor contact editor controller into its own class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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.app.Activity; 7 import android.app.Activity;
8 import android.graphics.Bitmap; 8 import android.graphics.Bitmap;
9 import android.os.Handler; 9 import android.os.Handler;
10 import android.telephony.PhoneNumberUtils;
10 import android.text.TextUtils; 11 import android.text.TextUtils;
12 import android.util.Patterns;
11 13
12 import org.chromium.base.Callback; 14 import org.chromium.base.Callback;
13 import org.chromium.base.Log; 15 import org.chromium.base.Log;
14 import org.chromium.base.VisibleForTesting; 16 import org.chromium.base.VisibleForTesting;
17 import org.chromium.chrome.R;
15 import org.chromium.chrome.browser.autofill.PersonalDataManager; 18 import org.chromium.chrome.browser.autofill.PersonalDataManager;
16 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; 19 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
17 import org.chromium.chrome.browser.favicon.FaviconHelper; 20 import org.chromium.chrome.browser.favicon.FaviconHelper;
21 import org.chromium.chrome.browser.payments.ui.EditorFieldModel;
22 import org.chromium.chrome.browser.payments.ui.EditorFieldModel.EditorFieldValid ator;
23 import org.chromium.chrome.browser.payments.ui.EditorModel;
18 import org.chromium.chrome.browser.payments.ui.LineItem; 24 import org.chromium.chrome.browser.payments.ui.LineItem;
19 import org.chromium.chrome.browser.payments.ui.PaymentInformation; 25 import org.chromium.chrome.browser.payments.ui.PaymentInformation;
20 import org.chromium.chrome.browser.payments.ui.PaymentOption; 26 import org.chromium.chrome.browser.payments.ui.PaymentOption;
21 import org.chromium.chrome.browser.payments.ui.PaymentRequestUI; 27 import org.chromium.chrome.browser.payments.ui.PaymentRequestUI;
22 import org.chromium.chrome.browser.payments.ui.SectionInformation; 28 import org.chromium.chrome.browser.payments.ui.SectionInformation;
23 import org.chromium.chrome.browser.payments.ui.ShoppingCart; 29 import org.chromium.chrome.browser.payments.ui.ShoppingCart;
24 import org.chromium.chrome.browser.preferences.PreferencesLauncher; 30 import org.chromium.chrome.browser.preferences.PreferencesLauncher;
25 import org.chromium.chrome.browser.preferences.autofill.AutofillCreditCardEditor ; 31 import org.chromium.chrome.browser.preferences.autofill.AutofillCreditCardEditor ;
26 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileEditor; 32 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileEditor;
27 import org.chromium.chrome.browser.profiles.Profile; 33 import org.chromium.chrome.browser.profiles.Profile;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 private SectionInformation mShippingAddressesSection; 128 private SectionInformation mShippingAddressesSection;
123 private SectionInformation mContactSection; 129 private SectionInformation mContactSection;
124 private List<PaymentApp> mPendingApps; 130 private List<PaymentApp> mPendingApps;
125 private List<PaymentInstrument> mPendingInstruments; 131 private List<PaymentInstrument> mPendingInstruments;
126 private SectionInformation mPaymentMethodsSection; 132 private SectionInformation mPaymentMethodsSection;
127 private PaymentRequestUI mUI; 133 private PaymentRequestUI mUI;
128 private Callback<PaymentInformation> mPaymentInformationCallback; 134 private Callback<PaymentInformation> mPaymentInformationCallback;
129 private Pattern mRegionCodePattern; 135 private Pattern mRegionCodePattern;
130 private boolean mMerchantNeedsShippingAddress; 136 private boolean mMerchantNeedsShippingAddress;
131 private boolean mPaymentAppRunning; 137 private boolean mPaymentAppRunning;
132 private ContactEditor mContactEditor; 138 private boolean mRequestPayerPhone;
139 private boolean mRequestPayerEmail;
140 private List<CharSequence> mAllPhoneNumbers;
141 private List<CharSequence> mAllEmailAddresses;
142 private EditorFieldValidator mPhoneValidator;
143 private EditorFieldValidator mEmailValidator;
133 144
134 /** 145 /**
135 * Builds the PaymentRequest service implementation. 146 * Builds the PaymentRequest service implementation.
136 * 147 *
137 * @param webContents The web contents that have invoked the PaymentRequest API. 148 * @param webContents The web contents that have invoked the PaymentRequest API.
138 */ 149 */
139 public PaymentRequestImpl(WebContents webContents) { 150 public PaymentRequestImpl(WebContents webContents) {
140 if (webContents == null) return; 151 if (webContents == null) return;
141 152
142 ContentViewCore contentViewCore = ContentViewCore.fromWebContents(webCon tents); 153 ContentViewCore contentViewCore = ContentViewCore.fromWebContents(webCon tents);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 } 220 }
210 221
211 if (!parseAndValidateDetailsOrDisconnectFromClient(details)) return; 222 if (!parseAndValidateDetailsOrDisconnectFromClient(details)) return;
212 223
213 // If the merchant requests shipping and does not provide a selected shi pping option, then 224 // If the merchant requests shipping and does not provide a selected shi pping option, then
214 // the merchant needs the shipping address to calculate the shipping pri ce and availability. 225 // the merchant needs the shipping address to calculate the shipping pri ce and availability.
215 boolean requestShipping = options != null && options.requestShipping; 226 boolean requestShipping = options != null && options.requestShipping;
216 mMerchantNeedsShippingAddress = 227 mMerchantNeedsShippingAddress =
217 requestShipping && mUiShippingOptions.getSelectedItem() == null; 228 requestShipping && mUiShippingOptions.getSelectedItem() == null;
218 229
219 boolean requestPayerPhone = options != null && options.requestPayerPhone ; 230 mRequestPayerPhone = options != null && options.requestPayerPhone;
220 boolean requestPayerEmail = options != null && options.requestPayerEmail ; 231 mRequestPayerEmail = options != null && options.requestPayerEmail;
221 if (requestPayerPhone || requestPayerEmail) {
222 mContactEditor = new ContactEditor(requestPayerPhone, requestPayerEm ail);
223 }
224 232
225 if (requestShipping || requestPayerPhone || requestPayerEmail) { 233 if (requestShipping || mRequestPayerPhone || mRequestPayerEmail) {
226 List<AutofillProfile> profiles = 234 List<AutofillProfile> profiles =
227 PersonalDataManager.getInstance().getProfilesToSuggest(); 235 PersonalDataManager.getInstance().getProfilesToSuggest();
228 List<AutofillContact> contacts = new ArrayList<>(); 236 List<AutofillContact> contacts = new ArrayList<>();
229 List<AutofillAddress> addresses = new ArrayList<>(); 237 List<AutofillAddress> addresses = new ArrayList<>();
238 mAllPhoneNumbers = new ArrayList<>();
239 mAllEmailAddresses = new ArrayList<>();
230 int firstCompleteContactIndex = SectionInformation.NO_SELECTION; 240 int firstCompleteContactIndex = SectionInformation.NO_SELECTION;
231 for (int i = 0; i < profiles.size(); i++) { 241 for (int i = 0; i < profiles.size(); i++) {
232 AutofillProfile profile = profiles.get(i); 242 AutofillProfile profile = profiles.get(i);
233 243
234 String phone = requestPayerPhone && !TextUtils.isEmpty(profile.g etPhoneNumber()) 244 String phone = mRequestPayerPhone && !TextUtils.isEmpty(profile. getPhoneNumber())
235 ? profile.getPhoneNumber() : null; 245 ? profile.getPhoneNumber() : null;
236 String email = requestPayerEmail && !TextUtils.isEmpty(profile.g etEmailAddress()) 246 String email = mRequestPayerEmail && !TextUtils.isEmpty(profile. getEmailAddress())
237 ? profile.getEmailAddress() : null; 247 ? profile.getEmailAddress() : null;
238 if (phone != null || email != null) { 248 if (phone != null || email != null) {
239 boolean isComplete = mContactEditor.isContactInformationComp lete(phone, email); 249 boolean isComplete = isContactInformationComplete(phone, ema il);
240 contacts.add(new AutofillContact(profile, phone, email, isCo mplete)); 250 contacts.add(new AutofillContact(profile, phone, email, isCo mplete));
241 if (isComplete && firstCompleteContactIndex < 0) firstComple teContactIndex = i; 251 if (isComplete && firstCompleteContactIndex < 0) firstComple teContactIndex = i;
242 mContactEditor.addPhoneNumberIfValid(phone); 252 if (getPhoneValidator().isValid(phone)) mAllPhoneNumbers.add (phone);
243 mContactEditor.addEmailAddressIfValid(email); 253 if (getEmailValidator().isValid(email)) mAllEmailAddresses.a dd(email);
244 } 254 }
245 255
246 if (canUseAddress(profile, requestShipping)) { 256 if (canUseAddress(profile, requestShipping)) {
247 addresses.add(new AutofillAddress(profile)); 257 addresses.add(new AutofillAddress(profile));
248 } 258 }
249 } 259 }
250 260
251 if (requestShipping) { 261 if (requestShipping) {
252 int selectedIndex = SectionInformation.NO_SELECTION; 262 int selectedIndex = SectionInformation.NO_SELECTION;
253 if (!addresses.isEmpty() && mUiShippingOptions.getSelectedItem() != null) { 263 if (!addresses.isEmpty() && mUiShippingOptions.getSelectedItem() != null) {
254 selectedIndex = 0; 264 selectedIndex = 0;
255 } 265 }
256 mShippingAddressesSection = new SectionInformation( 266 mShippingAddressesSection = new SectionInformation(
257 PaymentRequestUI.TYPE_SHIPPING_ADDRESSES, selectedIndex, addresses); 267 PaymentRequestUI.TYPE_SHIPPING_ADDRESSES, selectedIndex, addresses);
258 } 268 }
259 269
260 // The contact section automatically selects the first complete entr y. 270 // The contact section automatically selects the first complete entr y.
261 if (requestPayerPhone || requestPayerEmail) { 271 if (mRequestPayerPhone || mRequestPayerEmail) {
262 mContactSection = new SectionInformation( 272 mContactSection = new SectionInformation(
263 PaymentRequestUI.TYPE_CONTACT_DETAILS, firstCompleteCont actIndex, contacts); 273 PaymentRequestUI.TYPE_CONTACT_DETAILS, firstCompleteCont actIndex, contacts);
264 } 274 }
265 } 275 }
266 276
267 mPendingApps = new ArrayList<>(mApps); 277 mPendingApps = new ArrayList<>(mApps);
268 mPendingInstruments = new ArrayList<>(); 278 mPendingInstruments = new ArrayList<>();
269 boolean isGettingInstruments = false; 279 boolean isGettingInstruments = false;
270 280
271 for (int i = 0; i < mApps.size(); i++) { 281 for (int i = 0; i < mApps.size(); i++) {
272 PaymentApp app = mApps.get(i); 282 PaymentApp app = mApps.get(i);
273 Set<String> appMethods = app.getSupportedMethodNames(); 283 Set<String> appMethods = app.getSupportedMethodNames();
274 appMethods.retainAll(mMethodData.keySet()); 284 appMethods.retainAll(mMethodData.keySet());
275 if (appMethods.isEmpty()) { 285 if (appMethods.isEmpty()) {
276 mPendingApps.remove(app); 286 mPendingApps.remove(app);
277 } else { 287 } else {
278 isGettingInstruments = true; 288 isGettingInstruments = true;
279 app.getInstruments(mRawTotal, mRawLineItems, this); 289 app.getInstruments(mRawTotal, mRawLineItems, this);
280 } 290 }
281 } 291 }
282 292
283 if (!isGettingInstruments) { 293 if (!isGettingInstruments) {
284 mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYP E_PAYMENT_METHODS); 294 mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYP E_PAYMENT_METHODS);
285 } 295 }
286 296
287 mUI = new PaymentRequestUI(mContext, this, requestShipping, 297 mUI = new PaymentRequestUI(mContext, this, requestShipping,
288 requestPayerPhone || requestPayerEmail, mMerchantName, mOrigin); 298 mRequestPayerPhone || mRequestPayerEmail, mMerchantName, mOrigin );
289
290 if (mFavicon != null) mUI.setTitleBitmap(mFavicon); 299 if (mFavicon != null) mUI.setTitleBitmap(mFavicon);
291 mFavicon = null; 300 mFavicon = null;
292
293 if (mContactEditor != null) mContactEditor.setEditorView(mUI.getEditorVi ew());
294 } 301 }
295 302
296 private static HashMap<String, JSONObject> getValidatedMethodData( 303 private static HashMap<String, JSONObject> getValidatedMethodData(
297 PaymentMethodData[] methodData) { 304 PaymentMethodData[] methodData) {
298 // Payment methodData are required. 305 // Payment methodData are required.
299 if (methodData == null || methodData.length == 0) return null; 306 if (methodData == null || methodData.length == 0) return null;
300 HashMap<String, JSONObject> result = new HashMap<>(); 307 HashMap<String, JSONObject> result = new HashMap<>();
301 for (int i = 0; i < methodData.length; i++) { 308 for (int i = 0; i < methodData.length; i++) {
302 JSONObject data = null; 309 JSONObject data = null;
303 if (!TextUtils.isEmpty(methodData[i].stringifiedData)) { 310 if (!TextUtils.isEmpty(methodData[i].stringifiedData)) {
(...skipping 17 matching lines...) Expand all
321 328
322 for (int j = 0; j < methods.length; j++) { 329 for (int j = 0; j < methods.length; j++) {
323 // Payment methods should be non-empty. 330 // Payment methods should be non-empty.
324 if (TextUtils.isEmpty(methods[j])) return null; 331 if (TextUtils.isEmpty(methods[j])) return null;
325 result.put(methods[j], data); 332 result.put(methods[j], data);
326 } 333 }
327 } 334 }
328 return result; 335 return result;
329 } 336 }
330 337
338 private boolean isContactInformationComplete(String phone, String email) {
339 return (!mRequestPayerPhone || getPhoneValidator().isValid(phone))
340 && (!mRequestPayerEmail || getEmailValidator().isValid(email));
341 }
342
331 private boolean canUseAddress(AutofillProfile profile, boolean requestShippi ng) { 343 private boolean canUseAddress(AutofillProfile profile, boolean requestShippi ng) {
332 return requestShipping && profile.getCountryCode() != null 344 return requestShipping && profile.getCountryCode() != null
333 && mRegionCodePattern.matcher(profile.getCountryCode()).matches( ) 345 && mRegionCodePattern.matcher(profile.getCountryCode()).matches( )
334 && profile.getStreetAddress() != null && profile.getRegion() != null 346 && profile.getStreetAddress() != null && profile.getRegion() != null
335 && profile.getLocality() != null && profile.getDependentLocality () != null 347 && profile.getLocality() != null && profile.getDependentLocality () != null
336 && profile.getPostalCode() != null && profile.getSortingCode() ! = null 348 && profile.getPostalCode() != null && profile.getSortingCode() ! = null
337 && profile.getCompanyName() != null && profile.getFullName() != null 349 && profile.getCompanyName() != null && profile.getFullName() != null
338 && profile.getPhoneNumber() != null; 350 && profile.getPhoneNumber() != null;
339 } 351 }
340 352
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } else { 614 } else {
603 editContact(contact); 615 editContact(contact);
604 } 616 }
605 } else if (optionType == PaymentRequestUI.TYPE_PAYMENT_METHODS) { 617 } else if (optionType == PaymentRequestUI.TYPE_PAYMENT_METHODS) {
606 assert option instanceof PaymentInstrument; 618 assert option instanceof PaymentInstrument;
607 mPaymentMethodsSection.setSelectedItem(option); 619 mPaymentMethodsSection.setSelectedItem(option);
608 } 620 }
609 return false; 621 return false;
610 } 622 }
611 623
624 private void editContact(final AutofillContact contact) {
625 final EditorFieldModel phoneField = mRequestPayerPhone
626 ? new EditorFieldModel(EditorFieldModel.INPUT_TYPE_HINT_PHONE,
627 mContext.getString(R.string.autofill_profile_editor_ph one_number),
628 mAllPhoneNumbers, getPhoneValidator(),
629 mContext.getString(R.string.payments_phone_required_va lidation_message),
630 mContext.getString(R.string.payments_phone_invalid_val idation_message),
631 contact == null ? null : contact.getPayerPhone())
632 : null;
633
634 final EditorFieldModel emailField = mRequestPayerEmail
635 ? new EditorFieldModel(EditorFieldModel.INPUT_TYPE_HINT_EMAIL,
636 mContext.getString(R.string.autofill_profile_editor_em ail_address),
637 mAllEmailAddresses, getEmailValidator(),
638 mContext.getString(R.string.payments_email_required_va lidation_message),
639 mContext.getString(R.string.payments_email_invalid_val idation_message),
640 contact == null ? null : contact.getPayerEmail())
641 : null;
642
643 EditorModel editor =
644 new EditorModel(mContext.getString(R.string.payments_add_contact _details_label));
645 if (phoneField != null) editor.addField(phoneField);
646 if (emailField != null) editor.addField(emailField);
647
648 editor.setCancelCallback(new Runnable() {
649 @Override
650 public void run() {
651 mContactSection.setSelectedItemIndex(SectionInformation.NO_SELEC TION);
652 mUI.updateSection(PaymentRequestUI.TYPE_CONTACT_DETAILS, mContac tSection);
653 }
654 });
655
656 editor.setDoneCallback(new Runnable() {
657 @Override
658 public void run() {
659 AutofillProfile profile =
660 contact != null ? contact.getProfile() : new AutofillPro file();
661 String phone = null;
662 String email = null;
663 if (phoneField != null) {
664 phone = phoneField.getValue().toString();
665 profile.setPhoneNumber(phone);
666 }
667 if (emailField != null) {
668 email = emailField.getValue().toString();
669 profile.setEmailAddress(email);
670 }
671 PersonalDataManager.getInstance().setProfile(profile);
672
673 if (contact == null) {
674 mContactSection.addAndSelectItem(
675 new AutofillContact(profile, phone, email, true));
676 } else {
677 contact.completeContact(phone, email);
678 }
679 mUI.updateSection(PaymentRequestUI.TYPE_CONTACT_DETAILS, mContac tSection);
680 }
681 });
682 mUI.showEditor(editor);
683 }
684
685 private EditorFieldValidator getPhoneValidator() {
686 if (mPhoneValidator == null) {
687 mPhoneValidator = new EditorFieldValidator() {
688 @Override
689 public boolean isValid(CharSequence value) {
690 return value != null
691 && PhoneNumberUtils.isGlobalPhoneNumber(
692 PhoneNumberUtils.stripSeparators(value.to String()));
693 }
694 };
695 }
696 return mPhoneValidator;
697 }
698
699 private EditorFieldValidator getEmailValidator() {
700 if (mEmailValidator == null) {
701 mEmailValidator = new EditorFieldValidator() {
702 @Override
703 public boolean isValid(CharSequence value) {
704 return value != null && Patterns.EMAIL_ADDRESS.matcher(value ).matches();
705 }
706 };
707 }
708 return mEmailValidator;
709 }
710
612 @Override 711 @Override
613 public void onSectionAddOption(@PaymentRequestUI.DataType int optionType) { 712 public void onSectionAddOption(@PaymentRequestUI.DataType int optionType) {
614 if (optionType == PaymentRequestUI.TYPE_SHIPPING_ADDRESSES) { 713 if (optionType == PaymentRequestUI.TYPE_SHIPPING_ADDRESSES) {
615 PreferencesLauncher.launchSettingsPage(mContext, AutofillProfileEdit or.class.getName()); 714 PreferencesLauncher.launchSettingsPage(mContext, AutofillProfileEdit or.class.getName());
616 } else if (optionType == PaymentRequestUI.TYPE_CONTACT_DETAILS) { 715 } else if (optionType == PaymentRequestUI.TYPE_CONTACT_DETAILS) {
617 editContact(null); 716 editContact(null);
618 } else if (optionType == PaymentRequestUI.TYPE_PAYMENT_METHODS) { 717 } else if (optionType == PaymentRequestUI.TYPE_PAYMENT_METHODS) {
619 PreferencesLauncher.launchSettingsPage( 718 PreferencesLauncher.launchSettingsPage(
620 mContext, AutofillCreditCardEditor.class.getName()); 719 mContext, AutofillCreditCardEditor.class.getName());
621 } 720 }
622 } 721 }
623 722
624 private void editContact(final AutofillContact toEdit) {
625 mContactEditor.editContact(toEdit, new Callback<AutofillContact>() {
626 @Override
627 public void onResult(AutofillContact completeContact) {
628 if (completeContact == null) {
629 mContactSection.setSelectedItemIndex(SectionInformation.NO_S ELECTION);
630 } else if (toEdit == null) {
631 mContactSection.addAndSelectItem(completeContact);
632 }
633
634 mUI.updateSection(PaymentRequestUI.TYPE_CONTACT_DETAILS, mContac tSection);
635 }
636 });
637 }
638
639 @Override 723 @Override
640 public void onPayClicked(PaymentOption selectedShippingAddress, 724 public void onPayClicked(PaymentOption selectedShippingAddress,
641 PaymentOption selectedShippingOption, PaymentOption selectedPaymentM ethod) { 725 PaymentOption selectedShippingOption, PaymentOption selectedPaymentM ethod) {
642 assert selectedPaymentMethod instanceof PaymentInstrument; 726 assert selectedPaymentMethod instanceof PaymentInstrument;
643 PaymentInstrument instrument = (PaymentInstrument) selectedPaymentMethod ; 727 PaymentInstrument instrument = (PaymentInstrument) selectedPaymentMethod ;
644 mPaymentAppRunning = true; 728 mPaymentAppRunning = true;
645 instrument.getDetails(mMerchantName, mOrigin, mRawTotal, mRawLineItems, 729 instrument.getDetails(mMerchantName, mOrigin, mRawTotal, mRawLineItems,
646 mMethodData.get(instrument.getMethodName()), this); 730 mMethodData.get(instrument.getMethodName()), this);
647 } 731 }
648 732
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 private void closeClient() { 891 private void closeClient() {
808 if (mClient != null) mClient.close(); 892 if (mClient != null) mClient.close();
809 mClient = null; 893 mClient = null;
810 } 894 }
811 895
812 @VisibleForTesting 896 @VisibleForTesting
813 public static void setObserverForTest(PaymentRequestServiceObserverForTest o bserverForTest) { 897 public static void setObserverForTest(PaymentRequestServiceObserverForTest o bserverForTest) {
814 sObserverForTest = observerForTest; 898 sObserverForTest = observerForTest;
815 } 899 }
816 } 900 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698