From ba6c435eff014fd596b067603d3dc7014210568b Mon Sep 17 00:00:00 2001 From: Zaiyue Xue Date: Thu, 28 Jul 2022 11:55:24 +0800 Subject: [PATCH] Support showing app usage list for two battery charts Test: manual Bug: 236101166 Change-Id: I29b4615bd5a967bcfd0a4ab378fec4e700dfc7f0 --- .../BatteryChartPreferenceControllerV2.java | 89 ++++----------- ...atteryChartPreferenceControllerV2Test.java | 103 +++++++++--------- 2 files changed, 73 insertions(+), 119 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java index 2932984b550..45d145ab0de 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceControllerV2.java @@ -79,7 +79,7 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro private static int sUiMode = Configuration.UI_MODE_NIGHT_UNDEFINED; @VisibleForTesting - Map> mBatteryIndexedMap; + Map> mBatteryUsageMap; @VisibleForTesting Context mPrefContext; @@ -112,7 +112,6 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro 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 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro // Preference cache to avoid create new instance each time. @VisibleForTesting final Map mPreferenceCache = new HashMap<>(); - @VisibleForTesting - final List mSystemEntries = new ArrayList<>(); public BatteryChartPreferenceControllerV2( Context context, String preferenceKey, @@ -134,10 +131,6 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro 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 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro final Map> 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 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS)); } refreshUi(); - // TODO: Loads item icon and label and build mBatteryIndexedMap. } void setBatteryChartView(@NonNull final BatteryChartViewV2 dailyChartView, @@ -335,7 +330,7 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro @VisibleForTesting boolean refreshUi() { - if (mBatteryIndexedMap == null || mDailyChartView == null || mHourlyChartView == null) { + if (mBatteryUsageMap == null || mDailyChartView == null || mHourlyChartView == null) { return false; } @@ -378,45 +373,22 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro } private void addAllPreferences() { - // TODO: Get the right diff entry according to daily and hourly chart selection. - final int index = mDailyChartIndex; - final List 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 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 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro } private void refreshExpandUi() { + final List 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 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro 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 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro 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 a5f193be41d..16e04599c43 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 @@ package com.android.settings.fuelgauge.batteryusage; 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 @@ public final class BatteryChartPreferenceControllerV2Test { @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 @@ public final class BatteryChartPreferenceControllerV2Test { @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"), @@ -255,6 +250,12 @@ public final class BatteryChartPreferenceControllerV2Test { BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS)); } + @Test + public void refreshUi_normalCase_returnTrue() { + mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(6)); + assertThat(mBatteryChartPreferenceController.refreshUi()).isTrue(); + } + @Test public void refreshUi_batteryIndexedMapIsNull_ignoreRefresh() { mBatteryChartPreferenceController.setBatteryHistoryMap(null); @@ -275,13 +276,33 @@ public final class BatteryChartPreferenceControllerV2Test { @Test public void removeAndCacheAllPrefs_emptyContent_ignoreRemoveAll() { - mBatteryChartPreferenceController.mHourlyChartIndex = 1; + mBatteryChartPreferenceController.setBatteryHistoryMap(createBatteryHistoryMap(6)); + mBatteryChartPreferenceController.mBatteryUsageMap = createBatteryUsageMap(); doReturn(0).when(mAppListGroup).getPreferenceCount(); mBatteryChartPreferenceController.refreshUi(); verify(mAppListGroup, never()).removeAll(); } + @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( @@ -453,37 +474,10 @@ public final class BatteryChartPreferenceControllerV2Test { assertThat(pref.getSummary()).isNull(); } - @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 final class BatteryChartPreferenceControllerV2Test { 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 @@ public final class BatteryChartPreferenceControllerV2Test { .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 @@ public final class BatteryChartPreferenceControllerV2Test { 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 entryMap = new HashMap<>(); entryMap.put("fake_entry_key" + index, entry); @@ -611,6 +594,22 @@ public final class BatteryChartPreferenceControllerV2Test { return batteryHistoryMap; } + private Map> 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(