Merge "Fix lcr icon direction in RTL layout" into main
diff --git a/aconfig/settings_datetime_flag_declarations.aconfig b/aconfig/settings_datetime_flag_declarations.aconfig
index 93d41d6..9951243 100644
--- a/aconfig/settings_datetime_flag_declarations.aconfig
+++ b/aconfig/settings_datetime_flag_declarations.aconfig
@@ -8,12 +8,3 @@
     description: "Enable the time feedback feature, a button to launch feedback in Date & Time Settings"
     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/res/layout/apn_preference_layout.xml b/res/layout/apn_preference_layout.xml
deleted file mode 100644
index 9b6efe7..0000000
--- a/res/layout/apn_preference_layout.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-    android:minHeight="?android:attr/listPreferredItemHeight"
-    android:focusable="false"
-    android:gravity="center_vertical">
-
-    <RelativeLayout
-        android:id="@+id/text_layout"
-        android:layout_width="0dip"
-        android:layout_height="wrap_content"
-        android:gravity="center_vertical"
-        android:layout_weight="1"
-        android:focusable="true"
-        android:clickable="true"
-        android:background="?android:attr/selectableItemBackground">
-
-        <TextView
-            android:id="@android:id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:focusable="false"
-            android:labelFor="@id/apn_radio_button_frame"
-            android:singleLine="true"
-            android:textAppearance="?android:attr/textAppearanceListItem" />
-
-        <TextView
-            android:id="@android:id/summary"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@android:id/title"
-            android:layout_alignStart="@android:id/title"
-            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
-            android:textColor="?android:attr/textColorSecondary"
-            android:focusable="false"
-            android:hyphenationFrequency="normalFast"
-            android:lineBreakWordStyle="phrase"
-            android:maxLines="2" />
-
-    </RelativeLayout>
-
-    <FrameLayout
-        android:id="@+id/apn_radio_button_frame"
-        android:layout_width="@dimen/min_tap_target_size"
-        android:layout_height="@dimen/min_tap_target_size"
-        android:layout_margin="8dp">
-
-        <RadioButton
-            android:id="@+id/apn_radiobutton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:clickable="false"
-            android:focusable="false" />
-    </FrameLayout>
-
-</LinearLayout>
diff --git a/res/layout/battery_chart_graph.xml b/res/layout/battery_chart_graph.xml
index 9e816ed..b84f38a 100644
--- a/res/layout/battery_chart_graph.xml
+++ b/res/layout/battery_chart_graph.xml
@@ -36,8 +36,7 @@
         android:id="@+id/battery_chart_group"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:alpha="0">
+        android:orientation="vertical">
         <com.android.settings.fuelgauge.batteryusage.BatteryChartView
             android:id="@+id/daily_battery_chart"
             android:layout_width="match_parent"
@@ -53,7 +52,7 @@
             android:layout_width="match_parent"
             android:layout_height="@dimen/chartview_layout_height"
             android:layout_marginBottom="16dp"
-            android:visibility="visible"
+            android:visibility="gone"
             android:contentDescription="@string/hourly_battery_usage_chart"
             android:textAppearance="?android:attr/textAppearanceSmall"
             settings:textColor="?android:attr/textColorSecondary" />
diff --git a/res/layout/display_topology_preference.xml b/res/layout/display_topology_preference.xml
index d2e4300..beaf816 100644
--- a/res/layout/display_topology_preference.xml
+++ b/res/layout/display_topology_preference.xml
@@ -16,8 +16,9 @@
 
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/display_topology_pane_holder"
     android:importantForAccessibility="no"
-    android:layout_height="160dp"
+    android:layout_height="wrap_content"
     android:layout_width="match_parent"
     android:paddingHorizontal="@dimen/display_topology_pane_margin"
     android:orientation="horizontal">
@@ -27,14 +28,14 @@
         android:layout_width="match_parent"
         android:src="@drawable/display_topology_background"/>
     <FrameLayout
-        android:id="@+id/display_topology_container"
+        android:id="@+id/display_topology_pane_content"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"/>
+        android:layout_height="match_parent"/>
     <TextView
         android:id="@+id/topology_hint"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         android:layout_gravity="top|center_horizontal"
-        android:paddingTop="10dp"
-        android:text="@string/external_display_topology_hint"/>
+        android:paddingBottom="10dp"
+        android:paddingTop="10dp" />
 </FrameLayout>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 200253a..87c3ce9 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -50,8 +50,6 @@
         <attr name="android:textAppearance" />
     </declare-styleable>
 
-    <attr name="apnPreferenceStyle" format="reference" />
-
     <attr name="slicePreferenceStyle" format="reference" />
 
     <attr name="cardPreferenceStyle" format="reference" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8faf62a..89f6d8f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4514,6 +4514,8 @@
     <string name="language_settings">Languages&#160;&amp; input</string>
     <!-- Title of setting on main settings screen.  This item will take the user to the screen to tweak settings related to languages -->
     <string name="languages_settings">Languages</string>
+    <!-- Title of setting on main settings screen.  This item will take the user to the screen to tweak settings related to language and region-->
+    <string name="language_and_region_settings">Language &amp; region</string>
     <!-- Title of setting on main settings screen.  This item will take the user to the screen to tweak settings related to keyboards -->
     <string name="keyboard_settings">Keyboard</string>
     <!-- Text displayed when user has restriction DISALLOW_CONFIG_LOCALE [CHAR LIMIT=NONE]-->
diff --git a/res/values/styles_preference.xml b/res/values/styles_preference.xml
index ec0a747..c7638d3 100644
--- a/res/values/styles_preference.xml
+++ b/res/values/styles_preference.xml
@@ -20,7 +20,6 @@
 <resources>
 
     <style name="SettingsPreferenceTheme" parent="@style/PreferenceTheme.SettingsLib">
-        <item name="apnPreferenceStyle">@style/ApnPreference</item>
         <item name="cardPreferenceStyle">@style/CardPreference</item>
         <item name="slicePreferenceStyle">@style/SlicePreference</item>
         <item name="seekBarPreferenceStyle">@style/SettingsSeekBarPreference</item>
@@ -32,10 +31,6 @@
         <item name="preferenceFragmentCompatStyle">@style/SetupWizardPreferenceFragmentStyle</item>
     </style>
 
-    <style name="ApnPreference" parent="@style/Preference.Material">
-        <item name="android:layout">@layout/apn_preference_layout</item>
-    </style>
-
     <style name="CardPreference" parent="@style/Preference.Material">
         <item name="android:layout">@layout/card_preference_layout</item>
     </style>
diff --git a/res/values/styles_preference_expressive.xml b/res/values/styles_preference_expressive.xml
index a6fe2f1..278fe00 100644
--- a/res/values/styles_preference_expressive.xml
+++ b/res/values/styles_preference_expressive.xml
@@ -20,7 +20,6 @@
 <resources>
 
     <style name="SettingsPreferenceTheme.Expressive" parent="@style/PreferenceTheme.SettingsLib.Expressive">
-        <item name="apnPreferenceStyle">@style/ApnPreference</item>
         <item name="cardPreferenceStyle">@style/CardPreference</item>
         <item name="slicePreferenceStyle">@style/SlicePreference</item>
         <item name="seekBarPreferenceStyle">@style/SettingsSeekBarPreference</item>
diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml
index 779555b..f491055 100644
--- a/res/xml/connected_devices_advanced.xml
+++ b/res/xml/connected_devices_advanced.xml
@@ -42,7 +42,7 @@
         android:order="-7"
         android:title="@string/nfc_quick_toggle_title"
         settings:controller="com.android.settings.connecteddevice.NfcAndPaymentFragmentController"
-        settings:searchable="false"
+        settings:searchable="true"
         settings:useAdminDisabledSummary="true"
         settings:userRestriction="no_near_field_communication_radio" />
 
diff --git a/res/xml/date_time_prefs.xml b/res/xml/date_time_prefs.xml
index d8643be..fe0fd7e 100644
--- a/res/xml/date_time_prefs.xml
+++ b/res/xml/date_time_prefs.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
@@ -94,10 +94,6 @@
         android:key="time_format_preference_category"
         android:title="@string/time_format_category_title"
         settings:keywords="@string/keywords_time_format">
-        <SwitchPreferenceCompat
-            android:key="auto_24hour"
-            android:title="@string/date_time_24hour_auto"
-            settings:controller="com.android.settings.datetime.AutoTimeFormatPreferenceController" />
 
         <SwitchPreferenceCompat
             android:key="24 hour"
diff --git a/res/xml/date_time_prefs_revamped.xml b/res/xml/date_time_prefs_revamped.xml
deleted file mode 100644
index fe0fd7e..0000000
--- a/res/xml/date_time_prefs_revamped.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-<?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/language_and_region_settings.xml b/res/xml/language_and_region_settings.xml
new file mode 100644
index 0000000..5626f22
--- /dev/null
+++ b/res/xml/language_and_region_settings.xml
@@ -0,0 +1,127 @@
+<?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/language_and_region_settings"
+    android:key="language_and_region_settings">
+  <PreferenceCategory
+      android:key="languages_category"
+      android:title="@string/locale_picker_category_title">
+    <Preference
+        android:key="phone_language"
+        android:title="@string/system_language"
+        android:fragment="com.android.settings.localepicker.LocaleListEditor"
+        settings:controller="com.android.settings.language.PhoneLanguagePreferenceController" />
+  </PreferenceCategory>
+
+  <PreferenceCategory
+      android:key="more_language_settings_category"
+      android:title="@string/more_language_settings_category"
+      settings:controller="com.android.settings.language.MoreLanguagesSettingsCategoryController">
+    <Preference
+        android:key="apps_language_in_more_language_settings"
+        android:title="@string/app_locales_picker_menu_title"
+        android:summary="@string/app_locale_picker_summary"
+        android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
+        settings:controller="com.android.settings.applications.appinfo.NewAppsLocalePreferenceController">
+      <extra
+          android:name="classname"
+          android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
+    </Preference>
+  </PreferenceCategory>
+
+  <PreferenceCategory
+      android:key="regional_preferences_category"
+      android:title="@string/regional_preferences_category_title"
+      settings:controller="com.android.settings.regionalpreferences.RegionalPreferencesCategoryController">
+
+    <Preference
+        android:key="temperature_preference"
+        android:title="@string/temperature_preferences_title"
+        android:summary="@string/default_string_of_regional_preference"
+        settings:controller="com.android.settings.regionalpreferences.NewTemperatureUnitController"
+        settings:fragment="com.android.settings.regionalpreferences.TemperatureUnitFragment">
+      <extra
+          android:name="arg_key_regional_preference"
+          android:value="mu"/>
+    </Preference>
+
+    <Preference
+        android:key="key_measurement_system"
+        android:title="@string/measurement_system_preferences_title"
+        android:summary="@string/default_string_of_regional_preference"
+        settings:controller="com.android.settings.regionalpreferences.MeasurementSystemController"
+        settings:fragment="com.android.settings.regionalpreferences.MeasurementSystemItemFragment">
+      <extra
+          android:name="arg_key_regional_preference"
+          android:value="ms"/>
+    </Preference>
+
+    <Preference
+        android:key="first_day_of_week_preference"
+        android:title="@string/first_day_of_week_preferences_title"
+        android:summary="@string/default_string_of_regional_preference"
+        settings:controller="com.android.settings.regionalpreferences.NewFirstDayOfWeekController"
+        settings:fragment="com.android.settings.regionalpreferences.FirstDayOfWeekItemFragment">
+      <extra
+          android:name="arg_key_regional_preference"
+          android:value="fw"/>
+    </Preference>
+
+    <Preference
+        android:key="numbering_system_preference"
+        android:title="@string/numbers_preferences_title"
+        android:summary="@string/default_string_of_regional_preference"
+        settings:controller="com.android.settings.regionalpreferences.NewNumberingSystemController"
+        settings:fragment="com.android.settings.regionalpreferences.NumberingPreferencesFragment">
+      <extra
+          android:name="arg_key_regional_preference"
+          android:value="arg_value_language_select"/>
+    </Preference>
+  </PreferenceCategory>
+
+  <PreferenceCategory
+      android:key="speech_category"
+      android:title="@string/speech_category_title">
+    <com.android.settings.widget.GearPreference
+        android:key="voice_input_settings"
+        android:title="@string/voice_input_settings_title"
+        android:fragment="com.android.settings.language.DefaultVoiceInputPicker" />
+
+    <Preference
+        android:key="on_device_recognition_settings"
+        android:title="@string/on_device_recognition_settings_title"
+        android:summary="@string/on_device_recognition_settings_summary"
+        settings:controller=
+            "com.android.settings.language.OnDeviceRecognitionPreferenceController" />
+
+    <Preference
+        android:key="tts_settings_summary"
+        android:title="@string/tts_settings_title"
+        android:fragment="com.android.settings.tts.TextToSpeechSettings"
+        settings:searchable="false"/>
+  </PreferenceCategory>
+
+  <com.android.settingslib.widget.FooterPreference
+      android:key="new_regional_pref_footer"
+      android:title="@string/title_regional_pref_footer"
+      android:selectable="false"
+      settings:searchable="false"
+      settings:controller="com.android.settings.regionalpreferences.NewRegionalFooterPreferenceController"/>
+</PreferenceScreen>
diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml
index 44a195c..eccbbc1 100644
--- a/res/xml/language_settings.xml
+++ b/res/xml/language_settings.xml
@@ -50,72 +50,6 @@
     </PreferenceCategory>
 
     <PreferenceCategory
-        android:key="more_language_settings_category"
-        android:title="@string/more_language_settings_category"
-        settings:controller="com.android.settings.language.MoreLanguagesSettingsCategoryController">
-        <Preference
-            android:key="apps_language_in_more_language_settings"
-            android:title="@string/app_locales_picker_menu_title"
-            android:summary="@string/app_locale_picker_summary"
-            android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
-            settings:controller="com.android.settings.applications.appinfo.NewAppsLocalePreferenceController">
-            <extra
-                android:name="classname"
-                android:value="com.android.settings.applications.appinfo.AppLocaleDetails" />
-        </Preference>
-    </PreferenceCategory>
-
-    <PreferenceCategory
-        android:key="regional_preferences_category"
-        android:title="@string/regional_preferences_category_title"
-        settings:controller="com.android.settings.regionalpreferences.RegionalPreferencesCategoryController">
-
-        <Preference
-            android:key="temperature_preference"
-            android:title="@string/temperature_preferences_title"
-            android:summary="@string/default_string_of_regional_preference"
-            settings:controller="com.android.settings.regionalpreferences.NewTemperatureUnitController"
-            settings:fragment="com.android.settings.regionalpreferences.TemperatureUnitFragment">
-            <extra
-                android:name="arg_key_regional_preference"
-                android:value="mu"/>
-        </Preference>
-
-        <Preference
-            android:key="key_measurement_system"
-            android:title="@string/measurement_system_preferences_title"
-            android:summary="@string/default_string_of_regional_preference"
-            settings:controller="com.android.settings.regionalpreferences.MeasurementSystemController"
-            settings:fragment="com.android.settings.regionalpreferences.MeasurementSystemItemFragment">
-            <extra
-                android:name="arg_key_regional_preference"
-                android:value="ms"/>
-        </Preference>
-
-        <Preference
-            android:key="first_day_of_week_preference"
-            android:title="@string/first_day_of_week_preferences_title"
-            android:summary="@string/default_string_of_regional_preference"
-            settings:controller="com.android.settings.regionalpreferences.NewFirstDayOfWeekController"
-            settings:fragment="com.android.settings.regionalpreferences.FirstDayOfWeekItemFragment">
-            <extra
-                android:name="arg_key_regional_preference"
-                android:value="fw"/>
-        </Preference>
-
-        <Preference
-            android:key="numbering_system_preference"
-            android:title="@string/numbers_preferences_title"
-            android:summary="@string/default_string_of_regional_preference"
-            settings:controller="com.android.settings.regionalpreferences.NewNumberingSystemController"
-            settings:fragment="com.android.settings.regionalpreferences.NumberingPreferencesFragment">
-            <extra
-                android:name="arg_key_regional_preference"
-                android:value="arg_value_language_select"/>
-        </Preference>
-    </PreferenceCategory>
-
-    <PreferenceCategory
         android:key="speech_category"
         android:title="@string/speech_category_title">
         <com.android.settings.widget.GearPreference
@@ -136,11 +70,4 @@
             android:fragment="com.android.settings.tts.TextToSpeechSettings"
             settings:searchable="false"/>
     </PreferenceCategory>
-
-    <com.android.settingslib.widget.FooterPreference
-        android:key="new_regional_pref_footer"
-        android:title="@string/title_regional_pref_footer"
-        android:selectable="false"
-        settings:searchable="false"
-        settings:controller="com.android.settings.regionalpreferences.NewRegionalFooterPreferenceController"/>
 </PreferenceScreen>
diff --git a/res/xml/system_dashboard_fragment.xml b/res/xml/system_dashboard_fragment.xml
index 9c7f001..a9d7444 100644
--- a/res/xml/system_dashboard_fragment.xml
+++ b/res/xml/system_dashboard_fragment.xml
@@ -30,6 +30,15 @@
         settings:controller="com.android.settings.language.LanguagePreferenceController"/>
 
     <Preference
+        android:key="language_and_region_settings"
+        android:title="@string/language_and_region_settings"
+        android:summary="@string/languages_setting_summary"
+        android:icon="@drawable/ic_settings_languages"
+        android:order="-260"
+        android:fragment="com.android.settings.language.LanguageAndRegionSettings"
+        settings:controller="com.android.settings.language.LanguageAndRegionPreferenceController"/>
+
+    <Preference
         android:key="Keyboard_settings"
         android:title="@string/keyboard_settings"
         android:icon="@drawable/ic_settings_keyboards"
diff --git a/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java b/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
index 09e2d97..3bda864 100644
--- a/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityHearingAidsFragment.java
@@ -97,17 +97,6 @@
     }
 
     @Override
-    protected ComponentName getTileComponentName() {
-        return AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_TILE_COMPONENT_NAME;
-    }
-
-    @Override
-    protected CharSequence getTileTooltipContent(int type) {
-        // No tooltip to be shown
-        return null;
-    }
-
-    @Override
     protected boolean showGeneralCategory() {
         // Have static preference under dynamically created PreferenceCategory KEY_GENERAL_CATEGORY.
         // In order to modify that, we need to use our own PreferenceCategory for this page.
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
index 23c3fd4..2a22902 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -20,10 +20,8 @@
 import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
 import static com.android.settings.accessibility.AccessibilityUtil.getShortcutSummaryList;
 import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.KEY_GENERAL_CATEGORY;
-import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.KEY_SAVED_QS_TOOLTIP_TYPE;
 
 import android.annotation.SuppressLint;
-import android.app.Activity;
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
@@ -44,7 +42,6 @@
 
 import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.settings.R;
-import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
 import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment;
 import com.android.settings.dashboard.RestrictedDashboardFragment;
 
@@ -60,16 +57,12 @@
 public abstract class AccessibilityShortcutPreferenceFragment extends RestrictedDashboardFragment
         implements ShortcutPreference.OnClickCallback {
     private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
-    protected static final String KEY_SAVED_QS_TOOLTIP_RESHOW = "qs_tooltip_reshow";
 
     protected ShortcutPreference mShortcutPreference;
     protected Dialog mDialog;
     private AccessibilityManager.TouchExplorationStateChangeListener
             mTouchExplorationStateChangeListener;
     private AccessibilitySettingsContentObserver mSettingsContentObserver;
-    private AccessibilityQuickSettingsTooltipWindow mTooltipWindow;
-    private boolean mNeedsQSTooltipReshow = false;
-    private int mNeedsQSTooltipType = QuickSettingsTooltipType.GUIDE_TO_EDIT;
 
     public AccessibilityShortcutPreferenceFragment(String restrictionKey) {
         super(restrictionKey);
@@ -81,26 +74,10 @@
     /** Returns the accessibility feature name. */
     protected abstract CharSequence getLabelName();
 
-    /** Returns the accessibility tile component name. */
-    protected abstract ComponentName getTileComponentName();
-
-    /** Returns the accessibility tile tooltip content. */
-    protected abstract CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type);
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        // Restore the user shortcut type and tooltip.
-        if (savedInstanceState != null) {
-            if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_RESHOW)) {
-                mNeedsQSTooltipReshow = savedInstanceState.getBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW);
-            }
-            if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_TYPE)) {
-                mNeedsQSTooltipType = savedInstanceState.getInt(KEY_SAVED_QS_TOOLTIP_TYPE);
-            }
-        }
-
         final int resId = getPreferenceScreenResId();
         if (resId <= 0) {
             final PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
@@ -142,21 +119,6 @@
     }
 
     @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-
-        // Reshow tooltip when activity recreate, such as rotate device.
-        if (mNeedsQSTooltipReshow) {
-            view.post(() -> {
-                final Activity activity = getActivity();
-                if (activity != null && !activity.isFinishing()) {
-                    showQuickSettingsTooltipIfNeeded();
-                }
-            });
-        }
-    }
-
-    @Override
     public void onResume() {
         super.onResume();
 
@@ -178,16 +140,6 @@
     }
 
     @Override
-    public void onSaveInstanceState(Bundle outState) {
-        final boolean isTooltipWindowShowing = mTooltipWindow != null && mTooltipWindow.isShowing();
-        if (mNeedsQSTooltipReshow || isTooltipWindowShowing) {
-            outState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, /* value= */ true);
-            outState.putInt(KEY_SAVED_QS_TOOLTIP_TYPE, mNeedsQSTooltipType);
-        }
-        super.onSaveInstanceState(outState);
-    }
-
-    @Override
     public Dialog onCreateDialog(int dialogId) {
         switch (dialogId) {
             case DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
@@ -289,7 +241,6 @@
      */
     private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
         dialog.dismiss();
-        showQuickSettingsTooltipIfNeeded();
     }
 
     @VisibleForTesting
@@ -363,26 +314,6 @@
     }
 
     /**
-     * Shows the quick settings tooltip if the quick settings feature is assigned. The tooltip only
-     * shows once.
-     *
-     * @param type The quick settings tooltip type
-     */
-    protected void showQuickSettingsTooltipIfNeeded(@QuickSettingsTooltipType int type) {
-        mNeedsQSTooltipType = type;
-        showQuickSettingsTooltipIfNeeded();
-    }
-
-    /**
-     * @deprecated made obsolete by quick settings rollout.
-     *
-     * (TODO 367414968: finish removal.)
-     */
-    @Deprecated
-    private void showQuickSettingsTooltipIfNeeded() {
-    }
-
-    /**
      * Returns the user preferred shortcut types or the default shortcut types if not set
      */
     @ShortcutConstants.UserShortcutType
diff --git a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
index e49078b..f729cc7 100644
--- a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
@@ -72,11 +72,6 @@
     }
 
     @Override
-    protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
-        // Do nothing.
-    }
-
-    @Override
     protected void onProcessArguments(Bundle arguments) {
         super.onProcessArguments(arguments);
         mComponentName = arguments.getParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME);
diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
index e286225..b779f9d 100644
--- a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
@@ -107,10 +107,6 @@
         if (enabled == isEnabled) {
             return;
         }
-
-        if (enabled) {
-            showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
-        }
         logAccessibilityServiceEnabled(mComponentName, enabled);
         Settings.Secure.putInt(getContentResolver(), ENABLED, enabled ? ON : OFF);
     }
diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
index 5b2df5a..fe51e69 100644
--- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
@@ -158,10 +158,6 @@
         if (enabled == isEnabled) {
             return;
         }
-
-        if (enabled) {
-            showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
-        }
         logAccessibilityServiceEnabled(mComponentName, enabled);
         Settings.Secure.putInt(getContentResolver(), ENABLED, enabled ? ON : OFF);
     }
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 65a1cd4..49f22bf 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -21,7 +21,6 @@
 import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
 import static com.android.settings.accessibility.AccessibilityUtil.getShortcutSummaryList;
 
-import android.app.Activity;
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
@@ -85,8 +84,6 @@
     public static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
     protected static final String KEY_TOP_INTRO_PREFERENCE = "top_intro";
     protected static final String KEY_HTML_DESCRIPTION_PREFERENCE = "html_description";
-    protected static final String KEY_SAVED_QS_TOOLTIP_RESHOW = "qs_tooltip_reshow";
-    protected static final String KEY_SAVED_QS_TOOLTIP_TYPE = "qs_tooltip_type";
     protected static final String KEY_ANIMATED_IMAGE = "animated_image";
     // For html description of accessibility service, must follow the rule, such as
     // <img src="R.drawable.fileName"/>, a11y settings will get the resources successfully.
@@ -112,10 +109,6 @@
     private CharSequence mDescription;
     private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
     private AccessibilitySettingsContentObserver mSettingsContentObserver;
-
-    private AccessibilityQuickSettingsTooltipWindow mTooltipWindow;
-    private boolean mNeedsQSTooltipReshow = false;
-    private int mNeedsQSTooltipType = QuickSettingsTooltipType.GUIDE_TO_EDIT;
     private ImageView mImageGetterCacheView;
     protected final Html.ImageGetter mImageGetter = (String str) -> {
         if (str != null && str.startsWith(IMG_PREFIX)) {
@@ -133,16 +126,6 @@
         super.onCreate(savedInstanceState);
 
         onProcessArguments(getArguments());
-        // Restore the user shortcut type and tooltip.
-        if (savedInstanceState != null) {
-            if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_RESHOW)) {
-                mNeedsQSTooltipReshow = savedInstanceState.getBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW);
-            }
-            if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_TYPE)) {
-                mNeedsQSTooltipType = savedInstanceState.getInt(KEY_SAVED_QS_TOOLTIP_TYPE);
-            }
-        }
-
         final int resId = getPreferenceScreenResId();
         if (resId <= 0) {
             final PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
@@ -227,16 +210,6 @@
         final SettingsMainSwitchBar switchBar = settingsActivity.getSwitchBar();
         switchBar.hide();
 
-        // Reshow tooltip when activity recreate, such as rotate device.
-        if (mNeedsQSTooltipReshow) {
-            view.post(() -> {
-                final Activity activity = getActivity();
-                if (activity != null && !activity.isFinishing()) {
-                    showQuickSettingsTooltipIfNeeded();
-                }
-            });
-        }
-
         writeConfigDefaultAccessibilityServiceIntoShortcutTargetServiceIfNeeded(getContext());
     }
 
@@ -262,23 +235,9 @@
     }
 
     @Override
-    public void onSaveInstanceState(Bundle outState) {
-        final boolean isTooltipWindowShowing = mTooltipWindow != null && mTooltipWindow.isShowing();
-        if (mNeedsQSTooltipReshow || isTooltipWindowShowing) {
-            outState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, /* value= */ true);
-            outState.putInt(KEY_SAVED_QS_TOOLTIP_TYPE, mNeedsQSTooltipType);
-        }
-        super.onSaveInstanceState(outState);
-    }
-
-    @Override
     public void onDestroyView() {
         super.onDestroyView();
         removeActionBarToggleSwitch();
-        final boolean isTooltipWindowShowing = mTooltipWindow != null && mTooltipWindow.isShowing();
-        if (isTooltipWindowShowing) {
-            mTooltipWindow.dismiss();
-        }
     }
 
     @Override
@@ -314,7 +273,12 @@
     /** Returns the accessibility tile component name. */
     abstract ComponentName getTileComponentName();
 
-    /** Returns the accessibility tile tooltip content. */
+    /** Returns the accessibility tile component name.
+     *
+     * @deprecated unused, as this class no longer displays tile tooltips.
+     *
+     * (TODO 367414968: finish removal.)*/
+    @Deprecated
     abstract CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type);
 
     protected void updateToggleServiceTitle(SettingsMainSwitchPreference switchPreference) {
@@ -332,9 +296,6 @@
     }
 
     protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
-        if (enabled) {
-            showQuickSettingsTooltipIfNeeded();
-        }
     }
 
     protected void onInstallSwitchPreferenceToggleSwitch() {
@@ -646,7 +607,6 @@
      */
     private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
         dialog.dismiss();
-        showQuickSettingsTooltipIfNeeded();
     }
 
     protected void updateShortcutPreferenceData() {
@@ -737,26 +697,6 @@
         }
     }
 
-    /**
-     * Shows the quick settings tooltip if the quick settings feature is assigned. The tooltip only
-     * shows once.
-     *
-     * @param type The quick settings tooltip type
-     */
-    protected void showQuickSettingsTooltipIfNeeded(@QuickSettingsTooltipType int type) {
-        mNeedsQSTooltipType = type;
-        showQuickSettingsTooltipIfNeeded();
-    }
-
-    /**
-     * @deprecated made obsolete by quick settings rollout.
-     *
-     * (TODO 367414968: finish removal.)
-     */
-    @Deprecated
-    private void showQuickSettingsTooltipIfNeeded() {
-    }
-
     /** Returns user visible name of the tile by given {@link ComponentName}. */
     protected CharSequence loadTileLabel(Context context, ComponentName componentName) {
         final PackageManager packageManager = context.getPackageManager();
diff --git a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
index 16911f6..ff14021 100644
--- a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
@@ -149,9 +149,6 @@
 
     @Override
     protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
-        if (enabled) {
-            showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
-        }
         logAccessibilityServiceEnabled(mComponentName, enabled);
         mColorDisplayManager.setReduceBrightColorsActivated(enabled);
     }
diff --git a/src/com/android/settings/connecteddevice/display/DisplayTopology.kt b/src/com/android/settings/connecteddevice/display/DisplayTopology.kt
index 76abc03..9cac772 100644
--- a/src/com/android/settings/connecteddevice/display/DisplayTopology.kt
+++ b/src/com/android/settings/connecteddevice/display/DisplayTopology.kt
@@ -16,14 +16,32 @@
 
 package com.android.settings.connecteddevice.display
 
+import android.app.WallpaperManager
 import com.android.settings.R
 
 import android.content.Context
+import android.graphics.Color
 import android.graphics.Point
 import android.graphics.PointF
 import android.graphics.RectF
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.ColorDrawable
+import android.hardware.display.DisplayManager
+import android.hardware.display.DisplayTopology
+import android.hardware.display.DisplayTopology.TreeNode.POSITION_BOTTOM
+import android.hardware.display.DisplayTopology.TreeNode.POSITION_LEFT
+import android.hardware.display.DisplayTopology.TreeNode.POSITION_RIGHT
+import android.hardware.display.DisplayTopology.TreeNode.POSITION_TOP
+import android.util.Log
+import android.view.ViewGroup
+import android.view.ViewTreeObserver
+import android.widget.Button
+import android.widget.FrameLayout
+import android.widget.TextView
 
+import androidx.annotation.VisibleForTesting
 import androidx.preference.Preference
+import androidx.preference.PreferenceViewHolder
 
 import java.util.Locale
 
@@ -143,11 +161,27 @@
 
 const val PREFERENCE_KEY = "display_topology_preference"
 
+/** dp of padding on each side of a display block. */
+const val BLOCK_PADDING = 2
+
 /**
  * DisplayTopologyPreference allows the user to change the display topology
  * when there is one or more extended display attached.
  */
-class DisplayTopologyPreference(context : Context) : Preference(context) {
+class DisplayTopologyPreference(context : Context)
+        : Preference(context), ViewTreeObserver.OnGlobalLayoutListener {
+    @VisibleForTesting lateinit var mPaneContent : FrameLayout
+    @VisibleForTesting lateinit var mPaneHolder : FrameLayout
+    @VisibleForTesting lateinit var mTopologyHint : TextView
+
+    @VisibleForTesting var injector : Injector
+
+    /**
+     * This is needed to prevent a repopulation of the pane causing another
+     * relayout and vice-versa ad infinitum.
+     */
+    private var mPaneNeedsRefresh = false
+
     init {
         layoutResource = R.layout.display_topology_preference
 
@@ -155,5 +189,108 @@
         isSelectable = false
 
         key = PREFERENCE_KEY
+
+        injector = Injector()
+    }
+
+    override fun onBindViewHolder(holder: PreferenceViewHolder) {
+        super.onBindViewHolder(holder)
+
+        val newPane = holder.findViewById(R.id.display_topology_pane_content) as FrameLayout
+        if (this::mPaneContent.isInitialized) {
+            if (newPane == mPaneContent) {
+                return
+            }
+            mPaneContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
+        }
+        mPaneContent = newPane
+        mPaneHolder = holder.itemView as FrameLayout
+        mTopologyHint = holder.findViewById(R.id.topology_hint) as TextView
+        mPaneContent.viewTreeObserver.addOnGlobalLayoutListener(this)
+    }
+
+    override fun onAttached() {
+        // We don't know if topology changes happened when we were detached, as it is impossible to
+        // listen at that time (we must remove listeners when detaching). Setting this flag makes
+        // the following onGlobalLayout call refresh the pane.
+        mPaneNeedsRefresh = true
+    }
+
+    override fun onGlobalLayout() {
+        if (mPaneNeedsRefresh) {
+            mPaneNeedsRefresh = false
+            refreshPane()
+        }
+    }
+
+    open class Injector {
+        open fun displayTopology(context : Context) : DisplayTopology? {
+            val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+            return displayManager.displayTopology
+        }
+
+        open fun wallpaper(context : Context) : Drawable {
+            return WallpaperManager.getInstance(context).drawable ?: ColorDrawable(Color.BLACK)
+        }
+    }
+
+    private fun calcAbsRects(
+            dest : MutableMap<Int, RectF>, n : DisplayTopology.TreeNode, x : Float, y : Float) {
+        dest.put(n.displayId, RectF(x, y, x + n.width, y + n.height))
+
+        for (c in n.children) {
+            val (xoff, yoff) = when (c.position) {
+                POSITION_LEFT -> Pair(-c.width, +c.offset)
+                POSITION_RIGHT -> Pair(+n.width, +c.offset)
+                POSITION_TOP -> Pair(+c.offset, -c.height)
+                POSITION_BOTTOM -> Pair(+c.offset, +n.height)
+                else -> throw IllegalStateException("invalid position for display: ${c}")
+            }
+            calcAbsRects(dest, c, x + xoff, y + yoff)
+        }
+    }
+
+    private fun refreshPane() {
+        mPaneContent.removeAllViews()
+
+        val root = injector.displayTopology(context)?.root
+        if (root == null) {
+            // This occurs when no topology is active.
+            // TODO(b/352648432): show main display or mirrored displays rather than an empty pane.
+            mTopologyHint.text = ""
+            return
+        }
+        mTopologyHint.text = context.getString(R.string.external_display_topology_hint)
+
+        val blocksPos = buildMap { calcAbsRects(this, root, x = 0f, y = 0f) }
+
+        val scaling = TopologyScale(
+                mPaneContent.width, minEdgeLength = 60, maxBlockRatio = 0.12f, blocksPos.values)
+        mPaneHolder.layoutParams.let {
+            if (it.height != scaling.paneHeight) {
+                it.height = scaling.paneHeight
+                mPaneHolder.layoutParams = it
+            }
+        }
+        val wallpaper = injector.wallpaper(context)
+        blocksPos.values.forEach { p ->
+            Button(context).apply {
+                isScrollContainer = false
+                isVerticalScrollBarEnabled = false
+                isHorizontalScrollBarEnabled = false
+                background = wallpaper
+                val topLeft = scaling.displayToPaneCoor(PointF(p.left, p.top))
+                val bottomRight = scaling.displayToPaneCoor(PointF(p.right, p.bottom))
+
+                mPaneContent.addView(this)
+
+                val layout = layoutParams
+                layout.width = bottomRight.x - topLeft.x - BLOCK_PADDING * 2
+                layout.height = bottomRight.y - topLeft.y - BLOCK_PADDING * 2
+                layoutParams = layout
+                x = (topLeft.x + BLOCK_PADDING).toFloat()
+                y = (topLeft.y + BLOCK_PADDING).toFloat()
+            }
+        }
     }
 }
diff --git a/src/com/android/settings/datetime/AutoTimeFormatPreferenceController.java b/src/com/android/settings/datetime/AutoTimeFormatPreferenceController.java
deleted file mode 100644
index 44e7cc6..0000000
--- a/src/com/android/settings/datetime/AutoTimeFormatPreferenceController.java
+++ /dev/null
@@ -1,73 +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.datetime;
-
-import android.content.Context;
-import android.provider.Settings;
-import android.provider.Settings.System;
-import android.text.format.DateFormat;
-
-import com.android.settings.R;
-import com.android.settings.core.TogglePreferenceController;
-
-import java.util.Locale;
-
-public class AutoTimeFormatPreferenceController extends TogglePreferenceController {
-
-    public AutoTimeFormatPreferenceController(Context context, String preferenceKey) {
-        super(context, preferenceKey);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return AVAILABLE;
-    }
-
-    @Override
-    public boolean isChecked() {
-        return isAutoTimeFormatSelection(mContext);
-    }
-
-    @Override
-    public boolean setChecked(boolean isChecked) {
-        Boolean is24Hour;
-        if (isChecked) {
-            is24Hour = null;
-        } else {
-            is24Hour = is24HourLocale(mContext.getResources().getConfiguration().locale);
-        }
-        TimeFormatPreferenceController.update24HourFormat(mContext, is24Hour);
-        return true;
-    }
-
-    @Override
-    public int getSliceHighlightMenuRes() {
-        return R.string.menu_key_system;
-    }
-
-    boolean is24HourLocale(Locale locale) {
-        return DateFormat.is24HourLocale(locale);
-    }
-
-    /**
-     * Returns if the system is currently configured to pick the time format automatically based on
-     * the locale.
-     */
-    static boolean isAutoTimeFormatSelection(Context context) {
-        return Settings.System.getString(context.getContentResolver(), System.TIME_12_24) == null;
-    }
-}
diff --git a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java
index 3d8f801..ecd416d 100644
--- a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java
+++ b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java
@@ -32,7 +32,6 @@
 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 {
 
@@ -107,19 +106,17 @@
         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();
+        // "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);
-            }
+        if (!isChecked
+                && (geoDetectionCapability == CAPABILITY_NOT_APPLICABLE
+                || geoDetectionCapability == CAPABILITY_POSSESSED)) {
+            configuration.setGeoDetectionEnabled(false);
         }
 
         boolean result = mTimeManager.updateTimeZoneConfiguration(configuration.build());
diff --git a/src/com/android/settings/datetime/DateTimeSettings.java b/src/com/android/settings/datetime/DateTimeSettings.java
index e5c13bf..f3c11d4 100644
--- a/src/com/android/settings/datetime/DateTimeSettings.java
+++ b/src/com/android/settings/datetime/DateTimeSettings.java
@@ -23,7 +23,6 @@
 
 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;
 
@@ -50,9 +49,6 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        if (Flags.revampToggles()) {
-            return R.xml.date_time_prefs_revamped;
-        }
         return R.xml.date_time_prefs;
     }
 
@@ -123,6 +119,5 @@
     }
 
     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(
-                    Flags.revampToggles() ? R.xml.date_time_prefs_revamped : R.xml.date_time_prefs);
+            new BaseSearchIndexProvider(R.xml.date_time_prefs);
 }
diff --git a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
index 52d49ac..d475d9d 100644
--- a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
+++ b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
@@ -32,7 +32,6 @@
 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;
@@ -68,7 +67,7 @@
         // forceRefresh set to true as the location toggle may have been turned off by switching off
         // automatic time zone
         TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
-                getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/ Flags.revampToggles());
+                getTimeZoneCapabilitiesAndConfig(/*forceRefresh=*/ true);
         TimeZoneConfiguration configuration = capabilitiesAndConfig.getConfiguration();
         return configuration.isGeoDetectionEnabled();
     }
@@ -137,11 +136,7 @@
         if (capability == CAPABILITY_NOT_SUPPORTED || capability == CAPABILITY_NOT_ALLOWED) {
             return UNSUPPORTED_ON_DEVICE;
         } else if (capability == CAPABILITY_NOT_APPLICABLE || capability == CAPABILITY_POSSESSED) {
-            if (Flags.revampToggles()) {
-                return isAutoTimeZoneEnabled() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
-            } else {
-                return AVAILABLE;
-            }
+            return isAutoTimeZoneEnabled() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
         } else {
             throw new IllegalStateException("Unknown capability=" + capability);
         }
@@ -151,10 +146,8 @@
     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());
-        }
+        // enable / disable the toggle based on automatic time zone being enabled or not
+        preference.setEnabled(isAutoTimeZoneEnabled());
     }
 
     @Override
diff --git a/src/com/android/settings/datetime/TimeFormatPreferenceController.java b/src/com/android/settings/datetime/TimeFormatPreferenceController.java
index 2dee76e..c400f4e 100644
--- a/src/com/android/settings/datetime/TimeFormatPreferenceController.java
+++ b/src/com/android/settings/datetime/TimeFormatPreferenceController.java
@@ -25,7 +25,6 @@
 
 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;
@@ -73,11 +72,6 @@
         if (mIsFromSUW) {
             return DISABLED_DEPENDENT_SETTING;
         }
-        if (!Flags.revampToggles()) {
-            if (AutoTimeFormatPreferenceController.isAutoTimeFormatSelection(mContext)) {
-                return DISABLED_DEPENDENT_SETTING;
-            }
-        }
         return AVAILABLE;
     }
 
@@ -120,12 +114,12 @@
         return DateFormat.is24HourFormat(mContext);
     }
 
-    static void update24HourFormat(Context context, Boolean is24Hour) {
+    private static void update24HourFormat(Context context, Boolean is24Hour) {
         set24Hour(context, is24Hour);
         timeUpdated(context, is24Hour);
     }
 
-    static void timeUpdated(Context context, Boolean is24Hour) {
+    private static void timeUpdated(Context context, Boolean is24Hour) {
         Intent timeChanged = new Intent(Intent.ACTION_TIME_CHANGED);
         timeChanged.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
         int timeFormatPreference;
@@ -139,9 +133,8 @@
         context.sendBroadcast(timeChanged);
     }
 
-    static void set24Hour(Context context, Boolean is24Hour) {
-        String value = is24Hour == null ? null :
-                is24Hour ? HOURS_24 : HOURS_12;
+    private static void set24Hour(Context context, boolean is24Hour) {
+        String value = is24Hour ? HOURS_24 : HOURS_12;
         Settings.System.putString(context.getContentResolver(),
                 Settings.System.TIME_12_24, value);
     }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
index 5e17f4b..2edbf99 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java
@@ -274,7 +274,6 @@
         }
         if (mDailyChartView != dailyChartView || mHourlyChartView != hourlyChartView) {
             mHandler.post(() -> setBatteryChartViewInner(dailyChartView, hourlyChartView));
-            animateBatteryChartViewGroup();
         }
         if (mBatteryChartViewGroup != null) {
             final View grandparentView = (View) mBatteryChartViewGroup.getParent();
diff --git a/src/com/android/settings/gestures/OneHandedSettings.java b/src/com/android/settings/gestures/OneHandedSettings.java
index 0378888..0a2599e 100644
--- a/src/com/android/settings/gestures/OneHandedSettings.java
+++ b/src/com/android/settings/gestures/OneHandedSettings.java
@@ -22,9 +22,9 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.os.UserHandle;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
+import android.widget.CompoundButton;
 
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -33,7 +33,6 @@
 import com.android.settings.R;
 import com.android.settings.accessibility.AccessibilityFragmentUtils;
 import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
-import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.search.SearchIndexableRaw;
@@ -82,12 +81,7 @@
 
         final MainSwitchPreference mainSwitchPreference =
                 getPreferenceScreen().findPreference(ONE_HANDED_MAIN_SWITCH_KEY);
-        mainSwitchPreference.addOnSwitchChangeListener((switchView, isChecked) -> {
-            switchView.setChecked(isChecked);
-            if (isChecked) {
-                showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
-            }
-        });
+        mainSwitchPreference.addOnSwitchChangeListener(CompoundButton::setChecked);
     }
 
     @Override
@@ -146,24 +140,6 @@
     }
 
     @Override
-    protected ComponentName getTileComponentName() {
-        return AccessibilityShortcutController.ONE_HANDED_TILE_COMPONENT_NAME;
-    }
-
-    @Override
-    protected CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
-        final Context context = getContext();
-        if (context == null) {
-            Log.w(TAG, "OneHandedSettings not attached to a context.");
-            return null;
-        }
-        return type == QuickSettingsTooltipType.GUIDE_TO_EDIT
-                ? context.getText(R.string.accessibility_one_handed_mode_qs_tooltip_content)
-                : context.getText(
-                        R.string.accessibility_one_handed_mode_auto_added_qs_tooltip_content);
-    }
-
-    @Override
     protected int getPreferenceScreenResId() {
         return R.xml.one_handed_settings;
     }
diff --git a/src/com/android/settings/language/DefaultVoiceInputPreferenceController.java b/src/com/android/settings/language/DefaultVoiceInputPreferenceController.java
index 74c156c..c0b65df 100644
--- a/src/com/android/settings/language/DefaultVoiceInputPreferenceController.java
+++ b/src/com/android/settings/language/DefaultVoiceInputPreferenceController.java
@@ -22,9 +22,12 @@
 import android.content.pm.PackageManager;
 import android.text.TextUtils;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
+import com.android.internal.annotations.Initializer;
 import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
 import com.android.settingslib.applications.DefaultAppInfo;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -43,7 +46,8 @@
     private Preference mPreference;
     private Context mContext;
 
-    public DefaultVoiceInputPreferenceController(Context context, Lifecycle lifecycle) {
+    public DefaultVoiceInputPreferenceController(
+            @NonNull Context context, @Nullable Lifecycle lifecycle) {
         super(context);
         mContext = context;
         mHelper = new VoiceInputHelper(context);
@@ -65,6 +69,7 @@
     }
 
     @Override
+    @Initializer
     public void displayPreference(PreferenceScreen screen) {
         mScreen = screen;
         mPreference = screen.findPreference(getPreferenceKey());
diff --git a/src/com/android/settings/language/LanguageAndRegionPreferenceController.java b/src/com/android/settings/language/LanguageAndRegionPreferenceController.java
new file mode 100644
index 0000000..4e554ed
--- /dev/null
+++ b/src/com/android/settings/language/LanguageAndRegionPreferenceController.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.language;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.flags.Flags;
+
+/**
+ * This is a display controller for new language activity entry.
+ * TODO(b/379962955): When new layout is on board, all old layouts should be removed.
+ */
+public class LanguageAndRegionPreferenceController extends BasePreferenceController {
+
+    public LanguageAndRegionPreferenceController(@NonNull Context context, @NonNull String key) {
+        super(context, key);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (!Flags.regionalPreferencesApiEnabled()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+        // TODO: Add setComponentEnabledSetting after LanguageAndRegionSettingsActivity is created.
+        return AVAILABLE;
+    }
+}
diff --git a/src/com/android/settings/language/LanguageAndRegionSettings.java b/src/com/android/settings/language/LanguageAndRegionSettings.java
new file mode 100644
index 0000000..a405878
--- /dev/null
+++ b/src/com/android/settings/language/LanguageAndRegionSettings.java
@@ -0,0 +1,129 @@
+/*
+ * 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.language;
+
+import android.app.Activity;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+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.settings.widget.PreferenceCategoryController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.search.SearchIndexable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SearchIndexable
+public class LanguageAndRegionSettings extends DashboardFragment {
+
+    private static final String KEY_SPEECH_CATEGORY = "speech_category";
+    private static final String KEY_ON_DEVICE_RECOGNITION = "on_device_recognition_settings";
+    private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
+
+    private static final String TAG = "LanguageAndRegionSettings";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.SETTINGS_LANGUAGES_CATEGORY;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        // Hack to update action bar title. It's necessary to refresh title because this page user
+        // can change locale from here and fragment won't relaunch. Once language changes, title
+        // must display in the new language.
+        final Activity activity = getActivity();
+        if (activity == null) {
+            return;
+        }
+        activity.setTitle(R.string.languages_settings);
+    }
+
+    @Override
+    public @Nullable String getPreferenceScreenBindingKey(@NonNull Context context) {
+        return LanguageSettingScreen.KEY;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.language_and_region_settings;
+    }
+
+    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+        return buildPreferenceControllers(context, getSettingsLifecycle());
+    }
+
+    private static List<AbstractPreferenceController> buildPreferenceControllers(
+            @NonNull Context context, @Nullable Lifecycle lifecycle) {
+        final List<AbstractPreferenceController> controllers = new ArrayList<>();
+
+        final DefaultVoiceInputPreferenceController defaultVoiceInputPreferenceController =
+                new DefaultVoiceInputPreferenceController(context, lifecycle);
+        final TtsPreferenceController ttsPreferenceController =
+                new TtsPreferenceController(context, KEY_TEXT_TO_SPEECH);
+        final OnDeviceRecognitionPreferenceController onDeviceRecognitionPreferenceController =
+                new OnDeviceRecognitionPreferenceController(context, KEY_ON_DEVICE_RECOGNITION);
+
+        controllers.add(defaultVoiceInputPreferenceController);
+        controllers.add(ttsPreferenceController);
+        List<AbstractPreferenceController> speechCategoryChildren = new ArrayList<>(
+                List.of(defaultVoiceInputPreferenceController, ttsPreferenceController));
+
+        if (onDeviceRecognitionPreferenceController.isAvailable()) {
+            controllers.add(onDeviceRecognitionPreferenceController);
+            speechCategoryChildren.add(onDeviceRecognitionPreferenceController);
+        }
+
+        controllers.add(new PreferenceCategoryController(context, KEY_SPEECH_CATEGORY)
+                .setChildren(speechCategoryChildren));
+
+        return controllers;
+    }
+
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.language_and_region_settings) {
+
+                @Override
+                @NonNull
+                public List<AbstractPreferenceController> createPreferenceControllers(
+                        @NonNull Context context) {
+                    return buildPreferenceControllers(context, null);
+                }
+
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    if (Flags.regionalPreferencesApiEnabled()) {
+                        return true;
+                    }
+                    return false;
+                }
+            };
+}
diff --git a/src/com/android/settings/language/LanguagePreferenceController.java b/src/com/android/settings/language/LanguagePreferenceController.java
index 84624a2..90aaec4 100644
--- a/src/com/android/settings/language/LanguagePreferenceController.java
+++ b/src/com/android/settings/language/LanguagePreferenceController.java
@@ -22,6 +22,7 @@
 
 import com.android.settings.Settings;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.flags.Flags;
 
 /**
  * This is a display controller for new language activity entry.
@@ -34,6 +35,10 @@
 
     @Override
     public int getAvailabilityStatus() {
+        if (Flags.regionalPreferencesApiEnabled()) {
+            setActivityEnabled(mContext, Settings.LanguageSettingsActivity.class, false);
+            return CONDITIONALLY_UNAVAILABLE;
+        }
         setActivityEnabled(mContext, Settings.LanguageSettingsActivity.class, true);
         return AVAILABLE;
     }
diff --git a/src/com/android/settings/language/LanguageSettings.java b/src/com/android/settings/language/LanguageSettings.java
index d992ff2..58df053 100644
--- a/src/com/android/settings/language/LanguageSettings.java
+++ b/src/com/android/settings/language/LanguageSettings.java
@@ -25,6 +25,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.settings.widget.PreferenceCategoryController;
 import com.android.settingslib.core.AbstractPreferenceController;
@@ -116,6 +117,9 @@
                 }
                 @Override
                 protected boolean isPageSearchEnabled(Context context) {
+                    if (Flags.regionalPreferencesApiEnabled()) {
+                        return false;
+                    }
                     return true;
                 }
             };
diff --git a/src/com/android/settings/network/apn/ApnPreference.java b/src/com/android/settings/network/apn/ApnPreference.java
index 55258c1..3ba3508 100644
--- a/src/com/android/settings/network/apn/ApnPreference.java
+++ b/src/com/android/settings/network/apn/ApnPreference.java
@@ -24,31 +24,29 @@
 import android.net.Uri;
 import android.provider.Telephony;
 import android.telephony.SubscriptionManager;
-import android.util.AttributeSet;
 import android.util.Log;
 import android.view.View;
 import android.widget.CompoundButton;
 import android.widget.RadioButton;
-import android.widget.RelativeLayout;
 import android.widget.Toast;
 
-import androidx.annotation.Nullable;
+import androidx.annotation.NonNull;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settings.R;
 import com.android.settings.flags.Flags;
 import com.android.settings.spa.SpaActivity;
+import com.android.settingslib.widget.TwoTargetPreference;
 
 /**
  * Preference of APN UI entry
  */
-public class ApnPreference extends Preference
-        implements CompoundButton.OnCheckedChangeListener, View.OnClickListener {
+public class ApnPreference extends TwoTargetPreference
+        implements CompoundButton.OnCheckedChangeListener, Preference.OnPreferenceClickListener {
     private static final String TAG = "ApnPreference";
     private boolean mIsChecked = false;
-    @Nullable
-    private RadioButton mRadioButton = null;
+    private RadioButton mRadioButton;
     private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     private boolean mProtectFromCheckedChange = false;
     private boolean mDefaultSelectable = true;
@@ -57,50 +55,36 @@
     /**
      * Constructor of Preference
      */
-    public ApnPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        // Primary target and radio button could be selectable, but entire preference itself is not
-        // selectable.
-        setSelectable(false);
-    }
-
-    /**
-     * Constructor of Preference
-     */
-    public ApnPreference(Context context, AttributeSet attrs) {
-        this(context, attrs, R.attr.apnPreferenceStyle);
-    }
-
-    /**
-     * Constructor of Preference
-     */
     public ApnPreference(Context context) {
-        this(context, null);
+        super(context);
+        setOnPreferenceClickListener(this);
     }
 
     @Override
-    public void onBindViewHolder(PreferenceViewHolder view) {
-        super.onBindViewHolder(view);
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
 
-        final RelativeLayout textArea = (RelativeLayout) view.findViewById(R.id.text_layout);
-        textArea.setOnClickListener(this);
-
-        final View radioButtonFrame = view.itemView.requireViewById(R.id.apn_radio_button_frame);
-        final RadioButton rb = view.itemView.requireViewById(R.id.apn_radiobutton);
-        mRadioButton = rb;
-        if (mDefaultSelectable) {
-            radioButtonFrame.setOnClickListener((v) -> {
-                rb.performClick();
-            });
-            rb.setOnCheckedChangeListener(this);
-
-            mProtectFromCheckedChange = true;
-            rb.setChecked(mIsChecked);
-            mProtectFromCheckedChange = false;
-            radioButtonFrame.setVisibility(View.VISIBLE);
-        } else {
-            radioButtonFrame.setVisibility(View.GONE);
+        final RadioButton rb = (RadioButton) holder.findViewById(android.R.id.checkbox);
+        final View radioButtonFrame = holder.findViewById(android.R.id.widget_frame);
+        if (rb == null || radioButtonFrame == null) {
+            throw new RuntimeException("Failed to load system layout.");
         }
+
+        mRadioButton = rb;
+        radioButtonFrame.setOnClickListener(v -> rb.performClick());
+        rb.setOnCheckedChangeListener(this);
+        setIsChecked(mIsChecked);
+        rb.setVisibility(View.VISIBLE);
+    }
+
+    @Override
+    protected boolean shouldHideSecondTarget() {
+        return !mDefaultSelectable;
+    }
+
+    @Override
+    protected int getSecondTargetResId() {
+        return R.layout.preference_widget_radiobutton;
     }
 
     /**
@@ -118,6 +102,7 @@
     /**
      * Change the preference status.
      */
+    @Override
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
         Log.i(TAG, "ID: " + getKey() + " :" + isChecked);
         if (mProtectFromCheckedChange) {
@@ -130,19 +115,14 @@
     }
 
     @Override
-    public void onClick(View layoutView) {
-        super.onClick();
+    public boolean onPreferenceClick(@NonNull Preference preference) {
         final Context context = getContext();
         final int pos = Integer.parseInt(getKey());
-        if (context == null) {
-            Log.w(TAG, "No context available for pos=" + pos);
-            return;
-        }
 
         if (mHideDetails) {
             Toast.makeText(context, context.getString(R.string.cannot_change_apn_toast),
                     Toast.LENGTH_LONG).show();
-            return;
+            return true;
         }
 
         final Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
@@ -156,6 +136,7 @@
             editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
             context.startActivity(editIntent);
         }
+        return true;
     }
 
     public void setDefaultSelectable(boolean defaultSelectable) {
diff --git a/src/com/android/settings/network/telephony/SubscriptionRepository.kt b/src/com/android/settings/network/telephony/SubscriptionRepository.kt
index 43bba07..33c1e655 100644
--- a/src/com/android/settings/network/telephony/SubscriptionRepository.kt
+++ b/src/com/android/settings/network/telephony/SubscriptionRepository.kt
@@ -40,6 +40,7 @@
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.shareIn
+import java.util.stream.Collectors
 
 private const val TAG = "SubscriptionRepository"
 
@@ -154,6 +155,18 @@
             .conflate()
             .flowOn(Dispatchers.Default)
 
+    fun removableSubscriptionInfoListFlow(): Flow<List<SubscriptionInfo>> {
+        return subscriptionsChangedFlow()
+            .map {
+                subscriptionManager.availableSubscriptionInfoList?.stream()
+                    ?.filter { sub: SubscriptionInfo -> !sub.isEmbedded }
+                    ?.collect(Collectors.toList()) ?: emptyList()
+            }
+            .conflate()
+            .onEach { Log.d(TAG, "getRemovableSubscriptionVisibleFlow: $it") }
+            .flowOn(Dispatchers.Default)
+    }
+
     @OptIn(ExperimentalCoroutinesApi::class)
     fun phoneNumberFlow(subId: Int): Flow<String?> =
         activeSubscriptionInfoFlow(subId).flatMapLatest { subInfo ->
diff --git a/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java b/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java
index 9f15cf4..231a34e 100644
--- a/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java
+++ b/src/com/android/settings/regionalpreferences/MeasurementSystemItemFragment.java
@@ -63,7 +63,7 @@
             new BaseSearchIndexProvider(R.xml.regional_preferences_measurement_system) {
                 @Override
                 protected boolean isPageSearchEnabled(Context context) {
-                    if (Flags.regionalPreferencesApiEnabled()) {
+                    if (!Flags.regionalPreferencesApiEnabled()) {
                         return false;
                     }
                     return true;
diff --git a/src/com/android/settings/service/PreferenceService.kt b/src/com/android/settings/service/PreferenceService.kt
index d07e78d..81ab584 100644
--- a/src/com/android/settings/service/PreferenceService.kt
+++ b/src/com/android/settings/service/PreferenceService.kt
@@ -19,7 +19,6 @@
 import android.app.Application
 import android.os.Binder
 import android.os.OutcomeReceiver
-import android.os.Process
 import android.service.settings.preferences.GetValueRequest
 import android.service.settings.preferences.GetValueResult
 import android.service.settings.preferences.MetadataRequest
@@ -37,7 +36,6 @@
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.launch
-import java.lang.Exception
 
 class PreferenceService : SettingsPreferenceService() {
 
@@ -49,14 +47,22 @@
 
     override fun onGetAllPreferenceMetadata(
         request: MetadataRequest,
-        callback: OutcomeReceiver<MetadataResult, Exception>
+        callback: OutcomeReceiver<MetadataResult, Exception>,
     ) {
+        // MUST get pid/uid in binder thread
+        val callingPid = Binder.getCallingPid()
+        val callingUid = Binder.getCallingUid()
         scope.launch {
-            val graphProto = graphApi.invoke(application, Process.myUid(), Binder.getCallingUid(),
-                GetPreferenceGraphRequest(
-                    includeValue = false,
-                    flags = PreferenceGetterFlags.METADATA
-                ))
+            val graphProto =
+                graphApi.invoke(
+                    application,
+                    callingPid,
+                    callingUid,
+                    GetPreferenceGraphRequest(
+                        includeValue = false,
+                        flags = PreferenceGetterFlags.METADATA,
+                    ),
+                )
             val result = transformCatalystGetMetadataResponse(this@PreferenceService, graphProto)
             callback.onResult(result)
         }
@@ -64,17 +70,16 @@
 
     override fun onGetPreferenceValue(
         request: GetValueRequest,
-        callback: OutcomeReceiver<GetValueResult, Exception>
+        callback: OutcomeReceiver<GetValueResult, Exception>,
     ) {
+        // MUST get pid/uid in binder thread
+        val callingPid = Binder.getCallingPid()
+        val callingUid = Binder.getCallingUid()
         scope.launch {
             val apiRequest = transformFrameworkGetValueRequest(request)
-            val response = getApiHandler.invoke(application, Process.myUid(),
-                Binder.getCallingUid(), apiRequest)
-            val result = transformCatalystGetValueResponse(
-                this@PreferenceService,
-                request,
-                response
-            )
+            val response = getApiHandler.invoke(application, callingPid, callingUid, apiRequest)
+            val result =
+                transformCatalystGetValueResponse(this@PreferenceService, request, response)
             if (result == null) {
                 callback.onError(IllegalStateException("No response"))
             } else {
@@ -85,8 +90,11 @@
 
     override fun onSetPreferenceValue(
         request: SetValueRequest,
-        callback: OutcomeReceiver<SetValueResult, Exception>
+        callback: OutcomeReceiver<SetValueResult, Exception>,
     ) {
+        // MUST get pid/uid in binder thread
+        val callingPid = Binder.getCallingPid()
+        val callingUid = Binder.getCallingUid()
         scope.launch {
             val apiRequest = transformFrameworkSetValueRequest(request)
             if (apiRequest == null) {
@@ -94,8 +102,7 @@
                     SetValueResult.Builder(SetValueResult.RESULT_INVALID_REQUEST).build()
                 )
             } else {
-                val response = setApiHandler.invoke(application, Process.myUid(),
-                    Binder.getCallingUid(), apiRequest)
+                val response = setApiHandler.invoke(application, callingPid, callingUid, apiRequest)
 
                 callback.onResult(transformCatalystSetValueResponse(response))
             }
@@ -106,9 +113,9 @@
     private class GraphProvider(override val id: Int) : GetPreferenceGraphApiHandler(emptySet()) {
         override fun hasPermission(
             application: Application,
-            myUid: Int,
+            callingPid: Int,
             callingUid: Int,
-            request: GetPreferenceGraphRequest
+            request: GetPreferenceGraphRequest,
         ) = true
     }
 }
diff --git a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
deleted file mode 100644
index f808924..0000000
--- a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (C) 2020 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.sim.receivers;
-
-import static android.content.Context.MODE_PRIVATE;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Looper;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.UiccCardInfo;
-import android.telephony.UiccPortInfo;
-import android.telephony.UiccSlotInfo;
-import android.util.Log;
-
-import com.android.settings.flags.Flags;
-import com.android.settings.network.SubscriptionUtil;
-import com.android.settings.network.UiccSlotUtil;
-import com.android.settings.network.UiccSlotsException;
-import com.android.settings.sim.ChooseSimActivity;
-import com.android.settings.sim.DsdsDialogActivity;
-import com.android.settings.sim.SimActivationNotifier;
-import com.android.settings.sim.SimNotificationService;
-import com.android.settings.sim.SwitchToEsimConfirmDialogActivity;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-import javax.annotation.Nullable;
-
-/** Perform actions after a slot change event is triggered. */
-public class SimSlotChangeHandler {
-    private static final String TAG = "SimSlotChangeHandler";
-
-    private static final String EUICC_PREFS = "euicc_prefs";
-    // Shared preference keys
-    private static final String KEY_REMOVABLE_SLOT_STATE = "removable_slot_state";
-    private static final String KEY_SUW_PSIM_ACTION = "suw_psim_action";
-    // User's last removable SIM insertion / removal action during SUW.
-    private static final int LAST_USER_ACTION_IN_SUW_NONE = 0;
-    private static final int LAST_USER_ACTION_IN_SUW_INSERT = 1;
-    private static final int LAST_USER_ACTION_IN_SUW_REMOVE = 2;
-
-    private static volatile SimSlotChangeHandler sSlotChangeHandler;
-
-    /** Returns a SIM slot change handler singleton. */
-    public static SimSlotChangeHandler get() {
-        if (sSlotChangeHandler == null) {
-            synchronized (SimSlotChangeHandler.class) {
-                if (sSlotChangeHandler == null) {
-                    sSlotChangeHandler = new SimSlotChangeHandler();
-                }
-            }
-        }
-        return sSlotChangeHandler;
-    }
-
-    private SubscriptionManager mSubMgr;
-    private TelephonyManager mTelMgr;
-    private Context mContext;
-
-    void onSlotsStatusChange(Context context) {
-        init(context);
-
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            throw new IllegalStateException("Cannot be called from main thread.");
-        }
-
-        UiccSlotInfo removableSlotInfo = getRemovableUiccSlotInfo();
-        if (removableSlotInfo == null) {
-            Log.e(TAG, "Unable to find the removable slot. Do nothing.");
-            return;
-        }
-        Log.i(TAG, "The removableSlotInfo: " + removableSlotInfo);
-        int lastRemovableSlotState = getLastRemovableSimSlotState(mContext);
-        int currentRemovableSlotState = removableSlotInfo.getCardStateInfo();
-        Log.d(TAG,
-                "lastRemovableSlotState: " + lastRemovableSlotState + ",currentRemovableSlotState: "
-                        + currentRemovableSlotState);
-        boolean isRemovableSimInserted =
-                lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT
-                        && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT;
-        boolean isRemovableSimRemoved =
-                lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT
-                        && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT;
-
-        // Sets the current removable slot state.
-        setRemovableSimSlotState(mContext, currentRemovableSlotState);
-
-        if (mTelMgr.getActiveModemCount() > 1) {
-            if (!isRemovableSimInserted) {
-                Log.d(TAG, "Removable Sim is not inserted in DSDS mode. Do nothing.");
-                return;
-            }
-
-            if (Flags.isDualSimOnboardingEnabled()) {
-                // ForNewUi, when the user inserts the psim, showing the sim onboarding for the user
-                // to setup the sim switching or the default data subscription in DSDS.
-                // Will show dialog for below case.
-                // 1. the psim slot is not active.
-                // 2. there are one or more active sim.
-                handleRemovableSimInsertWhenDsds(removableSlotInfo);
-                return;
-            } else if (!isMultipleEnabledProfilesSupported()) {
-                Log.d(TAG, "The device is already in DSDS mode and no MEP. Do nothing.");
-                return;
-            } else if (isMultipleEnabledProfilesSupported()) {
-                handleRemovableSimInsertUnderDsdsMep(removableSlotInfo);
-                return;
-            }
-        }
-
-        if (isRemovableSimInserted) {
-            handleSimInsert(removableSlotInfo);
-            return;
-        }
-        if (isRemovableSimRemoved) {
-            handleSimRemove(removableSlotInfo);
-            return;
-        }
-        Log.i(TAG, "Do nothing on slot status changes.");
-    }
-
-    void onSuwFinish(Context context) {
-        init(context);
-
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            throw new IllegalStateException("Cannot be called from main thread.");
-        }
-
-        if (mTelMgr.getActiveModemCount() > 1) {
-            Log.i(TAG, "The device is already in DSDS mode. Do nothing.");
-            return;
-        }
-
-        UiccSlotInfo removableSlotInfo = getRemovableUiccSlotInfo();
-        if (removableSlotInfo == null) {
-            Log.e(TAG, "Unable to find the removable slot. Do nothing.");
-            return;
-        }
-
-        boolean embeddedSimExist = getGroupedEmbeddedSubscriptions().size() != 0;
-        int removableSlotAction = getSuwRemovableSlotAction(mContext);
-        setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_NONE);
-
-        if (embeddedSimExist
-                && removableSlotInfo.getCardStateInfo() == UiccSlotInfo.CARD_STATE_INFO_PRESENT) {
-            if (mTelMgr.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
-                Log.i(TAG, "DSDS condition satisfied. Show notification.");
-                SimNotificationService.scheduleSimNotification(
-                        mContext, SimActivationNotifier.NotificationType.ENABLE_DSDS);
-            } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_INSERT) {
-                Log.i(
-                        TAG,
-                        "Both removable SIM and eSIM are present. DSDS condition doesn't"
-                                + " satisfied. User inserted pSIM during SUW. Show choose SIM"
-                                + " screen.");
-                startChooseSimActivity(true);
-            }
-        } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_REMOVE) {
-            handleSimRemove(removableSlotInfo);
-        }
-    }
-
-    private void init(Context context) {
-        mSubMgr =
-                (SubscriptionManager)
-                        context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-        mTelMgr = context.getSystemService(TelephonyManager.class);
-        mContext = context;
-    }
-
-    private void handleSimInsert(UiccSlotInfo removableSlotInfo) {
-        Log.i(TAG, "Handle SIM inserted.");
-        if (!isSuwFinished(mContext)) {
-            Log.i(TAG, "Still in SUW. Handle SIM insertion after SUW is finished");
-            setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_INSERT);
-            return;
-        }
-        if (removableSlotInfo.getPorts().stream().findFirst().get().isActive()) {
-            Log.i(TAG, "The removable slot is already active. Do nothing.");
-            return;
-        }
-
-        if (hasActiveEsimSubscription()) {
-            if (mTelMgr.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
-                Log.i(TAG, "Enabled profile exists. DSDS condition satisfied.");
-                if (Flags.isDualSimOnboardingEnabled()) {
-                    // enable dsds by sim onboarding flow
-                    handleRemovableSimInsertWhenDsds(removableSlotInfo);
-                } else {
-                    startDsdsDialogActivity();
-                }
-            } else {
-                Log.i(TAG, "Enabled profile exists. DSDS condition not satisfied.");
-                startChooseSimActivity(true);
-            }
-            return;
-        }
-
-        Log.i(
-                TAG,
-                "No enabled eSIM profile. Ready to switch to removable slot and show"
-                        + " notification.");
-        try {
-            UiccSlotUtil.switchToRemovableSlot(
-                    UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID, mContext.getApplicationContext());
-        } catch (UiccSlotsException e) {
-            Log.e(TAG, "Failed to switch to removable slot.");
-            return;
-        }
-        SimNotificationService.scheduleSimNotification(
-                mContext, SimActivationNotifier.NotificationType.SWITCH_TO_REMOVABLE_SLOT);
-    }
-
-    private void handleSimRemove(UiccSlotInfo removableSlotInfo) {
-        Log.i(TAG, "Handle SIM removed.");
-
-        if (!isSuwFinished(mContext)) {
-            Log.i(TAG, "Still in SUW. Handle SIM removal after SUW is finished");
-            setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_REMOVE);
-            return;
-        }
-
-        List<SubscriptionInfo> groupedEmbeddedSubscriptions = getGroupedEmbeddedSubscriptions();
-        if (groupedEmbeddedSubscriptions.size() == 0 || !removableSlotInfo.getPorts().stream()
-                .findFirst().get().isActive()) {
-            Log.i(TAG, "eSIM slot is active or no subscriptions exist. Do nothing."
-                    + " The removableSlotInfo: " + removableSlotInfo
-                    + ", groupedEmbeddedSubscriptions: " + groupedEmbeddedSubscriptions);
-            return;
-        }
-
-        // If there is only 1 eSIM profile exists, we ask the user if they want to switch to that
-        // profile.
-        if (groupedEmbeddedSubscriptions.size() == 1) {
-            Log.i(TAG, "Only 1 eSIM profile found. Ask user's consent to switch.");
-            startSwitchSlotConfirmDialogActivity(groupedEmbeddedSubscriptions.get(0));
-            return;
-        }
-
-        // If there are more than 1 eSIM profiles installed, we show a screen to let users to choose
-        // the number they want to use.
-        Log.i(TAG, "Multiple eSIM profiles found. Ask user which subscription to use.");
-        startChooseSimActivity(false);
-    }
-
-    private boolean hasOtherActiveSubInfo(int psimSubId) {
-        List<SubscriptionInfo> activeSubs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
-        return activeSubs.stream()
-                .anyMatch(subscriptionInfo -> subscriptionInfo.getSubscriptionId() != psimSubId);
-    }
-
-    private boolean hasAnyPortActiveInSlot(UiccSlotInfo removableSlotInfo) {
-        return removableSlotInfo.getPorts().stream().anyMatch(UiccPortInfo::isActive);
-    }
-
-    private void handleRemovableSimInsertWhenDsds(UiccSlotInfo removableSlotInfo) {
-        Log.i(TAG, "ForNewUi: Handle Removable SIM inserted");
-        List<SubscriptionInfo> subscriptionInfos = getAvailableRemovableSubscription();
-        if (subscriptionInfos.isEmpty()) {
-            Log.e(TAG, "Unable to find the removable subscriptionInfo. Do nothing.");
-            return;
-        }
-        Log.d(TAG, "getAvailableRemovableSubscription:" + subscriptionInfos);
-        int psimSubId = subscriptionInfos.get(0).getSubscriptionId();
-        if (!hasAnyPortActiveInSlot(removableSlotInfo) || hasOtherActiveSubInfo(psimSubId)) {
-            Log.d(TAG, "ForNewUi Start Setup flow");
-            startSimConfirmDialogActivity(psimSubId);
-        }
-    }
-
-    private void handleRemovableSimInsertUnderDsdsMep(UiccSlotInfo removableSlotInfo) {
-        Log.i(TAG, "Handle Removable SIM inserted under DSDS+Mep.");
-
-        if (removableSlotInfo.getPorts().stream().findFirst().get().isActive()) {
-            Log.i(TAG, "The removable slot is already active. Do nothing. removableSlotInfo: "
-                    + removableSlotInfo);
-            return;
-        }
-
-        List<SubscriptionInfo> subscriptionInfos = getAvailableRemovableSubscription();
-        if (subscriptionInfos.isEmpty()) {
-            Log.e(TAG, "Unable to find the removable subscriptionInfo. Do nothing.");
-            return;
-        }
-        Log.d(TAG, "getAvailableRemovableSubscription:" + subscriptionInfos);
-        startSimConfirmDialogActivity(subscriptionInfos.get(0).getSubscriptionId());
-    }
-
-    private int getLastRemovableSimSlotState(Context context) {
-        final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE);
-        return prefs.getInt(KEY_REMOVABLE_SLOT_STATE, UiccSlotInfo.CARD_STATE_INFO_ABSENT);
-    }
-
-    private void setRemovableSimSlotState(Context context, int state) {
-        final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE);
-        prefs.edit().putInt(KEY_REMOVABLE_SLOT_STATE, state).apply();
-        Log.d(TAG, "setRemovableSimSlotState: " + state);
-    }
-
-    private int getSuwRemovableSlotAction(Context context) {
-        final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE);
-        return prefs.getInt(KEY_SUW_PSIM_ACTION, LAST_USER_ACTION_IN_SUW_NONE);
-    }
-
-    private void setSuwRemovableSlotAction(Context context, int action) {
-        final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE);
-        prefs.edit().putInt(KEY_SUW_PSIM_ACTION, action).apply();
-    }
-
-    @Nullable
-    private UiccSlotInfo getRemovableUiccSlotInfo() {
-        UiccSlotInfo[] slotInfos = mTelMgr.getUiccSlotsInfo();
-        if (slotInfos == null) {
-            Log.e(TAG, "slotInfos is null. Unable to get slot infos.");
-            return null;
-        }
-        for (UiccSlotInfo slotInfo : slotInfos) {
-            if (slotInfo != null && slotInfo.isRemovable()) {
-                return slotInfo;
-            }
-        }
-        return null;
-    }
-
-    private static boolean isSuwFinished(Context context) {
-        try {
-            // DEVICE_PROVISIONED is 0 if still in setup wizard. 1 if setup completed.
-            return Settings.Global.getInt(
-                    context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED)
-                    == 1;
-        } catch (Settings.SettingNotFoundException e) {
-            Log.e(TAG, "Cannot get DEVICE_PROVISIONED from the device.", e);
-            return false;
-        }
-    }
-
-    private boolean hasActiveEsimSubscription() {
-        List<SubscriptionInfo> activeSubs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
-        return activeSubs.stream().anyMatch(SubscriptionInfo::isEmbedded);
-    }
-
-    private List<SubscriptionInfo> getGroupedEmbeddedSubscriptions() {
-        List<SubscriptionInfo> groupedSubscriptions =
-                SubscriptionUtil.getSelectableSubscriptionInfoList(mContext);
-        if (groupedSubscriptions == null) {
-            return ImmutableList.of();
-        }
-        return ImmutableList.copyOf(
-                groupedSubscriptions.stream()
-                        .filter(sub -> sub.isEmbedded())
-                        .collect(Collectors.toList()));
-    }
-
-    protected List<SubscriptionInfo> getAvailableRemovableSubscription() {
-        List<SubscriptionInfo> removableSubscriptions =
-                SubscriptionUtil.getAvailableSubscriptions(mContext);
-        return ImmutableList.copyOf(
-                removableSubscriptions.stream()
-                        // ToDo: This condition is for psim only. If device supports removable
-                        //  esim, it needs an new condition.
-                        .filter(sub -> !sub.isEmbedded())
-                        .collect(Collectors.toList()));
-    }
-
-    private void startChooseSimActivity(boolean psimInserted) {
-        Intent intent = ChooseSimActivity.getIntent(mContext);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.putExtra(ChooseSimActivity.KEY_HAS_PSIM, psimInserted);
-        mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
-    }
-
-    private void startSwitchSlotConfirmDialogActivity(SubscriptionInfo subscriptionInfo) {
-        Intent intent = new Intent(mContext, SwitchToEsimConfirmDialogActivity.class);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.putExtra(SwitchToEsimConfirmDialogActivity.KEY_SUB_TO_ENABLE, subscriptionInfo);
-        mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
-    }
-
-    private void startDsdsDialogActivity() {
-        Intent intent = new Intent(mContext, DsdsDialogActivity.class);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivityAsUser(intent, UserHandle.SYSTEM);
-    }
-
-    private void startSimConfirmDialogActivity(int subId) {
-        if (!isSuwFinished(mContext)) {
-            Log.d(TAG, "Still in SUW. Do nothing");
-            return;
-        }
-        if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
-            Log.i(TAG, "Unable to enable subscription due to invalid subscription ID.");
-            return;
-        }
-        Log.d(TAG, "Start ToggleSubscriptionDialogActivity with " + subId + " under DSDS+Mep.");
-        SubscriptionUtil.startToggleSubscriptionDialogActivity(mContext, subId, true, true);
-    }
-
-    private boolean isMultipleEnabledProfilesSupported() {
-        List<UiccCardInfo> cardInfos = mTelMgr.getUiccCardsInfo();
-        if (cardInfos == null) {
-            Log.d(TAG, "UICC cards info list is empty.");
-            return false;
-        }
-        return cardInfos.stream().anyMatch(
-                cardInfo -> cardInfo.isMultipleEnabledProfilesSupported());
-    }
-
-    private SimSlotChangeHandler() {}
-}
diff --git a/src/com/android/settings/sim/receivers/SimSlotChangeHandler.kt b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.kt
new file mode 100644
index 0000000..940184a
--- /dev/null
+++ b/src/com/android/settings/sim/receivers/SimSlotChangeHandler.kt
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2020 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.sim.receivers
+
+import android.content.Context
+import android.content.Intent
+import android.os.Looper
+import android.os.UserHandle
+import android.provider.Settings
+import android.provider.Settings.SettingNotFoundException
+import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import android.telephony.TelephonyManager
+import android.telephony.UiccCardInfo
+import android.telephony.UiccSlotInfo
+import android.util.Log
+import com.android.settings.flags.Flags
+import com.android.settings.network.SubscriptionUtil
+import com.android.settings.network.UiccSlotUtil
+import com.android.settings.network.UiccSlotsException
+import com.android.settings.network.telephony.SubscriptionRepository
+import com.android.settings.sim.ChooseSimActivity
+import com.android.settings.sim.DsdsDialogActivity
+import com.android.settings.sim.SimActivationNotifier
+import com.android.settings.sim.SimNotificationService
+import com.android.settings.sim.SwitchToEsimConfirmDialogActivity
+import com.google.common.collect.ImmutableList
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.flow.firstOrNull
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import kotlinx.coroutines.withTimeoutOrNull
+import java.util.stream.Collectors
+import kotlin.concurrent.Volatile
+
+/** Perform actions after a slot change event is triggered.  */
+class SimSlotChangeHandler private constructor() {
+    private var mSubMgr: SubscriptionManager? = null
+    private var mTelMgr: TelephonyManager? = null
+    private var mContext: Context? = null
+
+    fun onSlotsStatusChange(context: Context) {
+        init(context)
+
+        check(Looper.myLooper() != Looper.getMainLooper()) { "Cannot be called from main thread." }
+
+        val removableSlotInfo = removableUiccSlotInfo
+        if (removableSlotInfo == null) {
+            Log.e(TAG, "Unable to find the removable slot. Do nothing.")
+            return
+        }
+        Log.i(
+            TAG,
+            "The removableSlotInfo: $removableSlotInfo"
+        )
+        val lastRemovableSlotState = getLastRemovableSimSlotState(mContext!!)
+        val currentRemovableSlotState = removableSlotInfo.cardStateInfo
+        Log.d(
+            TAG,
+            ("lastRemovableSlotState: " + lastRemovableSlotState + ",currentRemovableSlotState: "
+                    + currentRemovableSlotState)
+        )
+        val isRemovableSimInserted =
+            lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT
+                    && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT
+        val isRemovableSimRemoved =
+            lastRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_PRESENT
+                    && currentRemovableSlotState == UiccSlotInfo.CARD_STATE_INFO_ABSENT
+
+        // Sets the current removable slot state.
+        setRemovableSimSlotState(mContext!!, currentRemovableSlotState)
+
+        if (mTelMgr!!.activeModemCount > 1) {
+            if (!isRemovableSimInserted) {
+                Log.d(TAG, "Removable Sim is not inserted in DSDS mode. Do nothing.")
+                return
+            }
+
+            if (Flags.isDualSimOnboardingEnabled()) {
+                // ForNewUi, when the user inserts the psim, showing the sim onboarding for the user
+                // to setup the sim switching or the default data subscription in DSDS.
+                // Will show dialog for below case.
+                // 1. the psim slot is not active.
+                // 2. there are one or more active sim.
+                handleRemovableSimInsertWhenDsds(removableSlotInfo)
+                return
+            } else if (!isMultipleEnabledProfilesSupported) {
+                Log.d(TAG, "The device is already in DSDS mode and no MEP. Do nothing.")
+                return
+            } else if (isMultipleEnabledProfilesSupported) {
+                handleRemovableSimInsertUnderDsdsMep(removableSlotInfo)
+                return
+            }
+        }
+
+        if (isRemovableSimInserted) {
+            handleSimInsert(removableSlotInfo)
+            return
+        }
+        if (isRemovableSimRemoved) {
+            handleSimRemove(removableSlotInfo)
+            return
+        }
+        Log.i(TAG, "Do nothing on slot status changes.")
+    }
+
+    fun onSuwFinish(context: Context) {
+        init(context)
+
+        check(Looper.myLooper() != Looper.getMainLooper()) { "Cannot be called from main thread." }
+
+        if (mTelMgr!!.activeModemCount > 1) {
+            Log.i(TAG, "The device is already in DSDS mode. Do nothing.")
+            return
+        }
+
+        val removableSlotInfo = removableUiccSlotInfo
+        if (removableSlotInfo == null) {
+            Log.e(TAG, "Unable to find the removable slot. Do nothing.")
+            return
+        }
+
+        val embeddedSimExist = groupedEmbeddedSubscriptions.size != 0
+        val removableSlotAction = getSuwRemovableSlotAction(mContext!!)
+        setSuwRemovableSlotAction(mContext!!, LAST_USER_ACTION_IN_SUW_NONE)
+
+        if (embeddedSimExist
+            && removableSlotInfo.cardStateInfo == UiccSlotInfo.CARD_STATE_INFO_PRESENT
+        ) {
+            if (mTelMgr!!.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
+                Log.i(TAG, "DSDS condition satisfied. Show notification.")
+                SimNotificationService.scheduleSimNotification(
+                    mContext, SimActivationNotifier.NotificationType.ENABLE_DSDS
+                )
+            } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_INSERT) {
+                Log.i(
+                    TAG,
+                    ("Both removable SIM and eSIM are present. DSDS condition doesn't"
+                            + " satisfied. User inserted pSIM during SUW. Show choose SIM"
+                            + " screen.")
+                )
+                startChooseSimActivity(true)
+            }
+        } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_REMOVE) {
+            handleSimRemove(removableSlotInfo)
+        }
+    }
+
+    private fun init(context: Context) {
+        mSubMgr =
+            context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
+        mTelMgr = context.getSystemService(TelephonyManager::class.java)
+        mContext = context
+    }
+
+    private fun handleSimInsert(removableSlotInfo: UiccSlotInfo) {
+        Log.i(TAG, "Handle SIM inserted.")
+        if (!isSuwFinished(mContext!!)) {
+            Log.i(TAG, "Still in SUW. Handle SIM insertion after SUW is finished")
+            setSuwRemovableSlotAction(mContext!!, LAST_USER_ACTION_IN_SUW_INSERT)
+            return
+        }
+        if (removableSlotInfo.ports.stream().findFirst().get().isActive) {
+            Log.i(TAG, "The removable slot is already active. Do nothing.")
+            return
+        }
+
+        if (hasActiveEsimSubscription()) {
+            if (mTelMgr!!.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) {
+                Log.i(TAG, "Enabled profile exists. DSDS condition satisfied.")
+                if (Flags.isDualSimOnboardingEnabled()) {
+                    // enable dsds by sim onboarding flow
+                    handleRemovableSimInsertWhenDsds(removableSlotInfo)
+                } else {
+                    startDsdsDialogActivity()
+                }
+            } else {
+                Log.i(TAG, "Enabled profile exists. DSDS condition not satisfied.")
+                startChooseSimActivity(true)
+            }
+            return
+        }
+
+        Log.i(
+            TAG,
+            "No enabled eSIM profile. Ready to switch to removable slot and show"
+                    + " notification."
+        )
+        try {
+            UiccSlotUtil.switchToRemovableSlot(
+                UiccSlotUtil.INVALID_PHYSICAL_SLOT_ID, mContext!!.applicationContext
+            )
+        } catch (e: UiccSlotsException) {
+            Log.e(TAG, "Failed to switch to removable slot.")
+            return
+        }
+        SimNotificationService.scheduleSimNotification(
+            mContext, SimActivationNotifier.NotificationType.SWITCH_TO_REMOVABLE_SLOT
+        )
+    }
+
+    private fun handleSimRemove(removableSlotInfo: UiccSlotInfo) {
+        Log.i(TAG, "Handle SIM removed.")
+
+        if (!isSuwFinished(mContext!!)) {
+            Log.i(TAG, "Still in SUW. Handle SIM removal after SUW is finished")
+            setSuwRemovableSlotAction(mContext!!, LAST_USER_ACTION_IN_SUW_REMOVE)
+            return
+        }
+
+        val groupedEmbeddedSubscriptions =
+            groupedEmbeddedSubscriptions
+        if (groupedEmbeddedSubscriptions.isEmpty() || !removableSlotInfo.ports.stream()
+                .findFirst().get().isActive
+        ) {
+            Log.i(
+                TAG, ("eSIM slot is active or no subscriptions exist. Do nothing."
+                        + " The removableSlotInfo: " + removableSlotInfo
+                        + ", groupedEmbeddedSubscriptions: " + groupedEmbeddedSubscriptions)
+            )
+            return
+        }
+
+        // If there is only 1 eSIM profile exists, we ask the user if they want to switch to that
+        // profile.
+        if (groupedEmbeddedSubscriptions.size == 1) {
+            Log.i(TAG, "Only 1 eSIM profile found. Ask user's consent to switch.")
+            startSwitchSlotConfirmDialogActivity(groupedEmbeddedSubscriptions[0])
+            return
+        }
+
+        // If there are more than 1 eSIM profiles installed, we show a screen to let users to choose
+        // the number they want to use.
+        Log.i(TAG, "Multiple eSIM profiles found. Ask user which subscription to use.")
+        startChooseSimActivity(false)
+    }
+
+    private fun hasOtherActiveSubInfo(psimSubId: Int): Boolean {
+        val activeSubs = SubscriptionUtil.getActiveSubscriptions(mSubMgr)
+        return activeSubs.stream()
+            .anyMatch { subscriptionInfo -> subscriptionInfo.subscriptionId != psimSubId }
+    }
+
+    private fun hasAnyPortActiveInSlot(removableSlotInfo: UiccSlotInfo): Boolean {
+        return removableSlotInfo.ports.stream().anyMatch { slot -> slot.isActive }
+    }
+
+    private fun handleRemovableSimInsertWhenDsds(removableSlotInfo: UiccSlotInfo) {
+        Log.i(TAG, "ForNewUi: Handle Removable SIM inserted")
+        CoroutineScope(Dispatchers.Default + SupervisorJob()).launch {
+            withContext(Dispatchers.Default) {
+                val subscriptionInfos =
+                    withTimeoutOrNull(DEFAULT_WAIT_AFTER_SIM_INSERTED_TIMEOUT_MILLIS) {
+                        SubscriptionRepository(mContext!!)
+                            .removableSubscriptionInfoListFlow()
+                            .firstOrNull { it.isNotEmpty() }
+                    }
+
+                if (subscriptionInfos.isNullOrEmpty()) {
+                    Log.e(TAG, "Unable to find the removable subscriptionInfo. Do nothing.")
+                    return@withContext
+                }
+                Log.d(
+                    TAG,
+                    "getAvailableRemovableSubscription:$subscriptionInfos"
+                )
+                val psimSubId = subscriptionInfos[0].subscriptionId
+                if (!hasAnyPortActiveInSlot(removableSlotInfo)
+                        || hasOtherActiveSubInfo(psimSubId)) {
+                    Log.d(TAG, "ForNewUi Start Setup flow")
+                    startSimConfirmDialogActivity(psimSubId)
+                }
+            }
+        }
+    }
+
+    private fun handleRemovableSimInsertUnderDsdsMep(removableSlotInfo: UiccSlotInfo) {
+        Log.i(TAG, "Handle Removable SIM inserted under DSDS+Mep.")
+
+        if (removableSlotInfo.ports.stream().findFirst().get().isActive) {
+            Log.i(
+                TAG, "The removable slot is already active. Do nothing. removableSlotInfo: "
+                        + removableSlotInfo
+            )
+            return
+        }
+
+        val subscriptionInfos =
+            availableRemovableSubscription
+        if (subscriptionInfos.isEmpty()) {
+            Log.e(TAG, "Unable to find the removable subscriptionInfo. Do nothing.")
+            return
+        }
+        Log.d(
+            TAG,
+            "getAvailableRemovableSubscription:$subscriptionInfos"
+        )
+        startSimConfirmDialogActivity(subscriptionInfos[0].subscriptionId)
+    }
+
+    private fun getLastRemovableSimSlotState(context: Context): Int {
+        val prefs = context.getSharedPreferences(EUICC_PREFS, Context.MODE_PRIVATE)
+        return prefs.getInt(KEY_REMOVABLE_SLOT_STATE, UiccSlotInfo.CARD_STATE_INFO_ABSENT)
+    }
+
+    private fun setRemovableSimSlotState(context: Context, state: Int) {
+        val prefs = context.getSharedPreferences(EUICC_PREFS, Context.MODE_PRIVATE)
+        prefs.edit().putInt(KEY_REMOVABLE_SLOT_STATE, state).apply()
+        Log.d(TAG, "setRemovableSimSlotState: $state")
+    }
+
+    private fun getSuwRemovableSlotAction(context: Context): Int {
+        val prefs = context.getSharedPreferences(EUICC_PREFS, Context.MODE_PRIVATE)
+        return prefs.getInt(KEY_SUW_PSIM_ACTION, LAST_USER_ACTION_IN_SUW_NONE)
+    }
+
+    private fun setSuwRemovableSlotAction(context: Context, action: Int) {
+        val prefs = context.getSharedPreferences(EUICC_PREFS, Context.MODE_PRIVATE)
+        prefs.edit().putInt(KEY_SUW_PSIM_ACTION, action).apply()
+    }
+
+    private val removableUiccSlotInfo: UiccSlotInfo?
+        get() {
+            val slotInfos = mTelMgr!!.uiccSlotsInfo
+            if (slotInfos == null) {
+                Log.e(
+                    TAG,
+                    "slotInfos is null. Unable to get slot infos."
+                )
+                return null
+            }
+            for (slotInfo in slotInfos) {
+                if (slotInfo != null && slotInfo.isRemovable) {
+                    return slotInfo
+                }
+            }
+            return null
+        }
+
+    private fun hasActiveEsimSubscription(): Boolean {
+        val activeSubs = SubscriptionUtil.getActiveSubscriptions(mSubMgr)
+        return activeSubs.stream().anyMatch { subscriptionInfo -> subscriptionInfo.isEmbedded }
+    }
+
+    private val groupedEmbeddedSubscriptions: List<SubscriptionInfo>
+        get() {
+            val groupedSubscriptions =
+                SubscriptionUtil.getSelectableSubscriptionInfoList(mContext)
+                    ?: return ImmutableList.of()
+            return ImmutableList.copyOf(
+                groupedSubscriptions.stream()
+                    .filter { sub: SubscriptionInfo -> sub.isEmbedded }
+                    .collect(Collectors.toList()))
+        }
+
+    protected val availableRemovableSubscription: List<SubscriptionInfo>
+        get() {
+            val removableSubscriptions =
+                SubscriptionUtil.getAvailableSubscriptions(mContext)
+            return ImmutableList.copyOf(
+                removableSubscriptions.stream()
+                    // ToDo: This condition is for psim only. If device supports removable
+                    //  esim, it needs an new condition.
+                    .filter { sub: SubscriptionInfo -> !sub.isEmbedded }
+                    .collect(Collectors.toList()))
+        }
+
+    private fun startChooseSimActivity(psimInserted: Boolean) {
+        val intent = ChooseSimActivity.getIntent(mContext)
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        intent.putExtra(ChooseSimActivity.KEY_HAS_PSIM, psimInserted)
+        mContext!!.startActivityAsUser(intent, UserHandle.SYSTEM)
+    }
+
+    private fun startSwitchSlotConfirmDialogActivity(subscriptionInfo: SubscriptionInfo) {
+        val intent = Intent(
+            mContext,
+            SwitchToEsimConfirmDialogActivity::class.java
+        )
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        intent.putExtra(SwitchToEsimConfirmDialogActivity.KEY_SUB_TO_ENABLE, subscriptionInfo)
+        mContext!!.startActivityAsUser(intent, UserHandle.SYSTEM)
+    }
+
+    private fun startDsdsDialogActivity() {
+        val intent = Intent(mContext, DsdsDialogActivity::class.java)
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        mContext!!.startActivityAsUser(intent, UserHandle.SYSTEM)
+    }
+
+    private fun startSimConfirmDialogActivity(subId: Int) {
+        if (!isSuwFinished(mContext!!)) {
+            Log.d(TAG, "Still in SUW. Do nothing")
+            return
+        }
+        if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
+            Log.i(TAG, "Unable to enable subscription due to invalid subscription ID.")
+            return
+        }
+        Log.d(
+            TAG,
+            "Start ToggleSubscriptionDialogActivity with $subId under DSDS+Mep."
+        )
+        SubscriptionUtil.startToggleSubscriptionDialogActivity(mContext, subId, true, true)
+    }
+
+    private val isMultipleEnabledProfilesSupported: Boolean
+        get() {
+            val cardInfos = mTelMgr!!.uiccCardsInfo
+            if (cardInfos == null) {
+                Log.d(
+                    TAG,
+                    "UICC cards info list is empty."
+                )
+                return false
+            }
+            return cardInfos.stream()
+                .anyMatch { cardInfo: UiccCardInfo -> cardInfo.isMultipleEnabledProfilesSupported }
+        }
+
+    private fun isSuwFinished(context: Context): Boolean {
+        try {
+            // DEVICE_PROVISIONED is 0 if still in setup wizard. 1 if setup completed.
+            return (Settings.Global.getInt(
+                    context.contentResolver, Settings.Global.DEVICE_PROVISIONED)
+                    == 1)
+        } catch (e: SettingNotFoundException) {
+            Log.e(TAG, "Cannot get DEVICE_PROVISIONED from the device.", e)
+            return false
+        }
+    }
+
+    companion object {
+        private const val TAG = "SimSlotChangeHandler"
+
+        private const val EUICC_PREFS = "euicc_prefs"
+
+        // Shared preference keys
+        private const val KEY_REMOVABLE_SLOT_STATE = "removable_slot_state"
+        private const val KEY_SUW_PSIM_ACTION = "suw_psim_action"
+
+        // User's last removable SIM insertion / removal action during SUW.
+        private const val LAST_USER_ACTION_IN_SUW_NONE = 0
+        private const val LAST_USER_ACTION_IN_SUW_INSERT = 1
+        private const val LAST_USER_ACTION_IN_SUW_REMOVE = 2
+
+        private const val DEFAULT_WAIT_AFTER_SIM_INSERTED_TIMEOUT_MILLIS: Long = 25 * 1000L
+
+        @Volatile
+        private var slotChangeHandler: SimSlotChangeHandler? = null
+
+        /** Returns a SIM slot change handler singleton.  */
+        @JvmStatic
+        fun get(): SimSlotChangeHandler? {
+            if (slotChangeHandler == null) {
+                synchronized(SimSlotChangeHandler::class.java) {
+                    if (slotChangeHandler == null) {
+                        slotChangeHandler = SimSlotChangeHandler()
+                    }
+                }
+            }
+            return slotChangeHandler
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
index 5973d26..552a4a7 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
@@ -19,7 +19,6 @@
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
-import static com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -37,7 +36,6 @@
 import android.content.Intent;
 import android.icu.text.CaseMap;
 import android.os.Bundle;
-import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -57,7 +55,6 @@
 import com.android.settings.testutils.shadow.ShadowFragment;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
@@ -83,18 +80,11 @@
             PLACEHOLDER_PACKAGE_NAME + "tile.placeholder";
     private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
             PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
-    private static final ComponentName PLACEHOLDER_TILE_COMPONENT_NAME = new ComponentName(
-            PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
-    private static final String PLACEHOLDER_TILE_TOOLTIP_CONTENT =
-            PLACEHOLDER_PACKAGE_NAME + "tooltip_content";
-    private static final String PLACEHOLDER_DIALOG_TITLE = "title";
 
     private static final String SOFTWARE_SHORTCUT_KEY =
             Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
     private static final String HARDWARE_SHORTCUT_KEY =
             Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
     private TestAccessibilityShortcutPreferenceFragment mFragment;
     private PreferenceScreen mScreen;
     private Context mContext = ApplicationProvider.getApplicationContext();
@@ -153,14 +143,6 @@
 
     @Test
     @Config(shadows = ShadowFragment.class)
-    public void showQuickSettingsTooltipIfNeeded_dontShowTooltipView() {
-        mFragment.showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_EDIT);
-
-        assertThat(getLatestPopupWindow()).isNull();
-    }
-
-    @Test
-    @Config(shadows = ShadowFragment.class)
     public void showGeneralCategory_shouldInitCategory() {
         final Bundle savedInstanceState = new Bundle();
         when(mFragment.showGeneralCategory()).thenReturn(true);
@@ -261,16 +243,6 @@
         }
 
         @Override
-        protected ComponentName getTileComponentName() {
-            return PLACEHOLDER_TILE_COMPONENT_NAME;
-        }
-
-        @Override
-        protected CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) {
-            return PLACEHOLDER_TILE_TOOLTIP_CONTENT;
-        }
-
-        @Override
         public int getUserShortcutTypes() {
             return 0;
         }
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
index 86322f9..6dbb8b5 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
@@ -316,14 +316,6 @@
     }
 
     @Test
-    @Config(shadows = ShadowFragment.class)
-    public void showQuickSettingsTooltipIfNeeded_dontShowTooltipView() {
-        mFragment.showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_EDIT);
-
-        assertThat(getLatestPopupWindow()).isNull();
-    }
-
-    @Test
     public void getShortcutTypeSummary_shortcutSummaryIsCorrectlySet() {
         final PreferredShortcut userPreferredShortcut = new PreferredShortcut(
                 PLACEHOLDER_COMPONENT_NAME.flattenToString(),
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/display/DisplayTopologyPreferenceTest.kt b/tests/robotests/src/com/android/settings/connecteddevice/display/DisplayTopologyPreferenceTest.kt
new file mode 100644
index 0000000..ad633cc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/connecteddevice/display/DisplayTopologyPreferenceTest.kt
@@ -0,0 +1,120 @@
+/*
+ * 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.connecteddevice.display
+
+import android.hardware.display.DisplayTopology.TreeNode.POSITION_LEFT
+
+import android.content.Context
+import android.graphics.Color
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.ColorDrawable
+import android.hardware.display.DisplayTopology
+import android.view.View
+import android.widget.FrameLayout
+import androidx.preference.PreferenceViewHolder
+import androidx.test.core.app.ApplicationProvider
+
+import com.android.settings.R
+import com.google.common.truth.Truth.assertThat
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class DisplayTopologyPreferenceTest {
+    val context = ApplicationProvider.getApplicationContext<Context>()
+    val preference = DisplayTopologyPreference(context)
+    val injector = TestInjector()
+    val rootView = View.inflate(context, preference.layoutResource, /*parent=*/ null)
+    val holder = PreferenceViewHolder.createInstanceForTests(rootView)
+    val wallpaper = ColorDrawable(Color.MAGENTA)
+
+    init {
+        preference.injector = injector
+        injector.systemWallpaper = wallpaper
+        preference.onBindViewHolder(holder)
+    }
+
+    class TestInjector : DisplayTopologyPreference.Injector() {
+        var topology : DisplayTopology? = null
+        var systemWallpaper : Drawable? = null
+
+        override fun displayTopology(context : Context) : DisplayTopology? { return topology }
+
+        override fun wallpaper(context : Context) : Drawable { return systemWallpaper!! }
+    }
+
+    @Test
+    fun disabledTopology() {
+        preference.onAttached()
+        preference.onGlobalLayout()
+
+        assertThat(preference.mPaneContent.childCount).isEqualTo(0)
+        // TODO(b/352648432): update test when we show the main display even when
+        // a topology is not active.
+        assertThat(preference.mTopologyHint.text).isEqualTo("")
+    }
+
+    @Test
+    fun twoDisplaysGenerateBlocks() {
+        val child = DisplayTopology.TreeNode(
+                /* displayId= */ 42, /* width= */ 100f, /* height= */ 80f,
+                POSITION_LEFT, /* offset= */ 42f)
+        val root = DisplayTopology.TreeNode(
+                /* displayId= */ 0, /* width= */ 200f, /* height= */ 160f,
+                POSITION_LEFT, /* offset= */ 0f)
+        root.addChild(child)
+        injector.topology = DisplayTopology(root, /*primaryDisplayId=*/ 0)
+
+        // This layoutParams needs to be non-null for the global layout handler.
+        preference.mPaneHolder.layoutParams = FrameLayout.LayoutParams(
+                /* width= */ 640, /* height= */ 480)
+
+        // Force pane width to have a reasonable value (hundreds of dp) so the TopologyScale is
+        // calculated reasonably.
+        preference.mPaneContent.left = 0
+        preference.mPaneContent.right = 640
+
+        preference.onAttached()
+        preference.onGlobalLayout()
+
+        assertThat(preference.mPaneContent.childCount).isEqualTo(2)
+        val block0 = preference.mPaneContent.getChildAt(0)
+        val block1 = preference.mPaneContent.getChildAt(1)
+
+        // Block of child display is on the left.
+        val (childBlock, rootBlock) = if (block0.x < block1.x)
+                listOf(block0, block1)
+        else
+                listOf(block1, block0)
+
+        // After accounting for padding, child should be half the length of root in each dimension.
+        assertThat(childBlock.layoutParams.width + BLOCK_PADDING)
+                .isEqualTo(rootBlock.layoutParams.width / 2)
+        assertThat(childBlock.layoutParams.height + BLOCK_PADDING)
+                .isEqualTo(rootBlock.layoutParams.height / 2)
+        assertThat(childBlock.y).isGreaterThan(rootBlock.y)
+        assertThat(block0.background).isEqualTo(wallpaper)
+        assertThat(block1.background).isEqualTo(wallpaper)
+        assertThat(rootBlock.x - BLOCK_PADDING * 2)
+                .isEqualTo(childBlock.x + childBlock.layoutParams.width)
+
+        assertThat(preference.mTopologyHint.text)
+                .isEqualTo(context.getString(R.string.external_display_topology_hint))
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/datetime/AutoTimeFormatPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/AutoTimeFormatPreferenceControllerTest.java
deleted file mode 100644
index f9b566e..0000000
--- a/tests/robotests/src/com/android/settings/datetime/AutoTimeFormatPreferenceControllerTest.java
+++ /dev/null
@@ -1,152 +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.datetime;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.content.Intent;
-import android.provider.Settings;
-import android.text.format.DateFormat;
-
-import androidx.preference.SwitchPreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowApplication;
-
-import java.util.List;
-import java.util.Locale;
-
-@RunWith(RobolectricTestRunner.class)
-public class AutoTimeFormatPreferenceControllerTest {
-
-    @Mock
-    private UpdateTimeAndDateCallback mCallback;
-
-    private ShadowApplication mApplication;
-    private Context mContext;
-    private SwitchPreference mPreference;
-    private TestAutoTimeFormatPreferenceController mController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mApplication = ShadowApplication.getInstance();
-        mContext = RuntimeEnvironment.application;
-        mController = new TestAutoTimeFormatPreferenceController(mContext, "test_key");
-        mPreference = new SwitchPreference(mContext);
-        mPreference.setKey("test_key");
-    }
-
-    @Test
-    public void updateState_24HourSet_shouldCheckPreference() {
-        Settings.System.putString(mContext.getContentResolver(), Settings.System.TIME_12_24,
-                TimeFormatPreferenceController.HOURS_24);
-
-        mController.updateState(mPreference);
-
-        assertThat(mPreference.isChecked()).isFalse();
-    }
-
-    @Test
-    public void updateState_12HourSet_shouldCheckPreference() {
-        Settings.System.putString(mContext.getContentResolver(), Settings.System.TIME_12_24,
-                TimeFormatPreferenceController.HOURS_12);
-
-        mController.updateState(mPreference);
-
-        assertThat(mPreference.isChecked()).isFalse();
-    }
-
-    @Test
-    public void updateState_autoSet_shouldNotCheckPreference() {
-        Settings.System.putString(mContext.getContentResolver(), Settings.System.TIME_12_24, null);
-
-        mController.updateState(mPreference);
-
-        assertThat(mPreference.isChecked()).isTrue();
-    }
-
-    @Test
-    public void updatePreference_autoSet_shouldSendIntent_12HourLocale() {
-        mController.setChecked(false);
-
-        List<Intent> intentsFired = mApplication.getBroadcastIntents();
-        assertThat(intentsFired.size()).isEqualTo(1);
-        Intent intentFired = intentsFired.get(0);
-        assertThat(intentFired.getAction()).isEqualTo(Intent.ACTION_TIME_CHANGED);
-        assertThat(intentFired.getIntExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, -1))
-                .isEqualTo(Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR);
-    }
-
-    @Test
-    public void updatePreference_autoSet_shouldSendIntent_24HourLocale() {
-        mController.setIs24HourLocale(true);
-
-        mController.setChecked(false);
-
-        List<Intent> intentsFired = mApplication.getBroadcastIntents();
-        assertThat(intentsFired.size()).isEqualTo(1);
-        Intent intentFired = intentsFired.get(0);
-        assertThat(intentFired.getAction()).isEqualTo(Intent.ACTION_TIME_CHANGED);
-        assertThat(intentFired.getIntExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, -1))
-                .isEqualTo(Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR);
-    }
-
-    @Test
-    public void updatePreference_24HourSet_shouldSendIntent() {
-        mController.setIs24HourLocale(false);
-
-        mController.setChecked(true);
-
-        List<Intent> intentsFired = mApplication.getBroadcastIntents();
-        assertThat(intentsFired.size()).isEqualTo(1);
-        Intent intentFired = intentsFired.get(0);
-        assertThat(intentFired.getAction()).isEqualTo(Intent.ACTION_TIME_CHANGED);
-        assertThat(intentFired.getIntExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, -1))
-                .isEqualTo(Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT);
-    }
-
-    /**
-     * Extend class under test to change {@link #is24HourLocale} to not call
-     * {@link DateFormat#is24HourLocale(Locale)} because that's not available in roboelectric.
-     */
-    private static class TestAutoTimeFormatPreferenceController
-            extends AutoTimeFormatPreferenceController {
-
-        private boolean is24HourLocale = false;
-
-        TestAutoTimeFormatPreferenceController(Context context, String preferenceKey) {
-            super(context, preferenceKey);
-        }
-
-        void setIs24HourLocale(boolean value) {
-            is24HourLocale = value;
-        }
-
-        @Override
-        boolean is24HourLocale(Locale locale) {
-            return is24HourLocale;
-        }
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java
index 7bf8d52..2961935 100644
--- a/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java
@@ -40,17 +40,12 @@
 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;
@@ -62,9 +57,6 @@
 @RunWith(RobolectricTestRunner.class)
 public class AutoTimeZonePreferenceControllerTest {
 
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
     @Mock
     private UpdateTimeAndDateCallback mCallback;
     private Context mContext;
@@ -247,7 +239,6 @@
     }
 
     @Test
-    @EnableFlags({Flags.FLAG_REVAMP_TOGGLES})
     public void toggleOff_revampFlagOn_shouldToggleOffUseLocation() {
         TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = createCapabilitiesAndConfig(
                 /* autoSupported= */ true,
@@ -266,25 +257,6 @@
         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);
diff --git a/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
index 40794d2..2f23257 100644
--- a/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
@@ -45,17 +45,13 @@
 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;
@@ -71,9 +67,6 @@
 })
 public class LocationTimeZoneDetectionPreferenceControllerTest {
 
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
     @Mock
     private TimeManager mTimeManager;
     private Context mContext;
@@ -131,8 +124,7 @@
     }
 
     @Test
-    @EnableFlags({Flags.FLAG_REVAMP_TOGGLES})
-    public void flagRevampTogglesOn_toggleOff_automaticTimeZone_disablesLocationToggle() {
+    public void toggleOff_automaticTimeZone_disablesLocationToggle() {
         TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
                 createTimeZoneCapabilitiesAndConfig(/* useLocationEnabled= */ true,
                         CAPABILITY_POSSESSED, /* setAutoDetectionEnabled= */ false);
diff --git a/tests/robotests/src/com/android/settings/datetime/TimeFormatPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/TimeFormatPreferenceControllerTest.java
index c5aac84..a341922 100644
--- a/tests/robotests/src/com/android/settings/datetime/TimeFormatPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/TimeFormatPreferenceControllerTest.java
@@ -23,16 +23,11 @@
 
 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;
@@ -46,9 +41,6 @@
 @RunWith(RobolectricTestRunner.class)
 public class TimeFormatPreferenceControllerTest {
 
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
     @Mock
     private UpdateTimeAndDateCallback mCallback;
 
@@ -105,16 +97,6 @@
     }
 
     @Test
-    @DisableFlags({Flags.FLAG_REVAMP_TOGGLES})
-    public void updateState_autoSet_shouldNotEnablePreference() {
-        Settings.System.putString(mContext.getContentResolver(), Settings.System.TIME_12_24, null);
-
-        mController.updateState(mPreference);
-
-        assertThat(mPreference.isEnabled()).isFalse();
-    }
-
-    @Test
     public void updatePreference_12HourSet_shouldSendIntent() {
         mController.setChecked(false);
 
diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsTest.java
index a03ca61..1ce6c3f 100644
--- a/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/OneHandedSettingsTest.java
@@ -21,7 +21,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.os.SystemProperties;
@@ -32,8 +31,6 @@
 
 import androidx.test.core.app.ApplicationProvider;
 
-import com.android.settings.R;
-import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
 import com.android.settingslib.search.SearchIndexableRaw;
 
 import org.junit.Before;
@@ -63,21 +60,6 @@
     }
 
     @Test
-    public void getTileTooltipContent_returnsExpectedValues() {
-        // Simulate to call getTileTooltipContent after onDetach
-        assertThat(mSettings.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_EDIT))
-                .isNull();
-        // Simulate to call getTileTooltipContent after onAttach
-        when(mSettings.getContext()).thenReturn(mContext);
-        assertThat(mSettings.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_EDIT))
-                .isEqualTo(mContext.getText(
-                        R.string.accessibility_one_handed_mode_qs_tooltip_content));
-        assertThat(mSettings.getTileTooltipContent(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE))
-                .isEqualTo(mContext.getText(
-                        R.string.accessibility_one_handed_mode_auto_added_qs_tooltip_content));
-    }
-
-    @Test
     public void getLogTag_returnsCorrectTag() {
         assertThat(mSettings.getLogTag()).isEqualTo("OneHandedSettings");
     }
diff --git a/tests/unit/src/com/android/settings/accessibility/ReduceBrightColorsIntensityPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/ReduceBrightColorsIntensityPreferenceControllerTest.java
index c3ccf34..96d9583 100644
--- a/tests/unit/src/com/android/settings/accessibility/ReduceBrightColorsIntensityPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/accessibility/ReduceBrightColorsIntensityPreferenceControllerTest.java
@@ -24,20 +24,29 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.internal.R;
+import com.android.server.display.feature.flags.Flags;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/** Tests for {@link ReduceBrightColorsIntensityPreferenceController} */
 @RunWith(AndroidJUnit4.class)
 public class ReduceBrightColorsIntensityPreferenceControllerTest {
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private Context mContext;
     private Resources mResources;
     private ReduceBrightColorsIntensityPreferenceController mPreferenceController;
@@ -52,27 +61,119 @@
     }
 
     @Test
-    public void isAvailable_configuredRbcAvailable_enabledRbc_shouldReturnTrue() {
+    @DisableFlags(Flags.FLAG_EVEN_DIMMER)
+    public void isAvailable_whenEvenDimmerOffAndDisabled_RbcOnAndAvailable_returnTrue() {
+        doReturn(false).when(mResources).getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
         doReturn(true).when(mResources).getBoolean(
                 R.bool.config_reduceBrightColorsAvailable);
+
         assertThat(mPreferenceController.isAvailable()).isTrue();
     }
+
     @Test
-    public void isAvailable_configuredRbcAvailable_disabledRbc_shouldReturnTrue() {
+    @DisableFlags(Flags.FLAG_EVEN_DIMMER)
+    public void isAvailable_whenEvenDimmerOffAndDisabled_RbcOffAndAvailable_returnTrue() {
+        doReturn(false).when(mResources).getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 0);
         doReturn(true).when(mResources).getBoolean(
                 R.bool.config_reduceBrightColorsAvailable);
+
         assertThat(mPreferenceController.isAvailable()).isTrue();
     }
+
     @Test
-    public void isAvailable_configuredRbcUnavailable_enabledRbc_shouldReturnFalse() {
+    @DisableFlags(Flags.FLAG_EVEN_DIMMER)
+    public void isAvailable_whenEvenDimmerOffAndDisabled_RbcOnAndUnavailable_returnFalse() {
+        doReturn(false).when(mResources).getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
         doReturn(false).when(mResources).getBoolean(
                 R.bool.config_reduceBrightColorsAvailable);
+
+        assertThat(mPreferenceController.isAvailable()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_EVEN_DIMMER)
+    public void isAvailable_whenEvenDimmerOnAndDisabled_RbcOnAndAvailable_returnTrue() {
+        doReturn(false).when(mResources).getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
+        doReturn(true).when(mResources).getBoolean(
+                R.bool.config_reduceBrightColorsAvailable);
+
+        assertThat(mPreferenceController.isAvailable()).isTrue();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_EVEN_DIMMER)
+    public void isAvailable_whenEvenDimmerOnAndDisabled_RbcOffAndAvailable_returnTrue() {
+        doReturn(false).when(mResources).getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 0);
+        doReturn(true).when(mResources).getBoolean(
+                R.bool.config_reduceBrightColorsAvailable);
+
+        assertThat(mPreferenceController.isAvailable()).isTrue();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_EVEN_DIMMER)
+    public void isAvailable_whenEvenDimmerOnAndDisabled_RbcOnAndUnavailable_returnFalse() {
+        doReturn(false).when(mResources).getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
+        doReturn(false).when(mResources).getBoolean(
+                R.bool.config_reduceBrightColorsAvailable);
+
+        assertThat(mPreferenceController.isAvailable()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_EVEN_DIMMER)
+    public void isAvailable_whenEvenDimmerOnAndEnabled_RbcOnAndAvailable_returnFalse() {
+        doReturn(true).when(mResources).getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
+        doReturn(true).when(mResources).getBoolean(
+                R.bool.config_reduceBrightColorsAvailable);
+
+        assertThat(mPreferenceController.isAvailable()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_EVEN_DIMMER)
+    public void isAvailable_whenEvenDimmerOnAndEnabled_RbcOffAndAvailable_returnFalse() {
+        doReturn(true).when(mResources).getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 0);
+        doReturn(true).when(mResources).getBoolean(
+                R.bool.config_reduceBrightColorsAvailable);
+
+        assertThat(mPreferenceController.isAvailable()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_EVEN_DIMMER)
+    public void isAvailable_whenEvenDimmerOnAndEnabled_RbcOnAndUnavailable_returnFalse() {
+        doReturn(true).when(mResources).getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled);
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
+        doReturn(false).when(mResources).getBoolean(
+                R.bool.config_reduceBrightColorsAvailable);
+
         assertThat(mPreferenceController.isAvailable()).isFalse();
     }
 
diff --git a/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java b/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java
index 656fa27..2209355 100644
--- a/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/language/LanguagePreferenceControllerTest.java
@@ -21,18 +21,24 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 
 import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.Settings;
+import com.android.settings.flags.Flags;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
 public class LanguagePreferenceControllerTest {
     private Context mContext;
     private LanguagePreferenceController mController;
 
+    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     @Before
     public void setup() {
         mContext = ApplicationProvider.getApplicationContext();
@@ -40,6 +46,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED)
     public void getAvailabilityStatus_featureFlagOff_LanguageSettingsActivitydisabled() {
         mController.getAvailabilityStatus();
 
diff --git a/tests/unit/src/com/android/settings/network/telephony/CellInfoUtilTest.kt b/tests/unit/src/com/android/settings/network/telephony/CellInfoUtilTest.kt
index 27b5c38..c6974ab 100644
--- a/tests/unit/src/com/android/settings/network/telephony/CellInfoUtilTest.kt
+++ b/tests/unit/src/com/android/settings/network/telephony/CellInfoUtilTest.kt
@@ -24,6 +24,7 @@
 import com.android.settings.network.telephony.CellInfoUtil.getNetworkTitle
 import com.android.settings.network.telephony.CellInfoUtil.getOperatorNumeric
 import com.google.common.truth.Truth.assertThat
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -95,6 +96,7 @@
     }
 
     @Test
+    @Ignore("b/383858953")
     fun cellInfoListToString() {
         val cellInfoList =
             listOf(