Merge "Fix SettingsHomepageActivityTest failed" into main
diff --git a/aconfig/settings_device_diagnostics_declarations.aconfig b/aconfig/settings_device_diagnostics_declarations.aconfig
new file mode 100644
index 0000000..90a12db
--- /dev/null
+++ b/aconfig/settings_device_diagnostics_declarations.aconfig
@@ -0,0 +1,9 @@
+package: "com.android.settings.flags"
+container: "system_ext"
+
+flag {
+  name: "enable_device_diagnostics_in_settings"
+  namespace: "phoenix"
+  description: "Enable the Device Diagnostics app in Settings"
+  bug: "309886423"
+}
diff --git a/res/drawable/ic_device_diagnostics.xml b/res/drawable/ic_device_diagnostics.xml
new file mode 100644
index 0000000..26953a7
--- /dev/null
+++ b/res/drawable/ic_device_diagnostics.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?android:attr/colorControlNormal">
+  <path
+      android:pathData="M320,760h320v-80L320,680v80ZM320,640h320v-80L320,560v80ZM480,492q66,-60 113,-106.5t47,-97.5q0,-36 -26,-62t-62,-26q-21,0 -40.5,8.5T480,232q-12,-15 -31.5,-23.5T408,200q-36,0 -62,26t-26,62q0,51 45.5,96T480,492ZM720,880L240,880q-33,0 -56.5,-23.5T160,800v-640q0,-33 23.5,-56.5T240,80h480q33,0 56.5,23.5T800,160v640q0,33 -23.5,56.5T720,880ZM240,800h480v-640L240,160v640ZM240,800v-640,640Z"
+      android:fillColor="#FFFFFFFF"/>
+</vector>
diff --git a/res/values/config.xml b/res/values/config.xml
index 4d3a233..4b638b2 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -836,4 +836,7 @@
 
     <!-- The Activity intent to trigger to launch time-related feedback. -->
     <string name="config_time_feedback_intent_uri" translatable="false" />
+
+    <!-- Package name for diagnostics app. -->
+    <string name="config_device_diagnostics_package_name" translatable="false">com.android.devicediagnostics</string>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 86395fe..f88b036 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1257,8 +1257,8 @@
     <string name="private_space_auto_lock_page_summary">You can lock your private space automatically if you haven\’t used your device for a period of time</string>
     <!-- Configure auto lock: Value for auto lock configuration to lock private space every time device locks. [CHAR LIMIT=40] -->
     <string name="private_space_auto_lock_every_time">Every time device locks</string>
-    <!-- Configure auto lock: Value for auto lock configuration to lock private space after 5 minutes of inactivity. [CHAR LIMIT=40] -->
-    <string name="private_space_auto_lock_after_inactivity">After 5 minutes of inactivity</string>
+    <!-- Configure auto lock: Value for auto lock configuration to lock private space after 5 minutes of inactivity post screen timeout. [CHAR LIMIT=40] -->
+    <string name="private_space_auto_lock_after_inactivity">5 minutes after screen timeout</string>
     <!-- Configure auto lock: Value for auto lock configuration to lock private space only after device restarts. [CHAR LIMIT=40] -->
     <string name="private_space_auto_lock_after_device_restart">Only after device restarts</string>
     <!-- Title for the settings page for hiding private space. [CHAR LIMIT=45] -->
@@ -4088,7 +4088,7 @@
     <!-- Manage applications, restore updated system application to factory version -->
     <string name="app_factory_reset">Uninstall updates</string>
     <!-- [CHAR LIMIT=50] Manage applications, unlock restricted setting from lock screen title -->
-    <string name="app_restricted_settings_lockscreen_title">Allow restricted permissions</string>
+    <string name="app_restricted_settings_lockscreen_title">Allow restricted settings</string>
     <!-- Manage applications, individual application info screen, screen, message text under Launch by default heading. This is present if the app is set as a default for some actions. -->
     <string name="auto_launch_enable_text">Some activities you\u2019ve selected open in this app by default.</string>
     <!-- Manage applications, individual application info screen, screen, message text under Launch by default heading. This is present if the app was given user permission to create widgets. -->
@@ -7893,6 +7893,9 @@
     <!-- Sound: Title for the Do not Disturb option and associated settings page. [CHAR LIMIT=50]-->
     <string name="zen_mode_settings_title">Do Not Disturb</string>
 
+    <!-- Sound: Title for the Modes option and associated settings page. [CHAR LIMIT=50]-->
+    <string name="zen_modes_list_title">Priority Modes</string>
+
     <!-- Sound: Summary for the Do not Disturb option and associated settings page. [CHAR LIMIT=240]-->
     <string name="zen_mode_settings_summary">Only get notified by important people and apps</string>
 
@@ -13262,4 +13265,9 @@
 
     <!--Title for Sync Across Devices category-->
     <string name="sync_across_devices_title">Sync across devices</string>
+
+    <!-- Device Diagnostics -->
+
+    <!-- Title for System dashboard fragment -->
+    <string name="device_diagnostics_title">Device diagnostics</string>
 </resources>
diff --git a/res/xml/modes_list_settings.xml b/res/xml/modes_list_settings.xml
new file mode 100644
index 0000000..c6b6200
--- /dev/null
+++ b/res/xml/modes_list_settings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:title="@string/zen_modes_list_title" >
+
+    <!-- TODO: b/333682392 - add strings for summary as appropriate -->
+
+    <PreferenceCategory
+        android:key="zen_modes_list">
+        <!-- Preferences leading to rules are added in this PreferenceCategory. -->
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/modes_rule_settings.xml b/res/xml/modes_rule_settings.xml
new file mode 100644
index 0000000..d7e2694
--- /dev/null
+++ b/res/xml/modes_rule_settings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:title="@string/zen_modes_list_title" >
+
+    <!-- TODO: b/308819292 - implement page, delete this test preference -->
+    <Preference
+        android:key="zen_mode_test" />
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/system_dashboard_fragment.xml b/res/xml/system_dashboard_fragment.xml
index 628eab9..6225f4f 100644
--- a/res/xml/system_dashboard_fragment.xml
+++ b/res/xml/system_dashboard_fragment.xml
@@ -98,6 +98,13 @@
         settings:controller="com.android.settings.system.DeveloperOptionsController"/>
 
     <Preference
+        android:key="device_diagnostics"
+        android:title="@string/device_diagnostics_title"
+        android:order="-35"
+        android:icon="@drawable/ic_device_diagnostics"
+        settings:controller="com.android.settings.system.DeviceDiagnosticsPreferenceController"/>
+
+    <Preference
         android:key="reset_dashboard"
         android:title="@string/reset_dashboard_title"
         android:icon="@drawable/ic_restore"
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 35fe6e4..2295dee 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -44,6 +44,7 @@
 import com.android.settings.R;
 import com.android.settings.accessibility.AccessibilityUtil.AccessibilityServiceFragmentType;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.development.Enable16kUtils;
 import com.android.settings.inputmethod.PhysicalKeyboardFragment;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -98,6 +99,8 @@
     static final String EXTRA_TIME_FOR_LOGGING = "start_time_to_log_a11y_tool";
     static final String EXTRA_METRICS_CATEGORY = "metrics_category";
 
+    public static final String VOICE_ACCESS_SERVICE = "android.apps.accessibility.voiceaccess";
+
     // Timeout before we update the services if packages are added/removed
     // since the AccessibilityManagerService has to do that processing first
     // to generate the AccessibilityServiceInfo we need for proper
@@ -488,6 +491,11 @@
         String[] services = getResources().getStringArray(key);
         PreferenceCategory category = mCategoryToPrefCategoryMap.get(categoryKey);
         for (int i = 0; i < services.length; i++) {
+            // TODO(b/335443194) Voice access is not available in 16kB mode.
+            if (services[i].contains(VOICE_ACCESS_SERVICE)
+                    && Enable16kUtils.isPageAgnosticModeOn(getContext())) {
+                continue;
+            }
             ComponentName component = ComponentName.unflattenFromString(services[i]);
             mPreBundledServiceComponentToCategoryMap.put(component, category);
         }
diff --git a/src/com/android/settings/accessibility/RestrictedPreferenceHelper.java b/src/com/android/settings/accessibility/RestrictedPreferenceHelper.java
index c806c0b..7455eea 100644
--- a/src/com/android/settings/accessibility/RestrictedPreferenceHelper.java
+++ b/src/com/android/settings/accessibility/RestrictedPreferenceHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.accessibility;
 
+import static com.android.settings.accessibility.AccessibilitySettings.VOICE_ACCESS_SERVICE;
 import static com.android.settingslib.widget.TwoTargetPreference.ICON_SIZE_MEDIUM;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -37,6 +38,7 @@
 
 import com.android.settings.R;
 import com.android.settings.Utils;
+import com.android.settings.development.Enable16kUtils;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -89,6 +91,11 @@
             final AccessibilityServiceInfo info = installedServices.get(i);
             final ResolveInfo resolveInfo = info.getResolveInfo();
             final String packageName = resolveInfo.serviceInfo.packageName;
+            // TODO(b/335443194) Voice access is not available in 16kB mode.
+            if (packageName.contains(VOICE_ACCESS_SERVICE)
+                    && Enable16kUtils.isPageAgnosticModeOn(mContext)) {
+                continue;
+            }
             final ComponentName componentName = new ComponentName(packageName,
                     resolveInfo.serviceInfo.name);
 
diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
index 1adbbaf..f07241a 100644
--- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
@@ -521,16 +521,7 @@
         // Get the selected autofill provider. If it is the placeholder then replace it with an
         // empty string.
         String selectedAutofillProvider =
-                DefaultCombinedPicker.getSelectedAutofillProvider(mContext, getUser());
-        String credentialAutofillService = "";
-        if (android.service.autofill.Flags.autofillCredmanDevIntegration()) {
-            credentialAutofillService = getCredentialAutofillService(mContext, TAG);
-        }
-        if (TextUtils.equals(selectedAutofillProvider, credentialAutofillService)
-                || TextUtils.equals(
-                        selectedAutofillProvider, AUTOFILL_CREDMAN_ONLY_PROVIDER_PLACEHOLDER)) {
-            selectedAutofillProvider = "";
-        }
+                getSelectedAutofillProvider(mContext, getUser(), TAG);
 
         // Get the list of combined providers.
         List<CombinedProviderInfo> providers =
@@ -695,6 +686,31 @@
         return "";
     }
 
+    /** Gets the selected autofill provider name. This will filter out place holder names. **/
+    public static @Nullable String getSelectedAutofillProvider(
+            Context context, int userId, String tag) {
+        String providerName = Settings.Secure.getStringForUser(
+                context.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, userId);
+
+        if (TextUtils.isEmpty(providerName)) {
+            return providerName;
+        }
+
+        if (providerName.equals(AUTOFILL_CREDMAN_ONLY_PROVIDER_PLACEHOLDER)) {
+            return "";
+        }
+
+        String credentialAutofillService = "";
+        if (android.service.autofill.Flags.autofillCredmanDevIntegration()) {
+            credentialAutofillService = getCredentialAutofillService(context, tag);
+        }
+        if (providerName.equals(credentialAutofillService)) {
+            return "";
+        }
+
+        return providerName;
+    }
+
     private CombiPreference addProviderPreference(
             @NonNull Context prefContext,
             @NonNull CharSequence title,
diff --git a/src/com/android/settings/applications/credentials/DefaultCombinedPicker.java b/src/com/android/settings/applications/credentials/DefaultCombinedPicker.java
index 8bc0bca..f422411 100644
--- a/src/com/android/settings/applications/credentials/DefaultCombinedPicker.java
+++ b/src/com/android/settings/applications/credentials/DefaultCombinedPicker.java
@@ -275,15 +275,13 @@
                             CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_INCLUDING_HIDDEN));
         }
 
-        final String selectedAutofillProvider = getSelectedAutofillProvider(context, userId);
+        final String selectedAutofillProvider =
+                CredentialManagerPreferenceController
+                    .getSelectedAutofillProvider(context, userId, TAG);
         return CombinedProviderInfo.buildMergedList(
                 autofillProviders, credManProviders, selectedAutofillProvider);
     }
 
-    public static String getSelectedAutofillProvider(Context context, int userId) {
-        return Settings.Secure.getStringForUser(
-                context.getContentResolver(), AUTOFILL_SETTING, userId);
-    }
 
     protected List<DefaultAppInfo> getCandidates() {
         final Context context = getContext();
diff --git a/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java b/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java
index 57cd1d2..33d9067 100644
--- a/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/DefaultCombinedPreferenceController.java
@@ -183,16 +183,15 @@
         final List<AutofillServiceInfo> autofillProviders =
                 AutofillServiceInfo.getAvailableServices(mContext, userId);
         final String selectedAutofillProvider =
-                Settings.Secure.getStringForUser(
-                        mContext.getContentResolver(),
-                        DefaultCombinedPicker.AUTOFILL_SETTING,
-                        userId);
+                CredentialManagerPreferenceController
+                .getSelectedAutofillProvider(mContext, userId, TAG);
 
         final List<CredentialProviderInfo> credManProviders = new ArrayList<>();
         if (mCredentialManager != null) {
             credManProviders.addAll(
                     mCredentialManager.getCredentialProviderServices(
-                            userId, CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY));
+                            userId,
+                            CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_INCLUDING_HIDDEN));
         }
 
         return CombinedProviderInfo.buildMergedList(
@@ -226,6 +225,12 @@
             return;
         }
 
+        // Clean the autofill provider settings
+        Settings.Secure.putStringForUser(
+                mContext.getContentResolver(),
+                DefaultCombinedPicker.AUTOFILL_SETTING, null, getUser());
+
+        // Clean the credman provider settings.
         mCredentialManager.setEnabledProviders(
                 List.of(), // empty primary provider.
                 List.of(), // empty enabled providers.
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
index 8467b2f..0365f80 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
@@ -61,9 +61,8 @@
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         mBatteryUsageProgressBarPref = screen.findPreference(getPreferenceKey());
-        // Set up loading text first to prevent layout flaky before info loaded.
-        mBatteryUsageProgressBarPref.setBottomSummary(
-                mContext.getString(R.string.settings_license_activity_loading));
+        // Set up empty space text first to prevent layout flaky before info loaded.
+        mBatteryUsageProgressBarPref.setBottomSummary(" ");
 
         if (com.android.settings.Utils.isBatteryPresent(mContext)) {
             quickUpdateHeaderPreference();
diff --git a/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java b/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
index eb833b1..b56c1b9 100644
--- a/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/CallsDefaultSubscriptionController.java
@@ -31,6 +31,10 @@
         super(context, preferenceKey, lifecycle, lifecycleOwner);
     }
 
+    public CallsDefaultSubscriptionController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
     @Override
     protected int getDefaultSubscriptionId() {
         int defaultCallSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
diff --git a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
index 1acfaf8..c08ea99 100644
--- a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
+++ b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
@@ -68,15 +68,19 @@
 
     public ConvertToEsimPreferenceController(Context context, String key, Lifecycle lifecycle,
             LifecycleOwner lifecycleOwner, int subId) {
-        super(context, key);
+        this(context, key);
         mSubId = subId;
-        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
         mLifecycleOwner = lifecycleOwner;
         if (lifecycle != null) {
             lifecycle.addObserver(this);
         }
     }
 
+    public ConvertToEsimPreferenceController(Context context, String key) {
+        super(context, key);
+        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+    }
+
     public void init(int subId, SubscriptionInfoEntity subInfoEntity) {
         mSubId = subId;
         mSubscriptionInfoEntity = subInfoEntity;
diff --git a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
index fa8760c..b058694 100644
--- a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
@@ -64,16 +64,20 @@
 
     public DefaultSubscriptionController(Context context, String preferenceKey, Lifecycle lifecycle,
             LifecycleOwner lifecycleOwner) {
+        this(context, preferenceKey);
+        mLifecycleOwner = lifecycleOwner;
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    public DefaultSubscriptionController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mManager = context.getSystemService(SubscriptionManager.class);
         mIsRtlMode = context.getResources().getConfiguration().getLayoutDirection()
                 == View.LAYOUT_DIRECTION_RTL;
         mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
         mDataSubscriptionChangedReceiver = new DefaultSubscriptionReceiver(context, this);
-        mLifecycleOwner = lifecycleOwner;
-        if (lifecycle != null) {
-            lifecycle.addObserver(this);
-        }
     }
 
     /** @return the id of the default subscription for the service, or
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index 2c3ab18..6adc505 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -73,16 +73,20 @@
 
     public MobileDataPreferenceController(Context context, String key, Lifecycle lifecycle,
             LifecycleOwner lifecycleOwner, int subId) {
-        super(context, key);
+        this(context, key);
         mSubId = subId;
-        mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
-        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
         mLifecycleOwner = lifecycleOwner;
         if (lifecycle != null) {
             lifecycle.addObserver(this);
         }
     }
 
+    public MobileDataPreferenceController(Context context, String key) {
+        super(context, key);
+        mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+    }
+
     @Override
     public int getAvailabilityStatus(int subId) {
         if (Flags.isDualSimOnboardingEnabled()) {
diff --git a/src/com/android/settings/network/telephony/RoamingPreferenceController.java b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
index fb8cd51..bf02308 100644
--- a/src/com/android/settings/network/telephony/RoamingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/RoamingPreferenceController.java
@@ -63,16 +63,20 @@
 
     public RoamingPreferenceController(Context context, String key, Lifecycle lifecycle,
             LifecycleOwner lifecycleOwner, int subId) {
-        super(context, key);
+        this(context, key);
         mSubId = subId;
-        mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
-        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
         mLifecycleOwner = lifecycleOwner;
         if (lifecycle != null) {
             lifecycle.addObserver(this);
         }
     }
 
+    public RoamingPreferenceController(Context context, String key) {
+        super(context, key);
+        mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
+        mMobileNetworkRepository = MobileNetworkRepository.getInstance(context);
+    }
+
     @Override
     public int getAvailabilityStatus() {
         final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
diff --git a/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java b/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
index c49647d..c35a78c 100644
--- a/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/SmsDefaultSubscriptionController.java
@@ -35,6 +35,12 @@
                 .getBoolean(com.android.internal.R.bool.config_sms_ask_every_time_support);
     }
 
+    public SmsDefaultSubscriptionController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mIsAskEverytimeSupported = mContext.getResources()
+                .getBoolean(com.android.internal.R.bool.config_sms_ask_every_time_support);
+    }
+
     @Override
     protected int getDefaultSubscriptionId() {
         int defaultSmsSubId = SubscriptionManager.getDefaultSmsSubscriptionId();
diff --git a/src/com/android/settings/notification/modes/ZenModeFragment.java b/src/com/android/settings/notification/modes/ZenModeFragment.java
new file mode 100644
index 0000000..616332e
--- /dev/null
+++ b/src/com/android/settings/notification/modes/ZenModeFragment.java
@@ -0,0 +1,78 @@
+/*
+ * 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.notification.modes;
+
+import android.app.AutomaticZenRule;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenModeFragment extends ZenModeFragmentBase {
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.modes_rule_settings;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        // TODO: fill in with all the elements of this page. Each should be an instance of
+        //       {@link AbstractZenModePreferenceController}.
+        List<AbstractPreferenceController> prefControllers = new ArrayList<>();
+        return prefControllers;
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        // Set title for the entire screen
+        ZenMode mode = getMode();
+        AutomaticZenRule azr = getAZR();
+        if (mode == null || azr == null) {
+            return;
+        }
+        getActivity().setTitle(azr.getName());
+
+        // TODO: b/308819292 - implement the real screen!
+        final PreferenceScreen screen = getPreferenceScreen();
+        if (screen == null) {
+            return;
+        }
+
+        Preference tmpPref = screen.findPreference("zen_mode_test");
+        if (tmpPref == null) {
+            return;
+        }
+        tmpPref.setTitle(azr.getTriggerDescription());
+        tmpPref.setSummary("active?: " + mode.isActive());
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO: b/332937635 - make this the correct metrics category
+        return SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION;
+    }
+}
diff --git a/src/com/android/settings/notification/modes/ZenModeListPreference.java b/src/com/android/settings/notification/modes/ZenModeListPreference.java
new file mode 100644
index 0000000..cb04561
--- /dev/null
+++ b/src/com/android/settings/notification/modes/ZenModeListPreference.java
@@ -0,0 +1,65 @@
+/*
+ * 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.notification.modes;
+
+import static com.android.settings.notification.modes.ZenModeFragmentBase.MODE_ID;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.notification.zen.ZenModeSettings;
+import com.android.settingslib.RestrictedPreference;
+
+/**
+ * Preference representing a single mode item on the modes aggregator page. Clicking on this
+ * preference leads to an individual mode's configuration page.
+ */
+public class ZenModeListPreference extends RestrictedPreference {
+    final Context mContext;
+    ZenMode mZenMode;
+
+    ZenModeListPreference(Context context, ZenMode zenMode) {
+        super(context);
+        mContext = context;
+        mZenMode = zenMode;
+        setTitle(mZenMode.getRule().getName());
+        setSummary((mZenMode.isActive() ? "ACTIVE" : "inactive") + ": "
+                + mZenMode.getRule().getTriggerDescription());
+    }
+
+    @Override
+    public void onClick() {
+        // TODO: b/322373473 - This implementation is a hack that just leads to the old DND page
+        //                     for manual only; remove this in favor of the real implementation.
+        if (mZenMode.isManualDnd()) {
+            new SubSettingLauncher(mContext)
+                    .setDestination(ZenModeSettings.class.getName())
+                    .setSourceMetricsCategory(SettingsEnums.NOTIFICATION_ZEN_MODE)
+                    .launch();
+        } else {
+            Bundle bundle = new Bundle();
+            bundle.putString(MODE_ID, mZenMode.getId());
+            new SubSettingLauncher(mContext)
+                    .setDestination(ZenModeFragment.class.getName())
+                    .setArguments(bundle)
+                    .setSourceMetricsCategory(SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION)
+                    .launch();
+        }
+
+    }
+}
diff --git a/src/com/android/settings/notification/modes/ZenModesListFragment.java b/src/com/android/settings/notification/modes/ZenModesListFragment.java
new file mode 100644
index 0000000..040621e
--- /dev/null
+++ b/src/com/android/settings/notification/modes/ZenModesListFragment.java
@@ -0,0 +1,113 @@
+/*
+ * 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.notification.modes;
+
+import android.app.NotificationManager;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.service.notification.ConditionProviderService;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.R;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.utils.ManagedServiceSettings;
+import com.android.settings.utils.ZenServiceListing;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SearchIndexable
+public class ZenModesListFragment extends ZenModesFragmentBase {
+    protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
+
+    @Override
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        ZenServiceListing serviceListing = new ZenServiceListing(getContext(), CONFIG);
+        serviceListing.reloadApprovedServices();
+        return buildPreferenceControllers(context, this, serviceListing);
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+            @Nullable Fragment parent, @Nullable ZenServiceListing serviceListing) {
+        // We need to redefine ZenModesBackend here even though mBackend exists so that this method
+        // can be static; it must be static to be able to be used in SEARCH_INDEX_DATA_PROVIDER.
+        ZenModesBackend backend = ZenModesBackend.getInstance(context);
+        List<AbstractPreferenceController> controllers = new ArrayList<>();
+        controllers.add(new ZenModesListPreferenceController(
+                context, parent, backend));
+
+        // TODO: b/326442408 - Add controller for "Add Mode" preference/flow, which is what uses
+        //                     the ZenServiceListing.
+        return controllers;
+    }
+
+    @Override
+    protected void updateZenModeState() {
+        // TODO: b/322373473 -- update any overall description of modes state here if necessary.
+        // Note the preferences linking to individual rules do not need to be updated, as
+        // updateState() is called on all preference controllers whenever the page is resumed.
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.modes_list_settings;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO: b/332937635 - add new & set metrics categories correctly
+        return SettingsEnums.NOTIFICATION_ZEN_MODE_AUTOMATION;
+    }
+
+    protected static ManagedServiceSettings.Config getConditionProviderConfig() {
+        return new ManagedServiceSettings.Config.Builder()
+                .setTag(TAG)
+                .setIntentAction(ConditionProviderService.SERVICE_INTERFACE)
+                .setConfigurationIntentAction(NotificationManager.ACTION_AUTOMATIC_ZEN_RULE)
+                .setPermission(android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE)
+                .setNoun("condition provider")
+                .build();
+    }
+
+    // TODO: b/322373473 - Add 3-dot options menu with capability to delete modes.
+
+    /**
+     * For Search.
+     */
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.modes_list_settings) {
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    final List<String> keys = super.getNonIndexableKeys(context);
+                    // TODO: b/332937523 - determine if this should be removed once the preference
+                    //                     controller adds dynamic data to index
+                    keys.add(ZenModesListPreferenceController.KEY);
+                    return keys;
+                }
+
+                @Override
+                public List<AbstractPreferenceController> createPreferenceControllers(
+                        Context context) {
+                    return buildPreferenceControllers(context, null, null);
+                }
+            };
+}
diff --git a/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
new file mode 100644
index 0000000..53336c8
--- /dev/null
+++ b/src/com/android/settings/notification/modes/ZenModesListPreferenceController.java
@@ -0,0 +1,80 @@
+/*
+ * 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.notification.modes;
+
+import android.app.Flags;
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+
+import com.android.settingslib.core.AbstractPreferenceController;
+
+/**
+ * Controller for the PreferenceCategory on the modes aggregator page ({@link ZenModesListFragment})
+ * containing links to each individual mode. This is a central controller that populates and updates
+ * all the preferences that then lead to a mode configuration page.
+ */
+public class ZenModesListPreferenceController extends AbstractPreferenceController {
+    protected static final String KEY = "zen_modes_list";
+
+    @Nullable
+    protected Fragment mParent;
+    protected ZenModesBackend mBackend;
+
+    public ZenModesListPreferenceController(Context context, @Nullable Fragment parent,
+            @NonNull ZenModesBackend backend) {
+        super(context);
+        mParent = parent;
+        mBackend = backend;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return KEY;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return Flags.modesUi();
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        if (mBackend == null) {
+            return;
+        }
+
+        // The preference given us is a PreferenceCategory; create one preference inside the
+        // category for each rule that exists.
+        PreferenceCategory category = (PreferenceCategory) preference;
+
+        // TODO: b/322373473 - This is not the right way to replace these preferences; we should
+        //                     follow something similar to what
+        //                     ZenModeAutomaticRulesPreferenceController does to change rules
+        //                     only as necessary and update them.
+        category.removeAll();
+
+        for (ZenMode mode : mBackend.getModes()) {
+            Preference pref = new ZenModeListPreference(mContext, mode);
+            category.addPreference(pref);
+        }
+    }
+
+}
diff --git a/src/com/android/settings/notification/zen/ZenModePreferenceController.java b/src/com/android/settings/notification/zen/ZenModePreferenceController.java
index 24cf158..7c36d80 100644
--- a/src/com/android/settings/notification/zen/ZenModePreferenceController.java
+++ b/src/com/android/settings/notification/zen/ZenModePreferenceController.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.notification.zen;
 
+import android.app.Flags;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
@@ -27,7 +28,9 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
+import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.notification.modes.ZenModesListFragment;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.core.lifecycle.events.OnResume;
@@ -46,7 +49,9 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-        mSettingObserver = new SettingObserver(screen.findPreference(getPreferenceKey()));
+        Preference preference = screen.findPreference(getPreferenceKey());
+        mSettingObserver = new SettingObserver(preference);
+        maybeSetTitleAndDestination(preference);
     }
 
     @Override
@@ -71,11 +76,22 @@
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
+        maybeSetTitleAndDestination(preference);
         if (preference.isEnabled()) {
             preference.setSummary(mSummaryBuilder.getSoundSummary());
         }
     }
 
+    // Only when modes_ui is active: change title & target fragment.
+    private void maybeSetTitleAndDestination(Preference preference) {
+        if (!Flags.modesUi()) {
+            return;
+        }
+
+        preference.setTitle(R.string.zen_modes_list_title);
+        preference.setFragment(ZenModesListFragment.class.getCanonicalName());
+    }
+
     class SettingObserver extends ContentObserver {
         private final Uri ZEN_MODE_URI = Settings.Global.getUriFor(Settings.Global.ZEN_MODE);
         private final Uri ZEN_MODE_CONFIG_ETAG_URI = Settings.Global.getUriFor(
diff --git a/src/com/android/settings/system/DeviceDiagnosticsPreferenceController.kt b/src/com/android/settings/system/DeviceDiagnosticsPreferenceController.kt
new file mode 100644
index 0000000..695bb5b
--- /dev/null
+++ b/src/com/android/settings/system/DeviceDiagnosticsPreferenceController.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.system
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ResolveInfo
+
+import androidx.preference.Preference
+
+import com.android.settings.R
+import com.android.settings.core.BasePreferenceController
+import com.android.settings.flags.Flags
+
+class DeviceDiagnosticsPreferenceController(context: Context, preferenceKey: String) :
+    BasePreferenceController(context, preferenceKey) {
+
+    override fun getAvailabilityStatus(): Int {
+        if (!Flags.enableDeviceDiagnosticsInSettings()) {
+            return UNSUPPORTED_ON_DEVICE
+        }
+        if (getIntent() == null) {
+            return UNSUPPORTED_ON_DEVICE
+        }
+        return AVAILABLE
+    }
+
+    override fun handlePreferenceTreeClick(preference: Preference): Boolean {
+        if (preferenceKey != preference.key) {
+            return false
+        }
+
+        val intent = getIntent()
+        if (intent == null) {
+            return false
+        }
+
+        preference.getContext().startActivity(intent)
+        return true
+    }
+
+    private fun getIntent(): Intent? {
+        val intent = Intent(Intent.ACTION_MAIN)
+
+        val packageName = mContext.getResources().getString(
+                R.string.config_device_diagnostics_package_name)
+        intent.setPackage(packageName)
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        return intent
+    }
+}
diff --git a/src/com/android/settings/users/MultiUserSwitchBarController.java b/src/com/android/settings/users/MultiUserSwitchBarController.java
index 33651c3..f57b795 100644
--- a/src/com/android/settings/users/MultiUserSwitchBarController.java
+++ b/src/com/android/settings/users/MultiUserSwitchBarController.java
@@ -63,8 +63,7 @@
                     .checkIfRestrictionEnforced(mContext, UserManager.DISALLOW_ADD_USER,
                             UserHandle.myUserId()));
         } else {
-            mSwitchBar.setEnabled(!mUserCapabilities.mDisallowSwitchUser
-                    && !mUserCapabilities.mIsGuest && mUserCapabilities.isAdmin());
+            mSwitchBar.setEnabled(mUserCapabilities.mIsMain);
         }
         mSwitchBar.setListener(this);
     }
diff --git a/src/com/android/settings/users/UserCapabilities.java b/src/com/android/settings/users/UserCapabilities.java
index cf0e10b..590cb0c 100644
--- a/src/com/android/settings/users/UserCapabilities.java
+++ b/src/com/android/settings/users/UserCapabilities.java
@@ -32,6 +32,7 @@
     boolean mEnabled = true;
     boolean mCanAddUser = true;
     boolean mCanAddRestrictedProfile;
+    boolean mIsMain;
     boolean mIsAdmin;
     boolean mIsGuest;
     boolean mIsEphemeral;
@@ -57,6 +58,7 @@
         final UserInfo myUserInfo = userManager.getUserInfo(UserHandle.myUserId());
         caps.mIsGuest = myUserInfo.isGuest();
         caps.mIsAdmin = myUserInfo.isAdmin();
+        caps.mIsMain = myUserInfo.isMain();
         caps.mIsEphemeral = myUserInfo.isEphemeral();
         DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 083608d..bf21c9b 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -287,7 +287,7 @@
         final SettingsActivity activity = (SettingsActivity) getActivity();
         final SettingsMainSwitchBar switchBar = activity.getSwitchBar();
         switchBar.setTitle(getContext().getString(R.string.multiple_users_main_switch_title));
-        if (isCurrentUserAdmin()) {
+        if (!mUserCaps.mIsGuest) {
             switchBar.show();
         } else {
             switchBar.hide();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
index 1899eab..c987bcd 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
@@ -35,7 +35,6 @@
 
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.fuelgauge.batterytip.tips.LowBatteryTip;
@@ -483,11 +482,10 @@
     }
 
     @Test
-    public void displayPreference_init_showLoading() {
+    public void displayPreference_init_showEmptySpace() {
         mController.displayPreference(mPreferenceScreen);
 
-        verify(mBatteryUsageProgressBarPref)
-                .setBottomSummary(mContext.getString(R.string.settings_license_activity_loading));
+        verify(mBatteryUsageProgressBarPref).setBottomSummary(" ");
     }
 
     private CharSequence formatBatteryPercentageText() {
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModePreferenceControllerTest.java
index c2abbcd..f611c9b 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModePreferenceControllerTest.java
@@ -16,10 +16,13 @@
 
 package com.android.settings.notification.zen;
 
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+
 import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
@@ -27,13 +30,20 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.Flags;
 import android.app.NotificationManager;
 import android.app.NotificationManager.Policy;
 import android.content.Context;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 
 import androidx.preference.Preference;
 
+import com.android.settings.notification.modes.ZenModesListFragment;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -46,6 +56,9 @@
 @RunWith(RobolectricTestRunner.class)
 public class ZenModePreferenceControllerTest {
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
     @Mock
     private Preference mPreference;
     @Mock
@@ -96,4 +109,20 @@
 
         verify(mPreference, never()).setSummary(anyString());
     }
+
+    @Test
+    @EnableFlags(Flags.FLAG_MODES_UI)
+    public void updateState_modesUi_resetsTitleAndFragment() {
+        mController.updateState(mPreference);
+        verify(mPreference).setTitle(anyInt());  // Resource IDs are ints
+        verify(mPreference).setFragment(ZenModesListFragment.class.getCanonicalName());
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_MODES_UI)
+    public void updateState_noModesUi_doesNotSetTitleAndFragment() {
+        mController.updateState(mPreference);
+        verify(mPreference, never()).setTitle(anyInt());
+        verify(mPreference, never()).setFragment(anyString());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java
index 1cfb3f6..bfab257 100644
--- a/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/users/MultiUserSwitchBarControllerTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.os.UserHandle;
 import android.os.UserManager;
 
@@ -79,4 +80,26 @@
 
         verify(mSwitchWidgetController, never()).setDisabledByAdmin(any());
     }
+
+    @Test
+    public void onStart_userIsNotMain_shouldNotBeEnabled() {
+        mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
+                UserManager.DISALLOW_USER_SWITCH, false);
+        mUserManager.addUser(10, "Test", UserInfo.FLAG_ADMIN);
+        mUserManager.switchUser(10);
+        new MultiUserSwitchBarController(mContext, mSwitchWidgetController, null);
+
+        verify(mSwitchWidgetController, never()).setDisabledByAdmin(any());
+        verify(mSwitchWidgetController).setEnabled(false);
+    }
+
+    @Test
+    public void onStart_userIsMain_shouldBeEnabled() {
+        mUserManager.setUserRestriction(UserHandle.of(UserHandle.myUserId()),
+                UserManager.DISALLOW_USER_SWITCH, false);
+        new MultiUserSwitchBarController(mContext, mSwitchWidgetController, null);
+
+        verify(mSwitchWidgetController, never()).setDisabledByAdmin(any());
+        verify(mSwitchWidgetController).setEnabled(true);
+    }
 }
diff --git a/tests/unit/src/com/android/settings/datausage/DataUsageInfoControllerTest.java b/tests/unit/src/com/android/settings/datausage/DataUsageInfoControllerTest.java
index cb5860a..4193b0a 100644
--- a/tests/unit/src/com/android/settings/datausage/DataUsageInfoControllerTest.java
+++ b/tests/unit/src/com/android/settings/datausage/DataUsageInfoControllerTest.java
@@ -23,10 +23,12 @@
 import com.android.settingslib.net.DataUsageController.DataUsageInfo;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
+@Ignore("b/340657656")
 public class DataUsageInfoControllerTest {
 
     private static final int ZERO = 0;
diff --git a/tests/unit/src/com/android/settings/localepicker/TermsOfAddressFeminineControllerTest.java b/tests/unit/src/com/android/settings/localepicker/TermsOfAddressFeminineControllerTest.java
index 246fad6..215e58f 100644
--- a/tests/unit/src/com/android/settings/localepicker/TermsOfAddressFeminineControllerTest.java
+++ b/tests/unit/src/com/android/settings/localepicker/TermsOfAddressFeminineControllerTest.java
@@ -18,8 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.spy;
-
 import android.app.GrammaticalInflectionManager;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -34,7 +32,6 @@
 import com.android.settings.widget.TickButtonPreference;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
@@ -62,7 +59,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mContext = spy(ApplicationProvider.getApplicationContext());
+        mContext = ApplicationProvider.getApplicationContext();
 
         if (Looper.myLooper() == null) {
             Looper.prepare();
@@ -93,7 +90,6 @@
     }
 
     @Test
-    @Ignore("b/339543490")
     public void displayPreference_setGrammaticalGenderIsFeminine_FeminineIsSelected() {
         TickButtonPreference selectedPreference =
                 (TickButtonPreference) mPreferenceScreen.getPreference(2);
diff --git a/tests/unit/src/com/android/settings/localepicker/TermsOfAddressMasculineControllerTest.java b/tests/unit/src/com/android/settings/localepicker/TermsOfAddressMasculineControllerTest.java
index f5ed395..b4c8893 100644
--- a/tests/unit/src/com/android/settings/localepicker/TermsOfAddressMasculineControllerTest.java
+++ b/tests/unit/src/com/android/settings/localepicker/TermsOfAddressMasculineControllerTest.java
@@ -18,8 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.spy;
-
 import android.app.GrammaticalInflectionManager;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -34,7 +32,6 @@
 import com.android.settings.widget.TickButtonPreference;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
@@ -62,7 +59,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mContext = spy(ApplicationProvider.getApplicationContext());
+        mContext = ApplicationProvider.getApplicationContext();
 
         if (Looper.myLooper() == null) {
             Looper.prepare();
@@ -93,7 +90,6 @@
     }
 
     @Test
-    @Ignore("b/339543490")
     public void displayPreference_setGrammaticalGenderIsMasculine_MasculineIsSelected() {
         TickButtonPreference selectedPreference =
                 (TickButtonPreference) mPreferenceScreen.getPreference(3);
diff --git a/tests/unit/src/com/android/settings/localepicker/TermsOfAddressNeutralControllerTest.java b/tests/unit/src/com/android/settings/localepicker/TermsOfAddressNeutralControllerTest.java
index 0e53198..76aed0a 100644
--- a/tests/unit/src/com/android/settings/localepicker/TermsOfAddressNeutralControllerTest.java
+++ b/tests/unit/src/com/android/settings/localepicker/TermsOfAddressNeutralControllerTest.java
@@ -18,8 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.spy;
-
 import android.app.GrammaticalInflectionManager;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -34,7 +32,6 @@
 import com.android.settings.widget.TickButtonPreference;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
@@ -62,7 +59,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mContext = spy(ApplicationProvider.getApplicationContext());
+        mContext = ApplicationProvider.getApplicationContext();
 
         if (Looper.myLooper() == null) {
             Looper.prepare();
@@ -93,7 +90,6 @@
     }
 
     @Test
-    @Ignore("b/339543490")
     public void displayPreference_setGrammaticalGenderIsNotSpecified_NeutralIsSelected() {
         TickButtonPreference selectedPreference =
                 (TickButtonPreference) mPreferenceScreen.getPreference(4);
diff --git a/tests/unit/src/com/android/settings/localepicker/TermsOfAddressNotSpecifiedControllerTest.java b/tests/unit/src/com/android/settings/localepicker/TermsOfAddressNotSpecifiedControllerTest.java
index 96bac08..0f51b7d 100644
--- a/tests/unit/src/com/android/settings/localepicker/TermsOfAddressNotSpecifiedControllerTest.java
+++ b/tests/unit/src/com/android/settings/localepicker/TermsOfAddressNotSpecifiedControllerTest.java
@@ -18,8 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.spy;
-
 import android.app.GrammaticalInflectionManager;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -34,7 +32,6 @@
 import com.android.settings.widget.TickButtonPreference;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
@@ -62,7 +59,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mContext = spy(ApplicationProvider.getApplicationContext());
+        mContext = ApplicationProvider.getApplicationContext();
 
         if (Looper.myLooper() == null) {
             Looper.prepare();
@@ -93,7 +90,6 @@
     }
 
     @Test
-    @Ignore("b/339543490")
     public void displayPreference_setGrammaticalGenderIsNotSpecified_NotSpecifiedIsSelected() {
         TickButtonPreference selectedPreference =
                 (TickButtonPreference) mPreferenceScreen.getPreference(1);
diff --git a/tests/unit/src/com/android/settings/privatespace/autolock/AutoLockPreferenceControllerTest.java b/tests/unit/src/com/android/settings/privatespace/autolock/AutoLockPreferenceControllerTest.java
index 3a605ea..fb2cddd 100644
--- a/tests/unit/src/com/android/settings/privatespace/autolock/AutoLockPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/privatespace/autolock/AutoLockPreferenceControllerTest.java
@@ -127,7 +127,7 @@
                 Settings.Secure.PRIVATE_SPACE_AUTO_LOCK,
                 Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_INACTIVITY);
         assertThat(mAutoLockPreferenceController.getSummary().toString())
-                .isEqualTo("After 5 minutes of inactivity");
+                .isEqualTo("5 minutes after screen timeout");
     }
 
     /**