Merge "Update "none selected" state to align with mocks:" into main
diff --git a/res/drawable/ic_private_space_icon.xml b/res/drawable/ic_private_space_icon.xml
new file mode 100644
index 0000000..fc0894d
--- /dev/null
+++ b/res/drawable/ic_private_space_icon.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+<path
+    android:pathData="M5,3H19C20.1,3 21,3.9 21,5V19C21,20.1 20.1,21 19,21H5C3.9,21 3,20.1 3,19V5C3,3.9 3.9,3 5,3ZM13.5,15.501L12.93,12.271C13.57,11.941 14,11.271 14,10.501C14,9.401 13.1,8.501 12,8.501C10.9,8.501 10,9.401 10,10.501C10,11.271 10.43,11.941 11.07,12.271L10.5,15.501H13.5Z"
+    android:fillColor="?android:attr/colorAccent"
+    android:fillType="evenOdd"/>
+</vector>
diff --git a/res/drawable/ic_privatespace_icon.xml b/res/drawable/ic_privatespace_icon.xml
deleted file mode 100644
index b651f52..0000000
--- a/res/drawable/ic_privatespace_icon.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-  ~ Copyright (C) 2023 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="960"
-        android:viewportHeight="960"
-        android:tint="?attr/colorControlNormal">
-    <path
-        android:fillColor="@android:color/white"
-        android:pathData="M420,600L540,600L517,471Q537,461 548.5,442Q560,423 560,400Q560,367 536.5,343.5Q513,320 480,320Q447,320 423.5,343.5Q400,367 400,400Q400,423 411.5,442Q423,461 443,471L420,600ZM480,880Q341,845 250.5,720.5Q160,596 160,444L160,200L480,80L800,200L800,444Q800,596 709.5,720.5Q619,845 480,880ZM480,796Q584,763 652,664Q720,565 720,444L720,255L480,165L240,255L240,444Q240,565 308,664Q376,763 480,796ZM480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Z"/>
-</vector>
-
diff --git a/res/layout/privatespace_advancing_screen.xml b/res/layout/privatespace_advancing_screen.xml
index 3a85b16..bce37a6 100644
--- a/res/layout/privatespace_advancing_screen.xml
+++ b/res/layout/privatespace_advancing_screen.xml
@@ -20,7 +20,7 @@
     android:id="@+id/private_space_autoadvance_screen"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:icon="@drawable/ic_privatespace_icon">
+    android:icon="@drawable/ic_private_space_icon">
     <LinearLayout style="@style/SudContentFrame"
                   android:layout_width="match_parent"
                   android:layout_height="match_parent"
diff --git a/res/layout/privatespace_education_screen.xml b/res/layout/privatespace_education_screen.xml
index 350e780..6f2ac4e 100644
--- a/res/layout/privatespace_education_screen.xml
+++ b/res/layout/privatespace_education_screen.xml
@@ -23,7 +23,7 @@
     android:filterTouchesWhenObscured="true"
     app:sucHeaderText="@string/private_space_setup_title"
     app:sudDescriptionText="@string/private_space_hide_apps_summary"
-    android:icon="@drawable/ic_privatespace_icon">
+    android:icon="@drawable/ic_private_space_icon">
     <ScrollView
         android:id="@+id/main_clear_scrollview"
         android:layout_width="match_parent"
diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
index d98bc51..be0658e 100644
--- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
@@ -568,7 +568,7 @@
      */
     @VisibleForTesting
     public boolean togglePackageNameEnabled(String packageName) {
-        if (mEnabledPackageNames.size() >= MAX_SELECTABLE_PROVIDERS) {
+        if (hasProviderLimitBeenReached()) {
             return false;
         } else {
             mEnabledPackageNames.add(packageName);
@@ -623,6 +623,19 @@
         return mIconResizer.createIconThumbnail(providerIcon);
     }
 
+    private boolean hasProviderLimitBeenReached() {
+        return hasProviderLimitBeenReached(mEnabledPackageNames.size());
+    }
+
+    @VisibleForTesting
+    public static boolean hasProviderLimitBeenReached(int enabledAdditionalProviderCount) {
+        // If the number of package names has reached the maximum limit then
+        // we should stop any new packages from being added. We will also
+        // reserve one place for the primary provider so if the max limit is
+        // five providers this will be four additional plus the primary.
+        return (enabledAdditionalProviderCount + 1) >= MAX_SELECTABLE_PROVIDERS;
+    }
+
     private CombiPreference addProviderPreference(
             @NonNull Context prefContext,
             @NonNull CharSequence title,
@@ -648,19 +661,18 @@
         pref.setPreferenceListener(
                 new CombiPreference.OnCombiPreferenceClickListener() {
                     @Override
-                    public void onCheckChanged(CombiPreference p, boolean isChecked) {
+                    public boolean onCheckChanged(CombiPreference p, boolean isChecked) {
                         if (isChecked) {
-                            if (mEnabledPackageNames.size() >= MAX_SELECTABLE_PROVIDERS) {
+                            if (hasProviderLimitBeenReached()) {
                                 // Show the error if too many enabled.
-                                pref.setChecked(false);
                                 final DialogFragment fragment = newErrorDialogFragment();
 
                                 if (fragment == null || mFragmentManager == null) {
-                                    return;
+                                    return false;
                                 }
 
                                 fragment.show(mFragmentManager, ErrorDialogFragment.TAG);
-                                return;
+                                return false;
                             }
 
                             togglePackageNameEnabled(packageName);
@@ -672,6 +684,8 @@
                         } else {
                             togglePackageNameDisabled(packageName);
                         }
+
+                        return true;
                     }
 
                     @Override
@@ -989,8 +1003,13 @@
             @Override
             public void onClick(View buttonView) {
                 // Forward the event.
-                if (mSwitch != null) {
-                    mOnClickListener.onCheckChanged(CombiPreference.this, mSwitch.isChecked());
+                if (mSwitch != null && mOnClickListener != null) {
+                    if (!mOnClickListener.onCheckChanged(CombiPreference.this, mSwitch.isChecked())) {
+                      // The update was not successful since there were too
+                      // many enabled providers to manually reset any state.
+                      mChecked = false;
+                      mSwitch.setChecked(false);
+                    }
                 }
             }
         }
@@ -1004,7 +1023,7 @@
 
         public interface OnCombiPreferenceClickListener {
             /** Called when the check is updated */
-            void onCheckChanged(CombiPreference p, boolean isChecked);
+            boolean onCheckChanged(CombiPreference p, boolean isChecked);
 
             /** Called when the left side is clicked. */
             void onLeftSideClicked();
diff --git a/src/com/android/settings/display/DisplayFeatureProvider.java b/src/com/android/settings/display/DisplayFeatureProvider.java
new file mode 100644
index 0000000..a7c8dbb
--- /dev/null
+++ b/src/com/android/settings/display/DisplayFeatureProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.display;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.TogglePreferenceController;
+
+/** Feature provider for display settings */
+public interface DisplayFeatureProvider {
+
+    /** Create toggle preference */
+    @Nullable
+    TogglePreferenceController createAdditionalPreference(@NonNull Context context);
+
+    /** Update toggle preference */
+    void updatePreference(@Nullable TogglePreferenceController togglePreferenceController);
+
+    /** Add toggle preference to PreferenceScreen */
+    void addToScreen(@Nullable TogglePreferenceController togglePreferenceController,
+            @NonNull PreferenceScreen screen);
+}
diff --git a/src/com/android/settings/display/DisplayFeatureProviderImpl.java b/src/com/android/settings/display/DisplayFeatureProviderImpl.java
new file mode 100644
index 0000000..c9ec791
--- /dev/null
+++ b/src/com/android/settings/display/DisplayFeatureProviderImpl.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.display;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.TogglePreferenceController;
+
+public class DisplayFeatureProviderImpl implements DisplayFeatureProvider {
+
+    @Override
+    @Nullable
+    public TogglePreferenceController createAdditionalPreference(@NonNull Context context) {
+        return null;
+    }
+
+    @Override
+    public void updatePreference(@Nullable TogglePreferenceController togglePreferenceController) {
+
+    }
+
+    @Override
+    public void addToScreen(@Nullable TogglePreferenceController togglePreferenceController,
+            @NonNull PreferenceScreen screen) {
+
+    }
+}
diff --git a/src/com/android/settings/display/ScreenTimeoutSettings.java b/src/com/android/settings/display/ScreenTimeoutSettings.java
index 1c99d5f..2d229a3 100644
--- a/src/com/android/settings/display/ScreenTimeoutSettings.java
+++ b/src/com/android/settings/display/ScreenTimeoutSettings.java
@@ -34,9 +34,11 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import androidx.annotation.Nullable;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
 import com.android.settings.flags.Flags;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -106,6 +108,9 @@
     @VisibleForTesting
     AdaptiveSleepBatterySaverPreferenceController mAdaptiveSleepBatterySaverPreferenceController;
 
+    @Nullable
+    TogglePreferenceController mAdditionalTogglePreferenceController;
+
     public ScreenTimeoutSettings() {
         super();
         mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
@@ -133,6 +138,8 @@
                 com.android.settingslib.widget.preference.footer.R.layout.preference_footer);
         mPrivacyManager = SensorPrivacyManager.getInstance(context);
         mPrivacyChangedListener = (sensor, enabled) -> mAdaptiveSleepController.updatePreference();
+        mAdditionalTogglePreferenceController = FeatureFactory.getFeatureFactory()
+                .getDisplayFeatureProvider().createAdditionalPreference(context);
     }
 
     @Override
@@ -164,6 +171,8 @@
                 mReceiver, new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
         mPrivacyManager.addSensorPrivacyListener(CAMERA, mPrivacyChangedListener);
         mIsUserAuthenticated = false;
+        FeatureFactory.getFeatureFactory().getDisplayFeatureProvider().updatePreference(
+                mAdditionalTogglePreferenceController);
     }
 
     @Override
@@ -210,6 +219,9 @@
         mPrivacyPreference.setLayoutResource(
                 com.android.settingslib.widget.preference.footer.R.layout.preference_footer);
 
+        FeatureFactory.getFeatureFactory().getDisplayFeatureProvider()
+                .addToScreen(mAdditionalTogglePreferenceController, screen);
+
         if (isScreenAttentionAvailable(getContext())) {
             mAdaptiveSleepPermissionController.addToScreen(screen);
             mAdaptiveSleepCameraStatePreferenceController.addToScreen(screen);
diff --git a/src/com/android/settings/overlay/FeatureFactory.kt b/src/com/android/settings/overlay/FeatureFactory.kt
index 8a68122..37507a8 100644
--- a/src/com/android/settings/overlay/FeatureFactory.kt
+++ b/src/com/android/settings/overlay/FeatureFactory.kt
@@ -29,6 +29,7 @@
 import com.android.settings.dashboard.DashboardFeatureProvider
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider
 import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider
+import com.android.settings.display.DisplayFeatureProvider
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider
 import com.android.settings.fuelgauge.BatterySettingsFeatureProvider
 import com.android.settings.fuelgauge.BatteryStatusFeatureProvider
@@ -176,6 +177,11 @@
      */
     abstract val privateSpaceLoginFeatureProvider: PrivateSpaceLoginFeatureProvider
 
+    /**
+     * Gets implementation for Display feature.
+     */
+    abstract val displayFeatureProvider: DisplayFeatureProvider
+
     companion object {
         private var _factory: FeatureFactory? = null
 
diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.kt b/src/com/android/settings/overlay/FeatureFactoryImpl.kt
index 28dbb23..e0313b7 100644
--- a/src/com/android/settings/overlay/FeatureFactoryImpl.kt
+++ b/src/com/android/settings/overlay/FeatureFactoryImpl.kt
@@ -45,6 +45,8 @@
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl
 import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider
 import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProviderImpl
+import com.android.settings.display.DisplayFeatureProvider
+import com.android.settings.display.DisplayFeatureProviderImpl
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProviderImpl
 import com.android.settings.fuelgauge.BatterySettingsFeatureProviderImpl
 import com.android.settings.fuelgauge.BatteryStatusFeatureProviderImpl
@@ -190,4 +192,7 @@
     override val privateSpaceLoginFeatureProvider: PrivateSpaceLoginFeatureProvider by lazy {
         PrivateSpaceLoginFeatureProviderImpl()
     }
+    override val displayFeatureProvider: DisplayFeatureProvider by lazy {
+        DisplayFeatureProviderImpl()
+    }
 }
diff --git a/src/com/android/settings/webview/WebViewUpdateServiceWrapper.java b/src/com/android/settings/webview/WebViewUpdateServiceWrapper.java
index 05855e4..546320c 100644
--- a/src/com/android/settings/webview/WebViewUpdateServiceWrapper.java
+++ b/src/com/android/settings/webview/WebViewUpdateServiceWrapper.java
@@ -20,12 +20,12 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.os.RemoteException;
 import android.util.Log;
 import android.webkit.IWebViewUpdateService;
 import android.webkit.UserPackage;
 import android.webkit.WebViewFactory;
 import android.webkit.WebViewProviderInfo;
+import android.webkit.WebViewUpdateManager;
 import android.widget.Toast;
 
 import androidx.annotation.Nullable;
@@ -44,8 +44,12 @@
      */
     public PackageInfo getCurrentWebViewPackage() {
         try {
-            return WebViewFactory.getUpdateService().getCurrentWebViewPackage();
-        } catch (RemoteException e) {
+            if (android.webkit.Flags.updateServiceIpcWrapper()) {
+                return WebViewUpdateManager.getInstance().getCurrentWebViewPackage();
+            } else {
+                return WebViewFactory.getUpdateService().getCurrentWebViewPackage();
+            }
+        } catch (Exception e) {
             Log.e(TAG, e.toString());
         }
         return null;
@@ -59,8 +63,13 @@
     public List<ApplicationInfo> getValidWebViewApplicationInfos(Context context) {
         WebViewProviderInfo[] providers = null;
         try {
-            providers = WebViewFactory.getUpdateService().getValidWebViewPackages();
-        } catch (RemoteException e) {
+            if (android.webkit.Flags.updateServiceIpcWrapper()) {
+                providers = context.getSystemService(WebViewUpdateManager.class)
+                        .getValidWebViewPackages();
+            } else {
+                providers = WebViewFactory.getUpdateService().getValidWebViewPackages();
+            }
+        } catch (Exception e) {
         }
         List<ApplicationInfo> pkgs = new ArrayList<>();
         for (WebViewProviderInfo provider : providers) {
@@ -80,10 +89,15 @@
      */
     public boolean setWebViewProvider(String packageName) {
         try {
-            return packageName.equals(
-                    WebViewFactory.getUpdateService().changeProviderAndSetting(packageName));
-        } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException when trying to change provider to " + packageName, e);
+            if (android.webkit.Flags.updateServiceIpcWrapper()) {
+                return packageName.equals(
+                        WebViewUpdateManager.getInstance().changeProviderAndSetting(packageName));
+            } else {
+                return packageName.equals(
+                        WebViewFactory.getUpdateService().changeProviderAndSetting(packageName));
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "Exception when trying to change provider to " + packageName, e);
         }
         return false;
     }
@@ -112,18 +126,23 @@
      */
     @Nullable
     public String getDefaultWebViewPackageName() {
+        WebViewProviderInfo provider = null;
         try {
-            IWebViewUpdateService service = WebViewFactory.getUpdateService();
-            if (service != null) {
-                WebViewProviderInfo provider = service.getDefaultWebViewPackage();
-                if (provider != null) {
-                    return provider.packageName;
+            if (android.webkit.Flags.updateServiceIpcWrapper()) {
+                WebViewUpdateManager manager = WebViewUpdateManager.getInstance();
+                if (manager != null) {
+                    provider = manager.getDefaultWebViewPackage();
+                }
+            } else {
+                IWebViewUpdateService service = WebViewFactory.getUpdateService();
+                if (service != null) {
+                    provider = service.getDefaultWebViewPackage();
                 }
             }
-        } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException when trying to fetch default WebView package Name", e);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception when trying to fetch default WebView package Name", e);
         }
-        return null;
+        return provider != null ? provider.packageName : null;
     }
 
     static final int PACKAGE_FLAGS = PackageManager.MATCH_ANY_USER;
diff --git a/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java
index 5a5008c..a11b226 100644
--- a/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/testutils/com/android/settings/testutils/FakeFeatureFactory.java
@@ -33,6 +33,7 @@
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider;
 import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProviderImpl;
+import com.android.settings.display.DisplayFeatureProvider;
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
 import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
 import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -101,6 +102,7 @@
     public OnboardingFeatureProvider mOnboardingFeatureProvider;
     public FastPairFeatureProvider mFastPairFeatureProvider;
     public PrivateSpaceLoginFeatureProvider mPrivateSpaceLoginFeatureProvider;
+    public DisplayFeatureProvider mDisplayFeatureProvider;
 
     /**
      * Call this in {@code @Before} method of the test class to use fake factory.
@@ -149,6 +151,7 @@
         mOnboardingFeatureProvider = mock(OnboardingFeatureProvider.class);
         mFastPairFeatureProvider = mock(FastPairFeatureProvider.class);
         mPrivateSpaceLoginFeatureProvider =  mock(PrivateSpaceLoginFeatureProvider.class);
+        mDisplayFeatureProvider = mock(DisplayFeatureProvider.class);
     }
 
     @Override
@@ -331,5 +334,10 @@
     public PrivateSpaceLoginFeatureProvider getPrivateSpaceLoginFeatureProvider() {
         return mPrivateSpaceLoginFeatureProvider;
     }
+
+    @Override
+    public DisplayFeatureProvider getDisplayFeatureProvider() {
+        return mDisplayFeatureProvider;
+    }
 }
 
diff --git a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt
index 9b098a7..4048c24 100644
--- a/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt
+++ b/tests/spa_unit/src/com/android/settings/testutils/FakeFeatureFactory.kt
@@ -30,6 +30,7 @@
 import com.android.settings.dashboard.DashboardFeatureProvider
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider
 import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider
+import com.android.settings.display.DisplayFeatureProvider
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider
 import com.android.settings.fuelgauge.BatterySettingsFeatureProvider
 import com.android.settings.fuelgauge.BatteryStatusFeatureProvider
@@ -146,4 +147,6 @@
         get() = TODO("Not yet implemented")
     override val privateSpaceLoginFeatureProvider: PrivateSpaceLoginFeatureProvider
         get() = TODO("Not yet implemented")
+    override val displayFeatureProvider: DisplayFeatureProvider
+        get() = TODO("Not yet implemented")
 }
diff --git a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
index b5aeac7..0a04a73 100644
--- a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
@@ -217,33 +217,33 @@
         assertThat(controller.isHiddenDueToNoProviderSet()).isFalse();
         assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
 
-        // Ensure that we stay under 5 providers.
+        // Ensure that we stay under 5 providers (one is reserved for primary).
         assertThat(controller.togglePackageNameEnabled("com.android.provider1")).isTrue();
         assertThat(controller.togglePackageNameEnabled("com.android.provider2")).isTrue();
         assertThat(controller.togglePackageNameEnabled("com.android.provider3")).isTrue();
         assertThat(controller.togglePackageNameEnabled("com.android.provider4")).isTrue();
-        assertThat(controller.togglePackageNameEnabled("com.android.provider5")).isTrue();
+        assertThat(controller.togglePackageNameEnabled("com.android.provider5")).isFalse();
         assertThat(controller.togglePackageNameEnabled("com.android.provider6")).isFalse();
 
         // Check that they are all actually registered.
         Set<String> enabledProviders = controller.getEnabledProviders();
-        assertThat(enabledProviders.size()).isEqualTo(5);
+        assertThat(enabledProviders.size()).isEqualTo(4);
         assertThat(enabledProviders.contains("com.android.provider1")).isTrue();
         assertThat(enabledProviders.contains("com.android.provider2")).isTrue();
         assertThat(enabledProviders.contains("com.android.provider3")).isTrue();
         assertThat(enabledProviders.contains("com.android.provider4")).isTrue();
-        assertThat(enabledProviders.contains("com.android.provider5")).isTrue();
+        assertThat(enabledProviders.contains("com.android.provider5")).isFalse();
         assertThat(enabledProviders.contains("com.android.provider6")).isFalse();
 
         // Check that the settings string has the right component names.
         List<String> enabledServices = controller.getEnabledSettings();
-        assertThat(enabledServices.size()).isEqualTo(6);
+        assertThat(enabledServices.size()).isEqualTo(5);
         assertThat(enabledServices.contains("com.android.provider1/ClassA")).isTrue();
         assertThat(enabledServices.contains("com.android.provider1/ClassB")).isTrue();
         assertThat(enabledServices.contains("com.android.provider2/ClassA")).isTrue();
         assertThat(enabledServices.contains("com.android.provider3/ClassA")).isTrue();
         assertThat(enabledServices.contains("com.android.provider4/ClassA")).isTrue();
-        assertThat(enabledServices.contains("com.android.provider5/ClassA")).isTrue();
+        assertThat(enabledServices.contains("com.android.provider5/ClassA")).isFalse();
         assertThat(enabledServices.contains("com.android.provider6/ClassA")).isFalse();
 
         // Toggle the provider disabled.
@@ -251,22 +251,22 @@
 
         // Check that the provider was removed from the list of providers.
         Set<String> currentlyEnabledProviders = controller.getEnabledProviders();
-        assertThat(currentlyEnabledProviders.size()).isEqualTo(4);
+        assertThat(currentlyEnabledProviders.size()).isEqualTo(3);
         assertThat(currentlyEnabledProviders.contains("com.android.provider1")).isTrue();
         assertThat(currentlyEnabledProviders.contains("com.android.provider2")).isFalse();
         assertThat(currentlyEnabledProviders.contains("com.android.provider3")).isTrue();
         assertThat(currentlyEnabledProviders.contains("com.android.provider4")).isTrue();
-        assertThat(currentlyEnabledProviders.contains("com.android.provider5")).isTrue();
+        assertThat(currentlyEnabledProviders.contains("com.android.provider5")).isFalse();
         assertThat(currentlyEnabledProviders.contains("com.android.provider6")).isFalse();
 
         // Check that the provider was removed from the list of services stored in the setting.
         List<String> currentlyEnabledServices = controller.getEnabledSettings();
-        assertThat(currentlyEnabledServices.size()).isEqualTo(5);
+        assertThat(currentlyEnabledServices.size()).isEqualTo(4);
         assertThat(currentlyEnabledServices.contains("com.android.provider1/ClassA")).isTrue();
         assertThat(currentlyEnabledServices.contains("com.android.provider1/ClassB")).isTrue();
         assertThat(currentlyEnabledServices.contains("com.android.provider3/ClassA")).isTrue();
         assertThat(currentlyEnabledServices.contains("com.android.provider4/ClassA")).isTrue();
-        assertThat(currentlyEnabledServices.contains("com.android.provider5/ClassA")).isTrue();
+        assertThat(currentlyEnabledServices.contains("com.android.provider5/ClassA")).isFalse();
         assertThat(currentlyEnabledServices.contains("com.android.provider6/ClassA")).isFalse();
     }
 
@@ -528,6 +528,17 @@
         assertThat(thumbnail.getIntrinsicWidth()).isEqualTo(getIconSize());
     }
 
+    @Test
+    public void testProviderLimitReached() {
+        // The limit is 5 with one slot reserved for primary.
+        assertThat(CredentialManagerPreferenceController.hasProviderLimitBeenReached(0)).isFalse();
+        assertThat(CredentialManagerPreferenceController.hasProviderLimitBeenReached(1)).isFalse();
+        assertThat(CredentialManagerPreferenceController.hasProviderLimitBeenReached(2)).isFalse();
+        assertThat(CredentialManagerPreferenceController.hasProviderLimitBeenReached(3)).isFalse();
+        assertThat(CredentialManagerPreferenceController.hasProviderLimitBeenReached(4)).isTrue();
+        assertThat(CredentialManagerPreferenceController.hasProviderLimitBeenReached(5)).isTrue();
+    }
+
     private int getIconSize() {
         final Resources resources = mContext.getResources();
         return (int) resources.getDimension(android.R.dimen.app_icon_size);
diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
index 6c4c5b4..9e7948c 100644
--- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -33,6 +33,7 @@
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProvider;
 import com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFeatureProviderImpl;
+import com.android.settings.display.DisplayFeatureProvider;
 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
 import com.android.settings.fuelgauge.BatterySettingsFeatureProvider;
 import com.android.settings.fuelgauge.BatteryStatusFeatureProvider;
@@ -100,6 +101,7 @@
     public OnboardingFeatureProvider mOnboardingFeatureProvider;
     public FastPairFeatureProvider mFastPairFeatureProvider;
     public PrivateSpaceLoginFeatureProvider mPrivateSpaceLoginFeatureProvider;
+    public DisplayFeatureProvider mDisplayFeatureProvider;
 
     /** Call this in {@code @Before} method of the test class to use fake factory. */
     public static FakeFeatureFactory setupForTest() {
@@ -150,6 +152,7 @@
         mOnboardingFeatureProvider = mock(OnboardingFeatureProvider.class);
         mFastPairFeatureProvider = mock(FastPairFeatureProvider.class);
         mPrivateSpaceLoginFeatureProvider = mock(PrivateSpaceLoginFeatureProvider.class);
+        mDisplayFeatureProvider = mock(DisplayFeatureProvider.class);
     }
 
     @Override
@@ -332,4 +335,9 @@
     public PrivateSpaceLoginFeatureProvider getPrivateSpaceLoginFeatureProvider() {
         return mPrivateSpaceLoginFeatureProvider;
     }
+
+    @Override
+    public DisplayFeatureProvider getDisplayFeatureProvider() {
+        return mDisplayFeatureProvider;
+    }
 }