| 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 27 matching lines...) Expand all Loading... |
| 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; | 47 import org.chromium.components.payments.CurrencyFormatter; |
| 48 import org.chromium.components.payments.OriginSecurityChecker; |
| 48 import org.chromium.components.payments.PaymentValidator; | 49 import org.chromium.components.payments.PaymentValidator; |
| 49 import org.chromium.components.url_formatter.UrlFormatter; | 50 import org.chromium.components.url_formatter.UrlFormatter; |
| 50 import org.chromium.content_public.browser.RenderFrameHost; | 51 import org.chromium.content_public.browser.RenderFrameHost; |
| 51 import org.chromium.content_public.browser.WebContents; | 52 import org.chromium.content_public.browser.WebContents; |
| 52 import org.chromium.content_public.browser.WebContentsStatics; | 53 import org.chromium.content_public.browser.WebContentsStatics; |
| 53 import org.chromium.mojo.system.MojoException; | 54 import org.chromium.mojo.system.MojoException; |
| 54 import org.chromium.payments.mojom.CanMakePaymentQueryResult; | 55 import org.chromium.payments.mojom.CanMakePaymentQueryResult; |
| 55 import org.chromium.payments.mojom.PaymentComplete; | 56 import org.chromium.payments.mojom.PaymentComplete; |
| 56 import org.chromium.payments.mojom.PaymentDetails; | 57 import org.chromium.payments.mojom.PaymentDetails; |
| 57 import org.chromium.payments.mojom.PaymentDetailsModifier; | 58 import org.chromium.payments.mojom.PaymentDetailsModifier; |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 | 399 |
| 399 /** | 400 /** |
| 400 * Called by the merchant website to initialize the payment request data. | 401 * Called by the merchant website to initialize the payment request data. |
| 401 */ | 402 */ |
| 402 @Override | 403 @Override |
| 403 public void init(PaymentRequestClient client, PaymentMethodData[] methodData
, | 404 public void init(PaymentRequestClient client, PaymentMethodData[] methodData
, |
| 404 PaymentDetails details, PaymentOptions options) { | 405 PaymentDetails details, PaymentOptions options) { |
| 405 if (mClient != null || client == null) return; | 406 if (mClient != null || client == null) return; |
| 406 mClient = client; | 407 mClient = client; |
| 407 | 408 |
| 409 if (!OriginSecurityChecker.isSecureOrigin(mWebContents.getLastCommittedU
rl())) { |
| 410 recordAbortReasonHistogram( |
| 411 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE
R); |
| 412 disconnectFromClientWithDebugMessage("Not in a secure context"); |
| 413 return; |
| 414 } |
| 415 |
| 416 mRequestShipping = options != null && options.requestShipping; |
| 417 mRequestPayerName = options != null && options.requestPayerName; |
| 418 mRequestPayerPhone = options != null && options.requestPayerPhone; |
| 419 mRequestPayerEmail = options != null && options.requestPayerEmail; |
| 420 mShippingType = options == null ? PaymentShippingType.SHIPPING : options
.shippingType; |
| 421 |
| 422 PaymentRequestMetrics.recordRequestedInformationHistogram( |
| 423 mRequestPayerEmail, mRequestPayerPhone, mRequestShipping, mReque
stPayerName); |
| 424 |
| 425 if (OriginSecurityChecker.isCryptographicScheme(mWebContents.getLastComm
ittedUrl()) |
| 426 && !SslValidityChecker.isValidSslCertificate(mWebContents)) { |
| 427 Log.d(TAG, "SSL certificate is not valid"); |
| 428 // Don't show any UI. Resolve .canMakePayment() with "false". Reject
.show() with |
| 429 // "NotSupportedError". |
| 430 onAllPaymentAppsCreated(); |
| 431 return; |
| 432 } |
| 433 |
| 408 if (mMethodData != null) { | 434 if (mMethodData != null) { |
| 409 disconnectFromClientWithDebugMessage("PaymentRequest.show() called m
ore than once."); | 435 disconnectFromClientWithDebugMessage("PaymentRequest.show() called m
ore than once."); |
| 410 recordAbortReasonHistogram( | 436 recordAbortReasonHistogram( |
| 411 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE
R); | 437 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE
R); |
| 412 return; | 438 return; |
| 413 } | 439 } |
| 414 | 440 |
| 415 mMethodData = getValidatedMethodData(methodData, mCardEditor); | 441 mMethodData = getValidatedMethodData(methodData, mCardEditor); |
| 416 if (mMethodData == null) { | 442 if (mMethodData == null) { |
| 417 disconnectFromClientWithDebugMessage("Invalid payment methods or dat
a"); | 443 disconnectFromClientWithDebugMessage("Invalid payment methods or dat
a"); |
| 418 recordAbortReasonHistogram( | 444 recordAbortReasonHistogram( |
| 419 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE
R); | 445 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE
R); |
| 420 return; | 446 return; |
| 421 } | 447 } |
| 422 | 448 |
| 423 if (!parseAndValidateDetailsOrDisconnectFromClient(details)) return; | 449 if (!parseAndValidateDetailsOrDisconnectFromClient(details)) return; |
| 424 | 450 |
| 425 if (mRawTotal == null) { | 451 if (mRawTotal == null) { |
| 426 disconnectFromClientWithDebugMessage("Missing total"); | 452 disconnectFromClientWithDebugMessage("Missing total"); |
| 427 recordAbortReasonHistogram( | 453 recordAbortReasonHistogram( |
| 428 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE
R); | 454 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE
R); |
| 429 return; | 455 return; |
| 430 } | 456 } |
| 431 | 457 |
| 432 PaymentAppFactory.getInstance().create(mWebContents, | 458 PaymentAppFactory.getInstance().create(mWebContents, |
| 433 Collections.unmodifiableSet(mMethodData.keySet()), this /* callb
ack */); | 459 Collections.unmodifiableSet(mMethodData.keySet()), this /* callb
ack */); |
| 434 | 460 |
| 435 mRequestShipping = options != null && options.requestShipping; | |
| 436 mRequestPayerName = options != null && options.requestPayerName; | |
| 437 mRequestPayerPhone = options != null && options.requestPayerPhone; | |
| 438 mRequestPayerEmail = options != null && options.requestPayerEmail; | |
| 439 mShippingType = options == null ? PaymentShippingType.SHIPPING : options
.shippingType; | |
| 440 | |
| 441 // If there is a single payment method and the merchant has not requeste
d any other | 461 // If there is a single payment method and the merchant has not requeste
d any other |
| 442 // information, we can safely go directly to the payment app instead of
showing | 462 // information, we can safely go directly to the payment app instead of
showing |
| 443 // Payment Request UI. | 463 // Payment Request UI. |
| 444 mShouldSkipShowingPaymentRequestUi = | 464 mShouldSkipShowingPaymentRequestUi = |
| 445 ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_PAYMENTS_SINGL
E_APP_UI_SKIP) | 465 ChromeFeatureList.isEnabled(ChromeFeatureList.WEB_PAYMENTS_SINGL
E_APP_UI_SKIP) |
| 446 && mMethodData.size() == 1 && !mRequestShipping && !mRequestPaye
rName | 466 && mMethodData.size() == 1 && !mRequestShipping && !mRequestPaye
rName |
| 447 && !mRequestPayerPhone && !mRequestPayerEmail | 467 && !mRequestPayerPhone && !mRequestPayerEmail |
| 448 // Only allowing payment apps that own their own UIs. | 468 // Only allowing payment apps that own their own UIs. |
| 449 // This excludes AutofillPaymentApp as its UI is rendered inline
in | 469 // This excludes AutofillPaymentApp as its UI is rendered inline
in |
| 450 // the payment request UI, thus can't be skipped. | 470 // the payment request UI, thus can't be skipped. |
| 451 && mMethodData.keySet().iterator().next() != null | 471 && mMethodData.keySet().iterator().next() != null |
| 452 && mMethodData.keySet().iterator().next().startsWith(UrlConstant
s.HTTPS_URL_PREFIX); | 472 && mMethodData.keySet().iterator().next().startsWith(UrlConstant
s.HTTPS_URL_PREFIX); |
| 453 | |
| 454 PaymentRequestMetrics.recordRequestedInformationHistogram(mRequestPayerE
mail, | |
| 455 mRequestPayerPhone, mRequestShipping, mRequestPayerName); | |
| 456 } | 473 } |
| 457 | 474 |
| 458 private void buildUI(Activity activity) { | 475 private void buildUI(Activity activity) { |
| 459 assert activity != null; | 476 assert activity != null; |
| 460 | 477 |
| 461 List<AutofillProfile> profiles = null; | 478 List<AutofillProfile> profiles = null; |
| 462 if (mRequestShipping || mRequestPayerName || mRequestPayerPhone || mRequ
estPayerEmail) { | 479 if (mRequestShipping || mRequestPayerName || mRequestPayerPhone || mRequ
estPayerEmail) { |
| 463 profiles = PersonalDataManager.getInstance().getProfilesToSuggest( | 480 profiles = PersonalDataManager.getInstance().getProfilesToSuggest( |
| 464 false /* includeNameInLabel */); | 481 false /* includeNameInLabel */); |
| 465 } | 482 } |
| (...skipping 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 | 1706 |
| 1690 /** | 1707 /** |
| 1691 * The frecency score is calculated according to use count and last use date
. The formula is | 1708 * The frecency score is calculated according to use count and last use date
. The formula is |
| 1692 * the same as the one used in GetFrecencyScore in autofill_data_model.cc. | 1709 * the same as the one used in GetFrecencyScore in autofill_data_model.cc. |
| 1693 */ | 1710 */ |
| 1694 private static final double getFrecencyScore(int count, long date) { | 1711 private static final double getFrecencyScore(int count, long date) { |
| 1695 long currentTime = System.currentTimeMillis(); | 1712 long currentTime = System.currentTimeMillis(); |
| 1696 return -Math.log((currentTime - date) / (24 * 60 * 60 * 1000) + 2) / Mat
h.log(count + 2); | 1713 return -Math.log((currentTime - date) / (24 * 60 * 60 * 1000) + 2) / Mat
h.log(count + 2); |
| 1697 } | 1714 } |
| 1698 } | 1715 } |
| OLD | NEW |