Refactor processBatteryDiffData() from DataProcessor to BatteryDiffData class.

So that only hourly battery diff data needs purgeFakeAndHiddenPackages()
and combineBatteryDiffEntry(). This is also easy to set hourly threshold
in the next cl.

Bug: 264840285
Test: manual
Change-Id: Ie0bc6d53f96285285019dd83c1f39305eca79c71
This commit is contained in:
Zaiyue Xue
2023-01-09 17:04:57 +08:00
parent 7f3ff17bcf
commit f080429ddb
6 changed files with 387 additions and 276 deletions

View File

@@ -16,10 +16,20 @@
package com.android.settings.fuelgauge.batteryusage;
import android.app.Application;
import android.content.Context;
import androidx.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/** Wraps the battery usage diff data for each entry used for battery usage app list. */
public class BatteryDiffData {
@@ -28,10 +38,22 @@ public class BatteryDiffData {
/** Constructor for the diff entries. */
public BatteryDiffData(
@NonNull List<BatteryDiffEntry> appDiffEntries,
@NonNull List<BatteryDiffEntry> systemDiffEntries) {
final Context context,
final @NonNull List<BatteryDiffEntry> appDiffEntries,
final @NonNull List<BatteryDiffEntry> systemDiffEntries,
final boolean isAccumulated) {
mAppEntries = appDiffEntries;
mSystemEntries = systemDiffEntries;
if (!isAccumulated) {
final PowerUsageFeatureProvider featureProvider =
FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context);
purgeFakeAndHiddenPackages(featureProvider);
combineBatteryDiffEntry(context, featureProvider);
}
setTotalConsumePower();
sortEntries();
}
public List<BatteryDiffEntry> getAppDiffEntryList() {
@@ -42,20 +64,111 @@ public class BatteryDiffData {
return mSystemEntries;
}
// Sorts entries based on consumed percentage.
void sortEntries() {
Collections.sort(mAppEntries, BatteryDiffEntry.COMPARATOR);
Collections.sort(mSystemEntries, BatteryDiffEntry.COMPARATOR);
/** Removes fake usage data and hidden packages. */
private void purgeFakeAndHiddenPackages(final PowerUsageFeatureProvider featureProvider) {
purgeFakeAndHiddenPackages(featureProvider, mAppEntries);
purgeFakeAndHiddenPackages(featureProvider, mSystemEntries);
}
// Sets total consume power for app and system entries separately.
void setTotalConsumePower() {
/** Combines into SystemAppsBatteryDiffEntry and OthersBatteryDiffEntry. */
private void combineBatteryDiffEntry(
final Context context, final PowerUsageFeatureProvider featureProvider) {
combineIntoSystemApps(context, featureProvider, mAppEntries);
combineSystemItemsIntoOthers(context, featureProvider, mSystemEntries);
}
/** Sets total consume power for app and system entries separately. */
private void setTotalConsumePower() {
setTotalConsumePowerForAllEntries(mAppEntries);
setTotalConsumePowerForAllEntries(mSystemEntries);
}
/** Sorts entries based on consumed percentage. */
private void sortEntries() {
Collections.sort(mAppEntries, BatteryDiffEntry.COMPARATOR);
Collections.sort(mSystemEntries, BatteryDiffEntry.COMPARATOR);
}
private static void purgeFakeAndHiddenPackages(
final PowerUsageFeatureProvider featureProvider,
final List<BatteryDiffEntry> entries) {
final Set<Integer> hideSystemComponentSet = featureProvider.getHideSystemComponentSet();
final Set<String> hideBackgroundUsageTimeSet =
featureProvider.getHideBackgroundUsageTimeSet();
final Set<String> hideApplicationSet = featureProvider.getHideApplicationSet();
final Iterator<BatteryDiffEntry> iterator = entries.iterator();
while (iterator.hasNext()) {
final BatteryDiffEntry entry = iterator.next();
final String packageName = entry.getPackageName();
final Integer componentId = entry.mBatteryHistEntry.mDrainType;
if (ConvertUtils.FAKE_PACKAGE_NAME.equals(packageName)
|| hideSystemComponentSet.contains(componentId)
|| (packageName != null && hideApplicationSet.contains(packageName))) {
iterator.remove();
}
if (packageName != null && hideBackgroundUsageTimeSet.contains(packageName)) {
entry.mBackgroundUsageTimeInMs = 0;
}
}
}
private static void combineIntoSystemApps(
final Context context,
final PowerUsageFeatureProvider featureProvider,
final List<BatteryDiffEntry> appEntries) {
final List<String> systemAppsAllowlist = featureProvider.getSystemAppsAllowlist();
final Application application = (Application) context.getApplicationContext();
final ApplicationsState applicationsState =
application == null ? null : ApplicationsState.getInstance(application);
BatteryDiffEntry.SystemAppsBatteryDiffEntry systemAppsDiffEntry = null;
final Iterator<BatteryDiffEntry> appListIterator = appEntries.iterator();
while (appListIterator.hasNext()) {
final BatteryDiffEntry batteryDiffEntry = appListIterator.next();
if (needsCombineInSystemApp(batteryDiffEntry, systemAppsAllowlist, applicationsState)) {
if (systemAppsDiffEntry == null) {
systemAppsDiffEntry = new BatteryDiffEntry.SystemAppsBatteryDiffEntry(context);
}
systemAppsDiffEntry.mConsumePower += batteryDiffEntry.mConsumePower;
systemAppsDiffEntry.mForegroundUsageTimeInMs +=
batteryDiffEntry.mForegroundUsageTimeInMs;
systemAppsDiffEntry.setTotalConsumePower(
batteryDiffEntry.getTotalConsumePower());
appListIterator.remove();
}
}
if (systemAppsDiffEntry != null) {
appEntries.add(systemAppsDiffEntry);
}
}
private static void combineSystemItemsIntoOthers(
final Context context,
final PowerUsageFeatureProvider featureProvider,
final List<BatteryDiffEntry> systemEntries) {
final Set<Integer> othersSystemComponentSet = featureProvider.getOthersSystemComponentSet();
BatteryDiffEntry.OthersBatteryDiffEntry othersDiffEntry = null;
final Iterator<BatteryDiffEntry> systemListIterator = systemEntries.iterator();
while (systemListIterator.hasNext()) {
final BatteryDiffEntry batteryDiffEntry = systemListIterator.next();
if (othersSystemComponentSet.contains(batteryDiffEntry.mBatteryHistEntry.mDrainType)) {
if (othersDiffEntry == null) {
othersDiffEntry = new BatteryDiffEntry.OthersBatteryDiffEntry(context);
}
othersDiffEntry.mConsumePower += batteryDiffEntry.mConsumePower;
othersDiffEntry.setTotalConsumePower(
batteryDiffEntry.getTotalConsumePower());
systemListIterator.remove();
}
}
if (othersDiffEntry != null) {
systemEntries.add(othersDiffEntry);
}
}
// Sets total consume power for each entry.
private void setTotalConsumePowerForAllEntries(List<BatteryDiffEntry> batteryDiffEntries) {
private static void setTotalConsumePowerForAllEntries(
final List<BatteryDiffEntry> batteryDiffEntries) {
double totalConsumePower = 0.0;
for (BatteryDiffEntry batteryDiffEntry : batteryDiffEntries) {
totalConsumePower += batteryDiffEntry.mConsumePower;
@@ -64,4 +177,32 @@ public class BatteryDiffData {
batteryDiffEntry.setTotalConsumePower(totalConsumePower);
}
}
@VisibleForTesting
static boolean needsCombineInSystemApp(final BatteryDiffEntry batteryDiffEntry,
final List<String> systemAppsAllowlist, final ApplicationsState applicationsState) {
if (batteryDiffEntry.mBatteryHistEntry.mIsHidden) {
return true;
}
final String packageName = batteryDiffEntry.getPackageName();
if (packageName == null || packageName.isEmpty()) {
return false;
}
if (systemAppsAllowlist != null && systemAppsAllowlist.contains(packageName)) {
return true;
}
if (applicationsState == null) {
return false;
}
final ApplicationsState.AppEntry appEntry =
applicationsState.getEntry(packageName, /* userId= */ 0);
if (appEntry == null || appEntry.info == null) {
return false;
}
return !ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER_AND_INSTANT.filterApp(
appEntry);
}
}

View File

@@ -49,7 +49,7 @@ public class BatteryDiffEntry {
/** A comparator for {@link BatteryDiffEntry} based on consumed percentage. */
public static final Comparator<BatteryDiffEntry> COMPARATOR =
(a, b) -> Double.compare(b.getPercentOfTotal(), a.getPercentOfTotal());
(a, b) -> Double.compare(b.getSortingKey(), a.getSortingKey());
public long mForegroundUsageTimeInMs;
public long mBackgroundUsageTimeInMs;
@@ -121,6 +121,11 @@ public class BatteryDiffEntry {
return mPercentOfTotal;
}
/** Gets the key for sorting */
public double getSortingKey() {
return getPercentOfTotal();
}
/** Clones a new instance. */
public BatteryDiffEntry clone() {
return new BatteryDiffEntry(
@@ -265,7 +270,6 @@ public class BatteryDiffEntry {
}
}
@VisibleForTesting
String getKey() {
return mBatteryHistEntry.getKey();
}
@@ -434,6 +438,26 @@ public class BatteryDiffEntry {
public boolean isSystemEntry() {
return false;
}
@Override
public double getSortingKey() {
// Always on the bottom of the app list.
return -1;
}
@Override
public BatteryDiffEntry clone() {
SystemAppsBatteryDiffEntry newEntry = new SystemAppsBatteryDiffEntry(this.mContext);
newEntry.mForegroundUsageTimeInMs = this.mForegroundUsageTimeInMs;
newEntry.mBackgroundUsageTimeInMs = this.mBackgroundUsageTimeInMs;
newEntry.mScreenOnTimeInMs = this.mScreenOnTimeInMs;
newEntry.mConsumePower = this.mConsumePower;
newEntry.mForegroundUsageConsumePower = this.mForegroundUsageConsumePower;
newEntry.mForegroundServiceUsageConsumePower = this.mForegroundServiceUsageConsumePower;
newEntry.mBackgroundUsageConsumePower = this.mBackgroundUsageConsumePower;
newEntry.mCachedUsageConsumePower = this.mCachedUsageConsumePower;
return newEntry;
}
}
/** Specific battery diff entry for others. */
@@ -475,5 +499,25 @@ public class BatteryDiffEntry {
public boolean isSystemEntry() {
return true;
}
@Override
public double getSortingKey() {
// Always on the bottom of the system list.
return -1;
}
@Override
public BatteryDiffEntry clone() {
OthersBatteryDiffEntry newEntry = new OthersBatteryDiffEntry(this.mContext);
newEntry.mForegroundUsageTimeInMs = this.mForegroundUsageTimeInMs;
newEntry.mBackgroundUsageTimeInMs = this.mBackgroundUsageTimeInMs;
newEntry.mScreenOnTimeInMs = this.mScreenOnTimeInMs;
newEntry.mConsumePower = this.mConsumePower;
newEntry.mForegroundUsageConsumePower = this.mForegroundUsageConsumePower;
newEntry.mForegroundServiceUsageConsumePower = this.mForegroundServiceUsageConsumePower;
newEntry.mBackgroundUsageConsumePower = this.mBackgroundUsageConsumePower;
newEntry.mCachedUsageConsumePower = this.mCachedUsageConsumePower;
return newEntry;
}
}
}

View File

@@ -19,7 +19,6 @@ package com.android.settings.fuelgauge.batteryusage;
import static com.android.settings.fuelgauge.batteryusage.ConvertUtils.getEffectivePackageName;
import static com.android.settings.fuelgauge.batteryusage.ConvertUtils.utcToLocalTime;
import android.app.Application;
import android.app.usage.IUsageStatsManager;
import android.app.usage.UsageEvents;
import android.app.usage.UsageEvents.Event;
@@ -53,7 +52,6 @@ import com.android.internal.os.PowerProfile;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.fuelgauge.BatteryStatus;
import java.time.Duration;
@@ -63,7 +61,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -645,10 +642,9 @@ public final class DataProcessor {
context, hourlyBatteryLevelsPerDay, batteryHistoryMap, appUsagePeriodMap,
resultMap);
// Insert diff data from [0][SELECTED_INDEX_ALL] to [maxDailyIndex][SELECTED_INDEX_ALL].
insertDailyUsageDiffData(hourlyBatteryLevelsPerDay, resultMap);
insertDailyUsageDiffData(context, hourlyBatteryLevelsPerDay, resultMap);
// Insert diff data [SELECTED_INDEX_ALL][SELECTED_INDEX_ALL].
insertAllUsageDiffData(resultMap);
processBatteryDiffData(context, resultMap);
insertAllUsageDiffData(context, resultMap);
if (!isUsageMapValid(resultMap, hourlyBatteryLevelsPerDay)) {
return null;
}
@@ -703,7 +699,7 @@ public final class DataProcessor {
return null;
}
return new BatteryDiffData(appEntries, systemEntries);
return new BatteryDiffData(context, appEntries, systemEntries, /* isAccumulated= */ false);
}
/**
@@ -866,7 +862,6 @@ public final class DataProcessor {
allUsageMap.put(SELECTED_INDEX_ALL,
generateBatteryDiffData(context, getBatteryHistListFromFromStatsService(context)));
resultMap.put(SELECTED_INDEX_ALL, allUsageMap);
processBatteryDiffData(context, resultMap);
return resultMap;
}
@@ -1389,6 +1384,7 @@ public final class DataProcessor {
}
private static void insertDailyUsageDiffData(
final Context context,
final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay,
final Map<Integer, Map<Integer, BatteryDiffData>> resultMap) {
for (int index = 0; index < hourlyBatteryLevelsPerDay.size(); index++) {
@@ -1399,23 +1395,24 @@ public final class DataProcessor {
}
dailyUsageMap.put(
SELECTED_INDEX_ALL,
getAccumulatedUsageDiffData(dailyUsageMap.values()));
getAccumulatedUsageDiffData(context, dailyUsageMap.values()));
}
}
private static void insertAllUsageDiffData(
final Context context,
final Map<Integer, Map<Integer, BatteryDiffData>> resultMap) {
final List<BatteryDiffData> diffDataList = new ArrayList<>();
resultMap.keySet().forEach(
key -> diffDataList.add(resultMap.get(key).get(SELECTED_INDEX_ALL)));
final Map<Integer, BatteryDiffData> allUsageMap = new HashMap<>();
allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedUsageDiffData(diffDataList));
allUsageMap.put(SELECTED_INDEX_ALL, getAccumulatedUsageDiffData(context, diffDataList));
resultMap.put(SELECTED_INDEX_ALL, allUsageMap);
}
@Nullable
private static BatteryDiffData insertHourlyUsageDiffDataPerSlot(
Context context,
final Context context,
final int currentUserId,
final int workProfileUserId,
final int currentIndex,
@@ -1570,7 +1567,7 @@ public final class DataProcessor {
return null;
}
return new BatteryDiffData(appEntries, systemEntries);
return new BatteryDiffData(context, appEntries, systemEntries, /* isAccumulated= */ false);
}
private static long getScreenOnTime(@Nullable final List<AppUsagePeriod> appUsagePeriodList) {
@@ -1627,7 +1624,7 @@ public final class DataProcessor {
@Nullable
private static BatteryDiffData getAccumulatedUsageDiffData(
final Collection<BatteryDiffData> diffEntryListData) {
final Context context, final Collection<BatteryDiffData> diffEntryListData) {
final Map<String, BatteryDiffEntry> diffEntryMap = new HashMap<>();
final List<BatteryDiffEntry> appEntries = new ArrayList<>();
final List<BatteryDiffEntry> systemEntries = new ArrayList<>();
@@ -1653,13 +1650,14 @@ public final class DataProcessor {
}
}
return diffEntryList.isEmpty() ? null : new BatteryDiffData(appEntries, systemEntries);
return diffEntryList.isEmpty() ? null : new BatteryDiffData(
context, appEntries, systemEntries, /* isAccumulated= */ true);
}
private static void computeUsageDiffDataPerEntry(
final BatteryDiffEntry entry,
final Map<String, BatteryDiffEntry> diffEntryMap) {
final String key = entry.mBatteryHistEntry.getKey();
final String key = entry.getKey();
final BatteryDiffEntry oldBatteryDiffEntry = diffEntryMap.get(key);
// Creates new BatteryDiffEntry if we don't have it.
if (oldBatteryDiffEntry == null) {
@@ -1681,157 +1679,6 @@ public final class DataProcessor {
}
}
// Process every battery diff data in the battery usage result map.
// (1) Removes low percentage data and fake usage data, which will be zero value.
// (2) Sets total consume power, so the usage percentage is updated.
// (3) Sorts the result.
private static void processBatteryDiffData(
final Context context,
final Map<Integer, Map<Integer, BatteryDiffData>> resultMap) {
final Set<Integer> hideSystemComponentSet =
FeatureFactory.getFactory(context)
.getPowerUsageFeatureProvider(context)
.getHideSystemComponentSet();
final Set<String> hideBackgroundUsageTimeSet =
FeatureFactory.getFactory(context)
.getPowerUsageFeatureProvider(context)
.getHideBackgroundUsageTimeSet();
final Set<String> hideApplicationSet =
FeatureFactory.getFactory(context)
.getPowerUsageFeatureProvider(context)
.getHideApplicationSet();
resultMap.keySet().forEach(dailyKey -> {
final Map<Integer, BatteryDiffData> dailyUsageMap = resultMap.get(dailyKey);
dailyUsageMap.values().forEach(batteryDiffData -> {
if (batteryDiffData == null) {
return;
}
purgeFakeAndHiddenPackages(
batteryDiffData.getAppDiffEntryList(),
hideSystemComponentSet,
hideApplicationSet,
hideBackgroundUsageTimeSet);
purgeFakeAndHiddenPackages(
batteryDiffData.getSystemDiffEntryList(),
hideSystemComponentSet,
hideApplicationSet,
hideBackgroundUsageTimeSet);
batteryDiffData.setTotalConsumePower();
batteryDiffData.sortEntries();
combineIntoSystemApps(context, batteryDiffData);
combineSystemItemsIntoOthers(context, batteryDiffData);
});
});
}
private static void purgeFakeAndHiddenPackages(
final List<BatteryDiffEntry> entries,
final Set<Integer> hideSystemComponentSet,
final Set<String> hideApplicationSet,
final Set<String> hideBackgroundUsageTimeSet) {
final Iterator<BatteryDiffEntry> iterator = entries.iterator();
while (iterator.hasNext()) {
final BatteryDiffEntry entry = iterator.next();
final String packageName = entry.getPackageName();
final Integer componentId = entry.mBatteryHistEntry.mDrainType;
if (ConvertUtils.FAKE_PACKAGE_NAME.equals(packageName)
|| hideSystemComponentSet.contains(componentId)
|| hideApplicationSet.contains(packageName)) {
iterator.remove();
}
if (hideBackgroundUsageTimeSet.contains(packageName)) {
entry.mBackgroundUsageTimeInMs = 0;
}
}
}
private static void combineSystemItemsIntoOthers(
final Context context, final BatteryDiffData batteryDiffData) {
final Set<Integer> othersSystemComponentSet =
FeatureFactory.getFactory(context)
.getPowerUsageFeatureProvider(context)
.getOthersSystemComponentSet();
BatteryDiffEntry.OthersBatteryDiffEntry othersDiffEntry = null;
final Iterator<BatteryDiffEntry> systemListIterator =
batteryDiffData.getSystemDiffEntryList().iterator();
while (systemListIterator.hasNext()) {
final BatteryDiffEntry batteryDiffEntry = systemListIterator.next();
if (othersSystemComponentSet.contains(batteryDiffEntry.mBatteryHistEntry.mDrainType)) {
if (othersDiffEntry == null) {
othersDiffEntry = new BatteryDiffEntry.OthersBatteryDiffEntry(context);
}
othersDiffEntry.mConsumePower += batteryDiffEntry.mConsumePower;
othersDiffEntry.setTotalConsumePower(
batteryDiffEntry.getTotalConsumePower());
systemListIterator.remove();
}
}
if (othersDiffEntry != null) {
batteryDiffData.getSystemDiffEntryList().add(othersDiffEntry);
}
}
private static void combineIntoSystemApps(
final Context context, final BatteryDiffData batteryDiffData) {
final List<String> systemAppsAllowlist =
FeatureFactory.getFactory(context)
.getPowerUsageFeatureProvider(context)
.getSystemAppsAllowlist();
final Application application = (Application) context.getApplicationContext();
final ApplicationsState applicationsState =
application == null ? null : ApplicationsState.getInstance(application);
BatteryDiffEntry.SystemAppsBatteryDiffEntry systemAppsDiffEntry = null;
final Iterator<BatteryDiffEntry> appListIterator =
batteryDiffData.getAppDiffEntryList().iterator();
while (appListIterator.hasNext()) {
final BatteryDiffEntry batteryDiffEntry = appListIterator.next();
if (needsCombineInSystemApp(batteryDiffEntry, systemAppsAllowlist, applicationsState)) {
if (systemAppsDiffEntry == null) {
systemAppsDiffEntry = new BatteryDiffEntry.SystemAppsBatteryDiffEntry(context);
}
systemAppsDiffEntry.mConsumePower += batteryDiffEntry.mConsumePower;
systemAppsDiffEntry.mForegroundUsageTimeInMs +=
batteryDiffEntry.mForegroundUsageTimeInMs;
systemAppsDiffEntry.setTotalConsumePower(
batteryDiffEntry.getTotalConsumePower());
appListIterator.remove();
}
}
if (systemAppsDiffEntry != null) {
batteryDiffData.getAppDiffEntryList().add(systemAppsDiffEntry);
}
}
@VisibleForTesting
static boolean needsCombineInSystemApp(final BatteryDiffEntry batteryDiffEntry,
final List<String> systemAppsAllowlist, final ApplicationsState applicationsState) {
if (batteryDiffEntry.mBatteryHistEntry.mIsHidden) {
return true;
}
final String packageName = batteryDiffEntry.getPackageName();
if (packageName == null || packageName.isEmpty()) {
return false;
}
if (systemAppsAllowlist != null && systemAppsAllowlist.contains(packageName)) {
return true;
}
if (applicationsState == null) {
return false;
}
final ApplicationsState.AppEntry appEntry =
applicationsState.getEntry(packageName, /* userId= */ 0);
if (appEntry == null || appEntry.info == null) {
return false;
}
return !ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER_AND_INSTANT.filterApp(
appEntry);
}
private static boolean shouldShowBatteryAttributionList(final Context context) {
final PowerProfile powerProfile = new PowerProfile(context);
// Cheap hack to try to figure out if the power_profile.xml was populated.

View File

@@ -0,0 +1,176 @@
/*
* 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.fuelgauge.batteryusage;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import com.android.settingslib.applications.ApplicationsState;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class BatteryDiffDataTest {
private Context mContext;
@Mock private ApplicationsState mApplicationsState;
@Mock private ApplicationsState.AppEntry mAppEntry;
@Mock private ApplicationInfo mApplicationInfo;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
}
@Test
public void needsCombineInSystemApp_isHidden_returnTrue() {
final int currentUserId = mContext.getUserId();
final BatteryHistEntry hiddenHistEntry = createBatteryHistEntry(
ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", /*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0, /*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0, /*cachedUsageConsumePower=*/ 0,
/*uid=*/ 0L, currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
/*foregroundUsageTimeInMs=*/ 0L, /*backgroundUsageTimeInMs=*/ 0L, true);
final BatteryDiffEntry hiddenDiffEntry = new BatteryDiffEntry(
mContext,
/*foregroundUsageTimeInMs=*/ 0,
/*backgroundUsageTimeInMs=*/ 0,
/*screenOnTimeInMs=*/ 0,
/*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0,
/*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0,
/*cachedUsageConsumePower=*/ 0,
hiddenHistEntry);
boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp(
hiddenDiffEntry, List.of(), mApplicationsState);
assertThat(needsCombineInSystemApp).isTrue();
}
@Test
public void needsCombineInSystemApp_isSystemApp_returnTrue() {
final int currentUserId = mContext.getUserId();
final BatteryHistEntry batteryHistEntry = createBatteryHistEntry(
ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", /*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0, /*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0, /*cachedUsageConsumePower=*/ 0,
/*uid=*/ 0L, currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
/*foregroundUsageTimeInMs=*/ 0L, /*backgroundUsageTimeInMs=*/ 0L, false);
final BatteryDiffEntry batteryDiffEntry = new BatteryDiffEntry(
mContext,
/*foregroundUsageTimeInMs=*/ 0,
/*backgroundUsageTimeInMs=*/ 0,
/*screenOnTimeInMs=*/ 0,
/*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0,
/*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0,
/*cachedUsageConsumePower=*/ 0,
batteryHistEntry);
doReturn(mAppEntry).when(mApplicationsState).getEntry(anyString(), anyInt());
mAppEntry.info = mApplicationInfo;
mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp(
batteryDiffEntry, List.of(), mApplicationsState);
assertThat(needsCombineInSystemApp).isTrue();
}
@Test
public void needsCombineInSystemApp_notSystemApp_returnFalse() {
final int currentUserId = mContext.getUserId();
final BatteryHistEntry batteryHistEntry = createBatteryHistEntry(
ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", /*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0, /*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0, /*cachedUsageConsumePower=*/ 0,
/*uid=*/ 0L, currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
/*foregroundUsageTimeInMs=*/ 0L, /*backgroundUsageTimeInMs=*/ 0L, false);
final BatteryDiffEntry batteryDiffEntry = new BatteryDiffEntry(
mContext,
/*foregroundUsageTimeInMs=*/ 0,
/*backgroundUsageTimeInMs=*/ 0,
/*screenOnTimeInMs=*/ 0,
/*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0,
/*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0,
/*cachedUsageConsumePower=*/ 0,
batteryHistEntry);
doReturn(mAppEntry).when(mApplicationsState).getEntry(anyString(), anyInt());
mAppEntry.info = mApplicationInfo;
mApplicationInfo.flags = 0;
boolean needsCombineInSystemApp = BatteryDiffData.needsCombineInSystemApp(
batteryDiffEntry, List.of(), mApplicationsState);
assertThat(needsCombineInSystemApp).isFalse();
}
private static BatteryHistEntry createBatteryHistEntry(
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 boolean isHidden) {
// Only insert required fields.
final BatteryInformation batteryInformation =
BatteryInformation
.newBuilder()
.setAppLabel(appLabel)
.setConsumePower(consumePower)
.setForegroundUsageConsumePower(foregroundUsageConsumePower)
.setForegroundServiceUsageConsumePower(foregroundServiceUsageConsumePower)
.setBackgroundUsageConsumePower(backgroundUsageConsumePower)
.setCachedUsageConsumePower(cachedUsageConsumePower)
.setForegroundUsageTimeInMs(foregroundUsageTimeInMs)
.setBackgroundUsageTimeInMs(backgroundUsageTimeInMs)
.setIsHidden(isHidden)
.build();
final ContentValues values = new ContentValues();
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, packageName);
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,
ConvertUtils.convertBatteryInformationToString(batteryInformation));
return new BatteryHistEntry(values);
}
}

View File

@@ -105,10 +105,8 @@ public final class BatteryUsageBreakdownControllerTest {
/*cachedUsageConsumePower=*/ 0,
mBatteryHistEntry);
mBatteryDiffEntry = spy(mBatteryDiffEntry);
mBatteryUsageBreakdownController.mBatteryDiffData =
new BatteryDiffData(Arrays.asList(mBatteryDiffEntry), Arrays.asList());
mBatteryUsageBreakdownController.mBatteryDiffData.setTotalConsumePower();
mBatteryUsageBreakdownController.mBatteryDiffData.sortEntries();
mBatteryUsageBreakdownController.mBatteryDiffData = new BatteryDiffData(mContext,
Arrays.asList(mBatteryDiffEntry), Arrays.asList(), /* isAccumulated= */ false);
// Adds fake testing data.
BatteryDiffEntry.sResourceCache.put(
"fakeBatteryDiffEntryKey",

View File

@@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.spy;
@@ -33,7 +32,6 @@ import android.app.usage.UsageEvents.Event;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.UserInfo;
import android.os.BatteryConsumer;
import android.os.BatteryManager;
@@ -45,7 +43,6 @@ import android.text.format.DateUtils;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.applications.ApplicationsState;
import org.junit.Before;
import org.junit.Test;
@@ -78,9 +75,6 @@ public final class DataProcessorTest {
@Mock private BatteryUsageStats mBatteryUsageStats;
@Mock private UserManager mUserManager;
@Mock private IUsageStatsManager mUsageStatsManager;
@Mock private ApplicationsState mApplicationsState;
@Mock private ApplicationsState.AppEntry mAppEntry;
@Mock private ApplicationInfo mApplicationInfo;
@Mock private BatteryEntry mMockBatteryEntry1;
@Mock private BatteryEntry mMockBatteryEntry2;
@Mock private BatteryEntry mMockBatteryEntry3;
@@ -1403,8 +1397,6 @@ public final class DataProcessorTest {
final BatteryDiffData batteryDiffData = DataProcessor.generateBatteryDiffData(mContext,
DataProcessor.convertToBatteryHistEntry(batteryEntryList, mBatteryUsageStats));
batteryDiffData.setTotalConsumePower();
batteryDiffData.sortEntries();
assertBatteryDiffEntry(
batteryDiffData.getAppDiffEntryList().get(0), 0, /*uid=*/ 2L,
@@ -1611,93 +1603,6 @@ public final class DataProcessorTest {
assertThat(DataProcessor.getScreenOnTime(appUsageMap, userId, packageName)).isEqualTo(0);
}
@Test
public void needsCombineInSystemApp_isHidden_returnTrue() {
final int currentUserId = mContext.getUserId();
final BatteryHistEntry hiddenHistEntry = createBatteryHistEntry(
ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", /*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0, /*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0, /*cachedUsageConsumePower=*/ 0,
/*uid=*/ 0L, currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
/*foregroundUsageTimeInMs=*/ 0L, /*backgroundUsageTimeInMs=*/ 0L, true);
final BatteryDiffEntry hiddenDiffEntry = new BatteryDiffEntry(
mContext,
/*foregroundUsageTimeInMs=*/ 0,
/*backgroundUsageTimeInMs=*/ 0,
/*screenOnTimeInMs=*/ 0,
/*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0,
/*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0,
/*cachedUsageConsumePower=*/ 0,
hiddenHistEntry);
boolean needsCombineInSystemApp = DataProcessor.needsCombineInSystemApp(
hiddenDiffEntry, List.of(), mApplicationsState);
assertThat(needsCombineInSystemApp).isTrue();
}
@Test
public void needsCombineInSystemApp_isSystemApp_returnTrue() {
final int currentUserId = mContext.getUserId();
final BatteryHistEntry batteryHistEntry = createBatteryHistEntry(
ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", /*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0, /*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0, /*cachedUsageConsumePower=*/ 0,
/*uid=*/ 0L, currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
/*foregroundUsageTimeInMs=*/ 0L, /*backgroundUsageTimeInMs=*/ 0L, false);
final BatteryDiffEntry batteryDiffEntry = new BatteryDiffEntry(
mContext,
/*foregroundUsageTimeInMs=*/ 0,
/*backgroundUsageTimeInMs=*/ 0,
/*screenOnTimeInMs=*/ 0,
/*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0,
/*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0,
/*cachedUsageConsumePower=*/ 0,
batteryHistEntry);
doReturn(mAppEntry).when(mApplicationsState).getEntry(anyString(), anyInt());
mAppEntry.info = mApplicationInfo;
mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
boolean needsCombineInSystemApp = DataProcessor.needsCombineInSystemApp(
batteryDiffEntry, List.of(), mApplicationsState);
assertThat(needsCombineInSystemApp).isTrue();
}
@Test
public void needsCombineInSystemApp_notSystemApp_returnFalse() {
final int currentUserId = mContext.getUserId();
final BatteryHistEntry batteryHistEntry = createBatteryHistEntry(
ConvertUtils.FAKE_PACKAGE_NAME, "fake_label", /*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0, /*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0, /*cachedUsageConsumePower=*/ 0,
/*uid=*/ 0L, currentUserId, ConvertUtils.CONSUMER_TYPE_UID_BATTERY,
/*foregroundUsageTimeInMs=*/ 0L, /*backgroundUsageTimeInMs=*/ 0L, false);
final BatteryDiffEntry batteryDiffEntry = new BatteryDiffEntry(
mContext,
/*foregroundUsageTimeInMs=*/ 0,
/*backgroundUsageTimeInMs=*/ 0,
/*screenOnTimeInMs=*/ 0,
/*consumePower=*/ 0,
/*foregroundUsageConsumePower=*/ 0,
/*foregroundServiceUsageConsumePower=*/ 0,
/*backgroundUsageConsumePower=*/ 0,
/*cachedUsageConsumePower=*/ 0,
batteryHistEntry);
doReturn(mAppEntry).when(mApplicationsState).getEntry(anyString(), anyInt());
mAppEntry.info = mApplicationInfo;
mApplicationInfo.flags = 0;
boolean needsCombineInSystemApp = DataProcessor.needsCombineInSystemApp(
batteryDiffEntry, List.of(), mApplicationsState);
assertThat(needsCombineInSystemApp).isFalse();
}
private static Map<Long, Map<String, BatteryHistEntry>> createHistoryMap(
final long[] timestamps, final int[] levels) {
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap = new HashMap<>();