Merge "Add 'Restore' button to AppInfo screen" into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1312de5..19927a2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -492,6 +492,17 @@
                 android:value="@string/menu_key_display"/>
         </activity>
 
+        <activity android:name=".Settings$ScreenTimeoutActivity"
+                  android:label="@string/screen_timeout"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.settings.SCREEN_TIMEOUT_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                       android:value="com.android.settings.display.ScreenTimeoutSettings"/>
+        </activity>
+
         <activity
             android:name="Settings$ConfigureWifiSettingsActivity"
             android:label="@string/wifi_configure_settings_preference_title"
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 8278978..9722a85 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -37,10 +37,6 @@
     },
     {
       "name": "SettingsPerfTests"
-    },
-    {
-      "name": "SettingsScreenshotRNGTests",
-      "host": true
     }
   ]
 }
diff --git a/res/drawable/ic_calls_sms.xml b/res/drawable/ic_calls_sms.xml
new file mode 100644
index 0000000..2033e8f
--- /dev/null
+++ b/res/drawable/ic_calls_sms.xml
@@ -0,0 +1,29 @@
+<!--
+    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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?android:attr/colorControlNormal"
+    >
+
+    <path
+        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M20.17,14.85l-3.26-0.65c-0.33-0.07-0.67,0.04-0.9,0.27l-2.62,2.62c-2.75-1.49-5.01-3.75-6.5-6.5l2.62-2.62 c0.24-0.24,0.34-0.58,0.27-0.9L9.13,3.82c-0.09-0.47-0.5-0.8-0.98-0.8H4c-0.56,0-1.03,0.47-1,1.03c0.17,2.91,1.04,5.63,2.43,8.01 c1.57,2.69,3.81,4.93,6.5,6.5c2.38,1.39,5.1,2.26,8.01,2.43c0.56,0.03,1.03-0.44,1.03-1v-4.15C20.97,15.36,20.64,14.95,20.17,14.85 L20.17,14.85z M12,3v10l3-3h6V3H12z M19,8h-5V5h5V8z" />
+</vector>
diff --git a/res/layout/audio_sharing_device_item.xml b/res/layout/audio_sharing_device_item.xml
index f8e7454..04ecdd7 100644
--- a/res/layout/audio_sharing_device_item.xml
+++ b/res/layout/audio_sharing_device_item.xml
@@ -17,16 +17,17 @@
 
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
 
     <Button
         android:id="@+id/device_button"
-        android:overScrollMode="never"
+        style="@style/SettingsLibActionButton"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:textAlignment="center"
-        android:text=""/>
+        android:layout_marginTop="4dp"
+        android:background="@drawable/audio_sharing_rounded_bg_ripple"
+        android:textAlignment="center" />
 
 </FrameLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_audio_sharing.xml b/res/layout/dialog_audio_sharing.xml
index 3ea2c01..aace5ab 100644
--- a/res/layout/dialog_audio_sharing.xml
+++ b/res/layout/dialog_audio_sharing.xml
@@ -50,7 +50,7 @@
         android:src="@drawable/audio_sharing_guidance"
         android:visibility="gone" />
 
-    <com.android.internal.widget.RecyclerView
+    <androidx.recyclerview.widget.RecyclerView
         android:id="@+id/btn_list"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
diff --git a/res/layout/dialog_audio_sharing_disconnect.xml b/res/layout/dialog_audio_sharing_disconnect.xml
index 54dee40..592b41b 100644
--- a/res/layout/dialog_audio_sharing_disconnect.xml
+++ b/res/layout/dialog_audio_sharing_disconnect.xml
@@ -31,11 +31,13 @@
         android:layout_gravity="center"
         android:paddingBottom="24dp" />
 
-    <com.android.internal.widget.RecyclerView
+    <androidx.recyclerview.widget.RecyclerView
         android:id="@+id/device_btn_list"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center" />
+        android:layout_gravity="center"
+        android:nestedScrollingEnabled="false"
+        android:overScrollMode="never" />
 
     <Button
         android:id="@+id/cancel_btn"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e1e82b2..01f2525 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9115,6 +9115,12 @@
     <!-- Summary of the switch preference that controls whether the system will pause app activity when the app has not been used for months [CHAR LIMIT=NONE]-->
     <string name="unused_apps_switch_summary">Remove permissions, delete temporary files, and stop notifications</string>
 
+    <!-- Label of a switch preference that controls whether the system will pause app activity when the app has not been used for a while [CHAR LIMIT=40]-->
+    <string name="unused_apps_switch_v2">Manage app if unused</string>
+
+    <!-- Summary of the switch preference that controls whether the system will pause app activity when the app has not been used for a while [CHAR LIMIT=NONE]-->
+    <string name="unused_apps_switch_summary_v2">Remove permissions, delete temporary files, stop notifications, and archive the app</string>
+
     <!-- Label for showing all apps in list [CHAR LIMIT=30] -->
     <string name="filter_all_apps">All apps</string>
     <!-- Label for showing enabled apps in list [CHAR LIMIT=30] -->
diff --git a/res/xml/audio_stream_details_fragment.xml b/res/xml/audio_stream_details_fragment.xml
new file mode 100644
index 0000000..9727442
--- /dev/null
+++ b/res/xml/audio_stream_details_fragment.xml
@@ -0,0 +1,34 @@
+<?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"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="Audio stream details">
+
+    <com.android.settingslib.widget.LayoutPreference
+        android:key="audio_stream_header"
+        android:layout="@layout/settings_entity_header"
+        android:selectable="false"
+        settings:allowDividerBelow="true"
+        settings:searchable="false" />
+
+    <com.android.settingslib.widget.ActionButtonsPreference
+        android:key="audio_stream_button"
+        settings:allowDividerBelow="true" />
+
+</PreferenceScreen>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index f0a2881..e1ccad8 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -727,10 +727,11 @@
             android:title="@string/enable_non_resizable_multi_window"
             android:summary="@string/enable_non_resizable_multi_window_summary" />
 
-        <SwitchPreferenceCompat
-            android:key="back_navigation_animation"
-            android:title="@string/back_navigation_animation"
-            android:summary="@string/back_navigation_animation_summary" />
+        // TODO(b/315859328): Temporally removed since causing search indexing failure.
+<!--        <SwitchPreferenceCompat-->
+<!--            android:key="back_navigation_animation"-->
+<!--            android:title="@string/back_navigation_animation"-->
+<!--            android:summary="@string/back_navigation_animation_summary" />-->
 
         <Preference
             android:key="reset_shortcut_manager_throttling"
diff --git a/res/xml/network_provider_internet.xml b/res/xml/network_provider_internet.xml
index cd44ab1..1a8ee08 100644
--- a/res/xml/network_provider_internet.xml
+++ b/res/xml/network_provider_internet.xml
@@ -31,10 +31,16 @@
         settings:keywords="@string/keywords_internet"
         settings:useAdminDisabledSummary="true" />
 
-    <com.android.settings.spa.preference.ComposePreference
+    <com.android.settingslib.RestrictedPreference
         android:key="calls_and_sms"
         android:title="@string/calls_and_sms"
+        android:icon="@drawable/ic_calls_sms"
         android:order="-20"
+        android:summary="@string/summary_placeholder"
+        android:fragment="com.android.settings.network.NetworkProviderCallsSmsFragment"
+        settings:userRestriction="no_config_mobile_networks"
+        settings:allowDividerBelow="true"
+        settings:useAdminDisabledSummary="true"
         settings:controller="com.android.settings.network.NetworkProviderCallsSmsController" />
 
     <com.android.settingslib.RestrictedPreference
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 68ae0ae..86baba4 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -478,4 +478,6 @@
     public static class OneHandedSettingsActivity extends SettingsActivity { /* empty */ }
 
     public static class PreviouslyConnectedDeviceActivity extends SettingsActivity { /* empty */ }
+
+    public static class ScreenTimeoutActivity extends SettingsActivity { /* empty */ }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceAdapter.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceAdapter.java
index bc8ff21..a5f5adb 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceAdapter.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceAdapter.java
@@ -22,7 +22,8 @@
 import android.view.ViewGroup;
 import android.widget.Button;
 
-import com.android.internal.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView;
+
 import com.android.settings.R;
 
 import java.util.ArrayList;
@@ -32,11 +33,13 @@
     private static final String TAG = "AudioSharingDeviceAdapter";
     private final ArrayList<AudioSharingDeviceItem> mDevices;
     private final OnClickListener mOnClickListener;
+    private final String mPrefix;
 
     public AudioSharingDeviceAdapter(
-            ArrayList<AudioSharingDeviceItem> devices, OnClickListener listener) {
+            ArrayList<AudioSharingDeviceItem> devices, OnClickListener listener, String prefix) {
         mDevices = devices;
         mOnClickListener = listener;
+        mPrefix = prefix;
     }
 
     private class AudioSharingDeviceViewHolder extends RecyclerView.ViewHolder {
@@ -49,7 +52,7 @@
 
         public void bindView(int position) {
             if (mButtonView != null) {
-                mButtonView.setText(mDevices.get(position).getName());
+                mButtonView.setText(mPrefix + mDevices.get(position).getName());
                 mButtonView.setOnClickListener(
                         v -> mOnClickListener.onClick(mDevices.get(position)));
             } else {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
index e44939d..32cd2f8 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
@@ -28,9 +28,9 @@
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.internal.widget.LinearLayoutManager;
-import com.android.internal.widget.RecyclerView;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 
@@ -139,7 +139,8 @@
                             (AudioSharingDeviceItem item) -> {
                                 sListener.onItemClick(item);
                                 dismiss();
-                            }));
+                            },
+                            "Connect "));
             recyclerView.setLayoutManager(
                     new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
             recyclerView.setVisibility(View.VISIBLE);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
index 7eedb9a..a2b1824 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
@@ -28,9 +28,9 @@
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.internal.widget.LinearLayoutManager;
-import com.android.internal.widget.RecyclerView;
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 
@@ -110,7 +110,8 @@
                         (AudioSharingDeviceItem item) -> {
                             sListener.onItemClick(item);
                             dismiss();
-                        }));
+                        },
+                        "Disconnect "));
         recyclerView.setLayoutManager(
                 new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
         Button cancelBtn = rootView.findViewById(R.id.cancel_btn);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java
new file mode 100644
index 0000000..1e69829
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java
@@ -0,0 +1,47 @@
+/*
+ * 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.audiostreams;
+
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+
+public class AudioStreamDetailsFragment extends DashboardFragment {
+    private static final String TAG = "AudioStreamDetailsFragment";
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        // TODO(chelseahao): update metrics id
+        return 0;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.audio_stream_details_fragment;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java
index 6cf69c5..45f0c2f 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java
@@ -18,10 +18,18 @@
 
 import static java.util.Collections.emptyList;
 
+import android.app.AlertDialog;
+import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothLeBroadcastMetadata;
 import android.bluetooth.BluetoothLeBroadcastReceiveState;
 import android.content.Context;
+import android.os.Bundle;
+import android.provider.Settings;
 import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
 
 import androidx.annotation.NonNull;
 import androidx.lifecycle.DefaultLifecycleObserver;
@@ -29,13 +37,16 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
+import com.android.settings.R;
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.SubSettingLauncher;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.utils.ThreadUtils;
 
+import java.nio.charset.StandardCharsets;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
@@ -198,11 +209,48 @@
     }
 
     private boolean launchDetailFragment(AudioStreamPreference preference) {
-        // TODO(chelseahao): impl
+        Bundle broadcast = new Bundle();
+        broadcast.putString(
+                Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO,
+                (String) preference.getTitle());
+
+        new SubSettingLauncher(mContext)
+                .setTitleText("Audio stream details")
+                .setDestination(AudioStreamDetailsFragment.class.getName())
+                // TODO(chelseahao): Add logging enum
+                .setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN)
+                .setArguments(broadcast)
+                .launch();
         return true;
     }
 
     private void launchPasswordDialog(BluetoothLeBroadcastMetadata source, Preference preference) {
-        // TODO(chelseahao): impl
+        View layout =
+                LayoutInflater.from(mContext)
+                        .inflate(R.layout.bluetooth_find_broadcast_password_dialog, null);
+        ((TextView) layout.requireViewById(R.id.broadcast_name_text))
+                .setText(preference.getTitle());
+        AlertDialog alertDialog =
+                new AlertDialog.Builder(mContext)
+                        .setTitle(R.string.find_broadcast_password_dialog_title)
+                        .setView(layout)
+                        .setNeutralButton(android.R.string.cancel, null)
+                        .setPositiveButton(
+                                R.string.bluetooth_connect_access_dialog_positive,
+                                (dialog, which) -> {
+                                    var code =
+                                            ((EditText)
+                                                    layout.requireViewById(
+                                                            R.id.broadcast_edit_text))
+                                                    .getText()
+                                                    .toString();
+                                    mAudioStreamsHelper.addSource(
+                                            new BluetoothLeBroadcastMetadata.Builder(source)
+                                                    .setBroadcastCode(
+                                                            code.getBytes(StandardCharsets.UTF_8))
+                                                    .build());
+                                })
+                        .create();
+        alertDialog.show();
     }
 }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 6d1d4e8..d68f2c8 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -100,6 +100,7 @@
 import com.android.settings.deviceinfo.legal.ModuleLicensesDashboard;
 import com.android.settings.display.AutoBrightnessSettings;
 import com.android.settings.display.NightDisplaySettings;
+import com.android.settings.display.ScreenTimeoutSettings;
 import com.android.settings.display.SmartAutoRotatePreferenceFragment;
 import com.android.settings.display.darkmode.DarkModeSettingsFragment;
 import com.android.settings.dream.DreamSettings;
@@ -369,7 +370,8 @@
             LongBackgroundTasksDetails.class.getName(),
             RegionalPreferencesEntriesFragment.class.getName(),
             BatteryInfoFragment.class.getName(),
-            UserAspectRatioDetails.class.getName()
+            UserAspectRatioDetails.class.getName(),
+            ScreenTimeoutSettings.class.getName(),
     };
 
     public static final String[] SETTINGS_FOR_RESTRICTED = {
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
index 3321d50..0348e11 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
@@ -130,7 +130,6 @@
         if (titleResId > 0) {
             activity.setTitle(titleResId);
         }
-        final int selectedTab = getTabId(activity, getArguments());
 
         final View tabContainer = mContentView.findViewById(R.id.tab_container);
         mViewPager = tabContainer.findViewById(R.id.view_pager);
@@ -149,6 +148,7 @@
                 }
         );
         tabContainer.setVisibility(View.VISIBLE);
+        final int selectedTab = getTabId(activity, getArguments());
         final TabLayout.Tab tab = tabs.getTabAt(selectedTab);
         tab.select();
 
@@ -228,7 +228,7 @@
         if (bundle != null) {
             final int extraTab = bundle.getInt(SettingsActivity.EXTRA_SHOW_FRAGMENT_TAB, -1);
             if (extraTab != -1) {
-                return extraTab;
+                return ((ViewPagerAdapter) mViewPager.getAdapter()).getTabForPosition(extraTab);
             }
             final int userId = bundle.getInt(EXTRA_USER_ID, UserHandle.SYSTEM.getIdentifier());
             final boolean isWorkProfile = UserManager.get(activity).isManagedProfile(userId);
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 4c8b2dc..a483f9f 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -49,6 +49,7 @@
 import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.Toast;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 
@@ -606,8 +607,9 @@
     }
 
     private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Activity activity, Lifecycle lifecycle, DevelopmentSettingsDashboardFragment fragment,
-            BluetoothA2dpConfigStore bluetoothA2dpConfigStore) {
+            @Nullable Activity activity, @Nullable Lifecycle lifecycle,
+            @Nullable DevelopmentSettingsDashboardFragment fragment,
+            @Nullable BluetoothA2dpConfigStore bluetoothA2dpConfigStore) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
         controllers.add(new MemoryUsagePreferenceController(context));
         controllers.add(new BugReportPreferenceController(context));
@@ -735,7 +737,7 @@
         controllers.add(new OverlaySettingsPreferenceController(context));
         controllers.add(new StylusHandwritingPreferenceController(context));
         controllers.add(new IngressRateLimitPreferenceController((context)));
-        controllers.add(new BackAnimationPreferenceController(context, fragment));
+        // controllers.add(new BackAnimationPreferenceController(context, fragment));
         controllers.add(new PhantomProcessPreferenceController(context));
         controllers.add(new ContrastPreferenceController(
                 context, context.getSystemService(UiModeManager.class)));
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
index a2ee3e4..0bc6176 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java
@@ -22,6 +22,7 @@
 import android.util.ArrayMap;
 import android.util.SparseIntArray;
 
+import com.android.settings.fuelgauge.batteryusage.DetectRequestSourceType;
 import com.android.settings.fuelgauge.batteryusage.PowerAnomalyEventList;
 import com.android.settingslib.fuelgauge.Estimate;
 
@@ -103,11 +104,9 @@
     /** Returns {@code true} if delay the hourly job when device is booting */
     boolean delayHourlyJobWhenBooting();
 
-    /** Insert settings configuration data for anomaly detection */
-    void insertSettingsData(Context context, double displayDrain);
-
     /** Returns {@link Bundle} for settings anomaly detection result */
-    PowerAnomalyEventList detectSettingsAnomaly(Context context, double displayDrain);
+    PowerAnomalyEventList detectSettingsAnomaly(
+            Context context, double displayDrain, DetectRequestSourceType detectRequestSourceType);
 
     /** Gets an intent for one time bypass charge limited to resume charging. */
     Intent getResumeChargeIntent(boolean isDockDefender);
diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index 2e2cf12..a8a2f75 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -27,6 +27,7 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.settings.fuelgauge.batteryusage.DetectRequestSourceType;
 import com.android.settings.fuelgauge.batteryusage.PowerAnomalyEventList;
 import com.android.settingslib.fuelgauge.Estimate;
 
@@ -168,10 +169,8 @@
     }
 
     @Override
-    public void insertSettingsData(Context context, double displayDrain) {}
-
-    @Override
-    public PowerAnomalyEventList detectSettingsAnomaly(Context context, double displayDrain) {
+    public PowerAnomalyEventList detectSettingsAnomaly(
+            Context context, double displayDrain, DetectRequestSourceType detectRequestSourceType) {
         return null;
     }
 
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java
index ead580b..fb5b9a1 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java
@@ -135,7 +135,10 @@
                                                                             .isEmpty()))) {
                                 FeatureFactory.getFeatureFactory()
                                         .getPowerUsageFeatureProvider()
-                                        .detectSettingsAnomaly(context, /* displayDrain= */ 0);
+                                        .detectSettingsAnomaly(
+                                                context,
+                                                /* displayDrain= */ 0,
+                                                DetectRequestSourceType.TYPE_DATA_LOADER);
                             }
                         });
         if (batteryLevelData == null) {
diff --git a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java
index 072040d..1482117 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java
@@ -263,7 +263,9 @@
                             FeatureFactory.getFeatureFactory().getPowerUsageFeatureProvider();
                     final PowerAnomalyEventList anomalyEventList =
                             powerUsageFeatureProvider.detectSettingsAnomaly(
-                                    getContext(), /* displayDrain= */ 0);
+                                    getContext(),
+                                    /* displayDrain= */ 0,
+                                    DetectRequestSourceType.TYPE_USAGE_UI);
                     mHandler.post(() -> onAnomalyDetected(anomalyEventList));
                 });
     }
diff --git a/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto b/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
index 930a21b..3c0705f 100644
--- a/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
+++ b/src/com/android/settings/fuelgauge/protos/power_anomaly_event.proto
@@ -21,18 +21,12 @@
   optional string dismiss_record_key = 8;
 }
 
-// NOTE: Please DO NOT delete enum items or change enum values. Use [deprecated = true] instead.
-// The enum value will be used to decide the tips card style like icons and colors.
-//
 // Next id: 2
 enum PowerAnomalyType{
   TYPE_SETTINGS_BANNER = 0;
   TYPE_APPS_ITEM = 1;
 }
 
-// NOTE: Please DO NOT delete enum items or change enum values. Use [deprecated = true] instead.
-// The enum value will be used to decide pre-defined title and button labels.
-//
 // Next id: 8
 enum PowerAnomalyKey{
   KEY_BRIGHTNESS = 0;
@@ -45,6 +39,13 @@
   KEY_APP_FOREGROUND_HIGHER_THAN_USUAL = 7;
 }
 
+// Next id: 3
+enum DetectRequestSourceType{
+  TYPE_UNKNOWN_SOURCE = 0;
+  TYPE_USAGE_UI = 1;
+  TYPE_DATA_LOADER = 2;
+}
+
 message WarningBannerInfo {
   optional string title_string = 1;
   optional string description_string = 2;
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index e5d9242..323d935 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -59,6 +59,7 @@
         super.onAttach(context);
 
         use(AirplaneModePreferenceController.class).setFragment(this);
+        use(NetworkProviderCallsSmsController.class).init(this);
     }
 
     @Override
diff --git a/src/com/android/settings/network/NetworkProviderCallsSmsController.kt b/src/com/android/settings/network/NetworkProviderCallsSmsController.kt
index a265041..7346e23 100644
--- a/src/com/android/settings/network/NetworkProviderCallsSmsController.kt
+++ b/src/com/android/settings/network/NetworkProviderCallsSmsController.kt
@@ -16,35 +16,23 @@
 
 package com.android.settings.network
 
-import android.app.settings.SettingsEnums
 import android.content.Context
 import android.content.IntentFilter
-import android.os.UserManager
 import android.telephony.SubscriptionInfo
 import android.telephony.SubscriptionManager
 import android.telephony.TelephonyManager
 import androidx.annotation.VisibleForTesting
-import androidx.compose.foundation.layout.Column
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.outlined.PermPhoneMsg
-import androidx.compose.material3.HorizontalDivider
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
-import androidx.compose.ui.res.stringResource
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import androidx.lifecycle.viewmodel.compose.viewModel
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.LifecycleOwner
+import androidx.preference.PreferenceScreen
 import com.android.settings.R
-import com.android.settings.core.SubSettingLauncher
-import com.android.settings.spa.preference.ComposePreferenceController
+import com.android.settings.core.BasePreferenceController
+import com.android.settingslib.RestrictedPreference
 import com.android.settingslib.Utils
-import com.android.settingslib.spa.widget.preference.PreferenceModel
-import com.android.settingslib.spa.widget.ui.SettingsIcon
+import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
 import com.android.settingslib.spaprivileged.framework.common.broadcastReceiverFlow
 import com.android.settingslib.spaprivileged.framework.common.userManager
-import com.android.settingslib.spaprivileged.framework.compose.placeholder
-import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
-import com.android.settingslib.spaprivileged.template.preference.RestrictedPreference
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
@@ -64,7 +52,14 @@
         SubscriptionUtil.getUniqueSubscriptionDisplayName(subInfo, context)
     },
     private val isInService: (Int) -> Boolean = IsInServiceImpl(context)::isInService,
-) : ComposePreferenceController(context, preferenceKey) {
+) : BasePreferenceController(context, preferenceKey) {
+
+    private lateinit var lazyViewModel: Lazy<SubscriptionInfoListViewModel>
+    private lateinit var preference: RestrictedPreference
+
+    fun init(fragment: Fragment) {
+        lazyViewModel = fragment.viewModels()
+    }
 
     override fun getAvailabilityStatus() = when {
         !SubscriptionUtil.isSimHardwareVisible(mContext) -> UNSUPPORTED_ON_DEVICE
@@ -72,35 +67,23 @@
         else -> AVAILABLE
     }
 
-    @Composable
-    override fun Content() {
-        Column {
-            CallsAndSms()
-            HorizontalDivider()
-        }
+    override fun displayPreference(screen: PreferenceScreen) {
+        super.displayPreference(screen)
+        preference = screen.findPreference(preferenceKey)!!
     }
 
-    @Composable
-    private fun CallsAndSms() {
-        val viewModel: SubscriptionInfoListViewModel = viewModel()
-        val subscriptionInfos by viewModel.subscriptionInfoListFlow.collectAsStateWithLifecycle()
-        val summary by remember { summaryFlow(viewModel.subscriptionInfoListFlow) }
-            .collectAsStateWithLifecycle(initialValue = placeholder())
-        RestrictedPreference(
-            model = object : PreferenceModel {
-                override val title = stringResource(R.string.calls_and_sms)
-                override val icon = @Composable { SettingsIcon(Icons.Outlined.PermPhoneMsg) }
-                override val summary = { summary }
-                override val enabled = { subscriptionInfos.isNotEmpty() }
-                override val onClick = {
-                    SubSettingLauncher(mContext).apply {
-                        setDestination(NetworkProviderCallsSmsFragment::class.qualifiedName)
-                        setSourceMetricsCategory(SettingsEnums.SETTINGS_NETWORK_CATEGORY)
-                    }.launch()
+    override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
+        val viewModel by lazyViewModel
+
+        summaryFlow(viewModel.subscriptionInfoListFlow)
+            .collectLatestWithLifecycle(viewLifecycleOwner) { preference.summary = it }
+
+        viewModel.subscriptionInfoListFlow
+            .collectLatestWithLifecycle(viewLifecycleOwner) { subscriptionInfoList ->
+                if (!preference.isDisabledByAdmin) {
+                    preference.isEnabled = subscriptionInfoList.isNotEmpty()
                 }
-            },
-            restrictions = Restrictions(keys = listOf(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)),
-        )
+            }
     }
 
     private fun summaryFlow(subscriptionInfoListFlow: Flow<List<SubscriptionInfo>>) = combine(
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 7a127bb..e416760 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -158,7 +158,7 @@
         }
 
         // hide provisioning/bootstrap and satellite profiles for user
-        if (isEmbeddedSubscriptionVisible(subInfo)) {
+        if (!isEmbeddedSubscriptionVisible(subInfo)) {
             Log.d(TAG, "Do not insert the provision eSIM or NTN eSim");
             return null;
         }
@@ -587,7 +587,7 @@
         if (info == null) return false;
 
         // hide provisioning/bootstrap and satellite profiles for user
-        if (isEmbeddedSubscriptionVisible(info)) {
+        if (!isEmbeddedSubscriptionVisible(info)) {
             return false;
         }
 
diff --git a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
index a17144f..799543f 100644
--- a/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
+++ b/src/com/android/settings/network/telephony/ConvertToEsimPreferenceController.java
@@ -43,6 +43,7 @@
 
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.settings.network.MobileNetworkRepository;
+import com.android.settings.network.SubscriptionUtil;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
 
@@ -98,10 +99,21 @@
 
     @Override
     public int getAvailabilityStatus(int subId) {
-        // TODO(b/262195754): Need the intent to enabled the feature.
+        // TODO(b/315073761) : Add a new API to set whether the profile has been
+        // converted/transferred. Remove any confusion to the user according to the set value.
+
+        /*
+         * If pSIM is set to preferred SIM and there is an active eSIM, convert the pSIM to eSIM
+         * and then disable the pSIM.
+         * This causes a dialog to switch the preferred SIM to downloaded new eSIM.
+         * This may cause confusion for the user about the seamless conversion.
+         * To avoid showing users dialogs that can cause confusion,
+         * add conditions to allow conversion in the absence of active eSIM.
+         */
         if (findConversionSupportComponent()) {
             return mSubscriptionInfoEntity != null && mSubscriptionInfoEntity.isActiveSubscriptionId
                     && !mSubscriptionInfoEntity.isEmbedded && isActiveSubscription(subId)
+                    && !hasActiveEsimProfiles()
                     ? AVAILABLE
                     : CONDITIONALLY_UNAVAILABLE;
         }
@@ -135,7 +147,6 @@
 
     @Override
     public void onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
-        // TODO(b/262195754): Need the intent to enabled the feature.
         mSubscriptionInfoEntityList = subInfoEntityList;
         mSubscriptionInfoEntityList.forEach(entity -> {
             if (Integer.parseInt(entity.subId) == mSubId) {
@@ -155,6 +166,24 @@
         return true;
     }
 
+    private boolean hasActiveEsimProfiles() {
+        SubscriptionManager subscriptionManager = mContext.getSystemService(
+                SubscriptionManager.class);
+        List<SubscriptionInfo> subscriptionInfoList =
+                SubscriptionUtil.getActiveSubscriptions(subscriptionManager);
+        if (subscriptionInfoList == null || subscriptionInfoList.isEmpty()) {
+            return false;
+        }
+        int activatedEsimCount = (int) subscriptionInfoList
+                .stream()
+                .filter(SubscriptionInfo::isEmbedded)
+                .count();
+        if (activatedEsimCount > 0) {
+            return true;
+        }
+        return false;
+    }
+
     private boolean findConversionSupportComponent() {
         Intent intent = new Intent(EuiccService.ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION);
         PackageManager packageManager = mContext.getPackageManager();
diff --git a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
index 3ec7c92..b5e76920 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
@@ -34,6 +34,7 @@
 import android.util.Log;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -226,6 +227,26 @@
                 HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL);
     }
 
+    /**
+     * Returns true if private space exists and quiet mode is successfully enabled, otherwise
+     * returns false
+     */
+    public synchronized boolean lockPrivateSpace() {
+        if (isPrivateProfileRunning()) {
+            return mUserManager.requestQuietModeEnabled(true, mUserHandle);
+        }
+        return false;
+    }
+
+    /** Returns true if private space exists and is running, otherwise returns false */
+    @VisibleForTesting
+    synchronized boolean isPrivateProfileRunning() {
+        if (doesPrivateSpaceExist() && mUserHandle != null) {
+            return mUserManager.isUserRunning(mUserHandle);
+        }
+        return false;
+    }
+
     private void resetPrivateSpaceSettings() {
         setHidePrivateSpaceEntryPointSetting(HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL);
     }
diff --git a/src/com/android/settings/privatespace/SetupSuccessFragment.java b/src/com/android/settings/privatespace/SetupSuccessFragment.java
index 0b1b9d9..ebeae7a 100644
--- a/src/com/android/settings/privatespace/SetupSuccessFragment.java
+++ b/src/com/android/settings/privatespace/SetupSuccessFragment.java
@@ -84,6 +84,8 @@
             if (activity != null) {
                 mMetricsFeatureProvider.action(
                         getContext(), SettingsEnums.ACTION_PRIVATE_SPACE_SETUP_DONE);
+                //TODO(b/307729746): Add a test to verify PS is locked after setup completion.
+                PrivateSpaceMaintainer.getInstance(activity).lockPrivateSpace();
                 Intent allAppsIntent = new Intent(Intent.ACTION_ALL_APPS);
                 ResolveInfo resolveInfo =
                         activity.getPackageManager()
diff --git a/src/com/android/settings/search/BaseSearchIndexProvider.java b/src/com/android/settings/search/BaseSearchIndexProvider.java
index 581eb2e..d21d983 100644
--- a/src/com/android/settings/search/BaseSearchIndexProvider.java
+++ b/src/com/android/settings/search/BaseSearchIndexProvider.java
@@ -136,7 +136,7 @@
         try {
             controllersFromCode = createPreferenceControllers(context);
         } catch (Exception e) {
-            Log.w(TAG, "Error initial controller");
+            Log.w(TAG, "Error initializing controller in fragment: " + this + ", e: " + e);
         }
 
         final List<SearchIndexableResource> res = getXmlResourcesToIndex(context, true);
diff --git a/src/com/android/settings/slices/SliceBackgroundWorker.java b/src/com/android/settings/slices/SliceBackgroundWorker.java
index 2b02999..5145f18 100644
--- a/src/com/android/settings/slices/SliceBackgroundWorker.java
+++ b/src/com/android/settings/slices/SliceBackgroundWorker.java
@@ -29,6 +29,8 @@
 import android.util.ArrayMap;
 import android.util.Log;
 
+import androidx.annotation.VisibleForTesting;
+
 import java.io.Closeable;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
@@ -172,7 +174,8 @@
     /**
      * Notify that data was updated and attempt to sync changes to the Slice.
      */
-    protected final void notifySliceChange() {
+    @VisibleForTesting
+    public final void notifySliceChange() {
         NotifySliceChangeHandler.getInstance().updateSlice(this);
     }
 
diff --git a/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt b/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt
index 78ca15b..efa88b5 100644
--- a/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt
+++ b/src/com/android/settings/spa/app/appinfo/HibernationSwitchPreference.kt
@@ -22,6 +22,7 @@
 import android.app.AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
 import android.content.Context
 import android.content.pm.ApplicationInfo
+import android.content.pm.Flags
 import android.os.Build
 import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_EXEMPT_BY_SYSTEM
 import android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_UNKNOWN
@@ -60,8 +61,17 @@
     val isCheckedState = presenter.isCheckedFlow.collectAsStateWithLifecycle(initialValue = null)
     SwitchPreference(remember {
         object : SwitchPreferenceModel {
-            override val title = context.getString(R.string.unused_apps_switch)
-            override val summary = { context.getString(R.string.unused_apps_switch_summary) }
+            override val title =
+                if (isArchivingEnabled())
+                    context.getString(R.string.unused_apps_switch_v2)
+                else
+                    context.getString(R.string.unused_apps_switch)
+            override val summary = {
+                if (isArchivingEnabled())
+                    context.getString(R.string.unused_apps_switch_summary_v2)
+                else
+                    context.getString(R.string.unused_apps_switch_summary)
+            }
             override val changeable = { isEligibleState }
             override val checked = { if (changeable()) isCheckedState.value else false }
             override val onCheckedChange = presenter::onCheckedChange
@@ -69,6 +79,9 @@
     })
 }
 
+private fun isArchivingEnabled() =
+        Flags.archiving() || "true" == System.getProperty("pm.archiving.enabled")
+
 private class HibernationSwitchPresenter(context: Context, private val app: ApplicationInfo) {
     private val appOpsManager = context.appOpsManager
     private val permissionControllerManager =
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java
index 86c724c..fa6cc6c 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java
@@ -34,13 +34,13 @@
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
+import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.settings.R;
 import com.android.settings.flags.Flags;
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -85,6 +85,7 @@
 
     @Before
     public void setUp() {
+        ShadowAlertDialogCompat.reset();
         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
         mShadowBluetoothAdapter.setEnabled(true);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
@@ -97,11 +98,6 @@
                 mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
     }
 
-    @After
-    public void tearDown() {
-        ShadowAlertDialogCompat.reset();
-    }
-
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOff_dialogNotExist() {
@@ -154,7 +150,7 @@
         Button shareBtn = rootView.findViewById(R.id.share_btn);
         assertThat(dialog.isShowing()).isTrue();
         assertThat(subtitle1.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(TEST_DEVICE_NAME1).isEqualTo(subtitle1.getText());
+        assertThat(subtitle1.getText().toString()).isEqualTo(TEST_DEVICE_NAME1);
         assertThat(guidance.getVisibility()).isEqualTo(View.GONE);
         assertThat(shareBtn.getVisibility()).isEqualTo(View.VISIBLE);
     }
@@ -205,10 +201,13 @@
         TextView subtitle1 = rootView.findViewById(R.id.share_audio_subtitle1);
         ImageView guidance = rootView.findViewById(R.id.share_audio_guidance);
         Button shareBtn = rootView.findViewById(R.id.share_btn);
+        RecyclerView recyclerView = rootView.findViewById(R.id.btn_list);
         assertThat(dialog.isShowing()).isTrue();
         assertThat(subtitle1.getVisibility()).isEqualTo(View.GONE);
         assertThat(guidance.getVisibility()).isEqualTo(View.GONE);
         assertThat(shareBtn.getVisibility()).isEqualTo(View.GONE);
+        assertThat(recyclerView.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(recyclerView.getAdapter().getItemCount()).isEqualTo(3);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java
index 976e164..335bbe3 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java
@@ -31,14 +31,13 @@
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
+import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.internal.widget.RecyclerView;
 import com.android.settings.R;
 import com.android.settings.flags.Flags;
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -79,6 +78,7 @@
 
     @Before
     public void setUp() {
+        ShadowAlertDialogCompat.reset();
         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
         mShadowBluetoothAdapter.setEnabled(true);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
@@ -96,16 +96,11 @@
         shadowMainLooper().idle();
     }
 
-    @After
-    public void tearDown() {
-        ShadowAlertDialogCompat.reset();
-    }
-
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOff_dialogNotExist() {
         AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
-        assertThat(dialog).isNotNull();
+        assertThat(dialog).isNull();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java
index 5eb0e8a..38f80e0 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java
@@ -38,7 +38,6 @@
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -77,6 +76,7 @@
 
     @Before
     public void setUp() {
+        ShadowAlertDialogCompat.reset();
         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
         mShadowBluetoothAdapter.setEnabled(true);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
@@ -89,11 +89,6 @@
                 mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
     }
 
-    @After
-    public void tearDown() {
-        ShadowAlertDialogCompat.reset();
-    }
-
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOff_dialogNotExist() {
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java
index 1de7b2d..61bc88a 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java
@@ -35,7 +35,6 @@
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -70,6 +69,7 @@
 
     @Before
     public void setUp() {
+        ShadowAlertDialogCompat.reset();
         mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
         mShadowBluetoothAdapter.setEnabled(true);
         mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
@@ -82,11 +82,6 @@
                 mParent, FragmentActivity.class, /* containerViewId= */ 0, /* bundle= */ null);
     }
 
-    @After
-    public void tearDown() {
-        ShadowAlertDialogCompat.reset();
-    }
-
     @Test
     @RequiresFlagsDisabled(Flags.FLAG_ENABLE_LE_AUDIO_SHARING)
     public void onCreateDialog_flagOff_dialogNotExist() {
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorkerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorkerTest.java
index f306693..43630e8 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorkerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothUpdateWorkerTest.java
@@ -16,12 +16,9 @@
 
 package com.android.settings.homepage.contextualcards.slices;
 
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
-import android.content.ContentResolver;
 import android.content.Context;
 import android.net.Uri;
 
@@ -29,7 +26,6 @@
 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
@@ -43,50 +39,46 @@
     private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
 
     private BluetoothUpdateWorker mBluetoothUpdateWorker;
-    private ContentResolver mResolver;
     private Context mContext;
 
     @Before
     public void setUp() {
-        mContext = spy(RuntimeEnvironment.application);
-        mBluetoothUpdateWorker = new BluetoothUpdateWorker(mContext, URI);
-        mResolver = mock(ContentResolver.class);
-        doReturn(mResolver).when(mContext).getContentResolver();
+        mContext = RuntimeEnvironment.getApplication();
+        mBluetoothUpdateWorker = spy(new BluetoothUpdateWorker(mContext, URI));
     }
 
     @Test
     public void onAclConnectionStateChanged_shouldNotifyChange() {
         mBluetoothUpdateWorker.onAclConnectionStateChanged(null, 0);
 
-        verify(mResolver).notifyChange(URI, null);
+        verify(mBluetoothUpdateWorker).notifySliceChange();
     }
 
-    @Ignore("b/315399487")
     @Test
     public void onActiveDeviceChanged_shouldNotifyChange() {
         mBluetoothUpdateWorker.onActiveDeviceChanged(null, 0);
 
-        verify(mResolver).notifyChange(URI, null);
+        verify(mBluetoothUpdateWorker).notifySliceChange();
     }
 
     @Test
     public void onBluetoothStateChanged_shouldNotifyChange() {
         mBluetoothUpdateWorker.onBluetoothStateChanged(0);
 
-        verify(mResolver).notifyChange(URI, null);
+        verify(mBluetoothUpdateWorker).notifySliceChange();
     }
 
     @Test
     public void onConnectionStateChanged_shouldNotifyChange() {
         mBluetoothUpdateWorker.onConnectionStateChanged(null, 0);
 
-        verify(mResolver).notifyChange(URI, null);
+        verify(mBluetoothUpdateWorker).notifySliceChange();
     }
 
     @Test
     public void onProfileConnectionStateChanged_shouldNotifyChange() {
         mBluetoothUpdateWorker.onProfileConnectionStateChanged(null, 0, 0);
 
-        verify(mResolver).notifyChange(URI, null);
+        verify(mBluetoothUpdateWorker).notifySliceChange();
     }
 }
\ No newline at end of file
diff --git a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
index 0a2f3d1..1d27326 100644
--- a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
+++ b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
@@ -21,8 +21,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.ActivityManager;
+import android.app.IActivityManager;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.os.RemoteException;
 import android.provider.Settings;
 
 import androidx.test.core.app.ApplicationProvider;
@@ -30,6 +33,8 @@
 
 import com.android.settings.privatespace.PrivateSpaceMaintainer.ErrorDeletingPrivateSpace;
 
+import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -37,6 +42,7 @@
 
 @RunWith(AndroidJUnit4.class)
 public class PrivateSpaceMaintainerTest {
+    private static final String TAG = "PSMaintainerTest";
     private Context mContext;
     private ContentResolver mContentResolver;
 
@@ -48,6 +54,13 @@
         mContentResolver = mContext.getContentResolver();
     }
 
+    @After
+    public void tearDown() {
+        PrivateSpaceMaintainer privateSpaceMaintainer =
+                PrivateSpaceMaintainer.getInstance(mContext);
+        privateSpaceMaintainer.deletePrivateSpace();
+    }
+
     /** Tests that {@link PrivateSpaceMaintainer#deletePrivateSpace()} deletes PS when PS exists. */
     @Test
     public void deletePrivateSpace_psExists_deletesPS() {
@@ -137,4 +150,52 @@
         assertThat(privateSpaceMaintainer.getHidePrivateSpaceEntryPointSetting())
                 .isEqualTo(HIDE_PRIVATE_SPACE_ENTRY_POINT_ENABLED_VAL);
     }
+
+    /**
+     * Tests that {@link PrivateSpaceMaintainer#lockPrivateSpace()} when PS exists and is running
+     * locks the private profile.
+     */
+    @Test
+    public void lockPrivateSpace_psExistsAndPrivateProfileRunning_locksCreatedPrivateSpace() {
+        PrivateSpaceMaintainer privateSpaceMaintainer =
+                PrivateSpaceMaintainer.getInstance(mContext);
+        privateSpaceMaintainer.createPrivateSpace();
+        assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isTrue();
+        assertThat(privateSpaceMaintainer.isPrivateProfileRunning()).isTrue();
+        assertThat(privateSpaceMaintainer.isPrivateSpaceLocked()).isFalse();
+        assertThat(privateSpaceMaintainer.lockPrivateSpace()).isTrue();
+        assertThat(privateSpaceMaintainer.isPrivateSpaceLocked()).isTrue();
+    }
+
+    /**
+     * Tests that {@link PrivateSpaceMaintainer#lockPrivateSpace()} when PS exist and private
+     * profile not running returns false.
+     */
+    @Test
+    public void lockPrivateSpace_psExistsAndPrivateProfileNotRunning_returnsFalse() {
+        PrivateSpaceMaintainer privateSpaceMaintainer =
+                PrivateSpaceMaintainer.getInstance(mContext);
+        privateSpaceMaintainer.createPrivateSpace();
+        assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isTrue();
+        assertThat(privateSpaceMaintainer.isPrivateProfileRunning()).isTrue();
+        IActivityManager am = ActivityManager.getService();
+        try {
+            am.stopProfile(privateSpaceMaintainer.getPrivateProfileHandle().getIdentifier());
+        } catch (RemoteException e) {
+            Assert.fail("Stop profile failed with exception " + e.getMessage());
+        }
+        assertThat(privateSpaceMaintainer.isPrivateProfileRunning()).isFalse();
+        assertThat(privateSpaceMaintainer.lockPrivateSpace()).isFalse();
+    }
+
+    /**
+     * Tests that {@link PrivateSpaceMaintainer#lockPrivateSpace()} when no PS exists returns false.
+     */
+    @Test
+    public void lockPrivateSpace_psDoesNotExist_returnsFalse() {
+        PrivateSpaceMaintainer privateSpaceMaintainer =
+                PrivateSpaceMaintainer.getInstance(mContext);
+        assertThat(privateSpaceMaintainer.doesPrivateSpaceExist()).isFalse();
+        assertThat(privateSpaceMaintainer.lockPrivateSpace()).isFalse();
+    }
 }