Merge "Fix broken RoboTests in "com.android.settings.fuelgauge.*"" into main
diff --git a/aconfig/settings_globalintl_flag_declarations.aconfig b/aconfig/settings_globalintl_flag_declarations.aconfig
index 3740dd3..68662d0 100644
--- a/aconfig/settings_globalintl_flag_declarations.aconfig
+++ b/aconfig/settings_globalintl_flag_declarations.aconfig
@@ -2,14 +2,14 @@
 
 flag {
     name: "terms_of_address_enabled"
-    namespace: "settings_globalintl"
+    namespace: "globalintl"
     description: "Feature flag for Terms of Address"
     bug: "297798866"
 }
 
 flag {
     name: "locale_notification_enabled"
-    namespace: "settings_globalintl"
+    namespace: "globalintl"
     description: "Feature flag for locale notification"
-    bug: "248514263"
+    bug: "301380610"
 }
diff --git a/res/drawable/ic_battery_uninstalled.xml b/res/drawable/ic_battery_uninstalled.xml
new file mode 100644
index 0000000..2d8ea86
--- /dev/null
+++ b/res/drawable/ic_battery_uninstalled.xml
@@ -0,0 +1,33 @@
+<!--
+  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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24.0dp"
+    android:height="24.0dp"
+    android:tint="@color/battery_usage_system_icon_color"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M15,4V3H9v1H4v2h1v13c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V6h1V4H15zM17,19H7V6h10V19z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M9,8h2v9h-2z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M13,8h2v9h-2z" />
+</vector>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1bbecc0..7a467d5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5567,8 +5567,10 @@
     <string name="battery_usage_without_time"></string>
     <!-- Description for the specific time slot in the battery usage page [CHAR LIMIT=120] -->
     <string name="battery_usage_since_last_full_charge">since last full charge</string>
-   <!-- Description for system apps aggregated battery usage data [CHAR LIMIT=120] -->
+    <!-- Description for system apps aggregated battery usage data [CHAR LIMIT=120] -->
     <string name="battery_usage_system_apps">System apps</string>
+    <!-- Description for uninstalled apps aggregated battery usage data [CHAR LIMIT=120] -->
+    <string name="battery_usage_uninstalled_apps">Uninstalled apps</string>
     <!-- Description for others battery usage data [CHAR LIMIT=120] -->
     <string name="battery_usage_others">Others</string>
 
@@ -12493,4 +12495,21 @@
     <string name="quarantined_apps_title" translatable="false">Quarantined Apps</string>
     <!-- Do not translate. Developer settings: Button to unquarantine an app [CHAR LIMIT=20] -->
     <string name="unquarantine_app_button" translatable="false">Unquarantine app</string>
+
+    <!-- Title of preference to manage content protection settings -->
+    <string name="content_protection_preference_title">Scanning for deceptive apps</string>
+    <!-- Summary of the preference to manage content protection settings -->
+    <string name="content_protection_preference_summary">Check app activity for phishing</string>
+    <!-- Title of the switch bar on the subpage of content protection settings -->
+    <string name="content_protection_preference_user_consent_switch_title">Use scanning</string>
+    <!-- Title of the toggle switch of work apps on the subpage of content protection settings -->
+    <string name="content_protection_preference_user_consent_work_profile_switch_title">Use scanning for work apps</string>
+    <!-- Summary of the subpage of content protection settings -->
+    <string name="content_protection_preference_subpage_summary">Scanning runs privately right on your device, checking app activity for phishing or other deceptive behavior. If it\’s detected, some app info is sent to Google Play Protect to confirm the threat and warn app users.</string>
+    <!-- Information at the bottom of the subpage of content protection settings -->
+    <string name="content_protection_preference_subpage_info">
+        <![CDATA[
+        This is a protected security feature. No device or personal info is shared with Google.
+        \n\nPhishing is an attempt to steal sign-in credentials or other personal info.
+        ]]></string>
 </resources>
diff --git a/res/xml/apps.xml b/res/xml/apps.xml
index 85d187c..c4313f6 100644
--- a/res/xml/apps.xml
+++ b/res/xml/apps.xml
@@ -111,9 +111,7 @@
         android:key="advanced_category"
         android:title="@string/advanced_apps"
         android:order="21"
-        android:visibility="gone"
-        settings:searchable="false"
-        settings:controller="com.android.settings.widget.PreferenceCategoryController">
+        settings:searchable="false">
 
         <Preference
             android:key="aspect_ratio_apps"
diff --git a/res/xml/wifi_settings.xml b/res/xml/wifi_settings.xml
deleted file mode 100644
index eadea68..0000000
--- a/res/xml/wifi_settings.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<PreferenceScreen
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:settings="http://schemas.android.com/apk/res-auto"
-        android:title="@string/wifi_settings"
-        settings:keywords="@string/keywords_wifi">
-
-    <com.android.settings.wifi.LinkablePreference
-        android:key="wifi_status_message"/>
-
-    <PreferenceCategory
-        android:key="connected_access_point"
-        android:layout="@layout/preference_category_no_label"/>
-
-    <PreferenceCategory
-        android:key="access_points"
-        android:layout="@layout/preference_category_no_label"/>
-
-    <Preference
-        android:key="configure_wifi_settings"
-        android:title="@string/wifi_configure_settings_preference_title"
-        settings:allowDividerAbove="true"
-        android:fragment="com.android.settings.wifi.ConfigureWifiSettings"/>
-
-    <Preference
-        android:key="saved_networks"
-        android:title="@string/wifi_saved_access_points_label"
-        android:fragment="com.android.settings.wifi.savedaccesspoints2.SavedAccessPointsWifiSettings2"/>
-
-    <com.android.settings.datausage.DataUsagePreference
-        android:key="wifi_data_usage"
-        android:title="@string/wifi_data_usage"/>
-</PreferenceScreen>
diff --git a/src/com/android/settings/applications/AdvancedAppsPreferenceCategoryController.java b/src/com/android/settings/applications/AdvancedAppsPreferenceCategoryController.java
new file mode 100644
index 0000000..6a518fd
--- /dev/null
+++ b/src/com/android/settings/applications/AdvancedAppsPreferenceCategoryController.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+
+import com.android.settings.widget.PreferenceCategoryController;
+
+/**
+ * Preference category controller for Advanced category under Apps page
+ */
+public class AdvancedAppsPreferenceCategoryController extends PreferenceCategoryController {
+
+    public AdvancedAppsPreferenceCategoryController(@NonNull Context context,
+            @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+    }
+}
diff --git a/src/com/android/settings/applications/AppDashboardFragment.java b/src/com/android/settings/applications/AppDashboardFragment.java
index 11f8405..41160d8 100644
--- a/src/com/android/settings/applications/AppDashboardFragment.java
+++ b/src/com/android/settings/applications/AppDashboardFragment.java
@@ -20,9 +20,12 @@
 import android.content.Context;
 import android.provider.SearchIndexableResource;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
+import com.android.settings.applications.appcompat.UserAspectRatioAppsPreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.widget.PreferenceCategoryController;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.SearchIndexable;
 
@@ -35,11 +38,21 @@
 public class AppDashboardFragment extends DashboardFragment {
 
     private static final String TAG = "AppDashboardFragment";
+    private static final String ADVANCED_CATEGORY_KEY = "advanced_category";
+    private static final String ASPECT_RATIO_PREF_KEY = "aspect_ratio_apps";
     private AppsPreferenceController mAppsPreferenceController;
 
     private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
         controllers.add(new AppsPreferenceController(context));
+
+        final UserAspectRatioAppsPreferenceController aspectRatioAppsPreferenceController =
+                new UserAspectRatioAppsPreferenceController(context, ASPECT_RATIO_PREF_KEY);
+        final AdvancedAppsPreferenceCategoryController advancedCategoryController =
+                new AdvancedAppsPreferenceCategoryController(context, ADVANCED_CATEGORY_KEY);
+        advancedCategoryController.setChildren(List.of(aspectRatioAppsPreferenceController));
+        controllers.add(advancedCategoryController);
+
         return controllers;
     }
 
@@ -75,6 +88,11 @@
         getSettingsLifecycle().addObserver(hibernatedAppsPreferenceController);
     }
 
+    @VisibleForTesting
+    PreferenceCategoryController getAdvancedAppsPreferenceCategoryController() {
+        return use(AdvancedAppsPreferenceCategoryController.class);
+    }
+
     @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
         return buildPreferenceControllers(context);
diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
index b08bc61..de06806 100644
--- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
@@ -95,6 +95,9 @@
     private static final String ALTERNATE_INTENT = "android.settings.SYNC_SETTINGS";
     private static final String PRIMARY_INTENT = "android.settings.CREDENTIAL_PROVIDER";
     private static final int MAX_SELECTABLE_PROVIDERS = 5;
+    private static final String SETTINGS_ACTIVITY_INTENT_ACTION = "android.intent.action.MAIN";
+    private static final String SETTINGS_ACTIVITY_INTENT_CATEGORY =
+            "android.intent.category.LAUNCHER";
 
     private final PackageManager mPm;
     private final List<CredentialProviderInfo> mServices;
@@ -481,13 +484,22 @@
                 continue;
             }
 
+            // Get the settings activity.
+            CharSequence settingsActivity =
+                    combinedInfo.getCredentialProviderInfos().get(0).getSettingsActivity();
+
             Drawable icon = combinedInfo.getAppIcon(context, getUser());
             CharSequence title = combinedInfo.getAppName(context);
 
             // Build the pref and add it to the output & group.
             CombiPreference pref =
                     addProviderPreference(
-                            context, title, icon, packageName, combinedInfo.getSettingsSubtitle());
+                            context,
+                            title == null ? "" : title,
+                            icon,
+                            packageName,
+                            combinedInfo.getSettingsSubtitle(),
+                            settingsActivity);
             output.put(packageName, pref);
             group.addPreference(pref);
         }
@@ -507,7 +519,8 @@
                 label == null ? "" : label,
                 service.getServiceIcon(mContext),
                 service.getServiceInfo().packageName,
-                service.getSettingsSubtitle());
+                service.getSettingsSubtitle(),
+                service.getSettingsActivity());
     }
 
     /**
@@ -566,7 +579,8 @@
             @NonNull CharSequence title,
             @Nullable Drawable icon,
             @NonNull String packageName,
-            @Nullable CharSequence subtitle) {
+            @Nullable CharSequence subtitle,
+            @Nullable CharSequence settingsActivity) {
         final CombiPreference pref =
                 new CombiPreference(prefContext, mEnabledPackageNames.contains(packageName));
         pref.setTitle(title);
@@ -582,29 +596,73 @@
         }
 
         pref.setPreferenceListener(
-                (p, isChecked) -> {
-                    if (isChecked) {
-                        if (mEnabledPackageNames.size() >= MAX_SELECTABLE_PROVIDERS) {
-                            // Show the error if too many enabled.
-                            pref.setChecked(false);
-                            final DialogFragment fragment = newErrorDialogFragment();
+                new CombiPreference.OnCombiPreferenceClickListener() {
+                    @Override
+                    public void onCheckChanged(CombiPreference p, boolean isChecked) {
+                        if (isChecked) {
+                            if (mEnabledPackageNames.size() >= MAX_SELECTABLE_PROVIDERS) {
+                                // Show the error if too many enabled.
+                                pref.setChecked(false);
+                                final DialogFragment fragment = newErrorDialogFragment();
 
-                            if (fragment == null || mFragmentManager == null) {
+                                if (fragment == null || mFragmentManager == null) {
+                                    return;
+                                }
+
+                                fragment.show(mFragmentManager, ErrorDialogFragment.TAG);
                                 return;
                             }
 
-                            fragment.show(mFragmentManager, ErrorDialogFragment.TAG);
+                            togglePackageNameEnabled(packageName);
+
+                            // Enable all prefs.
+                            if (mPrefs.containsKey(packageName)) {
+                                mPrefs.get(packageName).setChecked(true);
+                            }
+                        } else {
+                            togglePackageNameDisabled(packageName);
+                        }
+                    }
+
+                    @Override
+                    public void onLeftSideClicked() {
+                        if (settingsActivity == null) {
+                            Log.w(TAG, "settingsActivity was null");
                             return;
                         }
 
-                        togglePackageNameEnabled(packageName);
-
-                        // Enable all prefs.
-                        if (mPrefs.containsKey(packageName)) {
-                            mPrefs.get(packageName).setChecked(true);
+                        String settingsActivityStr = String.valueOf(settingsActivity);
+                        ComponentName cn = ComponentName.unflattenFromString(settingsActivityStr);
+                        if (cn == null) {
+                            Log.w(
+                                    TAG,
+                                    "Failed to deserialize settingsActivity attribute, we got: "
+                                            + settingsActivityStr);
+                            return;
                         }
-                    } else {
-                        togglePackageNameDisabled(packageName);
+
+                        Intent intent = new Intent(SETTINGS_ACTIVITY_INTENT_ACTION);
+                        intent.addCategory(SETTINGS_ACTIVITY_INTENT_CATEGORY);
+                        intent.setComponent(cn);
+
+                        Context context = mContext;
+                        int currentUserId = getUser();
+                        int contextUserId = context.getUser().getIdentifier();
+
+                        if (currentUserId != contextUserId) {
+                            Log.d(
+                                    TAG,
+                                    "onLeftSideClicked(): using context for current user ("
+                                            + currentUserId
+                                            + ") instead of user "
+                                            + contextUserId
+                                            + " on headless system user mode");
+                            context =
+                                    context.createContextAsUser(
+                                            UserHandle.of(currentUserId), /* flags= */ 0);
+                        }
+
+                        context.startActivity(intent);
                     }
                 });
 
@@ -920,6 +978,9 @@
         public interface OnCombiPreferenceClickListener {
             /** Called when the check is updated */
             void onCheckChanged(CombiPreference p, boolean isChecked);
+
+            /** Called when the left side is clicked. */
+            void onLeftSideClicked();
         }
 
         public CombiPreference(Context context, boolean initialValue) {
@@ -968,6 +1029,18 @@
                 // Store this for later.
                 mSwitch = switchView;
             }
+
+            super.setOnPreferenceClickListener(
+                    new Preference.OnPreferenceClickListener() {
+                        @Override
+                        public boolean onPreferenceClick(Preference preference) {
+                            if (mOnClickListener != null) {
+                                mOnClickListener.onLeftSideClicked();
+                            }
+
+                            return true;
+                        }
+                    });
         }
     }
 }
diff --git a/src/com/android/settings/backup/SettingsBackupHelper.java b/src/com/android/settings/backup/SettingsBackupHelper.java
index a682df8..ad7e314 100644
--- a/src/com/android/settings/backup/SettingsBackupHelper.java
+++ b/src/com/android/settings/backup/SettingsBackupHelper.java
@@ -16,10 +16,13 @@
 
 package com.android.settings.backup;
 
+import static com.android.settings.localepicker.LocaleNotificationDataManager.LOCALE_NOTIFICATION;
+
 import android.app.backup.BackupAgentHelper;
 import android.app.backup.BackupDataInputStream;
 import android.app.backup.BackupDataOutput;
 import android.app.backup.BackupHelper;
+import android.app.backup.SharedPreferencesBackupHelper;
 import android.os.ParcelFileDescriptor;
 
 import com.android.settings.fuelgauge.BatteryBackupHelper;
@@ -33,12 +36,15 @@
  * Backup agent for Settings APK
  */
 public class SettingsBackupHelper extends BackupAgentHelper {
+    private static final String PREF_LOCALE_NOTIFICATION = "localeNotificationSharedPref";
 
     @Override
     public void onCreate() {
         super.onCreate();
         addHelper("no-op", new NoOpHelper());
         addHelper(BatteryBackupHelper.TAG, new BatteryBackupHelper(this));
+        addHelper(PREF_LOCALE_NOTIFICATION,
+                new SharedPreferencesBackupHelper(this, LOCALE_NOTIFICATION));
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsPairOtherController.java b/src/com/android/settings/bluetooth/BluetoothDetailsPairOtherController.java
index 562a469..d1d00d8 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsPairOtherController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsPairOtherController.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.bluetooth;
 
+import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 
 import androidx.preference.PreferenceFragmentCompat;
@@ -75,7 +76,6 @@
     protected void refresh() {
         updateButtonPreferenceTitle(mPreference);
         setPreferencesVisibility(getButtonPreferenceVisibility(mCachedDevice));
-
     }
 
     private void updateButtonPreferenceTitle(ButtonPreference preference) {
@@ -97,7 +97,7 @@
         if (!cachedDevice.isConnectedHearingAidDevice()) {
             return false;
         }
-        return isBinauralMode(cachedDevice) && !isOtherSideConnected(cachedDevice);
+        return isBinauralMode(cachedDevice) && !isOtherSideBonded(cachedDevice);
     }
 
     private void launchPairingDetail() {
@@ -112,25 +112,16 @@
         return cachedDevice.getDeviceMode() == HearingAidInfo.DeviceMode.MODE_BINAURAL;
     }
 
-    private boolean isOtherSideConnected(CachedBluetoothDevice cachedDevice) {
-        // Check sub device for ASHA hearing aid
-        if (cachedDevice.isConnectedAshaHearingAidDevice()) {
-            final CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
-            if (subDevice != null && subDevice.isConnectedAshaHearingAidDevice()) {
-                return true;
-            }
-        }
+    private boolean isOtherSideBonded(CachedBluetoothDevice cachedDevice) {
+        final CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
+        final boolean subDeviceBonded =
+                subDevice != null && subDevice.getBondState() == BluetoothDevice.BOND_BONDED;
 
-        // Check member device for LE audio hearing aid
-        if (cachedDevice.isConnectedLeAudioHearingAidDevice()) {
-            final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
-            for (CachedBluetoothDevice memberDevice : memberDevices) {
-                if (memberDevice.isConnectedLeAudioHearingAidDevice()) {
-                    return true;
-                }
-            }
-        }
+        final Set<CachedBluetoothDevice> memberDevice = cachedDevice.getMemberDevice();
+        final boolean allMemberDevicesBonded =
+                !memberDevice.isEmpty() && memberDevice.stream().allMatch(
+                        device -> device.getBondState() == BluetoothDevice.BOND_BONDED);
 
-        return false;
+        return subDeviceBonded || allMemberDevicesBonded;
     }
 }
diff --git a/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverController.java b/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverController.java
index 95cf64c..992136c 100644
--- a/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverController.java
+++ b/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverController.java
@@ -170,9 +170,10 @@
             ((SwitchPreference) mPreference).setChecked(false);
         }
 
-        // Regardless of whether ANGLE is enabled, disable the developer option UI
-        // as long as UI is not enabled via debug property.
-        if (!isAngleDeveloperOptionEnabled()) {
+        // Disable the developer option toggle UI if ANGLE is disabled, this means next time the
+        // debug property needs to be set to true again to enable ANGLE. If ANGLE is enabled, don't
+        // disable the developer option toggle UI so that it can be turned off easily.
+        if (!isAngleDeveloperOptionEnabled() && !((SwitchPreference) mPreference).isChecked()) {
             mPreference.setEnabled(false);
         }
     }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java
index f25e16f..eebf1f5 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffData.java
@@ -131,14 +131,14 @@
             final PowerUsageFeatureProvider featureProvider,
             final @NonNull Set<String> systemAppsPackageNames,
             final @NonNull Set<Integer> systemAppsUids) {
+        combineIntoUninstalledApps(context, mAppEntries);
         combineIntoSystemApps(
                 context, featureProvider, systemAppsPackageNames, systemAppsUids, mAppEntries);
         combineSystemItemsIntoOthers(context, featureProvider, mSystemEntries);
     }
 
     private static void purgeBatteryDiffData(
-            final PowerUsageFeatureProvider featureProvider,
-            final List<BatteryDiffEntry> entries) {
+            final PowerUsageFeatureProvider featureProvider, final List<BatteryDiffEntry> entries) {
         final double screenOnTimeThresholdInMs =
                 featureProvider.getBatteryUsageListScreenOnTimeThresholdInMs();
         final double consumePowerThreshold =
@@ -155,7 +155,7 @@
             final String packageName = entry.getPackageName();
             final Integer componentId = entry.mComponentId;
             if ((screenOnTimeInMs < screenOnTimeThresholdInMs
-                    && comsumePower < consumePowerThreshold)
+                            && comsumePower < consumePowerThreshold)
                     || ConvertUtils.FAKE_PACKAGE_NAME.equals(packageName)
                     || hideSystemComponentSet.contains(componentId)
                     || (packageName != null && hideApplicationSet.contains(packageName))) {
@@ -178,18 +178,23 @@
         final Iterator<BatteryDiffEntry> appListIterator = appEntries.iterator();
         while (appListIterator.hasNext()) {
             final BatteryDiffEntry batteryDiffEntry = appListIterator.next();
-            if (needsCombineInSystemApp(batteryDiffEntry, systemAppsAllowlist,
-                    systemAppsPackageNames, systemAppsUids)) {
+            if (needsCombineInSystemApp(
+                    batteryDiffEntry,
+                    systemAppsAllowlist,
+                    systemAppsPackageNames,
+                    systemAppsUids)) {
                 if (systemAppsDiffEntry == null) {
-                    systemAppsDiffEntry = new BatteryDiffEntry(context,
-                            BatteryDiffEntry.SYSTEM_APPS_KEY, BatteryDiffEntry.SYSTEM_APPS_KEY,
-                            ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+                    systemAppsDiffEntry =
+                            new BatteryDiffEntry(
+                                    context,
+                                    BatteryDiffEntry.SYSTEM_APPS_KEY,
+                                    BatteryDiffEntry.SYSTEM_APPS_KEY,
+                                    ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
                 }
                 systemAppsDiffEntry.mConsumePower += batteryDiffEntry.mConsumePower;
                 systemAppsDiffEntry.mForegroundUsageTimeInMs +=
                         batteryDiffEntry.mForegroundUsageTimeInMs;
-                systemAppsDiffEntry.setTotalConsumePower(
-                        batteryDiffEntry.getTotalConsumePower());
+                systemAppsDiffEntry.setTotalConsumePower(batteryDiffEntry.getTotalConsumePower());
                 appListIterator.remove();
             }
         }
@@ -198,6 +203,35 @@
         }
     }
 
+    private static void combineIntoUninstalledApps(
+            final Context context, final @NonNull List<BatteryDiffEntry> appEntries) {
+        BatteryDiffEntry uninstalledAppDiffEntry = null;
+        final Iterator<BatteryDiffEntry> appListIterator = appEntries.iterator();
+        while (appListIterator.hasNext()) {
+            final BatteryDiffEntry batteryDiffEntry = appListIterator.next();
+            if (!batteryDiffEntry.isUninstalledEntry()) {
+                continue;
+            }
+
+            if (uninstalledAppDiffEntry == null) {
+                uninstalledAppDiffEntry =
+                        new BatteryDiffEntry(
+                                context,
+                                BatteryDiffEntry.UNINSTALLED_APPS_KEY,
+                                BatteryDiffEntry.UNINSTALLED_APPS_KEY,
+                                ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+            }
+            uninstalledAppDiffEntry.mConsumePower += batteryDiffEntry.mConsumePower;
+            uninstalledAppDiffEntry.mForegroundUsageTimeInMs +=
+                    batteryDiffEntry.mForegroundUsageTimeInMs;
+            uninstalledAppDiffEntry.setTotalConsumePower(batteryDiffEntry.getTotalConsumePower());
+            appListIterator.remove();
+        }
+        if (uninstalledAppDiffEntry != null) {
+            appEntries.add(uninstalledAppDiffEntry);
+        }
+    }
+
     private static void combineSystemItemsIntoOthers(
             final Context context,
             final PowerUsageFeatureProvider featureProvider,
@@ -210,17 +244,20 @@
         while (systemListIterator.hasNext()) {
             final BatteryDiffEntry batteryDiffEntry = systemListIterator.next();
             final int componentId = batteryDiffEntry.mComponentId;
-            if (othersSystemComponentSet.contains(componentId) || (
-                    componentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+            if (othersSystemComponentSet.contains(componentId)
+                    || (componentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
                             && othersCustomComponentNameSet.contains(
                                     batteryDiffEntry.getAppLabel()))) {
                 if (othersDiffEntry == null) {
-                    othersDiffEntry = new BatteryDiffEntry(context, BatteryDiffEntry.OTHERS_KEY,
-                            BatteryDiffEntry.OTHERS_KEY, ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
+                    othersDiffEntry =
+                            new BatteryDiffEntry(
+                                    context,
+                                    BatteryDiffEntry.OTHERS_KEY,
+                                    BatteryDiffEntry.OTHERS_KEY,
+                                    ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
                 }
                 othersDiffEntry.mConsumePower += batteryDiffEntry.mConsumePower;
-                othersDiffEntry.setTotalConsumePower(
-                        batteryDiffEntry.getTotalConsumePower());
+                othersDiffEntry.setTotalConsumePower(batteryDiffEntry.getTotalConsumePower());
                 systemListIterator.remove();
             }
         }
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntry.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntry.java
index b284ea5..971ada9 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntry.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntry.java
@@ -22,6 +22,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
 
@@ -43,22 +44,33 @@
     static Locale sCurrentLocale = null;
     // Caches app label and icon to improve loading performance.
     static final Map<String, BatteryEntry.NameAndIcon> sResourceCache = new HashMap<>();
+
     // Whether a specific item is valid to launch restriction page?
     @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
     static final Map<String, Boolean> sValidForRestriction = new HashMap<>();
+
     /** A comparator for {@link BatteryDiffEntry} based on the sorting key. */
     static final Comparator<BatteryDiffEntry> COMPARATOR =
             (a, b) -> Double.compare(b.getSortingKey(), a.getSortingKey());
+
     static final String SYSTEM_APPS_KEY = "A|SystemApps";
+    static final String UNINSTALLED_APPS_KEY = "A|UninstalledApps";
     static final String OTHERS_KEY = "S|Others";
 
     // key -> (label_id, icon_id)
-    private static final Map<String, Pair<Integer, Integer>> SPECIAL_ENTRY_MAP = Map.of(
-            SYSTEM_APPS_KEY,
-            Pair.create(R.string.battery_usage_system_apps, R.drawable.ic_power_system),
-            OTHERS_KEY,
-            Pair.create(R.string.battery_usage_others,
-                    R.drawable.ic_settings_battery_usage_others));
+    private static final Map<String, Pair<Integer, Integer>> SPECIAL_ENTRY_MAP =
+            Map.of(
+                    SYSTEM_APPS_KEY,
+                    Pair.create(
+                            R.string.battery_usage_system_apps, R.drawable.ic_power_system),
+                    UNINSTALLED_APPS_KEY,
+                    Pair.create(
+                            R.string.battery_usage_uninstalled_apps,
+                            R.drawable.ic_battery_uninstalled),
+                    OTHERS_KEY,
+                    Pair.create(
+                            R.string.battery_usage_others,
+                            R.drawable.ic_settings_battery_usage_others));
 
     public long mUid;
     public long mUserId;
@@ -146,8 +158,7 @@
     /** Sets the total consumed power in a specific time slot. */
     public void setTotalConsumePower(double totalConsumePower) {
         mTotalConsumePower = totalConsumePower;
-        mPercentage = totalConsumePower == 0
-                ? 0 : (mConsumePower / mTotalConsumePower) * 100.0;
+        mPercentage = totalConsumePower == 0 ? 0 : (mConsumePower / mTotalConsumePower) * 100.0;
         mAdjustPercentageOffset = 0;
     }
 
@@ -173,8 +184,21 @@
 
     /** Gets the key for sorting */
     public double getSortingKey() {
-        return getKey() != null && SPECIAL_ENTRY_MAP.containsKey(getKey())
-                ? -1 : getPercentage() + getAdjustPercentageOffset();
+        String key = getKey();
+        if (key == null) {
+            return getPercentage() + getAdjustPercentageOffset();
+        }
+
+        // For special entries, put them to the end of the list.
+        switch (key) {
+            case UNINSTALLED_APPS_KEY:
+            case OTHERS_KEY:
+                return -1;
+            case SYSTEM_APPS_KEY:
+                return -2;
+            default:
+                return getPercentage() + getAdjustPercentageOffset();
+        }
     }
 
     /** Clones a new instance. */
@@ -222,8 +246,8 @@
 
     /** Gets the searching package name for UID battery type. */
     public String getPackageName() {
-        final String packageName = mDefaultPackageName != null
-                ? mDefaultPackageName : mLegacyPackageName;
+        final String packageName =
+                mDefaultPackageName != null ? mDefaultPackageName : mLegacyPackageName;
         if (packageName == null) {
             return packageName;
         }
@@ -231,7 +255,8 @@
         // From "com.opera.browser:privileged_process0" to "com.opera.browser"
         final String[] splitPackageNames = packageName.split(":");
         return splitPackageNames != null && splitPackageNames.length > 0
-                ? splitPackageNames[0] : packageName;
+                ? splitPackageNames[0]
+                : packageName;
     }
 
     /** Whether this item is valid for users to launch restriction page? */
@@ -255,6 +280,17 @@
         }
     }
 
+    /** Whether the current BatteryDiffEntry is uninstalled app or not. */
+    public boolean isUninstalledEntry() {
+        final String packageName = getPackageName();
+        if (TextUtils.isEmpty(packageName) || isSystemEntry()) {
+            return false;
+        }
+
+        final int uid = BatteryUtils.getInstance(mContext).getPackageUid(packageName);
+        return uid == BatteryUtils.UID_REMOVED_APPS || uid == BatteryUtils.UID_NULL;
+    }
+
     void loadLabelAndIcon() {
         if (mIsLoaded) {
             return;
@@ -286,8 +322,7 @@
             mAppIconId = pair.second;
             mAppIcon = mContext.getDrawable(mAppIconId);
             sResourceCache.put(
-                    getKey(),
-                    new BatteryEntry.NameAndIcon(mAppLabel, mAppIcon, mAppIconId));
+                    getKey(), new BatteryEntry.NameAndIcon(mAppLabel, mAppIcon, mAppIconId));
             return;
         }
 
@@ -301,7 +336,7 @@
                     mAppLabel = nameAndIconForUser.mName;
                     sResourceCache.put(
                             getKey(),
-                            new BatteryEntry.NameAndIcon(mAppLabel, mAppIcon, /*iconId=*/ 0));
+                            new BatteryEntry.NameAndIcon(mAppLabel, mAppIcon, /* iconId= */ 0));
                 }
                 break;
             case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY:
@@ -329,7 +364,7 @@
                 if (mAppLabel != null || mAppIcon != null) {
                     sResourceCache.put(
                             getKey(),
-                            new BatteryEntry.NameAndIcon(mAppLabel, mAppIcon, /*iconId=*/ 0));
+                            new BatteryEntry.NameAndIcon(mAppLabel, mAppIcon, /* iconId= */ 0));
                 }
                 break;
         }
@@ -354,16 +389,20 @@
         }
         try {
             mValidForRestriction =
-                    mContext.getPackageManager().getPackageInfo(
-                            getPackageName(),
-                            PackageManager.MATCH_DISABLED_COMPONENTS
-                                    | PackageManager.MATCH_ANY_USER
-                                    | PackageManager.GET_SIGNATURES
-                                    | PackageManager.GET_PERMISSIONS)
+                    mContext.getPackageManager()
+                                    .getPackageInfo(
+                                            getPackageName(),
+                                            PackageManager.MATCH_DISABLED_COMPONENTS
+                                                    | PackageManager.MATCH_ANY_USER
+                                                    | PackageManager.GET_SIGNATURES
+                                                    | PackageManager.GET_PERMISSIONS)
                             != null;
         } catch (Exception e) {
-            Log.e(TAG, String.format("getPackageInfo() error %s for package=%s",
-                    e.getCause(), getPackageName()));
+            Log.e(
+                    TAG,
+                    String.format(
+                            "getPackageInfo() error %s for package=%s",
+                            e.getCause(), getPackageName()));
             mValidForRestriction = false;
         }
     }
@@ -371,8 +410,11 @@
     private BatteryEntry.NameAndIcon getCache() {
         final Locale locale = Locale.getDefault();
         if (sCurrentLocale != locale) {
-            Log.d(TAG, String.format("clearCache() locale is changed from %s to %s",
-                    sCurrentLocale, locale));
+            Log.d(
+                    TAG,
+                    String.format(
+                            "clearCache() locale is changed from %s to %s",
+                            sCurrentLocale, locale));
             sCurrentLocale = locale;
             clearCache();
         }
@@ -421,8 +463,11 @@
             mDefaultPackageName = nameAndIcon.mPackageName;
             if (mDefaultPackageName != null
                     && !mDefaultPackageName.equals(nameAndIcon.mPackageName)) {
-                Log.w(TAG, String.format("found different package: %s | %s",
-                        mDefaultPackageName, nameAndIcon.mPackageName));
+                Log.w(
+                        TAG,
+                        String.format(
+                                "found different package: %s | %s",
+                                mDefaultPackageName, nameAndIcon.mPackageName));
             }
         }
     }
@@ -459,7 +504,8 @@
 
     private Drawable getBadgeIconForUser(Drawable icon) {
         final int userId = UserHandle.getUserId((int) mUid);
-        return userId == UserHandle.USER_OWNER ? icon :
-                mUserManager.getBadgedIconForUser(icon, new UserHandle(userId));
+        return userId == UserHandle.USER_OWNER
+                ? icon
+                : mUserManager.getBadgedIconForUser(icon, new UserHandle(userId));
     }
 }
diff --git a/src/com/android/settings/localepicker/LocaleNotificationDataManager.java b/src/com/android/settings/localepicker/LocaleNotificationDataManager.java
index 09d6280..4d948f1 100644
--- a/src/com/android/settings/localepicker/LocaleNotificationDataManager.java
+++ b/src/com/android/settings/localepicker/LocaleNotificationDataManager.java
@@ -31,7 +31,7 @@
  * information.
  */
 public class LocaleNotificationDataManager {
-    private static final String LOCALE_NOTIFICATION = "locale_notification";
+    public static final String LOCALE_NOTIFICATION = "locale_notification";
     private Context mContext;
 
     /**
diff --git a/src/com/android/settings/tts/TtsEnginePreferenceFragment.java b/src/com/android/settings/tts/TtsEnginePreferenceFragment.java
index 33648fe..f6416db 100644
--- a/src/com/android/settings/tts/TtsEnginePreferenceFragment.java
+++ b/src/com/android/settings/tts/TtsEnginePreferenceFragment.java
@@ -165,16 +165,16 @@
     private void updateDefaultEngine(String engine) {
         Log.d(TAG, "Updating default synth to : " + engine);
 
-        // Keep track of the previous engine that was being used. So that
-        // we can reuse the previous engine.
-        //
-        // Note that if TextToSpeech#getCurrentEngine is not null, it means at
-        // the very least that we successfully bound to the engine service.
-        mPreviousEngine = mTts.getCurrentEngine();
-
         // Step 1: Shut down the existing TTS engine.
         Log.i(TAG, "Shutting down current tts engine");
         if (mTts != null) {
+            // Keep track of the previous engine that was being used. So that
+            // we can reuse the previous engine.
+            //
+            // Note that if TextToSpeech#getCurrentEngine is not null, it means at
+            // the very least that we successfully bound to the engine service.
+            mPreviousEngine = mTts.getCurrentEngine();
+
             try {
                 mTts.shutdown();
                 mTts = null;
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index b2b7346..d2beec8 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -653,6 +653,9 @@
             case AccessPoint.SECURITY_EAP:
             case AccessPoint.SECURITY_EAP_WPA3_ENTERPRISE:
             case AccessPoint.SECURITY_EAP_SUITE_B:
+                if (mEapMethodSpinner == null || mPhase2Spinner == null) {
+                    break;
+                }
                 if (mAccessPointSecurity == AccessPoint.SECURITY_EAP_SUITE_B) {
                     // allowedSuiteBCiphers will be set according to certificate type
                     config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
diff --git a/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2.java
index 76fed9b..8c78e80 100644
--- a/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2.java
+++ b/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2.java
@@ -72,6 +72,10 @@
     @Override
     public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) {
         final int privacy = Integer.parseInt((String) newValue);
+        if (mWifiEntry.getPrivacy() == privacy) {
+            // Prevent disconnection + reconnection if settings not changed.
+            return true;
+        }
         mWifiEntry.setPrivacy(privacy);
 
         // To activate changing, we need to reconnect network. WiFi will auto connect to
diff --git a/tests/robotests/src/com/android/settings/applications/AppDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/AppDashboardFragmentTest.java
index 0eca43c..5137516 100644
--- a/tests/robotests/src/com/android/settings/applications/AppDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/AppDashboardFragmentTest.java
@@ -16,12 +16,24 @@
 
 package com.android.settings.applications;
 
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
 import static com.google.common.truth.Truth.assertThat;
 
-import android.content.Context;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.settings.applications.appcompat.UserAspectRatioAppsPreferenceController;
 import com.android.settings.testutils.XmlTestUtils;
 import com.android.settings.testutils.shadow.ShadowUserManager;
+import com.android.settings.widget.PreferenceCategoryController;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.drawer.CategoryKey;
 
@@ -31,6 +43,7 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.shadows.androidx.fragment.FragmentController;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -66,4 +79,22 @@
 
         assertThat(preferenceScreenKeys).containsAtLeastElementsIn(preferenceKeys);
     }
+
+    @Test
+    @Config(shadows = ShadowUserManager.class)
+    public void testAdvancedAppsCategory() {
+        AppDashboardFragment fragment = FragmentController.of(new AppDashboardFragment(),
+                new Bundle()).create().get();
+        UserAspectRatioAppsPreferenceController controller =
+                mock(UserAspectRatioAppsPreferenceController.class);
+        final PreferenceCategoryController advancedController =
+                fragment.getAdvancedAppsPreferenceCategoryController();
+        advancedController.setChildren(List.of(controller));
+
+        when(controller.getAvailabilityStatus()).thenReturn(AVAILABLE);
+        assertTrue(advancedController.isAvailable());
+
+        when(controller.getAvailabilityStatus()).thenReturn(CONDITIONALLY_UNAVAILABLE);
+        assertFalse(advancedController.isAvailable());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsPairOtherControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsPairOtherControllerTest.java
index 2bd2d74..c02ec32 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsPairOtherControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsPairOtherControllerTest.java
@@ -20,6 +20,8 @@
 
 import static org.mockito.Mockito.when;
 
+import android.bluetooth.BluetoothDevice;
+
 import com.android.settings.R;
 import com.android.settings.applications.SpacePreference;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -65,7 +67,7 @@
 
     /** Test the pair other side button title during initialization. */
     @Test
-    public void init_leftSideDevice_pairRightSideButtonTitle() {
+    public void init_deviceIsLeftSide_showPairRightSideTitle() {
         when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_LEFT);
 
         mController.init(mScreen);
@@ -76,7 +78,7 @@
 
     /** Test the pair other side button title during initialization. */
     @Test
-    public void init_rightSideDevice_pairLeftSideButtonTitle() {
+    public void init_deviceIsRightSide_showPairLeftSideTitle() {
         when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT);
 
         mController.init(mScreen);
@@ -87,7 +89,7 @@
 
     /** Test the pair other side button visibility during initialization. */
     @Test
-    public void init_isNotConnectedHearingAidDevice_preferenceIsNotVisible() {
+    public void init_deviceIsNotConnectedHearingAid_preferenceIsNotVisible() {
         when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false);
 
         mController.init(mScreen);
@@ -99,13 +101,13 @@
     /**
      * Test if the controller is available.
      * Conditions:
-     *      1. Hearing aids is not connected
+     *      1. The device is not a connected hearing aid
      * Expected result:
      *      The controller is not available. No need to show pair other side hint for
-     *      not connected device.
+     *      non-hearing aid device or not connected device.
      */
     @Test
-    public void isAvailable_isNotConnectedHearingAidDevice_notAvailable() {
+    public void isAvailable_deviceIsNotConnectedHearingAid_notAvailable() {
         when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false);
 
         assertThat(mController.isAvailable()).isFalse();
@@ -114,13 +116,13 @@
     /**
      * Test if the controller is available.
      * Conditions:
-     *      1. Monaural hearing aids
+     *      1. Monaural hearing aid
      * Expected result:
      *      The controller is not available. No need to show pair other side hint for
      *      monaural device.
      */
     @Test
-    public void isAvailable_isConnectedHearingAidDevice_isMonaural_notAvailable() {
+    public void isAvailable_deviceIsConnectedHearingAid_isMonaural_notAvailable() {
         when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
         when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_MONAURAL);
 
@@ -130,18 +132,17 @@
     /**
      * Test if the controller is available.
      * Conditions:
-     *      1. Binaural ASHA hearing aids
+     *      1. Binaural hearing aids
      *      2. Sub device is added
-     *      3. Sub device is connected
+     *      3. Sub device is bonded
      * Expected result:
-     *      The controller is not available. Both sides are already paired and connected.
+     *      The controller is not available. Both sides are already paired.
      */
     @Test
-    public void isAvailable_ashaDevice_otherDeviceIsConnected_notAvailable() {
+    public void isAvailable_deviceIsConnectedHearingAid_subDeviceIsBonded_notAvailable() {
         when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
         when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
-        when(mSubCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
+        when(mSubCachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
         when(mCachedDevice.getSubDevice()).thenReturn(mSubCachedDevice);
 
         assertThat(mController.isAvailable()).isFalse();
@@ -150,18 +151,17 @@
     /**
      * Test if the controller is available.
      * Conditions:
-     *      1. Binaural ASHA hearing aids
+     *      1. Binaural hearing aids
      *      2. Sub device is added
-     *      3. Sub device is not connected
+     *      3. Sub device is not bonded
      * Expected result:
      *      The controller is available. Need to show the hint to pair the other side.
      */
     @Test
-    public void isAvailable_ashaDevice_otherDeviceIsNotConnected_available() {
+    public void isAvailable_deviceIsConnectedHearingAid_subDeviceIsNotBonded_available() {
         when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
         when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
-        when(mSubCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(false);
+        when(mSubCachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
         when(mCachedDevice.getSubDevice()).thenReturn(mSubCachedDevice);
 
         assertThat(mController.isAvailable()).isTrue();
@@ -170,74 +170,55 @@
     /**
      * Test if the controller is available.
      * Conditions:
-     *      1. Binaural ASHA hearing aids
-     *      2. No sub device added
+     *      1. Binaural hearing aids
+     *      2. Member device is added
+     *      3. Member device is bonded
+     * Expected result:
+     *      The controller is not available. Both sides are already paired.
+     */
+    @Test
+    public void isAvailable_deviceIsConnectedHearingAid_memberDeviceIsBonded_notAvailable() {
+        when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
+        when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
+        when(mSubCachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mSubCachedDevice));
+
+        assertThat(mController.isAvailable()).isFalse();
+    }
+
+    /**
+     * Test if the controller is available.
+     * Conditions:
+     *      1. Binaural hearing aids
+     *      2. Member device is added
+     *      3. Member device is not bonded
      * Expected result:
      *      The controller is available. Need to show the hint to pair the other side.
      */
     @Test
-    public void isAvailable_ashaDevice_otherDeviceIsNotExist_available() {
+    public void isAvailable_deviceIsConnectedHearingAid_memberDeviceIsNotBonded_available() {
         when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
+        when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
+        when(mSubCachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+        when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mSubCachedDevice));
+
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    /**
+     * Test if the controller is available.
+     * Conditions:
+     *      1. Binaural hearing aids
+     *      2. No sub device is added
+     *      2. No member device is added
+     * Expected result:
+     *      The controller is available. Need to show the hint to pair the other side.
+     */
+    @Test
+    public void isAvailable_deviceIsConnectedHearingAid_otherDeviceIsNotExist_available() {
+        when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
         when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
         when(mCachedDevice.getSubDevice()).thenReturn(null);
-
-        assertThat(mController.isAvailable()).isTrue();
-    }
-
-    /**
-     * Test if the controller is available.
-     * Conditions:
-     *      1. Binaural LE Audio hearing aids
-     *      2. Member device is added
-     *      3. Member device is connected
-     * Expected result:
-     *      The controller is not available. Both sides are already paired and connected.
-     */
-    @Test
-    public void isAvailable_leAudioDevice_otherDeviceIsConnected_notAvailable() {
-        when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
-        when(mSubCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mSubCachedDevice));
-
-        assertThat(mController.isAvailable()).isFalse();
-    }
-
-    /**
-     * Test if the controller is available.
-     * Conditions:
-     *      1. Binaural LE Audio hearing aids
-     *      2. Member device is added
-     *      3. Member device is not connected
-     * Expected result:
-     *      The controller is available. Need to show the hint to pair the other side.
-     */
-    @Test
-    public void isAvailable_leAudioDevice_otherDeviceIsNotConnected_available() {
-        when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
-        when(mSubCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(false);
-        when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mSubCachedDevice));
-
-        assertThat(mController.isAvailable()).isTrue();
-    }
-
-    /**
-     * Test if the controller is available.
-     * Conditions:
-     *      1. Binaural LE Audio hearing aids
-     *      2. No member device added
-     * Expected result:
-     *      The controller is available. Need to show the hint to pair the other side.
-     */
-    @Test
-    public void isAvailable_leAudioDevice_otherDeviceIsNotExist_available() {
-        when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(true);
-        when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
         when(mCachedDevice.getMemberDevice()).thenReturn(new HashSet<>());
 
         assertThat(mController.isAvailable()).isTrue();
@@ -245,7 +226,7 @@
 
     /** Test the pair other side button title after refreshing. */
     @Test
-    public void refresh_rightSideDevice_pairLeftSideButtonTitle() {
+    public void refresh_deviceIsRightSide_showPairLeftSideTitle() {
         when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT);
         mController.init(mScreen);
 
@@ -257,7 +238,7 @@
 
     /** Test the pair other side button visibility after refreshing. */
     @Test
-    public void refresh_isNotConnectedHearingAidDevice_preferenceIsNotVisible() {
+    public void refresh_deviceIsNotConnectedHearingAid_preferenceIsNotVisible() {
         when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false);
         mController.init(mScreen);
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java
index d4bae29..04d601f 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffDataTest.java
@@ -60,10 +60,11 @@
     @Test
     public void needsCombineInSystemApp_isHidden_returnTrue() {
         final BatteryDiffEntry hiddenDiffEntry =
-                createBatteryDiffEntry(mContext, /*consumePower=*/ 0, /*isHidden=*/ true);
+                createBatteryDiffEntry(mContext, /* consumePower= */ 0, /* isHidden= */ true);
 
-        final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp(
-                hiddenDiffEntry, List.of(), Set.of(), Set.of());
+        final boolean needsCombineInSystemApp =
+                BatteryDiffData.needsCombineInSystemApp(
+                        hiddenDiffEntry, List.of(), Set.of(), Set.of());
 
         assertThat(needsCombineInSystemApp).isTrue();
     }
@@ -71,13 +72,17 @@
     @Test
     public void needsCombineInSystemApp_isSystemApp_returnTrue() {
         final BatteryDiffEntry batteryDiffEntry =
-                createBatteryDiffEntry(mContext, /*consumePower=*/ 0, /*isHidden=*/ false);
+                createBatteryDiffEntry(mContext, /* consumePower= */ 0, /* isHidden= */ false);
         doReturn(mAppEntry).when(mApplicationsState).getEntry(anyString(), anyInt());
         mAppEntry.info = mApplicationInfo;
         mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
 
-        final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp(
-                batteryDiffEntry, List.of(), Set.of(ConvertUtils.FAKE_PACKAGE_NAME), Set.of());
+        final boolean needsCombineInSystemApp =
+                BatteryDiffData.needsCombineInSystemApp(
+                        batteryDiffEntry,
+                        List.of(),
+                        Set.of(ConvertUtils.FAKE_PACKAGE_NAME),
+                        Set.of());
 
         assertThat(needsCombineInSystemApp).isTrue();
     }
@@ -85,13 +90,14 @@
     @Test
     public void needsCombineInSystemApp_notSystemApp_returnFalse() {
         final BatteryDiffEntry batteryDiffEntry =
-                createBatteryDiffEntry(mContext, /*consumePower=*/ 0, /*isHidden=*/ false);
+                createBatteryDiffEntry(mContext, /* consumePower= */ 0, /* isHidden= */ false);
         doReturn(mAppEntry).when(mApplicationsState).getEntry(anyString(), anyInt());
         mAppEntry.info = mApplicationInfo;
         mApplicationInfo.flags = 0;
 
-        final boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp(
-                batteryDiffEntry, List.of(), Set.of(), Set.of());
+        final boolean needsCombineInSystemApp =
+                BatteryDiffData.needsCombineInSystemApp(
+                        batteryDiffEntry, List.of(), Set.of(), Set.of());
 
         assertThat(needsCombineInSystemApp).isFalse();
     }
@@ -100,11 +106,11 @@
     public void processPercentsAndSort_sumLessThan100_adjustTo100() {
         List<BatteryDiffEntry> batteryDiffEntries = new ArrayList<>();
         batteryDiffEntries.add(
-                createBatteryDiffEntry(mContext, /*consumePower=*/ 33.33, /*isHidden=*/ false));
+                createBatteryDiffEntry(mContext, /* consumePower= */ 33.33, /* isHidden= */ false));
         batteryDiffEntries.add(
-                createBatteryDiffEntry(mContext, /*consumePower=*/ 33.34, /*isHidden=*/ false));
+                createBatteryDiffEntry(mContext, /* consumePower= */ 33.34, /* isHidden= */ false));
         batteryDiffEntries.add(
-                createBatteryDiffEntry(mContext, /*consumePower=*/ 33.33, /*isHidden=*/ false));
+                createBatteryDiffEntry(mContext, /* consumePower= */ 33.33, /* isHidden= */ false));
 
         BatteryDiffData.processAndSortEntries(batteryDiffEntries);
 
@@ -120,11 +126,11 @@
     public void processPercentsAndSort_sumGreaterThan100_adjustTo100() {
         List<BatteryDiffEntry> batteryDiffEntries = new ArrayList<>();
         batteryDiffEntries.add(
-                createBatteryDiffEntry(mContext, /*consumePower=*/ 48.5, /*isHidden=*/ false));
+                createBatteryDiffEntry(mContext, /* consumePower= */ 48.5, /* isHidden= */ false));
         batteryDiffEntries.add(
-                createBatteryDiffEntry(mContext, /*consumePower=*/ 3, /*isHidden=*/ false));
+                createBatteryDiffEntry(mContext, /* consumePower= */ 3, /* isHidden= */ false));
         batteryDiffEntries.add(
-                createBatteryDiffEntry(mContext, /*consumePower=*/ 48.5, /*isHidden=*/ false));
+                createBatteryDiffEntry(mContext, /* consumePower= */ 48.5, /* isHidden= */ false));
 
         BatteryDiffData.processAndSortEntries(batteryDiffEntries);
 
@@ -136,47 +142,101 @@
         assertThat(batteryDiffEntries.get(2).getAdjustPercentageOffset()).isEqualTo(0);
     }
 
+    @Test
+    public void processPercentsAndSort_uninstalledApps_sortAsExpected() {
+        List<BatteryDiffEntry> batteryDiffEntries = new ArrayList<>();
+        batteryDiffEntries.add(
+                createBatteryDiffEntry(mContext, /* consumePower= */ 28.5, /* key= */ "APP_1"));
+        batteryDiffEntries.add(
+                createBatteryDiffEntry(
+                        mContext,
+                        /* consumePower= */ 20,
+                        BatteryDiffEntry.UNINSTALLED_APPS_KEY));
+        batteryDiffEntries.add(
+                createBatteryDiffEntry(mContext, /* consumePower= */ 3, /* key= */ "APP_2"));
+        batteryDiffEntries.add(
+                createBatteryDiffEntry(
+                        mContext,
+                        /* consumePower= */ 28.5,
+                        BatteryDiffEntry.SYSTEM_APPS_KEY));
+        batteryDiffEntries.add(
+                createBatteryDiffEntry(mContext, /* consumePower= */ 20, /* key= */ "APP_3"));
+
+        BatteryDiffData.processAndSortEntries(batteryDiffEntries);
+
+        assertThat(batteryDiffEntries.get(0).getKey()).isEqualTo("APP_1");
+        assertThat(batteryDiffEntries.get(1).getKey()).isEqualTo("APP_3");
+        assertThat(batteryDiffEntries.get(2).getKey()).isEqualTo("APP_2");
+        assertThat(batteryDiffEntries.get(3).getKey())
+                .isEqualTo(BatteryDiffEntry.UNINSTALLED_APPS_KEY);
+        assertThat(batteryDiffEntries.get(4).getKey()).isEqualTo(BatteryDiffEntry.SYSTEM_APPS_KEY);
+    }
+
     private static BatteryDiffEntry createBatteryDiffEntry(
             Context context, double consumePower, boolean isHidden) {
+        return createBatteryDiffEntry(context, consumePower, isHidden, /* key= */ null);
+    }
+
+    private static BatteryDiffEntry createBatteryDiffEntry(
+            Context context, double consumePower, String key) {
+        return createBatteryDiffEntry(context, consumePower, /* isHidden= */ false, key);
+    }
+
+    private static BatteryDiffEntry createBatteryDiffEntry(
+            Context context, double consumePower, boolean isHidden, String key) {
         final int currentUserId = context.getUserId();
-        final BatteryHistEntry batteryHistEntry = createBatteryHistEntry(
-                ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", consumePower,
-                /*foregroundUsageConsumePower=*/ 0, /*foregroundServiceUsageConsumePower=*/ 0,
-                /*backgroundUsageConsumePower=*/ 0, /*cachedUsageConsumePower=*/ 0,
-                /*uid=*/ 0L, currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
-                /*foregroundUsageTimeInMs=*/ 0L,  /*backgroundUsageTimeInMs=*/ 0L, isHidden);
+        final BatteryHistEntry batteryHistEntry =
+                createBatteryHistEntry(
+                        ConvertUtils.FAKE_PACKAGE_NAME,
+                        "fake_label",
+                        consumePower,
+                        /* foregroundUsageConsumePower= */ 0,
+                        /* foregroundServiceUsageConsumePower= */ 0,
+                        /* backgroundUsageConsumePower= */ 0,
+                        /* cachedUsageConsumePower= */ 0,
+                        /* uid= */ 0L,
+                        currentUserId,
+                        ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
+                        /* foregroundUsageTimeInMs= */ 0L,
+                        /* backgroundUsageTimeInMs= */ 0L,
+                        isHidden);
         return new BatteryDiffEntry(
                 context,
                 batteryHistEntry.mUid,
                 batteryHistEntry.mUserId,
-                batteryHistEntry.getKey(),
+                key == null ? batteryHistEntry.getKey() : key,
                 batteryHistEntry.mIsHidden,
                 batteryHistEntry.mDrainType,
                 batteryHistEntry.mPackageName,
                 batteryHistEntry.mAppLabel,
                 batteryHistEntry.mConsumerType,
-                /*foregroundUsageTimeInMs=*/ 0,
-                /*backgroundUsageTimeInMs=*/ 0,
-                /*screenOnTimeInMs=*/ 0,
-                /*consumePower=*/ consumePower,
-                /*foregroundUsageConsumePower=*/ 0,
-                /*foregroundServiceUsageConsumePower=*/ 0,
-                /*backgroundUsageConsumePower=*/ 0,
-                /*cachedUsageConsumePower=*/ 0);
+                /* foregroundUsageTimeInMs= */ 0,
+                /* backgroundUsageTimeInMs= */ 0,
+                /* screenOnTimeInMs= */ 0,
+                consumePower,
+                /* foregroundUsageConsumePower= */ 0,
+                /* foregroundServiceUsageConsumePower= */ 0,
+                /* backgroundUsageConsumePower= */ 0,
+                /* cachedUsageConsumePower= */ 0);
     }
 
     private static BatteryHistEntry createBatteryHistEntry(
-            final String packageName, final String appLabel, final double consumePower,
+            final String packageName,
+            final String appLabel,
+            final double consumePower,
             final double foregroundUsageConsumePower,
             final double foregroundServiceUsageConsumePower,
-            final double backgroundUsageConsumePower, final double cachedUsageConsumePower,
-            final long uid, final long userId, final int consumerType,
-            final long foregroundUsageTimeInMs, final long backgroundUsageTimeInMs,
+            final double backgroundUsageConsumePower,
+            final double cachedUsageConsumePower,
+            final long uid,
+            final long userId,
+            final int consumerType,
+            final long foregroundUsageTimeInMs,
+            final long backgroundUsageTimeInMs,
             final boolean isHidden) {
         // Only insert required fields.
         final BatteryInformation batteryInformation =
-                BatteryInformation
-                        .newBuilder()
+                BatteryInformation.newBuilder()
                         .setAppLabel(appLabel)
                         .setConsumePower(consumePower)
                         .setForegroundUsageConsumePower(foregroundUsageConsumePower)
@@ -192,7 +252,8 @@
         values.put(BatteryHistEntry.KEY_UID, uid);
         values.put(BatteryHistEntry.KEY_USER_ID, userId);
         values.put(BatteryHistEntry.KEY_CONSUMER_TYPE, consumerType);
-        values.put(BatteryHistEntry.KEY_BATTERY_INFORMATION,
+        values.put(
+                BatteryHistEntry.KEY_BATTERY_INFORMATION,
                 ConvertUtils.convertBatteryInformationToString(batteryInformation));
         return new BatteryHistEntry(values);
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntryTest.java
index 9bb4b73..2cafadb 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryDiffEntryTest.java
@@ -58,35 +58,37 @@
 @Config(shadows = {BatteryDiffEntryTest.ShadowUserHandle.class})
 public final class BatteryDiffEntryTest {
 
+    private static final int UID = 100;
+    private static final int UNINSTALLED_UID = 101;
+    private static final String PACKAGE_NAME = "com.android.testing";
+    private static final String UNINSTALLED_PACKAGE_NAME = "com.android.testing.uninstalled";
+
     private Context mContext;
 
-    @Mock
-    private ApplicationInfo mMockAppInfo;
-    @Mock
-    private PackageManager mMockPackageManager;
-    @Mock
-    private UserManager mMockUserManager;
-    @Mock
-    private Drawable mMockDrawable;
-    @Mock
-    private Drawable mMockDrawable2;
-    @Mock
-    private Drawable mMockBadgedDrawable;
-    @Mock
-    private BatteryHistEntry mBatteryHistEntry;
-    @Mock
-    private PackageInfo mMockPackageInfo;
-    @Mock
-    private ConstantState mMockConstantState;
+    @Mock private ApplicationInfo mMockAppInfo;
+    @Mock private PackageManager mMockPackageManager;
+    @Mock private UserManager mMockUserManager;
+    @Mock private Drawable mMockDrawable;
+    @Mock private Drawable mMockDrawable2;
+    @Mock private Drawable mMockBadgedDrawable;
+    @Mock private BatteryHistEntry mBatteryHistEntry;
+    @Mock private PackageInfo mMockPackageInfo;
+    @Mock private ConstantState mMockConstantState;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         ShadowUserHandle.reset();
         mContext = spy(RuntimeEnvironment.application);
         doReturn(mContext).when(mContext).getApplicationContext();
         doReturn(mMockUserManager).when(mContext).getSystemService(UserManager.class);
         doReturn(mMockPackageManager).when(mContext).getPackageManager();
+        doReturn(UID)
+                .when(mMockPackageManager)
+                .getPackageUid(PACKAGE_NAME, PackageManager.GET_META_DATA);
+        doReturn(BatteryUtils.UID_NULL)
+                .when(mMockPackageManager)
+                .getPackageUid(UNINSTALLED_PACKAGE_NAME, PackageManager.GET_META_DATA);
         BatteryDiffEntry.clearCache();
     }
 
@@ -95,22 +97,22 @@
         final BatteryDiffEntry entry =
                 new BatteryDiffEntry(
                         mContext,
-                        /*uid=*/ 0,
-                        /*userId=*/ 0,
-                        /*key=*/ "key",
-                        /*isHidden=*/ false,
-                        /*componentId=*/ -1,
-                        /*legacyPackageName=*/ null,
-                        /*legacyLabel=*/ null,
+                        /* uid= */ 0,
+                        /* userId= */ 0,
+                        /* key= */ "key",
+                        /* isHidden= */ false,
+                        /* componentId= */ -1,
+                        /* legacyPackageName= */ null,
+                        /* legacyLabel= */ null,
                         /*consumerType*/ ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
-                        /*foregroundUsageTimeInMs=*/ 10001L,
-                        /*backgroundUsageTimeInMs=*/ 20002L,
-                        /*screenOnTimeInMs=*/ 30003L,
-                        /*consumePower=*/ 22.0,
-                        /*foregroundUsageConsumePower=*/ 10.0,
-                        /*foregroundServiceUsageConsumePower=*/ 10.0,
-                        /*backgroundUsageConsumePower=*/ 1.0,
-                        /*cachedUsageConsumePower=*/ 1.0);
+                        /* foregroundUsageTimeInMs= */ 10001L,
+                        /* backgroundUsageTimeInMs= */ 20002L,
+                        /* screenOnTimeInMs= */ 30003L,
+                        /* consumePower= */ 22.0,
+                        /* foregroundUsageConsumePower= */ 10.0,
+                        /* foregroundServiceUsageConsumePower= */ 10.0,
+                        /* backgroundUsageConsumePower= */ 1.0,
+                        /* cachedUsageConsumePower= */ 1.0);
         entry.setTotalConsumePower(100.0);
 
         assertThat(entry.getPercentage()).isEqualTo(22.0);
@@ -121,22 +123,22 @@
         final BatteryDiffEntry entry =
                 new BatteryDiffEntry(
                         mContext,
-                        /*uid=*/ 0,
-                        /*userId=*/ 0,
-                        /*key=*/ "key",
-                        /*isHidden=*/ false,
-                        /*componentId=*/ -1,
-                        /*legacyPackageName=*/ null,
-                        /*legacyLabel=*/ null,
+                        /* uid= */ 0,
+                        /* userId= */ 0,
+                        /* key= */ "key",
+                        /* isHidden= */ false,
+                        /* componentId= */ -1,
+                        /* legacyPackageName= */ null,
+                        /* legacyLabel= */ null,
                         /*consumerType*/ ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
-                        /*foregroundUsageTimeInMs=*/ 10001L,
-                        /*backgroundUsageTimeInMs=*/ 20002L,
-                        /*screenOnTimeInMs=*/ 30003L,
-                        /*consumePower=*/ 22.0,
-                        /*foregroundUsageConsumePower=*/ 10.0,
-                        /*foregroundServiceUsageConsumePower=*/ 10.0,
-                        /*backgroundUsageConsumePower=*/ 1.0,
-                        /*cachedUsageConsumePower=*/ 1.0);
+                        /* foregroundUsageTimeInMs= */ 10001L,
+                        /* backgroundUsageTimeInMs= */ 20002L,
+                        /* screenOnTimeInMs= */ 30003L,
+                        /* consumePower= */ 22.0,
+                        /* foregroundUsageConsumePower= */ 10.0,
+                        /* foregroundServiceUsageConsumePower= */ 10.0,
+                        /* backgroundUsageConsumePower= */ 1.0,
+                        /* cachedUsageConsumePower= */ 1.0);
         entry.setTotalConsumePower(0);
 
         assertThat(entry.getPercentage()).isEqualTo(0);
@@ -149,22 +151,22 @@
         BatteryDiffEntry systemAppsBatteryDiffEntry =
                 new BatteryDiffEntry(
                         mContext,
-                        /*uid=*/ 0,
-                        /*userId=*/ 0,
-                        /*key=*/ BatteryDiffEntry.SYSTEM_APPS_KEY,
-                        /*isHidden=*/ false,
-                        /*componentId=*/ -1,
-                        /*legacyPackageName=*/ null,
-                        /*legacyLabel=*/ BatteryDiffEntry.SYSTEM_APPS_KEY,
+                        /* uid= */ 0,
+                        /* userId= */ 0,
+                        /* key= */ BatteryDiffEntry.SYSTEM_APPS_KEY,
+                        /* isHidden= */ false,
+                        /* componentId= */ -1,
+                        /* legacyPackageName= */ null,
+                        /* legacyLabel= */ BatteryDiffEntry.SYSTEM_APPS_KEY,
                         /*consumerType*/ ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
-                        /*foregroundUsageTimeInMs=*/ 0,
-                        /*backgroundUsageTimeInMs=*/ 0,
-                        /*screenOnTimeInMs=*/ 0,
-                        /*consumePower=*/ 0,
-                        /*foregroundUsageConsumePower=*/ 0,
-                        /*foregroundServiceUsageConsumePower=*/ 0,
-                        /*backgroundUsageConsumePower=*/ 0,
-                        /*cachedUsageConsumePower=*/ 0);
+                        /* foregroundUsageTimeInMs= */ 0,
+                        /* backgroundUsageTimeInMs= */ 0,
+                        /* screenOnTimeInMs= */ 0,
+                        /* consumePower= */ 0,
+                        /* foregroundUsageConsumePower= */ 0,
+                        /* foregroundServiceUsageConsumePower= */ 0,
+                        /* backgroundUsageConsumePower= */ 0,
+                        /* cachedUsageConsumePower= */ 0);
         systemAppsBatteryDiffEntry.mConsumePower = 16;
         systemAppsBatteryDiffEntry.setTotalConsumePower(100);
         entryList.add(systemAppsBatteryDiffEntry);
@@ -184,14 +186,14 @@
     public void testLoadLabelAndIcon_forSystemBattery_returnExpectedResult() {
         final String expectedName = "Ambient display";
         // Generates fake testing data.
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
         final BatteryInformation batteryInformation =
-                BatteryInformation
-                        .newBuilder()
+                BatteryInformation.newBuilder()
                         .setDrainType(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY)
                         .build();
-        values.put(BatteryHistEntry.KEY_BATTERY_INFORMATION,
+        values.put(
+                BatteryHistEntry.KEY_BATTERY_INFORMATION,
                 ConvertUtils.convertBatteryInformationToString(batteryInformation));
         final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
 
@@ -215,8 +217,8 @@
         final String expectedName = "Removed user";
         doReturn(null).when(mMockUserManager).getUserInfo(1001);
         // Generates fake testing data.
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
         values.put(BatteryHistEntry.KEY_USER_ID, Integer.valueOf(1001));
         final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
 
@@ -240,14 +242,12 @@
     public void testGetAppLabel_loadDataFromApplicationInfo() throws Exception {
         final String expectedAppLabel = "fake app label";
         final String fakePackageName = "com.fake.google.com";
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
         values.put(BatteryHistEntry.KEY_UID, /*invalid uid*/ 10001);
         values.put(BatteryHistEntry.KEY_PACKAGE_NAME, fakePackageName);
-        doReturn(mMockAppInfo).when(mMockPackageManager)
-                .getApplicationInfo(fakePackageName, 0);
-        doReturn(expectedAppLabel).when(mMockPackageManager)
-                .getApplicationLabel(mMockAppInfo);
+        doReturn(mMockAppInfo).when(mMockPackageManager).getApplicationInfo(fakePackageName, 0);
+        doReturn(expectedAppLabel).when(mMockPackageManager).getApplicationLabel(mMockAppInfo);
         final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
 
         final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
@@ -267,8 +267,8 @@
     @Test
     public void testGetAppLabel_loadDataFromPreDefinedNameAndUid() {
         final String expectedAppLabel = "Android OS";
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
         final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
 
         final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
@@ -284,14 +284,12 @@
     @Test
     public void testGetAppLabel_nullAppLabel_returnAppLabelInBatteryHistEntry() {
         final String expectedAppLabel = "fake app label";
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
         final BatteryInformation batteryInformation =
-                BatteryInformation
-                        .newBuilder()
-                        .setAppLabel(expectedAppLabel)
-                        .build();
-        values.put(BatteryHistEntry.KEY_BATTERY_INFORMATION,
+                BatteryInformation.newBuilder().setAppLabel(expectedAppLabel).build();
+        values.put(
+                BatteryHistEntry.KEY_BATTERY_INFORMATION,
                 ConvertUtils.convertBatteryInformationToString(batteryInformation));
         final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
 
@@ -304,8 +302,8 @@
 
     @Test
     public void testGetAppIcon_nonUidConsumer_returnAppIconInBatteryDiffEntry() {
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
         final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
         mockConstantState(mMockDrawable);
 
@@ -324,7 +322,8 @@
         final BatteryDiffEntry entry = createBatteryDiffEntry(mMockDrawable);
         mockConstantState(mMockDrawable);
         mockConstantState(mMockBadgedDrawable);
-        doReturn(mMockBadgedDrawable).when(mMockUserManager)
+        doReturn(mMockBadgedDrawable)
+                .when(mMockUserManager)
                 .getBadgedIconForUser(eq(mMockDrawable), any());
 
         entry.mAppIcon = null;
@@ -350,9 +349,8 @@
     public void testClearCache_clearDataForResourcesAndFlags() {
         BatteryDiffEntry.sResourceCache.put(
                 "fake application key",
-                new BatteryEntry.NameAndIcon("app label", null, /*iconId=*/ 0));
-        BatteryDiffEntry.sValidForRestriction.put(
-                "fake application key", Boolean.valueOf(false));
+                new BatteryEntry.NameAndIcon("app label", null, /* iconId= */ 0));
+        BatteryDiffEntry.sValidForRestriction.put("fake application key", Boolean.valueOf(false));
 
         BatteryDiffEntry.clearCache();
 
@@ -386,7 +384,8 @@
         final BatteryDiffEntry entry =
                 createBatteryDiffEntry(
                         ConvertUtils.CONSUMER_TYPE_USER_BATTERY,
-                        /*uid=*/ 0, /*isHidden=*/ false);
+                        /* uid= */ 0,
+                        /* isHidden= */ false);
         assertThat(entry.isSystemEntry()).isTrue();
     }
 
@@ -395,7 +394,8 @@
         final BatteryDiffEntry entry =
                 createBatteryDiffEntry(
                         ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY,
-                        /*uid=*/ 0, /*isHidden=*/ false);
+                        /* uid= */ 0,
+                        /* isHidden= */ false);
         assertThat(entry.isSystemEntry()).isTrue();
     }
 
@@ -404,7 +404,8 @@
         final BatteryDiffEntry entry =
                 createBatteryDiffEntry(
                         ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
-                        /*uid=*/ 123, /*isHidden=*/ false);
+                        /* uid= */ 123,
+                        /* isHidden= */ false);
         assertThat(entry.isSystemEntry()).isFalse();
     }
 
@@ -413,39 +414,80 @@
         final BatteryDiffEntry entry =
                 createBatteryDiffEntry(
                         ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
-                        /*uid=*/ 1230, /*isHidden=*/ false);
+                        /* uid= */ 1230,
+                        /* isHidden= */ false);
         assertThat(entry.isSystemEntry()).isFalse();
     }
 
     @Test
+    public void testIsUninstalledEntry_systemApp_returnFalse() {
+        final BatteryDiffEntry entry =
+                createBatteryDiffEntry(
+                        ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY,
+                        /* uid= */ 0,
+                        /* isHidden= */ false);
+        assertThat(entry.isSystemEntry()).isTrue();
+        assertThat(entry.isUninstalledEntry()).isFalse();
+    }
+
+    @Test
+    public void testIsUninstalledEntry_installedApp_returnFalse() throws Exception {
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        values.put(BatteryHistEntry.KEY_UID, UID);
+        values.put(BatteryHistEntry.KEY_PACKAGE_NAME, PACKAGE_NAME);
+        final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values));
+
+        assertThat(entry.isSystemEntry()).isFalse();
+        assertThat(entry.isUninstalledEntry()).isFalse();
+    }
+
+    @Test
+    public void testIsUninstalledEntry_uninstalledApp_returnTrue() throws Exception {
+        doReturn(BatteryUtils.UID_NULL)
+                .when(mMockPackageManager)
+                .getPackageUid(PACKAGE_NAME, PackageManager.GET_META_DATA);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        values.put(BatteryHistEntry.KEY_UID, UNINSTALLED_UID);
+        values.put(BatteryHistEntry.KEY_PACKAGE_NAME, UNINSTALLED_PACKAGE_NAME);
+        final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values));
+
+        assertThat(entry.isSystemEntry()).isFalse();
+        assertThat(entry.isUninstalledEntry()).isTrue();
+    }
+
+    @Test
     public void testUpdateRestrictionFlagState_updateFlagAsExpected() throws Exception {
         final String expectedAppLabel = "fake app label";
         final String fakePackageName = "com.fake.google.com";
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
         values.put(BatteryHistEntry.KEY_UID, /*invalid uid*/ 10001);
         values.put(BatteryHistEntry.KEY_PACKAGE_NAME, fakePackageName);
-        final BatteryDiffEntry entry =
-                createBatteryDiffEntry(10, new BatteryHistEntry(values));
+        final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values));
 
         entry.updateRestrictionFlagState();
         // Sets false if the app entry cannot be found.
         assertThat(entry.mValidForRestriction).isFalse();
 
-        doReturn(BatteryUtils.UID_NULL).when(mMockPackageManager).getPackageUid(
-                entry.getPackageName(), PackageManager.GET_META_DATA);
+        doReturn(BatteryUtils.UID_NULL)
+                .when(mMockPackageManager)
+                .getPackageUid(entry.getPackageName(), PackageManager.GET_META_DATA);
         entry.updateRestrictionFlagState();
         // Sets false if the app is invalid package name.
         assertThat(entry.mValidForRestriction).isFalse();
 
-        doReturn(1000).when(mMockPackageManager).getPackageUid(
-                entry.getPackageName(), PackageManager.GET_META_DATA);
+        doReturn(1000)
+                .when(mMockPackageManager)
+                .getPackageUid(entry.getPackageName(), PackageManager.GET_META_DATA);
         entry.updateRestrictionFlagState();
         // Sets false if the app PackageInfo cannot be found.
         assertThat(entry.mValidForRestriction).isFalse();
 
-        doReturn(mMockPackageInfo).when(mMockPackageManager).getPackageInfo(
-                eq(entry.getPackageName()), anyInt());
+        doReturn(mMockPackageInfo)
+                .when(mMockPackageManager)
+                .getPackageInfo(eq(entry.getPackageName()), anyInt());
         entry.updateRestrictionFlagState();
         // Sets true if package is valid and PackageInfo can be found.
         assertThat(entry.mValidForRestriction).isTrue();
@@ -454,11 +496,10 @@
     @Test
     public void testGetPackageName_returnExpectedResult() {
         final String expectedPackageName = "com.fake.google.com";
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
         values.put(BatteryHistEntry.KEY_PACKAGE_NAME, expectedPackageName);
-        final BatteryDiffEntry entry =
-                createBatteryDiffEntry(10, new BatteryHistEntry(values));
+        final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values));
 
         assertThat(entry.getPackageName()).isEqualTo(expectedPackageName);
     }
@@ -466,59 +507,56 @@
     @Test
     public void testGetPackageName_withProcessName_returnExpectedResult() {
         final String expectedPackageName = "com.fake.google.com";
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
-        values.put(
-                BatteryHistEntry.KEY_PACKAGE_NAME,
-                expectedPackageName + ":privileged_process0");
-        final BatteryDiffEntry entry =
-                createBatteryDiffEntry(10, new BatteryHistEntry(values));
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        values.put(BatteryHistEntry.KEY_PACKAGE_NAME, expectedPackageName + ":privileged_process0");
+        final BatteryDiffEntry entry = createBatteryDiffEntry(10, new BatteryHistEntry(values));
 
         assertThat(entry.getPackageName()).isEqualTo(expectedPackageName);
     }
 
-    private BatteryDiffEntry createBatteryDiffEntry(
-            int consumerType, long uid, boolean isHidden) {
+    private BatteryDiffEntry createBatteryDiffEntry(int consumerType, long uid, boolean isHidden) {
         return new BatteryDiffEntry(
                 mContext,
-                /*uid=*/ uid,
-                /*userId=*/ 0,
-                /*key=*/ "key",
-                /*isHidden=*/ isHidden,
-                /*componentId=*/ -1,
-                /*legacyPackageName=*/ null,
-                /*legacyLabel=*/ null,
+                /* uid= */ uid,
+                /* userId= */ 0,
+                /* key= */ "key",
+                /* isHidden= */ isHidden,
+                /* componentId= */ -1,
+                /* legacyPackageName= */ null,
+                /* legacyLabel= */ null,
                 /*consumerType*/ consumerType,
-                /*foregroundUsageTimeInMs=*/ 0,
-                /*backgroundUsageTimeInMs=*/ 0,
-                /*screenOnTimeInMs=*/ 0,
-                /*consumePower=*/ 0,
-                /*foregroundUsageConsumePower=*/ 0,
-                /*foregroundServiceUsageConsumePower=*/ 0,
-                /*backgroundUsageConsumePower=*/ 0,
-                /*cachedUsageConsumePower=*/ 0);
+                /* foregroundUsageTimeInMs= */ 0,
+                /* backgroundUsageTimeInMs= */ 0,
+                /* screenOnTimeInMs= */ 0,
+                /* consumePower= */ 0,
+                /* foregroundUsageConsumePower= */ 0,
+                /* foregroundServiceUsageConsumePower= */ 0,
+                /* backgroundUsageConsumePower= */ 0,
+                /* cachedUsageConsumePower= */ 0);
     }
 
     private BatteryDiffEntry createBatteryDiffEntry(
             double consumePower, BatteryHistEntry batteryHistEntry) {
-        final BatteryDiffEntry entry = new BatteryDiffEntry(
-                mContext,
-                batteryHistEntry.mUid,
-                batteryHistEntry.mUserId,
-                batteryHistEntry.getKey(),
-                batteryHistEntry.mIsHidden,
-                batteryHistEntry.mDrainType,
-                batteryHistEntry.mPackageName,
-                batteryHistEntry.mAppLabel,
-                batteryHistEntry.mConsumerType,
-                /*foregroundUsageTimeInMs=*/ 0,
-                /*backgroundUsageTimeInMs=*/ 0,
-                /*screenOnTimeInMs=*/ 0,
-                consumePower,
-                /*foregroundUsageConsumePower=*/ 0,
-                /*foregroundServiceUsageConsumePower=*/ 0,
-                /*backgroundUsageConsumePower=*/ 0,
-                /*cachedUsageConsumePower=*/ 0);
+        final BatteryDiffEntry entry =
+                new BatteryDiffEntry(
+                        mContext,
+                        batteryHistEntry.mUid,
+                        batteryHistEntry.mUserId,
+                        batteryHistEntry.getKey(),
+                        batteryHistEntry.mIsHidden,
+                        batteryHistEntry.mDrainType,
+                        batteryHistEntry.mPackageName,
+                        batteryHistEntry.mAppLabel,
+                        batteryHistEntry.mConsumerType,
+                        /* foregroundUsageTimeInMs= */ 0,
+                        /* backgroundUsageTimeInMs= */ 0,
+                        /* screenOnTimeInMs= */ 0,
+                        consumePower,
+                        /* foregroundUsageConsumePower= */ 0,
+                        /* foregroundServiceUsageConsumePower= */ 0,
+                        /* backgroundUsageConsumePower= */ 0,
+                        /* cachedUsageConsumePower= */ 0);
         entry.setTotalConsumePower(100.0);
         return entry;
     }
@@ -530,15 +568,14 @@
     }
 
     private BatteryDiffEntry createBatteryDiffEntry(Drawable drawable) throws Exception {
-        final ContentValues values = getContentValuesWithType(
-                ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
+        final ContentValues values =
+                getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
         values.put(BatteryHistEntry.KEY_UID, 1001);
         values.put(BatteryHistEntry.KEY_PACKAGE_NAME, "com.a.b.c");
         final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
         doReturn(drawable).when(mMockPackageManager).getDefaultActivityIcon();
         doReturn(null).when(mMockPackageManager).getApplicationInfo("com.a.b.c", 0);
-        doReturn(new String[]{"com.a.b.c"}).when(mMockPackageManager)
-                .getPackagesForUid(1001);
+        doReturn(new String[] {"com.a.b.c"}).when(mMockPackageManager).getPackagesForUid(1001);
         return createBatteryDiffEntry(10, batteryHistEntry);
     }
 
diff --git a/tests/robotests/src/com/android/settings/tts/TtsEnginePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/tts/TtsEnginePreferenceFragmentTest.java
index 00b8e86..1cb188c 100644
--- a/tests/robotests/src/com/android/settings/tts/TtsEnginePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/tts/TtsEnginePreferenceFragmentTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
 
 import android.content.Context;
 import android.content.Intent;
@@ -31,6 +32,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.os.Bundle;
+import android.os.Looper;
 import android.speech.tts.TextToSpeech;
 import android.speech.tts.TtsEngines;
 
@@ -43,6 +45,7 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implements;
 import org.robolectric.shadow.api.Shadow;
 import org.robolectric.shadows.ShadowPackageManager;
 import org.robolectric.shadows.androidx.fragment.FragmentController;
@@ -50,12 +53,15 @@
 @RunWith(RobolectricTestRunner.class)
 public class TtsEnginePreferenceFragmentTest {
 
+    @Implements(TextToSpeech.class)
+    public static class NoOpShadowTextToSpeech {}
+
     private Context mContext;
     private TtsEnginePreferenceFragment mTtsEnginePreferenceFragment;
 
     @Before
     public void setUp() {
-        mContext = RuntimeEnvironment.application;
+        mContext = RuntimeEnvironment.systemContext;
 
         final ResolveInfo info = new ResolveInfo();
         final ServiceInfo serviceInfo = spy(new ServiceInfo());
@@ -76,17 +82,19 @@
     }
 
     @Test
+    @Config(shadows = {NoOpShadowTextToSpeech.class})
     public void getCandidates_AddEngines_returnCorrectEngines() {
         mTtsEnginePreferenceFragment = FragmentController.of(new TtsEnginePreferenceFragment(),
                 new Bundle())
                 .create()
                 .get();
+        shadowOf(Looper.getMainLooper()).idle();
 
         assertThat(mTtsEnginePreferenceFragment.getCandidates().size()).isEqualTo(1);
     }
 
     @Test
-    @Config(shadows = {ShadowTtsEngines.class})
+    @Config(shadows = {ShadowTtsEngines.class, NoOpShadowTextToSpeech.class})
     public void getDefaultKey_validKey_returnCorrectKey() {
         final String TEST_ENGINE = "test_engine";
         final TtsEngines engine = mock(TtsEngines.class);
@@ -95,13 +103,14 @@
                 new Bundle())
                 .create()
                 .get();
+        shadowOf(Looper.getMainLooper()).idle();
         when(engine.getDefaultEngine()).thenReturn(TEST_ENGINE);
 
         assertThat(mTtsEnginePreferenceFragment.getDefaultKey()).isEqualTo(TEST_ENGINE);
     }
 
     @Test
-    @Config(shadows = {ShadowTtsEngines.class})
+    @Config(shadows = {ShadowTtsEngines.class, NoOpShadowTextToSpeech.class})
     public void setDefaultKey_validKey_callingTtsEngineFunction() {
         final TtsEngines engine = mock(TtsEngines.class);
         ShadowTtsEngines.setInstance(engine);
@@ -109,6 +118,7 @@
                 new Bundle())
                 .create()
                 .get();
+        shadowOf(Looper.getMainLooper()).idle();
 
         mTtsEnginePreferenceFragment.setDefaultKey(mContext.getPackageName());
 
@@ -116,14 +126,17 @@
     }
 
     @Test
+    @Config(shadows = {NoOpShadowTextToSpeech.class})
     public void setDefaultKey_validKey_updateCheckedState() {
-        mTtsEnginePreferenceFragment = spy(FragmentController.of(new TtsEnginePreferenceFragment(),
+        mTtsEnginePreferenceFragment = FragmentController.of(new TtsEnginePreferenceFragment(),
                 new Bundle())
                 .create()
-                .get());
+                .get();
+        shadowOf(Looper.getMainLooper()).idle();
+        TtsEnginePreferenceFragment fragmentSpy = spy(mTtsEnginePreferenceFragment);
 
-        mTtsEnginePreferenceFragment.setDefaultKey(mContext.getPackageName());
+        fragmentSpy.setDefaultKey(mContext.getPackageName());
 
-        verify(mTtsEnginePreferenceFragment).updateCheckedState(mContext.getPackageName());
+        verify(fragmentSpy).updateCheckedState(mContext.getPackageName());
     }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.java
deleted file mode 100644
index d3244fa..0000000
--- a/tests/robotests/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.wifi.details2;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-
-import androidx.preference.DropDownPreference;
-
-import com.android.settings.R;
-import com.android.wifitrackerlib.WifiEntry;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class WifiPrivacyPreferenceController2Test {
-
-    private static final int PRIVACY_RANDOMIZED = WifiEntry.PRIVACY_RANDOMIZED_MAC;
-    private static final int PRIVACY_TRUSTED = WifiEntry.PRIVACY_DEVICE_MAC;
-
-    @Mock private WifiEntry mMockWifiEntry;
-
-    private WifiPrivacyPreferenceController2 mPreferenceController;
-    private Context mContext;
-    private DropDownPreference mDropDownPreference;
-    private String[] mPerferenceStrings;
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-
-        mMockWifiEntry = mock(WifiEntry.class);
-        WifiPrivacyPreferenceController2 preferenceController =
-                new WifiPrivacyPreferenceController2(mContext);
-        preferenceController.setWifiEntry(mMockWifiEntry);
-        mPreferenceController = spy(preferenceController);
-        mDropDownPreference = new DropDownPreference(mContext);
-        mDropDownPreference.setEntries(R.array.wifi_privacy_entries);
-        mDropDownPreference.setEntryValues(R.array.wifi_privacy_values);
-
-        mPerferenceStrings = mContext.getResources().getStringArray(R.array.wifi_privacy_entries);
-    }
-
-    @Test
-    public void testUpdateState_wifiPrivacy_setCorrectValue() {
-        doReturn(PRIVACY_TRUSTED).when(mPreferenceController).getRandomizationValue();
-
-        mPreferenceController.updateState(mDropDownPreference);
-
-        int prefValue = mPreferenceController.translateMacRandomizedValueToPrefValue(
-                PRIVACY_TRUSTED);
-        assertThat(mDropDownPreference.getEntry()).isEqualTo(mPerferenceStrings[prefValue]);
-    }
-
-    @Test
-    public void testUpdateState_wifiNotMetered_setCorrectValue() {
-        doReturn(PRIVACY_RANDOMIZED).when(mPreferenceController).getRandomizationValue();
-
-        mPreferenceController.updateState(mDropDownPreference);
-
-        int prefValue = mPreferenceController.translateMacRandomizedValueToPrefValue(
-                PRIVACY_RANDOMIZED);
-        assertThat(mDropDownPreference.getEntry()).isEqualTo(mPerferenceStrings[prefValue]);
-    }
-
-    @Test
-    public void testUpdateState_canSetPrivacyInNextUpdate_shouldBeSelectable() {
-        // Return false in WifiEntry#canSetPrivacy to make preference un-selectable first.
-        when(mMockWifiEntry.canSetPrivacy()).thenReturn(false);
-
-        mPreferenceController.updateState(mDropDownPreference);
-
-        assertThat(mDropDownPreference.isSelectable()).isFalse();
-
-        // Return true in WifiEntry#canSetPrivacy to verify preference back to selectable.
-        when(mMockWifiEntry.canSetPrivacy()).thenReturn(true);
-
-        mPreferenceController.updateState(mDropDownPreference);
-
-        assertThat(mDropDownPreference.isSelectable()).isTrue();
-    }
-
-    @Test
-    public void testUpdateState_canNotSetPrivacyInNextUpdate_shouldNotBeSelectable() {
-        // Return true in WifiEntry#canSetPrivacy to make preference selectable first.
-        when(mMockWifiEntry.canSetPrivacy()).thenReturn(true);
-
-        mPreferenceController.updateState(mDropDownPreference);
-
-        assertThat(mDropDownPreference.isSelectable()).isTrue();
-
-        // Return false in WifiEntry#canSetPrivacy to verify preference back to un-selectable.
-        when(mMockWifiEntry.canSetPrivacy()).thenReturn(false);
-
-        mPreferenceController.updateState(mDropDownPreference);
-
-        assertThat(mDropDownPreference.isSelectable()).isFalse();
-    }
-}
diff --git a/tests/spa_unit/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.kt b/tests/spa_unit/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.kt
new file mode 100644
index 0000000..cb1f997
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.kt
@@ -0,0 +1,143 @@
+/*
+ * 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.wifi.details2
+
+import android.content.Context
+import androidx.preference.ListPreference
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.R
+import com.android.wifitrackerlib.WifiEntry
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@RunWith(AndroidJUnit4::class)
+class WifiPrivacyPreferenceController2Test {
+    private var mockWifiEntry = mock<WifiEntry>()
+
+    private var context: Context = ApplicationProvider.getApplicationContext()
+
+    private var controller = spy(WifiPrivacyPreferenceController2(context).apply {
+        setWifiEntry(mockWifiEntry)
+    })
+
+    private var preference = ListPreference(context).apply {
+        setEntries(R.array.wifi_privacy_entries)
+        setEntryValues(R.array.wifi_privacy_values)
+    }
+
+    private var preferenceStrings = context.resources.getStringArray(R.array.wifi_privacy_entries)
+
+    @Test
+    fun updateState_wifiPrivacy_setCorrectValue() {
+        controller.stub {
+            doReturn(WifiEntry.PRIVACY_DEVICE_MAC).whenever(mock).randomizationValue
+        }
+
+        controller.updateState(preference)
+
+        val prefValue = WifiPrivacyPreferenceController2.translateMacRandomizedValueToPrefValue(
+            WifiEntry.PRIVACY_DEVICE_MAC
+        )
+        assertThat(preference.entry).isEqualTo(preferenceStrings[prefValue])
+    }
+
+    @Test
+    fun updateState_wifiNotMetered_setCorrectValue() {
+        controller.stub {
+            doReturn(WifiEntry.PRIVACY_RANDOMIZED_MAC).whenever(mock).randomizationValue
+        }
+
+        controller.updateState(preference)
+
+        val prefValue = WifiPrivacyPreferenceController2.translateMacRandomizedValueToPrefValue(
+            WifiEntry.PRIVACY_RANDOMIZED_MAC
+        )
+        assertThat(preference.entry).isEqualTo(preferenceStrings[prefValue])
+    }
+
+    @Test
+    fun updateState_canSetPrivacyInNextUpdate_shouldBeSelectable() {
+        mockWifiEntry.stub {
+            // Return false in WifiEntry#canSetPrivacy to make preference un-selectable first.
+            on { canSetPrivacy() } doReturn false
+        }
+        controller.updateState(preference)
+        assertThat(preference.isSelectable).isFalse()
+
+        mockWifiEntry.stub {
+            // Return true in WifiEntry#canSetPrivacy to verify preference back to selectable.
+            on { canSetPrivacy() } doReturn true
+        }
+        controller.updateState(preference)
+        assertThat(preference.isSelectable).isTrue()
+    }
+
+    @Test
+    fun updateState_canNotSetPrivacyInNextUpdate_shouldNotBeSelectable() {
+        mockWifiEntry.stub {
+            // Return true in WifiEntry#canSetPrivacy to make preference selectable first.
+            on { canSetPrivacy() } doReturn true
+        }
+        controller.updateState(preference)
+        assertThat(preference.isSelectable).isTrue()
+
+        mockWifiEntry.stub {
+            // Return false in WifiEntry#canSetPrivacy to verify preference back to un-selectable.
+            on { canSetPrivacy() } doReturn false
+        }
+        controller.updateState(preference)
+        assertThat(preference.isSelectable).isFalse()
+    }
+
+    @Test
+    fun onPreferenceChange_sameNewValue_doNoting() {
+        mockWifiEntry.stub {
+            on { privacy } doReturn 0
+            on { connectedState } doReturn WifiEntry.CONNECTED_STATE_CONNECTED
+        }
+
+        controller.onPreferenceChange(preference, "0")
+
+        verify(mockWifiEntry, never()).privacy = any()
+        verify(mockWifiEntry, never()).disconnect(null)
+        verify(mockWifiEntry, never()).connect(null)
+    }
+
+    @Test
+    fun onPreferenceChange_differentNewValue_setAndReconnect() {
+        mockWifiEntry.stub {
+            on { privacy } doReturn 0
+            on { connectedState } doReturn WifiEntry.CONNECTED_STATE_CONNECTED
+        }
+
+        controller.onPreferenceChange(preference, "1")
+
+        verify(mockWifiEntry).privacy = 1
+        verify(mockWifiEntry).disconnect(null)
+        verify(mockWifiEntry).connect(null)
+    }
+}
diff --git a/tests/unit/src/com/android/settings/applications/appcompat/UserAspectRatioManagerTest.java b/tests/unit/src/com/android/settings/applications/appcompat/UserAspectRatioManagerTest.java
index 61c4507..cf2a1f0 100644
--- a/tests/unit/src/com/android/settings/applications/appcompat/UserAspectRatioManagerTest.java
+++ b/tests/unit/src/com/android/settings/applications/appcompat/UserAspectRatioManagerTest.java
@@ -17,7 +17,6 @@
 package com.android.settings.applications.appcompat;
 
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
-import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
@@ -243,9 +242,6 @@
         assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_SPLIT_SCREEN,
                 mPackageName)).isEqualTo(ResourcesUtils.getResourcesString(mContext,
                         "user_aspect_ratio_half_screen"));
-        // R,string.user_aspect_ratio_4_3
-        assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_4_3, mPackageName))
-                .isEqualTo(ResourcesUtils.getResourcesString(mContext, "user_aspect_ratio_4_3"));
         assertThat(mUtils.getUserMinAspectRatioEntry(USER_MIN_ASPECT_RATIO_FULLSCREEN,
                 mPackageName)).isEqualTo(ResourcesUtils.getResourcesString(mContext,
                         "user_aspect_ratio_fullscreen"));
diff --git a/tests/unit/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest.java b/tests/unit/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest.java
index 4aa38ae..a402d91 100644
--- a/tests/unit/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest.java
+++ b/tests/unit/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest.java
@@ -24,6 +24,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
@@ -472,4 +474,27 @@
         SystemProperties.removeChangeCallback(propertyChangeSignal1.getCountDownJob());
         SystemProperties.removeChangeCallback(propertyChangeSignal2.getCountDownJob());
     }
+
+    @Test
+    public void updateState_DeveloperOptionPropertyIsFalse() {
+        // Test that when debug.graphics.angle.developeroption.enable is false:
+        when(mSystemPropertiesMock.getBoolean(eq(PROPERTY_DEBUG_ANGLE_DEVELOPER_OPTION),
+                                              anyBoolean())).thenReturn(false);
+        when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any()))
+                .thenReturn("true");
+
+        // 1. "Enable ANGLE" switch is on, the switch should be enabled.
+        when(mSystemPropertiesMock.get(eq(PROPERTY_PERSISTENT_GRAPHICS_EGL), any()))
+                .thenReturn(ANGLE_DRIVER_SUFFIX);
+        mController.updateState(mPreference);
+        assertTrue(mPreference.isChecked());
+        assertTrue(mPreference.isEnabled());
+
+        // 2. "Enable ANGLE" switch is off, the switch should be disabled.
+        when(mSystemPropertiesMock.get(eq(PROPERTY_PERSISTENT_GRAPHICS_EGL), any()))
+                .thenReturn("");
+        mController.updateState(mPreference);
+        assertFalse(mPreference.isChecked());
+        assertFalse(mPreference.isEnabled());
+    }
 }