Refine startBatteryDetailPage method to support history data

Bug: 177406865
Test: make SettingsRoboTests
Test: make SettingsGoogleRoboTests
Change-Id: Iee3b6b353c4f92bdad37fac55adad58b4f205bf6
This commit is contained in:
ykhung
2021-04-19 13:37:59 +08:00
committed by YUKAI HUNG
parent d2bffb94a7
commit 4752ea17b9
9 changed files with 187 additions and 31 deletions

View File

@@ -116,37 +116,82 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
private String mPackageName;
/**
* Launches battery details page for an individual battery consumer.
*/
// A wrapper class to carry LaunchBatteryDetailPage required arguments.
private static final class LaunchBatteryDetailPageArgs {
private String mUsagePercent;
private String mPackageName;
private String mAppLabel;
private int mUid;
private int mIconId;
private int mConsumedPower;
private long mForegroundTimeMs;
private long mBackgroundTimeMs;
private boolean mIsUserEntry;
}
/** Launches battery details page for an individual battery consumer. */
public static void startBatteryDetailPage(
Activity caller, InstrumentedPreferenceFragment fragment,
BatteryDiffEntry diffEntry, String usagePercent) {
final BatteryHistEntry histEntry = diffEntry.mBatteryHistEntry;
final LaunchBatteryDetailPageArgs launchArgs = new LaunchBatteryDetailPageArgs();
// configure the launch argument.
launchArgs.mUsagePercent = usagePercent;
launchArgs.mPackageName = diffEntry.getPackageName();
launchArgs.mAppLabel = diffEntry.getAppLabel();
launchArgs.mUid = (int) histEntry.mUid;
launchArgs.mIconId = diffEntry.getAppIconId();
launchArgs.mConsumedPower = (int) diffEntry.mConsumePower;
launchArgs.mForegroundTimeMs = diffEntry.mForegroundUsageTimeInMs;
launchArgs.mBackgroundTimeMs = diffEntry.mBackgroundUsageTimeInMs;
launchArgs.mIsUserEntry = histEntry.isUserEntry();
startBatteryDetailPage(caller, fragment, launchArgs);
}
/** Launches battery details page for an individual battery consumer. */
public static void startBatteryDetailPage(Activity caller,
InstrumentedPreferenceFragment fragment, BatteryEntry entry, String usagePercent) {
final LaunchBatteryDetailPageArgs launchArgs = new LaunchBatteryDetailPageArgs();
// configure the launch argument.
launchArgs.mUsagePercent = usagePercent;
launchArgs.mPackageName = entry.getDefaultPackageName();
launchArgs.mAppLabel = entry.getLabel();
launchArgs.mUid = entry.getUid();
launchArgs.mIconId = entry.iconId;
launchArgs.mConsumedPower = (int) entry.getConsumedPower();
launchArgs.mForegroundTimeMs = entry.getTimeInForegroundMs();
launchArgs.mBackgroundTimeMs = entry.getTimeInBackgroundMs();
launchArgs.mIsUserEntry = entry.isUserEntry();
startBatteryDetailPage(caller, fragment, launchArgs);
}
private static void startBatteryDetailPage(Activity caller,
InstrumentedPreferenceFragment fragment, LaunchBatteryDetailPageArgs launchArgs) {
final Bundle args = new Bundle();
final long foregroundTimeMs = entry.getTimeInForegroundMs();
final long backgroundTimeMs = entry.getTimeInBackgroundMs();
final String packageName = entry.getDefaultPackageName();
if (packageName == null) {
if (launchArgs.mPackageName == null) {
// populate data for system app
args.putString(EXTRA_LABEL, entry.getLabel());
args.putInt(EXTRA_ICON_ID, entry.iconId);
args.putString(EXTRA_LABEL, launchArgs.mAppLabel);
args.putInt(EXTRA_ICON_ID, launchArgs.mIconId);
args.putString(EXTRA_PACKAGE_NAME, null);
} else {
// populate data for normal app
args.putString(EXTRA_PACKAGE_NAME, packageName);
args.putString(EXTRA_PACKAGE_NAME, launchArgs.mPackageName);
}
args.putInt(EXTRA_UID, entry.getUid());
args.putLong(EXTRA_BACKGROUND_TIME, backgroundTimeMs);
args.putLong(EXTRA_FOREGROUND_TIME, foregroundTimeMs);
args.putString(EXTRA_POWER_USAGE_PERCENT, usagePercent);
args.putInt(EXTRA_POWER_USAGE_AMOUNT, (int) entry.getConsumedPower());
args.putInt(EXTRA_UID, launchArgs.mUid);
args.putLong(EXTRA_BACKGROUND_TIME, launchArgs.mBackgroundTimeMs);
args.putLong(EXTRA_FOREGROUND_TIME, launchArgs.mForegroundTimeMs);
args.putString(EXTRA_POWER_USAGE_PERCENT, launchArgs.mUsagePercent);
args.putInt(EXTRA_POWER_USAGE_AMOUNT, launchArgs.mConsumedPower);
final int userId = launchArgs.mIsUserEntry ? ActivityManager.getCurrentUser()
: UserHandle.getUserId(launchArgs.mUid);
new SubSettingLauncher(caller)
.setDestination(AdvancedPowerUsageDetail.class.getName())
.setTitleRes(R.string.battery_details_title)
.setArguments(args)
.setSourceMetricsCategory(fragment.getMetricsCategory())
.setUserHandle(new UserHandle(getUserIdToLaunchAdvancePowerUsageDetail(entry)))
.setUserHandle(new UserHandle(userId))
.launch();
}

View File

@@ -58,6 +58,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
Map<Integer, List<BatteryDiffEntry>> mBatteryIndexedMap;
@VisibleForTesting Context mPrefContext;
@VisibleForTesting BatteryUtils mBatteryUtils;
@VisibleForTesting PreferenceGroup mAppListPrefGroup;
@VisibleForTesting BatteryChartView mBatteryChartView;
@@ -98,6 +99,9 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
}
mHandler.removeCallbacksAndMessages(/*token=*/ null);
mPreferenceCache.clear();
if (mAppListPrefGroup != null) {
mAppListPrefGroup.removeAll();
}
}
@Override
@@ -120,6 +124,28 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!(preference instanceof PowerGaugePreference)) {
return false;
}
final PowerGaugePreference powerPref = (PowerGaugePreference) preference;
final BatteryDiffEntry diffEntry = powerPref.getBatteryDiffEntry();
final BatteryHistEntry histEntry = diffEntry.mBatteryHistEntry;
// Checks whether the package is installed or not.
boolean isValidPackage = true;
if (histEntry.isAppEntry()) {
if (mBatteryUtils == null) {
mBatteryUtils = BatteryUtils.getInstance(mPrefContext);
}
isValidPackage = mBatteryUtils.getPackageUid(histEntry.mPackageName)
!= BatteryUtils.UID_NULL;
}
Log.d(TAG, String.format("handleClick() label=%s key=%s isValid:%b",
diffEntry.getAppLabel(), histEntry.getKey(), isValidPackage));
if (isValidPackage) {
AdvancedPowerUsageDetail.startBatteryDetailPage(
mActivity, mFragment, diffEntry, powerPref.getPercent());
return true;
}
return false;
}
@@ -273,6 +299,8 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
pref.setTitle(appLabel);
pref.setOrder(prefIndex);
pref.setPercent(entry.getPercentOfTotal());
// Sets the BatteryDiffEntry to preference for launching detailed page.
pref.setBatteryDiffEntry(entry);
mAppListPrefGroup.addPreference(pref);
prefIndex++;
}

View File

@@ -57,6 +57,7 @@ public class BatteryDiffEntry {
private UserManager mUserManager;
private String mDefaultPackageName = null;
@VisibleForTesting int mAppIconId;
@VisibleForTesting String mAppLabel = null;
@VisibleForTesting Drawable mAppIcon = null;
@VisibleForTesting boolean mIsLoaded = false;
@@ -112,9 +113,16 @@ public class BatteryDiffEntry {
return mAppIcon;
}
/** Gets the app icon id for this entry. */
public int getAppIconId() {
loadLabelAndIcon();
return mAppIconId;
}
/** Gets the searching package name for UID battery type. */
public String getPackageName() {
return mDefaultPackageName;
return mDefaultPackageName != null
? mDefaultPackageName : mBatteryHistEntry.mPackageName;
}
/** Whether the current BatteryDiffEntry is system component or not. */
@@ -153,6 +161,7 @@ public class BatteryDiffEntry {
if (nameAndIconForSystem != null) {
mAppLabel = nameAndIconForSystem.name;
if (nameAndIconForSystem.iconId != 0) {
mAppIconId = nameAndIconForSystem.iconId;
mAppIcon = mContext.getDrawable(nameAndIconForSystem.iconId);
}
}
@@ -225,8 +234,8 @@ public class BatteryDiffEntry {
// Clears BatteryEntry internal cache since we will have another one.
BatteryEntry.clearUidCache();
if (nameAndIcon != null) {
mAppLabel = getNonNull(mAppLabel, nameAndIcon.name);
mAppIcon = getNonNull(mAppIcon, nameAndIcon.icon);
mAppLabel = nameAndIcon.name;
mAppIcon = nameAndIcon.icon;
mDefaultPackageName = nameAndIcon.packageName;
if (mDefaultPackageName != null
&& !mDefaultPackageName.equals(nameAndIcon.packageName)) {
@@ -265,8 +274,4 @@ public class BatteryDiffEntry {
final int appUid = UserHandle.getAppId(uid);
return appUid >= Process.SYSTEM_UID && appUid < Process.FIRST_APPLICATION_UID;
}
private static <T> T getNonNull(T originalObj, T newObj) {
return newObj != null ? newObj : originalObj;
}
}

View File

@@ -113,10 +113,9 @@ public class BatteryEntry {
be.mContext, be.getUid(), sHandler, be,
be.mDefaultPackageName, be.name, be.icon);
if (nameAndIcon != null) {
be.icon = getNonNull(be.icon, nameAndIcon.icon);
be.name = getNonNull(be.name, nameAndIcon.name);
be.mDefaultPackageName = getNonNull(
be.mDefaultPackageName, nameAndIcon.packageName);
be.icon = nameAndIcon.icon;
be.name = nameAndIcon.name;
be.mDefaultPackageName = nameAndIcon.packageName;
}
}
}
@@ -589,8 +588,4 @@ public class BatteryEntry {
}
return new NameAndIcon(name, null /* icon */, iconId);
}
private static <T> T getNonNull(T originalObj, T newObj) {
return newObj != null ? newObj : originalObj;
}
}

View File

@@ -113,6 +113,16 @@ public class BatteryHistEntry {
return mIsValidEntry;
}
/** Whether this {@link BatteryHistEntry} is user consumer or not. */
public boolean isUserEntry() {
return mConsumerType == ConvertUtils.CONSUMER_TYPE_USER_BATTERY;
}
/** Whether this {@link BatteryHistEntry} is app consumer or not. */
public boolean isAppEntry() {
return mConsumerType == ConvertUtils.CONSUMER_TYPE_UID_BATTERY;
}
/** Gets an identifier to represent this {@link BatteryHistEntry}. */
public String getKey() {
if (mKey == null) {

View File

@@ -37,6 +37,7 @@ import com.android.settingslib.widget.AppPreference;
public class PowerGaugePreference extends AppPreference {
private BatteryEntry mInfo;
private BatteryDiffEntry mBatteryDiffEntry;
private CharSequence mContentDescription;
private CharSequence mProgress;
private boolean mShowAnomalyIcon;
@@ -98,10 +99,18 @@ public class PowerGaugePreference extends AppPreference {
return mShowAnomalyIcon;
}
public void setBatteryDiffEntry(BatteryDiffEntry entry) {
mBatteryDiffEntry = entry;
}
BatteryEntry getInfo() {
return mInfo;
}
BatteryDiffEntry getBatteryDiffEntry() {
return mBatteryDiffEntry;
}
@Override
public void onBindViewHolder(PreferenceViewHolder view) {
super.onBindViewHolder(view);

View File

@@ -63,6 +63,7 @@ public final class BatteryChartPreferenceControllerTest {
@Mock private BatteryHistEntry mBatteryHistEntry;
@Mock private BatteryChartView mBatteryChartView;
@Mock private PowerGaugePreference mPowerGaugePreference;
@Mock private BatteryUtils mBatteryUtils;
private Context mContext;
private BatteryDiffEntry mBatteryDiffEntry;
@@ -127,6 +128,12 @@ public final class BatteryChartPreferenceControllerTest {
assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
}
@Test
public void testOnDestroy_removeAllPreferenceFromPreferenceGroup() {
mBatteryChartPreferenceController.onDestroy();
verify(mAppListGroup).removeAll();
}
@Test
public void testSetBatteryHistoryMap_createExpectedKeysAndLevels() {
mBatteryChartPreferenceController.setBatteryHistoryMap(
@@ -266,6 +273,34 @@ public final class BatteryChartPreferenceControllerTest {
assertThat(pref.getTitle()).isEqualTo(appLabel);
assertThat(pref.getIcon()).isEqualTo(mDrawable);
assertThat(pref.getOrder()).isEqualTo(1);
assertThat(pref.getBatteryDiffEntry()).isSameInstanceAs(mBatteryDiffEntry);
}
@Test
public void testHandlePreferenceTreeClick_notPowerGaugePreference_returnFalse() {
assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(mAppListGroup))
.isFalse();
}
@Test
public void testHandlePreferenceTreeClick_validPackageName_returnTrue() {
doReturn(false).when(mBatteryHistEntry).isAppEntry();
doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry();
assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(
mPowerGaugePreference)).isTrue();
}
@Test
public void testHandlePreferenceTreeClick_appEntryWithInvalidPackage_returnFalse() {
mBatteryChartPreferenceController.mBatteryUtils = mBatteryUtils;
doReturn(true).when(mBatteryHistEntry).isAppEntry();
doReturn(BatteryUtils.UID_NULL).when(mBatteryUtils)
.getPackageUid(mBatteryHistEntry.mPackageName);
doReturn(mBatteryDiffEntry).when(mPowerGaugePreference).getBatteryDiffEntry();
assertThat(mBatteryChartPreferenceController.handlePreferenceTreeClick(
mPowerGaugePreference)).isFalse();
}
private Map<Long, List<BatteryHistEntry>> createBatteryHistoryMap(int size) {

View File

@@ -30,6 +30,8 @@ import android.os.SystemBatteryConsumer;
import android.os.UserManager;
import android.os.UserHandle;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -118,6 +120,7 @@ public final class BatteryDiffEntryTest {
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
assertThat(entry.getAppLabel()).isEqualTo("Ambient display");
assertThat(entry.getAppIconId()).isEqualTo(R.drawable.ic_settings_aod);
assertThat(BatteryDiffEntry.sResourceCache).isEmpty();
}
@@ -134,6 +137,7 @@ public final class BatteryDiffEntryTest {
assertThat(entry.getAppLabel()).isEqualTo("Removed user");
assertThat(entry.getAppIcon()).isNull();
assertThat(entry.getAppIconId()).isEqualTo(0);
assertThat(BatteryDiffEntry.sResourceCache).isEmpty();
}
@@ -154,6 +158,7 @@ public final class BatteryDiffEntryTest {
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);
assertThat(entry.getAppLabel()).isEqualTo(expectedAppLabel);
assertThat(entry.getAppIconId()).isEqualTo(0);
assertThat(BatteryDiffEntry.sResourceCache).hasSize(1);
// Verifies the app label in the cache.
final BatteryEntry.NameAndIcon nameAndIcon =

View File

@@ -167,6 +167,30 @@ public final class BatteryHistEntryTest {
assertThat(batteryHistEntry.getKey()).isEqualTo("S|1");
}
@Test
public void testIsAppEntry_returnExpectedResult() {
assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY).isAppEntry())
.isFalse();
assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_USER_BATTERY).isAppEntry())
.isFalse();
assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_UID_BATTERY).isAppEntry())
.isTrue();
}
@Test
public void testIsUserEntry_returnExpectedResult() {
assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY).isUserEntry())
.isFalse();
assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_USER_BATTERY).isUserEntry())
.isTrue();
assertThat(createEntry(ConvertUtils.CONSUMER_TYPE_UID_BATTERY).isUserEntry())
.isFalse();
}
private static BatteryHistEntry createEntry(int consumerType) {
return new BatteryHistEntry(getContentValuesWithType(consumerType));
}
private static ContentValues getContentValuesWithType(int consumerType) {
final ContentValues values = new ContentValues();
values.put("consumerType", Integer.valueOf(consumerType));