0

[Android][CredMan] Clean up launched WebAuthnAndroid Features

The feature is fully launched and can be cleaned up. While the parameter
for the flag isn't necessary, it should remain in tests to cover the
behaviour on different device types.

Minor fixes:
* guard clauses for what is an easy return now
* ResettersForTesting prevents leaking overrides or cached support
* renamed tests which included the flag name

Fixed: 40284674
Change-Id: I466a7b2f386ab73e2007bbfd60daeac3f1b812b5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6263448
Commit-Queue: Friedrich Hauser <friedrichh@chromium.org>
Reviewed-by: Nina Satragno <nsatragno@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1421019}
This commit is contained in:
Friedrich Horschig
2025-02-17 03:45:25 -08:00
committed by Chromium LUCI CQ
parent 8f44711a62
commit be6a3663a7
8 changed files with 95 additions and 239 deletions
chrome/browser/touch_to_fill/password_manager/android/javatests/src/org/chromium/chrome/browser/touch_to_fill
components/webauthn/android
java
src
org
chromium
components
junit
src
org
device/fido
services/device/public
tools/metrics/histograms

@ -944,7 +944,8 @@ public class TouchToFillViewTest {
.getString(
R.string.touch_to_fill_sheet_passkey_credential_context)));
CredManSupportProvider.setupForTesting(/*override*/ false);
CredManSupportProvider.setupForTesting(
/* overrideAndroidVersion= */ null, /* overrideForcesGpm= */ null);
}
private ChromeActivity getActivity() {

@ -7,9 +7,12 @@ package org.chromium.components.webauthn.cred_man;
import android.content.Context;
import android.os.Build;
import androidx.annotation.Nullable;
import org.jni_zero.CalledByNative;
import org.chromium.base.ContextUtils;
import org.chromium.base.ResettersForTesting;
import org.chromium.base.ServiceLoaderUtil;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.version_info.VersionInfo;
@ -17,8 +20,6 @@ import org.chromium.components.webauthn.CredManSupport;
import org.chromium.components.webauthn.GmsCoreUtils;
import org.chromium.components.webauthn.WebauthnMode;
import org.chromium.components.webauthn.WebauthnModeProvider;
import org.chromium.device.DeviceFeatureList;
import org.chromium.device.DeviceFeatureMap;
public class CredManSupportProvider {
private static final int GMSCORE_MIN_VERSION_CANARY_DEV = 241900000;
@ -26,11 +27,23 @@ public class CredManSupportProvider {
private static @CredManSupport int sCredManSupport;
private static boolean sOverrideVersionCheckForTesting;
private static @Nullable Integer sOverrideAndroidVersion;
private static @Nullable Boolean sOverrideForcesGpm;
public static void setupForTesting(boolean override) {
sOverrideVersionCheckForTesting = override;
public static void setupForTesting(
@Nullable Integer overrideAndroidVersion, @Nullable Boolean overrideForcesGpm) {
sOverrideAndroidVersion = overrideAndroidVersion;
sOverrideForcesGpm = overrideForcesGpm;
sCredManSupport = CredManSupport.NOT_EVALUATED;
ResettersForTesting.register(
() -> {
sOverrideAndroidVersion = null;
sOverrideForcesGpm = null;
// While this is not a test-specific value, the state shouldn't leak between
// tests.
sCredManSupport = CredManSupport.NOT_EVALUATED;
});
}
@CalledByNative
@ -38,18 +51,15 @@ public class CredManSupportProvider {
if (sCredManSupport != CredManSupport.NOT_EVALUATED) {
return sCredManSupport;
}
if (!sOverrideVersionCheckForTesting) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
sCredManSupport = CredManSupport.DISABLED;
return sCredManSupport;
}
if (hasOldGmsVersion()) {
sCredManSupport = CredManSupport.DISABLED;
return sCredManSupport;
}
if (getAndroidVersion() < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
sCredManSupport = CredManSupport.DISABLED;
return sCredManSupport;
}
if (!sOverrideVersionCheckForTesting
if (notSkippedBecauseInTests() && hasOldGmsVersion()) {
sCredManSupport = CredManSupport.DISABLED;
return sCredManSupport;
}
if (notSkippedBecauseInTests()
&& ContextUtils.getApplicationContext().getSystemService(Context.CREDENTIAL_SERVICE)
== null) {
sCredManSupport = CredManSupport.DISABLED;
@ -58,30 +68,20 @@ public class CredManSupportProvider {
}
recordCredManAvailability(/*available*/ true);
if (DeviceFeatureMap.isEnabled(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN)) {
CredManUiRecommender recommender =
ServiceLoaderUtil.maybeCreate(CredManUiRecommender.class);
boolean customUiRecommended =
recommender == null ? false : recommender.recommendsCustomUi();
boolean gpmInCredMan =
DeviceFeatureMap.getInstance()
.getFieldTrialParamByFeatureAsBoolean(
DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN,
"gpm_in_cred_man",
customUiRecommended);
boolean isChrome3pPwmMode =
WebauthnModeProvider.getInstance().getGlobalWebauthnMode()
== WebauthnMode.CHROME_3PP_ENABLED;
// In CHROME_3PP_ENABLED mode Chrome does not use FIDO2 APIs parallel with CredMan. This
// is because Chrome's Password Manager capabilities are disabled.
sCredManSupport =
gpmInCredMan || isChrome3pPwmMode
? CredManSupport.FULL_UNLESS_INAPPLICABLE
: CredManSupport.PARALLEL_WITH_FIDO_2;
return sCredManSupport;
}
sCredManSupport = CredManSupport.IF_REQUIRED;
final CredManUiRecommender recommender =
ServiceLoaderUtil.maybeCreate(CredManUiRecommender.class);
boolean customUiRecommended = recommender != null && recommender.recommendsCustomUi();
boolean gpmInCredMan =
sOverrideForcesGpm != null ? sOverrideForcesGpm : customUiRecommended;
boolean isChrome3pPwmMode =
WebauthnModeProvider.getInstance().getGlobalWebauthnMode()
== WebauthnMode.CHROME_3PP_ENABLED;
// In CHROME_3PP_ENABLED mode Chrome does not use FIDO2 APIs parallel with CredMan. This
// is because Chrome's Password Manager capabilities are disabled.
sCredManSupport =
gpmInCredMan || isChrome3pPwmMode
? CredManSupport.FULL_UNLESS_INAPPLICABLE
: CredManSupport.PARALLEL_WITH_FIDO_2;
return sCredManSupport;
}
@ -89,16 +89,15 @@ public class CredManSupportProvider {
if (sCredManSupport != CredManSupport.NOT_EVALUATED) {
return sCredManSupport;
}
if (!sOverrideVersionCheckForTesting) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
sCredManSupport = CredManSupport.DISABLED;
return sCredManSupport;
}
if (ContextUtils.getApplicationContext().getSystemService(Context.CREDENTIAL_SERVICE)
== null) {
sCredManSupport = CredManSupport.DISABLED;
return sCredManSupport;
}
if (getAndroidVersion() < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
sCredManSupport = CredManSupport.DISABLED;
return sCredManSupport;
}
if (notSkippedBecauseInTests()
&& ContextUtils.getApplicationContext().getSystemService(Context.CREDENTIAL_SERVICE)
== null) {
sCredManSupport = CredManSupport.DISABLED;
return sCredManSupport;
}
sCredManSupport = CredManSupport.FULL_UNLESS_INAPPLICABLE;
return sCredManSupport;
@ -110,20 +109,18 @@ public class CredManSupportProvider {
}
private static boolean hasOldGmsVersion() {
assert !sOverrideVersionCheckForTesting : "Don't use in testing!";
int gmsVersion = GmsCoreUtils.getGmsCoreVersion();
if (gmsVersion == -1) {
return true; // Couldn't get a GMS version. Assume insufficient GMS availability.
}
assert sOverrideAndroidVersion == null : "Don't use in testing!";
// The check works for unavailable and low GMS versions. `getGmsCoreVersion()` is -1 if the
// GMS version can't be retrieved. Chrome assumes an insufficient GMS availability then.
return GmsCoreUtils.getGmsCoreVersion() < getMinGmsVersionForCurrentChannel();
}
final int requiredMinGmsVersion =
DeviceFeatureMap.getInstance()
.getFieldTrialParamByFeatureAsInt(
DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN,
"min_gms_core_version_no_dots",
getMinGmsVersionForCurrentChannel());
private static int getAndroidVersion() {
return sOverrideAndroidVersion == null ? Build.VERSION.SDK_INT : sOverrideAndroidVersion;
}
return gmsVersion < requiredMinGmsVersion;
private static boolean notSkippedBecauseInTests() {
return sOverrideForcesGpm == null && sOverrideAndroidVersion == null;
}
private static int getMinGmsVersionForCurrentChannel() {

@ -101,8 +101,6 @@ public class Fido2CredentialRequestRobolectricTest {
@Before
public void setUp() throws Exception {
FeatureOverrides.newBuilder()
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN)
.param("gpm_in_cred_man", true)
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_USE_PASSKEY_CACHE)
.disable(BlinkFeatures.SECURE_PAYMENT_CONFIRMATION_BROWSER_BOUND_KEYS)
.apply();
@ -175,8 +173,9 @@ public class Fido2CredentialRequestRobolectricTest {
.performGetAssertionWebAuthSecurityChecks(
any(String.class), any(Origin.class), anyBoolean(), any(Callback.class));
// Reset any cached evaluation of whether CredMan should be supported.
CredManSupportProvider.setupForTesting(true);
CredManSupportProvider.setupForTesting(
/* overrideAndroidVersion= */ Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
/* overrideForcesGpm= */ true);
Fido2GetCredentialsComparator.Factory.setInstanceForTesting(mGetCredentialsComparator);
mRequest.overrideBrowserBridgeForTesting(mBrowserBridgeMock);
mRequest.setCredManHelperForTesting(mCredManHelperMock);
@ -191,8 +190,7 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void testMakeCredential_credManEnabled() {
public void testMakeCredential() {
mRequest.handleMakeCredentialRequest(
mCreationOptions,
/* maybeBrowserOptions= */ null,
@ -207,25 +205,6 @@ public class Fido2CredentialRequestRobolectricTest {
.startMakeRequest(any(), any(), any(), any(), any(), any());
}
@Test
@SmallTest
public void testMakeCredential_credManDisabled_notUsed() {
FeatureOverrides.disable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN);
mRequest.handleMakeCredentialRequest(
mCreationOptions,
mBrowserOptions,
mOrigin,
mOrigin,
/* paymentOptions= */ null,
mCallback::onRegisterResponse,
mCallback::onError,
mCallback::onRequestOutcome);
verify(mCredManHelperMock, times(0))
.startMakeRequest(any(), any(), any(), any(), any(), any());
}
@Test
@SmallTest
public void testMakeCredential_rkDiscouraged_goesToPlayServices() {
@ -273,7 +252,9 @@ public class Fido2CredentialRequestRobolectricTest {
public void testMakeCredential_webauthnModeAppAndBelowAndroid14_goesToPlayServices() {
Mockito.when(mModeProviderMock.getWebauthnMode(any())).thenReturn(WebauthnMode.APP);
Mockito.when(mModeProviderMock.getGlobalWebauthnMode()).thenReturn(WebauthnMode.NONE);
CredManSupportProvider.setupForTesting(/* override= */ false);
CredManSupportProvider.setupForTesting(
/* overrideAndroidVersion= */ Build.VERSION_CODES.TIRAMISU,
/* overrideForcesGpm= */ false);
mRequest.handleMakeCredentialRequest(
mCreationOptions,
@ -294,7 +275,6 @@ public class Fido2CredentialRequestRobolectricTest {
public void testMakeCredential_webauthnModeAppAndAboveAndroid14_goesToCredMan() {
Mockito.when(mModeProviderMock.getWebauthnMode(any())).thenReturn(WebauthnMode.APP);
Mockito.when(mModeProviderMock.getGlobalWebauthnMode()).thenReturn(WebauthnMode.NONE);
CredManSupportProvider.setupForTesting(/* override= */ true);
mRequest.handleMakeCredentialRequest(
mCreationOptions,
@ -319,8 +299,7 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void testGetAssertion_credManEnabledWithGpmInCredManFlag_success() {
public void testGetAssertion_success() {
mRequest.handleGetAssertionRequest(
mRequestOptions,
mOrigin,
@ -346,13 +325,10 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void
testGetAssertion_credManEnabledWithGpmNotInCredManFlag_doesNotCallGetAssertionImmediately() {
FeatureOverrides.newBuilder()
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_USE_PASSKEY_CACHE)
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN)
.param("gpm_in_cred_man", false)
.apply();
public void testGetAssertion_GpmNotInCredMan_doesNotCallGetAssertionImmediately() {
CredManSupportProvider.setupForTesting(
/* overrideAndroidVersion= */ Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
/* overrideForcesGpm= */ false);
mRequest.handleGetAssertionRequest(
mRequestOptions,
@ -385,27 +361,6 @@ public class Fido2CredentialRequestRobolectricTest {
assertThat(mFido2ApiCallHelper.mGetAssertionCalled).isFalse();
}
@Test
@SmallTest
public void testGetAssertion_credManDisabled_notUsed() {
FeatureOverrides.newBuilder()
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_USE_PASSKEY_CACHE)
.disable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN)
.apply();
mRequest.handleGetAssertionRequest(
mRequestOptions,
mOrigin,
mOrigin,
/* payment= */ null,
(responseStatus, response) -> mCallback.onSignResponse(responseStatus, response),
mCallback::onError,
mCallback::onRequestOutcome);
verifyNoInteractions(mCredManHelperMock);
assertThat(mFido2ApiCallHelper.mPasskeyCacheGetCredentialsCalled).isTrue();
}
@Test
@SmallTest
public void testGetAssertion_allowListMatchWithExplicitHash_goesToPlayServices() {
@ -426,7 +381,7 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void testGetAssertion_credManNoCredentialsWithGpmInCredManFlag_fallbackToPlayServices() {
public void testGetAssertion_NoCredentials_fallbackToPlayServices() {
mFido2ApiCallHelper.mCredentialsError = new IllegalStateException("injected error");
mRequest.handleGetAssertionRequest(
@ -526,10 +481,9 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void testGetAssertion_allowListNoMatchWhenGpmNotInCredMan_goesToCredMan() {
FeatureOverrides.newBuilder()
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN)
.param("gpm_in_cred_man", false)
.apply();
CredManSupportProvider.setupForTesting(
/* overrideAndroidVersion= */ Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
/* overrideForcesGpm= */ false);
PublicKeyCredentialDescriptor descriptor = new PublicKeyCredentialDescriptor();
descriptor.type = 0;
@ -555,7 +509,9 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void testGetAssertion_WebAuthnModeApp_GoesToPlayServices() {
CredManSupportProvider.setupForTesting(/* override= */ false);
CredManSupportProvider.setupForTesting(
/* overrideAndroidVersion= */ Build.VERSION_CODES.TIRAMISU,
/* overrideForcesGpm= */ false);
Mockito.when(mModeProviderMock.getWebauthnMode(any())).thenReturn(WebauthnMode.APP);
Mockito.when(mModeProviderMock.getGlobalWebauthnMode()).thenReturn(WebauthnMode.NONE);
@ -576,7 +532,9 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void testGetAssertion_WebAuthnModeApp_failsIfGmscoreNotAvailable() {
CredManSupportProvider.setupForTesting(/* override= */ false);
CredManSupportProvider.setupForTesting(
/* overrideAndroidVersion= */ Build.VERSION_CODES.TIRAMISU,
/* overrideForcesGpm= */ false);
Mockito.when(mModeProviderMock.getWebauthnMode(any())).thenReturn(WebauthnMode.APP);
Mockito.when(mModeProviderMock.getGlobalWebauthnMode()).thenReturn(WebauthnMode.NONE);
@ -601,7 +559,7 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void testConditionalGetAssertion_credManEnabledSuccessWithGpmInCredManFlag_success() {
public void testConditionalGetAssertion_success() {
mRequestOptions.mediation = Mediation.CONDITIONAL;
mRequest.handleGetAssertionRequest(
@ -629,13 +587,11 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void testConditionalGetAssertion_credManEnabledSuccessWithGpmNotInCredManFlag_success() {
public void testConditionalGetAssertion_GpmNotInCredMan_success() {
mRequestOptions.mediation = Mediation.CONDITIONAL;
FeatureOverrides.newBuilder()
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_USE_PASSKEY_CACHE)
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN)
.param("gpm_in_cred_man", false)
.apply();
CredManSupportProvider.setupForTesting(
/* overrideAndroidVersion= */ Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
/* overrideForcesGpm= */ false);
mRequest.handleGetAssertionRequest(
mRequestOptions,
@ -689,8 +645,7 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void
testConditionalGetAssertion_credManEnabledRpCancelWhileIdleWithGpmInCredManFlag_notAllowedError() {
public void testConditionalGetAssertion_RpCancelWhileIdleWithGpmInCredMan_notAllowedError() {
mRequestOptions.mediation = Mediation.CONDITIONAL;
mRequest.handleGetAssertionRequest(
@ -713,14 +668,11 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void
testConditionalGetAssertion_credManEnabledRpCancelWhileIdleWithGpmNotInCredManFlag_notAllowedError() {
public void testConditionalGetAssertion_RpCancelWhileIdleWithGpmNotInCredMan_notAllowedError() {
mRequestOptions.mediation = Mediation.CONDITIONAL;
FeatureOverrides.newBuilder()
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_USE_PASSKEY_CACHE)
.enable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN)
.param("gpm_in_cred_man", false)
.apply();
CredManSupportProvider.setupForTesting(
/* overrideAndroidVersion= */ Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
/* overrideForcesGpm= */ false);
mRequest.handleGetAssertionRequest(
mRequestOptions,
@ -784,55 +736,7 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void
testConditionalGetAssertion_webauthnModeChrome3ppAndCredManDisabled_notImplemented() {
FeatureOverrides.disable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN);
mRequestOptions.mediation = Mediation.CONDITIONAL;
Mockito.when(mModeProviderMock.getWebauthnMode(any()))
.thenReturn(WebauthnMode.CHROME_3PP_ENABLED);
Mockito.when(mModeProviderMock.getGlobalWebauthnMode())
.thenReturn(WebauthnMode.CHROME_3PP_ENABLED);
mRequest.handleGetAssertionRequest(
mRequestOptions,
mOrigin,
mOrigin,
/* payment= */ null,
mCallback::onSignResponse,
mCallback::onError,
mCallback::onRequestOutcome);
assertThat(mCallback.getStatus()).isEqualTo(AuthenticatorStatus.NOT_IMPLEMENTED);
verifyNoInteractions(mCredManHelperMock);
}
@Test
@SmallTest
public void testGetAssertion_webauthnModeChrome3ppAndCredManDisabled_goesToPlayServices() {
FeatureOverrides.disable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN);
Mockito.when(mModeProviderMock.getWebauthnMode(any()))
.thenReturn(WebauthnMode.CHROME_3PP_ENABLED);
Mockito.when(mModeProviderMock.getGlobalWebauthnMode())
.thenReturn(WebauthnMode.CHROME_3PP_ENABLED);
mRequest.handleGetAssertionRequest(
mRequestOptions,
mOrigin,
mOrigin,
/* payment= */ null,
mCallback::onSignResponse,
mCallback::onError,
mCallback::onRequestOutcome);
verifyNoInteractions(mCredManHelperMock);
assertThat(mFido2ApiCallHelper.mGetAssertionCalled).isTrue();
}
@Test
@SmallTest
public void testConditionalGetAssertion_webauthnModeChrome3ppAndCredManEnabled_goesToCredMan() {
FeatureOverrides.enable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN);
public void testConditionalGetAssertion_webauthnModeChrome3pp_goesToCredMan() {
mRequestOptions.mediation = Mediation.CONDITIONAL;
Mockito.when(mModeProviderMock.getWebauthnMode(any()))
.thenReturn(WebauthnMode.CHROME_3PP_ENABLED);
@ -856,9 +760,7 @@ public class Fido2CredentialRequestRobolectricTest {
@Test
@SmallTest
public void testGetAssertion_webauthnModeChrome3ppAndCredManEnabled_goesToCredMan() {
FeatureOverrides.enable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN);
public void testGetAssertion_webauthnModeChrome3pp_goesToCredMan() {
Mockito.when(mModeProviderMock.getWebauthnMode(any()))
.thenReturn(WebauthnMode.CHROME_3PP_ENABLED);
Mockito.when(mModeProviderMock.getGlobalWebauthnMode())
@ -878,28 +780,6 @@ public class Fido2CredentialRequestRobolectricTest {
assertThat(mFido2ApiCallHelper.mGetAssertionCalled).isFalse();
}
@Test
@SmallTest
public void
testGetAssertion_webauthnModeChromeAndCredManDisabledAndComparatorDisabled_noPasskeyCacheCall() {
FeatureOverrides.newBuilder()
.disable(DeviceFeatureList.WEBAUTHN_ANDROID_USE_PASSKEY_CACHE)
.disable(DeviceFeatureList.WEBAUTHN_ANDROID_CRED_MAN)
.apply();
mRequest.handleGetAssertionRequest(
mRequestOptions,
mOrigin,
mOrigin,
/* payment= */ null,
mCallback::onSignResponse,
mCallback::onError,
mCallback::onRequestOutcome);
assertThat(mFido2ApiCallHelper.mFido2GetCredentialsCalled).isTrue();
assertThat(mFido2ApiCallHelper.mPasskeyCacheGetCredentialsCalled).isFalse();
}
private WebauthnCredentialDetails createWebauthnCredential() {
PublicKeyCredentialDescriptor descriptor = new PublicKeyCredentialDescriptor();
descriptor.type = 0;

@ -38,11 +38,6 @@ BASE_FEATURE(kWebAuthCableExtensionAnywhere,
base::FEATURE_DISABLED_BY_DEFAULT);
#if BUILDFLAG(IS_ANDROID)
// Enabled in M129. Remove in or after M132.
BASE_FEATURE(kWebAuthnAndroidCredMan,
"WebAuthenticationAndroidCredMan",
base::FEATURE_ENABLED_BY_DEFAULT);
// Enabled in M132. Remove in or after M135 or when the comparison histograms
// are not needed anymore.
BASE_FEATURE(kWebAuthnAndroidUsePasskeyCache,

@ -23,15 +23,6 @@ COMPONENT_EXPORT(DEVICE_FIDO)
BASE_DECLARE_FEATURE(kWebAuthCableExtensionAnywhere);
#if BUILDFLAG(IS_ANDROID)
// Use the Android 14 Credential Manager API.
COMPONENT_EXPORT(DEVICE_FIDO)
BASE_DECLARE_FEATURE(kWebAuthnAndroidCredMan);
// Use the Android 14 Credential Manager API for credentials stored in Gmscore.
COMPONENT_EXPORT(DEVICE_FIDO)
inline constexpr base::FeatureParam<bool> kWebAuthnAndroidGpmInCredMan{
&kWebAuthnAndroidCredMan, "gpm_in_cred_man", false};
// Use the passkey cache service parallel to the FIDO2 module to retrieve
// passkeys from GMSCore. This is for comparison only.
COMPONENT_EXPORT(DEVICE_FIDO)

@ -22,7 +22,6 @@ namespace {
// services/device/public/cpp/device_features.h or in other locations in the
// code base.
const base::Feature* const kFeaturesExposedToJava[] = {
&device::kWebAuthnAndroidCredMan,
&device::kWebAuthnAndroidUsePasskeyCache,
&device::kWebAuthnEnablePaaskFragment,
&kGenericSensorExtraClasses,

@ -18,7 +18,6 @@ import org.chromium.build.annotations.NullMarked;
@NullMarked
public abstract class DeviceFeatureList {
public static final String GENERIC_SENSOR_EXTRA_CLASSES = "GenericSensorExtraClasses";
public static final String WEBAUTHN_ANDROID_CRED_MAN = "WebAuthenticationAndroidCredMan";
public static final String WEBAUTHN_ANDROID_USE_PASSKEY_CACHE =
"WebAuthenticationAndroidUsePasskeyCache";
public static final String BATTERY_STATUS_MANAGER_BROADCAST_RECEIVER_IN_BACKGROUND =

@ -10308,7 +10308,6 @@ from previous Chrome versions.
label="RTCDisallowPlanBOutsideDeprecationTrial:enabled"/>
<int value="-1508852757" label="CreditCardAutofillTouchBar:disabled"/>
<int value="-1508837668" label="VCPortraitRelighting:enabled"/>
<int value="-1507810873" label="WebAuthenticationAndroidCredMan:enabled"/>
<int value="-1507722271" label="ImprovedDesksKeyboardShortcuts:enabled"/>
<int value="-1506880454"
label="SupervisedUserCommittedInterstitials:disabled"/>
@ -10850,8 +10849,6 @@ from previous Chrome versions.
<int value="-1300934428" label="ExternalNavigationDebugLogs:enabled"/>
<int value="-1300692087" label="SplitTabStrip:enabled"/>
<int value="-1299599424" label="VcDlcUi:disabled"/>
<int value="-1298884037"
label="WebAuthenticationAndroidCredManAndGmsCore:disabled"/>
<int value="-1298273481" label="http2-grease-settings"/>
<int value="-1298067767" label="CalendarModelDebugMode:disabled"/>
<int value="-1297664593" label="SafetyHubMagicStack:enabled"/>
@ -11816,8 +11813,6 @@ from previous Chrome versions.
<int value="-917218910" label="FirstPartyVietnameseInput:enabled"/>
<int value="-916780902" label="ExternalPciDevicesAllowed:enabled"/>
<int value="-916419217" label="LensOverlay:disabled"/>
<int value="-916325423"
label="WebAuthenticationAndroidCredManAndGmsCore:enabled"/>
<int value="-915687759" label="CrOSLateBootAudioOffloadCrasDSPToSOF:enabled"/>
<int value="-915328316" label="CupsIppPrintingBackend:disabled"/>
<int value="-915035507" label="ArcPrintSpoolerExperiment:enabled"/>
@ -16840,7 +16835,6 @@ from previous Chrome versions.
label="SyncOnlySeparateUserDisplayModeForCrOS:enabled"/>
<int value="1084972292" label="WebXRAnchors:enabled"/>
<int value="1085130793" label="LongPressBackForHistory:disabled"/>
<int value="1085260595" label="WebAuthenticationAndroidCredMan:disabled"/>
<int value="1085366788"
label="kFileSystemAccessPersistentPermissions:disabled"/>
<int value="1085919447"