Fix uninstalled app issue on battery usage page

Context: for uninstalled app, we cannot get the package UID, name and icon from the package manager, and the app would be shown as package name and default system icon in the page. For those unknown apps, we will put them into 'Uninstalled app' component for a quick fix.

Some lines are changed by auto format, and please ignore it. I will send out a follow up cl to format all battery files. It can improve the productivity if all team members are using the auto-format tool during the development.

Before: https://screenshot.googleplex.com/6zmFVgMxHGYMwqH
After: https://screenshot.googleplex.com/3cZwrhcE8zhDyfN

Test: manual
Bug: 264339271
Change-Id: I61a32675a31eefc8fdb1a408fbcebe9a2d6dcd68
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 2cd7806..b3efaed 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5557,8 +5557,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>
 
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/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);
     }