diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java index 43465ab3c57..20c43230a42 100644 --- a/src/com/android/settings/fuelgauge/BatteryInfo.java +++ b/src/com/android/settings/fuelgauge/BatteryInfo.java @@ -35,18 +35,15 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.R; import com.android.settingslib.utils.PowerUtil; import com.android.settingslib.utils.StringUtil; -import java.util.concurrent.TimeUnit; public class BatteryInfo { - private static final long SEVEN_MINUTES_MICROS = TimeUnit.MINUTES.toMicros(7); - private static final long FIFTEEN_MINUTES_MICROS = TimeUnit.MINUTES.toMicros(15); - private static final long ONE_DAY_MICROS = TimeUnit.DAYS.toMicros(1); public CharSequence chargeLabel; public CharSequence remainingLabel; public int batteryLevel; public boolean discharging = true; public long remainingTimeUs = 0; + public long averageTimeToDischarge = Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN; public String batteryPercentString; public String statusLabel; private boolean mCharging; @@ -180,16 +177,18 @@ public class BatteryInfo { BatteryUtils .logRuntime(LOG_TAG, "time for enhanced BatteryInfo", startTime); return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats, - elapsedRealtimeUs, shortString, - PowerUtil.convertMsToUs(estimate.estimateMillis), - estimate.isBasedOnUsage); + estimate, elapsedRealtimeUs, shortString); } } long prediction = discharging ? stats.computeBatteryTimeRemaining(elapsedRealtimeUs) : 0; + Estimate estimate = new Estimate( + PowerUtil.convertUsToMs(prediction), + false, /* isBasedOnUsage */ + Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN); BatteryUtils.logRuntime(LOG_TAG, "time for regular BatteryInfo", startTime); return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats, - elapsedRealtimeUs, shortString, prediction, false); + estimate, elapsedRealtimeUs, shortString); } @Override @@ -204,25 +203,29 @@ public class BatteryInfo { @WorkerThread public static BatteryInfo getBatteryInfoOld(Context context, Intent batteryBroadcast, BatteryStats stats, long elapsedRealtimeUs, boolean shortString) { - return getBatteryInfo(context, batteryBroadcast, stats, elapsedRealtimeUs, shortString, - stats.computeBatteryTimeRemaining(elapsedRealtimeUs), false); + Estimate estimate = new Estimate( + PowerUtil.convertUsToMs(stats.computeBatteryTimeRemaining(elapsedRealtimeUs)), + false, + Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN); + return getBatteryInfo(context, batteryBroadcast, stats, estimate, elapsedRealtimeUs, + shortString); } @WorkerThread public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast, - BatteryStats stats, long elapsedRealtimeUs, boolean shortString, long drainTimeUs, - boolean basedOnUsage) { + BatteryStats stats, Estimate estimate, long elapsedRealtimeUs, boolean shortString) { final long startTime = System.currentTimeMillis(); BatteryInfo info = new BatteryInfo(); info.mStats = stats; info.batteryLevel = Utils.getBatteryLevel(batteryBroadcast); info.batteryPercentString = Utils.formatPercentage(info.batteryLevel); info.mCharging = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0; + info.averageTimeToDischarge = estimate.averageDischargeTime; final Resources resources = context.getResources(); info.statusLabel = Utils.getBatteryStatus(resources, batteryBroadcast); if (!info.mCharging) { - updateBatteryInfoDischarging(context, shortString, drainTimeUs, basedOnUsage, info); + updateBatteryInfoDischarging(context, shortString, estimate, info); } else { updateBatteryInfoCharging(context, batteryBroadcast, stats, elapsedRealtimeUs, info); } @@ -256,20 +259,21 @@ public class BatteryInfo { } private static void updateBatteryInfoDischarging(Context context, boolean shortString, - long drainTimeUs, boolean basedOnUsage, BatteryInfo info) { + Estimate estimate, BatteryInfo info) { + final long drainTimeUs = PowerUtil.convertMsToUs(estimate.estimateMillis); if (drainTimeUs > 0) { info.remainingTimeUs = drainTimeUs; info.remainingLabel = PowerUtil.getBatteryRemainingStringFormatted( context, PowerUtil.convertUsToMs(drainTimeUs), null /* percentageString */, - basedOnUsage && !shortString + estimate.isBasedOnUsage && !shortString ); info.chargeLabel = PowerUtil.getBatteryRemainingStringFormatted( context, PowerUtil.convertUsToMs(drainTimeUs), info.batteryPercentString, - basedOnUsage && !shortString + estimate.isBasedOnUsage && !shortString ); } else { info.remainingLabel = null; diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java index 10bc85343e9..3a84026e7c9 100644 --- a/src/com/android/settings/fuelgauge/BatteryUtils.java +++ b/src/com/android/settings/fuelgauge/BatteryUtils.java @@ -438,14 +438,15 @@ public class BatteryUtils { if (estimate != null) { batteryInfo = BatteryInfo.getBatteryInfo(mContext, batteryBroadcast, stats, - elapsedRealtimeUs, false /* shortString */, - PowerUtil.convertMsToUs(estimate.estimateMillis), - estimate.isBasedOnUsage); + estimate, elapsedRealtimeUs, false /* shortString */); } else { + estimate = new Estimate( + PowerUtil.convertUsToMs(stats.computeBatteryTimeRemaining(elapsedRealtimeUs)), + false, + Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN + ); batteryInfo = BatteryInfo.getBatteryInfo(mContext, batteryBroadcast, stats, - elapsedRealtimeUs, false /* shortString */, - discharging ? stats.computeBatteryTimeRemaining(elapsedRealtimeUs) : 0, - false /* basedOnUsage */); + estimate, elapsedRealtimeUs, false /* shortString */); } BatteryUtils.logRuntime(tag, "BatteryInfoLoader.loadInBackground", startTime); diff --git a/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java b/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java index 509f96758d2..784902fca79 100644 --- a/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java +++ b/src/com/android/settings/fuelgauge/DebugEstimatesLoader.java @@ -58,12 +58,10 @@ public class DebugEstimatesLoader extends AsyncLoader> { Estimate estimate = powerUsageFeatureProvider.getEnhancedBatteryPrediction(context); if (estimate == null) { - estimate = new Estimate(0, false); + estimate = new Estimate(0, false, Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN); } BatteryInfo newInfo = BatteryInfo.getBatteryInfo(getContext(), batteryBroadcast, stats, - elapsedRealtimeUs, false, - PowerUtil.convertMsToUs(estimate.estimateMillis), - estimate.isBasedOnUsage); + estimate, elapsedRealtimeUs, false); List infos = new ArrayList<>(); infos.add(oldinfo); diff --git a/src/com/android/settings/fuelgauge/Estimate.java b/src/com/android/settings/fuelgauge/Estimate.java index 541678c91fa..f59bbf15ac1 100644 --- a/src/com/android/settings/fuelgauge/Estimate.java +++ b/src/com/android/settings/fuelgauge/Estimate.java @@ -2,11 +2,17 @@ package com.android.settings.fuelgauge; public class Estimate { - public final long estimateMillis; - public final boolean isBasedOnUsage; + // Value to indicate averageTimeToDischarge could not be obtained + public static final int AVERAGE_TIME_TO_DISCHARGE_UNKNOWN = -1; - public Estimate(long estimateMillis, boolean isBasedOnUsage) { - this.estimateMillis = estimateMillis; - this.isBasedOnUsage = isBasedOnUsage; - } + public final long estimateMillis; + public final boolean isBasedOnUsage; + public final long averageDischargeTime; + + public Estimate(long estimateMillis, boolean isBasedOnUsage, + long averageDischargeTime) { + this.estimateMillis = estimateMillis; + this.isBasedOnUsage = isBasedOnUsage; + this.averageDischargeTime = averageDischargeTime; + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java index bfd117d18c1..654f7fc5a83 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryInfoTest.java @@ -63,7 +63,6 @@ public class BatteryInfoTest { private static final String STATUS_CHARGING_NO_TIME = "50% - charging"; private static final String STATUS_CHARGING_TIME = "50% - 0m until fully charged"; private static final String STATUS_NOT_CHARGING = "Not charging"; - private static final int PLUGGED_IN = 1; private static final long REMAINING_TIME_NULL = -1; private static final long REMAINING_TIME = 2; private static final String ENHANCED_STRING_SUFFIX = "based on your usage"; @@ -72,6 +71,11 @@ public class BatteryInfoTest { "1m left until fully charged"; private static final String TEST_BATTERY_LEVEL_10 = "10%"; private static final String FIFTEEN_MIN_FORMATTED = "15m"; + public static final Estimate DUMMY_ESTIMATE = new Estimate( + 1000, /* estimateMillis */ + false, /* isBasedOnUsage */ + 1000 /* averageDischargeTime */); + private Intent mDisChargingBatteryBroadcast; private Intent mChargingBatteryBroadcast; private Context mContext; @@ -132,14 +136,15 @@ public class BatteryInfoTest { @Test public void testGetBatteryInfo_basedOnUsageTrueMoreThanFifteenMinutes_usesCorrectString() { + Estimate estimate = new Estimate(Duration.ofHours(4).toMillis(), + true /* isBasedOnUsage */, + 1000 /* averageDischargeTime */); BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */, - PowerUtil.convertMsToUs(Duration.ofHours(4).toMillis()), - true /* basedOnUsage */); + mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000, + false /* shortString */); BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */, - PowerUtil.convertMsToUs(Duration.ofHours(4).toMillis()), - true /* basedOnUsage */); + mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000, + true /* shortString */); // We only add special mention for the long string assertThat(info.remainingLabel.toString()).contains(ENHANCED_STRING_SUFFIX); @@ -149,14 +154,15 @@ public class BatteryInfoTest { @Test public void testGetBatteryInfo_basedOnUsageTrueLessThanSevenMinutes_usesCorrectString() { + Estimate estimate = new Estimate(Duration.ofMinutes(7).toMillis(), + true /* isBasedOnUsage */, + 1000 /* averageDischargeTime */); BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */, - PowerUtil.convertMsToUs(Duration.ofMinutes(7).toMillis()), - true /* basedOnUsage */); + mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000, + false /* shortString */); BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */, - PowerUtil.convertMsToUs(Duration.ofMinutes(7).toMillis()), - true /* basedOnUsage */); + mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000, + true /* shortString */); // These should be identical in either case assertThat(info.remainingLabel.toString()).isEqualTo( @@ -167,10 +173,12 @@ public class BatteryInfoTest { @Test public void testGetBatteryInfo_basedOnUsageTrueBetweenSevenAndFifteenMinutes_usesCorrectString() { + Estimate estimate = new Estimate(Duration.ofMinutes(10).toMillis(), + true /* isBasedOnUsage */, + 1000 /* averageDischargeTime */); BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */, - PowerUtil.convertMsToUs(Duration.ofMinutes(10).toMillis()), - true /* basedOnUsage */); + mBatteryStats, estimate, SystemClock.elapsedRealtime() * 1000, + false /* shortString */); // Check that strings are showing less than 15 minutes remaining regardless of exact time. assertThat(info.chargeLabel.toString()).isEqualTo( @@ -184,11 +192,11 @@ public class BatteryInfoTest { @Test public void testGetBatteryInfo_basedOnUsageFalse_usesDefaultString() { BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */, - 1000, false /* basedOnUsage */); + mBatteryStats, DUMMY_ESTIMATE, SystemClock.elapsedRealtime() * 1000, + false /* shortString */); BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */, - 1000, false /* basedOnUsage */); + mBatteryStats, DUMMY_ESTIMATE, SystemClock.elapsedRealtime() * 1000, + true /* shortString */); assertThat(info.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX); assertThat(info2.remainingLabel.toString()).doesNotContain(ENHANCED_STRING_SUFFIX); @@ -199,8 +207,10 @@ public class BatteryInfoTest { doReturn(TEST_CHARGE_TIME_REMAINING) .when(mBatteryStats) .computeChargeTimeRemaining(anyLong()); + BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, false, 1000, false); + mBatteryStats, DUMMY_ESTIMATE, SystemClock.elapsedRealtime() * 1000, + false /* shortString */); assertThat(info.remainingTimeUs).isEqualTo(TEST_CHARGE_TIME_REMAINING); assertThat(info.remainingLabel.toString()) .isEqualTo(TEST_CHARGE_TIME_REMAINING_STRINGIFIED); @@ -211,8 +221,8 @@ public class BatteryInfoTest { mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_LEVEL, 100); BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */, - 1000, false /* basedOnUsage */); + mBatteryStats, DUMMY_ESTIMATE, SystemClock.elapsedRealtime() * 1000, + false /* shortString */); assertThat(info.chargeLabel).isEqualTo("100%"); } @@ -296,10 +306,13 @@ public class BatteryInfoTest { } else { doReturn(0L).when(mBatteryStats).computeChargeTimeRemaining(anyLong()); } + Estimate batteryEstimate = new Estimate( + estimate ? 1000 : 0, + false /* isBasedOnUsage */, + 1000 /* averageDischargeTime */); BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, charging ? mChargingBatteryBroadcast : mDisChargingBatteryBroadcast, - mBatteryStats, SystemClock.elapsedRealtime() * 1000, false, - estimate ? 1000 : 0 /* drainTimeUs */, false); + mBatteryStats, batteryEstimate, SystemClock.elapsedRealtime() * 1000, false); doReturn(enhanced).when(mFeatureFactory.powerUsageFeatureProvider) .isEnhancedBatteryPredictionEnabled(mContext); return info;