Make App info page support new battery entry

- Add new battery entry to app info battery preference, support both
 legacy and new args, controlled by P/H
 - Add a method to check is work profile app or not, use owner context to
 query correct context for feature provider
 - Add string for new args

Bug: 178197718
Test: make RunSettingsRoboTests
Change-Id: Ic93142a0c5e2851917cb3e224340a6e3e81fd801
This commit is contained in:
Wesley.CW Wang
2021-06-02 20:55:14 +08:00
parent ad84b3dd39
commit e1b1f67681
6 changed files with 116 additions and 21 deletions

View File

@@ -10479,13 +10479,15 @@
Allowing <xliff:g id="app_name" example="Settings">%1$s</xliff:g> to always run in the background may reduce battery life. Allowing <xliff:g id="app_name" example="Settings">%1$s</xliff:g> to always run in the background may reduce battery life.
\n\nYou can change this later from Settings > Apps &amp; notifications.</string> \n\nYou can change this later from Settings > Apps &amp; notifications.</string>
<!-- Summary of power usage for an app [CHAR LIMIT=NONE] --> <!-- Summary of power usage for an app [CHAR LIMIT=NONE] -->
<string name="battery_summary"><xliff:g id="percentage" example="2">%1$s</xliff:g> use for past 24 hours</string> <string name="battery_summary"><xliff:g id="percentage" example="2">%1$s</xliff:g> use since last full charge</string>
<!-- Summary of power usage for an app within past 24 hr[CHAR LIMIT=NONE] -->
<!-- Title of a group of settings that let you manage settings that affect battery life [CHAR LIMIT=60] --> <string name="battery_summary_24hr"><xliff:g id="percentage" example="2">%1$s</xliff:g> use for past 24 hours</string>
<string name="battery_power_management">Power management</string>
<!-- Summary for app with no battery usage [CHAR LIMIT=NONE] --> <!-- Summary for app with no battery usage [CHAR LIMIT=NONE] -->
<string name="no_battery_summary">No battery use for past 24 hours</string> <string name="no_battery_summary">No battery use since last full charge</string>
<!-- Summary for app with no battery usage for past 24 hours [CHAR LIMIT=NONE] -->
<string name="no_battery_summary_24hr">No battery use for past 24 hours</string>
<!-- Link to an apps notification settings [CHAR LIMIT=50] --> <!-- Link to an apps notification settings [CHAR LIMIT=50] -->
<string name="app_notification_preferences">App settings</string> <string name="app_notification_preferences">App settings</string>

View File

@@ -18,11 +18,14 @@ package com.android.settings.applications.appinfo;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.BatteryUsageStats; import android.os.BatteryUsageStats;
import android.os.Bundle; import android.os.Bundle;
import android.os.UidBatteryConsumer; import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
@@ -40,6 +43,8 @@ import com.android.settings.fuelgauge.BatteryDiffEntry;
import com.android.settings.fuelgauge.BatteryEntry; import com.android.settings.fuelgauge.BatteryEntry;
import com.android.settings.fuelgauge.BatteryUsageStatsLoader; import com.android.settings.fuelgauge.BatteryUsageStatsLoader;
import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnPause;
@@ -50,6 +55,7 @@ import java.util.List;
public class AppBatteryPreferenceController extends BasePreferenceController public class AppBatteryPreferenceController extends BasePreferenceController
implements LifecycleObserver, OnResume, OnPause { implements LifecycleObserver, OnResume, OnPause {
private static final String TAG = "AppBatteryPreferenceController";
private static final String KEY_BATTERY = "battery"; private static final String KEY_BATTERY = "battery";
@VisibleForTesting @VisibleForTesting
@@ -61,13 +67,16 @@ public class AppBatteryPreferenceController extends BasePreferenceController
BatteryUsageStats mBatteryUsageStats; BatteryUsageStats mBatteryUsageStats;
@VisibleForTesting @VisibleForTesting
UidBatteryConsumer mUidBatteryConsumer; UidBatteryConsumer mUidBatteryConsumer;
@VisibleForTesting
BatteryDiffEntry mBatteryDiffEntry;
@VisibleForTesting
boolean mIsChartGraphEnabled;
private Preference mPreference; private Preference mPreference;
private final AppInfoDashboardFragment mParent; private final AppInfoDashboardFragment mParent;
private String mBatteryPercent; private String mBatteryPercent;
private final String mPackageName; private final String mPackageName;
private final int mUid; private final int mUid;
private BatteryDiffEntry mBatteryDiffEntry;
private boolean mBatteryUsageStatsLoaded = false; private boolean mBatteryUsageStatsLoaded = false;
private boolean mBatteryDiffEntriesLoaded = false; private boolean mBatteryDiffEntriesLoaded = false;
@@ -78,6 +87,7 @@ public class AppBatteryPreferenceController extends BasePreferenceController
mBatteryUtils = BatteryUtils.getInstance(mContext); mBatteryUtils = BatteryUtils.getInstance(mContext);
mPackageName = packageName; mPackageName = packageName;
mUid = uid; mUid = uid;
refreshFeatureFlag(mContext);
if (lifecycle != null) { if (lifecycle != null) {
lifecycle.addObserver(this); lifecycle.addObserver(this);
} }
@@ -108,7 +118,8 @@ public class AppBatteryPreferenceController extends BasePreferenceController
mParent.getActivity(), mParent.getActivity(),
mParent, mParent,
mBatteryDiffEntry, mBatteryDiffEntry,
mBatteryPercent, Utils.formatPercentage(
mBatteryDiffEntry.getPercentOfTotal(), /* round */ true),
/*isValidToShowSummary=*/ true, /*isValidToShowSummary=*/ true,
/*slotInformation=*/ null); /*slotInformation=*/ null);
return true; return true;
@@ -120,8 +131,9 @@ public class AppBatteryPreferenceController extends BasePreferenceController
final BatteryEntry entry = new BatteryEntry(mContext, /* handler */null, userManager, final BatteryEntry entry = new BatteryEntry(mContext, /* handler */null, userManager,
mUidBatteryConsumer, /* isHidden */ false, mUidBatteryConsumer, /* isHidden */ false,
mUidBatteryConsumer.getUid(), /* packages */ null, mPackageName); mUidBatteryConsumer.getUid(), /* packages */ null, mPackageName);
AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent, AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent, entry,
entry, mBatteryPercent); mIsChartGraphEnabled ? Utils.formatPercentage(0) : mBatteryPercent,
!mIsChartGraphEnabled);
} else { } else {
AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent, AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent,
mPackageName); mPackageName);
@@ -161,12 +173,29 @@ public class AppBatteryPreferenceController extends BasePreferenceController
@Override @Override
protected void onPostExecute(BatteryDiffEntry batteryDiffEntry) { protected void onPostExecute(BatteryDiffEntry batteryDiffEntry) {
mBatteryDiffEntry = batteryDiffEntry; mBatteryDiffEntry = batteryDiffEntry;
mBatteryDiffEntriesLoaded = true; updateBatteryWithDiffEntry();
mPreference.setEnabled(mBatteryUsageStatsLoaded);
} }
}.execute(); }.execute();
} }
@VisibleForTesting
void updateBatteryWithDiffEntry() {
if (mIsChartGraphEnabled) {
if (mBatteryDiffEntry != null && mBatteryDiffEntry.mConsumePower > 0) {
mBatteryPercent = Utils.formatPercentage(
mBatteryDiffEntry.getPercentOfTotal(), /* round */ true);
mPreference.setSummary(mContext.getString(
R.string.battery_summary_24hr, mBatteryPercent));
} else {
mPreference.setSummary(
mContext.getString(R.string.no_battery_summary_24hr));
}
}
mBatteryDiffEntriesLoaded = true;
mPreference.setEnabled(mBatteryUsageStatsLoaded);
}
private void onLoadFinished() { private void onLoadFinished() {
if (mBatteryUsageStats == null) { if (mBatteryUsageStats == null) {
return; return;
@@ -182,10 +211,33 @@ public class AppBatteryPreferenceController extends BasePreferenceController
} }
} }
private void refreshFeatureFlag(Context context) {
if (isWorkProfile(context)) {
try {
context = context.createPackageContextAsUser(
context.getPackageName(), 0, UserHandle.OWNER);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "context.createPackageContextAsUser() fail: " + e);
}
}
final PowerUsageFeatureProvider powerUsageFeatureProvider =
FeatureFactory.getFactory(context).getPowerUsageFeatureProvider(context);
mIsChartGraphEnabled = powerUsageFeatureProvider.isChartGraphEnabled(context);
}
private boolean isWorkProfile(Context context) {
final UserManager userManager = context.getSystemService(UserManager.class);
return userManager.isManagedProfile() && !userManager.isSystemUser();
}
@VisibleForTesting @VisibleForTesting
void updateBattery() { void updateBattery() {
mBatteryUsageStatsLoaded = true; mBatteryUsageStatsLoaded = true;
mPreference.setEnabled(mBatteryDiffEntriesLoaded); mPreference.setEnabled(mBatteryDiffEntriesLoaded);
if (mIsChartGraphEnabled) {
return;
}
if (isBatteryStatsAvailable()) { if (isBatteryStatsAvailable()) {
final int percentOfMax = (int) mBatteryUtils.calculateBatteryPercent( final int percentOfMax = (int) mBatteryUtils.calculateBatteryPercent(
mUidBatteryConsumer.getConsumedPower(), mBatteryUsageStats.getConsumedPower(), mUidBatteryConsumer.getConsumedPower(), mBatteryUsageStats.getConsumedPower(),

View File

@@ -157,7 +157,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
/** Launches battery details page for an individual battery consumer. */ /** Launches battery details page for an individual battery consumer. */
public static void startBatteryDetailPage(Activity caller, public static void startBatteryDetailPage(Activity caller,
InstrumentedPreferenceFragment fragment, BatteryEntry entry, String usagePercent) { InstrumentedPreferenceFragment fragment, BatteryEntry entry, String usagePercent,
boolean isValidToShowSummary) {
final LaunchBatteryDetailPageArgs launchArgs = new LaunchBatteryDetailPageArgs(); final LaunchBatteryDetailPageArgs launchArgs = new LaunchBatteryDetailPageArgs();
// configure the launch argument. // configure the launch argument.
launchArgs.mUsagePercent = usagePercent; launchArgs.mUsagePercent = usagePercent;
@@ -166,8 +167,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
launchArgs.mUid = entry.getUid(); launchArgs.mUid = entry.getUid();
launchArgs.mIconId = entry.iconId; launchArgs.mIconId = entry.iconId;
launchArgs.mConsumedPower = (int) entry.getConsumedPower(); launchArgs.mConsumedPower = (int) entry.getConsumedPower();
launchArgs.mForegroundTimeMs = entry.getTimeInForegroundMs(); launchArgs.mForegroundTimeMs = isValidToShowSummary ? entry.getTimeInForegroundMs() : 0;
launchArgs.mBackgroundTimeMs = entry.getTimeInBackgroundMs(); launchArgs.mBackgroundTimeMs = isValidToShowSummary ? entry.getTimeInBackgroundMs() : 0;
launchArgs.mIsUserEntry = entry.isUserEntry(); launchArgs.mIsUserEntry = entry.isUserEntry();
startBatteryDetailPage(caller, fragment, launchArgs); startBatteryDetailPage(caller, fragment, launchArgs);
} }

View File

@@ -188,7 +188,7 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro
PowerGaugePreference pgp = (PowerGaugePreference) preference; PowerGaugePreference pgp = (PowerGaugePreference) preference;
BatteryEntry entry = pgp.getInfo(); BatteryEntry entry = pgp.getInfo();
AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity,
mFragment, entry, pgp.getPercent()); mFragment, entry, pgp.getPercent(), /*isValidToShowSummary=*/ true);
return true; return true;
} }
return false; return false;

View File

@@ -39,6 +39,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.fuelgauge.BatteryDiffEntry;
import com.android.settings.fuelgauge.BatteryUtils; import com.android.settings.fuelgauge.BatteryUtils;
import org.junit.Before; import org.junit.Before;
@@ -76,6 +77,8 @@ public class AppBatteryPreferenceControllerTest {
private PackageManager mPackageManager; private PackageManager mPackageManager;
@Mock @Mock
private LoaderManager mLoaderManager; private LoaderManager mLoaderManager;
@Mock
private BatteryDiffEntry mBatteryDiffEntry;
private Context mContext; private Context mContext;
private AppInfoDashboardFragment mFragment; private AppInfoDashboardFragment mFragment;
@@ -134,7 +137,7 @@ public class AppBatteryPreferenceControllerTest {
mController.updateBattery(); mController.updateBattery();
assertThat(mBatteryPreference.getSummary()) assertThat(mBatteryPreference.getSummary())
.isEqualTo("No battery use for past 24 hours"); .isEqualTo("No battery use since last full charge");
} }
@Test @Test
@@ -147,6 +150,29 @@ public class AppBatteryPreferenceControllerTest {
mController.updateBattery(); mController.updateBattery();
assertThat(mBatteryPreference.getSummary()).isEqualTo("60% use since last full charge");
}
@Test
public void updateBatteryWithDiffEntry_noConsumePower_summaryNo() {
mController.displayPreference(mScreen);
mController.mIsChartGraphEnabled = true;
mController.updateBatteryWithDiffEntry();
assertThat(mBatteryPreference.getSummary()).isEqualTo("No battery use for past 24 hours");
}
@Test
public void updateBatteryWithDiffEntry_withConsumePower_summaryPercent() {
mController.displayPreference(mScreen);
mController.mIsChartGraphEnabled = true;
mBatteryDiffEntry.mConsumePower = 1;
mController.mBatteryDiffEntry = mBatteryDiffEntry;
when(mBatteryDiffEntry.getPercentOfTotal()).thenReturn(60.0);
mController.updateBatteryWithDiffEntry();
assertThat(mBatteryPreference.getSummary()).isEqualTo("60% use for past 24 hours"); assertThat(mBatteryPreference.getSummary()).isEqualTo("60% use for past 24 hours");
} }

View File

@@ -611,7 +611,7 @@ public class AdvancedPowerUsageDetailTest {
@Test @Test
public void testStartBatteryDetailPage_hasBasicData() { public void testStartBatteryDetailPage_hasBasicData() {
AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment,
mBatteryEntry, USAGE_PERCENT); mBatteryEntry, USAGE_PERCENT, /*isValidToShowSummary=*/ true);
assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID); assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID);
assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME)) assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME))
@@ -622,12 +622,26 @@ public class AdvancedPowerUsageDetailTest {
.isEqualTo(USAGE_PERCENT); .isEqualTo(USAGE_PERCENT);
} }
@Test
public void testStartBatteryDetailPage_invalidToShowSummary_noFGBDData() {
AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment,
mBatteryEntry, USAGE_PERCENT, /*isValidToShowSummary=*/ false);
assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID);
assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME))
.isEqualTo(0);
assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME))
.isEqualTo(0);
assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_PERCENT))
.isEqualTo(USAGE_PERCENT);
}
@Test @Test
public void testStartBatteryDetailPage_NormalApp() { public void testStartBatteryDetailPage_NormalApp() {
when(mBatteryEntry.getDefaultPackageName()).thenReturn(PACKAGE_NAME[0]); when(mBatteryEntry.getDefaultPackageName()).thenReturn(PACKAGE_NAME[0]);
AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment,
mBatteryEntry, USAGE_PERCENT); mBatteryEntry, USAGE_PERCENT, /*isValidToShowSummary=*/ true);
assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo( assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo(
PACKAGE_NAME[0]); PACKAGE_NAME[0]);
@@ -638,7 +652,7 @@ public class AdvancedPowerUsageDetailTest {
when(mBatteryEntry.getDefaultPackageName()).thenReturn(null); when(mBatteryEntry.getDefaultPackageName()).thenReturn(null);
AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment,
mBatteryEntry, USAGE_PERCENT); mBatteryEntry, USAGE_PERCENT, /*isValidToShowSummary=*/ true);
assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_LABEL)).isEqualTo(APP_LABEL); assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_LABEL)).isEqualTo(APP_LABEL);
assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_ICON_ID)).isEqualTo(ICON_ID); assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_ICON_ID)).isEqualTo(ICON_ID);
@@ -651,7 +665,7 @@ public class AdvancedPowerUsageDetailTest {
doReturn(appUid).when(mBatteryEntry).getUid(); doReturn(appUid).when(mBatteryEntry).getUid();
AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment,
mBatteryEntry, USAGE_PERCENT); mBatteryEntry, USAGE_PERCENT, /*isValidToShowSummary=*/ true);
verify(mActivity).startActivityAsUser(any(Intent.class), eq(new UserHandle(10))); verify(mActivity).startActivityAsUser(any(Intent.class), eq(new UserHandle(10)));
} }
@@ -663,7 +677,7 @@ public class AdvancedPowerUsageDetailTest {
final int currentUser = 20; final int currentUser = 20;
ShadowActivityManager.setCurrentUser(currentUser); ShadowActivityManager.setCurrentUser(currentUser);
AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment,
mBatteryEntry, USAGE_PERCENT); mBatteryEntry, USAGE_PERCENT, /*isValidToShowSummary=*/ true);
verify(mActivity).startActivityAsUser(any(Intent.class), eq(new UserHandle(currentUser))); verify(mActivity).startActivityAsUser(any(Intent.class), eq(new UserHandle(currentUser)));
} }