Merge "Support fetching PackageInfo for archived apps" into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9b9efe9..a08bda3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3090,23 +3090,6 @@
             </intent-filter>
         </activity>
 
-        <!-- NFC settings -->
-        <activity
-            android:name="Settings$AndroidBeamSettingsActivity"
-            android:exported="true"
-            android:label="@string/android_beam_settings_title">
-            <intent-filter android:priority="1">
-                <action android:name="android.settings.NFCSHARING_SETTINGS" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.nfc.AndroidBeam" />
-            <meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
-                       android:value="@string/menu_key_connected_devices"/>
-            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
-                android:value="true" />
-        </activity>
-
         <activity
             android:name="Settings$WifiDisplaySettingsActivity"
             android:label="@string/wifi_display_settings_title"
diff --git a/aconfig/settings_connecteddevice_flag_declarations.aconfig b/aconfig/settings_connecteddevice_flag_declarations.aconfig
index 450fc0d..07aaecc 100644
--- a/aconfig/settings_connecteddevice_flag_declarations.aconfig
+++ b/aconfig/settings_connecteddevice_flag_declarations.aconfig
@@ -13,3 +13,10 @@
   description: "Gates whether to enable LE audio sharing"
   bug: "305620450"
 }
+
+flag {
+  name: "enable_le_audio_qr_code_private_broadcast_sharing"
+  namespace: "pixel_cross_device_control"
+  description: "Gates whether to enable LE audio private broadcast sharing via QR code"
+  bug: "308368124"
+}
diff --git a/res/drawable/ic_audio_calls_and_alarms.xml b/res/drawable/ic_audio_calls_and_alarms.xml
new file mode 100644
index 0000000..5da27c6
--- /dev/null
+++ b/res/drawable/ic_audio_calls_and_alarms.xml
@@ -0,0 +1,32 @@
+<!--
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0"
+    android:tint="?android:attr/colorControlNormal">
+    <path
+        android:pathData="M3,15V9H7L12,4V20L7,15H3ZM10,15.17V8.83L7.83,11H5V13H7.83L10,15.17Z"
+        android:fillType="evenOdd"
+        android:fillColor="?android:attr/colorPrimary"/>
+    <path
+        android:pathData="M16.5,12C16.5,10.23 15.48,8.71 14,7.97V16.02C15.48,15.29 16.5,13.77 16.5,12Z"
+        android:fillColor="?android:attr/colorPrimary"/>
+    <path
+        android:pathData="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.85 14,18.71V20.77C18.01,19.86 21,16.28 21,12C21,7.72 18.01,4.14 14,3.23Z"
+        android:fillColor="?android:attr/colorPrimary"/>
+</vector>
diff --git a/res/layout/accessibility_shortcut_secondary_action.xml b/res/layout/accessibility_shortcut_secondary_action.xml
index b3b81fe..80defdb 100644
--- a/res/layout/accessibility_shortcut_secondary_action.xml
+++ b/res/layout/accessibility_shortcut_secondary_action.xml
@@ -93,7 +93,7 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:gravity="end|center_vertical"
-        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingHorizontal="?android:attr/listPreferredItemPaddingEnd"
         android:minWidth="58dp"
         android:orientation="vertical" />
 
diff --git a/res/layout/preference_widget_switch_compat.xml b/res/layout/preference_widget_switch_compat.xml
new file mode 100644
index 0000000..e833171
--- /dev/null
+++ b/res/layout/preference_widget_switch_compat.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<com.google.android.material.materialswitch.MaterialSwitch
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/switchWidget"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@null"
+    android:clickable="false"
+    android:focusable="false"
+    android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
diff --git a/res/values/config.xml b/res/values/config.xml
index f60b58c..99052ca 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -529,10 +529,14 @@
         <item>content://com.android.settings.slices/intent/media_output_indicator</item>
     </string-array>
 
-    <!-- List containing the apps keep in battery mode = "Optimize" -->
+    <!-- List containing the apps keep in battery mode = "Optimized" -->
     <string-array name="config_force_battery_optimize_mode_apps" translatable="false">
     </string-array>
 
+    <!-- List containing the apps keep in battery mode = "Unrestricted" -->
+    <string-array name="config_force_battery_unrestrict_mode_apps" translatable="false">
+    </string-array>
+
     <!-- Uri to query non-public Slice Uris. -->
     <string name="config_non_public_slice_query_uri" translatable="false"></string>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1485405..ba56c53 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -292,6 +292,17 @@
     <string name="audio_sharing_title">Audio sharing</string>
     <!-- Title for audio sharing primary switch [CHAR LIMIT=none]-->
     <string name="audio_sharing_switch_title">Share audio</string>
+    <!-- Title for calls and alarms device on audio sharing page [CHAR LIMIT=none]-->
+    <string name="calls_and_alarms_device_title">Calls and alarms</string>
+
+    <!-- Title for audio streams preference category [CHAR LIMIT=none]-->
+    <string name="audio_sharing_streams_category_title">Connect to a LE audio stream</string>
+    <!-- Title for audio streams preference [CHAR LIMIT=none]-->
+    <string name="audio_sharing_streams_pref_title">Nearby audio streams</string>
+    <!-- Title for audio streams page [CHAR LIMIT=none]-->
+    <string name="audio_sharing_streams_title">Audio streams</string>
+    <!-- Summary for QR code scanning in audio streams page [CHAR LIMIT=none]-->
+    <string name="audio_sharing_streams_qr_code_summary">Connect to an audio stream using QR code</string>
 
     <!-- Date & time settings screen title -->
     <string name="date_and_time">Date &amp; time</string>
@@ -4633,8 +4644,6 @@
     <string name="accessibility_tutorial_dialog_title_volume">Hold volume keys to open</string>
     <!-- Title for the accessibility tutorial dialog in accessibility service with triple tap. [CHAR LIMIT=100] -->
     <string name="accessibility_tutorial_dialog_title_triple">Triple tap screen to open</string>
-    <!-- Title for the accessibility tutorial dialog in accessibility service with two finger triple tap. [CHAR LIMIT=100] -->
-    <string name="accessibility_tutorial_dialog_title_two_finger_triple">Two finger triple tap screen to open</string>
     <!-- Title for the accessibility tutorial dialog in accessibility service with gesture. [CHAR LIMIT=50] -->
     <string name="accessibility_tutorial_dialog_title_gesture">Use gesture to open</string>
     <!-- Title for the accessibility tutorial dialog in gesture navigation settings. [CHAR LIMIT=50] -->
@@ -4647,8 +4656,6 @@
     <string name="accessibility_tutorial_dialog_message_volume">To use this feature, press &amp; hold both volume keys.</string>
     <!-- Instruction for the accessibility tutorial dialog in accessibility service with triple tap. [CHAR LIMIT=100] -->
     <string name="accessibility_tutorial_dialog_message_triple">To start and stop magnification, triple-tap anywhere on your screen.</string>
-    <!-- Instruction for the accessibility tutorial dialog in accessibility service with two finger triple tap. [CHAR LIMIT=100] -->
-    <string name="accessibility_tutorial_dialog_message_two_finger_triple">To start and stop magnification, triple-tap anywhere on your screen with two fingers.</string>
     <!-- Message for the accessibility tutorial dialog when user enables an accessibility service while using gesture navigation and touch exploration is not enabled. [CHAR LIMIT=NONE] -->
     <string name="accessibility_tutorial_dialog_message_gesture">To use this feature, swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold.</string>
     <!-- Message for the accessibility tutorial dialog when user enables an accessibility service while using gesture navigation and touch exploration is enabled. [CHAR LIMIT=NONE] -->
diff --git a/res/xml/bluetooth_audio_sharing.xml b/res/xml/bluetooth_audio_sharing.xml
index a90da72..86bb062 100644
--- a/res/xml/bluetooth_audio_sharing.xml
+++ b/res/xml/bluetooth_audio_sharing.xml
@@ -19,4 +19,24 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/audio_sharing_title">
 
+    <Preference
+        android:key="calls_and_alarms"
+        android:title="@string/calls_and_alarms_device_title"
+        android:icon="@drawable/ic_audio_calls_and_alarms"
+        settings:controller="com.android.settings.connecteddevice.audiosharing.CallsAndAlarmsPreferenceController"
+        android:summary=""/>
+
+    <PreferenceCategory
+        android:key="audio_streams_settings_category"
+        android:title="@string/audio_sharing_streams_category_title"
+        settings:controller="com.android.settings.connecteddevice.audiosharing.AudioStreamsCategoryController" >
+
+        <Preference
+            android:key="audio_streams_settings"
+            android:fragment="com.android.settings.connecteddevice.audiosharing.AudioStreamsDashboardFragment"
+            android:title="@string/audio_sharing_streams_pref_title"
+            android:icon="@drawable/ic_chevron_right_24dp" />
+
+    </PreferenceCategory>
+
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/bluetooth_audio_streams.xml b/res/xml/bluetooth_audio_streams.xml
new file mode 100644
index 0000000..9d05a06
--- /dev/null
+++ b/res/xml/bluetooth_audio_streams.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/audio_sharing_streams_title">
+
+    <Preference
+        android:key="audio_streams_scan_qr_code"
+        android:title="@string/bluetooth_find_broadcast_button_scan"
+        android:icon="@drawable/ic_add_24dp"
+        android:summary="@string/audio_sharing_streams_qr_code_summary"/>
+
+</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml
index c52140c..59c0c21 100644
--- a/res/xml/configure_notification_settings.xml
+++ b/res/xml/configure_notification_settings.xml
@@ -174,7 +174,7 @@
             android:title="@string/notification_pulse_title"
             settings:controller="com.android.settings.notification.PulseNotificationPreferenceController"/>
 
-        <SwitchPreference
+        <SwitchPreferenceCompat
             android:key="notification_assistant"
             android:order="25"
             android:title="@string/notification_assistant_title"
diff --git a/res/xml/connected_devices_advanced.xml b/res/xml/connected_devices_advanced.xml
index 3c66998..cb4167b 100644
--- a/res/xml/connected_devices_advanced.xml
+++ b/res/xml/connected_devices_advanced.xml
@@ -54,14 +54,6 @@
         settings:keywords="@string/keywords_wifi_display_settings"/>
 
     <com.android.settingslib.RestrictedPreference
-        android:fragment="com.android.settings.nfc.AndroidBeam"
-        android:key="android_beam_settings"
-        android:title="@string/android_beam_settings_title"
-        settings:controller="com.android.settings.nfc.AndroidBeamPreferenceController"
-        android:icon="@drawable/ic_android"
-        android:order="-5"/>
-
-    <com.android.settingslib.RestrictedPreference
         android:key="connected_device_printing"
         android:title="@string/print_settings"
         android:summary="@string/summary_placeholder"
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index 9325969..29c3c62 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -114,7 +114,7 @@
             settings:controller="com.android.settings.deviceinfo.HardwareInfoPreferenceController"/>
 
         <!-- EID -->
-        <com.android.settings.network.telephony.TelephonyPreferenceDialog
+        <com.android.settingslib.CustomDialogPreferenceCompat
             android:key="eid_info"
             android:order="31"
             android:title="@string/status_eid"
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 7ea4be4..49b2174 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -314,7 +314,6 @@
     public static class ConfigureWifiSettingsActivity extends SettingsActivity { /* empty */ }
     public static class SavedAccessPointsSettingsActivity extends SettingsActivity { /* empty */ }
     public static class TextToSpeechSettingsActivity extends SettingsActivity { /* empty */ }
-    public static class AndroidBeamSettingsActivity extends SettingsActivity { /* empty */ }
     public static class WifiDisplaySettingsActivity extends SettingsActivity { /* empty */ }
     public static class DreamSettingsActivity extends SettingsActivity { /* empty */ }
     /** Activity to manage communal settings */
diff --git a/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java b/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java
index e90ed87..ee2dc05 100644
--- a/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java
+++ b/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java
@@ -54,7 +54,6 @@
 import androidx.viewpager.widget.PagerAdapter;
 import androidx.viewpager.widget.ViewPager;
 
-import com.android.server.accessibility.Flags;
 import com.android.settings.R;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settingslib.widget.LottieColorUtils;
@@ -412,23 +411,6 @@
         return new TutorialPage(type, title, image, indicatorIcon, instruction);
     }
 
-    private static TutorialPage createTwoFingerTripleTapTutorialPage(@NonNull Context context) {
-        // TODO(b/308088945): Update tutorial string and image when UX provides them
-        final int type = UserShortcutType.TWOFINGERTRIPLETAP;
-        final CharSequence title =
-                context.getText(R.string.accessibility_tutorial_dialog_title_two_finger_triple);
-        final View image =
-                createIllustrationViewWithImageRawResource(context,
-                        R.raw.a11y_shortcut_type_triple_tap);
-        final CharSequence instruction =
-                context.getText(R.string.accessibility_tutorial_dialog_message_two_finger_triple);
-        final ImageView indicatorIcon =
-                createImageView(context, R.drawable.ic_accessibility_page_indicator);
-        indicatorIcon.setEnabled(false);
-
-        return new TutorialPage(type, title, image, indicatorIcon, instruction);
-    }
-
     @VisibleForTesting
     static List<TutorialPage> createShortcutTutorialPages(@NonNull Context context,
             int shortcutTypes) {
@@ -445,13 +427,6 @@
             tutorialPages.add(createTripleTapTutorialPage(context));
         }
 
-        if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
-            if ((shortcutTypes & UserShortcutType.TWOFINGERTRIPLETAP)
-                    == UserShortcutType.TWOFINGERTRIPLETAP) {
-                tutorialPages.add(createTwoFingerTripleTapTutorialPage(context));
-            }
-        }
-
         return tutorialPages;
     }
 
diff --git a/src/com/android/settings/accessibility/ShortcutPreference.java b/src/com/android/settings/accessibility/ShortcutPreference.java
index 4b6868e..a04f8f4 100644
--- a/src/com/android/settings/accessibility/ShortcutPreference.java
+++ b/src/com/android/settings/accessibility/ShortcutPreference.java
@@ -62,7 +62,7 @@
     ShortcutPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
         setLayoutResource(R.layout.accessibility_shortcut_secondary_action);
-        setWidgetLayoutResource(com.android.settingslib.R.layout.preference_widget_primary_switch);
+        setWidgetLayoutResource(androidx.preference.R.layout.preference_widget_switch_compat);
         setIconSpaceReserved(false);
         // Treat onSettingsClicked as this preference's click.
         setOnPreferenceClickListener(preference -> {
@@ -89,7 +89,7 @@
         }
 
         CompoundButton switchWidget =
-                holder.itemView.findViewById(com.android.settingslib.R.id.switchWidget);
+                holder.itemView.findViewById(androidx.preference.R.id.switchWidget);
         if (switchWidget != null) {
             // Consumes move events to ignore drag actions.
             switchWidget.setOnTouchListener((v, event) -> {
diff --git a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
index e2d92c7..8e230cb 100644
--- a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
@@ -17,12 +17,10 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.nfc.AndroidBeamPreferenceController;
 import com.android.settings.print.PrintSettingPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.uwb.UwbPreferenceController;
@@ -112,17 +110,6 @@
                 }
 
                 @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    final List<String> keys = super.getNonIndexableKeys(context);
-                    PackageManager pm = context.getPackageManager();
-                    if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
-                        keys.add(AndroidBeamPreferenceController.KEY_ANDROID_BEAM_SETTINGS);
-                    }
-
-                    return keys;
-                }
-
-                @Override
                 public List<AbstractPreferenceController> createPreferenceControllers(
                         Context context) {
                     return buildControllers(context, null /* lifecycle */);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
index 370b69a..b9ef8f4 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDashboardFragment.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.connecteddevice.audiosharing;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
 
@@ -36,8 +37,7 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO: update category id.
-        return 0;
+        return SettingsEnums.AUDIO_SHARING_SETTINGS;
     }
 
     @Override
@@ -63,6 +63,7 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
+        use(CallsAndAlarmsPreferenceController.class).init(this);
     }
 
     @Override
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsCategoryController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsCategoryController.java
new file mode 100644
index 0000000..e25a6ab
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsCategoryController.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.connecteddevice.audiosharing;
+
+import android.content.Context;
+
+import com.android.settings.flags.Flags;
+import com.android.settings.widget.PreferenceCategoryController;
+
+public class AudioStreamsCategoryController extends PreferenceCategoryController {
+
+    public AudioStreamsCategoryController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return Flags.enableLeAudioQrCodePrivateBroadcastSharing() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsDashboardFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsDashboardFragment.java
new file mode 100644
index 0000000..40a8b29
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioStreamsDashboardFragment.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.connecteddevice.audiosharing;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+
+public class AudioStreamsDashboardFragment extends DashboardFragment {
+    private static final String TAG = "AudioStreamsDashboardFrag";
+
+    public AudioStreamsDashboardFragment() {
+        super();
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO: update category id.
+        return 0;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
+    public int getHelpResource() {
+        return R.string.help_url_audio_sharing;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.bluetooth_audio_streams;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java
new file mode 100644
index 0000000..0577f70
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsDialogFragment.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.connecteddevice.audiosharing;
+
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.os.Bundle;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.flags.Flags;
+
+/** Provides a dialog to choose the active device for calls and alarms. */
+public class CallsAndAlarmsDialogFragment extends InstrumentedDialogFragment {
+    private static final String TAG = "CallsAndAlarmsDialog";
+
+    @Override
+    public int getMetricsCategory() {
+        return SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_ACTIVE;
+    }
+
+    /**
+     * Display the {@link CallsAndAlarmsDialogFragment} dialog.
+     *
+     * @param host The Fragment this dialog will be hosted.
+     */
+    public static void show(Fragment host) {
+        if (!Flags.enableLeAudioSharing()) return;
+        final FragmentManager manager = host.getChildFragmentManager();
+        if (manager.findFragmentByTag(TAG) == null) {
+            final CallsAndAlarmsDialogFragment dialog = new CallsAndAlarmsDialogFragment();
+            dialog.show(manager, TAG);
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // TODO: use real device names
+        String[] choices = {"Buds 1", "Buds 2"};
+        AlertDialog.Builder builder =
+                new AlertDialog.Builder(getActivity())
+                        .setTitle(R.string.calls_and_alarms_device_title)
+                        .setSingleChoiceItems(
+                                choices,
+                                0, // TODO: set to current active device.
+                                (dialog, which) -> {
+                                    // TODO: set device to active device for calls and alarms.
+                                });
+        return builder.create();
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceController.java
new file mode 100644
index 0000000..480b257
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/CallsAndAlarmsPreferenceController.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.connecteddevice.audiosharing;
+
+import android.content.Context;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.flags.Flags;
+
+/** PreferenceController to control the dialog to choose the active device for calls and alarms */
+public class CallsAndAlarmsPreferenceController extends BasePreferenceController {
+
+    private static final String TAG = "CallsAndAlarmsPreferenceController";
+
+    private static final String PREF_KEY = "calls_and_alarms";
+
+    private Preference mPreference;
+    private DashboardFragment mFragment;
+
+    public CallsAndAlarmsPreferenceController(Context context) {
+        super(context, PREF_KEY);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return Flags.enableLeAudioSharing() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return PREF_KEY;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+        mPreference.setOnPreferenceClickListener(
+                preference -> {
+                    if (mFragment != null) {
+                        CallsAndAlarmsDialogFragment.show(mFragment);
+                    } else {
+                        Log.w(TAG, "Dialog fail to show due to null host.");
+                    }
+                    return true;
+                });
+    }
+
+    /**
+     * Initialize the controller.
+     *
+     * @param fragment The fragment to host the {@link CallsAndAlarmsDialogFragment} dialog.
+     */
+    public void init(DashboardFragment fragment) {
+        this.mFragment = fragment;
+    }
+}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index e89f20e..554d23e 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -143,7 +143,6 @@
 import com.android.settings.network.telephony.MobileNetworkSettings;
 import com.android.settings.network.telephony.NetworkSelectSettings;
 import com.android.settings.network.tether.TetherSettings;
-import com.android.settings.nfc.AndroidBeam;
 import com.android.settings.nfc.PaymentSettings;
 import com.android.settings.notification.ConfigureNotificationSettings;
 import com.android.settings.notification.NotificationAccessSettings;
@@ -258,7 +257,6 @@
             PrivateVolumeForget.class.getName(),
             PublicVolumeSettings.class.getName(),
             DevelopmentSettingsDashboardFragment.class.getName(),
-            AndroidBeam.class.getName(),
             WifiDisplaySettings.class.getName(),
             PowerUsageSummary.class.getName(),
             AccountSyncSettings.class.getName(),
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimEidPreferenceController.kt b/src/com/android/settings/deviceinfo/simstatus/SimEidPreferenceController.kt
index 4d1b90b..5a3ff49 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimEidPreferenceController.kt
+++ b/src/com/android/settings/deviceinfo/simstatus/SimEidPreferenceController.kt
@@ -21,16 +21,24 @@
 import android.view.WindowManager
 import android.widget.ImageView
 import android.widget.TextView
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
 import androidx.preference.Preference
 import androidx.preference.PreferenceScreen
 import com.android.settings.R
 import com.android.settings.core.BasePreferenceController
 import com.android.settings.deviceinfo.PhoneNumberUtil
 import com.android.settings.network.SubscriptionUtil
-import com.android.settings.network.telephony.TelephonyPreferenceDialog
+import com.android.settingslib.CustomDialogPreferenceCompat
 import com.android.settingslib.Utils
 import com.android.settingslib.qrcode.QrCodeGenerator
 import com.android.settingslib.spaprivileged.framework.common.userManager
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /**
  * This is to show a preference regarding EID of SIM card.
@@ -41,7 +49,8 @@
     BasePreferenceController(context, preferenceKey) {
     private var slotSimStatus: SlotSimStatus? = null
     private var eidStatus: EidStatus? = null
-    private lateinit var preference: TelephonyPreferenceDialog
+    private lateinit var preference: CustomDialogPreferenceCompat
+    private var coroutineScope: CoroutineScope? = null
     private lateinit var eid: String
 
     fun init(slotSimStatus: SlotSimStatus?, eidStatus: EidStatus?) {
@@ -49,21 +58,51 @@
         this.eidStatus = eidStatus
     }
 
-    override fun getAvailabilityStatus(): Int {
-        if (!SubscriptionUtil.isSimHardwareVisible(mContext)) return UNSUPPORTED_ON_DEVICE
-        eid = eidStatus?.eid ?: ""
-        val isAvailable = mContext.userManager.isAdminUser &&
-            !Utils.isWifiOnly(mContext) &&
-            eid.isNotEmpty()
-        return if (isAvailable) AVAILABLE else CONDITIONALLY_UNAVAILABLE
-    }
+    /**
+     * Returns available here, but UI availability is retrieved asynchronously later.
+     *
+     * Check [updateNonIndexableKeys] for search availability.
+     */
+    override fun getAvailabilityStatus() = AVAILABLE
 
     override fun displayPreference(screen: PreferenceScreen) {
         super.displayPreference(screen)
         preference = screen.findPreference(preferenceKey)!!
-        val title = getTitle()
-        preference.title = title
-        preference.dialogTitle = title
+    }
+
+    override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
+        coroutineScope = viewLifecycleOwner.lifecycleScope
+        coroutineScope?.launch {
+            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+                update()
+            }
+        }
+    }
+
+    private suspend fun update() {
+        val isAvailable = withContext(Dispatchers.Default) {
+            getIsAvailableAndUpdateEid()
+        }
+        preference.isVisible = isAvailable
+        if (isAvailable) {
+            val title = withContext(Dispatchers.Default) {
+                getTitle()
+            }
+            preference.title = title
+            preference.dialogTitle = title
+            updateDialog()
+        }
+    }
+
+    private fun getIsAvailableAndUpdateEid(): Boolean {
+        if (!SubscriptionUtil.isSimHardwareVisible(mContext) ||
+            !mContext.userManager.isAdminUser ||
+            Utils.isWifiOnly(mContext)
+        ) {
+            return false
+        }
+        eid = eidStatus?.eid ?: ""
+        return eid.isNotEmpty()
     }
 
     /** Constructs title string. */
@@ -82,13 +121,7 @@
         return mContext.getString(R.string.status_eid)
     }
 
-    override fun updateState(preference: Preference?) {
-        super.updateState(preference)
-
-        updateDialog()
-    }
-
-    private fun updateDialog() {
+    private suspend fun updateDialog() {
         val dialog = preference.dialog ?: return
         dialog.window?.setFlags(
             WindowManager.LayoutParams.FLAG_SECURE,
@@ -106,11 +139,17 @@
     }
 
     override fun handlePreferenceTreeClick(preference: Preference): Boolean {
-        if (preference.key == preferenceKey) {
-            this.preference.setOnShowListener { updateDialog() }
-            return true
+        if (preference.key != preferenceKey) return false
+        this.preference.setOnShowListener {
+            coroutineScope?.launch { updateDialog() }
         }
-        return super.handlePreferenceTreeClick(preference)
+        return true
+    }
+
+    override fun updateNonIndexableKeys(keys: MutableList<String>) {
+        if (!getIsAvailableAndUpdateEid()) {
+            keys.add(preferenceKey)
+        }
     }
 
     companion object {
@@ -122,11 +161,13 @@
          * @param eid is the EID string
          * @return a Bitmap of QR code
          */
-        private fun getEidQrCode(eid: String): Bitmap? = try {
-            QrCodeGenerator.encodeQrCode(eid, QR_CODE_SIZE)
-        } catch (exception: Exception) {
-            Log.w(TAG, "Error when creating QR code width $QR_CODE_SIZE", exception)
-            null
+        private suspend fun getEidQrCode(eid: String): Bitmap? = withContext(Dispatchers.Default) {
+            try {
+                QrCodeGenerator.encodeQrCode(contents = eid, size = QR_CODE_SIZE)
+            } catch (exception: Exception) {
+                Log.w(TAG, "Error when creating QR code width $QR_CODE_SIZE", exception)
+                null
+            }
         }
     }
 }
diff --git a/src/com/android/settings/fuelgauge/BatteryBackupHelper.java b/src/com/android/settings/fuelgauge/BatteryBackupHelper.java
index 76200fe..821501c 100644
--- a/src/com/android/settings/fuelgauge/BatteryBackupHelper.java
+++ b/src/com/android/settings/fuelgauge/BatteryBackupHelper.java
@@ -342,7 +342,7 @@
 
     private boolean isSystemOrDefaultApp(String packageName, int uid) {
         return BatteryOptimizeUtils.isSystemOrDefaultApp(
-                getPowerAllowlistBackend(), packageName, uid);
+                mContext, getPowerAllowlistBackend(), packageName, uid);
     }
 
     private ArraySet<ApplicationInfo> getInstalledApplications() {
diff --git a/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java b/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
index 3ced790..7b3a6ad 100644
--- a/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
@@ -45,6 +45,10 @@
     private static final String TAG = "BatteryOptimizeUtils";
     private static final String UNKNOWN_PACKAGE = "unknown";
 
+    // Avoid reload the data again since it is predefined in the resource/config.
+    private static List<String> sBatteryOptimizeModeList = null;
+    private static List<String> sBatteryUnrestrictModeList = null;
+
     @VisibleForTesting AppOpsManager mAppOpsManager;
     @VisibleForTesting BatteryUtils mBatteryUtils;
     @VisibleForTesting PowerAllowlistBackend mPowerAllowListBackend;
@@ -139,7 +143,7 @@
      */
     public boolean isSystemOrDefaultApp() {
         mPowerAllowListBackend.refreshList();
-        return isSystemOrDefaultApp(mPowerAllowListBackend, mPackageName, mUid);
+        return isSystemOrDefaultApp(mContext, mPowerAllowListBackend, mPackageName, mUid);
     }
 
     /**
@@ -191,7 +195,8 @@
             // Ignores default optimized/unknown state or system/default apps.
             if (optimizationMode == MODE_OPTIMIZED
                     || optimizationMode == MODE_UNKNOWN
-                    || isSystemOrDefaultApp(allowlistBackend, info.packageName, info.uid)) {
+                    || isSystemOrDefaultApp(
+                            context, allowlistBackend, info.packageName, info.uid)) {
                 continue;
             }
 
@@ -211,14 +216,32 @@
     }
 
     static boolean isSystemOrDefaultApp(
-            PowerAllowlistBackend powerAllowlistBackend, String packageName, int uid) {
+            Context context,
+            PowerAllowlistBackend powerAllowlistBackend,
+            String packageName,
+            int uid) {
         return powerAllowlistBackend.isSysAllowlisted(packageName)
+                // Always forced unrestricted apps are one type of system important apps.
+                || getForceBatteryUnrestrictModeList(context).contains(packageName)
                 || powerAllowlistBackend.isDefaultActiveApp(packageName, uid);
     }
 
     static List<String> getForceBatteryOptimizeModeList(Context context) {
-        return Arrays.asList(context.getResources().getStringArray(
-                R.array.config_force_battery_optimize_mode_apps));
+        if (sBatteryOptimizeModeList == null) {
+            sBatteryOptimizeModeList = Arrays.asList(
+                    context.getResources().getStringArray(
+                            R.array.config_force_battery_optimize_mode_apps));
+        }
+        return sBatteryOptimizeModeList;
+    }
+
+    static List<String> getForceBatteryUnrestrictModeList(Context context) {
+        if (sBatteryUnrestrictModeList == null) {
+            sBatteryUnrestrictModeList = Arrays.asList(
+                    context.getResources().getStringArray(
+                            R.array.config_force_battery_unrestrict_mode_apps));
+        }
+        return sBatteryUnrestrictModeList;
     }
 
     private static void setAppUsageStateInternal(
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java b/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java
index dac2abf..b41e153 100644
--- a/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java
+++ b/src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java
@@ -56,12 +56,21 @@
     /** Avoid users set important apps into the unexpected battery optimize modes */
     static void verifyBatteryOptimizeModes(Context context) {
         Log.d(TAG, "invoke verifyOptimizationModes()");
-        verifyBatteryOptimizeModes(context,
+        verifyBatteryOptimizeModeApps(
+                context,
+                BatteryOptimizeUtils.MODE_OPTIMIZED,
                 BatteryOptimizeUtils.getForceBatteryOptimizeModeList(context));
+        verifyBatteryOptimizeModeApps(
+                context,
+                BatteryOptimizeUtils.MODE_UNRESTRICTED,
+                BatteryOptimizeUtils.getForceBatteryUnrestrictModeList(context));
     }
 
     @VisibleForTesting
-    static void verifyBatteryOptimizeModes(Context context, List<String> allowList) {
+    static void verifyBatteryOptimizeModeApps(
+            Context context,
+            @BatteryOptimizeUtils.OptimizationMode int optimizationMode,
+            List<String> allowList) {
         allowList.forEach(packageName -> {
             final BatteryOptimizeUtils batteryOptimizeUtils =
                     BatteryBackupHelper.newBatteryOptimizeUtils(context, packageName,
@@ -69,10 +78,10 @@
             if (batteryOptimizeUtils == null) {
                 return;
             }
-            if (batteryOptimizeUtils.getAppOptimizationMode() !=
-                    BatteryOptimizeUtils.MODE_OPTIMIZED) {
-                Log.w(TAG, "Reset optimization mode for: " + packageName);
-                batteryOptimizeUtils.setAppUsageState(BatteryOptimizeUtils.MODE_OPTIMIZED,
+            if (batteryOptimizeUtils.getAppOptimizationMode() != optimizationMode) {
+                Log.w(TAG, "Reset " + packageName + " battery mode into " + optimizationMode);
+                batteryOptimizeUtils.setAppUsageState(
+                        optimizationMode,
                         BatteryOptimizeHistoricalLogEntry.Action.FORCE_RESET);
             }
         });
diff --git a/src/com/android/settings/network/telephony/MmsMessagePreferenceController.java b/src/com/android/settings/network/telephony/MmsMessagePreferenceController.java
deleted file mode 100644
index 8f59f0e..0000000
--- a/src/com/android/settings/network/telephony/MmsMessagePreferenceController.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.network.telephony;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.network.MobileDataContentObserver;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.core.lifecycle.events.OnStop;
-
-/**
- * Preference controller for "MMS messages"
- */
-public class MmsMessagePreferenceController extends TelephonyTogglePreferenceController implements
-        LifecycleObserver, OnStart, OnStop {
-    private TelephonyManager mTelephonyManager;
-    private MobileDataContentObserver mMobileDataContentObserver;
-    private PreferenceScreen mScreen;
-    private Preference mPreference;
-
-    public MmsMessagePreferenceController(Context context, String key) {
-        super(context, key);
-        mMobileDataContentObserver = new MobileDataContentObserver(
-                new Handler(Looper.getMainLooper()));
-        mMobileDataContentObserver.setOnMobileDataChangedListener(() -> refreshPreference());
-    }
-
-    @Override
-    public int getAvailabilityStatus(int subId) {
-        final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(subId);
-        return (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
-                && !telephonyManager.isDataEnabled()
-                && telephonyManager.isApnMetered(ApnSetting.TYPE_MMS))
-                ? AVAILABLE
-                : CONDITIONALLY_UNAVAILABLE;
-    }
-
-    @Override
-    public void onStart() {
-        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            mMobileDataContentObserver.register(mContext, mSubId);
-            updateState(mPreference);
-        }
-    }
-
-    @Override
-    public void onStop() {
-        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            mMobileDataContentObserver.unRegister(mContext);
-        }
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mScreen = screen;
-        mPreference = screen.findPreference(getPreferenceKey());
-    }
-
-
-    public void init(int subId) {
-        mSubId = subId;
-        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(mSubId);
-    }
-
-    @Override
-    public boolean setChecked(boolean isChecked) {
-        if (mTelephonyManager == null) {
-            return false;
-        }
-        mTelephonyManager.setMobileDataPolicyEnabled(
-                TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, isChecked);
-        return true;
-    }
-
-
-    @Override
-    public boolean isChecked() {
-        return mTelephonyManager != null && mTelephonyManager.isDataEnabledForApn(
-                ApnSetting.TYPE_MMS);
-    }
-
-    private void refreshPreference() {
-        if (mScreen != null) {
-            super.displayPreference(mScreen);
-        }
-    }
-}
diff --git a/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt b/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt
new file mode 100644
index 0000000..23a9738
--- /dev/null
+++ b/src/com/android/settings/network/telephony/MmsMessagePreferenceController.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony
+
+import android.content.Context
+import android.os.Handler
+import android.os.Looper
+import android.telephony.SubscriptionManager
+import android.telephony.TelephonyManager
+import android.telephony.data.ApnSetting
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.LifecycleOwner
+import androidx.preference.PreferenceScreen
+import com.android.settings.network.MobileDataContentObserver
+
+/**
+ * Preference controller for "MMS messages"
+ */
+class MmsMessagePreferenceController(context: Context, key: String) :
+    TelephonyTogglePreferenceController(context, key), DefaultLifecycleObserver {
+
+    private lateinit var telephonyManager: TelephonyManager
+
+    private var preferenceScreen: PreferenceScreen? = null
+
+    private val mobileDataContentObserver =
+        MobileDataContentObserver(Handler(Looper.getMainLooper())).apply {
+            setOnMobileDataChangedListener {
+                preferenceScreen?.let { super.displayPreference(it) }
+            }
+        }
+
+    fun init(subId: Int) {
+        mSubId = subId
+        telephonyManager = mContext.getSystemService(TelephonyManager::class.java)!!
+            .createForSubscriptionId(subId)
+    }
+
+    override fun getAvailabilityStatus(subId: Int) =
+        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID &&
+            !telephonyManager.isDataEnabled &&
+            telephonyManager.isApnMetered(ApnSetting.TYPE_MMS)
+        ) AVAILABLE else CONDITIONALLY_UNAVAILABLE
+
+    override fun onStart(owner: LifecycleOwner) {
+        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            mobileDataContentObserver.register(mContext, mSubId)
+        }
+    }
+
+    override fun onStop(owner: LifecycleOwner) {
+        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            mobileDataContentObserver.unRegister(mContext)
+        }
+    }
+
+    override fun displayPreference(screen: PreferenceScreen) {
+        super.displayPreference(screen)
+        preferenceScreen = screen
+    }
+
+    override fun isChecked(): Boolean = telephonyManager.isMobileDataPolicyEnabled(
+        TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED
+    )
+
+    override fun setChecked(isChecked: Boolean): Boolean {
+        telephonyManager.setMobileDataPolicyEnabled(
+            TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED,
+            isChecked,
+        )
+        return true
+    }
+}
diff --git a/src/com/android/settings/network/telephony/TelephonyPreferenceDialog.java b/src/com/android/settings/network/telephony/TelephonyPreferenceDialog.java
deleted file mode 100644
index 7dbef0c..0000000
--- a/src/com/android/settings/network/telephony/TelephonyPreferenceDialog.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.network.telephony;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import com.android.settingslib.CustomDialogPreferenceCompat;
-
-/**
- * This is DialogPreference for supporting connectivity features.
- */
-public class TelephonyPreferenceDialog extends CustomDialogPreferenceCompat {
-
-    public TelephonyPreferenceDialog(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    public TelephonyPreferenceDialog(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public TelephonyPreferenceDialog(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public TelephonyPreferenceDialog(Context context) {
-        super(context);
-    }
-}
diff --git a/src/com/android/settings/nfc/AndroidBeam.java b/src/com/android/settings/nfc/AndroidBeam.java
deleted file mode 100644
index 9df24a5..0000000
--- a/src/com/android/settings/nfc/AndroidBeam.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2011 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.nfc;
-
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.nfc.NfcAdapter;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.core.InstrumentedFragment;
-import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
-import com.android.settings.widget.SettingsMainSwitchBar;
-import com.android.settingslib.HelpUtils;
-import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.android.settingslib.widget.OnMainSwitchChangeListener;
-
-public class AndroidBeam extends InstrumentedFragment
-        implements OnMainSwitchChangeListener {
-    private View mView;
-    private NfcAdapter mNfcAdapter;
-    private SettingsMainSwitchBar mSwitchBar;
-    private CharSequence mOldActivityTitle;
-    private boolean mBeamDisallowedByBase;
-    private boolean mBeamDisallowedByOnlyAdmin;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        final Context context = getActivity();
-        mNfcAdapter = NfcAdapter.getDefaultAdapter(context);
-        final PackageManager pm = context.getPackageManager();
-        if (mNfcAdapter == null || !pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM))
-            getActivity().finish();
-        setHasOptionsMenu(true);
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        super.onCreateOptionsMenu(menu, inflater);
-        HelpUtils.prepareHelpMenuItem(getActivity(), menu, R.string.help_uri_beam,
-                getClass().getName());
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
-                getActivity(), UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId());
-        final UserManager um = UserManager.get(getActivity());
-        mBeamDisallowedByBase = RestrictedLockUtilsInternal.hasBaseUserRestriction(getActivity(),
-                UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId());
-        if (!mBeamDisallowedByBase && admin != null) {
-            new ActionDisabledByAdminDialogHelper(getActivity())
-                    .prepareDialogBuilder(UserManager.DISALLOW_OUTGOING_BEAM, admin).show();
-            mBeamDisallowedByOnlyAdmin = true;
-            return new View(getContext());
-        }
-        mView = inflater.inflate(
-                com.android.settingslib.widget.preference.footer.R.layout.preference_footer, container, false);
-
-        ImageView iconInfo = mView.findViewById(android.R.id.icon);
-        iconInfo.setImageResource(R.drawable.ic_info_outline_24dp);
-        TextView textInfo = mView.findViewById(android.R.id.title);
-        textInfo.setText(R.string.android_beam_explained);
-
-        return mView;
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        SettingsActivity activity = (SettingsActivity) getActivity();
-
-        mOldActivityTitle = activity.getActionBar().getTitle();
-
-        mSwitchBar = activity.getSwitchBar();
-        if (mBeamDisallowedByOnlyAdmin) {
-            mSwitchBar.hide();
-        } else {
-            mSwitchBar.setChecked(!mBeamDisallowedByBase && mNfcAdapter.isNdefPushEnabled());
-            mSwitchBar.addOnSwitchChangeListener(this);
-            mSwitchBar.setEnabled(!mBeamDisallowedByBase);
-            mSwitchBar.show();
-        }
-
-        activity.setTitle(R.string.android_beam_settings_title);
-    }
-
-    @Override
-    public void onDestroyView() {
-        super.onDestroyView();
-        if (mOldActivityTitle != null) {
-            getActivity().getActionBar().setTitle(mOldActivityTitle);
-        }
-        if (!mBeamDisallowedByOnlyAdmin) {
-            mSwitchBar.removeOnSwitchChangeListener(this);
-            mSwitchBar.hide();
-        }
-    }
-
-    @Override
-    public void onSwitchChanged(Switch switchView, boolean desiredState) {
-        boolean success = false;
-        mSwitchBar.setEnabled(false);
-        if (desiredState) {
-            success = mNfcAdapter.enableNdefPush();
-        } else {
-            success = mNfcAdapter.disableNdefPush();
-        }
-        if (success) {
-            mSwitchBar.setChecked(desiredState);
-        }
-        mSwitchBar.setEnabled(true);
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return SettingsEnums.NFC_BEAM;
-    }
-}
diff --git a/src/com/android/settings/nfc/AndroidBeamEnabler.java b/src/com/android/settings/nfc/AndroidBeamEnabler.java
deleted file mode 100644
index 31ef702..0000000
--- a/src/com/android/settings/nfc/AndroidBeamEnabler.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2018 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.nfc;
-
-import android.content.Context;
-import android.nfc.NfcAdapter;
-import android.os.UserHandle;
-import android.os.UserManager;
-
-import com.android.settings.R;
-import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.android.settingslib.RestrictedPreference;
-
-/**
- * AndroidBeanEnabler is a helper to manage the Android Beam preference. It turns on/off
- * Android Beam and ensures the summary of the preference reflects the current state.
- */
-public class AndroidBeamEnabler extends BaseNfcEnabler {
-    private final boolean mBeamDisallowedBySystem;
-    private final RestrictedPreference mPreference;
-
-    public AndroidBeamEnabler(Context context, RestrictedPreference preference) {
-        super(context);
-        mPreference = preference;
-        mBeamDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(context,
-                UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId());
-        if (!isNfcAvailable()) {
-            // NFC is not supported
-            mPreference.setEnabled(false);
-            return;
-        }
-        if (mBeamDisallowedBySystem) {
-            mPreference.setEnabled(false);
-        }
-    }
-
-    @Override
-    protected void handleNfcStateChanged(int newState) {
-        switch (newState) {
-            case NfcAdapter.STATE_OFF:
-                mPreference.setEnabled(false);
-                mPreference.setSummary(R.string.nfc_disabled_summary);
-                break;
-            case NfcAdapter.STATE_ON:
-                if (mBeamDisallowedBySystem) {
-                    mPreference.setDisabledByAdmin(null);
-                    mPreference.setEnabled(false);
-                } else {
-                    mPreference.checkRestrictionAndSetDisabled(UserManager.DISALLOW_OUTGOING_BEAM);
-                }
-                if (mNfcAdapter.isNdefPushEnabled() && mPreference.isEnabled()) {
-                    mPreference.setSummary(R.string.android_beam_on_summary);
-                } else {
-                    mPreference.setSummary(R.string.android_beam_off_summary);
-                }
-                break;
-            case NfcAdapter.STATE_TURNING_ON:
-                mPreference.setEnabled(false);
-                break;
-            case NfcAdapter.STATE_TURNING_OFF:
-                mPreference.setEnabled(false);
-                break;
-        }
-    }
-}
diff --git a/src/com/android/settings/nfc/AndroidBeamPreferenceController.java b/src/com/android/settings/nfc/AndroidBeamPreferenceController.java
deleted file mode 100644
index 15c15aa..0000000
--- a/src/com/android/settings/nfc/AndroidBeamPreferenceController.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2018 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.nfc;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.nfc.NfcAdapter;
-
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.RestrictedPreference;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
-
-public class AndroidBeamPreferenceController extends BasePreferenceController
-        implements LifecycleObserver, OnResume, OnPause {
-
-    public static final String KEY_ANDROID_BEAM_SETTINGS = "android_beam_settings";
-    private final NfcAdapter mNfcAdapter;
-    private AndroidBeamEnabler mAndroidBeamEnabler;
-
-    public AndroidBeamPreferenceController(Context context, String key) {
-        super(context, key);
-        mNfcAdapter = NfcAdapter.getDefaultAdapter(context);
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        if (!isAvailable()) {
-            mAndroidBeamEnabler = null;
-            return;
-        }
-
-        final RestrictedPreference restrictedPreference = screen.findPreference(getPreferenceKey());
-        mAndroidBeamEnabler = new AndroidBeamEnabler(mContext, restrictedPreference);
-    }
-
-    @Override
-    @AvailabilityStatus
-    public int getAvailabilityStatus() {
-        PackageManager pm = mContext.getPackageManager();
-        if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM)) {
-            return UNSUPPORTED_ON_DEVICE;
-        }
-        return mNfcAdapter != null
-                ? AVAILABLE
-                : UNSUPPORTED_ON_DEVICE;
-    }
-
-    @Override
-    public void onResume() {
-        if (mAndroidBeamEnabler != null) {
-            mAndroidBeamEnabler.resume();
-        }
-    }
-
-    @Override
-    public void onPause() {
-        if (mAndroidBeamEnabler != null) {
-            mAndroidBeamEnabler.pause();
-        }
-    }
-}
diff --git a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java
index 3274aec..6f246b7 100644
--- a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java
+++ b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java
@@ -18,44 +18,31 @@
 
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.provider.Settings;
-import android.service.notification.NotificationAssistantService;
 
 import androidx.fragment.app.Fragment;
 import androidx.preference.Preference;
 
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
-import com.android.settingslib.PrimarySwitchPreference;
 
 import com.google.common.annotations.VisibleForTesting;
 
-import java.util.List;
-
 public class NotificationAssistantPreferenceController extends TogglePreferenceController {
     private static final String TAG = "NASPreferenceController";
     static final String KEY_NAS = "notification_assistant";
 
-    private final UserManager mUserManager;
-    private final PackageManager mPackageManager;
     private Fragment mFragment;
     private int mUserId = UserHandle.myUserId();
 
     @VisibleForTesting
     protected NotificationBackend mNotificationBackend;
     private ComponentName mDefaultNASComponent;
-    private Intent mNASSettingIntent;
 
     public NotificationAssistantPreferenceController(Context context) {
         super(context, KEY_NAS);
-        mUserManager = UserManager.get(context);
         mNotificationBackend = new NotificationBackend();
-        mPackageManager = context.getPackageManager();
         getDefaultNASIntent();
     }
 
@@ -118,12 +105,6 @@
     @VisibleForTesting
     void getDefaultNASIntent() {
         mDefaultNASComponent = mNotificationBackend.getDefaultNotificationAssistant();
-        if (mDefaultNASComponent != null) {
-            mNASSettingIntent = new Intent(
-                    NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS);
-            mNASSettingIntent.setPackage(mDefaultNASComponent.getPackageName());
-            mNASSettingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        }
     }
 
     @Override
@@ -136,7 +117,6 @@
         super.updateState(preference);
         if (mDefaultNASComponent == null) {
             preference.setEnabled(false);
-            ((PrimarySwitchPreference) preference).setSwitchEnabled(false);
         }
     }
 }
diff --git a/src/com/android/settings/panel/VolumePanel.java b/src/com/android/settings/panel/VolumePanel.java
index 938ee9d..1a53de0 100644
--- a/src/com/android/settings/panel/VolumePanel.java
+++ b/src/com/android/settings/panel/VolumePanel.java
@@ -25,7 +25,6 @@
 import static com.android.settings.slices.CustomSliceRegistry.VOLUME_CALL_URI;
 import static com.android.settings.slices.CustomSliceRegistry.VOLUME_MEDIA_URI;
 import static com.android.settings.slices.CustomSliceRegistry.VOLUME_NOTIFICATION_URI;
-import static com.android.settings.slices.CustomSliceRegistry.VOLUME_RINGER_URI;
 import static com.android.settings.slices.CustomSliceRegistry.VOLUME_SEPARATE_RING_URI;
 
 import android.app.Activity;
@@ -144,7 +143,6 @@
         }
         uris.add(MEDIA_OUTPUT_INDICATOR_SLICE_URI);
         uris.add(VOLUME_CALL_URI);
-        uris.add(VOLUME_RINGER_URI);
         uris.add(VOLUME_SEPARATE_RING_URI);
         uris.add(VOLUME_NOTIFICATION_URI);
         uris.add(VOLUME_ALARM_URI);
diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java
index b7fe091..08d2be6 100644
--- a/src/com/android/settings/slices/CustomSliceRegistry.java
+++ b/src/com/android/settings/slices/CustomSliceRegistry.java
@@ -196,16 +196,6 @@
             .build();
 
     /**
-     * Full {@link Uri} for the Ringer volume Slice. (Ring & notification combined)
-     */
-    public static final Uri VOLUME_RINGER_URI = new Uri.Builder()
-            .scheme(ContentResolver.SCHEME_CONTENT)
-            .authority(SettingsSliceProvider.SLICE_AUTHORITY)
-            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
-            .appendPath("ring_volume")
-            .build();
-
-    /**
      * Full {@link Uri} for the Separate Ring volume Slice.
      */
     public static final Uri VOLUME_SEPARATE_RING_URI = new Uri.Builder()
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java
index d6a2492..5d3557f 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java
@@ -32,15 +32,11 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.view.View;
 
 import androidx.appcompat.app.AlertDialog;
 import androidx.test.core.app.ApplicationProvider;
 
-import com.android.server.accessibility.Flags;
 import com.android.settings.SettingsActivity;
 import com.android.settings.SubSettings;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -63,8 +59,6 @@
 
     @Rule
     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
     @Mock
     private DialogInterface.OnClickListener mOnClickListener;
     @Mock
@@ -96,19 +90,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE)
-    public void createTutorialPages_turnOnTwoFingerTripleTapShortcut_hasOnePage() {
-        mShortcutTypes |= UserShortcutType.TWOFINGERTRIPLETAP;
-
-        final AlertDialog alertDialog =
-                createAccessibilityTutorialDialog(mContext, mShortcutTypes);
-
-        assertThat(createShortcutTutorialPages(mContext,
-                mShortcutTypes)).hasSize(/* expectedSize= */ 1);
-        assertThat(alertDialog).isNotNull();
-    }
-
-    @Test
     public void createTutorialPages_turnOnSoftwareShortcut_hasOnePage() {
         mShortcutTypes |= UserShortcutType.SOFTWARE;
 
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java
index aed3787..107d77c 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragmentTest.java
@@ -23,7 +23,6 @@
 import android.nfc.NfcAdapter;
 import android.provider.SearchIndexableResource;
 
-import com.android.settings.nfc.AndroidBeamPreferenceController;
 import com.android.settings.testutils.shadow.ShadowConnectivityManager;
 import com.android.settings.testutils.shadow.ShadowNfcAdapter;
 import com.android.settings.testutils.shadow.ShadowUserManager;
@@ -78,14 +77,4 @@
     public void testGetCategoryKey_returnCategoryDevice() {
         assertThat(mFragment.getCategoryKey()).isEqualTo(CategoryKey.CATEGORY_DEVICE);
     }
-
-    @Test
-    public void testSearchIndexProvider_correctNonIndexables() {
-        mShadowNfcAdapter.setSecureNfcSupported(true);
-        final List<String> niks =
-                AdvancedConnectedDeviceDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
-                        .getNonIndexableKeys(mContext);
-
-        assertThat(niks).contains(AndroidBeamPreferenceController.KEY_ANDROID_BEAM_SETTINGS);
-    }
-}
\ No newline at end of file
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
index 16b7895..e2058e7 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsMigrateCheckerTest.java
@@ -151,12 +151,15 @@
     }
 
     @Test
-    public void verifyBatteryOptimizeModes_inAllowList_resetOptimizationMode() throws Exception {
+    public void verifyBatteryOptimizeModeApps_inAllowList_resetOptimizationMode()
+            throws Exception {
         doReturn(BatteryOptimizeUtils.MODE_RESTRICTED).when(mBatteryOptimizeUtils)
                 .getAppOptimizationMode();
 
-        mBatterySettingsMigrateChecker.verifyBatteryOptimizeModes(
-                mContext, Arrays.asList(PACKAGE_NAME));
+        mBatterySettingsMigrateChecker.verifyBatteryOptimizeModeApps(
+                mContext,
+                BatteryOptimizeUtils.MODE_OPTIMIZED,
+                Arrays.asList(PACKAGE_NAME));
 
         final InOrder inOrder = inOrder(mBatteryOptimizeUtils);
         inOrder.verify(mBatteryOptimizeUtils).getAppOptimizationMode();
@@ -166,23 +169,27 @@
     }
 
     @Test
-    public void verifyBatteryOptimizeModes_optimizedMode_noAction() throws Exception {
+    public void verifyBatteryOptimizeModeApps_optimizedMode_noAction() throws Exception {
         doReturn(BatteryOptimizeUtils.MODE_OPTIMIZED).when(mBatteryOptimizeUtils)
                 .getAppOptimizationMode();
 
-        mBatterySettingsMigrateChecker.verifyBatteryOptimizeModes(
-                mContext, Arrays.asList(PACKAGE_NAME));
+        mBatterySettingsMigrateChecker.verifyBatteryOptimizeModeApps(
+                mContext,
+                BatteryOptimizeUtils.MODE_OPTIMIZED,
+                Arrays.asList(PACKAGE_NAME));
 
         verify(mBatteryOptimizeUtils, never()).setAppUsageState(anyInt(), any());
     }
 
     @Test
-    public void verifyBatteryOptimizeModes_notInAllowList_noAction() throws Exception {
+    public void verifyBatteryOptimizeModeApps_notInAllowList_noAction() throws Exception {
         doReturn(BatteryOptimizeUtils.MODE_RESTRICTED).when(mBatteryOptimizeUtils)
                 .getAppOptimizationMode();
 
-        mBatterySettingsMigrateChecker.verifyBatteryOptimizeModes(
-                mContext, new ArrayList<String>());
+        mBatterySettingsMigrateChecker.verifyBatteryOptimizeModeApps(
+                mContext,
+                BatteryOptimizeUtils.MODE_OPTIMIZED,
+                new ArrayList<String>());
 
         verifyNoInteractions(mBatteryOptimizeUtils);
     }
diff --git a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java
deleted file mode 100644
index 7e15618..0000000
--- a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2018 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.nfc;
-
-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.content.pm.PackageManager;
-import android.nfc.NfcAdapter;
-import android.nfc.NfcManager;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.testutils.shadow.ShadowNfcAdapter;
-import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.android.settingslib.RestrictedPreference;
-
-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.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowNfcAdapter.class)
-public class AndroidBeamPreferenceControllerTest {
-
-    Context mContext;
-    @Mock
-    NfcManager mNfcManager;
-    @Mock
-    private UserManager mUserManager;
-    @Mock
-    private PreferenceScreen mScreen;
-    @Mock
-    private PackageManager mPackageManager;
-
-    private RestrictedPreference mAndroidBeamPreference;
-    private AndroidBeamPreferenceController mAndroidBeamController;
-    private ShadowNfcAdapter mShadowNfcAdapter;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        mShadowNfcAdapter = Shadow.extract(NfcAdapter.getDefaultAdapter(mContext));
-
-        when(mContext.getApplicationContext()).thenReturn(mContext);
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-        when(mContext.getSystemService(Context.NFC_SERVICE)).thenReturn(mNfcManager);
-        when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
-                UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId())).thenReturn(false);
-
-        mAndroidBeamController = new AndroidBeamPreferenceController(mContext,
-                AndroidBeamPreferenceController.KEY_ANDROID_BEAM_SETTINGS);
-        mAndroidBeamPreference = new RestrictedPreference(RuntimeEnvironment.application);
-        when(mScreen.findPreference(mAndroidBeamController.getPreferenceKey())).thenReturn(
-                mAndroidBeamPreference);
-        when(mContext.getPackageManager()).thenReturn(mPackageManager);
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM)).thenReturn(true);
-
-        Settings.Global.putString(mContext.getContentResolver(),
-                Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
-                Settings.Global.RADIO_NFC);
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.AIRPLANE_MODE_ON,
-                0);
-        mAndroidBeamController.displayPreference(mScreen);
-    }
-
-    @Test
-    public void isAvailable_hasNfc_shouldReturnTrue() {
-        mShadowNfcAdapter.setEnabled(true);
-        assertThat(mAndroidBeamController.isAvailable()).isTrue();
-    }
-
-    @Test
-    public void isAvailable_noNfcFeature_shouldReturnFalse() {
-        mShadowNfcAdapter.setEnabled(true);
-        when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM)).thenReturn(false);
-        assertThat(mAndroidBeamController.isAvailable()).isFalse();
-    }
-
-    @Test
-    public void isAvailable_noNfcAdapter_shouldReturnFalse() {
-        ReflectionHelpers.setField(mAndroidBeamController, "mNfcAdapter", null);
-        assertThat(mAndroidBeamController.isAvailable()).isFalse();
-    }
-
-    @Test
-    public void isBeamEnable_disAllowBeam_shouldReturnFalse() {
-        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF);
-
-        when(RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
-                UserManager.DISALLOW_OUTGOING_BEAM, UserHandle.myUserId())).thenReturn(true);
-        mAndroidBeamController.displayPreference(mScreen);
-
-        assertThat(mAndroidBeamPreference.isEnabled()).isFalse();
-    }
-
-    @Test
-    public void isBeamEnable_nfcStateOn_shouldReturnTrue() {
-        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_ON);
-        try {
-            mAndroidBeamController.onResume();
-        } catch (NullPointerException e) {
-            // skip because it's just test
-            // it will meet NullPointerException in checkRestrictionAndSetDisabled
-        }
-        assertThat(mAndroidBeamPreference.isEnabled()).isTrue();
-    }
-
-    @Test
-    public void isBeamEnable_nfcStateNotOn_shouldReturnFalse() {
-        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_OFF);
-        mAndroidBeamController.onResume();
-        assertThat(mAndroidBeamPreference.isEnabled()).isFalse();
-
-        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_ON);
-        mAndroidBeamController.onResume();
-        assertThat(mAndroidBeamPreference.isEnabled()).isFalse();
-
-        mShadowNfcAdapter.setAdapterState(NfcAdapter.STATE_TURNING_OFF);
-        mAndroidBeamController.onResume();
-        assertThat(mAndroidBeamPreference.isEnabled()).isFalse();
-    }
-
-    @Test
-    public void updateNonIndexableKeys_available_shouldNotUpdate() {
-        mShadowNfcAdapter.setEnabled(true);
-        final List<String> keys = new ArrayList<>();
-
-        mAndroidBeamController.updateNonIndexableKeys(keys);
-
-        assertThat(keys).isEmpty();
-    }
-
-    @Test
-    public void updateNonIndexableKeys_notAvailable_shouldUpdate() {
-        ReflectionHelpers.setField(mAndroidBeamController, "mNfcAdapter", null);
-        final List<String> keys = new ArrayList<>();
-
-        mAndroidBeamController.updateNonIndexableKeys(keys);
-
-        assertThat(keys).hasSize(1);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java
index 5f506b8..7606057 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java
@@ -16,18 +16,12 @@
 
 package com.android.settings.notification;
 
-import static android.service.notification.NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS;
-
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -35,24 +29,19 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.Application;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.UserManager;
 import android.provider.Settings;
 
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.FragmentTransaction;
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreferenceCompat;
+import androidx.preference.TwoStatePreference;
 import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.testutils.shadow.ShadowSecureSettings;
-import com.android.settingslib.PrimarySwitchPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -61,12 +50,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.Shadows;
 import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowApplication;
-
-import java.util.ArrayList;
-import java.util.List;
 
 
 @RunWith(RobolectricTestRunner.class)
@@ -86,27 +70,19 @@
     private FragmentTransaction mFragmentTransaction;
     @Mock
     private NotificationBackend mBackend;
-    @Mock
-    private UserManager mUserManager;
-    @Mock
-    private PackageManager mPackageManager;
     private NotificationAssistantPreferenceController mPreferenceController;
     ComponentName mNASComponent = new ComponentName("pkgname", "clsname");
-    private PrimarySwitchPreference mPreference;
-    private ShadowApplication mShadowApplication;
+    private TwoStatePreference mPreference;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(ApplicationProvider.getApplicationContext());
-        mPreference = spy(new PrimarySwitchPreference(mContext));
-        mShadowApplication = ShadowApplication.getInstance();
-        mShadowApplication.setSystemService(Context.USER_SERVICE, mUserManager);
+        mPreference = spy(new SwitchPreferenceCompat(mContext));
         doReturn(mContext).when(mFragment).getContext();
         when(mFragment.getFragmentManager()).thenReturn(mFragmentManager);
         when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
         when(mBackend.getDefaultNotificationAssistant()).thenReturn(mNASComponent);
-        when(mContext.getPackageManager()).thenReturn(mPackageManager);
         mPreferenceController = new NotificationAssistantPreferenceController(mContext);
         mPreferenceController.setBackend(mBackend);
         mPreferenceController.setFragment(mFragment);
@@ -117,19 +93,6 @@
         mPreference.setKey(NotificationAssistantPreferenceController.KEY_NAS);
         screen.addPreference(mPreference);
         mPreferenceController.displayPreference(screen);
-
-        when(mUserManager.getProfileIds(eq(0), anyBoolean())).thenReturn(new int[] {0, 10});
-        when(mUserManager.getProfileIds(eq(20), anyBoolean())).thenReturn(new int[] {20});
-
-        ActivityInfo activityInfo1 = new ActivityInfo();
-        activityInfo1.packageName = "pkgname";
-        activityInfo1.name = "name";
-        ResolveInfo resolveInfo1 = new ResolveInfo();
-        resolveInfo1.activityInfo = activityInfo1;
-        List<ResolveInfo> resolvers1 = new ArrayList<>();
-        resolvers1.add(resolveInfo1);
-        when(mPackageManager.queryIntentActivities(any(Intent.class), any()))
-                .thenReturn(resolvers1);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java b/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java
index 74998c9..d30ef3e 100644
--- a/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java
+++ b/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java
@@ -62,7 +62,6 @@
                 CustomSliceRegistry.VOLUME_CALL_URI,
                 CustomSliceRegistry.VOLUME_MEDIA_URI,
                 CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI,
-                CustomSliceRegistry.VOLUME_RINGER_URI,
                 CustomSliceRegistry.VOLUME_SEPARATE_RING_URI,
                 CustomSliceRegistry.VOLUME_NOTIFICATION_URI,
                 CustomSliceRegistry.VOLUME_ALARM_URI);
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.kt
new file mode 100644
index 0000000..33a8575
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony
+
+import android.content.Context
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import android.telephony.TelephonyManager
+import android.telephony.data.ApnSetting
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.core.BasePreferenceController.AVAILABLE
+import com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+import org.mockito.kotlin.verify
+
+@RunWith(AndroidJUnit4::class)
+class MmsMessagePreferenceControllerTest {
+    private val mockTelephonyManager: TelephonyManager = mock<TelephonyManager> {
+        on { createForSubscriptionId(any()) } doReturn mock
+    }
+
+    private var context: Context = spy(ApplicationProvider.getApplicationContext()) {
+        on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
+    }
+
+    private val controller = MmsMessagePreferenceController(context, KEY).apply {
+        init(SUB_ID)
+    }
+
+    @Test
+    fun getAvailabilityStatus_invalidSubscription_returnUnavailable() {
+        controller.init(INVALID_SUBSCRIPTION_ID)
+
+        val availabilityStatus = controller.getAvailabilityStatus(INVALID_SUBSCRIPTION_ID)
+
+        assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE)
+    }
+
+    @Test
+    fun getAvailabilityStatus_mobileDataOn_returnUnavailable() {
+        mockTelephonyManager.stub {
+            on { isDataEnabled } doReturn true
+        }
+
+        val availabilityStatus = controller.getAvailabilityStatus(SUB_ID)
+
+        assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE)
+    }
+
+    @Test
+    fun getAvailabilityStatus_meteredOff_returnUnavailable() {
+        mockTelephonyManager.stub {
+            on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn false
+        }
+
+        val availabilityStatus = controller.getAvailabilityStatus(SUB_ID)
+
+        assertThat(availabilityStatus).isEqualTo(CONDITIONALLY_UNAVAILABLE)
+    }
+
+    @Test
+    fun getAvailabilityStatus_mobileDataOffWithValidSubId_returnAvailable() {
+        mockTelephonyManager.stub {
+            on { isDataEnabled } doReturn false
+            on { isApnMetered(ApnSetting.TYPE_MMS) } doReturn true
+        }
+
+        val availabilityStatus = controller.getAvailabilityStatus(SUB_ID)
+
+        assertThat(availabilityStatus).isEqualTo(AVAILABLE)
+    }
+
+    @Test
+    fun isChecked_whenMmsNotAlwaysAllowed_returnFalse() {
+        mockTelephonyManager.stub {
+            on {
+                isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED)
+            } doReturn false
+        }
+
+        val isChecked = controller.isChecked()
+
+        assertThat(isChecked).isFalse()
+    }
+
+    @Test
+    fun isChecked_whenMmsAlwaysAllowed_returnTrue() {
+        mockTelephonyManager.stub {
+            on {
+                isMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED)
+            } doReturn true
+        }
+
+        val isChecked = controller.isChecked()
+
+        assertThat(isChecked).isTrue()
+    }
+
+    @Test
+    fun setChecked_setTrue_setDataIntoSubscriptionManager() {
+        controller.setChecked(true)
+
+        verify(mockTelephonyManager).setMobileDataPolicyEnabled(
+            TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, true
+        )
+    }
+
+    @Test
+    fun setChecked_setFalse_setDataIntoSubscriptionManager() {
+        controller.setChecked(false)
+
+        verify(mockTelephonyManager).setMobileDataPolicyEnabled(
+            TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, false
+        )
+    }
+
+    private companion object {
+        const val KEY = "mms_message"
+        const val SUB_ID = 2
+    }
+}
diff --git a/tests/unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.java
deleted file mode 100644
index 127cdfd..0000000
--- a/tests/unit/src/com/android/settings/network/telephony/MmsMessagePreferenceControllerTest.java
+++ /dev/null
@@ -1,142 +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.network.telephony;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.os.Looper;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-
-import androidx.preference.PreferenceManager;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class MmsMessagePreferenceControllerTest {
-    private static final int SUB_ID = 2;
-
-    @Mock
-    private TelephonyManager mTelephonyManager;
-    @Mock
-    private SubscriptionManager mSubscriptionManager;
-
-    private MmsMessagePreferenceController mController;
-    private SwitchPreference mPreference;
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mContext = spy(ApplicationProvider.getApplicationContext());
-        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
-        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
-        when(mTelephonyManager.createForSubscriptionId(SUB_ID)).thenReturn(mTelephonyManager);
-
-        mPreference = spy(new SwitchPreference(mContext));
-        mController = new MmsMessagePreferenceController(mContext, "mms_message");
-        mController.init(SUB_ID);
-        mPreference.setKey(mController.getPreferenceKey());
-    }
-
-    @Test
-    public void getAvailabilityStatus_invalidSubscription_returnUnavailable() {
-        mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_mobileDataOn_returnUnavailable() {
-        when(mTelephonyManager.isDataEnabled()).thenReturn(true);
-
-        assertThat(mController.getAvailabilityStatus(SUB_ID)).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_meteredOff_returnUnavailable() {
-        when(mTelephonyManager.isApnMetered(ApnSetting.TYPE_MMS)).thenReturn(false);
-
-        assertThat(mController.getAvailabilityStatus(SUB_ID)).isEqualTo(CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_mobileDataOffWithValidSubId_returnAvailable() {
-        mController.init(SUB_ID);
-        when(mTelephonyManager.isDataEnabled()).thenReturn(false);
-        when(mTelephonyManager.isApnMetered(ApnSetting.TYPE_MMS)).thenReturn(true);
-
-        assertThat(mController.getAvailabilityStatus(SUB_ID)).isEqualTo(AVAILABLE);
-    }
-
-    @Test
-    public void isChecked_returnDataFromTelephonyManager() {
-        when(mTelephonyManager.isDataEnabledForApn(ApnSetting.TYPE_MMS)).thenReturn(false);
-        assertThat(mController.isChecked()).isFalse();
-
-        when(mTelephonyManager.isDataEnabledForApn(ApnSetting.TYPE_MMS)).thenReturn(true);
-        assertThat(mController.isChecked()).isTrue();
-    }
-
-    @Test
-    public void setChecked_setDataIntoSubscriptionManager() {
-        mController.setChecked(true);
-        verify(mTelephonyManager).setMobileDataPolicyEnabled(
-                TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, true);
-
-        mController.setChecked(false);
-        verify(mTelephonyManager).setMobileDataPolicyEnabled(
-                TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED, false);
-    }
-
-    @Test
-    public void onStart_updatePreferenceUiState() {
-        if (Looper.myLooper() == null) {
-            Looper.prepare();
-        }
-        PreferenceManager preferenceManager = new PreferenceManager(mContext);
-        PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
-        preferenceScreen.addPreference(mPreference);
-        mController.displayPreference(preferenceScreen);
-
-        mController.onStart();
-
-        // First is preference initialization, and second is in onStart();
-        verify(mPreference, times(2)).setChecked(anyBoolean());
-    }
-}