Fix b/265387286: The total percentage of all apps is not 100%
Bug: 265387286 Fix: 265387286 Test: manual Change-Id: I654f8211a45c818f9a2d4867ac679e72c9ce6eb1
This commit is contained in:
@@ -32,6 +32,8 @@ import java.util.Set;
|
||||
|
||||
/** Wraps the battery usage diff data for each entry used for battery usage app list. */
|
||||
public class BatteryDiffData {
|
||||
static final double SMALL_PERCENTAGE_THRESHOLD = 1f;
|
||||
|
||||
private final List<BatteryDiffEntry> mAppEntries;
|
||||
private final List<BatteryDiffEntry> mSystemEntries;
|
||||
|
||||
@@ -52,8 +54,8 @@ public class BatteryDiffData {
|
||||
combineBatteryDiffEntry(context, featureProvider, systemAppsSet);
|
||||
}
|
||||
|
||||
setTotalConsumePower();
|
||||
sortEntries();
|
||||
processAndSortEntries(mAppEntries);
|
||||
processAndSortEntries(mSystemEntries);
|
||||
}
|
||||
|
||||
public List<BatteryDiffEntry> getAppDiffEntryList() {
|
||||
@@ -77,18 +79,6 @@ public class BatteryDiffData {
|
||||
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 purgeBatteryDiffData(
|
||||
final PowerUsageFeatureProvider featureProvider,
|
||||
final List<BatteryDiffEntry> entries) {
|
||||
@@ -177,18 +167,6 @@ public class BatteryDiffData {
|
||||
}
|
||||
}
|
||||
|
||||
// Sets total consume power for each entry.
|
||||
private static void setTotalConsumePowerForAllEntries(
|
||||
final List<BatteryDiffEntry> batteryDiffEntries) {
|
||||
double totalConsumePower = 0.0;
|
||||
for (BatteryDiffEntry batteryDiffEntry : batteryDiffEntries) {
|
||||
totalConsumePower += batteryDiffEntry.mConsumePower;
|
||||
}
|
||||
for (BatteryDiffEntry batteryDiffEntry : batteryDiffEntries) {
|
||||
batteryDiffEntry.setTotalConsumePower(totalConsumePower);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean needsCombineInSystemApp(final BatteryDiffEntry batteryDiffEntry,
|
||||
final List<String> systemAppsAllowlist, final Set<String> systemAppsSet) {
|
||||
@@ -207,4 +185,51 @@ public class BatteryDiffData {
|
||||
|
||||
return systemAppsSet != null && systemAppsSet.contains(packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets total consume power, and adjusts the percentages to ensure the total round percentage
|
||||
* could be 100%, and then sorts entries based on the sorting key.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static void processAndSortEntries(final List<BatteryDiffEntry> batteryDiffEntries) {
|
||||
if (batteryDiffEntries.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sets total consume power.
|
||||
double totalConsumePower = 0.0;
|
||||
for (BatteryDiffEntry batteryDiffEntry : batteryDiffEntries) {
|
||||
totalConsumePower += batteryDiffEntry.mConsumePower;
|
||||
}
|
||||
for (BatteryDiffEntry batteryDiffEntry : batteryDiffEntries) {
|
||||
batteryDiffEntry.setTotalConsumePower(totalConsumePower);
|
||||
}
|
||||
|
||||
// Adjusts percentages to show.
|
||||
// The lower bound is treating all the small percentages as 0.
|
||||
// The upper bound is treating all the small percentages as 1.
|
||||
int totalLowerBound = 0;
|
||||
int totalUpperBound = 0;
|
||||
for (BatteryDiffEntry entry : batteryDiffEntries) {
|
||||
if (entry.getPercentage() < SMALL_PERCENTAGE_THRESHOLD) {
|
||||
totalUpperBound += 1;
|
||||
} else {
|
||||
int roundPercentage = Math.round((float) entry.getPercentage());
|
||||
totalLowerBound += roundPercentage;
|
||||
totalUpperBound += roundPercentage;
|
||||
}
|
||||
}
|
||||
if (totalLowerBound > 100 || totalUpperBound < 100) {
|
||||
Collections.sort(batteryDiffEntries, BatteryDiffEntry.COMPARATOR);
|
||||
for (int i = 0; i < totalLowerBound - 100 && i < batteryDiffEntries.size(); i++) {
|
||||
batteryDiffEntries.get(i).setAdjustPercentageOffset(-1);
|
||||
}
|
||||
for (int i = 0; i < 100 - totalUpperBound && i < batteryDiffEntries.size(); i++) {
|
||||
batteryDiffEntries.get(i).setAdjustPercentageOffset(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Sorts entries.
|
||||
Collections.sort(batteryDiffEntries, BatteryDiffEntry.COMPARATOR);
|
||||
}
|
||||
}
|
||||
|
@@ -47,7 +47,7 @@ public class BatteryDiffEntry {
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
||||
public static final Map<String, Boolean> sValidForRestriction = new HashMap<>();
|
||||
|
||||
/** A comparator for {@link BatteryDiffEntry} based on consumed percentage. */
|
||||
/** A comparator for {@link BatteryDiffEntry} based on the sorting key. */
|
||||
public static final Comparator<BatteryDiffEntry> COMPARATOR =
|
||||
(a, b) -> Double.compare(b.getSortingKey(), a.getSortingKey());
|
||||
|
||||
@@ -65,7 +65,8 @@ public class BatteryDiffEntry {
|
||||
protected Context mContext;
|
||||
|
||||
private double mTotalConsumePower;
|
||||
private double mPercentOfTotal;
|
||||
private double mPercentage;
|
||||
private int mAdjustPercentageOffset;
|
||||
private UserManager mUserManager;
|
||||
private String mDefaultPackageName = null;
|
||||
|
||||
@@ -107,8 +108,9 @@ public class BatteryDiffEntry {
|
||||
/** Sets the total consumed power in a specific time slot. */
|
||||
public void setTotalConsumePower(double totalConsumePower) {
|
||||
mTotalConsumePower = totalConsumePower;
|
||||
mPercentOfTotal = totalConsumePower == 0
|
||||
mPercentage = totalConsumePower == 0
|
||||
? 0 : (mConsumePower / mTotalConsumePower) * 100.0;
|
||||
mAdjustPercentageOffset = 0;
|
||||
}
|
||||
|
||||
/** Gets the total consumed power in a specific time slot. */
|
||||
@@ -117,13 +119,23 @@ public class BatteryDiffEntry {
|
||||
}
|
||||
|
||||
/** Gets the percentage of total consumed power. */
|
||||
public double getPercentOfTotal() {
|
||||
return mPercentOfTotal;
|
||||
public double getPercentage() {
|
||||
return mPercentage;
|
||||
}
|
||||
|
||||
/** Gets the percentage offset to adjust. */
|
||||
public double getAdjustPercentageOffset() {
|
||||
return mAdjustPercentageOffset;
|
||||
}
|
||||
|
||||
/** Sets the percentage offset to adjust. */
|
||||
public void setAdjustPercentageOffset(int offset) {
|
||||
mAdjustPercentageOffset = offset;
|
||||
}
|
||||
|
||||
/** Gets the key for sorting */
|
||||
public double getSortingKey() {
|
||||
return getPercentOfTotal();
|
||||
return getPercentage() + getAdjustPercentageOffset();
|
||||
}
|
||||
|
||||
/** Clones a new instance. */
|
||||
@@ -369,7 +381,7 @@ public class BatteryDiffEntry {
|
||||
.append(String.format("\n\tname=%s restrictable=%b",
|
||||
mAppLabel, mValidForRestriction))
|
||||
.append(String.format("\n\tconsume=%.2f%% %f/%f",
|
||||
mPercentOfTotal, mConsumePower, mTotalConsumePower))
|
||||
mPercentage, mConsumePower, mTotalConsumePower))
|
||||
.append(String.format("\n\tconsume power= foreground:%f foregroundService:%f",
|
||||
mForegroundUsageConsumePower, mForegroundServiceUsageConsumePower))
|
||||
.append(String.format("\n\tconsume power= background:%f cached:%f",
|
||||
|
@@ -35,6 +35,7 @@ import androidx.preference.PreferenceScreen;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
|
||||
@@ -86,6 +87,8 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
||||
FooterPreference mFooterPreference;
|
||||
@VisibleForTesting
|
||||
BatteryDiffData mBatteryDiffData;
|
||||
@VisibleForTesting
|
||||
String mPercentLessThanThresholdText;
|
||||
|
||||
public BatteryUsageBreakdownController(
|
||||
Context context, Lifecycle lifecycle, SettingsActivity activity,
|
||||
@@ -147,11 +150,11 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
||||
: SettingsEnums.ACTION_BATTERY_USAGE_SYSTEM_ITEM,
|
||||
/* pageId */ SettingsEnums.OPEN_BATTERY_USAGE,
|
||||
TextUtils.isEmpty(packageName) ? PACKAGE_NAME_NONE : packageName,
|
||||
(int) Math.round(diffEntry.getPercentOfTotal()));
|
||||
(int) Math.round(diffEntry.getPercentage()));
|
||||
Log.d(TAG, String.format("handleClick() label=%s key=%s package=%s",
|
||||
diffEntry.getAppLabel(), histEntry.getKey(), histEntry.mPackageName));
|
||||
AdvancedPowerUsageDetail.startBatteryDetailPage(
|
||||
mActivity, mFragment, diffEntry, powerPref.getPercent(), mSlotTimestamp);
|
||||
mActivity, mFragment, diffEntry, powerPref.getPercentage(), mSlotTimestamp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -163,6 +166,9 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
||||
mSpinnerPreference = screen.findPreference(SPINNER_PREFERENCE_KEY);
|
||||
mAppListPreferenceGroup = screen.findPreference(APP_LIST_PREFERENCE_KEY);
|
||||
mFooterPreference = screen.findPreference(FOOTER_PREFERENCE_KEY);
|
||||
mPercentLessThanThresholdText = mPrefContext.getString(
|
||||
R.string.battery_usage_less_than_percent,
|
||||
Utils.formatPercentage(BatteryDiffData.SMALL_PERCENTAGE_THRESHOLD, false));
|
||||
|
||||
mAppListPreferenceGroup.setOrderingAsAdded(false);
|
||||
mSpinnerPreference.initializeSpinner(
|
||||
@@ -279,11 +285,11 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
||||
pref.setIcon(appIcon);
|
||||
pref.setTitle(appLabel);
|
||||
pref.setOrder(prefIndex);
|
||||
pref.setPercent(entry.getPercentOfTotal());
|
||||
pref.setSingleLineTitle(true);
|
||||
// Sets the BatteryDiffEntry to preference for launching detailed page.
|
||||
pref.setBatteryDiffEntry(entry);
|
||||
pref.setSelectable(entry.validForRestriction());
|
||||
setPreferencePercentage(pref, entry);
|
||||
setPreferenceSummary(pref, entry);
|
||||
if (!isAdded) {
|
||||
mAppListPreferenceGroup.addPreference(pref);
|
||||
@@ -307,6 +313,17 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
|
||||
mAppListPreferenceGroup.removeAll();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setPreferencePercentage(
|
||||
PowerGaugePreference preference, BatteryDiffEntry entry) {
|
||||
preference.setPercentage(
|
||||
entry.getPercentage() < BatteryDiffData.SMALL_PERCENTAGE_THRESHOLD
|
||||
? mPercentLessThanThresholdText
|
||||
: Utils.formatPercentage(
|
||||
entry.getPercentage() + entry.getAdjustPercentageOffset(),
|
||||
/* round= */ true));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setPreferenceSummary(
|
||||
PowerGaugePreference preference, BatteryDiffEntry entry) {
|
||||
|
@@ -38,7 +38,6 @@ import com.android.settingslib.widget.AppPreference;
|
||||
*/
|
||||
public class PowerGaugePreference extends AppPreference {
|
||||
|
||||
private static final double PERCENTAGE_TO_SHOW_THRESHOLD = 1f;
|
||||
// Please see go/battery-usage-app-list-alpha
|
||||
private static final float SELECTABLE_ALPHA = 1f;
|
||||
private static final float UNSELECTABLE_ALPHA_LIGHT_MODE = 0.65f;
|
||||
@@ -81,29 +80,17 @@ public class PowerGaugePreference extends AppPreference {
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
/** Sets the percent of total. */
|
||||
public void setPercent(double percentOfTotal) {
|
||||
mProgress = percentOfTotal < PERCENTAGE_TO_SHOW_THRESHOLD
|
||||
? "-" : Utils.formatPercentage(percentOfTotal, true);
|
||||
/** Sets the percentage to show. */
|
||||
public void setPercentage(CharSequence percentage) {
|
||||
mProgress = percentage;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
/** Gets the percent of total. */
|
||||
public String getPercent() {
|
||||
/** Gets the percentage to show. */
|
||||
public String getPercentage() {
|
||||
return mProgress.toString();
|
||||
}
|
||||
|
||||
/** Sets the subtitle. */
|
||||
public void setSubtitle(CharSequence subtitle) {
|
||||
mProgress = subtitle;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
/** Gets the subtitle. */
|
||||
public CharSequence getSubtitle() {
|
||||
return mProgress;
|
||||
}
|
||||
|
||||
/** Sets whether to show anomaly icon */
|
||||
public void shouldShowAnomalyIcon(boolean showAnomalyIcon) {
|
||||
mShowAnomalyIcon = showAnomalyIcon;
|
||||
|
Reference in New Issue
Block a user