0

Add @NullMarked to //components/payments

Patch 1 contains the automated changes made by the annotator.
Patch 2 and 4 and 5 contains the manual changes made by me.

Bug: 389129271
Change-Id: I172b42479e35ae6ee4c38a80c6bf6243492fcc38
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6299969
Reviewed-by: Peter Wen <wnwen@chromium.org>
Reviewed-by: Andrew Grieve <agrieve@chromium.org>
Commit-Queue: Peter Wen <wnwen@chromium.org>
Commit-Queue: Martin Kong <martinkong@google.com>
Owners-Override: Andrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1424750}
This commit is contained in:
Martin Kong
2025-02-25 13:13:55 -08:00
committed by Chromium LUCI CQ
parent de7e4cb4fa
commit ea5943b112
47 changed files with 318 additions and 198 deletions
components/payments/content/android
url/android/java/src/org/chromium/url

@ -9,13 +9,14 @@ import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.ContextUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.task.PostTask;
import org.chromium.base.task.TaskTraits;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.components.payments.intent.IsReadyToPayServiceHelper;
import org.chromium.components.payments.intent.WebPaymentIntentHelper;
import org.chromium.components.payments.intent.WebPaymentIntentHelperType;
@ -40,31 +41,32 @@ import java.util.Set;
* The point of interaction with a locally installed 3rd party native Android payment app.
* https://web.dev/articles/android-payment-apps-developers-guide
*/
@NullMarked
public class AndroidPaymentApp extends PaymentApp
implements IsReadyToPayServiceHelper.ResultHandler, WindowAndroid.IntentCallback {
private final Handler mHandler;
private final AndroidIntentLauncher mLauncher;
@Nullable private final DialogController mDialogController;
private final @Nullable DialogController mDialogController;
private final Set<String> mMethodNames;
private final boolean mIsIncognito;
private final String mPackageName;
private final String mPayActivityName;
@Nullable private final String mIsReadyToPayServiceName;
@Nullable private final String mPaymentDetailsUpdateServiceName;
private final @Nullable String mIsReadyToPayServiceName;
private final @Nullable String mPaymentDetailsUpdateServiceName;
private final SupportedDelegations mSupportedDelegations;
private final boolean mShowReadyToPayDebugInfo;
private final boolean mRemoveDeprecatedFields;
private IsReadyToPayCallback mIsReadyToPayCallback;
private InstrumentDetailsCallback mInstrumentDetailsCallback;
private IsReadyToPayServiceHelper mIsReadyToPayServiceHelper;
private PaymentDetailsUpdateConnection mPaymentDetailsUpdateConnection;
@Nullable private String mApplicationIdentifierToHide;
private @Nullable IsReadyToPayCallback mIsReadyToPayCallback;
private @Nullable InstrumentDetailsCallback mInstrumentDetailsCallback;
private @Nullable IsReadyToPayServiceHelper mIsReadyToPayServiceHelper;
private @Nullable PaymentDetailsUpdateConnection mPaymentDetailsUpdateConnection;
private @Nullable String mApplicationIdentifierToHide;
private boolean mBypassIsReadyToPayServiceInTest;
private boolean mIsPreferred;
// Set inside launchPaymentApp and used to validate the received response.
@Nullable private WebPaymentIntentHelperType.PaymentOptions mPaymentOptions;
private WebPaymentIntentHelperType.@Nullable PaymentOptions mPaymentOptions;
/**
* Builds the point of interaction with a locally installed 3rd party native Android payment
@ -179,7 +181,7 @@ public class AndroidPaymentApp extends PaymentApp
Map<String, PaymentMethodData> methodDataMap,
String origin,
String iframeOrigin,
@Nullable byte[][] certificateChain,
byte @Nullable [][] certificateChain,
Map<String, PaymentDetailsModifier> modifiers,
IsReadyToPayCallback callback) {
ThreadUtils.assertOnUiThread();
@ -243,8 +245,7 @@ public class AndroidPaymentApp extends PaymentApp
}
@Override
@Nullable
public String getApplicationIdentifierToHide() {
public @Nullable String getApplicationIdentifierToHide() {
return mApplicationIdentifierToHide;
}
@ -259,7 +260,7 @@ public class AndroidPaymentApp extends PaymentApp
final String merchantName,
String origin,
String iframeOrigin,
final byte[][] certificateChain,
final byte @Nullable [][] certificateChain,
final Map<String, PaymentMethodData> methodDataMap,
final PaymentItem total,
final List<PaymentItem> displayItems,
@ -348,7 +349,7 @@ public class AndroidPaymentApp extends PaymentApp
String merchantName,
String origin,
String iframeOrigin,
byte[][] certificateChain,
byte @Nullable [][] certificateChain,
Map<String, PaymentMethodData> methodDataMap,
PaymentItem total,
List<PaymentItem> displayItems,

@ -10,6 +10,7 @@ import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Pair;
import org.chromium.build.annotations.NullMarked;
import org.chromium.components.payments.intent.WebPaymentIntentHelper;
import java.util.HashMap;
@ -17,6 +18,7 @@ import java.util.List;
import java.util.Map;
/** Looks up installed third party Android payment apps. */
@NullMarked
public class AndroidPaymentAppFactory implements PaymentAppFactoryInterface {
// PaymentAppFactoryInterface implementation.
@Override

@ -4,17 +4,21 @@
package org.chromium.components.payments;
import static org.chromium.build.NullUtil.assumeNonNull;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.Log;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.build.annotations.Contract;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.components.payments.PaymentManifestVerifier.ManifestVerifyCallback;
import org.chromium.components.payments.intent.WebPaymentIntentHelper;
import org.chromium.payments.mojom.PaymentDetailsModifier;
@ -35,6 +39,7 @@ import java.util.Set;
* payment method names are exceptions: these are common payment method names that do not have a
* manifest and can be used by any payment app.
*/
@NullMarked
public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
private static final String TAG = "PaymentAppFinder";
@ -67,10 +72,10 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
public static final String META_DATA_NAME_OF_SUPPORTED_DELEGATIONS =
"org.chromium.payment_supported_delegations";
private static PackageManagerDelegate sPackageManagerDelegateForTest;
private static PaymentManifestDownloader sDownloaderForTest;
private static @Nullable PackageManagerDelegate sPackageManagerDelegateForTest;
private static @Nullable PaymentManifestDownloader sDownloaderForTest;
private static boolean sBypassIsReadyToPayServiceInTest;
private static AndroidIntentLauncher sAndroidIntentLauncherForTest;
private static @Nullable AndroidIntentLauncher sAndroidIntentLauncherForTest;
private final Set<GURL> mUrlPaymentMethods = new HashSet<>();
private final PaymentManifestDownloader mDownloader;
@ -285,7 +290,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
|| urlMethod.equals(defaultUrlMethod);
}
private ResolveInfo findAppWithPackageName(List<ResolveInfo> apps, String packageName) {
private @Nullable ResolveInfo findAppWithPackageName(
List<ResolveInfo> apps, String packageName) {
assert packageName != null;
for (int i = 0; i < apps.size(); i++) {
ResolveInfo app = apps.get(i);
@ -555,8 +561,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
* @param metaDataName The name of the string array meta data to be retrieved.
* @return The string array.
*/
@Nullable
private String[] getStringArrayMetaData(ActivityInfo activityInfo, String metaDataName) {
private String @Nullable [] getStringArrayMetaData(
ActivityInfo activityInfo, String metaDataName) {
if (activityInfo.metaData == null) return null;
int resId = activityInfo.metaData.getInt(metaDataName);
@ -694,7 +700,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
* @param resolveInfo The payment app that's allowed to use the method name.
* @param methodName The method name that can be used by the app.
*/
private void onValidPaymentAppForPaymentMethodName(ResolveInfo resolveInfo, String methodName) {
private void onValidPaymentAppForPaymentMethodName(
ResolveInfo resolveInfo, String methodName) {
if (mFactoryDelegate.getParams().hasClosed()) return;
String packageName = resolveInfo.activityInfo.packageName;
@ -729,7 +736,7 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
app =
new AndroidPaymentApp(
sAndroidIntentLauncherForTest == null
? mFactoryDelegate.getAndroidIntentLauncher()
? assumeNonNull(mFactoryDelegate.getAndroidIntentLauncher())
: sAndroidIntentLauncherForTest,
mFactoryDelegate.getDialogController(),
packageName,
@ -779,14 +786,14 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
* @param url The URL to stringify.
* @return The URL string without a trailing slash, or null if the input parameter is null.
*/
@Nullable
private static String urlToStringWithoutTrailingSlash(@Nullable GURL url) {
@Contract("!null -> !null")
private static @Nullable String urlToStringWithoutTrailingSlash(@Nullable GURL url) {
if (url == null) return null;
return removeTrailingSlash(url.getSpec());
}
@Nullable
private static String removeTrailingSlash(@Nullable String string) {
@Contract("!null -> !null")
private static @Nullable String removeTrailingSlash(@Nullable String string) {
if (string == null) return null;
return string.endsWith("/") ? string.substring(0, string.length() - 1) : string;
}

@ -4,8 +4,8 @@
package org.chromium.components.payments;
import androidx.annotation.Nullable;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.content_public.browser.WebContents;
import org.chromium.payments.mojom.PaymentComplete;
import org.chromium.payments.mojom.PaymentDetails;
@ -24,6 +24,7 @@ import java.util.Map;
* The browser part of the PaymentRequest implementation. The browser here can be either the
* Android Chrome browser or the WebLayer "browser".
*/
@NullMarked
public interface BrowserPaymentRequest {
/**
* The client of the interface calls this when it has received the payment details update
@ -98,10 +99,9 @@ public interface BrowserPaymentRequest {
* implementer may consider other factors before deciding whether to show or skip.
* @return The error of the showing if any; null if success.
*/
@Nullable
String showOrSkipAppSelector(
@Nullable String showOrSkipAppSelector(
boolean isShowWaitingForUpdatedDetails,
PaymentItem total,
@Nullable PaymentItem total,
boolean shouldSkipAppSelector);
/**
@ -128,8 +128,7 @@ public interface BrowserPaymentRequest {
*
* @return The error if it fails; null otherwise.
*/
@Nullable
default String onShowCalledAndAppsQueriedAndDetailsFinalized() {
default @Nullable String onShowCalledAndAppsQueriedAndDetailsFinalized() {
return null;
}
@ -166,7 +165,7 @@ public interface BrowserPaymentRequest {
* @param ukmSourceId The ukm source id assigned to the payment app.
* @return The created WebContents.
*/
default WebContents openPaymentHandlerWindow(GURL url, long ukmSourceId) {
default @Nullable WebContents openPaymentHandlerWindow(GURL url, long ukmSourceId) {
return null;
}
@ -178,8 +177,7 @@ public interface BrowserPaymentRequest {
* their payment apps.
* @return The error if it fails; null otherwise.
*/
@Nullable
default String continueShowWithUpdatedDetails(
default @Nullable String continueShowWithUpdatedDetails(
PaymentDetails details, boolean isFinishedQueryingPaymentApps) {
return null;
}
@ -225,8 +223,7 @@ public interface BrowserPaymentRequest {
* Can return null when ANDROID_PAYMENT_INTENTS_OMIT_DEPRECATED_PARAMETERS is enabled or
* when the page is localhost or is a file.
*/
@Nullable
byte[][] getCertificateChain();
byte @Nullable [][] getCertificateChain();
/**
* @return The launcher for Android intent-based payment app.

@ -4,12 +4,11 @@
package org.chromium.components.payments;
import androidx.annotation.NonNull;
import org.jni_zero.CalledByNative;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.url.GURL;
/**
@ -24,6 +23,7 @@ import org.chromium.url.GURL;
* bridge.destroy();
*/
@JNINamespace("payments")
@NullMarked
public class CSPCheckerBridge {
// Performs the CSP checks.
private final CSPChecker mImpl;
@ -35,7 +35,7 @@ public class CSPCheckerBridge {
* Initializes the CSP checker bridge.
* @param cspChecker The object that will perform the CSP checks.
*/
public CSPCheckerBridge(@NonNull CSPChecker cspChecker) {
public CSPCheckerBridge(CSPChecker cspChecker) {
mImpl = cspChecker;
mNativeBridge = CSPCheckerBridgeJni.get().createNativeCSPChecker(this);
}

@ -9,10 +9,13 @@ import androidx.annotation.VisibleForTesting;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import java.util.Set;
/** Error messages for web payment. */
@JNINamespace("payments::android")
@NullMarked
public class ErrorMessageUtil {
/**
* Returns the "payment method not supported" message.

@ -9,6 +9,7 @@ import org.jni_zero.JNINamespace;
import org.jni_zero.JniType;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.content_public.browser.WebContents;
import org.chromium.payments.mojom.PaymentMethodData;
@ -17,6 +18,7 @@ import java.util.Set;
/** Checks whether hasEnrolledInstrument() can be queried. */
@JNINamespace("payments")
@NullMarked
public class HasEnrolledInstrumentQuery {
/**
* Checks whether the given hasEnrolledInstrument() query is allowed.

@ -4,6 +4,8 @@
package org.chromium.components.payments;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.mojo.system.MojoException;
import org.chromium.payments.mojom.CanMakePaymentQueryResult;
import org.chromium.payments.mojom.HasEnrolledInstrumentQueryResult;
@ -19,8 +21,9 @@ import org.chromium.payments.mojom.PaymentValidationErrors;
* An implementation of PaymentRequest that immediately rejects all connections.
* Necessary because Mojo does not handle null returned from createImpl().
*/
@NullMarked
public final class InvalidPaymentRequest implements PaymentRequest {
private PaymentRequestClient mClient;
private @Nullable PaymentRequestClient mClient;
@Override
public void init(

@ -8,12 +8,12 @@ import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import androidx.annotation.Nullable;
import org.jni_zero.CalledByNative;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.payments.mojom.PaymentDetailsModifier;
import org.chromium.payments.mojom.PaymentItem;
import org.chromium.payments.mojom.PaymentMethodData;
@ -31,6 +31,7 @@ import java.util.Set;
/** Wrapper around a C++ payment app. */
@JNINamespace("payments")
@NullMarked
public class JniPaymentApp extends PaymentApp {
private final Handler mHandler = new Handler();
private final @PaymentAppType int mPaymentAppType;
@ -38,8 +39,8 @@ public class JniPaymentApp extends PaymentApp {
// The Java object owns the C++ payment app and frees it in dismissInstrument().
private long mNativeObject;
private AbortCallback mAbortCallback;
private InstrumentDetailsCallback mInvokeCallback;
private @Nullable AbortCallback mAbortCallback;
private @Nullable InstrumentDetailsCallback mInvokeCallback;
@CalledByNative
private JniPaymentApp(
@ -170,7 +171,7 @@ public class JniPaymentApp extends PaymentApp {
String merchantName,
String origin,
String iframeOrigin,
@Nullable byte[][] certificateChain,
byte @Nullable [][] certificateChain,
Map<String, PaymentMethodData> methodDataMap,
PaymentItem total,
List<PaymentItem> displayItems,
@ -204,14 +205,12 @@ public class JniPaymentApp extends PaymentApp {
}
@Override
@Nullable
public String getApplicationIdentifierToHide() {
public @Nullable String getApplicationIdentifierToHide() {
return JniPaymentAppJni.get().getApplicationIdentifierToHide(mNativeObject);
}
@Override
@Nullable
public Set<String> getApplicationIdentifiersThatHideThisApp() {
public @Nullable Set<String> getApplicationIdentifiersThatHideThisApp() {
return new HashSet<>(
Arrays.asList(
JniPaymentAppJni.get()
@ -261,7 +260,7 @@ public class JniPaymentApp extends PaymentApp {
String[] getInstrumentMethodNames(long nativeJniPaymentApp);
boolean isValidForPaymentMethodData(
long nativeJniPaymentApp, String method, ByteBuffer dataByteBuffer);
long nativeJniPaymentApp, String method, @Nullable ByteBuffer dataByteBuffer);
boolean handlesShippingAddress(long nativeJniPaymentApp);

@ -7,12 +7,14 @@ package org.chromium.components.payments;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.content_public.browser.WebContents;
import java.util.List;
/** A class used to record journey metrics for the Payment Request feature. */
@JNINamespace("payments")
@NullMarked
public class JourneyLogger {
/** Pointer to the native implementation. */
private long mJourneyLoggerAndroid;

@ -4,6 +4,8 @@
package org.chromium.components.payments;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.mojo.system.MojoException;
import org.chromium.payments.mojom.PaymentDetails;
import org.chromium.payments.mojom.PaymentMethodData;
@ -16,9 +18,10 @@ import org.chromium.payments.mojom.PaymentValidationErrors;
* Guards against invalid mojo parameters and enforces correct call sequence from mojo IPC in the
* untrusted renderer, so PaymentRequestService does not have to.
*/
@NullMarked
public class MojoPaymentRequestGateKeeper implements PaymentRequest {
private final Delegate mDelegate;
private PaymentRequestService mPaymentRequestService;
private @Nullable PaymentRequestService mPaymentRequestService;
/** The delegate of the class. */
public interface Delegate {

@ -7,10 +7,12 @@ package org.chromium.components.payments;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.url.GURL;
/** Helper for origin security. */
@JNINamespace("payments")
@NullMarked
public class OriginSecurityChecker {
/**
* Returns true for a valid URL from a secure origin, e.g., http://localhost,

@ -21,7 +21,9 @@ public final class PaymentAddressTypeConverter {
* @param address The org.chromium.payments.mojom.PaymentAddress to be converted.
* @return The converted address with type org.chromium.components.payments.Address.
*/
public static @Nullable Address convertPaymentAddressFromMojo(PaymentAddress address) {
@Contract("!null -> !null")
public static @Nullable Address convertPaymentAddressFromMojo(
@Nullable PaymentAddress address) {
if (address == null) return null;
return new Address(
address.country,
@ -41,7 +43,8 @@ public final class PaymentAddressTypeConverter {
* @return The converted address with type org.chromium.payments.mojom.PaymentAddress.
*/
@Contract("!null -> !null")
public static @Nullable PaymentAddress convertAddressToMojoPaymentAddress(Address address) {
public static @Nullable PaymentAddress convertAddressToMojoPaymentAddress(
@Nullable Address address) {
if (address == null) return null;
PaymentAddress result = new PaymentAddress();
result.country = address.country;

@ -59,7 +59,7 @@ public abstract class PaymentApp extends EditableOption {
void onInstrumentAbortResult(boolean abortSucceeded);
}
protected PaymentApp(String id, String label, String sublabel, Drawable icon) {
protected PaymentApp(String id, String label, @Nullable String sublabel, Drawable icon) {
super(id, maybeElide(removeLineTerminators(label)), sublabel, icon);
}

@ -28,16 +28,16 @@ public interface PaymentAppFactoryParams extends PaymentRequestParams {
* @return The scheme, host, and port of the last committed URL of the top-level context as
* formatted by UrlFormatter.formatUrlForSecurityDisplay().
*/
default @Nullable String getTopLevelOrigin() {
return null;
default String getTopLevelOrigin() {
throw new UnsupportedOperationException();
}
/**
* @return The scheme, host, and port of the last committed URL of the iframe that invoked the
* PaymentRequest API as formatted by UrlFormatter.formatUrlForSecurityDisplay().
*/
default @Nullable String getPaymentRequestOrigin() {
return null;
default String getPaymentRequestOrigin() {
throw new UnsupportedOperationException();
}
/**
@ -45,8 +45,8 @@ public interface PaymentAppFactoryParams extends PaymentRequestParams {
* security features like 'Sec-Fetch-Site' and 'Cross-Origin-Resource-Policy'. Should not be
* null.
*/
default @Nullable Origin getPaymentRequestSecurityOrigin() {
return null;
default Origin getPaymentRequestSecurityOrigin() {
throw new UnsupportedOperationException();
}
/**
@ -64,14 +64,18 @@ public interface PaymentAppFactoryParams extends PaymentRequestParams {
return false;
}
/** @return The listener for payment method, shipping address, and shipping option change events. */
/**
* @return The listener for payment method, shipping address, and shipping option change events.
*/
default @Nullable PaymentRequestUpdateEventListener getPaymentRequestUpdateEventListener() {
return null;
}
/** @return The Payment Request information received from the merchant. */
default @Nullable PaymentRequestSpec getSpec() {
return null;
/**
* @return The Payment Request information received from the merchant.
*/
default PaymentRequestSpec getSpec() {
throw new UnsupportedOperationException();
}
/**

@ -9,11 +9,14 @@ import org.jni_zero.NativeMethods;
import org.chromium.base.ResettersForTesting;
import org.chromium.base.ThreadUtils;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.components.url_formatter.SchemeDisplay;
import org.chromium.components.url_formatter.UrlFormatter;
import org.chromium.content_public.browser.RenderFrameHost;
/** Native bridge for finding payment apps. */
@NullMarked
public class PaymentAppServiceBridge implements PaymentAppFactoryInterface {
private static boolean sCanMakePaymentForTesting;
@ -152,7 +155,7 @@ public class PaymentAppServiceBridge implements PaymentAppFactoryInterface {
RenderFrameHost initiatorRenderFrameHost,
String topOrigin,
PaymentRequestSpec spec,
String twaPackageName,
@Nullable String twaPackageName,
boolean mayCrawlForInstallablePaymentApps,
boolean isOffTheRecord,
long nativeCSPCheckerAndroid,

@ -4,6 +4,7 @@
package org.chromium.components.payments;
import org.chromium.build.annotations.NullMarked;
import org.chromium.payments.mojom.PaymentDetails;
import org.chromium.payments.mojom.PaymentHandlerMethodData;
import org.chromium.payments.mojom.PaymentHandlerModifier;
@ -16,6 +17,7 @@ import java.util.ArrayList;
* Redacts and converts the payment details update from the merchant into a data structure to be
* sent to the invoked payment handler.
*/
@NullMarked
public class PaymentDetailsConverter {
/**
* To be implemented by the object that can check whether the invoked payment instrument is
@ -47,7 +49,9 @@ public class PaymentDetailsConverter {
* @return The data structure that can be sent to the invoked payment handler.
*/
public static PaymentRequestDetailsUpdate convertToPaymentRequestDetailsUpdate(
PaymentDetails details, MethodChecker methodChecker, PaymentApp invokedPaymentApp) {
PaymentDetails details,
MethodChecker methodChecker,
PaymentApp invokedPaymentApp) {
// Keep in sync with components/payments/content/payment_details_converter.cc.
assert details != null;
assert methodChecker != null;

@ -7,10 +7,12 @@ package org.chromium.components.payments;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.content_public.browser.WebContents;
/** The navigation throttle of the payment handler pages. */
@JNINamespace("payments::android")
@NullMarked
public class PaymentHandlerNavigationThrottle {
/**
* Marks the given WebContents as a payment handler WebContents. This will allow the callers of

@ -9,6 +9,8 @@ import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.base.ThreadUtils;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.content_public.browser.WebContents;
import org.chromium.url.GURL;
import org.chromium.url.Origin;
@ -18,6 +20,7 @@ import org.chromium.url.Origin;
* components/payments/core/payment_manifest_downloader.h
*/
@JNINamespace("payments")
@NullMarked
public class PaymentManifestDownloader {
/** Interface for the callback to invoke when finished downloading. */
public interface ManifestDownloadCallback {
@ -54,7 +57,7 @@ public class PaymentManifestDownloader {
}
private long mNativeObject;
private CSPCheckerBridge mCSPCheckerBridge;
private @Nullable CSPCheckerBridge mCSPCheckerBridge;
/**
* Initializes the native downloader.

@ -9,11 +9,13 @@ import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.base.ThreadUtils;
import org.chromium.build.annotations.NullMarked;
import org.chromium.content_public.browser.WebContents;
import org.chromium.url.GURL;
/** Parses payment manifests in a utility process. */
@JNINamespace("payments")
@NullMarked
public class PaymentManifestParser {
/** Interface for the callback to invoke when finished parsing. */
public interface ManifestParseCallback {

@ -4,13 +4,15 @@
package org.chromium.components.payments;
import static org.chromium.build.NullUtil.assumeNonNull;
import android.content.pm.PackageInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import androidx.annotation.Nullable;
import org.chromium.base.Log;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.components.payments.PaymentManifestDownloader.ManifestDownloadCallback;
import org.chromium.components.payments.PaymentManifestParser.ManifestParseCallback;
import org.chromium.url.GURL;
@ -35,6 +37,7 @@ import java.util.Set;
* Spec:
* https://docs.google.com/document/d/1izV4uC-tiRJG3JLooqY3YRLU22tYOsLTNq0P_InPJeE/edit#heading=h.cjp3jlnl47h5
*/
@NullMarked
public class PaymentManifestVerifier
implements ManifestDownloadCallback,
ManifestParseCallback,
@ -84,6 +87,7 @@ public class PaymentManifestVerifier
/** Identifying information about an installed native Android payment app. */
private static class AppInfo {
/** Identifies a native Android payment app. */
@SuppressWarnings("NullAway.Init") // This is set to a non-null value immediately after init
public ResolveInfo resolveInfo;
/** The version code for the native Android payment app, e.g., 123. */
@ -93,7 +97,7 @@ public class PaymentManifestVerifier
* The SHA256 certificate fingerprints for the native Android payment app, .e.g,
* ["308201dd30820146020101300d06092a864886f70d010105050030"].
*/
public Set<String> sha256CertFingerprints;
public @Nullable Set<String> sha256CertFingerprints;
}
private static final String TAG = "PaymentManifest";
@ -130,10 +134,10 @@ public class PaymentManifestVerifier
private final PaymentManifestParser mParser;
private final PackageManagerDelegate mPackageManagerDelegate;
private final ManifestVerifyCallback mCallback;
private final MessageDigest mMessageDigest;
private final @Nullable MessageDigest mMessageDigest;
/** The origin of the payment method manifest after all redirects have been followed. */
private Origin mPaymentMethodManifestOrigin;
private @Nullable Origin mPaymentMethodManifestOrigin;
/**
* The number of web app manifests that have not yet been retrieved from cache or downloaded
@ -237,6 +241,8 @@ public class PaymentManifestVerifier
appInfo.version = packageInfo.versionCode;
appInfo.sha256CertFingerprints = new HashSet<>();
Signature[] signatures = packageInfo.signatures;
assumeNonNull(signatures);
assumeNonNull(mMessageDigest);
for (int i = 0; i < signatures.length; i++) {
mMessageDigest.update(signatures[i].toByteArray());
@ -263,8 +269,6 @@ public class PaymentManifestVerifier
* @return A string representation of the input bytes, e.g., "0123456789abcdef".
*/
private static String byteArrayToString(byte[] input) {
if (input == null) return null;
StringBuilder builder = new StringBuilder(input.length * 2);
Formatter formatter = new Formatter(builder);
for (byte b : input) {
@ -344,7 +348,8 @@ public class PaymentManifestVerifier
Set<String> validAppPackageNames = verifyAppWithWebAppManifest(manifest);
for (String validAppPackageName : validAppPackageNames) {
mCallback.onValidDefaultPaymentApp(
mMethodName, mDefaultApplications.get(validAppPackageName).resolveInfo);
mMethodName,
assumeNonNull(mDefaultApplications.get(validAppPackageName)).resolveInfo);
}
mPendingWebAppManifestsCount--;
@ -400,6 +405,7 @@ public class PaymentManifestVerifier
for (int i = 0; i < webAppManifestUris.length; i++) {
if (mAtLeastOneManifestFailedToDownloadOrParse) return;
assert webAppManifestUris[i] != null;
assumeNonNull(mPaymentMethodManifestOrigin);
mDownloader.downloadWebAppManifest(
mPaymentMethodManifestOrigin, webAppManifestUris[i], this);
}
@ -428,7 +434,8 @@ public class PaymentManifestVerifier
Set<String> validAppPackageNames = verifyAppWithWebAppManifest(manifest);
for (String validAppPackageName : validAppPackageNames) {
mCallback.onValidDefaultPaymentApp(
mMethodName, mDefaultApplications.get(validAppPackageName).resolveInfo);
mMethodName,
assumeNonNull(mDefaultApplications.get(validAppPackageName)).resolveInfo);
}
}

@ -8,10 +8,12 @@ import org.jni_zero.CalledByNative;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.content_public.browser.WebContents;
/** Java wrapper of the payment manifest web data service. */
@JNINamespace("payments")
@NullMarked
public class PaymentManifestWebDataService {
/** Interface for the callback to invoke when getting data from the web data service. */
public interface PaymentManifestWebDataServiceCallback {

@ -4,9 +4,11 @@
package org.chromium.components.payments;
import org.chromium.build.annotations.NullMarked;
import org.chromium.payments.mojom.PaymentErrorReason;
/** The error of payment UIs not being shown. */
@NullMarked
public class PaymentNotShownError {
private final String mErrorMessage;
private final int mReason;

@ -4,11 +4,12 @@
package org.chromium.components.payments;
import androidx.annotation.Nullable;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.payments.mojom.PaymentOptions;
/** A collection of utility methods for PaymentOptions. */
@NullMarked
public class PaymentOptionsUtils {
/**
* @param options Any PaymentOption, can be null.

@ -6,6 +6,7 @@ package org.chromium.components.payments;
import org.chromium.build.annotations.MockedInTests;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.payments.mojom.PaymentDetailsModifier;
import org.chromium.payments.mojom.PaymentItem;
import org.chromium.payments.mojom.PaymentMethodData;
@ -43,5 +44,5 @@ public interface PaymentRequestParams {
* @return The raw total amount being charged - the total property of the PaymentDetails of
* payment request.
*/
PaymentItem getRawTotal();
@Nullable PaymentItem getRawTotal();
}

@ -4,10 +4,11 @@
package org.chromium.components.payments;
import static org.chromium.build.NullUtil.assumeNonNull;
import android.content.Context;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.collection.ArrayMap;
@ -17,6 +18,8 @@ import org.chromium.base.Log;
import org.chromium.base.ResettersForTesting;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.supplier.Supplier;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.components.url_formatter.SchemeDisplay;
import org.chromium.components.url_formatter.UrlFormatter;
@ -65,6 +68,7 @@ import java.util.Set;
* class need to close them with {@link PaymentRequestService#close()}, after which no usage is
* allowed.
*/
@NullMarked
public class PaymentRequestService
implements PaymentAppFactoryDelegate,
PaymentAppFactoryParams,
@ -80,29 +84,37 @@ public class PaymentRequestService
* Hold the currently showing PaymentRequest. Used to prevent showing more than one
* PaymentRequest UI per browser process.
*/
private static PaymentRequestService sShowingPaymentRequest;
private static @Nullable PaymentRequestService sShowingPaymentRequest;
private static PaymentRequestServiceObserverForTest sObserverForTest;
private static NativeObserverForTest sNativeObserverForTest;
private static @Nullable PaymentRequestServiceObserverForTest sObserverForTest;
private static @Nullable NativeObserverForTest sNativeObserverForTest;
private static boolean sIsLocalHasEnrolledInstrumentQueryQuotaEnforcedForTest;
private final Runnable mOnClosedListener;
private final RenderFrameHost mRenderFrameHost;
private final Delegate mDelegate;
private final List<PaymentApp> mPendingApps = new ArrayList<>();
@Nullable private final Supplier<PaymentAppServiceBridge> mPaymentAppServiceBridgeSupplier;
private final @Nullable Supplier<PaymentAppServiceBridge> mPaymentAppServiceBridgeSupplier;
@SuppressWarnings("NullAway.Init") // When init() fails this can have null value
private WebContents mWebContents;
@SuppressWarnings("NullAway.Init") // When init() fails this can have null value
private JourneyLogger mJourneyLogger;
@SuppressWarnings("NullAway.Init") // When init() fails this can have null value
private String mTopLevelOrigin;
@SuppressWarnings("NullAway.Init") // When init() fails this can have null value
private String mPaymentRequestOrigin;
@SuppressWarnings("NullAway.Init") // When init() fails this can have null value
private Origin mPaymentRequestSecurityOrigin;
@SuppressWarnings("NullAway.Init") // When init() fails this can have null value
private String mMerchantName;
private boolean mIsOffTheRecord;
@SuppressWarnings("NullAway.Init") // When init() fails this can have null value
private PaymentOptions mPaymentOptions;
private boolean mRequestShipping;
private boolean mRequestPayerName;
private boolean mRequestPayerPhone;
private boolean mRequestPayerEmail;
private int mShippingType;
@SuppressWarnings("NullAway.Init") // When init() fails this can have null value
private PaymentRequestSpec mSpec;
private boolean mHasClosed;
private boolean mIsFinishedQueryingPaymentApps;
@ -110,21 +122,22 @@ public class PaymentRequestService
private boolean mIsShowWaitingForUpdatedDetails;
/** If not empty, use this error message for rejecting PaymentRequest.show(). */
private String mRejectShowErrorMessage;
private @Nullable String mRejectShowErrorMessage;
/** Internal reason for why PaymentRequest.show() should be rejected. */
private @AppCreationFailureReason int mRejectShowErrorReason = AppCreationFailureReason.UNKNOWN;
// mClient is null only when it has closed.
@Nullable private PaymentRequestClient mClient;
private @Nullable PaymentRequestClient mClient;
// mBrowserPaymentRequest is null when it has closed or is uninitiated.
@Nullable private BrowserPaymentRequest mBrowserPaymentRequest;
private @Nullable BrowserPaymentRequest mBrowserPaymentRequest;
/** The helper to create and fill the response to send to the merchant. */
@Nullable private PaymentResponseHelperInterface mPaymentResponseHelper;
private @Nullable PaymentResponseHelperInterface mPaymentResponseHelper;
/** A mapping of the payment method names to the corresponding payment method specific data. */
@SuppressWarnings("NullAway.Init") // When init() fails this can have null value
private HashMap<String, PaymentMethodData> mQueryForQuota;
/**
@ -142,7 +155,7 @@ public class PaymentRequestService
private boolean mIsCanMakePaymentResponsePending;
private boolean mIsHasEnrolledInstrumentResponsePending;
@Nullable private PaymentApp mInvokedPaymentApp;
private @Nullable PaymentApp mInvokedPaymentApp;
/** True if a show() call is rejected for lack of a user activation. */
private boolean mRejectShowForUserActivation;
@ -162,7 +175,7 @@ public class PaymentRequestService
void onHasEnrolledInstrumentReturned();
void onAppListReady(@Nullable List<PaymentApp> paymentApps, PaymentItem total);
void onAppListReady(@Nullable List<PaymentApp> paymentApps, @Nullable PaymentItem total);
void onShippingSectionVisibilityChange(boolean isShippingSectionVisible);
@ -223,8 +236,7 @@ public class PaymentRequestService
* returns the package name for Trusted Web Activity. Otherwise returns an empty string
* or null.
*/
@Nullable
String getTwaPackageName();
@Nullable String getTwaPackageName();
/**
* Gets the WebContents from a RenderFrameHost if the WebContents has not been destroyed;
@ -234,8 +246,7 @@ public class PaymentRequestService
* WebContents contains.
* @return The WebContents.
*/
@Nullable
default WebContents getLiveWebContents(RenderFrameHost renderFrameHost) {
default @Nullable WebContents getLiveWebContents(RenderFrameHost renderFrameHost) {
return PaymentRequestServiceUtil.getLiveWebContents(renderFrameHost);
}
@ -318,8 +329,7 @@ public class PaymentRequestService
*
* @return The instance, can be null for testing.
*/
@Nullable
default PaymentAppFactoryInterface createAndroidPaymentAppFactory() {
default @Nullable PaymentAppFactoryInterface createAndroidPaymentAppFactory() {
return new AndroidPaymentAppFactory();
}
@ -327,8 +337,7 @@ public class PaymentRequestService
* @return The context of the current activity, can be null when WebContents has been
* destroyed, the activity is gone, the window is closed, etc.
*/
@Nullable
default Context getContext(RenderFrameHost renderFrameHost) {
default @Nullable Context getContext(RenderFrameHost renderFrameHost) {
WindowAndroid window = getWindowAndroid(renderFrameHost);
if (window == null) return null;
return window.getContext().get();
@ -338,8 +347,7 @@ public class PaymentRequestService
* @return The WindowAndroid of the current activity, can be null when WebContents has been
* destroyed, the activity is gone, etc.
*/
@Nullable
default WindowAndroid getWindowAndroid(RenderFrameHost renderFrameHost) {
default @Nullable WindowAndroid getWindowAndroid(RenderFrameHost renderFrameHost) {
WebContents webContents = PaymentRequestServiceUtil.getLiveWebContents(renderFrameHost);
if (webContents == null) return null;
return webContents.getTopLevelNativeWindow();
@ -435,7 +443,7 @@ public class PaymentRequestService
* @return Whether the initialization is successful.
*/
public boolean init(
@Nullable PaymentMethodData[] rawMethodData,
PaymentMethodData @Nullable [] rawMethodData,
@Nullable PaymentDetails details,
@Nullable PaymentOptions options) {
if (mRenderFrameHost.getLastCommittedOrigin() == null
@ -448,11 +456,12 @@ public class PaymentRequestService
mPaymentRequestOrigin =
mDelegate.formatUrlForSecurityDisplay(mRenderFrameHost.getLastCommittedURL());
mWebContents = mDelegate.getLiveWebContents(mRenderFrameHost);
if (mWebContents == null || mWebContents.isDestroyed()) {
WebContents webContents = mDelegate.getLiveWebContents(mRenderFrameHost);
if (webContents == null || webContents.isDestroyed()) {
abortForInvalidDataFromRenderer(ErrorStrings.NO_WEB_CONTENTS);
return false;
}
mWebContents = webContents;
// TODO(crbug.com/41475385): replace UrlFormatter with GURL operations.
mTopLevelOrigin = mDelegate.formatUrlForSecurityDisplay(mWebContents.getLastCommittedUrl());
@ -585,6 +594,7 @@ public class PaymentRequestService
return false;
}
PaymentMethodData spcMethodData = methodData.get(MethodStrings.SECURE_PAYMENT_CONFIRMATION);
assumeNonNull(spcMethodData);
if (spcMethodData.securePaymentConfirmation == null) return false;
// TODO(crbug.com/40231121): Update checks to match desktop browser-side logic.
@ -637,12 +647,12 @@ public class PaymentRequestService
* @return The WebContents of the payment handler that's just opened when the opening is
* successful; null if failed.
*/
@Nullable
public static WebContents openPaymentHandlerWindow(GURL url) {
public static @Nullable WebContents openPaymentHandlerWindow(GURL url) {
if (sShowingPaymentRequest == null) return null;
PaymentApp invokedPaymentApp = sShowingPaymentRequest.mInvokedPaymentApp;
assert invokedPaymentApp != null;
assert invokedPaymentApp.getPaymentAppType() == PaymentAppType.SERVICE_WORKER_APP;
assumeNonNull(sShowingPaymentRequest.mBrowserPaymentRequest);
return sShowingPaymentRequest.mBrowserPaymentRequest.openPaymentHandlerWindow(
url, invokedPaymentApp.getUkmSourceId());
}
@ -698,8 +708,7 @@ public class PaymentRequestService
/**
* @return Get the native=side observer, for testing purpose only.
*/
@Nullable
public static NativeObserverForTest getNativeObserverForTest() {
public static @Nullable NativeObserverForTest getNativeObserverForTest() {
return sNativeObserverForTest;
}
@ -739,12 +748,14 @@ public class PaymentRequestService
// Implements PaymentResponseHelper.PaymentResponseResultCallback:
@Override
public void onPaymentResponseReady(PaymentResponse response) {
assumeNonNull(mBrowserPaymentRequest);
if (!mBrowserPaymentRequest.patchPaymentResponseIfNeeded(response)) {
disconnectFromClientWithDebugMessage(
ErrorStrings.PAYMENT_APP_INVALID_RESPONSE, PaymentErrorReason.NOT_SUPPORTED);
// Intentionally do not early-return.
}
if (response.methodName.equals(MethodStrings.SECURE_PAYMENT_CONFIRMATION)) {
assumeNonNull(mInvokedPaymentApp);
assert mInvokedPaymentApp.getInstrumentMethodNames().contains(response.methodName);
response = mInvokedPaymentApp.setAppSpecificResponseFields(response);
}
@ -825,13 +836,13 @@ public class PaymentRequestService
? mSpec.getRawShippingOptions()
: Collections.unmodifiableList(new ArrayList<>());
paymentApp.invokePaymentApp(
mSpec.getId(),
assumeNonNull(mSpec.getId()),
mMerchantName,
mTopLevelOrigin,
mPaymentRequestOrigin,
getCertificateChain(),
Collections.unmodifiableMap(methodData),
mSpec.getRawTotal(),
assumeNonNull(mSpec.getRawTotal()),
mSpec.getRawLineItems(),
Collections.unmodifiableMap(modifiers),
paymentOptions,
@ -912,8 +923,7 @@ public class PaymentRequestService
}
}
@Nullable
private PaymentNotShownError onShowCalledAndAppsQueried() {
private @Nullable PaymentNotShownError onShowCalledAndAppsQueried() {
assert mIsShowCalled;
assert mIsFinishedQueryingPaymentApps;
assert mBrowserPaymentRequest != null;
@ -989,10 +999,10 @@ public class PaymentRequestService
*
* @return The error if the payment cannot be made; null otherwise.
*/
@Nullable
private PaymentNotShownError ensureHasSupportedPaymentMethods() {
private @Nullable PaymentNotShownError ensureHasSupportedPaymentMethods() {
assert mIsShowCalled;
assert mIsFinishedQueryingPaymentApps;
assumeNonNull(mBrowserPaymentRequest);
if (!mCanMakePayment || !mBrowserPaymentRequest.hasAvailableApps()) {
// All factories have responded, but none of them have apps. It's possible to add credit
// cards, but the merchant does not support them either. The payment request must be
@ -1166,12 +1176,14 @@ public class PaymentRequestService
// Implements PaymentAppFactoryDelegate:
@Override
public DialogController getDialogController() {
assumeNonNull(mBrowserPaymentRequest);
return mBrowserPaymentRequest.getDialogController();
}
// Implements PaymentAppFactoryDelegate:
@Override
public AndroidIntentLauncher getAndroidIntentLauncher() {
assumeNonNull(mBrowserPaymentRequest);
return mBrowserPaymentRequest.getAndroidIntentLauncher();
}
@ -1180,8 +1192,7 @@ public class PaymentRequestService
* @return The validated method data, a mapping of method names to its PaymentMethodData(s);
* when the given method data is invalid, returns null.
*/
@Nullable
private static Map<String, PaymentMethodData> getValidatedMethodData(
private static @Nullable Map<String, PaymentMethodData> getValidatedMethodData(
PaymentMethodData[] methodDataList) {
// Payment methodData are required.
assert methodDataList != null;
@ -1228,6 +1239,7 @@ public class PaymentRequestService
if (!hadUserActivation) {
PaymentRequestWebContentsData paymentRequestWebContentsData =
PaymentRequestWebContentsData.from(mWebContents);
assumeNonNull(paymentRequestWebContentsData);
if (paymentRequestWebContentsData.hadActivationlessShow()) {
// Reject the call to show(), because only one activationless show is allowed per
// page.
@ -1326,13 +1338,14 @@ public class PaymentRequestService
}
private boolean isPaymentDetailsUpdateValid(PaymentDetails details) {
assumeNonNull(mBrowserPaymentRequest);
// ID cannot be updated. Updating the total is optional.
return details.id == null
&& mDelegate.validatePaymentDetails(details)
&& mBrowserPaymentRequest.parseAndValidateDetailsFurtherIfNeeded(details);
}
private String continueShowWithUpdatedDetails(@Nullable PaymentDetails details) {
private @Nullable String continueShowWithUpdatedDetails(@Nullable PaymentDetails details) {
assert mIsShowWaitingForUpdatedDetails;
assert mBrowserPaymentRequest != null;
// mSpec.updateWith() can be used only when mSpec has not been destroyed.
@ -1406,6 +1419,7 @@ public class PaymentRequestService
// After a payment app has been invoked, all of the merchant's calls to update the price
// via updateWith() should be forwarded to the invoked app, so it can reflect the
// updated price in its UI.
assumeNonNull(mInvokedPaymentApp);
mInvokedPaymentApp.updateWith(
PaymentDetailsConverter.convertToPaymentRequestDetailsUpdate(
details, /* methodChecker= */ this, mInvokedPaymentApp));
@ -1601,8 +1615,7 @@ public class PaymentRequestService
/**
* @return An observer for the payment request service, if any; otherwise, null.
*/
@Nullable
public static PaymentRequestServiceObserverForTest getObserverForTest() {
public static @Nullable PaymentRequestServiceObserverForTest getObserverForTest() {
return sObserverForTest;
}
@ -1685,7 +1698,7 @@ public class PaymentRequestService
// PaymentAppFactoryParams implementation.
@Override
public String getId() {
public @Nullable String getId() {
assert !mHasClosed;
assert !mSpec.isDestroyed();
return mSpec.getId();
@ -1711,8 +1724,8 @@ public class PaymentRequestService
// PaymentAppFactoryParams implementation.
@Override
@Nullable
public byte[][] getCertificateChain() {
public byte @Nullable [][] getCertificateChain() {
assumeNonNull(mBrowserPaymentRequest);
return mBrowserPaymentRequest.getCertificateChain();
}
@ -1726,7 +1739,7 @@ public class PaymentRequestService
// PaymentAppFactoryParams implementation.
@Override
public PaymentItem getRawTotal() {
public @Nullable PaymentItem getRawTotal() {
assert !mHasClosed;
assert !mSpec.isDestroyed();
return mSpec.getRawTotal();
@ -1758,8 +1771,7 @@ public class PaymentRequestService
// PaymentAppFactoryParams implementation.
@Override
@Nullable
public String getTwaPackageName() {
public @Nullable String getTwaPackageName() {
return mDelegate.getTwaPackageName();
}
@ -1881,8 +1893,7 @@ public class PaymentRequestService
}
@VisibleForTesting
@Nullable
public static BrowserPaymentRequest getBrowserPaymentRequestForTesting() {
public static @Nullable BrowserPaymentRequest getBrowserPaymentRequestForTesting() {
return sShowingPaymentRequest != null
? sShowingPaymentRequest.mBrowserPaymentRequest
: null;

@ -4,14 +4,15 @@
package org.chromium.components.payments;
import androidx.annotation.Nullable;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.content_public.browser.RenderFrameHost;
import org.chromium.content_public.browser.Visibility;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsStatics;
/** The utility class for PaymentRequestFactory and WebLayerPaymentRequestFactory. */
@NullMarked
public final class PaymentRequestServiceUtil {
/**
* Gets the WebContents from a RenderFrameHost if the WebContents has not been destroyed;
@ -20,8 +21,7 @@ public final class PaymentRequestServiceUtil {
* WebContents contains.
* @return The WebContents.
*/
@Nullable
public static WebContents getLiveWebContents(RenderFrameHost renderFrameHost) {
public static @Nullable WebContents getLiveWebContents(RenderFrameHost renderFrameHost) {
WebContents webContents = WebContentsStatics.fromRenderFrameHost(renderFrameHost);
return webContents != null && !webContents.isDestroyed() ? webContents : null;
}

@ -10,6 +10,8 @@ import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.base.UserData;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.content.browser.webcontents.WebContentsImpl;
import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory;
import org.chromium.content_public.browser.WebContents;
@ -21,8 +23,9 @@ import org.chromium.content_public.browser.WebContentsObserver;
* user activation, which is recorded and tracked by the native PaymentRequestWebContentsManager.
*/
@JNINamespace("payments::android")
@NullMarked
public class PaymentRequestWebContentsData extends WebContentsObserver implements UserData {
private static PaymentRequestWebContentsData sInstanceForTesting;
private static @Nullable PaymentRequestWebContentsData sInstanceForTesting;
private static final class UserDataFactoryLazyHolder {
private static final UserDataFactory<PaymentRequestWebContentsData> INSTANCE =
@ -40,7 +43,7 @@ public class PaymentRequestWebContentsData extends WebContentsObserver implement
* @param webContents The web contents of the current PaymentRequest.
* @return the PaymentRequestWebContentsData instance.
*/
public static PaymentRequestWebContentsData from(WebContents webContents) {
public static @Nullable PaymentRequestWebContentsData from(WebContents webContents) {
return sInstanceForTesting != null
? sInstanceForTesting
: ((WebContentsImpl) webContents)

@ -4,6 +4,7 @@
package org.chromium.components.payments;
import org.chromium.build.annotations.NullMarked;
import org.chromium.payments.mojom.PayerDetail;
import org.chromium.payments.mojom.PaymentOptions;
import org.chromium.payments.mojom.PaymentResponse;
@ -13,6 +14,7 @@ import org.chromium.payments.mojom.PaymentResponse;
* Compared to ChromePaymentResponseHelper, this helper does not handle the Autofill data, and so
* can be used for WebLayerPaymentRequestService.
*/
@NullMarked
public class PaymentResponseHelper implements PaymentResponseHelperInterface {
private final PaymentResponse mPaymentResponse;
private final PaymentOptions mPaymentOptions;

@ -4,12 +4,14 @@
package org.chromium.components.payments;
import org.chromium.build.annotations.NullMarked;
import org.chromium.payments.mojom.PaymentResponse;
/**
* The interface of a helper class that generates a {@link PaymentResponse} with the input of
* payment details.
*/
@NullMarked
public interface PaymentResponseHelperInterface {
/**
* Generates a {@link PaymentResponse} with the given payment details.

@ -4,9 +4,11 @@
package org.chromium.components.payments;
import org.chromium.build.annotations.NullMarked;
import org.chromium.content_public.browser.WebContents;
/** The interface of PaymentUiService that provides testing methods. */
@NullMarked
public interface PaymentUiServiceTestInterface {
/**
* Get the WebContents of the Payment Handler; return null if nonexistent.

@ -7,6 +7,7 @@ package org.chromium.components.payments;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.payments.mojom.PaymentDetails;
import org.chromium.payments.mojom.PaymentValidationErrors;
@ -14,6 +15,7 @@ import java.nio.ByteBuffer;
/** Static class to represent a JNI interface to a C++ validation library. */
@JNINamespace("payments")
@NullMarked
public class PaymentValidator {
public static boolean validatePaymentDetails(PaymentDetails details) {
if (details == null) {

@ -7,10 +7,12 @@ package org.chromium.components.payments;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.content_public.browser.WebContents;
/** SSL validity checker. */
@JNINamespace("payments")
@NullMarked
public class SslValidityChecker {
/**
* Returns a developer-facing error message for invalid SSL certificate state or an empty

@ -4,11 +4,12 @@
package org.chromium.components.payments;
import androidx.annotation.Nullable;
import org.chromium.base.Log;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
/** This class represents the supported delegations of a service worker based payment app. */
@NullMarked
public class SupportedDelegations {
private static final String TAG = "SupportedDelegations";
private final boolean mShippingAddress;
@ -57,7 +58,7 @@ public class SupportedDelegations {
}
public static SupportedDelegations createFromStringArray(
@Nullable String[] supportedDelegationsNames) throws IllegalArgumentException {
String @Nullable [] supportedDelegationsNames) throws IllegalArgumentException {
if (supportedDelegationsNames == null || supportedDelegationsNames.length == 0) {
return new SupportedDelegations();
}

@ -7,11 +7,13 @@ package org.chromium.components.payments;
import org.jni_zero.JNINamespace;
import org.jni_zero.NativeMethods;
import org.chromium.build.annotations.NullMarked;
import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.url.GURL;
/** URL validity checker for web payment APIs. */
@JNINamespace("payments::android")
@NullMarked
public class UrlUtil {
/**
* Returns false for invalid URL format or a relative URI.

@ -4,7 +4,10 @@
package org.chromium.components.payments;
import org.chromium.build.annotations.NullMarked;
/** Java equivalent of components/payments/content/web_app_manifest.h:WebAppManifestSection */
@NullMarked
public final class WebAppManifestSection {
/**
* Constructor that does not set the fingerprints. They have to be set after the object is

@ -17,9 +17,12 @@ import androidx.annotation.VisibleForTesting;
import org.chromium.IsReadyToPayService;
import org.chromium.IsReadyToPayServiceCallback;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.components.payments.PrePurchaseQuery;
/** A helper to query the payment app's IsReadyToPay service. */
@NullMarked
public class IsReadyToPayServiceHelper extends IsReadyToPayServiceCallback.Stub
implements ServiceConnection {
/** The maximum number of milliseconds to wait for a response from a READY_TO_PAY service. */
@ -31,7 +34,7 @@ public class IsReadyToPayServiceHelper extends IsReadyToPayServiceCallback.Stub
private final Context mContext;
// This callback can be used only once, set to null after that.
private ResultHandler mResultHandler;
private @Nullable ResultHandler mResultHandler;
private boolean mIsServiceBindingInitiated;
private boolean mIsServiceConnected;

@ -122,7 +122,7 @@ public class WebPaymentIntentHelper {
public static void parsePaymentResponse(
int resultCode,
Intent data,
PaymentOptions requestedPaymentOptions,
@Nullable PaymentOptions requestedPaymentOptions,
PaymentErrorCallback errorCallback,
PaymentSuccessCallback successCallback) {
if (data == null) {

@ -115,10 +115,10 @@ public final class WebPaymentIntentHelperType {
/** The class that corresponds mojom.PaymentDetailsModifier, with minimally required fields. */
public static final class PaymentDetailsModifier {
public final PaymentItem total;
public final @Nullable PaymentItem total;
public final PaymentMethodData methodData;
public PaymentDetailsModifier(PaymentItem total, PaymentMethodData methodData) {
public PaymentDetailsModifier(@Nullable PaymentItem total, PaymentMethodData methodData) {
this.total = total;
this.methodData = methodData;
}

@ -7,8 +7,9 @@ package org.chromium.components.payments.intent;
import android.os.Bundle;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import org.chromium.build.annotations.Contract;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.payments.mojom.AddressErrors;
import org.chromium.payments.mojom.PaymentCurrencyAmount;
import org.chromium.payments.mojom.PaymentDetailsModifier;
@ -29,34 +30,36 @@ import java.util.Map;
* This class defines the utility functions that convert the payment info types in
* org.chromium.payments.mojom to their counterparts in WebPaymentIntentHelperType.
*/
@NullMarked
public final class WebPaymentIntentHelperTypeConverter {
@Nullable
public static WebPaymentIntentHelperType.PaymentCurrencyAmount fromMojoPaymentCurrencyAmount(
@Nullable PaymentCurrencyAmount currencyAmount) {
@Contract("!null -> !null")
public static WebPaymentIntentHelperType.@Nullable PaymentCurrencyAmount
fromMojoPaymentCurrencyAmount(@Nullable PaymentCurrencyAmount currencyAmount) {
if (currencyAmount == null) return null;
return new WebPaymentIntentHelperType.PaymentCurrencyAmount(
/* currency= */ currencyAmount.currency, /* value= */ currencyAmount.value);
}
@Nullable
public static WebPaymentIntentHelperType.PaymentItem fromMojoPaymentItem(
@Contract("!null -> !null")
public static WebPaymentIntentHelperType.@Nullable PaymentItem fromMojoPaymentItem(
@Nullable PaymentItem item) {
if (item == null) return null;
return new WebPaymentIntentHelperType.PaymentItem(
fromMojoPaymentCurrencyAmount(item.amount));
}
@Nullable
public static WebPaymentIntentHelperType.PaymentDetailsModifier fromMojoPaymentDetailsModifier(
@Nullable PaymentDetailsModifier detailsModifier) {
@Contract("!null -> !null")
public static WebPaymentIntentHelperType.@Nullable PaymentDetailsModifier
fromMojoPaymentDetailsModifier(@Nullable PaymentDetailsModifier detailsModifier) {
if (detailsModifier == null) return null;
return new WebPaymentIntentHelperType.PaymentDetailsModifier(
fromMojoPaymentItem(detailsModifier.total),
fromMojoPaymentMethodData(detailsModifier.methodData));
}
@Nullable
public static WebPaymentIntentHelperType.PaymentMethodData fromMojoPaymentMethodData(
@Contract("!null -> !null")
public static WebPaymentIntentHelperType.@Nullable PaymentMethodData fromMojoPaymentMethodData(
@Nullable PaymentMethodData methodData) {
if (methodData == null) return null;
return new WebPaymentIntentHelperType.PaymentMethodData(
@ -64,9 +67,10 @@ public final class WebPaymentIntentHelperTypeConverter {
/* stringifiedData= */ methodData.stringifiedData);
}
@Nullable
public static Map<String, WebPaymentIntentHelperType.PaymentMethodData>
fromMojoPaymentMethodDataMap(@Nullable Map<String, PaymentMethodData> methodDataMap) {
@Contract("!null -> !null")
public static @Nullable
Map<String, WebPaymentIntentHelperType.PaymentMethodData> fromMojoPaymentMethodDataMap(
@Nullable Map<String, PaymentMethodData> methodDataMap) {
if (methodDataMap == null) return null;
Map<String, WebPaymentIntentHelperType.PaymentMethodData> compatibleMethodDataMap =
new HashMap<>();
@ -79,10 +83,11 @@ public final class WebPaymentIntentHelperTypeConverter {
return compatibleMethodDataMap;
}
@Nullable
public static Map<String, WebPaymentIntentHelperType.PaymentDetailsModifier>
fromMojoPaymentDetailsModifierMap(
@Nullable Map<String, PaymentDetailsModifier> modifiers) {
@Contract("!null -> !null")
public static @Nullable
Map<String, WebPaymentIntentHelperType.PaymentDetailsModifier>
fromMojoPaymentDetailsModifierMap(
@Nullable Map<String, PaymentDetailsModifier> modifiers) {
if (modifiers == null) return null;
Map<String, WebPaymentIntentHelperType.PaymentDetailsModifier> compatibleModifiers =
new HashMap<>();
@ -95,8 +100,8 @@ public final class WebPaymentIntentHelperTypeConverter {
return compatibleModifiers;
}
@Nullable
public static List<WebPaymentIntentHelperType.PaymentItem> fromMojoPaymentItems(
@Contract("!null -> !null")
public static @Nullable List<WebPaymentIntentHelperType.PaymentItem> fromMojoPaymentItems(
@Nullable List<PaymentItem> paymentItems) {
if (paymentItems == null) return null;
List<WebPaymentIntentHelperType.PaymentItem> compatiblePaymentItems = new ArrayList<>();
@ -107,9 +112,9 @@ public final class WebPaymentIntentHelperTypeConverter {
return compatiblePaymentItems;
}
@Nullable
public static WebPaymentIntentHelperType.PaymentShippingOption fromMojoPaymentShippingOption(
@Nullable PaymentShippingOption shippingOption) {
@Contract("!null -> !null")
public static WebPaymentIntentHelperType.@Nullable PaymentShippingOption
fromMojoPaymentShippingOption(@Nullable PaymentShippingOption shippingOption) {
if (shippingOption == null) return null;
return new WebPaymentIntentHelperType.PaymentShippingOption(
shippingOption.id,
@ -118,9 +123,10 @@ public final class WebPaymentIntentHelperTypeConverter {
shippingOption.selected);
}
@Nullable
public static List<WebPaymentIntentHelperType.PaymentShippingOption> fromMojoShippingOptionList(
@Nullable List<PaymentShippingOption> shippingOptions) {
@Contract("!null -> !null")
public static @Nullable
List<WebPaymentIntentHelperType.PaymentShippingOption> fromMojoShippingOptionList(
@Nullable List<PaymentShippingOption> shippingOptions) {
if (shippingOptions == null) return null;
List<WebPaymentIntentHelperType.PaymentShippingOption> shippingOptionList =
new ArrayList<>();
@ -131,8 +137,8 @@ public final class WebPaymentIntentHelperTypeConverter {
return shippingOptionList;
}
@Nullable
public static WebPaymentIntentHelperType.PaymentOptions fromMojoPaymentOptions(
@Contract("!null -> !null")
public static WebPaymentIntentHelperType.@Nullable PaymentOptions fromMojoPaymentOptions(
@Nullable PaymentOptions paymentOptions) {
if (paymentOptions == null) return null;
String shippingType = null;
@ -157,8 +163,9 @@ public final class WebPaymentIntentHelperTypeConverter {
shippingType);
}
@Nullable
private static Bundle fromMojoShippingAddressErrors(@Nullable AddressErrors addressErrors) {
@Contract("!null -> !null")
private static @Nullable Bundle fromMojoShippingAddressErrors(
@Nullable AddressErrors addressErrors) {
if (addressErrors == null) return null;
Bundle bundle = new Bundle();
putIfNonEmpty("addressLine", addressErrors.addressLine, bundle);
@ -184,8 +191,8 @@ public final class WebPaymentIntentHelperTypeConverter {
* @param update The mojo PaymentRequestDetailsUpdate to be converted.
* @return The converted update.
*/
@Nullable
public static WebPaymentIntentHelperType.PaymentRequestDetailsUpdate
@Contract("!null -> !null")
public static WebPaymentIntentHelperType.@Nullable PaymentRequestDetailsUpdate
fromMojoPaymentRequestDetailsUpdate(@Nullable PaymentRequestDetailsUpdate update) {
if (update == null) return null;
return new WebPaymentIntentHelperType.PaymentRequestDetailsUpdate(

@ -4,18 +4,21 @@
package org.chromium.components.payments.secure_payment_confirmation;
import static org.chromium.build.NullUtil.assertNonNull;
import static org.chromium.build.NullUtil.assumeNonNull;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Pair;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.core.content.res.ResourcesCompat;
import org.chromium.base.Callback;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
@ -41,12 +44,16 @@ import java.util.Locale;
* component from other components and acts as the point of contact between them. Any code in this
* component that needs to interact with another component does that through this controller.
*/
@NullMarked
public class SecurePaymentConfirmationAuthnController {
private final WebContents mWebContents;
private Runnable mHider;
private Callback<Boolean> mResponseCallback;
private Runnable mOptOutCallback;
private SecurePaymentConfirmationAuthnView mView;
private @Nullable Runnable mHider;
private @Nullable Callback<Boolean> mResponseCallback;
private @Nullable Runnable mOptOutCallback;
private @Nullable SecurePaymentConfirmationAuthnView mView;
private InputProtector mInputProtector = new InputProtector();
@ -66,11 +73,12 @@ public class SecurePaymentConfirmationAuthnController {
new BottomSheetContent() {
@Override
public View getContentView() {
assumeNonNull(mView);
return mView.getContentView();
}
@Override
public View getToolbarView() {
public @Nullable View getToolbarView() {
return null;
}
@ -112,7 +120,7 @@ public class SecurePaymentConfirmationAuthnController {
}
@Override
public @NonNull String getSheetContentDescription(Context context) {
public String getSheetContentDescription(Context context) {
return context.getString(
R.string.secure_payment_confirmation_authentication_sheet_description);
}
@ -139,7 +147,8 @@ public class SecurePaymentConfirmationAuthnController {
*
* @param webContents The WebContents of the merchant.
*/
public static SecurePaymentConfirmationAuthnController create(WebContents webContents) {
public static @Nullable SecurePaymentConfirmationAuthnController create(
WebContents webContents) {
return webContents != null
? new SecurePaymentConfirmationAuthnController(webContents)
: null;
@ -263,7 +272,7 @@ public class SecurePaymentConfirmationAuthnController {
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
public SecurePaymentConfirmationAuthnView getView() {
public @Nullable SecurePaymentConfirmationAuthnView getView() {
return mView;
}
@ -272,12 +281,13 @@ public class SecurePaymentConfirmationAuthnController {
return mHider == null;
}
private String getStoreLabel(@Nullable String payeeName, @Nullable Origin payeeOrigin) {
private String getStoreLabel(
@Nullable String payeeName, @Nullable Origin payeeOrigin) {
// At least one of the payeeName and payeeOrigin must be non-null in SPC; this should be
// enforced by PaymentRequestService.isValidSecurePaymentConfirmationRequest.
assert payeeName != null || payeeOrigin != null;
if (payeeOrigin == null) return payeeName;
if (payeeOrigin == null) return assertNonNull(payeeName);
String origin =
UrlFormatter.formatOriginForSecurityDisplay(
@ -295,6 +305,7 @@ public class SecurePaymentConfirmationAuthnController {
private void onConfirm() {
hide();
assumeNonNull(mResponseCallback);
mResponseCallback.onResult(true);
}
@ -304,6 +315,7 @@ public class SecurePaymentConfirmationAuthnController {
private void onCancel() {
hide();
assumeNonNull(mResponseCallback);
mResponseCallback.onResult(false);
}

@ -7,6 +7,7 @@ package org.chromium.components.payments.secure_payment_confirmation;
import android.graphics.drawable.Drawable;
import android.util.Pair;
import org.chromium.build.annotations.NullMarked;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel.ReadableObjectPropertyKey;
@ -14,6 +15,7 @@ import org.chromium.ui.modelutil.PropertyModel.ReadableObjectPropertyKey;
* The properties of the SecurePaymentConfirmation Authn UI, which fully describe the state of the
* UI.
*/
@NullMarked
/* package */ class SecurePaymentConfirmationAuthnProperties {
/** The store value of the UI. */
/* package */ static final ReadableObjectPropertyKey<String> STORE_LABEL =

@ -14,6 +14,7 @@ import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import org.chromium.build.annotations.NullMarked;
import org.chromium.components.payments.R;
import org.chromium.ui.widget.TextViewWithClickableSpans;
@ -22,6 +23,7 @@ import org.chromium.ui.widget.TextViewWithClickableSpans;
* state. It has a fixed height, which is the height of the visible content area. It shows the
* payment details and provides the option to continue with the payment or to cancel.
*/
@NullMarked
/* package */ class SecurePaymentConfirmationAuthnView {
/**
* Bundles the information necessary to show the opt out UX, if requested by the caller.

@ -11,6 +11,7 @@ import android.util.Pair;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import org.chromium.build.annotations.NullMarked;
import org.chromium.components.payments.R;
import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.modelutil.PropertyKey;
@ -23,6 +24,7 @@ import org.chromium.ui.text.SpanApplier.SpanInfo;
* The view binder of the SecurePaymentConfirmation Authn UI, which is stateless. It is called to
* bind a given model to a given view. Should contain as little business logic as possible.
*/
@NullMarked
/* package */ class SecurePaymentConfirmationAuthnViewBinder {
/* package */ static void bind(
PropertyModel model, SecurePaymentConfirmationAuthnView view, PropertyKey propertyKey) {

@ -3,12 +3,15 @@
// found in the LICENSE file.
package org.chromium.components.payments.secure_payment_confirmation;
import static org.chromium.build.NullUtil.assumeNonNull;
import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
@ -28,12 +31,13 @@ import org.chromium.ui.base.WindowAndroid;
* between them. Any code in this component that needs to interact with another component does that
* through this controller.
*/
@NullMarked
public class SecurePaymentConfirmationNoMatchingCredController {
private final WebContents mWebContents;
private Runnable mHider;
private Runnable mResponseCallback;
private Runnable mOptOutCallback;
private SecurePaymentConfirmationNoMatchingCredView mView;
private @Nullable Runnable mHider;
private @Nullable Runnable mResponseCallback;
private @Nullable Runnable mOptOutCallback;
private @Nullable SecurePaymentConfirmationNoMatchingCredView mView;
private InputProtector mInputProtector = new InputProtector();
@ -53,11 +57,12 @@ public class SecurePaymentConfirmationNoMatchingCredController {
new BottomSheetContent() {
@Override
public View getContentView() {
assumeNonNull(mView);
return mView.getContentView();
}
@Override
public View getToolbarView() {
public @Nullable View getToolbarView() {
return null;
}
@ -99,7 +104,7 @@ public class SecurePaymentConfirmationNoMatchingCredController {
}
@Override
public @NonNull String getSheetContentDescription(Context context) {
public String getSheetContentDescription(Context context) {
return context.getString(
R.string
.secure_payment_confirmation_no_matching_credential_sheet_description);
@ -127,7 +132,7 @@ public class SecurePaymentConfirmationNoMatchingCredController {
*
* @param webContents The WebContents of the merchant.
*/
public static SecurePaymentConfirmationNoMatchingCredController create(
public static @Nullable SecurePaymentConfirmationNoMatchingCredController create(
WebContents webContents) {
return webContents != null
? new SecurePaymentConfirmationNoMatchingCredController(webContents)
@ -223,7 +228,7 @@ public class SecurePaymentConfirmationNoMatchingCredController {
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
public SecurePaymentConfirmationNoMatchingCredView getView() {
public @Nullable SecurePaymentConfirmationNoMatchingCredView getView() {
return mView;
}

@ -15,6 +15,7 @@ import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import org.chromium.build.annotations.NullMarked;
import org.chromium.components.payments.R;
import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.text.ChromeClickableSpan;
@ -27,6 +28,7 @@ import org.chromium.ui.widget.TextViewWithClickableSpans;
* peeked or half-open state. It has a fixed height, which is the height of the visible content
* area. It informs the user that additional steps are needed to verify the payment.
*/
@NullMarked
public class SecurePaymentConfirmationNoMatchingCredView {
private final RelativeLayout mContentView;
private final ScrollView mScrollView;

@ -287,7 +287,7 @@ public class GURL {
}
@Override
public final boolean equals(Object other) {
public final boolean equals(@Nullable Object other) {
if (other == this) return true;
if (!(other instanceof GURL)) return false;
return mSpec.equals(((GURL) other).mSpec);