Merge "[Catalyst] Vibration and haptics screen migration" into main
diff --git a/Android.bp b/Android.bp
index 28c3148..8f7bd1b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -98,6 +98,7 @@
         "SettingsLibDataStore",
         "SettingsLibMetadata",
         "SettingsLibPreference",
+        "SettingsLibService",
         "aconfig_settings_flags_lib",
         "accessibility_settings_flags_lib",
         "contextualcards",
@@ -107,7 +108,6 @@
         "fuelgauge-protos-lite",
         "settings-logtags",
         "statslog-settings",
-        "telephony_flags_core_java_lib",
         "setupdesign-lottie-loading-layout",
         "device_policy_aconfig_flags_lib",
         "keyboard_flags_lib",
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6408ab1..11d9779 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -5293,12 +5293,36 @@
                 android:value="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamConfirmDialog" />
         </activity>
 
+        <activity
+            android:name="Settings$ContactsStorageSettingsActivity"
+            android:label="@string/contacts_storage_settings_title"
+            android:exported="true"
+            android:featureFlag="com.android.settings.flags.enable_contacts_default_account_in_settings">
+            <intent-filter>
+                <action android:name="android.provider.action.SET_DEFAULT_ACCOUNT" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                       android:value="com.android.settings.applications.contacts.ContactsStorageSettings"/>
+        </activity>
+
         <service
             android:name="com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService"
             android:foregroundServiceType="mediaPlayback"
             android:enabled="true"
             android:exported="false" />
 
+        <!-- Once b/364771256 is fixed, add android:featureFlag="com.android.settings.flags.catalyst_service". -->
+        <!-- Permission is not yet finalized, use READ_BASIC_PHONE_STATE temporarily. -->
+        <service
+            android:name=".SettingsService"
+            android:exported="true"
+            android:permission="android.permission.READ_BASIC_PHONE_STATE">
+            <intent-filter>
+                <action android:name="com.android.settingslib.PREFERENCE_SERVICE" />
+            </intent-filter>
+        </service>
+
         <receiver android:name="com.android.settings.connecteddevice.audiosharing.AudioSharingReceiver"
             android:exported="false">
             <intent-filter>
diff --git a/aconfig/catalyst/battery.aconfig b/aconfig/catalyst/battery.aconfig
new file mode 100644
index 0000000..ce5c5c5
--- /dev/null
+++ b/aconfig/catalyst/battery.aconfig
@@ -0,0 +1,9 @@
+package: "com.android.settings.flags"
+container: "system"
+
+flag {
+  name: "catalyst_battery_saver_screen"
+  namespace: "android_settings"
+  description: "Flag for Battery Saver"
+  bug: "323791114"
+}
diff --git a/aconfig/catalyst/network_and_internet.aconfig b/aconfig/catalyst/network_and_internet.aconfig
new file mode 100644
index 0000000..a3e1784
--- /dev/null
+++ b/aconfig/catalyst/network_and_internet.aconfig
@@ -0,0 +1,9 @@
+package: "com.android.settings.flags"
+container: "system"
+
+flag {
+  name: "catalyst_network_provider_and_internet_screen"
+  namespace: "android_settings"
+  description: "Flag for Network & Internet"
+  bug: "323791114"
+}
diff --git a/aconfig/settings_datetime_flag_declarations.aconfig b/aconfig/settings_datetime_flag_declarations.aconfig
index 3d9d8b3..93d41d6 100644
--- a/aconfig/settings_datetime_flag_declarations.aconfig
+++ b/aconfig/settings_datetime_flag_declarations.aconfig
@@ -9,3 +9,11 @@
     bug: "283239837"
 }
 
+flag {
+    name: "revamp_toggles"
+    # "location" is used by the Android System Time team for feature flags.
+    namespace: "location"
+    description: "Makes the use location toggle dependent on automatic time zone detection"
+    bug: "296835792"
+}
+
diff --git a/aconfig/settings_flag_declarations.aconfig b/aconfig/settings_flag_declarations.aconfig
index a9c7bd5..6eb1e02 100644
--- a/aconfig/settings_flag_declarations.aconfig
+++ b/aconfig/settings_flag_declarations.aconfig
@@ -63,3 +63,10 @@
   description: "Flag for all screens"
   bug: "323791114"
 }
+
+flag {
+  name: "catalyst_service"
+  namespace: "android_settings"
+  description: "Flag for catalyst service"
+  bug: "323791114"
+}
diff --git a/res/drawable/accessibility_contrast_button_background.xml b/res/drawable/accessibility_contrast_button_background.xml
index 281fcef..7e41aae 100644
--- a/res/drawable/accessibility_contrast_button_background.xml
+++ b/res/drawable/accessibility_contrast_button_background.xml
@@ -32,7 +32,7 @@
             <item
                 android:width="24dp"
                 android:height="24dp"
-                android:left="57dp"
+                android:start="57dp"
                 android:top="57dp">
                 <vector
                     android:width="24dp"
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 8e5519f..ed0bce4 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1551,7 +1551,7 @@
         <item>@*android:drawable/ic_zen_mode_icon_snowflake</item>
         <item>@*android:drawable/ic_zen_mode_icon_beach</item>
         <item>@*android:drawable/ic_zen_mode_icon_workshop</item>
-        <item>@*android:drawable/ic_zen_mode_icon_camping</item>
+        <item>@*android:drawable/ic_zen_mode_icon_piano</item>
         <item>@*android:drawable/ic_zen_mode_type_theater</item> <!-- Film reel -->
         <item>@*android:drawable/ic_zen_mode_icon_book</item>
         <!-- Wellbeing -->
@@ -1602,7 +1602,7 @@
         <item>Snowflake</item>
         <item>Beach umbrella</item>
         <item>Workshop tools</item>
-        <item>Tent</item>
+        <item>Piano</item>
         <item>Film reel</item>
         <item>Book</item>
         <!-- Wellbeing -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1f9aa61..ed293ff 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -579,7 +579,7 @@
     <!-- Date & time setting screen setting switch summary: whether the time zone should be determined automatically [CHAR LIMIT=100]  -->
     <string name="zone_auto_title_summary">Set automatically based on mobile networks near you</string>
     <!-- Date & time setting screen setting switch summary for non-telephony devices [CHAR LIMIT=100] -->
-    <string name="auto_zone_requires_location_summary">Set automatically using your device location, if available. An active Wifi connection may also be required.</string>
+    <string name="auto_zone_requires_location_summary">Set automatically using your device location, if available</string>
     <!-- Date & time setting screen setting option summary text for the automatic 24 hour setting checkbox [CHAR LIMIT=100] -->
     <string name="date_time_24hour_auto">Use locale default</string>
     <!-- Date & time setting screen setting check box title -->
@@ -4705,9 +4705,13 @@
     <!-- Summary for the button to trigger the 'Physical keyboard accessibility' page. [CHAR LIMIT=NONE] -->
     <string name="keyboard_a11y_settings_summary">Sticky keys, Bounce keys, Mouse keys</string>
     <!-- Title for the keyboard repeat key option. [CHAR LIMIT=60] -->
-    <string name="keyboard_repeat_key_title">Repeat Keys</string>
+    <string name="keyboard_repeat_keys_title">Repeat Keys</string>
+    <!-- Title for the keyboard repeat key timeout option. [CHAR LIMIT=60] -->
+    <string name="keyboard_repeat_keys_timeout_title">Delay before repeat</string>
+    <!-- Title for the keyboard repeat key delay option. [CHAR LIMIT=60] -->
+    <string name="keyboard_repeat_keys_delay_title">Repeat Rate</string>
     <!-- Summary for the keyboard repeat key option. [CHAR LIMIT=NONE] -->
-    <string name="keyboard_repeat_key_summary">Hold down a key to repeat its character until the key is released</string>
+    <string name="keyboard_repeat_keys_summary">Hold down a key to repeat its character until the key is released</string>
 
     <!-- Title text for per IME subtype keyboard layout. [CHAR LIMIT=35] -->
     <string name="ime_label_title"><xliff:g id="ime_label" example="Gboard">%s</xliff:g> layout</string>
@@ -13704,7 +13708,6 @@
     <!-- Learn more link for audio sharing qrcode [CHAR LIMIT=none]-->
     <string name="audio_streams_qr_code_help_with_link"><annotation id="link">Need help?</annotation></string>
 
-
     <!-- url for learning more about bluetooth audio sharing -->
     <string name="help_url_audio_sharing" translatable="false"></string>
 
@@ -13725,4 +13728,11 @@
     <string name="contacts_storage_no_account_set">No default set</string>
     <!-- Text for add account selection message when no account has been added [CHAR LIMIT=100] -->
     <string name="contacts_storage_first_time_add_account_message">Add an account to get started</string>
+
+    <!-- Circle to Search (shared between all entrypoints) -->
+    <!-- Name of Google's new feature to circle to search anything on your phone screen,
+         without switching apps. Also used as the setting title. [CHAR LIMIT=60] -->
+    <string name="search_gesture_feature_title">Circle to Search</string>
+    <!-- Summary text for press and hold nav handle OR home button to invoke Circle to Search. [CHAR LIMIT=NONE] -->
+    <string name="search_gesture_feature_summary">Touch and hold the Home button or the navigation handle to search using the content on your screen.</string>
 </resources>
diff --git a/res/xml/accessibility_system_controls.xml b/res/xml/accessibility_system_controls.xml
index 460214f..a8cb1bb 100644
--- a/res/xml/accessibility_system_controls.xml
+++ b/res/xml/accessibility_system_controls.xml
@@ -20,6 +20,9 @@
     android:persistent="false"
     android:title="@string/accessibility_system_controls_title">
 
+    <!-- The item is not specific to Accessibility.
+        The same entry is under System, which is unlikely to be removed,
+        so this is not searchable. -->
     <Preference
         android:fragment="com.android.settings.gestures.SystemNavigationGestureSettings"
         android:key="gesture_system_navigation_input_summary_accessibility"
@@ -28,6 +31,9 @@
         settings:searchable="false"
         settings:controller="com.android.settings.gestures.SystemNavigationPreferenceController"/>
 
+    <!-- The item is not specific to Accessibility.
+        The same entry is under System > Gesture, which is unlikely to be removed,
+        so this is not searchable. -->
     <Preference
         android:fragment="com.android.settings.gestures.OneHandedSettings"
         android:key="gesture_system_navigation_one_handed_accessibility"
@@ -43,21 +49,28 @@
         settings:controller="com.android.settings.accessibility.PowerButtonEndsCallPreferenceController"/>
 
     <!-- Standard auto-rotation preference that will be shown when device state based auto-rotation
-         settings are NOT available. -->
+         settings are NOT available.
+         The item is not specific to Accessibility.
+         The same entry is under Display & touch, which is unlikely to be removed,
+         so this is not searchable.-->
     <SwitchPreferenceCompat
         android:key="toggle_lock_screen_rotation_preference"
         android:persistent="false"
         android:title="@string/accelerometer_title"
+        settings:searchable="false"
         settings:controller="com.android.settings.accessibility.LockScreenRotationPreferenceController"/>
 
     <!-- Auto-rotation preference that will be shown when device state based auto-rotation settings
-         are available. -->
+         are available.
+         The item is not specific to Accessibility.
+         The same entry is under Display & touch, which is unlikely to be removed,
+         so this is not searchable. -->
     <Preference
         android:key="device_state_auto_rotate_accessibility"
         android:persistent="false"
         android:title="@string/accelerometer_title"
         android:fragment="com.android.settings.display.DeviceStateAutoRotateDetailsFragment"
-        settings:keywords="@string/keywords_auto_rotate"
+        settings:searchable="false"
         settings:controller="com.android.settings.display.DeviceStateAutoRotateOverviewController"/>
 
 </PreferenceScreen>
diff --git a/res/xml/button_navigation_settings.xml b/res/xml/button_navigation_settings.xml
index 1de011c..1f89539 100644
--- a/res/xml/button_navigation_settings.xml
+++ b/res/xml/button_navigation_settings.xml
@@ -28,7 +28,8 @@
         settings:searchable="false"
         settings:dynamicColor="true"
         settings:lottie_imageAssetsFolder="button_nav_menu"
-        settings:lottie_rawRes="@raw/lottie_button_nav_menu"/>
+        settings:lottie_rawRes="@raw/lottie_button_nav_menu"
+        settings:controller="com.android.settings.gestures.ButtonNavigationSettingsAssistController"/>
 
     <SwitchPreferenceCompat
         android:key="assistant_long_press_home_gesture"
diff --git a/res/xml/date_time_prefs_revamped.xml b/res/xml/date_time_prefs_revamped.xml
new file mode 100644
index 0000000..fe0fd7e
--- /dev/null
+++ b/res/xml/date_time_prefs_revamped.xml
@@ -0,0 +1,104 @@
+<?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"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="@string/date_and_time"
+    settings:keywords="@string/keywords_date_and_time">
+
+    <com.android.settingslib.RestrictedSwitchPreference
+        android:key="auto_time"
+        android:title="@string/date_time_auto"
+        android:summary="@string/summary_placeholder"
+        settings:userRestriction="no_config_date_time"
+        settings:controller="com.android.settings.datetime.AutoTimePreferenceController" />
+
+    <com.android.settingslib.RestrictedPreference
+        android:key="date"
+        android:title="@string/date_time_set_date_title"
+        android:summary="@string/summary_placeholder"
+        settings:userRestriction="no_config_date_time"
+        settings:controller="com.android.settings.datetime.DatePreferenceController" />
+
+    <com.android.settingslib.RestrictedPreference
+        android:key="time"
+        android:title="@string/date_time_set_time_title"
+        android:summary="@string/summary_placeholder"
+        settings:userRestriction="no_config_date_time"
+        settings:controller="com.android.settings.datetime.TimePreferenceController" />
+
+    <PreferenceCategory
+        android:key="timezone_preference_category"
+        android:title="@string/date_time_set_timezone_title">
+
+        <com.android.settingslib.RestrictedSwitchPreference
+            android:key="auto_zone"
+            android:title="@string/zone_auto_title"
+            android:summary="@string/summary_placeholder"
+            settings:userRestriction="no_config_date_time"
+            settings:controller="com.android.settings.datetime.AutoTimeZonePreferenceController" />
+
+        <com.android.settingslib.widget.BannerMessagePreference
+            android:key="location_time_zone_detection_status"
+            android:title="@string/location_time_zone_detection_status_title"
+            settings:controller="com.android.settings.datetime.LocationProviderStatusPreferenceController"/>
+
+        <!-- This preference gets removed if location-based time zone detection is not supported -->
+        <SwitchPreferenceCompat
+            android:key="location_time_zone_detection"
+            android:title="@string/location_time_zone_detection_toggle_title"
+            android:summary="@string/summary_placeholder"
+            settings:controller="com.android.settings.datetime.LocationTimeZoneDetectionPreferenceController"/>
+
+        <com.android.settingslib.RestrictedPreference
+            android:key="timezone"
+            android:title="@string/date_time_set_timezone_title"
+            android:summary="@string/summary_placeholder"
+            android:fragment="com.android.settings.datetime.timezone.TimeZoneSettings"
+            settings:userRestriction="no_config_date_time"
+            settings:keywords="@string/keywords_time_zone"
+            settings:controller="com.android.settings.datetime.TimeZonePreferenceController" />
+
+    </PreferenceCategory>
+
+    <!-- An optional preference category for feedback. Only displayed up if enabled via flags and config. -->
+    <PreferenceCategory
+            android:key="time_feedback_preference_category"
+            android:title="@string/time_feedback_category_title"
+            settings:keywords="@string/keywords_time_feedback_category"
+            settings:controller="com.android.settings.datetime.TimeFeedbackPreferenceCategoryController">
+
+        <Preference
+                android:key="time_feedback"
+                android:title="@string/time_feedback_title"
+                settings:keywords="@string/keywords_time_feedback"
+                settings:controller="com.android.settings.datetime.TimeFeedbackPreferenceController" />
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:key="time_format_preference_category"
+        android:title="@string/time_format_category_title"
+        settings:keywords="@string/keywords_time_format">
+
+        <SwitchPreferenceCompat
+            android:key="24 hour"
+            android:title="@string/date_time_24hour"
+            settings:controller="com.android.settings.datetime.TimeFormatPreferenceController" />
+    </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/physical_keyboard_settings.xml b/res/xml/physical_keyboard_settings.xml
index 5d2c5fc..5691405 100644
--- a/res/xml/physical_keyboard_settings.xml
+++ b/res/xml/physical_keyboard_settings.xml
@@ -33,11 +33,12 @@
             android:summary="@string/modifier_keys_settings_summary"
             android:fragment="com.android.settings.inputmethod.ModifierKeysSettings" />
 
-        <SwitchPreferenceCompat
-            android:key="physical_keyboard_repeat_key"
-            android:title="@string/keyboard_repeat_key_title"
-            android:summary="@string/keyboard_repeat_key_summary"
+        <com.android.settingslib.PrimarySwitchPreference
+            android:key="physical_keyboard_repeat_keys"
+            android:title="@string/keyboard_repeat_keys_title"
+            android:summary="@string/keyboard_repeat_keys_summary"
             android:defaultValue="false"
+            android:fragment="com.android.settings.inputmethod.KeyboardRepeatKeysMainFragment"
             settings:controller="com.android.settings.inputmethod.KeyboardRepeatKeysController" />
 
         <Preference
diff --git a/res/xml/repeat_key_main_page.xml b/res/xml/repeat_key_main_page.xml
new file mode 100644
index 0000000..c33eba7
--- /dev/null
+++ b/res/xml/repeat_key_main_page.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 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"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="@string/keyboard_repeat_keys_title"
+    android:key="repeat_keys_main_page">
+
+    <com.android.settingslib.widget.MainSwitchPreference
+        android:key="repeat_keys_main_switch"
+        android:title="@string/keyboard_repeat_keys_title"
+        settings:controller="com.android.settings.inputmethod.KeyboardRepeatKeysController"/>
+    <com.android.settings.widget.LabeledSeekBarPreference
+        android:key="repeat_keys_timeout_preference"
+        android:title="@string/keyboard_repeat_keys_timeout_title"
+        android:min="0"
+        android:max="6"
+        settings:seekBarIncrement="1"
+        settings:controller= "com.android.settings.inputmethod.KeyboardRepeatKeysTimeOutPreferenceController" />
+    <com.android.settings.widget.LabeledSeekBarPreference
+        android:key="repeat_keys_delay_preference"
+        android:title="@string/keyboard_repeat_keys_delay_title"
+        android:min="0"
+        android:max="8"
+        settings:seekBarIncrement="1"
+        settings:controller= "com.android.settings.inputmethod.KeyboardRepeatKeysDelayPreferenceController" />
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/system_navigation_gesture_settings.xml b/res/xml/system_navigation_gesture_settings.xml
index a75875b..8919a40 100644
--- a/res/xml/system_navigation_gesture_settings.xml
+++ b/res/xml/system_navigation_gesture_settings.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  Copyright (C) 2018 The Android Open Source Project
+  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.
@@ -19,4 +19,15 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/system_navigation_title"
-    settings:keywords="@string/keywords_system_navigation"/>
+    settings:keywords="@string/keywords_system_navigation">
+
+    <SwitchPreferenceCompat
+        android:key="search_gesture_press_hold"
+        android:title="@string/search_gesture_feature_title"
+        android:summary="@string/search_gesture_feature_summary"
+        android:order="100"
+        settings:allowDividerAbove="true"
+        settings:controller="com.android.settings.gestures.NavigationSettingsContextualSearchController"
+        settings:highlightableMenuKey="@string/menu_key_system" />
+
+</PreferenceScreen>
diff --git a/src/com/android/settings/ResetNetwork.java b/src/com/android/settings/ResetNetwork.java
index f86e29f..2178b60 100644
--- a/src/com/android/settings/ResetNetwork.java
+++ b/src/com/android/settings/ResetNetwork.java
@@ -47,7 +47,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.internal.telephony.flags.Flags;
 import com.android.settings.core.InstrumentedFragment;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.network.ResetNetworkRestrictionViewBuilder;
@@ -142,13 +141,10 @@
         Context context = getContext();
         boolean resetSims = false;
 
-        // TODO(b/317276437) Simplify the logic once flag is released
         int resetOptions = ResetNetworkRequest.RESET_CONNECTIVITY_MANAGER
-                        | ResetNetworkRequest.RESET_VPN_MANAGER;
-        if (Flags.resetMobileNetworkSettings()) {
-            resetOptions |= ResetNetworkRequest.RESET_IMS_STACK;
-            resetOptions |= ResetNetworkRequest.RESET_PHONE_PROCESS;
-        }
+                        | ResetNetworkRequest.RESET_VPN_MANAGER
+                        | ResetNetworkRequest.RESET_IMS_STACK
+                        | ResetNetworkRequest.RESET_PHONE_PROCESS;
         ResetNetworkRequest request = new ResetNetworkRequest(resetOptions);
         if (mSubscriptions != null && mSubscriptions.size() > 0) {
             int selectedIndex = mSubscriptionSpinner.getSelectedItemPosition();
@@ -156,9 +152,7 @@
             int subId = subscription.getSubscriptionId();
             request.setResetTelephonyAndNetworkPolicyManager(subId)
                     .setResetApn(subId);
-            if (Flags.resetMobileNetworkSettings()) {
-                request.setResetImsSubId(subId);
-            }
+            request.setResetImsSubId(subId);
         }
         if (mEsimContainer.getVisibility() == View.VISIBLE && mEsimCheckbox.isChecked()) {
             resetSims = true;
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index f7110b4..b04f3af 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -514,4 +514,5 @@
 
     public static class HearingDevicesActivity extends SettingsActivity { /* empty */ }
     public static class HearingDevicesPairingActivity extends SettingsActivity { /* empty */ }
+    public static class ContactsStorageSettingsActivity extends SettingsActivity { /* empty */ }
 }
diff --git a/src/com/android/settings/SettingsService.kt b/src/com/android/settings/SettingsService.kt
new file mode 100644
index 0000000..2cd706b
--- /dev/null
+++ b/src/com/android/settings/SettingsService.kt
@@ -0,0 +1,30 @@
+/*
+ * 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
+
+import android.content.Intent
+import android.os.IBinder
+import com.android.settings.flags.Flags
+import com.android.settingslib.service.PreferenceService
+
+/** Service to expose settings APIs. */
+class SettingsService : PreferenceService({ _, _, _ -> true }) {
+
+    override fun onBind(intent: Intent): IBinder? {
+        return if (!Flags.catalystService()) null else super.onBind(intent)
+    }
+}
diff --git a/src/com/android/settings/bluetooth/ui/model/DeviceSettingPreferenceModel.kt b/src/com/android/settings/bluetooth/ui/model/DeviceSettingPreferenceModel.kt
index ba6d1a6..f4992da 100644
--- a/src/com/android/settings/bluetooth/ui/model/DeviceSettingPreferenceModel.kt
+++ b/src/com/android/settings/bluetooth/ui/model/DeviceSettingPreferenceModel.kt
@@ -44,6 +44,7 @@
         val icon: DeviceSettingIcon? = null,
         val checked: Boolean,
         val onCheckedChange: ((Boolean) -> Unit),
+        val disabled: Boolean = false,
         val action: DeviceSettingActionModel? = null,
     ) : DeviceSettingPreferenceModel
 
diff --git a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt
index 5418a04..ad4176f 100644
--- a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt
+++ b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt
@@ -139,7 +139,7 @@
             viewModel
                 .getItems(fragmentType)
                 ?.filterIsInstance<DeviceSettingConfigItemModel.BuiltinItem.BluetoothProfilesItem>()
-                ?.first()
+                ?.firstOrNull()
                 ?.invisibleProfiles
         }
 
@@ -306,6 +306,7 @@
                 override val onCheckedChange = { newChecked: Boolean ->
                     model.onCheckedChange(newChecked)
                 }
+                override val changeable = { !model.disabled }
                 override val icon: (@Composable () -> Unit)?
                     get() {
                         if (model.icon == null) {
diff --git a/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModel.kt b/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModel.kt
index a9444a5..3b7a582 100644
--- a/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModel.kt
+++ b/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModel.kt
@@ -58,6 +58,8 @@
             deviceSettingRepository.getDeviceSettingsConfig(cachedDevice)
         }
 
+    private val spatialAudioModel by lazy { spatialAudioInteractor.getDeviceSetting(cachedDevice) }
+
     suspend fun getItems(fragment: FragmentTypeModel): List<DeviceSettingConfigItemModel>? =
         when (fragment) {
             is FragmentTypeModel.DeviceDetailsMainFragment -> items.await()?.mainItems
@@ -81,7 +83,7 @@
         }
         return when (settingId) {
             DeviceSettingId.DEVICE_SETTING_ID_SPATIAL_AUDIO_MULTI_TOGGLE ->
-                spatialAudioInteractor.getDeviceSetting(cachedDevice)
+                spatialAudioModel
             else -> deviceSettingRepository.getDeviceSetting(cachedDevice, settingId)
         }.map { it?.toPreferenceModel() }
     }
@@ -101,6 +103,7 @@
                                 DeviceSettingStateModel.ActionSwitchPreferenceState(newState)
                             )
                         },
+                        disabled = !isAllowedChangingState,
                         action = action,
                     )
                 } else {
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 3e92d5f..117364f 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -60,6 +60,7 @@
 import com.android.settings.applications.appinfo.WriteSettingsDetails;
 import com.android.settings.applications.appops.BackgroundCheckSummary;
 import com.android.settings.applications.assist.ManageAssist;
+import com.android.settings.applications.contacts.ContactsStorageSettings;
 import com.android.settings.applications.manageapplications.ManageApplications;
 import com.android.settings.applications.managedomainurls.ManageDomainUrls;
 import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminSettings;
@@ -401,7 +402,8 @@
             AccessibilityHearingAidsFragment.class.getName(),
             HearingDevicePairingFragment.class.getName(),
             ZenModesListFragment.class.getName(),
-            ZenModeFragment.class.getName()
+            ZenModeFragment.class.getName(),
+            ContactsStorageSettings.class.getName()
     };
 
     public static final String[] SETTINGS_FOR_RESTRICTED = {
diff --git a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java
index 2f06289..3d8f801 100644
--- a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java
+++ b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java
@@ -32,6 +32,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.flags.Flags;
 
 public class AutoTimeZonePreferenceController extends TogglePreferenceController {
 
@@ -46,7 +47,7 @@
         // setTimeAndDateCallback() isn't called, e.g. for slices and other cases where the
         // controller is instantiated outside of the context of the real Date & Time settings
         // screen.
-        mCallback  = (c) -> {};
+        mCallback = (c) -> {};
     }
 
     /**
@@ -103,10 +104,25 @@
 
     @Override
     public boolean setChecked(boolean isChecked) {
-        TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
-                .setAutoDetectionEnabled(isChecked)
-                .build();
-        boolean result = mTimeManager.updateTimeZoneConfiguration(configuration);
+        TimeZoneConfiguration.Builder configuration = new TimeZoneConfiguration.Builder()
+                .setAutoDetectionEnabled(isChecked);
+
+        if (Flags.revampToggles()) {
+            // "Use location for time zone" is only used if "Automatic time zone" is enabled. If
+            // the user toggles off automatic time zone, set the toggle off and disable the toggle.
+            int geoDetectionCapability = mTimeManager
+                    .getTimeZoneCapabilitiesAndConfig()
+                    .getCapabilities()
+                    .getConfigureGeoDetectionEnabledCapability();
+
+            if (!isChecked
+                    && (geoDetectionCapability == CAPABILITY_NOT_APPLICABLE
+                    || geoDetectionCapability == CAPABILITY_POSSESSED)) {
+                configuration.setGeoDetectionEnabled(false);
+            }
+        }
+
+        boolean result = mTimeManager.updateTimeZoneConfiguration(configuration.build());
 
         mCallback.updateTimeAndDateDisplay(mContext);
         return result;
@@ -138,8 +154,10 @@
 
     @VisibleForTesting
     boolean isEnabled() {
-        TimeZoneConfiguration config = getTimeZoneCapabilitiesAndConfig().getConfiguration();
-        return config.isAutoDetectionEnabled();
+        return mTimeManager
+                .getTimeZoneCapabilitiesAndConfig()
+                .getConfiguration()
+                .isAutoDetectionEnabled();
     }
 
     private TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig() {
diff --git a/src/com/android/settings/datetime/DateTimeSettings.java b/src/com/android/settings/datetime/DateTimeSettings.java
index f3c11d4..e5c13bf 100644
--- a/src/com/android/settings/datetime/DateTimeSettings.java
+++ b/src/com/android/settings/datetime/DateTimeSettings.java
@@ -23,6 +23,7 @@
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.flags.Flags;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 
@@ -49,6 +50,9 @@
 
     @Override
     protected int getPreferenceScreenResId() {
+        if (Flags.revampToggles()) {
+            return R.xml.date_time_prefs_revamped;
+        }
         return R.xml.date_time_prefs;
     }
 
@@ -119,5 +123,6 @@
     }
 
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.date_time_prefs);
+            new BaseSearchIndexProvider(
+                    Flags.revampToggles() ? R.xml.date_time_prefs_revamped : R.xml.date_time_prefs);
 }
diff --git a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
index a50ce4c..52d49ac 100644
--- a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
+++ b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
@@ -32,6 +32,7 @@
 import com.android.settings.R;
 import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.flags.Flags;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -64,8 +65,10 @@
 
     @Override
     public boolean isChecked() {
+        // forceRefresh set to true as the location toggle may have been turned off by switching off
+        // automatic time zone
         TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
-                getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/false);
+                getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/ Flags.revampToggles());
         TimeZoneConfiguration configuration = capabilitiesAndConfig.getConfiguration();
         return configuration.isGeoDetectionEnabled();
     }
@@ -73,7 +76,7 @@
     @Override
     public boolean setChecked(boolean isChecked) {
         TimeZoneCapabilitiesAndConfig timeZoneCapabilitiesAndConfig =
-                getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/false);
+                getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/ false);
         boolean isLocationEnabled =
                 timeZoneCapabilitiesAndConfig.getCapabilities().isUseLocationEnabled();
         if (isChecked && !isLocationEnabled) {
@@ -130,18 +133,31 @@
                 getTimeZoneCapabilitiesAndConfig(/* forceRefresh= */ false).getCapabilities();
         int capability = timeZoneCapabilities.getConfigureGeoDetectionEnabledCapability();
 
-        // The preference only has two states: present and not present. The preference is never
-        // present but disabled.
+        // The preference can be present and enabled, present and disabled or not present.
         if (capability == CAPABILITY_NOT_SUPPORTED || capability == CAPABILITY_NOT_ALLOWED) {
             return UNSUPPORTED_ON_DEVICE;
         } else if (capability == CAPABILITY_NOT_APPLICABLE || capability == CAPABILITY_POSSESSED) {
-            return AVAILABLE;
+            if (Flags.revampToggles()) {
+                return isAutoTimeZoneEnabled() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
+            } else {
+                return AVAILABLE;
+            }
         } else {
             throw new IllegalStateException("Unknown capability=" + capability);
         }
     }
 
     @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+
+        if (Flags.revampToggles()) {
+            // enable / disable the toggle based on automatic time zone being enabled or not
+            preference.setEnabled(isAutoTimeZoneEnabled());
+        }
+    }
+
+    @Override
     public CharSequence getSummary() {
         TimeZoneCapabilitiesAndConfig timeZoneCapabilitiesAndConfig =
                 getTimeZoneCapabilitiesAndConfig(/* forceRefresh= */ false);
@@ -212,4 +228,13 @@
         }
         return mTimeZoneCapabilitiesAndConfig;
     }
+
+    /**
+     * Returns whether the user can select this preference or not, as it is a sub toggle of
+     * automatic time zone.
+     */
+    private boolean isAutoTimeZoneEnabled() {
+        return mTimeManager.getTimeZoneCapabilitiesAndConfig().getConfiguration()
+                .isAutoDetectionEnabled();
+    }
 }
diff --git a/src/com/android/settings/datetime/TimeFormatPreferenceController.java b/src/com/android/settings/datetime/TimeFormatPreferenceController.java
index 19805ad..2dee76e 100644
--- a/src/com/android/settings/datetime/TimeFormatPreferenceController.java
+++ b/src/com/android/settings/datetime/TimeFormatPreferenceController.java
@@ -25,6 +25,7 @@
 
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.flags.Flags;
 
 import java.util.Calendar;
 import java.util.Date;
@@ -72,8 +73,10 @@
         if (mIsFromSUW) {
             return DISABLED_DEPENDENT_SETTING;
         }
-        if (AutoTimeFormatPreferenceController.isAutoTimeFormatSelection(mContext)) {
-            return DISABLED_DEPENDENT_SETTING;
+        if (!Flags.revampToggles()) {
+            if (AutoTimeFormatPreferenceController.isAutoTimeFormatSelection(mContext)) {
+                return DISABLED_DEPENDENT_SETTING;
+            }
         }
         return AVAILABLE;
     }
@@ -130,7 +133,7 @@
             timeFormatPreference = Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT;
         } else {
             timeFormatPreference = is24Hour ? Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR
-                : Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR;
+                    : Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR;
         }
         timeChanged.putExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, timeFormatPreference);
         context.sendBroadcast(timeChanged);
@@ -138,7 +141,7 @@
 
     static void set24Hour(Context context, Boolean is24Hour) {
         String value = is24Hour == null ? null :
-            is24Hour ? HOURS_24 : HOURS_12;
+                is24Hour ? HOURS_24 : HOURS_12;
         Settings.System.putString(context.getContentResolver(),
                 Settings.System.TIME_12_24, value);
     }
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScreen.kt b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScreen.kt
new file mode 100644
index 0000000..2226e37
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScreen.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.fuelgauge.batterysaver
+
+import android.content.Context
+import com.android.settings.R
+import com.android.settings.flags.Flags
+import com.android.settingslib.metadata.ProvidePreferenceScreen
+import com.android.settingslib.metadata.preferenceHierarchy
+import com.android.settingslib.preference.PreferenceScreenCreator
+
+@ProvidePreferenceScreen
+class BatterySaverScreen : PreferenceScreenCreator {
+    override val key: String
+        get() = KEY
+
+    override val title: Int
+        get() = R.string.battery_saver
+
+    override val keywords: Int
+        get() = R.string.keywords_battery_saver
+
+    override fun isFlagEnabled(context: Context) = Flags.catalystBatterySaverScreen()
+
+    override fun fragmentClass() = BatterySaverSettings::class.java
+
+    override fun hasCompleteHierarchy() = false
+
+    override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {}
+
+    companion object {
+        const val KEY = "battery_saver_screen"
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
index 8e281de..8373d03 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
@@ -17,8 +17,11 @@
 package com.android.settings.fuelgauge.batterysaver;
 
 import android.app.settings.SettingsEnums;
+import android.content.Context;
 import android.text.TextUtils;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.R;
@@ -93,4 +96,10 @@
             pref.setLearnMoreText(getString(R.string.battery_saver_link_a11y));
         }
     }
+
+    @Nullable
+    @Override
+    public String getPreferenceScreenBindingKey(@NonNull Context context) {
+        return BatterySaverScreen.KEY;
+    }
 }
diff --git a/src/com/android/settings/gestures/ButtonNavigationSettingsAssistController.java b/src/com/android/settings/gestures/ButtonNavigationSettingsAssistController.java
index 4c5e28c..72f8339 100644
--- a/src/com/android/settings/gestures/ButtonNavigationSettingsAssistController.java
+++ b/src/com/android/settings/gestures/ButtonNavigationSettingsAssistController.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.gestures;
 
+import static android.app.contextualsearch.ContextualSearchManager.FEATURE_CONTEXTUAL_SEARCH;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
 
@@ -50,6 +51,11 @@
 
     @Override
     public int getAvailabilityStatus() {
+        // Hide the existing assistant UI elements when contextual search is available.
+        if (mContext.getPackageManager().hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)) {
+            return UNSUPPORTED_ON_DEVICE;
+        }
+
         if (SystemNavigationPreferenceController.isOverlayPackageAvailable(mContext,
                 NAV_BAR_MODE_2BUTTON_OVERLAY)
                 || SystemNavigationPreferenceController.isOverlayPackageAvailable(mContext,
diff --git a/src/com/android/settings/gestures/NavigationSettingsContextualSearchController.java b/src/com/android/settings/gestures/NavigationSettingsContextualSearchController.java
new file mode 100644
index 0000000..5938b5f
--- /dev/null
+++ b/src/com/android/settings/gestures/NavigationSettingsContextualSearchController.java
@@ -0,0 +1,70 @@
+/*
+ * 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.gestures;
+
+import static android.app.contextualsearch.ContextualSearchManager.FEATURE_CONTEXTUAL_SEARCH;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+
+import com.android.settings.core.TogglePreferenceController;
+
+/**
+ * Configures behaviour of Contextual Search setting.
+ */
+public class NavigationSettingsContextualSearchController extends TogglePreferenceController {
+
+    public NavigationSettingsContextualSearchController(@NonNull Context context,
+            @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public boolean isChecked() {
+        boolean onByDefault = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_searchAllEntrypointsEnabledDefault);
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.SEARCH_ALL_ENTRYPOINTS_ENABLED, onByDefault ? 1 : 0)
+                == 1;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.SEARCH_ALL_ENTRYPOINTS_ENABLED, isChecked ? 1 : 0);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (mContext.getPackageManager().hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)) {
+            return AVAILABLE;
+        }
+        return UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public boolean isSliceable() {
+        return false;
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        return NO_RES;
+    }
+}
diff --git a/src/com/android/settings/inputmethod/KeyboardRepeatKeysController.java b/src/com/android/settings/inputmethod/KeyboardRepeatKeysController.java
index a232098..28392be 100644
--- a/src/com/android/settings/inputmethod/KeyboardRepeatKeysController.java
+++ b/src/com/android/settings/inputmethod/KeyboardRepeatKeysController.java
@@ -25,14 +25,20 @@
 import androidx.annotation.Nullable;
 import androidx.lifecycle.LifecycleObserver;
 import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreferenceCompat;
+
+import com.android.settingslib.PrimarySwitchPreference;
+import com.android.settingslib.widget.MainSwitchPreference;
 
 public class KeyboardRepeatKeysController extends
         InputSettingPreferenceController implements
         LifecycleObserver {
+    private static final String KEY_REPEAT_KEY = "physical_keyboard_repeat_keys";
+    private static final String KEY_REPEAT_KEY_MAIN_PAGE = "repeat_key_main_switch";
 
     @Nullable
-    private SwitchPreferenceCompat mSwitchPreferenceCompat;
+    private PrimarySwitchPreference mPrimarySwitchPreference;
+    @Nullable
+    private MainSwitchPreference mMainSwitchPreference;
 
     public KeyboardRepeatKeysController(@NonNull Context context,
             @NonNull String key) {
@@ -42,7 +48,11 @@
     @Override
     public void displayPreference(@NonNull PreferenceScreen screen) {
         super.displayPreference(screen);
-        mSwitchPreferenceCompat = screen.findPreference(getPreferenceKey());
+        if (KEY_REPEAT_KEY.equals(getPreferenceKey())) {
+            mPrimarySwitchPreference = screen.findPreference(getPreferenceKey());
+        } else if (KEY_REPEAT_KEY_MAIN_PAGE.equals(getPreferenceKey())) {
+            mMainSwitchPreference = screen.findPreference(getPreferenceKey());
+        }
     }
 
     @Override
@@ -63,8 +73,10 @@
 
     @Override
     protected void onInputSettingUpdated() {
-        if (mSwitchPreferenceCompat != null) {
-            mSwitchPreferenceCompat.setChecked(InputSettings.isRepeatKeysEnabled(mContext));
+        if (mPrimarySwitchPreference != null) {
+            mPrimarySwitchPreference.setChecked(InputSettings.isRepeatKeysEnabled(mContext));
+        } else if (mMainSwitchPreference != null) {
+            mMainSwitchPreference.setChecked(InputSettings.isRepeatKeysEnabled(mContext));
         }
     }
 
diff --git a/src/com/android/settings/inputmethod/KeyboardRepeatKeysDelayPreferenceController.java b/src/com/android/settings/inputmethod/KeyboardRepeatKeysDelayPreferenceController.java
new file mode 100644
index 0000000..bb074fd
--- /dev/null
+++ b/src/com/android/settings/inputmethod/KeyboardRepeatKeysDelayPreferenceController.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 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.inputmethod;
+
+import android.content.Context;
+import android.hardware.input.InputSettings;
+
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.core.SliderPreferenceController;
+
+import com.google.common.collect.ImmutableList;
+
+public class KeyboardRepeatKeysDelayPreferenceController extends SliderPreferenceController {
+    @VisibleForTesting
+    static final ImmutableList<Integer> REPEAT_KEY_DELAY_VALUE_LIST = ImmutableList.of(2000, 1000,
+            500, 300, 200, 100, 50, 30, 20);
+
+    public KeyboardRepeatKeysDelayPreferenceController(@NonNull Context context,
+            @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public int getSliderPosition() {
+        return REPEAT_KEY_DELAY_VALUE_LIST.indexOf(InputSettings.getRepeatKeysDelay(mContext));
+    }
+
+    @Override
+    public boolean setSliderPosition(int position) {
+        InputSettings.setRepeatKeysDelay(mContext, REPEAT_KEY_DELAY_VALUE_LIST.get(position));
+        return true;
+    }
+
+    @Override
+    public int getMax() {
+        return REPEAT_KEY_DELAY_VALUE_LIST.size() - 1;
+    }
+
+    @Override
+    public int getMin() {
+        return 0;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return InputSettings.isRepeatKeysFeatureFlagEnabled()
+                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+    }
+}
diff --git a/src/com/android/settings/inputmethod/KeyboardRepeatKeysMainFragment.java b/src/com/android/settings/inputmethod/KeyboardRepeatKeysMainFragment.java
new file mode 100644
index 0000000..39e605d
--- /dev/null
+++ b/src/com/android/settings/inputmethod/KeyboardRepeatKeysMainFragment.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 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.inputmethod;
+
+import static com.android.settings.inputmethod.PhysicalKeyboardFragment.getHardKeyboards;
+
+import android.app.settings.SettingsEnums;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.hardware.input.InputManager;
+import android.hardware.input.InputSettings;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.internal.util.Preconditions;
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.keyboard.Flags;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.widget.LabeledSeekBarPreference;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.util.List;
+
+public class KeyboardRepeatKeysMainFragment extends DashboardFragment
+        implements InputManager.InputDeviceListener {
+    private static final String TAG = "RepeatKeysMainFragment";
+    private static final String TIME_OUT_KEY = "repeat_keys_timeout_preference";
+    private static final String DELAY_KEY = "repeat_keys_delay_preference";
+
+    private final Uri mRepeatKeyUri = Settings.Secure.getUriFor(
+            Settings.Secure.KEY_REPEAT_ENABLED);
+    private final ContentObserver mContentObserver = new ContentObserver(new Handler(true)) {
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (mRepeatKeyUri.equals(uri)) {
+                updatePreferencesState();
+            }
+        }
+    };
+    private InputManager mInputManager;
+    private ContentResolver mContentResolver;
+    @Nullable
+    private LabeledSeekBarPreference mRepeatTimeoutPreference;
+    @Nullable
+    private LabeledSeekBarPreference mRepeatDelayPreference;
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.PHYSICAL_KEYBOARD_A11Y;
+    }
+
+    @Override
+    public void onAttach(@NonNull Context context) {
+        super.onAttach(context);
+        mInputManager = Preconditions.checkNotNull(getActivity()
+                .getSystemService(InputManager.class));
+        mContentResolver = context.getContentResolver();
+    }
+
+    @Override
+    public void onCreatePreferences(Bundle bundle, String s) {
+        super.onCreatePreferences(bundle, s);
+        mRepeatTimeoutPreference = findPreference(TIME_OUT_KEY);
+        mRepeatDelayPreference = findPreference(DELAY_KEY);
+        updatePreferencesState();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        finishEarlyIfNeeded();
+        mInputManager.registerInputDeviceListener(this, null);
+        registerSettingsObserver();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mInputManager.unregisterInputDeviceListener(this);
+        unregisterSettingsObserver();
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.repeat_key_main_page;
+    }
+
+    private void updatePreferencesState() {
+        boolean isRepeatKeyEnabled = InputSettings.isRepeatKeysEnabled(getContext());
+        if (mRepeatTimeoutPreference != null && mRepeatDelayPreference != null) {
+            mRepeatTimeoutPreference.setEnabled(isRepeatKeyEnabled);
+            mRepeatDelayPreference.setEnabled(isRepeatKeyEnabled);
+        }
+    }
+
+    private void registerSettingsObserver() {
+        unregisterSettingsObserver();
+        mContentResolver.registerContentObserver(
+                mRepeatKeyUri,
+                false,
+                mContentObserver,
+                UserHandle.myUserId());
+    }
+
+    private void unregisterSettingsObserver() {
+        mContentResolver.unregisterContentObserver(mContentObserver);
+    }
+
+    @Override
+    public void onInputDeviceAdded(int deviceId) {
+        finishEarlyIfNeeded();
+    }
+
+    @Override
+    public void onInputDeviceRemoved(int deviceId) {
+        finishEarlyIfNeeded();
+    }
+
+    @Override
+    public void onInputDeviceChanged(int deviceId) {
+        finishEarlyIfNeeded();
+    }
+
+    private void finishEarlyIfNeeded() {
+        final Context context = getContext();
+        ThreadUtils.postOnBackgroundThread(() -> {
+            final List<PhysicalKeyboardFragment.HardKeyboardDeviceInfo> newHardKeyboards =
+                    getHardKeyboards(context);
+            if (newHardKeyboards.isEmpty()) {
+                getActivity().finish();
+            }
+        });
+    }
+
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.repeat_key_main_page) {
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    return Flags.keyboardAndTouchpadA11yNewPageEnabled()
+                            && !getHardKeyboards(context).isEmpty();
+                }
+            };
+}
diff --git a/src/com/android/settings/inputmethod/KeyboardRepeatKeysTimeOutPreferenceController.java b/src/com/android/settings/inputmethod/KeyboardRepeatKeysTimeOutPreferenceController.java
new file mode 100644
index 0000000..e766d48
--- /dev/null
+++ b/src/com/android/settings/inputmethod/KeyboardRepeatKeysTimeOutPreferenceController.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 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.inputmethod;
+
+import android.content.Context;
+import android.hardware.input.InputSettings;
+
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.core.SliderPreferenceController;
+
+import com.google.common.collect.ImmutableList;
+
+public class KeyboardRepeatKeysTimeOutPreferenceController extends SliderPreferenceController {
+    @VisibleForTesting
+    static final ImmutableList<Integer> REPEAT_KEY_TIMEOUT_VALUE_LIST = ImmutableList.of(2000, 1500,
+            1000, 400, 300, 200, 150);
+
+    public KeyboardRepeatKeysTimeOutPreferenceController(
+            @NonNull Context context,
+            @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public int getSliderPosition() {
+        return REPEAT_KEY_TIMEOUT_VALUE_LIST.indexOf(InputSettings.getRepeatKeysTimeout(mContext));
+    }
+
+    @Override
+    public boolean setSliderPosition(int position) {
+        InputSettings.setRepeatKeysTimeout(mContext, REPEAT_KEY_TIMEOUT_VALUE_LIST.get(position));
+        return true;
+    }
+
+    @Override
+    public int getMax() {
+        return REPEAT_KEY_TIMEOUT_VALUE_LIST.size() - 1;
+    }
+
+    @Override
+    public int getMin() {
+        return 0;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return InputSettings.isRepeatKeysFeatureFlagEnabled()
+                ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+    }
+}
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index ee7d440..3ba3dc6 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.settings.R;
@@ -115,4 +116,10 @@
                     return buildPreferenceControllers(context, null /* lifecycle */);
                 }
             };
+
+    @Nullable
+    @Override
+    public String getPreferenceScreenBindingKey(@NonNull Context context) {
+        return NetworkDashboardScreen.KEY;
+    }
 }
diff --git a/src/com/android/settings/network/NetworkDashboardScreen.kt b/src/com/android/settings/network/NetworkDashboardScreen.kt
new file mode 100644
index 0000000..dcdc37f
--- /dev/null
+++ b/src/com/android/settings/network/NetworkDashboardScreen.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.network
+
+import android.content.Context
+import com.android.settings.R
+import com.android.settings.flags.Flags
+import com.android.settingslib.metadata.ProvidePreferenceScreen
+import com.android.settingslib.metadata.preferenceHierarchy
+import com.android.settingslib.preference.PreferenceScreenCreator
+
+@ProvidePreferenceScreen
+class NetworkDashboardScreen : PreferenceScreenCreator {
+    override val key: String
+        get() = KEY
+
+    override val title: Int
+        get() = R.string.network_dashboard_title
+
+    override val icon: Int
+        get() = R.drawable.ic_settings_wireless_filled
+
+    override fun isFlagEnabled(context: Context) = Flags.catalystNetworkProviderAndInternetScreen()
+
+    override fun hasCompleteHierarchy() = false
+
+    override fun fragmentClass() = NetworkDashboardFragment::class.java
+
+    override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {}
+
+    companion object {
+        const val KEY = "network_provider_and_internet_screen"
+    }
+}
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index 84c84b0..1cac363 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -109,7 +109,10 @@
 
 java_library {
     name: "Settings-robo-testutils",
-    srcs: ["testutils/**/*.java"],
+    srcs: [
+        "testutils/**/*.java",
+        "testutils/**/*.kt",
+    ],
     libs: [
         "Robolectric_all-target_upstream",
         "Settings-core",
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
index 8f983de..df2ab45 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrollingTest.java
@@ -63,12 +63,14 @@
 
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SystemProperty;
 import com.android.settings.widget.RingProgressBar;
 
 import com.airbnb.lottie.LottieAnimationView;
 import com.airbnb.lottie.LottieTask;
 import com.google.android.setupdesign.GlifLayout;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -111,15 +113,23 @@
     private final int[] mSfpsStageThresholds = new int[]{0, 9, 13, 19, 25};
     private final int[] mUdfpsStageThresholds = new int[]{0, 13, 17, 22};
 
+    private final SystemProperty mSystemProperty = new SystemProperty();
+
     private FingerprintEnrollEnrolling mActivity;
     private Context mContext;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mSystemProperty.override("robolectric.createActivityContexts", "true");
         FakeFeatureFactory.setupForTest();
     }
 
+    @After
+    public void tearDown() {
+        mSystemProperty.close();
+    }
+
     @Test
     public void fingerprintUdfpsEnrollSuccessProgress_shouldNotVibrate() {
         initializeActivityFor(TYPE_UDFPS_OPTICAL);
@@ -645,7 +655,6 @@
     }
 
     private void createActivity() {
-        System.setProperty("robolectric.createActivityContexts", "true");
         final Bundle savedInstanceState = new Bundle();
         savedInstanceState.putInt(KEY_STATE_PREVIOUS_ROTATION, Surface.ROTATION_90);
 
diff --git a/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java
index 651915b..7bf8d52 100644
--- a/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java
@@ -40,12 +40,17 @@
 import android.app.time.TimeZoneDetectorStatus;
 import android.content.Context;
 import android.os.UserHandle;
+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.R;
+import com.android.settings.flags.Flags;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -57,6 +62,9 @@
 @RunWith(RobolectricTestRunner.class)
 public class AutoTimeZonePreferenceControllerTest {
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     @Mock
     private UpdateTimeAndDateCallback mCallback;
     private Context mContext;
@@ -238,8 +246,53 @@
                 mContext.getString(R.string.auto_zone_requires_location_summary));
     }
 
+    @Test
+    @EnableFlags({Flags.FLAG_REVAMP_TOGGLES})
+    public void toggleOff_revampFlagOn_shouldToggleOffUseLocation() {
+        TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = createCapabilitiesAndConfig(
+                /* autoSupported= */ true,
+                /* autoEnabled= */ true,
+                /* telephonySupported= */ true,
+                /* locationSupported= */ true);
+        when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig);
+
+        mController.setChecked(false);
+
+        TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
+                .setAutoDetectionEnabled(false)
+                .setGeoDetectionEnabled(false)
+                .build();
+
+        verify(mTimeManager).updateTimeZoneConfiguration(configuration);
+    }
+
+    @Test
+    @DisableFlags({Flags.FLAG_REVAMP_TOGGLES})
+    public void toggleOff_revampFlagOff_shouldToggleOffUseLocation() {
+        TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = createCapabilitiesAndConfig(
+                /* autoSupported= */ true,
+                /* autoEnabled= */ true,
+                /* telephonySupported= */ true,
+                /* locationSupported= */ true);
+        when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig);
+
+        mController.setChecked(false);
+
+        TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
+                .setAutoDetectionEnabled(false)
+                .build();
+
+        verify(mTimeManager).updateTimeZoneConfiguration(configuration);
+    }
+
     private static TimeZoneCapabilitiesAndConfig createCapabilitiesAndConfig(
             boolean autoSupported, boolean autoEnabled, boolean telephonySupported) {
+        return createCapabilitiesAndConfig(autoSupported, autoEnabled, telephonySupported, false);
+    }
+
+    private static TimeZoneCapabilitiesAndConfig createCapabilitiesAndConfig(
+            boolean autoSupported, boolean autoEnabled, boolean telephonySupported,
+            boolean locationSupported) {
         TimeZoneDetectorStatus status = new TimeZoneDetectorStatus(DETECTOR_STATUS_RUNNING,
                 new TelephonyTimeZoneAlgorithmStatus(
                         telephonySupported ? DETECTION_ALGORITHM_STATUS_RUNNING
@@ -253,12 +306,14 @@
         TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder(UserHandle.SYSTEM)
                 .setConfigureAutoDetectionEnabledCapability(configureAutoDetectionEnabledCapability)
                 .setUseLocationEnabled(true)
-                .setConfigureGeoDetectionEnabledCapability(Capabilities.CAPABILITY_NOT_SUPPORTED)
+                .setConfigureGeoDetectionEnabledCapability(
+                        locationSupported ? Capabilities.CAPABILITY_POSSESSED
+                                : Capabilities.CAPABILITY_NOT_SUPPORTED)
                 .setSetManualTimeZoneCapability(Capabilities.CAPABILITY_POSSESSED)
                 .build();
         TimeZoneConfiguration config = new TimeZoneConfiguration.Builder()
                 .setAutoDetectionEnabled(autoEnabled)
-                .setGeoDetectionEnabled(false)
+                .setGeoDetectionEnabled(locationSupported)
                 .build();
         return new TimeZoneCapabilitiesAndConfig(status, capabilities, config);
     }
diff --git a/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
index cd89c0c..40794d2 100644
--- a/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
@@ -25,6 +25,8 @@
 import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_NOT_PRESENT;
 import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_NOT_READY;
 
+import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -43,11 +45,17 @@
 import android.app.time.TimeZoneDetectorStatus;
 import android.content.Context;
 import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.preference.SwitchPreference;
 
 import com.android.settings.R;
 import com.android.settings.core.InstrumentedPreferenceFragment;
+import com.android.settings.flags.Flags;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
@@ -62,9 +70,14 @@
         com.android.settings.testutils.shadow.ShadowFragment.class,
 })
 public class LocationTimeZoneDetectionPreferenceControllerTest {
+
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     @Mock
     private TimeManager mTimeManager;
     private Context mContext;
+    private SwitchPreference mPreference;
     private LocationTimeZoneDetectionPreferenceController mController;
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private InstrumentedPreferenceFragment mFragment;
@@ -76,6 +89,9 @@
         when(mContext.getSystemService(TimeManager.class)).thenReturn(mTimeManager);
         mController = new LocationTimeZoneDetectionPreferenceController(mContext);
         mController.setFragment(mFragment);
+
+        mPreference = new SwitchPreference(mContext);
+        mPreference.setKey("location_time_zone_detection");
     }
 
     @Test
@@ -115,6 +131,17 @@
     }
 
     @Test
+    @EnableFlags({Flags.FLAG_REVAMP_TOGGLES})
+    public void flagRevampTogglesOn_toggleOff_automaticTimeZone_disablesLocationToggle() {
+        TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
+                createTimeZoneCapabilitiesAndConfig(/* useLocationEnabled= */ true,
+                        CAPABILITY_POSSESSED, /* setAutoDetectionEnabled= */ false);
+        when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
+    }
+
+    @Test
     public void setChecked_withFalse_shouldUpdateSetting() {
         boolean useLocationEnabled = false;
         TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
@@ -181,7 +208,14 @@
     private static TimeZoneCapabilitiesAndConfig createTimeZoneCapabilitiesAndConfig(
             boolean useLocationEnabled,
             @CapabilityState int configureGeoDetectionEnabledCapability) {
+        return createTimeZoneCapabilitiesAndConfig(useLocationEnabled,
+                configureGeoDetectionEnabledCapability, /* setAutoDetectionEnabled= */ true);
+    }
 
+    private static TimeZoneCapabilitiesAndConfig createTimeZoneCapabilitiesAndConfig(
+            boolean useLocationEnabled,
+            @CapabilityState int configureGeoDetectionEnabledCapability,
+            boolean setAutoDetectionEnabled) {
         // Create a status that matches the user's capability state.
         LocationTimeZoneAlgorithmStatus locationAlgorithmStatus;
         switch (configureGeoDetectionEnabledCapability) {
@@ -213,7 +247,7 @@
                 .build();
 
         TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
-                .setAutoDetectionEnabled(true)
+                .setAutoDetectionEnabled(setAutoDetectionEnabled)
                 .setGeoDetectionEnabled(true)
                 .build();
 
diff --git a/tests/robotests/src/com/android/settings/datetime/TimeFormatPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/TimeFormatPreferenceControllerTest.java
index e1ea8f9..c5aac84 100644
--- a/tests/robotests/src/com/android/settings/datetime/TimeFormatPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/TimeFormatPreferenceControllerTest.java
@@ -23,11 +23,16 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 
 import androidx.preference.SwitchPreference;
 
+import com.android.settings.flags.Flags;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -41,6 +46,9 @@
 @RunWith(RobolectricTestRunner.class)
 public class TimeFormatPreferenceControllerTest {
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     @Mock
     private UpdateTimeAndDateCallback mCallback;
 
@@ -97,6 +105,7 @@
     }
 
     @Test
+    @DisableFlags({Flags.FLAG_REVAMP_TOGGLES})
     public void updateState_autoSet_shouldNotEnablePreference() {
         Settings.System.putString(mContext.getContentResolver(), Settings.System.TIME_12_24, null);
 
diff --git a/tests/robotests/src/com/android/settings/display/DisplayScreenTest.kt b/tests/robotests/src/com/android/settings/display/DisplayScreenTest.kt
index d869b84..61c3b19 100644
--- a/tests/robotests/src/com/android/settings/display/DisplayScreenTest.kt
+++ b/tests/robotests/src/com/android/settings/display/DisplayScreenTest.kt
@@ -21,6 +21,7 @@
 import com.android.internal.widget.LockPatternUtils
 import com.android.settings.flags.Flags
 import com.android.settings.testutils.FakeFeatureFactory
+import com.android.settings.testutils.SystemProperty
 import com.android.settingslib.preference.CatalystScreenTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
@@ -67,13 +68,14 @@
 
     override fun migration() {
         // avoid UnsupportedOperationException when getDisplay from context
-        System.setProperty("robolectric.createActivityContexts", "true")
+        SystemProperty("robolectric.createActivityContexts", "true").use {
+            val lockPatternUtils =
+                mock<LockPatternUtils> { on { isSecure(anyInt()) } doReturn true }
+            FakeFeatureFactory.setupForTest().securityFeatureProvider.stub {
+                on { getLockPatternUtils(any()) } doReturn lockPatternUtils
+            }
 
-        val lockPatternUtils = mock<LockPatternUtils> { on { isSecure(anyInt()) } doReturn true }
-        FakeFeatureFactory.setupForTest().securityFeatureProvider.stub {
-            on { getLockPatternUtils(any()) } doReturn lockPatternUtils
+            super.migration()
         }
-
-        super.migration()
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScreenTest.kt b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScreenTest.kt
new file mode 100644
index 0000000..a034e52
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScreenTest.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.fuelgauge.batterysaver
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.flags.Flags
+import com.android.settingslib.preference.CatalystScreenTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class BatterySaverScreenTest : CatalystScreenTestCase() {
+
+    override val preferenceScreenCreator = BatterySaverScreen()
+
+    override val flagName: String
+        get() = Flags.FLAG_CATALYST_BATTERY_SAVER_SCREEN
+
+    @Test
+    fun key() {
+        assertThat(preferenceScreenCreator.key).isEqualTo(BatterySaverScreen.KEY)
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/gestures/ButtonNavigationSettingsAssistControllerTest.java b/tests/robotests/src/com/android/settings/gestures/ButtonNavigationSettingsAssistControllerTest.java
index d961cdf..493fb01 100644
--- a/tests/robotests/src/com/android/settings/gestures/ButtonNavigationSettingsAssistControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/ButtonNavigationSettingsAssistControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.gestures;
 
+import static android.app.contextualsearch.ContextualSearchManager.FEATURE_CONTEXTUAL_SEARCH;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.mock;
@@ -23,6 +25,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.provider.Settings;
 
@@ -40,13 +43,16 @@
             "assistant_long_press_home_gesture";
 
     private Context mContext;
+    private PackageManager mPackageManager;
     private Resources mResources;
     private ButtonNavigationSettingsAssistController mController;
 
     @Before
     public void setUp() {
         mContext = spy(ApplicationProvider.getApplicationContext());
+        mPackageManager = mock(PackageManager.class);
         mResources = mock(Resources.class);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mContext.getResources()).thenReturn(mResources);
 
         mController = new ButtonNavigationSettingsAssistController(
@@ -97,4 +103,23 @@
                 Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, -1)).isEqualTo(1);
     }
 
+    @Test
+    public void onPreferenceChange_preferenceChecked_valueTrue() {
+        mController.onPreferenceChange(null, true);
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, -1)).isEqualTo(1);
+    }
+
+    @Test
+    public void onPreferenceChange_preferenceUnchecked_valueFalse() {
+        mController.onPreferenceChange(null, false);
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED, -1)).isEqualTo(0);
+    }
+
+    @Test
+    public void isAvailable_hasContextualSearchSystemFeature_shouldReturnFalse() {
+        when(mPackageManager.hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)).thenReturn(true);
+        assertThat(mController.isAvailable()).isFalse();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/gestures/NavigationSettingsContextualSearchControllerTest.java b/tests/robotests/src/com/android/settings/gestures/NavigationSettingsContextualSearchControllerTest.java
new file mode 100644
index 0000000..a4744db
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/gestures/NavigationSettingsContextualSearchControllerTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.gestures;
+
+import static android.app.contextualsearch.ContextualSearchManager.FEATURE_CONTEXTUAL_SEARCH;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.testutils.shadow.ShadowDeviceConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowDeviceConfig.class)
+public class NavigationSettingsContextualSearchControllerTest {
+
+    private static final String KEY_PRESS_HOLD_FOR_SEARCH = "search_gesture_press_hold";
+
+    private NavigationSettingsContextualSearchController mController;
+    private Context mContext;
+    private PackageManager mPackageManager;
+
+    @Before
+    public void setUp() {
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mPackageManager = mock(PackageManager.class);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        mController = new NavigationSettingsContextualSearchController(
+                mContext, KEY_PRESS_HOLD_FOR_SEARCH);
+    }
+
+    @Test
+    public void isAvailable_hasContextualSearchSystemFeature_shouldReturnTrue() {
+        when(mPackageManager.hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)).thenReturn(true);
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_doesNotHaveContextualSearchSystemFeature_shouldReturnFalse() {
+        when(mPackageManager.hasSystemFeature(FEATURE_CONTEXTUAL_SEARCH)).thenReturn(false);
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isChecked_noDefault_true() {
+        assertThat(mController.isChecked()).isTrue();
+    }
+
+    @Test
+    public void isChecked_valueFalse_shouldReturnFalse() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.SEARCH_ALL_ENTRYPOINTS_ENABLED, 0);
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void isChecked_valueTrue_shouldReturnTrue() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.SEARCH_ALL_ENTRYPOINTS_ENABLED, 1);
+        assertThat(mController.isChecked()).isTrue();
+    }
+
+    @Test
+    public void onPreferenceChange_preferenceChecked_valueTrue() {
+        mController.onPreferenceChange(null, true);
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.SEARCH_ALL_ENTRYPOINTS_ENABLED, -1)).isEqualTo(1);
+    }
+
+    @Test
+    public void onPreferenceChange_preferenceUnchecked_valueFalse() {
+        mController.onPreferenceChange(null, false);
+        assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.SEARCH_ALL_ENTRYPOINTS_ENABLED, -1)).isEqualTo(0);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysControllerTest.java
index e1b4ffd..d511edc 100644
--- a/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysControllerTest.java
+++ b/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysControllerTest.java
@@ -51,7 +51,7 @@
     public void setUp() {
         mContext = RuntimeEnvironment.application;
         mKeyboardRepeatKeysController = new KeyboardRepeatKeysController(mContext,
-                "physical_keyboard_repeat_key");
+                "physical_keyboard_repeat_keys");
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysDelayPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysDelayPreferenceControllerTest.java
new file mode 100644
index 0000000..0f2deac
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysDelayPreferenceControllerTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 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.inputmethod;
+
+import static com.android.input.flags.Flags.FLAG_KEYBOARD_REPEAT_KEYS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.hardware.input.InputSettings;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import com.android.settings.core.BasePreferenceController;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+        com.android.settings.testutils.shadow.ShadowFragment.class,
+})
+public class KeyboardRepeatKeysDelayPreferenceControllerTest {
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+    private Context mContext;
+    private KeyboardRepeatKeysDelayPreferenceController mRepeatKeysDelayPreferenceController;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mRepeatKeysDelayPreferenceController = new KeyboardRepeatKeysDelayPreferenceController(
+                mContext, "repeat_keys_delay_preference");
+    }
+
+    @Test
+    @EnableFlags(FLAG_KEYBOARD_REPEAT_KEYS)
+    public void getAvailabilityStatus_flagIsEnabled_isAvailable() {
+        assertThat(mRepeatKeysDelayPreferenceController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    @DisableFlags(FLAG_KEYBOARD_REPEAT_KEYS)
+    public void getAvailabilityStatus_flagIsDisabled_notSupport() {
+        assertThat(mRepeatKeysDelayPreferenceController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void setSliderPosition_updatesInputSettingValue() {
+        int sliderPosition = 1;
+        mRepeatKeysDelayPreferenceController.setSliderPosition(sliderPosition);
+        assertThat(InputSettings.getRepeatKeysDelay(mContext)).isEqualTo(
+                KeyboardRepeatKeysDelayPreferenceController.REPEAT_KEY_DELAY_VALUE_LIST.get(
+                        sliderPosition));
+    }
+
+    @Test
+    public void getSliderPosition_matchesWithDelayValue() {
+        int timeout = InputSettings.getRepeatKeysDelay(mContext);
+        assertThat(mRepeatKeysDelayPreferenceController.getSliderPosition()).isEqualTo(
+                KeyboardRepeatKeysDelayPreferenceController.REPEAT_KEY_DELAY_VALUE_LIST.indexOf(
+                        timeout));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysTimeOutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysTimeOutPreferenceControllerTest.java
new file mode 100644
index 0000000..f192c0c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/inputmethod/KeyboardRepeatKeysTimeOutPreferenceControllerTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 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.inputmethod;
+
+import static com.android.input.flags.Flags.FLAG_KEYBOARD_REPEAT_KEYS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.hardware.input.InputSettings;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import com.android.settings.core.BasePreferenceController;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+        com.android.settings.testutils.shadow.ShadowFragment.class,
+})
+public class KeyboardRepeatKeysTimeOutPreferenceControllerTest {
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+    private Context mContext;
+    private KeyboardRepeatKeysTimeOutPreferenceController
+            mKeyboardRepeatKeysTimeOutPreferenceController;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mKeyboardRepeatKeysTimeOutPreferenceController =
+                new KeyboardRepeatKeysTimeOutPreferenceController(mContext,
+                        "repeat_keys_timeout_preference");
+    }
+
+    @Test
+    @EnableFlags(FLAG_KEYBOARD_REPEAT_KEYS)
+    public void getAvailabilityStatus_flagIsEnabled_isAvailable() {
+        assertThat(mKeyboardRepeatKeysTimeOutPreferenceController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    @DisableFlags(FLAG_KEYBOARD_REPEAT_KEYS)
+    public void getAvailabilityStatus_flagIsDisabled_notSupport() {
+        assertThat(mKeyboardRepeatKeysTimeOutPreferenceController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+    }
+
+    @Test
+    public void setSliderPosition_updatesInputSettingValue() {
+        int sliderPosition = 1;
+        mKeyboardRepeatKeysTimeOutPreferenceController.setSliderPosition(sliderPosition);
+        assertThat(InputSettings.getRepeatKeysTimeout(mContext)).isEqualTo(
+                KeyboardRepeatKeysTimeOutPreferenceController.REPEAT_KEY_TIMEOUT_VALUE_LIST.get(
+                        sliderPosition));
+    }
+
+    @Test
+    public void getSliderPosition_matchesWithTimeoutValue() {
+        int timeout = InputSettings.getRepeatKeysTimeout(mContext);
+        assertThat(mKeyboardRepeatKeysTimeOutPreferenceController.getSliderPosition()).isEqualTo(
+                KeyboardRepeatKeysTimeOutPreferenceController.REPEAT_KEY_TIMEOUT_VALUE_LIST.indexOf(
+                        timeout));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/NetworkDashboardScreenTest.kt b/tests/robotests/src/com/android/settings/network/NetworkDashboardScreenTest.kt
new file mode 100644
index 0000000..bb80f19
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/NetworkDashboardScreenTest.kt
@@ -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.network
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.flags.Flags
+import com.android.settingslib.preference.CatalystScreenTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class NetworkDashboardScreenTest : CatalystScreenTestCase() {
+    override val preferenceScreenCreator = NetworkDashboardScreen()
+
+    override val flagName: String
+        get() = Flags.FLAG_CATALYST_NETWORK_PROVIDER_AND_INTERNET_SCREEN
+
+    @Test
+    fun key() {
+        assertThat(preferenceScreenCreator.key).isEqualTo(NetworkDashboardScreen.KEY)
+    }
+
+    override fun migration() {
+    }
+}
diff --git a/tests/robotests/testutils/com/android/settings/testutils/SystemProperty.kt b/tests/robotests/testutils/com/android/settings/testutils/SystemProperty.kt
new file mode 100644
index 0000000..9c2574e
--- /dev/null
+++ b/tests/robotests/testutils/com/android/settings/testutils/SystemProperty.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.testutils
+
+/**
+ * Helper class to override system properties.
+ *
+ * [System.setProperty] changes the static state in the JVM, which is shared by all tests. Hence,
+ * there is chance that test cases are dependent/interfered due to system property unexpectedly.
+ * This helper class backs up the old properties when invoking [override] and restore the old
+ * properties in [close] to avoid flaky testing.
+ */
+class SystemProperty(overrides: Map<String, String?> = mapOf()) : AutoCloseable {
+    private val oldProperties = mutableMapOf<String, String?>()
+
+    constructor(key: String, value: String?) : this(mapOf(key to value))
+
+    init {
+        override(overrides)
+    }
+
+    fun override(key: String, value: String?) = override(mapOf(key to value))
+
+    fun override(overrides: Map<String, String?>) {
+        // back up system properties for the overrides
+        for (key in overrides.keys) {
+            // only back up the oldest property
+            if (!oldProperties.containsKey(key)) {
+                oldProperties[key] = System.getProperty(key)
+            }
+        }
+        overrides.overrideProperties()
+    }
+
+    override fun close() {
+        // restore the backed up properties
+        oldProperties.overrideProperties()
+        oldProperties.clear()
+    }
+
+    private fun Map<String, String?>.overrideProperties() {
+        for ((key, value) in this) {
+            if (value != null) {
+                System.setProperty(key, value)
+            } else {
+                System.clearProperty(key)
+            }
+        }
+    }
+}
diff --git a/tests/spa_unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.kt
new file mode 100644
index 0000000..8524ef4
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.kt
@@ -0,0 +1,135 @@
+/*
+ * 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.deviceinfo
+
+import android.content.Context
+import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import android.telephony.TelephonyManager
+import androidx.preference.Preference
+import androidx.preference.PreferenceCategory
+import androidx.preference.PreferenceManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.R
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@RunWith(AndroidJUnit4::class)
+class PhoneNumberPreferenceControllerTest {
+
+    private val mockTelephonyManager = mock<TelephonyManager>()
+    private val mockSubscriptionManager = mock<SubscriptionManager>()
+
+    private val context: Context =
+        spy(ApplicationProvider.getApplicationContext()) {
+            on { getSystemService(SubscriptionManager::class.java) } doReturn
+                mockSubscriptionManager
+
+            on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
+        }
+
+    private val subscriptionInfo = mock<SubscriptionInfo>()
+    private val preference = spy(Preference(context))
+    private val secondPreference = mock<Preference>()
+    private var category = PreferenceCategory(context)
+    private var preferenceScreen = PreferenceManager(context).createPreferenceScreen(context)
+
+    private var controller = spy(PhoneNumberPreferenceController(context, "phone_number"))
+
+    @Before
+    fun setup() {
+        preference.setKey(controller.preferenceKey)
+        preference.isVisible = true
+        preferenceScreen.addPreference(preference)
+        category.key = "basic_info_category"
+        preferenceScreen.addPreference(category)
+
+        doReturn(secondPreference).whenever(controller).createNewPreference(context)
+    }
+
+    @Test
+    fun displayPreference_multiSim_shouldAddSecondPreference() {
+        whenever(mockTelephonyManager.phoneCount).thenReturn(2)
+
+        val sim1Preference = Preference(context)
+        category.addItemFromInflater(sim1Preference)
+        controller.displayPreference(preferenceScreen)
+
+        assertThat(category.preferenceCount).isEqualTo(2)
+    }
+
+    @Test
+    fun updateState_singleSim_shouldUpdateTitleAndPhoneNumber() {
+        val phoneNumber = "1111111111"
+        doReturn(subscriptionInfo).whenever(controller).getSubscriptionInfo(any())
+        doReturn(phoneNumber).whenever(controller).getFormattedPhoneNumber(subscriptionInfo)
+        whenever(mockTelephonyManager.phoneCount).thenReturn(1)
+        controller.displayPreference(preferenceScreen)
+
+        controller.updateState(preference)
+
+        verify(preference).title = context.getString(R.string.status_number)
+        verify(preference).summary = phoneNumber
+    }
+
+    @Test
+    fun updateState_multiSim_shouldUpdateTitleAndPhoneNumberOfMultiplePreferences() {
+        val phoneNumber = "1111111111"
+        doReturn(subscriptionInfo).whenever(controller).getSubscriptionInfo(any())
+        doReturn(phoneNumber).whenever(controller).getFormattedPhoneNumber(subscriptionInfo)
+        whenever(mockTelephonyManager.phoneCount).thenReturn(2)
+        controller.displayPreference(preferenceScreen)
+
+        controller.updateState(preference)
+
+        verify(preference).title =
+            context.getString(R.string.status_number_sim_slot, 1 /* sim slot */)
+        verify(preference).summary = phoneNumber
+        verify(secondPreference).title =
+            context.getString(R.string.status_number_sim_slot, 2 /* sim slot */)
+        verify(secondPreference).summary = phoneNumber
+    }
+
+    @Test
+    fun getSummary_cannotGetActiveSubscriptionInfo_shouldShowNotAvailable() {
+        whenever(mockSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null)
+        controller.displayPreference(preferenceScreen)
+
+        controller.updateState(preference)
+
+        verify(preference).summary = context.getString(R.string.device_info_not_available)
+    }
+
+    @Test
+    fun getSummary_getEmptySubscriptionInfo_shouldShowNotAvailable() {
+        whenever(mockSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(emptyList())
+        controller.displayPreference(preferenceScreen)
+
+        controller.updateState(preference)
+
+        verify(preference).summary = context.getString(R.string.device_info_not_available)
+    }
+}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
deleted file mode 100644
index 05e2f24..0000000
--- a/tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2017 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.deviceinfo;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.os.Looper;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceManager;
-import androidx.preference.PreferenceScreen;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.settings.R;
-import com.android.settings.testutils.ResourcesUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-public class PhoneNumberPreferenceControllerTest {
-
-    private Preference mPreference;
-    @Mock
-    private Preference mSecondPreference;
-    @Mock
-    private TelephonyManager mTelephonyManager;
-    @Mock
-    private SubscriptionInfo mSubscriptionInfo;
-    @Mock
-    private SubscriptionManager mSubscriptionManager;
-    private PreferenceCategory mCategory;
-    private PreferenceScreen mScreen;
-
-    private Context mContext;
-    private PhoneNumberPreferenceController mController;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(ApplicationProvider.getApplicationContext());
-        when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
-        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
-        mController = spy(new PhoneNumberPreferenceController(mContext, "phone_number"));
-
-        if (Looper.myLooper() == null) {
-            Looper.prepare();
-        }
-        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
-        mScreen = preferenceManager.createPreferenceScreen(mContext);
-        mPreference = spy(new Preference(mContext));
-        mPreference.setKey(mController.getPreferenceKey());
-        mPreference.setVisible(true);
-        mScreen.addPreference(mPreference);
-        final String categoryKey = "basic_info_category";
-        mCategory = new PreferenceCategory(mContext);
-        mCategory.setKey(categoryKey);
-        mScreen.addPreference(mCategory);
-
-        doReturn(mSecondPreference).when(mController).createNewPreference(mContext);
-    }
-
-    @Test
-    public void displayPreference_multiSim_shouldAddSecondPreference() {
-        when(mTelephonyManager.getPhoneCount()).thenReturn(2);
-
-        final Preference sim1Preference = new Preference(mContext);
-        mCategory.addItemFromInflater(sim1Preference);
-        mController.displayPreference(mScreen);
-
-        assertThat(mCategory.getPreferenceCount()).isEqualTo(2);
-    }
-
-    @Test
-    public void updateState_singleSim_shouldUpdateTitleAndPhoneNumber() {
-        final String phoneNumber = "1111111111";
-        doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt());
-        doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
-        when(mTelephonyManager.getPhoneCount()).thenReturn(1);
-        mController.displayPreference(mScreen);
-
-        mController.updateState(mPreference);
-
-        verify(mPreference).setTitle(ResourcesUtils.getResourcesString(mContext, "status_number"));
-        verify(mPreference).setSummary(phoneNumber);
-    }
-
-    @Test
-    public void updateState_multiSim_shouldUpdateTitleAndPhoneNumberOfMultiplePreferences() {
-        final String phoneNumber = "1111111111";
-        doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt());
-        doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
-        when(mTelephonyManager.getPhoneCount()).thenReturn(2);
-        mController.displayPreference(mScreen);
-
-        mController.updateState(mPreference);
-
-        verify(mPreference).setTitle(ResourcesUtils.getResourcesString(
-                mContext, "status_number_sim_slot", 1 /* sim slot */));
-        verify(mPreference).setSummary(phoneNumber);
-        verify(mSecondPreference).setTitle(ResourcesUtils.getResourcesString(
-                mContext, "status_number_sim_slot", 2 /* sim slot */));
-        verify(mSecondPreference).setSummary(phoneNumber);
-    }
-
-    @Test
-    public void getSummary_cannotGetActiveSubscriptionInfo_shouldShowNotAvailable() {
-        when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null);
-        mController.displayPreference(mScreen);
-
-        mController.updateState(mPreference);
-
-        verify(mPreference).setSummary(mContext.getString(R.string.device_info_not_available));
-    }
-
-    @Test
-    public void getSummary_getEmptySubscriptionInfo_shouldShowNotAvailable() {
-        List<SubscriptionInfo> infos = new ArrayList<>();
-        when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(infos);
-
-        mController.displayPreference(mScreen);
-        mController.updateState(mPreference);
-
-        verify(mPreference).setSummary(mContext.getString(R.string.device_info_not_available));
-    }
-}