Break infinite refresh loop in battery estimates

There was an infinite loop that could occur in BatterySaverUtils
what was caused by battery saver utils updating the battery estimate
which then told the page to check for an estimate and then it would
repeat from there. This cleans up the logic in that loop slightly
to prevent it from refreshing more than is necessary.

Test: atest BatteryUtilsTest
Bug: 132751712
Change-Id: I918484747ecd9735315570ad608489e0f61d7578
This commit is contained in:
Salvador Martinez
2019-05-17 15:36:55 -07:00
parent 9a51ede665
commit 12731cce3d
2 changed files with 36 additions and 9 deletions

View File

@@ -55,6 +55,8 @@ import com.android.settingslib.utils.ThreadUtils;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
@@ -450,16 +452,10 @@ public class BatteryUtils {
SystemClock.elapsedRealtime()); SystemClock.elapsedRealtime());
final BatteryStats stats = statsHelper.getStats(); final BatteryStats stats = statsHelper.getStats();
BatteryInfo batteryInfo; BatteryInfo batteryInfo;
Estimate estimate = null; Estimate estimate = getEnhancedEstimate();
// Get enhanced prediction if available
if (mPowerUsageFeatureProvider != null &&
mPowerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(mContext)) {
estimate = mPowerUsageFeatureProvider.getEnhancedBatteryPrediction(mContext);
}
if (estimate != null) { // couldn't get estimate from cache or provider, use fallback
Estimate.storeCachedEstimate(mContext, estimate); if (estimate == null) {
} else {
estimate = new Estimate( estimate = new Estimate(
PowerUtil.convertUsToMs(stats.computeBatteryTimeRemaining(elapsedRealtimeUs)), PowerUtil.convertUsToMs(stats.computeBatteryTimeRemaining(elapsedRealtimeUs)),
false /* isBasedOnUsage */, false /* isBasedOnUsage */,
@@ -474,6 +470,23 @@ public class BatteryUtils {
return batteryInfo; return batteryInfo;
} }
@VisibleForTesting
Estimate getEnhancedEstimate() {
Estimate estimate = null;
// Get enhanced prediction if available
if (Duration.between(Estimate.getLastCacheUpdateTime(mContext), Instant.now())
.compareTo(Duration.ofSeconds(10)) < 0) {
estimate = Estimate.getCachedEstimateIfAvailable(mContext);
} else if (mPowerUsageFeatureProvider != null &&
mPowerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(mContext)) {
estimate = mPowerUsageFeatureProvider.getEnhancedBatteryPrediction(mContext);
if (estimate != null) {
Estimate.storeCachedEstimate(mContext, estimate);
}
}
return estimate;
}
/** /**
* Find the {@link BatterySipper} with the corresponding {@link BatterySipper.DrainType} * Find the {@link BatterySipper} with the corresponding {@link BatterySipper.DrainType}
*/ */

View File

@@ -62,6 +62,7 @@ import com.android.settings.fuelgauge.batterytip.AnomalyInfo;
import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager; import com.android.settings.fuelgauge.batterytip.BatteryDatabaseManager;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settings.testutils.shadow.ShadowThreadUtils;
import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend; import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
import org.junit.Before; import org.junit.Before;
@@ -728,4 +729,17 @@ public class BatteryUtilsTest {
//Should not crash //Should not crash
assertThat(mBatteryUtils.getBatteryInfo(mBatteryStatsHelper, TAG)).isNotNull(); assertThat(mBatteryUtils.getBatteryInfo(mBatteryStatsHelper, TAG)).isNotNull();
} }
@Test
public void getEnhancedEstimate_doesNotUpdateCache_ifEstimateFresh() {
Estimate estimate = new Estimate(1000, true, 1000);
Estimate.storeCachedEstimate(mContext, estimate);
estimate = mBatteryUtils.getEnhancedEstimate();
// only pass if estimate has not changed
assertThat(estimate).isNotNull();
assertThat(estimate.isBasedOnUsage()).isTrue();
assertThat(estimate.getAverageDischargeTime()).isEqualTo(1000);
}
} }