Merge "Toast warning message when non-admin user tries to open dev options." into main
diff --git a/aconfig/settings_security_flag_declarations.aconfig b/aconfig/settings_security_flag_declarations.aconfig
new file mode 100644
index 0000000..42ef4d0
--- /dev/null
+++ b/aconfig/settings_security_flag_declarations.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.settings.flags"
+
+flag {
+  name: "protect_lock_after_timeout_with_auth"
+  namespace: "safety_center"
+  description: "Require an auth challenge to open Lock after timeout page"
+  bug: "315937886"
+}
diff --git a/res/layout/user_dictionary_add_word_fullscreen.xml b/res/layout/user_dictionary_add_word_fullscreen.xml
index 42bd197..cf73d411 100644
--- a/res/layout/user_dictionary_add_word_fullscreen.xml
+++ b/res/layout/user_dictionary_add_word_fullscreen.xml
@@ -17,31 +17,49 @@
     android:id="@+id/user_dict_settings_add_dialog_top"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="vertical" >
-
-    <EditText
-        android:id="@+id/user_dictionary_add_word_text"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="fill_horizontal|center_vertical"
-        android:layout_marginBottom="8dip"
-        android:layout_marginStart="8dip"
-        android:layout_marginTop="8dip"
-        android:hint="@string/user_dict_settings_add_word_hint"
-        android:imeOptions="flagNoFullscreen"
-        android:inputType="textNoSuggestions"
-        android:maxLength="@integer/maximum_user_dictionary_word_length" >
-
-        <requestFocus />
-    </EditText>
+    android:paddingStart="@dimen/settingslib_listPreferredItemPaddingStart"
+    android:paddingLeft="@dimen/settingslib_listPreferredItemPaddingStart"
+    android:paddingEnd="@dimen/settingslib_listPreferredItemPaddingStart"
+    android:paddingRight="@dimen/settingslib_listPreferredItemPaddingStart"
+    android:orientation="vertical">
 
     <GridLayout
         android:id="@+id/user_dictionary_add_word_grid"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginEnd="8dip"
-        android:layout_marginStart="8dip"
-        android:columnCount="2" >
+        android:columnCount="2">
+
+        <TextView
+            android:id="@+id/user_dictionary_add_word_label"
+            style="?android:attr/textAppearanceSmall"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="start|center_vertical"
+            android:text="@string/user_dict_settings_add_word_option_name"
+            android:textColor="?android:attr/textColorPrimary" />
+
+        <EditText
+            android:id="@+id/user_dictionary_add_word_text"
+            android:layout_height="wrap_content"
+            android:layout_gravity="fill_horizontal|center_vertical"
+            android:layout_marginBottom="8dip"
+            android:layout_marginStart="8dip"
+            android:layout_marginTop="8dip"
+            android:minHeight="@dimen/min_tap_target_size"
+            android:hint="@string/user_dict_settings_add_word_hint"
+            android:imeOptions="flagNoFullscreen"
+            android:inputType="textNoSuggestions"
+            android:maxLength="@integer/maximum_user_dictionary_word_length">
+
+            <requestFocus />
+        </EditText>
+    </GridLayout>
+
+    <GridLayout
+        android:id="@+id/user_dictionary_add_shortcut_grid"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:columnCount="2">
 
         <TextView
             android:id="@+id/user_dictionary_add_shortcut_label"
@@ -49,7 +67,8 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="start|center_vertical"
-            android:text="@string/user_dict_settings_add_shortcut_option_name" />
+            android:text="@string/user_dict_settings_add_shortcut_option_name"
+            android:textColor="?android:attr/textColorPrimary" />
 
         <EditText
             android:id="@+id/user_dictionary_add_shortcut"
@@ -58,6 +77,7 @@
             android:layout_marginBottom="8dip"
             android:layout_marginStart="8dip"
             android:layout_marginTop="8dip"
+            android:minHeight="@dimen/min_tap_target_size"
             android:hint="@string/user_dict_settings_add_shortcut_hint"
             android:imeOptions="flagNoFullscreen"
             android:inputType="textNoSuggestions"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index eba04c0..491cd0a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4061,8 +4061,6 @@
     <string name="archiving_succeeded">Archived <xliff:g id="package_label" example="Translate">%1$s</xliff:g></string>
     <!-- Toast message when restoring an app failed. -->
     <string name="restoring_failed">Restoring failed</string>
-    <!-- Toast message when restoring an app succeeded. -->
-    <string name="restoring_succeeded">Restored <xliff:g id="package_label" example="Translate">%1$s</xliff:g></string>
     <!-- Toast message when restoring an app has started. -->
     <string name="restoring_in_progress">Restoring <xliff:g id="package_label" example="Translate">%1$s</xliff:g></string>
 
@@ -11289,7 +11287,7 @@
     <string name="mobile_network_sim_name_rename">Save</string>
     <!-- Label for the on position of a switch on the mobile network details page which allows
          disabling/enabling a SIM. The SIM is enabled in this state. [CHAR LIMIT=40] -->
-    <string name="mobile_network_use_sim_on">Use SIM</string>
+    <string name="mobile_network_use_sim_on">Use this SIM</string>
     <!-- Label for the off position of a switch on the mobile network details page which allows
          disabling/enabling a SIM. The SIM is disabled in this state. [CHAR LIMIT=40] -->
     <string name="mobile_network_use_sim_off">Off</string>
@@ -11432,6 +11430,56 @@
     <!-- Body text of DSDS activation failure dialog. Users could toggle the selected SIM again or reboot to recover. [CHAR LIMIT=NONE] -->
     <string name="dsds_activation_failure_body_msg2">Try turning on the SIM again. If the problem continues, restart your device.</string>
 
+    <!-- Strings for dual SIM onboarding -->
+    <!-- Title of dual sim onboarding's bottom sheets. [CHAR LIMIT=30] -->
+    <string name="sim_onboarding_bottomsheets_title">Set up your SIM</string>
+    <!-- Body text of dual sim onboarding's bottom sheets. [CHAR LIMIT=NONE] -->
+    <string name="sim_onboarding_bottomsheets_msg">Set your mobile network preferences to use multiple SIMs on this device</string>
+    <!-- Title of dual sim onboarding's label sim page. [CHAR LIMIT=30] -->
+    <string name="sim_onboarding_label_sim_title">Label your SIMs</string>
+    <!-- Body text of dual sim onboarding's label sim page. [CHAR LIMIT=NONE] -->
+    <string name="sim_onboarding_label_sim_msg">You’ll see these labels when making calls, sending texts, and using data, and in Settings</string>
+    <!-- Title of dual sim onboarding's label sim dialog. [CHAR LIMIT=30] -->
+    <string name="sim_onboarding_label_sim_dialog_title">SIM label</string>
+    <!-- Label text of dual sim onboarding's label sim dialog. [CHAR LIMIT=30] -->
+    <string name="sim_onboarding_label_sim_dialog_label">Label</string>
+    <!-- Title of dual sim onboarding's select sim page. [CHAR LIMIT=30] -->
+    <string name="sim_onboarding_select_sim_title">Select which SIMs to use</string>
+    <!-- Body text of dual sim onboarding's select sim page. [CHAR LIMIT=NONE] -->
+    <string name="sim_onboarding_select_sim_msg">You can use 2 SIMs at a time</string>
+    <!-- Title of dual sim onboarding's primary sim page. [CHAR LIMIT=30] -->
+    <string name="sim_onboarding_primary_sim_title">Set your primary SIMs</string>
+    <!-- Body text of dual sim onboarding's primary sim page. [CHAR LIMIT=NONE] -->
+    <string name="sim_onboarding_primary_sim_msg">Choose which SIMs to use by default for calls, texts, and data</string>
+
+    <!-- Title of primary sim at SIMs page. [CHAR LIMIT=30] -->
+    <string name="primary_sim_title">Your primary SIMs</string>
+
+    <!-- Title of Calls item/dialog at dual sim onboarding's primary sim page or SIMs page. [CHAR LIMIT=30] -->
+    <string name="primary_sim_calls_title">Calls</string>
+    <!-- Title of Texts item/dialog at dual sim onboarding's primary sim page or SIMs page. [CHAR LIMIT=30] -->
+    <string name="primary_sim_texts_title">Texts</string>
+    <!-- Title of automatic data switching at dual sim onboarding's primary sim page or SIMs page. [CHAR LIMIT=30] -->
+    <string name="primary_sim_automatic_data_title">Automatic data switching</string>
+    <!-- Body text of automatic data switching at dual sim onboarding's primary sim page or SIMs page. [CHAR LIMIT=NONE] -->
+    <string name="primary_sim_automatic_data_msg">Use data from either SIM depending on coverage and availability</string>
+
+    <!-- Text of phone number item when the sim is data only. [CHAR LIMIT=NONE] -->
+    <string name="sim_onboarding_phoneNumber_data_only">Data only</string>
+
+    <!-- Button on the dual sim onboarding to start to set up sim. [CHAR LIMIT=30] -->
+    <string name="sim_onboarding_setup">Set up</string>
+    <!-- Button on the dual sim onboarding to go to next page. [CHAR LIMIT=30] -->
+    <string name="sim_onboarding_next">Next</string>
+    <!-- Text on the progressbar of dual sim onboarding for turning sim on. [CHAR LIMIT=30] -->
+    <string name="sim_onboarding_profressbar_turning_sim_on">Turning on <xliff:g id="carrier_name" example="Google Fi">%1$s</xliff:g>&#8230;</string>
+    <!-- Title of service provider name(SPN) at mobile network settings page. [CHAR LIMIT=30] -->
+    <string name="mobile_network_spn_title">Mobile network</string>
+    <!-- Title of phone number at mobile network settings page. [CHAR LIMIT=30] -->
+    <string name="mobile_network_phone_number_title">Phone number</string>
+    <!-- Title of SIM label and color editor dialog at mobile network settings page. [CHAR LIMIT=30] -->
+    <string name="mobile_network_sim_label_color_title">SIM label and color</string>
+
     <!--  Strings for SIM push notifications  -->
     <!-- Category name of the notifications related to SIM setup. [CHAR LIMIT=NONE] -->
     <string name="sim_setup_channel_id">Network activation</string>
diff --git a/res/xml/app_ops_permissions_details.xml b/res/xml/app_ops_permissions_details.xml
index eb8188b..3cbe009 100644
--- a/res/xml/app_ops_permissions_details.xml
+++ b/res/xml/app_ops_permissions_details.xml
@@ -17,7 +17,7 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto">
 
-    <com.android.settings.widget.FilterTouchesSwitchPreference
+    <com.android.settingslib.RestrictedSwitchPreference
         android:key="app_ops_settings_switch" />
 
     <com.android.settingslib.widget.FooterPreference
diff --git a/res/xml/screen_lock_settings.xml b/res/xml/screen_lock_settings.xml
index 3f732b9..19061d9 100644
--- a/res/xml/screen_lock_settings.xml
+++ b/res/xml/screen_lock_settings.xml
@@ -40,7 +40,7 @@
 
 
     <!-- available in pin/pattern/password -->
-    <com.android.settings.display.TimeoutListPreference
+    <com.android.settings.security.screenlock.ProtectedTimeoutListPreference
         android:key="lock_after_timeout"
         android:title="@string/lock_after_timeout"
         android:summary="@string/summary_placeholder"
diff --git a/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java
index 858b374..869443c 100644
--- a/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java
+++ b/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceController.java
@@ -21,7 +21,7 @@
 import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
 import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
 
-
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.database.ContentObserver;
 import android.net.Uri;
@@ -42,6 +42,8 @@
 
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 
 /**
@@ -62,6 +64,8 @@
     @Nullable
     private TwoStatePreference mPreference;
 
+    private MetricsFeatureProvider mMetricsFeatureProvider;
+
     public KeyboardVibrationTogglePreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
         mVibrator = context.getSystemService(Vibrator.class);
@@ -75,6 +79,7 @@
                 }
             }
         };
+        mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
     }
 
     @Override
@@ -120,6 +125,8 @@
     @Override
     public boolean setChecked(boolean isChecked) {
         final boolean success = updateKeyboardVibrationSetting(isChecked);
+        mMetricsFeatureProvider.action(mContext,
+                SettingsEnums.ACTION_KEYBOARD_VIBRATION_CHANGED, isChecked);
         if (success && isChecked) {
             // Play the preview vibration effect when the toggle is on.
             final VibrationAttributes touchAttrs =
diff --git a/src/com/android/settings/applications/UsageAccessDetails.java b/src/com/android/settings/applications/UsageAccessDetails.java
index b81c719..6976149 100644
--- a/src/com/android/settings/applications/UsageAccessDetails.java
+++ b/src/com/android/settings/applications/UsageAccessDetails.java
@@ -38,11 +38,11 @@
 import androidx.preference.Preference;
 import androidx.preference.Preference.OnPreferenceChangeListener;
 import androidx.preference.Preference.OnPreferenceClickListener;
-import androidx.preference.TwoStatePreference;
 
 import com.android.settings.R;
 import com.android.settings.applications.AppStateUsageBridge.UsageState;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.RestrictedSwitchPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 public class UsageAccessDetails extends AppInfoWithHeader implements OnPreferenceChangeListener,
@@ -57,7 +57,7 @@
     // TODO: Break out this functionality into its own class.
     private AppStateUsageBridge mUsageBridge;
     private AppOpsManager mAppOpsManager;
-    private TwoStatePreference mSwitchPref;
+    private RestrictedSwitchPreference mSwitchPref;
     private Preference mUsageDesc;
     private Intent mSettingsIntent;
     private UsageState mUsageState;
@@ -78,7 +78,7 @@
         mDpm = context.getSystemService(DevicePolicyManager.class);
 
         addPreferencesFromResource(R.xml.app_ops_permissions_details);
-        mSwitchPref = (TwoStatePreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
+        mSwitchPref = (RestrictedSwitchPreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
         mUsageDesc = findPreference(KEY_APP_OPS_SETTINGS_DESC);
 
         getPreferenceScreen().setTitle(R.string.usage_access);
@@ -170,8 +170,16 @@
                 mPackageInfo.applicationInfo.uid);
 
         boolean hasAccess = mUsageState.isPermissible();
+        boolean shouldEnable = mUsageState.permissionDeclared;
+
+        if (shouldEnable && !hasAccess) {
+            mSwitchPref.checkEcmRestrictionAndSetDisabled(AppOpsManager.OPSTR_GET_USAGE_STATS,
+                    mPackageName, mPackageInfo.applicationInfo.uid);
+            shouldEnable = !mSwitchPref.isDisabledByEcm();
+        }
+
         mSwitchPref.setChecked(hasAccess);
-        mSwitchPref.setEnabled(mUsageState.permissionDeclared);
+        mSwitchPref.setEnabled(shouldEnable);
 
         ResolveInfo resolveInfo = mPm.resolveActivityAsUser(mSettingsIntent,
                 PackageManager.GET_META_DATA, mUserId);
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItem.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItem.java
index 370a4df..f7dff2e 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItem.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItem.java
@@ -86,6 +86,14 @@
         return new UserHandle(getUserIdFromDeviceAdminInfo(mInfo));
     }
 
+    public int getUid() {
+        return mInfo.getActivityInfo().applicationInfo.uid;
+    }
+
+    public String getPackageName() {
+        return mInfo.getPackageName();
+    }
+
     public Intent getLaunchIntent(Context context) {
         return new Intent(context, DeviceAdminAdd.class)
                 .putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mInfo.getComponent());
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java
index 1184d8e..55ba8ac 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java
@@ -18,6 +18,7 @@
 
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
 
+import android.Manifest;
 import android.app.AppGlobals;
 import android.app.admin.DeviceAdminInfo;
 import android.app.admin.DeviceAdminReceiver;
@@ -45,12 +46,13 @@
 
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.RestrictedSwitchPreference;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
-import com.android.settingslib.widget.AppSwitchPreference;
 import com.android.settingslib.widget.FooterPreference;
+import com.android.settingslib.widget.TwoTargetPreference;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -167,35 +169,35 @@
         if (mFooterPreference != null) {
             mFooterPreference.setVisible(mAdmins.isEmpty());
         }
-        final Map<String, AppSwitchPreference> preferenceCache = new ArrayMap<>();
+        final Map<String, RestrictedSwitchPreference> preferenceCache = new ArrayMap<>();
         final Context prefContext = mPreferenceGroup.getContext();
         final int childrenCount = mPreferenceGroup.getPreferenceCount();
         for (int i = 0; i < childrenCount; i++) {
             final Preference pref = mPreferenceGroup.getPreference(i);
-            if (!(pref instanceof AppSwitchPreference)) {
+            if (!(pref instanceof RestrictedSwitchPreference switchPref)) {
                 continue;
             }
-            final AppSwitchPreference appSwitch = (AppSwitchPreference) pref;
-            preferenceCache.put(appSwitch.getKey(), appSwitch);
+            preferenceCache.put(switchPref.getKey(), switchPref);
         }
         for (DeviceAdminListItem item : mAdmins) {
             final String key = item.getKey();
-            AppSwitchPreference pref = preferenceCache.remove(key);
+            RestrictedSwitchPreference pref = preferenceCache.remove(key);
             if (pref == null) {
-                pref = new AppSwitchPreference(prefContext);
+                pref = new RestrictedSwitchPreference(prefContext);
                 mPreferenceGroup.addPreference(pref);
             }
             bindPreference(item, pref);
         }
-        for (AppSwitchPreference unusedCacheItem : preferenceCache.values()) {
+        for (RestrictedSwitchPreference unusedCacheItem : preferenceCache.values()) {
             mPreferenceGroup.removePreference(unusedCacheItem);
         }
     }
 
-    private void bindPreference(DeviceAdminListItem item, AppSwitchPreference pref) {
+    private void bindPreference(DeviceAdminListItem item, RestrictedSwitchPreference pref) {
         pref.setKey(item.getKey());
         pref.setTitle(item.getName());
         pref.setIcon(item.getIcon());
+        pref.setIconSize(TwoTargetPreference.ICON_SIZE_DEFAULT);
         pref.setChecked(item.isActive());
         pref.setSummary(item.getDescription());
         pref.setEnabled(item.isEnabled());
@@ -207,6 +209,8 @@
         });
         pref.setOnPreferenceChangeListener((preference, newValue) -> false);
         pref.setSingleLineTitle(true);
+        pref.checkEcmRestrictionAndSetDisabled(Manifest.permission.BIND_DEVICE_ADMIN,
+                item.getPackageName(), item.getUid());
     }
 
     /**
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
index 2f56f77..3396b8b 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
@@ -37,22 +37,20 @@
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.connecteddevice.DevicePreferenceCallback;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.VolumeControlProfile;
-import com.android.settingslib.utils.ThreadUtils;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 
 public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePreferenceController
         implements DevicePreferenceCallback {
-    private static final boolean DEBUG = BluetoothUtils.D;
-
     private static final String TAG = "AudioSharingDeviceVolumeGroupController";
     private static final String KEY = "audio_sharing_device_volume_group";
 
@@ -63,8 +61,43 @@
     private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
     private FragmentManager mFragmentManager;
     private PreferenceGroup mPreferenceGroup;
-    private Map<Preference, BluetoothVolumeControl.Callback> mCallbackMap =
-            new HashMap<Preference, BluetoothVolumeControl.Callback>();
+    private List<AudioSharingDeviceVolumePreference> mVolumePreferences = new ArrayList<>();
+    private Map<Integer, Integer> mValueMap = new HashMap<Integer, Integer>();
+
+    private BluetoothVolumeControl.Callback mVolumeControlCallback =
+            new BluetoothVolumeControl.Callback() {
+                @Override
+                public void onVolumeOffsetChanged(
+                        @NonNull BluetoothDevice device, int volumeOffset) {}
+
+                @Override
+                public void onDeviceVolumeChanged(
+                        @NonNull BluetoothDevice device,
+                        @IntRange(from = -255, to = 255) int volume) {
+                    CachedBluetoothDevice cachedDevice =
+                            mLocalBtManager.getCachedDeviceManager().findDevice(device);
+                    if (cachedDevice == null) return;
+                    mValueMap.put(cachedDevice.getGroupId(), volume);
+                    for (AudioSharingDeviceVolumePreference preference : mVolumePreferences) {
+                        if (preference.getCachedDevice() != null
+                                && preference.getCachedDevice().getGroupId()
+                                        == cachedDevice.getGroupId()) {
+                            // If the callback return invalid volume, try to
+                            // get the volume from AudioManager.STREAM_MUSIC
+                            int finalVolume = getAudioVolumeIfNeeded(volume);
+                            Log.d(
+                                    TAG,
+                                    "onDeviceVolumeChanged: set volume to "
+                                            + finalVolume
+                                            + " for "
+                                            + device.getAnonymizedAddress());
+                            mContext.getMainExecutor()
+                                    .execute(() -> preference.setProgress(finalVolume));
+                            break;
+                        }
+                    }
+                }
+            };
 
     private BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
             new BluetoothLeBroadcastAssistant.Callback() {
@@ -176,6 +209,10 @@
         }
         mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
         mBluetoothDeviceUpdater.registerCallback();
+        if (mVolumeControl != null) {
+            Log.d(TAG, "onStart() Registered volume control callback");
+            mVolumeControl.registerCallback(mExecutor, mVolumeControlCallback);
+        }
     }
 
     @Override
@@ -191,17 +228,16 @@
         }
         mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback);
         mBluetoothDeviceUpdater.unregisterCallback();
+        if (mVolumeControl != null) {
+            Log.d(TAG, "onStop() Unregistered volume control callback");
+            mVolumeControl.unregisterCallback(mVolumeControlCallback);
+            mValueMap.clear();
+        }
     }
 
     @Override
     public void onDestroy(@NonNull LifecycleOwner owner) {
-        for (var entry : mCallbackMap.entrySet()) {
-            if (DEBUG) {
-                Log.d(TAG, "onDestroy: unregister callback for " + entry.getKey());
-            }
-            mVolumeControl.unregisterCallback(entry.getValue());
-        }
-        mCallbackMap.clear();
+        mVolumePreferences.clear();
     }
 
     @Override
@@ -228,14 +264,22 @@
             mPreferenceGroup.setVisible(true);
         }
         mPreferenceGroup.addPreference(preference);
-        if (mVolumeControl != null && preference instanceof AudioSharingDeviceVolumePreference) {
-            BluetoothVolumeControl.Callback callback =
-                    buildVcCallback((AudioSharingDeviceVolumePreference) preference);
-            mCallbackMap.put(preference, callback);
-            if (DEBUG) {
-                Log.d(TAG, "onDeviceAdded: register callback for " + preference);
-            }
-            mVolumeControl.registerCallback(mExecutor, callback);
+        if (preference instanceof AudioSharingDeviceVolumePreference) {
+            var volumePref = (AudioSharingDeviceVolumePreference) preference;
+            mVolumePreferences.add(volumePref);
+            if (volumePref.getProgress() > 0) return;
+            CachedBluetoothDevice device = volumePref.getCachedDevice();
+            if (device == null) return;
+            int volume = mValueMap.getOrDefault(device.getGroupId(), -1);
+            // If the volume is invalid, try to get the volume from AudioManager.STREAM_MUSIC
+            int finalVolume = getAudioVolumeIfNeeded(volume);
+            Log.d(
+                    TAG,
+                    "onDeviceAdded: set volume to "
+                            + finalVolume
+                            + " for "
+                            + device.getDevice().getAnonymizedAddress());
+            mContext.getMainExecutor().execute(() -> volumePref.setProgress(finalVolume));
         }
     }
 
@@ -245,12 +289,18 @@
         if (mPreferenceGroup.getPreferenceCount() == 0) {
             mPreferenceGroup.setVisible(false);
         }
-        if (mVolumeControl != null && mCallbackMap.containsKey(preference)) {
-            if (DEBUG) {
-                Log.d(TAG, "onDeviceRemoved: unregister callback for " + preference);
+        if (preference instanceof AudioSharingDeviceVolumePreference) {
+            var volumePref = (AudioSharingDeviceVolumePreference) preference;
+            if (mVolumePreferences.contains(volumePref)) {
+                mVolumePreferences.remove(volumePref);
             }
-            mVolumeControl.unregisterCallback(mCallbackMap.get(preference));
-            mCallbackMap.remove(preference);
+            CachedBluetoothDevice device = volumePref.getCachedDevice();
+            Log.d(
+                    TAG,
+                    "onDeviceRemoved: "
+                            + (device == null
+                                    ? "null"
+                                    : device.getDevice().getAnonymizedAddress()));
         }
     }
 
@@ -278,39 +328,6 @@
                         fragment.getMetricsCategory());
     }
 
-    private BluetoothVolumeControl.Callback buildVcCallback(
-            AudioSharingDeviceVolumePreference preference) {
-        return new BluetoothVolumeControl.Callback() {
-            @Override
-            public void onVolumeOffsetChanged(BluetoothDevice device, int volumeOffset) {}
-
-            @Override
-            public void onDeviceVolumeChanged(
-                    @NonNull BluetoothDevice device,
-                    @IntRange(from = -255, to = 255) int volume) {
-                CachedBluetoothDevice cachedDevice =
-                        mLocalBtManager.getCachedDeviceManager().findDevice(device);
-                if (cachedDevice == null) return;
-                if (preference.getCachedDevice() != null
-                        && preference.getCachedDevice().getGroupId() == cachedDevice.getGroupId()) {
-                    // If the callback return invalid volume, try to get the volume from
-                    // AudioManager.STREAM_MUSIC
-                    int finalVolume = getAudioVolumeIfNeeded(volume);
-                    Log.d(
-                            TAG,
-                            "onDeviceVolumeChanged: set volume to "
-                                    + finalVolume
-                                    + " for "
-                                    + device.getAnonymizedAddress());
-                    ThreadUtils.postOnMainThread(
-                            () -> {
-                                preference.setProgress(finalVolume);
-                            });
-                }
-            }
-        };
-    }
-
     private int getAudioVolumeIfNeeded(int volume) {
         if (volume >= 0) return volume;
         try {
diff --git a/src/com/android/settings/datetime/TimeZonePreferenceController.java b/src/com/android/settings/datetime/TimeZonePreferenceController.java
index 913640d..d45173f 100644
--- a/src/com/android/settings/datetime/TimeZonePreferenceController.java
+++ b/src/com/android/settings/datetime/TimeZonePreferenceController.java
@@ -26,6 +26,7 @@
 import androidx.preference.Preference;
 
 import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.RestrictedPreference;
 import com.android.settingslib.datetime.ZoneGetter;
 
 import java.util.Calendar;
@@ -52,6 +53,12 @@
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
+
+        if (preference instanceof RestrictedPreference
+                && ((RestrictedPreference) preference).isDisabledByAdmin()) {
+            return;
+        }
+
         preference.setEnabled(shouldEnableManualTimeZoneSelection());
     }
 
diff --git a/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java b/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
index abe640b..05dc5be 100644
--- a/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
+++ b/src/com/android/settings/inputmethod/NewKeyboardLayoutEnabledLocalesFragment.java
@@ -105,8 +105,13 @@
     public void onActivityCreated(final Bundle icicle) {
         super.onActivityCreated(icicle);
         Bundle arguments = getArguments();
+        if (arguments == null) {
+            Log.e(TAG, "Arguments should not be null");
+            return;
+        }
         mInputDeviceIdentifier =
-                arguments.getParcelable(NewKeyboardSettingsUtils.EXTRA_INPUT_DEVICE_IDENTIFIER);
+                arguments.getParcelable(NewKeyboardSettingsUtils.EXTRA_INPUT_DEVICE_IDENTIFIER,
+                        InputDeviceIdentifier.class);
         if (mInputDeviceIdentifier == null) {
             Log.e(TAG, "The inputDeviceIdentifier should not be null");
             return;
@@ -128,6 +133,7 @@
         InputDevice inputDevice =
                 NewKeyboardSettingsUtils.getInputDevice(mIm, mInputDeviceIdentifier);
         if (inputDevice == null) {
+            Log.e(TAG, "Unable to start: input device is null");
             getActivity().finish();
             return;
         }
diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
index 38de93e..7de505e 100644
--- a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
@@ -151,7 +151,8 @@
             mKeyboardA11yCategory.removePreference(mAccessibilityStickyKeys);
         }
         InputDeviceIdentifier inputDeviceIdentifier = activity.getIntent().getParcelableExtra(
-                KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_IDENTIFIER);
+                KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_IDENTIFIER,
+                InputDeviceIdentifier.class);
         int intentFromWhere =
                 activity.getIntent().getIntExtra(android.provider.Settings.EXTRA_ENTRYPOINT, -1);
         if (intentFromWhere != -1) {
@@ -168,7 +169,8 @@
     }
 
     private static boolean isAutoSelection(Bundle bundle, InputDeviceIdentifier identifier) {
-        if (bundle != null && bundle.getParcelable(EXTRA_AUTO_SELECTION) != null) {
+        if (bundle != null && bundle.getParcelable(EXTRA_AUTO_SELECTION,
+                InputDeviceIdentifier.class) != null) {
             return false;
         }
         return identifier != null;
@@ -446,7 +448,8 @@
 
         if (mIntentWaitingForResult != null) {
             InputDeviceIdentifier inputDeviceIdentifier = mIntentWaitingForResult
-                    .getParcelableExtra(KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_IDENTIFIER);
+                    .getParcelableExtra(KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_IDENTIFIER,
+                            InputDeviceIdentifier.class);
             mIntentWaitingForResult = null;
             showKeyboardLayoutDialog(inputDeviceIdentifier);
         }
diff --git a/src/com/android/settings/security/screenlock/ProtectedTimeoutListPreference.java b/src/com/android/settings/security/screenlock/ProtectedTimeoutListPreference.java
new file mode 100644
index 0000000..26d914c
--- /dev/null
+++ b/src/com/android/settings/security/screenlock/ProtectedTimeoutListPreference.java
@@ -0,0 +1,40 @@
+/*
+ * 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.security.screenlock;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.settings.display.TimeoutListPreference;
+import com.android.settings.flags.Flags;
+import com.android.settings.wifi.dpp.WifiDppUtils;
+
+/** Wraps {@link TimeoutListPreference} with an authentication challenge for user. */
+public class ProtectedTimeoutListPreference extends TimeoutListPreference {
+    public ProtectedTimeoutListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public void performClick() {
+        if (Flags.protectLockAfterTimeoutWithAuth()) {
+            WifiDppUtils.showLockScreen(getContext(), super::performClick);
+        } else {
+            super.performClick();
+        }
+    }
+}
diff --git a/src/com/android/settings/spa/app/appinfo/AppArchiveButton.kt b/src/com/android/settings/spa/app/appinfo/AppArchiveButton.kt
index 0eef9c3..e4fb1ea 100644
--- a/src/com/android/settings/spa/app/appinfo/AppArchiveButton.kt
+++ b/src/com/android/settings/spa/app/appinfo/AppArchiveButton.kt
@@ -54,6 +54,7 @@
     private val packageName = packageInfoPresenter.packageName
     private val userHandle = UserHandle.of(packageInfoPresenter.userId)
     private var broadcastReceiverIsCreated = false
+    private lateinit var appLabel: CharSequence
 
     @Composable
     fun getActionButton(app: ApplicationInfo): ActionButton {
@@ -61,11 +62,12 @@
             val intentFilter = IntentFilter(INTENT_ACTION)
             DisposableBroadcastReceiverAsUser(intentFilter, userHandle) { intent ->
                 if (app.packageName == intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)) {
-                    onReceive(intent, app)
+                    onReceive(intent)
                 }
             }
             broadcastReceiverIsCreated = true
         }
+        appLabel = userPackageManager.getApplicationLabel(app)
         return ActionButton(
             text = context.getString(R.string.archive),
             imageVector = Icons.Outlined.CloudUpload,
@@ -113,10 +115,9 @@
         }
     }
 
-    private fun onReceive(intent: Intent, app: ApplicationInfo) {
+    private fun onReceive(intent: Intent) {
         when (val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, Int.MIN_VALUE)) {
             PackageInstaller.STATUS_SUCCESS -> {
-                val appLabel = userPackageManager.getApplicationLabel(app)
                 Toast.makeText(
                     context,
                     context.getString(R.string.archiving_succeeded, appLabel),
diff --git a/src/com/android/settings/spa/app/appinfo/AppForceStopButton.kt b/src/com/android/settings/spa/app/appinfo/AppForceStopButton.kt
index 345d931..c3183a7 100644
--- a/src/com/android/settings/spa/app/appinfo/AppForceStopButton.kt
+++ b/src/com/android/settings/spa/app/appinfo/AppForceStopButton.kt
@@ -19,6 +19,7 @@
 import android.app.settings.SettingsEnums
 import android.content.pm.ApplicationInfo
 import android.os.UserManager
+import androidx.annotation.VisibleForTesting
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.Report
 import androidx.compose.material3.Text
@@ -87,9 +88,10 @@
         dialogPresenter.open()
     }
 
-    private fun getAdminRestriction(app: ApplicationInfo): EnforcedAdmin? = when {
+    @VisibleForTesting
+    fun getAdminRestriction(app: ApplicationInfo): EnforcedAdmin? = when {
         packageManager.isPackageStateProtected(app.packageName, app.userId) -> {
-            RestrictedLockUtilsInternal.getDeviceOwner(context)
+            RestrictedLockUtilsInternal.getDeviceOwner(context) ?: EnforcedAdmin()
         }
 
         else -> RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
diff --git a/src/com/android/settings/spa/app/appinfo/AppRestoreButton.kt b/src/com/android/settings/spa/app/appinfo/AppRestoreButton.kt
index c47fdac..6596529 100644
--- a/src/com/android/settings/spa/app/appinfo/AppRestoreButton.kt
+++ b/src/com/android/settings/spa/app/appinfo/AppRestoreButton.kt
@@ -73,12 +73,6 @@
         )
         try {
             packageInstaller.requestUnarchive(app.packageName, pendingIntent.intentSender)
-            val appLabel = userPackageManager.getApplicationLabel(app)
-            Toast.makeText(
-                context,
-                context.getString(R.string.restoring_in_progress, appLabel),
-                Toast.LENGTH_SHORT
-            ).show()
         } catch (e: Exception) {
             Log.e(LOG_TAG, "Request unarchive failed", e)
             Toast.makeText(
@@ -92,23 +86,11 @@
     private fun onReceive(intent: Intent, app: ApplicationInfo) {
         when (val unarchiveStatus =
             intent.getIntExtra(PackageInstaller.EXTRA_UNARCHIVE_STATUS, Int.MIN_VALUE)) {
-            PackageInstaller.STATUS_PENDING_USER_ACTION -> {
-                Log.e(
-                    LOG_TAG,
-                    "Request unarchiving failed for $packageName with code $unarchiveStatus"
-                )
-                Toast.makeText(
-                    context,
-                    context.getString(R.string.restoring_failed),
-                    Toast.LENGTH_SHORT
-                ).show()
-            }
-
-            PackageInstaller.STATUS_SUCCESS -> {
+            PackageInstaller.UNARCHIVAL_OK -> {
                 val appLabel = userPackageManager.getApplicationLabel(app)
                 Toast.makeText(
                     context,
-                    context.getString(R.string.restoring_succeeded, appLabel),
+                    context.getString(R.string.restoring_in_progress, appLabel),
                     Toast.LENGTH_SHORT
                 ).show()
             }
diff --git a/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java
index 6bf83c6..cf12e34 100644
--- a/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/KeyboardVibrationTogglePreferenceControllerTest.java
@@ -23,9 +23,13 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.vibrator.Flags;
@@ -37,6 +41,7 @@
 import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
+import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -49,7 +54,6 @@
 /** Tests for {@link KeyboardVibrationTogglePreferenceController}. */
 @RunWith(RobolectricTestRunner.class)
 public class KeyboardVibrationTogglePreferenceControllerTest {
-
     @Rule
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
@@ -59,8 +63,8 @@
     private Context mContext;
     private Resources mResources;
     private KeyboardVibrationTogglePreferenceController mController;
-
     private SwitchPreference mPreference;
+    private FakeFeatureFactory mFeatureFactory;
 
     @Before
     public void setUp() {
@@ -68,6 +72,7 @@
         mContext = spy(ApplicationProvider.getApplicationContext());
         mResources = spy(mContext.getResources());
         when(mContext.getResources()).thenReturn(mResources);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
         mController = new KeyboardVibrationTogglePreferenceController(mContext, "preferenceKey");
         mPreference = new SwitchPreference(mContext);
         when(mPreferenceScreen.findPreference(
@@ -148,6 +153,8 @@
         mController.setChecked(true);
 
         assertThat(readSystemSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED)).isEqualTo(ON);
+        verify(mFeatureFactory.metricsFeatureProvider).action(any(),
+                eq(SettingsEnums.ACTION_KEYBOARD_VIBRATION_CHANGED), eq(true));
     }
 
     @Test
@@ -160,6 +167,8 @@
         mController.setChecked(false);
 
         assertThat(readSystemSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED)).isEqualTo(OFF);
+        verify(mFeatureFactory.metricsFeatureProvider).action(any(),
+                eq(SettingsEnums.ACTION_KEYBOARD_VIBRATION_CHANGED), eq(false));
     }
 
     private void updateSystemSetting(String key, int value) {
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java
index 42e5ef6..3174101 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragmentTest.java
@@ -19,8 +19,10 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -32,6 +34,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.os.Bundle;
+import android.platform.test.annotations.RequiresFlagsDisabled;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -45,7 +48,9 @@
 import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
+import com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment;
 import com.android.settings.widget.SettingsMainSwitchPreference;
 
 import org.junit.Before;
@@ -53,6 +58,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
@@ -298,7 +304,9 @@
 
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_CLEANUP_ACCESSIBILITY_WARNING_DIALOG)
-    public void clickShortcutSettingsPreference_warningNotRequired_dontShowWarning()
+    @RequiresFlagsDisabled(
+            com.android.settings.accessibility.Flags.FLAG_EDIT_SHORTCUTS_IN_FULL_SCREEN)
+    public void clickShortcutSettingsPreference_warningNotRequired_dontShowWarning_showDialog()
             throws Throwable {
         setupServiceWarningRequired(false);
         mFragment.mShortcutPreference = new ShortcutPreference(mContext, /* attrs= */null);
@@ -309,6 +317,23 @@
                 AccessibilityDialogUtils.DialogEnums.EDIT_SHORTCUT);
     }
 
+    @Test
+    @RequiresFlagsEnabled({Flags.FLAG_CLEANUP_ACCESSIBILITY_WARNING_DIALOG,
+            com.android.settings.accessibility.Flags.FLAG_EDIT_SHORTCUTS_IN_FULL_SCREEN})
+    public void clickShortcutSettingsPreference_warningNotRequired_dontShowWarning_launchActivity()
+            throws Throwable {
+        setupServiceWarningRequired(false);
+        mFragment.mShortcutPreference = new ShortcutPreference(mContext, /* attrs= */null);
+        doNothing().when(mContext).startActivity(any());
+
+        mFragment.onSettingsClicked(mFragment.mShortcutPreference);
+
+        ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).startActivity(captor.capture());
+        assertThat(captor.getValue().getExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+                .isEqualTo(EditShortcutsPreferenceFragment.class.getName());
+    }
+
     private void setupTileService(String packageName, String name, String tileName) {
         final Intent tileProbe = new Intent(TileService.ACTION_QS_TILE);
         final ResolveInfo info = new ResolveInfo();
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/vrlistener/VrListenerScreenPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/vrlistener/VrListenerScreenPreferenceControllerTest.java
index 1e5e235..7405980 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/vrlistener/VrListenerScreenPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/vrlistener/VrListenerScreenPreferenceControllerTest.java
@@ -23,15 +23,15 @@
 
 import android.content.Context;
 
-import com.android.settings.testutils.shadow.ShadowActivityManager;
+import androidx.test.core.app.ApplicationProvider;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowActivityManager;
 
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {
@@ -45,7 +45,7 @@
 
     @Before
     public void setUp() {
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
         mController = new VrListenerScreenPreferenceController(mContext, "key");
         mActivityManager = Shadow.extract(mContext.getSystemService(Context.ACTIVITY_SERVICE));
     }
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/zenaccess/ZenAccessControllerTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/zenaccess/ZenAccessControllerTest.java
index bf112a6..badc5db 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/zenaccess/ZenAccessControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/zenaccess/ZenAccessControllerTest.java
@@ -25,23 +25,20 @@
 import android.app.NotificationManager;
 import android.content.Context;
 
+import androidx.test.core.app.ApplicationProvider;
+
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowActivityManager;
 import com.android.settings.testutils.shadow.ShadowNotificationManager;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
 
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {
-        ShadowActivityManager.class,
-})
 public class ZenAccessControllerTest {
 
     private static final String TEST_PKG = "com.test.package";
@@ -49,15 +46,12 @@
     private FakeFeatureFactory mFeatureFactory;
     private Context mContext;
     private ZenAccessController mController;
-    private ShadowActivityManager mActivityManager;
-
 
     @Before
     public void setUp() {
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
         mFeatureFactory = FakeFeatureFactory.setupForTest();
         mController = new ZenAccessController(mContext, "key");
-        mActivityManager = Shadow.extract(mContext.getSystemService(Context.ACTIVITY_SERVICE));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index c6a9a71..583db5e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -46,6 +46,7 @@
 
 import androidx.fragment.app.FragmentActivity;
 import androidx.loader.app.LoaderManager;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
@@ -53,7 +54,6 @@
 import com.android.settings.fuelgauge.batteryusage.BatteryEntry;
 import com.android.settings.fuelgauge.batteryusage.ConvertUtils;
 import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowActivityManager;
 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.PrimarySwitchPreference;
@@ -65,15 +65,16 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.mockito.stubbing.Answer;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
@@ -83,10 +84,13 @@
 @Config(
         shadows = {
             ShadowEntityHeaderController.class,
-            ShadowActivityManager.class,
             com.android.settings.testutils.shadow.ShadowFragment.class,
         })
 public class AdvancedPowerUsageDetailTest {
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
     private static final String APP_LABEL = "app label";
     private static final String SUMMARY = "summary";
     private static final String[] PACKAGE_NAME = {"com.android.app"};
@@ -125,9 +129,7 @@
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mContext = spy(RuntimeEnvironment.application);
+        mContext = spy(ApplicationProvider.getApplicationContext());
         when(mContext.getPackageName()).thenReturn("foo");
         mFeatureFactory = FakeFeatureFactory.setupForTest();
         mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java
index 6edbafa..b6caa7f 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java
@@ -47,11 +47,11 @@
 
 import androidx.fragment.app.FragmentActivity;
 import androidx.loader.app.LoaderManager;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.SettingsActivity;
 import com.android.settings.fuelgauge.batteryusage.BatteryEntry;
 import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowActivityManager;
 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
 import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.applications.AppUtils;
@@ -65,15 +65,16 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.mockito.stubbing.Answer;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
@@ -83,10 +84,13 @@
 @Config(
         shadows = {
             ShadowEntityHeaderController.class,
-            ShadowActivityManager.class,
             com.android.settings.testutils.shadow.ShadowFragment.class,
         })
 public class PowerBackgroundUsageDetailTest {
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
     private static final String APP_LABEL = "app label";
     private static final String SUMMARY = "summary";
     private static final int ICON_ID = 123;
@@ -123,9 +127,7 @@
 
     @Before
     public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mContext = spy(RuntimeEnvironment.application);
+        mContext = spy(ApplicationProvider.getApplicationContext());
         when(mContext.getPackageName()).thenReturn("foo");
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
         when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo);
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
index 27a85fd..6cd4f16 100644
--- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -45,29 +45,30 @@
 import android.widget.FrameLayout;
 
 import androidx.fragment.app.Fragment;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
 import com.android.settings.testutils.shadow.ShadowActivityEmbeddingUtils;
-import com.android.settings.testutils.shadow.ShadowActivityManager;
 import com.android.settings.testutils.shadow.ShadowPasswordUtils;
 import com.android.settings.testutils.shadow.ShadowUserManager;
 import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
 
 import org.junit.After;
-import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.android.controller.ActivityController;
 import org.robolectric.annotation.Config;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowActivityManager;
 import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
@@ -77,11 +78,8 @@
         ShadowActivityManager.class,
 })
 public class SettingsHomepageActivityTest {
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-    }
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
     @After
     public void tearDown() {
@@ -120,7 +118,8 @@
     @Config(qualifiers = "mcc999")
     public void launch_LowRamDevice_shouldHideAvatar() {
         final ShadowActivityManager activityManager = Shadow.extract(
-                RuntimeEnvironment.application.getSystemService(ActivityManager.class));
+                ApplicationProvider.getApplicationContext().getSystemService(
+                        ActivityManager.class));
         activityManager.setIsLowRamDevice(true);
 
         final SettingsHomepageActivity activity = Robolectric.buildActivity(
diff --git a/tests/robotests/src/com/android/settings/notification/BubbleNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BubbleNotificationPreferenceControllerTest.java
index b275976..ea0b2a0 100644
--- a/tests/robotests/src/com/android/settings/notification/BubbleNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BubbleNotificationPreferenceControllerTest.java
@@ -34,21 +34,23 @@
 import android.widget.Switch;
 
 import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
 
-import com.android.settings.testutils.shadow.ShadowActivityManager;
 import com.android.settingslib.testutils.shadow.ShadowInteractionJankMonitor;
 import com.android.settingslib.widget.MainSwitchPreference;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowActivityManager;
 
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {
@@ -56,7 +58,10 @@
         ShadowActivityManager.class,
 })
 public class BubbleNotificationPreferenceControllerTest {
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
+    private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles";
     private Context mContext;
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private PreferenceScreen mScreen;
@@ -67,33 +72,29 @@
     private BubbleNotificationPreferenceController mController;
     private MainSwitchPreference mPreference;
 
-    private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles";
+    private ShadowActivityManager mActivityManager;
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
         mController = new BubbleNotificationPreferenceController(mContext,
                 KEY_NOTIFICATION_BUBBLES);
-        mPreference = new MainSwitchPreference(RuntimeEnvironment.application);
+        mPreference = new MainSwitchPreference(mContext);
         mPreference.setKey(mController.getPreferenceKey());
         when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
         mController.displayPreference(mScreen);
+        mActivityManager = Shadow.extract(mContext.getSystemService(ActivityManager.class));
     }
 
     @Test
     public void isAvailable_lowRam_returnsUnsupported() {
-        final ShadowActivityManager activityManager =
-                Shadow.extract(mContext.getSystemService(ActivityManager.class));
-        activityManager.setIsLowRamDevice(true);
+        mActivityManager.setIsLowRamDevice(true);
         assertEquals(UNSUPPORTED_ON_DEVICE, mController.getAvailabilityStatus());
     }
 
     @Test
     public void isAvailable_notLowRam_returnsAvailable() {
-        final ShadowActivityManager activityManager =
-                Shadow.extract(mContext.getSystemService(ActivityManager.class));
-        activityManager.setIsLowRamDevice(false);
+        mActivityManager.setIsLowRamDevice(false);
         assertEquals(AVAILABLE, mController.getAvailabilityStatus());
     }
 
diff --git a/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java
index e80fbc8..a201fdb 100644
--- a/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java
@@ -30,17 +30,17 @@
 import android.provider.Settings;
 
 import androidx.preference.Preference;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
-import com.android.settings.testutils.shadow.ShadowActivityManager;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowActivityManager;
 
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {
@@ -48,19 +48,23 @@
 })
 public class BubbleSummaryNotificationPreferenceControllerTest {
 
+    private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles";
     private Context mContext;
 
     private BubbleSummaryNotificationPreferenceController mController;
     private Preference mPreference;
 
-    private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles";
+    private ShadowActivityManager mActivityManager;
+
 
     @Before
     public void setUp() {
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
         mController = new BubbleSummaryNotificationPreferenceController(mContext,
                 KEY_NOTIFICATION_BUBBLES);
-        mPreference = new Preference(RuntimeEnvironment.application);
+        mPreference = new Preference(mContext);
+        mActivityManager =
+                Shadow.extract(mContext.getSystemService(ActivityManager.class));
     }
 
     @Test
@@ -80,17 +84,13 @@
 
     @Test
     public void isAvailable_lowRam_returnsUnsupported() {
-        final ShadowActivityManager activityManager =
-                Shadow.extract(mContext.getSystemService(ActivityManager.class));
-        activityManager.setIsLowRamDevice(true);
+        mActivityManager.setIsLowRamDevice(true);
         assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
     }
 
     @Test
     public void isAvailable_notLowRam_returnsAvailable() {
-        final ShadowActivityManager activityManager =
-                Shadow.extract(mContext.getSystemService(ActivityManager.class));
-        activityManager.setIsLowRamDevice(false);
+        mActivityManager.setIsLowRamDevice(false);
         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java
index 487ba76..893695c 100644
--- a/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/BubblePreferenceControllerTest.java
@@ -55,24 +55,26 @@
 import androidx.fragment.app.FragmentTransaction;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.notification.NotificationBackend;
-import com.android.settings.testutils.shadow.ShadowActivityManager;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedSwitchPreference;
 
 import com.google.common.collect.ImmutableList;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowActivityManager;
 import org.robolectric.shadows.ShadowApplication;
 
 import java.util.ArrayList;
@@ -83,6 +85,8 @@
         ShadowActivityManager.class,
 })
 public class BubblePreferenceControllerTest {
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
     private Context mContext;
     @Mock
@@ -103,11 +107,10 @@
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
         ShadowApplication shadowApplication = ShadowApplication.getInstance();
         shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
         shadowApplication.setSystemService(Context.USER_SERVICE, mUm);
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
         when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
         mController = spy(new BubblePreferenceController(mContext, mFragmentManager, mBackend,
                 false /* isAppPage */, mListener));
diff --git a/tests/robotests/src/com/android/settings/notification/app/BubbleSummaryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/BubbleSummaryPreferenceControllerTest.java
index 7db308e..6fbe40e 100644
--- a/tests/robotests/src/com/android/settings/notification/app/BubbleSummaryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/BubbleSummaryPreferenceControllerTest.java
@@ -43,27 +43,30 @@
 import android.provider.Settings;
 
 import androidx.preference.Preference;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.R;
 import com.android.settings.notification.NotificationBackend;
-import com.android.settings.testutils.shadow.ShadowActivityManager;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowActivityManager;
 
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {
         ShadowActivityManager.class,
 })
 public class BubbleSummaryPreferenceControllerTest {
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
     private Context mContext;
     @Mock
@@ -72,16 +75,17 @@
 
     private BubbleSummaryPreferenceController mController;
 
+    private ShadowActivityManager mActivityManager;
+
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        ShadowApplication shadowApplication = ShadowApplication.getInstance();
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
         when(mBackend.hasSentValidBubble(anyString(), anyInt())).thenReturn(true);
         mAppRow = new NotificationBackend.AppRow();
         mAppRow.pkg = "pkg";
         mAppRow.uid = 0;
         mController = spy(new BubbleSummaryPreferenceController(mContext, mBackend));
+        mActivityManager = Shadow.extract(mContext.getSystemService(ActivityManager.class));
     }
 
     @Test
@@ -151,9 +155,7 @@
         Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
         mController.onResume(mAppRow, null, null, null, null, null, null);
 
-        final ShadowActivityManager activityManager =
-                Shadow.extract(mContext.getSystemService(ActivityManager.class));
-        activityManager.setIsLowRamDevice(true);
+        mActivityManager.setIsLowRamDevice(true);
         assertFalse(mController.isAvailable());
     }
 
@@ -162,9 +164,7 @@
         Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, SYSTEM_WIDE_ON);
         mController.onResume(mAppRow, null, null, null, null, null, null);
 
-        final ShadowActivityManager activityManager =
-               Shadow.extract(mContext.getSystemService(ActivityManager.class));
-        activityManager.setIsLowRamDevice(false);
+        mActivityManager.setIsLowRamDevice(false);
         assertTrue(mController.isAvailable());
     }
 
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java
index 5d9202f..e259cad 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContentResolver.java
@@ -16,16 +16,10 @@
 
 package com.android.settings.testutils.shadow;
 
-import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS;
-
 import android.accounts.Account;
 import android.annotation.UserIdInt;
 import android.content.ContentResolver;
 import android.content.SyncAdapterType;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.provider.SearchIndexablesContract;
 import android.text.TextUtils;
 
 import org.robolectric.annotation.Implementation;
@@ -35,7 +29,7 @@
 import java.util.Map;
 
 @Implements(ContentResolver.class)
-public class ShadowContentResolver {
+public class ShadowContentResolver extends org.robolectric.shadows.ShadowContentResolver {
 
     private static SyncAdapterType[] sSyncAdapterTypes = new SyncAdapterType[0];
     private static Map<String, Integer> sSyncable = new HashMap<>();
@@ -48,23 +42,14 @@
     }
 
     @Implementation
-    protected final Cursor query(Uri uri, String[] projection, String selection,
-            String[] selectionArgs, String sortOrder) {
-        MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS);
-        MatrixCursor.RowBuilder builder = cursor.newRow()
-                .add(SearchIndexablesContract.NonIndexableKey.COLUMN_KEY_VALUE, "");
-        return cursor;
-    }
-
-    @Implementation
     protected static int getIsSyncableAsUser(Account account, String authority, int userId) {
-        return sSyncable.containsKey(authority) ? sSyncable.get(authority) : 1;
+        return sSyncable.getOrDefault(authority, 1);
     }
 
     @Implementation
     protected static boolean getSyncAutomaticallyAsUser(Account account, String authority,
             int userId) {
-        return sSyncAutomatically.containsKey(authority) ? sSyncAutomatically.get(authority) : true;
+        return sSyncAutomatically.getOrDefault(authority, true);
     }
 
     @Implementation
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsInternal.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsInternal.java
index d66aa61..5989d49 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsInternal.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowRestrictedLockUtilsInternal.java
@@ -50,7 +50,7 @@
     }
 
     @Implementation
-    protected static EnforcedAdmin checkIfMeteredDataRestricted(Context context,
+    protected static EnforcedAdmin checkIfMeteredDataUsageUserControlDisabled(Context context,
             String packageName, int userId) {
         if (sIsRestricted) {
             return new EnforcedAdmin();
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppArchiveButtonTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppArchiveButtonTest.kt
index df1f153..6b4cc0d 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppArchiveButtonTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppArchiveButtonTest.kt
@@ -63,8 +63,10 @@
         whenever(packageInfoPresenter.context).thenReturn(context)
         whenever(packageInfoPresenter.userPackageManager).thenReturn(userPackageManager)
         whenever(userPackageManager.packageInstaller).thenReturn(packageInstaller)
+        whenever(userPackageManager.getApplicationLabel(any())).thenReturn(APP_LABEL)
         whenever(packageInfoPresenter.packageName).thenReturn(PACKAGE_NAME)
-        appArchiveButton = AppArchiveButton(packageInfoPresenter, isHibernationSwitchEnabledStateFlow)
+        appArchiveButton =
+            AppArchiveButton(packageInfoPresenter, isHibernationSwitchEnabledStateFlow)
     }
 
     @Test
@@ -150,5 +152,6 @@
 
     private companion object {
         const val PACKAGE_NAME = "package.name"
+        const val APP_LABEL = "App label"
     }
 }
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppButtonsTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppButtonsTest.kt
index 733e1a4..c742bd7 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppButtonsTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppButtonsTest.kt
@@ -45,6 +45,7 @@
 import org.mockito.Mock
 import org.mockito.MockitoSession
 import org.mockito.Spy
+import org.mockito.kotlin.any
 import org.mockito.quality.Strictness
 import org.mockito.Mockito.`when` as whenever
 
@@ -80,6 +81,7 @@
         whenever(packageInfoPresenter.context).thenReturn(context)
         whenever(packageInfoPresenter.packageName).thenReturn(PACKAGE_NAME)
         whenever(packageInfoPresenter.userPackageManager).thenReturn(packageManager)
+        whenever(packageManager.getApplicationLabel(any())).thenReturn(APP_LABEL)
         whenever(packageManager.packageInstaller).thenReturn(packageInstaller)
         whenever(packageManager.getPackageInfo(PACKAGE_NAME, 0)).thenReturn(PACKAGE_INFO)
         whenever(AppUtils.isMainlineModule(packageManager, PACKAGE_NAME)).thenReturn(false)
@@ -113,7 +115,8 @@
         featureFlags.setFlag(Flags.FLAG_ARCHIVING, false)
         setContent()
 
-        composeTestRule.onNodeWithText(context.getString(R.string.launch_instant_app)).assertIsDisplayed()
+        composeTestRule.onNodeWithText(context.getString(R.string.launch_instant_app))
+            .assertIsDisplayed()
     }
 
     @Test
@@ -122,7 +125,8 @@
         featureFlags.setFlag(Flags.FLAG_ARCHIVING, true)
         setContent()
 
-        composeTestRule.onNodeWithText(context.getString(R.string.launch_instant_app)).assertIsNotDisplayed()
+        composeTestRule.onNodeWithText(context.getString(R.string.launch_instant_app))
+            .assertIsNotDisplayed()
     }
 
     @Test
@@ -184,6 +188,7 @@
 
     private companion object {
         const val PACKAGE_NAME = "package.name"
+        const val APP_LABEL = "App label"
         val PACKAGE_INFO = PackageInfo().apply {
             applicationInfo = ApplicationInfo().apply {
                 packageName = PACKAGE_NAME
diff --git a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppForceStopButtonTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppForceStopButtonTest.kt
index c093863..84d6651 100644
--- a/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppForceStopButtonTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/app/appinfo/AppForceStopButtonTest.kt
@@ -17,79 +17,82 @@
 package com.android.settings.spa.app.appinfo
 
 import android.app.admin.DevicePolicyManager
+import android.content.ComponentName
 import android.content.Context
 import android.content.pm.ApplicationInfo
 import android.content.pm.PackageManager
+import android.os.UserHandle
+import android.os.UserManager
+import androidx.compose.material3.Button
+import androidx.compose.material3.Text
+import androidx.compose.ui.test.assertIsEnabled
+import androidx.compose.ui.test.assertIsNotEnabled
 import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.android.settingslib.spa.widget.button.ActionButton
+import com.android.settings.R
+import com.android.settingslib.spa.testutils.delay
 import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
 import com.android.settingslib.spaprivileged.model.app.userId
 import com.google.common.truth.Truth.assertThat
-import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Spy
-import org.mockito.junit.MockitoJUnit
-import org.mockito.junit.MockitoRule
-import org.mockito.Mockito.`when` as whenever
+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
 
 @RunWith(AndroidJUnit4::class)
 class AppForceStopButtonTest {
     @get:Rule
     val composeTestRule = createComposeRule()
 
-    @get:Rule
-    val mockito: MockitoRule = MockitoJUnit.rule()
+    private val mockPackageManager = mock<PackageManager>()
 
-    @Spy
-    private val context: Context = ApplicationProvider.getApplicationContext()
+    private val mockDevicePolicyManager = mock<DevicePolicyManager>()
 
-    @Mock
-    private lateinit var packageInfoPresenter: PackageInfoPresenter
-
-    @Mock
-    private lateinit var packageManager: PackageManager
-
-    @Mock
-    private lateinit var devicePolicyManager: DevicePolicyManager
-
-    private lateinit var appForceStopButton: AppForceStopButton
-
-    @Before
-    fun setUp() {
-        whenever(packageInfoPresenter.context).thenReturn(context)
-        whenever(context.packageManager).thenReturn(packageManager)
-        whenever(context.devicePolicyManager).thenReturn(devicePolicyManager)
-        appForceStopButton = AppForceStopButton(packageInfoPresenter)
+    private val mockUserManager = mock<UserManager> {
+        on { getUserRestrictionSources(any(), any()) } doReturn emptyList()
     }
 
-    @Test
-    fun getActionButton() {
+    private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
+        on { packageManager } doReturn mockPackageManager
+        on { devicePolicyManager } doReturn mockDevicePolicyManager
+        on { getSystemService(Context.DEVICE_POLICY_SERVICE) } doReturn mockDevicePolicyManager
+        on { getSystemService(Context.USER_SERVICE) } doReturn mockUserManager
     }
 
+    private val packageInfoPresenter = mock<PackageInfoPresenter> {
+        on { context } doReturn context
+    }
+
+    private val appForceStopButton = AppForceStopButton(packageInfoPresenter)
+
     @Test
     fun getActionButton_isActiveAdmin_buttonDisabled() {
         val app = createApp()
-        whenever(devicePolicyManager.packageHasActiveAdmins(PACKAGE_NAME, app.userId))
-            .thenReturn(true)
+        mockDevicePolicyManager.stub {
+            on { packageHasActiveAdmins(PACKAGE_NAME, app.userId) } doReturn true
+        }
 
-        val actionButton = setForceStopButton(app)
+        setForceStopButton(app)
 
-        assertThat(actionButton.enabled).isFalse()
+        composeTestRule.onNodeWithText(context.getString(R.string.force_stop)).assertIsNotEnabled()
     }
 
     @Test
     fun getActionButton_isUninstallInQueue_buttonDisabled() {
         val app = createApp()
-        whenever(devicePolicyManager.isUninstallInQueue(PACKAGE_NAME)).thenReturn(true)
+        mockDevicePolicyManager.stub {
+            on { isUninstallInQueue(PACKAGE_NAME) } doReturn true
+        }
 
-        val actionButton = setForceStopButton(app)
+        setForceStopButton(app)
 
-        assertThat(actionButton.enabled).isFalse()
+        composeTestRule.onNodeWithText(context.getString(R.string.force_stop)).assertIsNotEnabled()
     }
 
     @Test
@@ -98,35 +101,79 @@
             flags = ApplicationInfo.FLAG_STOPPED
         }
 
-        val actionButton = setForceStopButton(app)
+        setForceStopButton(app)
 
-        assertThat(actionButton.enabled).isFalse()
+        composeTestRule.onNodeWithText(context.getString(R.string.force_stop)).assertIsNotEnabled()
     }
 
     @Test
     fun getActionButton_regularApp_buttonEnabled() {
         val app = createApp()
 
-        val actionButton = setForceStopButton(app)
+        setForceStopButton(app)
 
-        assertThat(actionButton.enabled).isTrue()
+        composeTestRule.onNodeWithText(context.getString(R.string.force_stop)).assertIsEnabled()
     }
 
-    private fun setForceStopButton(app: ApplicationInfo): ActionButton {
-        lateinit var actionButton: ActionButton
-        composeTestRule.setContent {
-            actionButton = appForceStopButton.getActionButton(app)
+    @Test
+    fun getAdminRestriction_packageNotProtected() {
+        mockPackageManager.stub {
+            on { isPackageStateProtected(PACKAGE_NAME, UserHandle.getUserId(UID)) } doReturn false
         }
-        return actionButton
+
+        val admin = appForceStopButton.getAdminRestriction(createApp())
+
+        assertThat(admin).isNull()
+    }
+
+    @Test
+    fun getAdminRestriction_packageProtectedAndHaveOwner() {
+        mockPackageManager.stub {
+            on { isPackageStateProtected(PACKAGE_NAME, UserHandle.getUserId(UID)) } doReturn true
+        }
+        mockDevicePolicyManager.stub {
+            on { deviceOwnerComponentOnAnyUser } doReturn DEVICE_OWNER
+        }
+
+        val admin = appForceStopButton.getAdminRestriction(createApp())!!
+
+        assertThat(admin.component).isEqualTo(DEVICE_OWNER)
+    }
+
+    @Test
+    fun getAdminRestriction_packageProtectedAndNotHaveOwner() {
+        mockPackageManager.stub {
+            on { isPackageStateProtected(PACKAGE_NAME, UserHandle.getUserId(UID)) } doReturn true
+        }
+        mockDevicePolicyManager.stub {
+            on { deviceOwnerComponentOnAnyUser } doReturn null
+        }
+
+        val admin = appForceStopButton.getAdminRestriction(createApp())!!
+
+        assertThat(admin.component).isNull()
+    }
+
+    private fun setForceStopButton(app: ApplicationInfo) {
+        composeTestRule.setContent {
+            val actionButton = appForceStopButton.getActionButton(app)
+            Button(onClick = {}, enabled = actionButton.enabled) {
+                Text(actionButton.text)
+            }
+        }
+        composeTestRule.delay()
     }
 
     private fun createApp(builder: ApplicationInfo.() -> Unit = {}) =
         ApplicationInfo().apply {
             packageName = PACKAGE_NAME
+            uid = UID
             enabled = true
         }.apply(builder)
 
     private companion object {
         const val PACKAGE_NAME = "package.name"
+        const val UID = 10000
+        val DEVICE_OWNER = ComponentName("device", "Owner")
     }
-}
\ No newline at end of file
+}