OLD | NEW |
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.content.Context; | 8 import android.content.Context; |
9 import android.content.Intent; | 9 import android.content.Intent; |
10 import android.graphics.Bitmap; | 10 import android.graphics.Bitmap; |
(...skipping 26 matching lines...) Expand all Loading... |
37 import org.chromium.chrome.browser.preferences.autofill.AutofillAndPaymentsPrefe
rences; | 37 import org.chromium.chrome.browser.preferences.autofill.AutofillAndPaymentsPrefe
rences; |
38 import org.chromium.chrome.browser.profiles.Profile; | 38 import org.chromium.chrome.browser.profiles.Profile; |
39 import org.chromium.chrome.browser.tab.Tab; | 39 import org.chromium.chrome.browser.tab.Tab; |
40 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; | 40 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; |
41 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; | 41 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; |
42 import org.chromium.chrome.browser.tabmodel.TabModel; | 42 import org.chromium.chrome.browser.tabmodel.TabModel; |
43 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; | 43 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; |
44 import org.chromium.chrome.browser.tabmodel.TabModelObserver; | 44 import org.chromium.chrome.browser.tabmodel.TabModelObserver; |
45 import org.chromium.chrome.browser.tabmodel.TabModelSelector; | 45 import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
46 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; | 46 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; |
| 47 import org.chromium.components.payments.CurrencyFormatter; |
| 48 import org.chromium.components.payments.PaymentValidator; |
47 import org.chromium.components.url_formatter.UrlFormatter; | 49 import org.chromium.components.url_formatter.UrlFormatter; |
48 import org.chromium.content_public.browser.WebContents; | 50 import org.chromium.content_public.browser.WebContents; |
49 import org.chromium.mojo.system.MojoException; | 51 import org.chromium.mojo.system.MojoException; |
50 import org.chromium.payments.mojom.CanMakePaymentQueryResult; | 52 import org.chromium.payments.mojom.CanMakePaymentQueryResult; |
51 import org.chromium.payments.mojom.PaymentComplete; | 53 import org.chromium.payments.mojom.PaymentComplete; |
52 import org.chromium.payments.mojom.PaymentDetails; | 54 import org.chromium.payments.mojom.PaymentDetails; |
53 import org.chromium.payments.mojom.PaymentDetailsModifier; | 55 import org.chromium.payments.mojom.PaymentDetailsModifier; |
54 import org.chromium.payments.mojom.PaymentErrorReason; | 56 import org.chromium.payments.mojom.PaymentErrorReason; |
55 import org.chromium.payments.mojom.PaymentItem; | 57 import org.chromium.payments.mojom.PaymentItem; |
56 import org.chromium.payments.mojom.PaymentMethodData; | 58 import org.chromium.payments.mojom.PaymentMethodData; |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 mMethodData = getValidatedMethodData(methodData, mCardEditor); | 398 mMethodData = getValidatedMethodData(methodData, mCardEditor); |
397 if (mMethodData == null) { | 399 if (mMethodData == null) { |
398 disconnectFromClientWithDebugMessage("Invalid payment methods or dat
a"); | 400 disconnectFromClientWithDebugMessage("Invalid payment methods or dat
a"); |
399 recordAbortReasonHistogram( | 401 recordAbortReasonHistogram( |
400 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE
R); | 402 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE
R); |
401 return; | 403 return; |
402 } | 404 } |
403 | 405 |
404 if (!parseAndValidateDetailsOrDisconnectFromClient(details)) return; | 406 if (!parseAndValidateDetailsOrDisconnectFromClient(details)) return; |
405 | 407 |
406 PaymentAppFactory.getInstance().create( | 408 PaymentAppFactory.getInstance().create(mWebContents, |
407 mWebContents, Collections.unmodifiableSet(mMethodData.keySet()),
this); | 409 Collections.unmodifiableSet(mMethodData.keySet()), this /* callb
ack */); |
408 | 410 |
409 mRequestShipping = options != null && options.requestShipping; | 411 mRequestShipping = options != null && options.requestShipping; |
410 mRequestPayerName = options != null && options.requestPayerName; | 412 mRequestPayerName = options != null && options.requestPayerName; |
411 mRequestPayerPhone = options != null && options.requestPayerPhone; | 413 mRequestPayerPhone = options != null && options.requestPayerPhone; |
412 mRequestPayerEmail = options != null && options.requestPayerEmail; | 414 mRequestPayerEmail = options != null && options.requestPayerEmail; |
413 mShippingType = options == null ? PaymentShippingType.SHIPPING : options
.shippingType; | 415 mShippingType = options == null ? PaymentShippingType.SHIPPING : options
.shippingType; |
414 | 416 |
415 // If there is a single payment method and the merchant has not requeste
d any other | 417 // If there is a single payment method and the merchant has not requeste
d any other |
416 // information, we can safely go directly to the payment app instead of
showing | 418 // information, we can safely go directly to the payment app instead of
showing |
417 // Payment Request UI. | 419 // Payment Request UI. |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 app.getAppMethodNames()); | 627 app.getAppMethodNames()); |
626 if (appMethods == null || !app.supportsMethodsAndData(appMethods)) { | 628 if (appMethods == null || !app.supportsMethodsAndData(appMethods)) { |
627 mPendingApps.remove(app); | 629 mPendingApps.remove(app); |
628 } else { | 630 } else { |
629 mArePaymentMethodsSupported = true; | 631 mArePaymentMethodsSupported = true; |
630 mMerchantSupportsAutofillPaymentInstruments |= app instanceof Au
tofillPaymentApp; | 632 mMerchantSupportsAutofillPaymentInstruments |= app instanceof Au
tofillPaymentApp; |
631 queryApps.put(app, appMethods); | 633 queryApps.put(app, appMethods); |
632 } | 634 } |
633 } | 635 } |
634 | 636 |
| 637 if (queryApps.isEmpty()) { |
| 638 CanMakePaymentQuery query = sCanMakePaymentQueries.get(mSchemelessOr
iginForPaymentApp); |
| 639 if (query != null && query.matchesPaymentMethods(mMethodData)) { |
| 640 query.notifyObserversOfResponse(false); |
| 641 } |
| 642 } |
| 643 |
| 644 if (disconnectIfNoPaymentMethodsSupported()) return; |
| 645 |
635 // Query instruments after mMerchantSupportsAutofillPaymentInstruments h
as been initialized, | 646 // Query instruments after mMerchantSupportsAutofillPaymentInstruments h
as been initialized, |
636 // so a fast response from a non-autofill payment app at the front of th
e app list does not | 647 // so a fast response from a non-autofill payment app at the front of th
e app list does not |
637 // cause NOT_SUPPORTED payment rejection. | 648 // cause NOT_SUPPORTED payment rejection. |
638 for (Map.Entry<PaymentApp, Map<String, PaymentMethodData>> q : queryApps
.entrySet()) { | 649 for (Map.Entry<PaymentApp, Map<String, PaymentMethodData>> q : queryApps
.entrySet()) { |
639 q.getKey().getInstruments( | 650 q.getKey().getInstruments( |
640 q.getValue(), mSchemelessOriginForPaymentApp, mCertificateCh
ain, this); | 651 q.getValue(), mSchemelessOriginForPaymentApp, mCertificateCh
ain, this); |
641 } | 652 } |
642 } | 653 } |
643 | 654 |
644 /** Filter out merchant method data that's not relevant to a payment app. Ca
n return null. */ | 655 /** Filter out merchant method data that's not relevant to a payment app. Ca
n return null. */ |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1379 AutofillPaymentInstrument creditCard = (AutofillPaymentInstrumen
t) first; | 1390 AutofillPaymentInstrument creditCard = (AutofillPaymentInstrumen
t) first; |
1380 if (creditCard.isComplete()) selection = 0; | 1391 if (creditCard.isComplete()) selection = 0; |
1381 } else { | 1392 } else { |
1382 // If a payment app is available, then PaymentRequest.canMakePay
ment() returns true. | 1393 // If a payment app is available, then PaymentRequest.canMakePay
ment() returns true. |
1383 mCanMakePayment = true; | 1394 mCanMakePayment = true; |
1384 selection = 0; | 1395 selection = 0; |
1385 } | 1396 } |
1386 } | 1397 } |
1387 | 1398 |
1388 CanMakePaymentQuery query = sCanMakePaymentQueries.get(mSchemelessOrigin
ForPaymentApp); | 1399 CanMakePaymentQuery query = sCanMakePaymentQueries.get(mSchemelessOrigin
ForPaymentApp); |
1389 if (query != null) query.notifyObserversOfResponse(mCanMakePayment); | 1400 if (query != null && query.matchesPaymentMethods(mMethodData)) { |
| 1401 query.notifyObserversOfResponse(mCanMakePayment); |
| 1402 } |
1390 | 1403 |
1391 // The list of payment instruments is ready to display. | 1404 // The list of payment instruments is ready to display. |
1392 List<PaymentInstrument> sortedInstruments = new ArrayList<>(); | 1405 List<PaymentInstrument> sortedInstruments = new ArrayList<>(); |
1393 for (List<PaymentInstrument> a : mPendingInstruments) { | 1406 for (List<PaymentInstrument> a : mPendingInstruments) { |
1394 sortedInstruments.addAll(a); | 1407 sortedInstruments.addAll(a); |
1395 } | 1408 } |
1396 mPaymentMethodsSection = new SectionInformation( | 1409 mPaymentMethodsSection = new SectionInformation( |
1397 PaymentRequestUI.TYPE_PAYMENT_METHODS, selection, sortedInstrume
nts); | 1410 PaymentRequestUI.TYPE_PAYMENT_METHODS, selection, sortedInstrume
nts); |
1398 | 1411 |
1399 mPendingInstruments.clear(); | 1412 mPendingInstruments.clear(); |
1400 | 1413 |
1401 updateInstrumentModifiedTotals(); | 1414 updateInstrumentModifiedTotals(); |
1402 | 1415 |
1403 // UI has requested the full list of payment instruments. Provide it now
. | 1416 // UI has requested the full list of payment instruments. Provide it now
. |
1404 if (mPaymentInformationCallback != null) providePaymentInformation(); | 1417 if (mPaymentInformationCallback != null) providePaymentInformation(); |
1405 | 1418 |
1406 triggerPaymentAppUiSkipIfApplicable(); | 1419 triggerPaymentAppUiSkipIfApplicable(); |
1407 } | 1420 } |
1408 | 1421 |
1409 /** | 1422 /** |
1410 * If no payment methods are supported, disconnect from the client and retur
n true. | 1423 * If no payment methods are supported, disconnect from the client and retur
n true. |
1411 * | 1424 * |
1412 * @return True if no payment methods are supported | 1425 * @return True if no payment methods are supported |
1413 */ | 1426 */ |
1414 private boolean disconnectIfNoPaymentMethodsSupported() { | 1427 private boolean disconnectIfNoPaymentMethodsSupported() { |
1415 if (!isFinishedQueryingPaymentApps()) return false; | 1428 if (!isFinishedQueryingPaymentApps() || !mIsCurrentPaymentRequestShowing
) return false; |
1416 | 1429 |
1417 boolean foundPaymentMethods = mPaymentMethodsSection != null | 1430 boolean foundPaymentMethods = mPaymentMethodsSection != null |
1418 && !mPaymentMethodsSection.isEmpty(); | 1431 && !mPaymentMethodsSection.isEmpty(); |
1419 boolean userCanAddCreditCard = mMerchantSupportsAutofillPaymentInstrumen
ts | 1432 boolean userCanAddCreditCard = mMerchantSupportsAutofillPaymentInstrumen
ts |
1420 && !ChromeFeatureList.isEnabled(ChromeFeatureList.NO_CREDIT_CARD
_ABORT); | 1433 && !ChromeFeatureList.isEnabled(ChromeFeatureList.NO_CREDIT_CARD
_ABORT); |
1421 | 1434 |
1422 if (!mArePaymentMethodsSupported || (mIsCurrentPaymentRequestShowing &&
!foundPaymentMethods | 1435 if (!mArePaymentMethodsSupported || (!foundPaymentMethods && !userCanAdd
CreditCard)) { |
1423 && !userCanAddCreditCard)) { | |
1424 // All payment apps have responded, but none of them have instrument
s. It's possible to | 1436 // All payment apps have responded, but none of them have instrument
s. It's possible to |
1425 // add credit cards, but the merchant does not support them either.
The payment request | 1437 // add credit cards, but the merchant does not support them either.
The payment request |
1426 // must be rejected. | 1438 // must be rejected. |
1427 disconnectFromClientWithDebugMessage("Requested payment methods have
no instruments", | 1439 disconnectFromClientWithDebugMessage("Requested payment methods have
no instruments", |
1428 PaymentErrorReason.NOT_SUPPORTED); | 1440 PaymentErrorReason.NOT_SUPPORTED); |
1429 recordNoShowReasonHistogram(mArePaymentMethodsSupported | 1441 recordNoShowReasonHistogram(mArePaymentMethodsSupported |
1430 ? PaymentRequestMetrics.NO_SHOW_NO_MATCHING_PAYMENT_
METHOD | 1442 ? PaymentRequestMetrics.NO_SHOW_NO_MATCHING_PAYMENT_
METHOD |
1431 : PaymentRequestMetrics.NO_SHOW_NO_SUPPORTED_PAYMENT
_METHOD); | 1443 : PaymentRequestMetrics.NO_SHOW_NO_SUPPORTED_PAYMENT
_METHOD); |
1432 if (sObserverForTest != null) sObserverForTest.onPaymentRequestServi
ceShowFailed(); | 1444 if (sObserverForTest != null) sObserverForTest.onPaymentRequestServi
ceShowFailed(); |
1433 return true; | 1445 return true; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 | 1657 |
1646 /** | 1658 /** |
1647 * The frecency score is calculated according to use count and last use date
. The formula is | 1659 * The frecency score is calculated according to use count and last use date
. The formula is |
1648 * the same as the one used in GetFrecencyScore in autofill_data_model.cc. | 1660 * the same as the one used in GetFrecencyScore in autofill_data_model.cc. |
1649 */ | 1661 */ |
1650 private static final double getFrecencyScore(int count, long date) { | 1662 private static final double getFrecencyScore(int count, long date) { |
1651 long currentTime = System.currentTimeMillis(); | 1663 long currentTime = System.currentTimeMillis(); |
1652 return -Math.log((currentTime - date) / (24 * 60 * 60 * 1000) + 2) / Mat
h.log(count + 2); | 1664 return -Math.log((currentTime - date) / (24 * 60 * 60 * 1000) + 2) / Mat
h.log(count + 2); |
1653 } | 1665 } |
1654 } | 1666 } |
OLD | NEW |