Merge "Support showing app usage list for two battery charts"
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java
index 2932984..45d145a 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java
@@ -79,7 +79,7 @@
     private static int sUiMode = Configuration.UI_MODE_NIGHT_UNDEFINED;
 
     @VisibleForTesting
-    Map<Integer, List<BatteryDiffEntry>> mBatteryIndexedMap;
+    Map<Integer, Map<Integer, BatteryDiffData>> mBatteryUsageMap;
 
     @VisibleForTesting
     Context mPrefContext;
@@ -112,7 +112,6 @@
     private final String mPreferenceKey;
     private final SettingsActivity mActivity;
     private final InstrumentedPreferenceFragment mFragment;
-    private final CharSequence[] mNotAllowShowEntryPackages;
     private final CharSequence[] mNotAllowShowSummaryPackages;
     private final MetricsFeatureProvider mMetricsFeatureProvider;
     private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -120,8 +119,6 @@
     // Preference cache to avoid create new instance each time.
     @VisibleForTesting
     final Map<String, Preference> mPreferenceCache = new HashMap<>();
-    @VisibleForTesting
-    final List<BatteryDiffEntry> mSystemEntries = new ArrayList<>();
 
     public BatteryChartPreferenceControllerV2(
             Context context, String preferenceKey,
@@ -134,10 +131,6 @@
         mIs24HourFormat = DateFormat.is24HourFormat(context);
         mMetricsFeatureProvider =
                 FeatureFactory.getFactory(mContext).getMetricsFeatureProvider();
-        mNotAllowShowEntryPackages =
-                FeatureFactory.getFactory(context)
-                        .getPowerUsageFeatureProvider(context)
-                        .getHideApplicationEntries(context);
         mNotAllowShowSummaryPackages =
                 FeatureFactory.getFactory(context)
                         .getPowerUsageFeatureProvider(context)
@@ -266,9 +259,12 @@
             final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
         Log.d(TAG, "setBatteryHistoryMap() " + (batteryHistoryMap == null ? "null"
                 : ("size=" + batteryHistoryMap.size())));
-        // TODO: implement the callback function.
         final BatteryLevelData batteryLevelData =
-                DataProcessor.getBatteryLevelData(mContext, mHandler, batteryHistoryMap, null);
+                DataProcessor.getBatteryLevelData(mContext, mHandler, batteryHistoryMap,
+                        batteryUsageMap -> {
+                            mBatteryUsageMap = batteryUsageMap;
+                            refreshUi();
+                        });
         Log.d(TAG, "getBatteryLevelData: " + batteryLevelData);
         if (batteryLevelData == null) {
             mDailyViewModel = null;
@@ -293,7 +289,6 @@
                     BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
         }
         refreshUi();
-        // TODO: Loads item icon and label and build mBatteryIndexedMap.
     }
 
     void setBatteryChartView(@NonNull final BatteryChartViewV2 dailyChartView,
@@ -335,7 +330,7 @@
 
     @VisibleForTesting
     boolean refreshUi() {
-        if (mBatteryIndexedMap == null || mDailyChartView == null || mHourlyChartView == null) {
+        if (mBatteryUsageMap == null || mDailyChartView == null || mHourlyChartView == null) {
             return false;
         }
 
@@ -378,45 +373,22 @@
     }
 
     private void addAllPreferences() {
-        // TODO: Get the right diff entry according to daily and hourly chart selection.
-        final int index = mDailyChartIndex;
-        final List<BatteryDiffEntry> entries =
-                mBatteryIndexedMap.get(Integer.valueOf(index));
-        addFooterPreferenceIfNeeded(entries != null && !entries.isEmpty());
-        if (entries == null) {
-            Log.w(TAG, "cannot find BatteryDiffEntry for:" + index);
+        final BatteryDiffData batteryDiffData =
+                mBatteryUsageMap.get(mDailyChartIndex).get(mHourlyChartIndex);
+        addFooterPreferenceIfNeeded(batteryDiffData != null
+                && (!batteryDiffData.getAppDiffEntryList().isEmpty()
+                || !batteryDiffData.getSystemDiffEntryList().isEmpty()));
+        if (batteryDiffData == null) {
+            Log.w(TAG, "cannot find BatteryDiffEntry for daily_index: " + mDailyChartIndex
+                    + " hourly_index: " + mHourlyChartIndex);
             return;
         }
-        // Separates data into two groups and sort them individually.
-        final List<BatteryDiffEntry> appEntries = new ArrayList<>();
-        mSystemEntries.clear();
-        entries.forEach(entry -> {
-            final String packageName = entry.getPackageName();
-            if (!isValidToShowEntry(packageName)) {
-                Log.w(TAG, "ignore showing item:" + packageName);
-                return;
-            }
-            if (entry.isSystemEntry()) {
-                mSystemEntries.add(entry);
-            } else {
-                appEntries.add(entry);
-            }
-            // Validates the usage time if users click a specific slot.
-            if (index >= 0) {
-                validateUsageTime(entry);
-            }
-        });
-        Collections.sort(appEntries, BatteryDiffEntry.COMPARATOR);
-        Collections.sort(mSystemEntries, BatteryDiffEntry.COMPARATOR);
-        Log.d(TAG, String.format("addAllPreferences() app=%d system=%d",
-                appEntries.size(), mSystemEntries.size()));
-
         // Adds app entries to the list if it is not empty.
-        if (!appEntries.isEmpty()) {
-            addPreferenceToScreen(appEntries);
+        if (!batteryDiffData.getAppDiffEntryList().isEmpty()) {
+            addPreferenceToScreen(batteryDiffData.getAppDiffEntryList());
         }
         // Adds the expabable divider if we have system entries data.
-        if (!mSystemEntries.isEmpty()) {
+        if (!batteryDiffData.getSystemDiffEntryList().isEmpty()) {
             if (mExpandDividerPreference == null) {
                 mExpandDividerPreference = new ExpandDividerPreference(mPrefContext);
                 mExpandDividerPreference.setOnExpandListener(this);
@@ -490,11 +462,13 @@
     }
 
     private void refreshExpandUi() {
+        final List<BatteryDiffEntry> systemEntries = mBatteryUsageMap.get(mDailyChartIndex).get(
+                mHourlyChartIndex).getSystemDiffEntryList();
         if (mIsExpanded) {
-            addPreferenceToScreen(mSystemEntries);
+            addPreferenceToScreen(systemEntries);
         } else {
             // Removes and recycles all system entries to hide all of them.
-            for (BatteryDiffEntry entry : mSystemEntries) {
+            for (BatteryDiffEntry entry : systemEntries) {
                 final String prefKey = entry.mBatteryHistEntry.getKey();
                 final Preference pref = mAppListPrefGroup.findPreference(prefKey);
                 if (pref != null) {
@@ -592,11 +566,6 @@
         return !contains(packageName, mNotAllowShowSummaryPackages);
     }
 
-    @VisibleForTesting
-    boolean isValidToShowEntry(String packageName) {
-        return !contains(packageName, mNotAllowShowEntryPackages);
-    }
-
     private void addFooterPreferenceIfNeeded(boolean containAppItems) {
         if (mIsFooterPrefAdded || mFooterPreference == null) {
             return;
@@ -643,20 +612,6 @@
         return false;
     }
 
-    @VisibleForTesting
-    static boolean validateUsageTime(BatteryDiffEntry entry) {
-        final long foregroundUsageTimeInMs = entry.mForegroundUsageTimeInMs;
-        final long backgroundUsageTimeInMs = entry.mBackgroundUsageTimeInMs;
-        final long totalUsageTimeInMs = foregroundUsageTimeInMs + backgroundUsageTimeInMs;
-        if (foregroundUsageTimeInMs > VALID_USAGE_TIME_DURATION
-                || backgroundUsageTimeInMs > VALID_USAGE_TIME_DURATION
-                || totalUsageTimeInMs > VALID_USAGE_TIME_DURATION) {
-            Log.e(TAG, "validateUsageTime() fail for\n" + entry);
-            return false;
-        }
-        return true;
-    }
-
     // TODO: Change this method to fromLastFullCharged.
 
     /** Used for {@link AppBatteryPreferenceController}. */
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java
index a5f193b..16e0459 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2Test.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -168,13 +169,10 @@
 
     @Test
     public void setBatteryChartViewModel_6Hours() {
-        // TODO: Removes the following line after loading mBatteryIndexedMap is supported.
-        mBatteryChartPreferenceController.mBatteryIndexedMap = new HashMap<>();
-
         mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(6));
 
-        verify(mDailyChartView).setVisibility(View.GONE);
-        verify(mHourlyChartView).setVisibility(View.VISIBLE);
+        verify(mDailyChartView, atLeastOnce()).setVisibility(View.GONE);
+        verify(mHourlyChartView, atLeastOnce()).setVisibility(View.VISIBLE);
         verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
                 List.of(100, 97, 95),
                 List.of("8 am", "10 am", "12 pm"),
@@ -184,13 +182,10 @@
 
     @Test
     public void setBatteryChartViewModel_60Hours() {
-        // TODO: Removes the following line after loading mBatteryIndexedMap is supported.
-        mBatteryChartPreferenceController.mBatteryIndexedMap = new HashMap<>();
-
         mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(60));
 
-        verify(mDailyChartView).setVisibility(View.VISIBLE);
-        verify(mHourlyChartView).setVisibility(View.GONE);
+        verify(mDailyChartView, atLeastOnce()).setVisibility(View.VISIBLE);
+        verify(mHourlyChartView, atLeastOnce()).setVisibility(View.GONE);
         verify(mDailyChartView).setViewModel(new BatteryChartViewModel(
                 List.of(100, 83, 59, 41),
                 List.of("SAT", "SUN", "MON", "MON"),
@@ -256,6 +251,12 @@
     }
 
     @Test
+    public void refreshUi_normalCase_returnTrue() {
+        mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(6));
+        assertThat(mBatteryChartPreferenceController.refreshUi()).isTrue();
+    }
+
+    @Test
     public void refreshUi_batteryIndexedMapIsNull_ignoreRefresh() {
         mBatteryChartPreferenceController.setBatteryHistoryMap(null);
         assertThat(mBatteryChartPreferenceController.refreshUi()).isFalse();
@@ -275,7 +276,8 @@
 
     @Test
     public void removeAndCacheAllPrefs_emptyContent_ignoreRemoveAll() {
-        mBatteryChartPreferenceController.mHourlyChartIndex = 1;
+        mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(6));
+        mBatteryChartPreferenceController.mBatteryUsageMap = createBatteryUsageMap();
         doReturn(0).when(mAppListGroup).getPreferenceCount();
 
         mBatteryChartPreferenceController.refreshUi();
@@ -283,6 +285,25 @@
     }
 
     @Test
+    public void removeAndCacheAllPrefs_buildCacheAndRemoveAllPreference() {
+        mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(6));
+        mBatteryChartPreferenceController.mBatteryUsageMap = createBatteryUsageMap();
+        doReturn(1).when(mAppListGroup).getPreferenceCount();
+        doReturn(mPowerGaugePreference).when(mAppListGroup).getPreference(0);
+        doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
+        doReturn(PREF_KEY).when(mPowerGaugePreference).getKey();
+        doReturn(mPowerGaugePreference).when(mAppListGroup).findPreference(PREF_KEY);
+        // Ensures the testing data is correct.
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
+
+        mBatteryChartPreferenceController.refreshUi();
+
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache.get(PREF_KEY))
+                .isEqualTo(mPowerGaugePreference);
+        verify(mAppListGroup).removeAll();
+    }
+
+    @Test
     public void addPreferenceToScreen_emptyContent_ignoreAddPreference() {
         mBatteryChartPreferenceController.addPreferenceToScreen(
                 new ArrayList<BatteryDiffEntry>());
@@ -454,36 +475,9 @@
     }
 
     @Test
-    public void validateUsageTime_returnTrueIfBatteryDiffEntryIsValid() {
-        assertThat(BatteryChartPreferenceControllerV2.validateUsageTime(
-                createBatteryDiffEntry(
-                        /*foregroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS,
-                        /*backgroundUsageTimeInMs=*/ DateUtils.MINUTE_IN_MILLIS)))
-                .isTrue();
-    }
-
-    @Test
-    public void validateUsageTime_foregroundTimeExceedThreshold_returnFalse() {
-        assertThat(BatteryChartPreferenceControllerV2.validateUsageTime(
-                createBatteryDiffEntry(
-                        /*foregroundUsageTimeInMs=*/ DateUtils.HOUR_IN_MILLIS * 3,
-                        /*backgroundUsageTimeInMs=*/ 0)))
-                .isFalse();
-    }
-
-    @Test
-    public void validateUsageTime_backgroundTimeExceedThreshold_returnFalse() {
-        assertThat(BatteryChartPreferenceControllerV2.validateUsageTime(
-                createBatteryDiffEntry(
-                        /*foregroundUsageTimeInMs=*/ 0,
-                        /*backgroundUsageTimeInMs=*/ DateUtils.HOUR_IN_MILLIS * 3)))
-                .isFalse();
-    }
-
-    @Test
     public void onExpand_expandedIsTrue_addSystemEntriesToPreferenceGroup() {
         doReturn(1).when(mAppListGroup).getPreferenceCount();
-        mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry);
+        mBatteryChartPreferenceController.mBatteryUsageMap = createBatteryUsageMap();
         doReturn("label").when(mBatteryDiffEntry).getAppLabel();
         doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
         doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
@@ -505,7 +499,7 @@
     public void onExpand_expandedIsFalse_removeSystemEntriesFromPreferenceGroup() {
         doReturn(PREF_KEY).when(mBatteryHistEntry).getKey();
         doReturn(mPowerGaugePreference).when(mAppListGroup).findPreference(PREF_KEY);
-        mBatteryChartPreferenceController.mSystemEntries.add(mBatteryDiffEntry);
+        mBatteryChartPreferenceController.mBatteryUsageMap = createBatteryUsageMap();
         // Verifies the cache is empty first.
         assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
 
@@ -580,18 +574,6 @@
                 .isFalse();
     }
 
-    @Test
-    public void isValidToShowEntry_returnExpectedResult() {
-        assertThat(mBatteryChartPreferenceController
-                .isValidToShowEntry("com.google.android.apps.scone"))
-                .isTrue();
-
-        // Verifies the items which are defined in the array list.
-        assertThat(mBatteryChartPreferenceController
-                .isValidToShowEntry("com.android.gms.persistent"))
-                .isFalse();
-    }
-
     private static Long generateTimestamp(int index) {
         // "2021-04-23 07:00:00 UTC" + index hours
         return 1619247600000L + index * DateUtils.HOUR_IN_MILLIS;
@@ -603,6 +585,7 @@
         for (int index = 0; index < numOfHours; index++) {
             final ContentValues values = new ContentValues();
             values.put("batteryLevel", Integer.valueOf(100 - index));
+            values.put("consumePower", Integer.valueOf(100 - index));
             final BatteryHistEntry entry = new BatteryHistEntry(values);
             final Map<String, BatteryHistEntry> entryMap = new HashMap<>();
             entryMap.put("fake_entry_key" + index, entry);
@@ -611,6 +594,22 @@
         return batteryHistoryMap;
     }
 
+    private Map<Integer, Map<Integer, BatteryDiffData>> createBatteryUsageMap() {
+        final int selectedAll = BatteryChartViewModel.SELECTED_INDEX_ALL;
+        return Map.of(
+                selectedAll, Map.of(
+                        selectedAll, new BatteryDiffData(
+                                Arrays.asList(mBatteryDiffEntry),
+                                Arrays.asList(mBatteryDiffEntry))),
+                0, Map.of(
+                        selectedAll, new BatteryDiffData(
+                                Arrays.asList(mBatteryDiffEntry),
+                                Arrays.asList(mBatteryDiffEntry)),
+                        0, new BatteryDiffData(
+                                Arrays.asList(mBatteryDiffEntry),
+                                Arrays.asList(mBatteryDiffEntry))));
+    }
+
     private BatteryDiffEntry createBatteryDiffEntry(
             long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) {
         return new BatteryDiffEntry(