From 2def5ccb6c1041e59e8f13035dd297192fcc103e Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Tue, 18 Dec 2018 15:20:22 -0800 Subject: [PATCH] Fix crash in BatteryUtils When enhanced estimation is enabled, it may still have malfunction when getting data from it. This CL handles this case and fall back to default estimation. Change-Id: Id8d75b07316afa8a73a302b49dc7f8e8b77d4fa4 Fixes: 121213171 Test: RunSettingsRoboTests --- .../settings/fuelgauge/BatteryUtils.java | 6 +++-- .../settings/fuelgauge/BatteryUtilsTest.java | 26 ++++++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java index c0712842706..6f779535943 100644 --- a/src/com/android/settings/fuelgauge/BatteryUtils.java +++ b/src/com/android/settings/fuelgauge/BatteryUtils.java @@ -449,12 +449,14 @@ public class BatteryUtils { final BatteryStats stats = statsHelper.getStats(); BatteryInfo batteryInfo; - final Estimate estimate; + Estimate estimate = null; // Get enhanced prediction if available if (mPowerUsageFeatureProvider != null && mPowerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(mContext)) { estimate = mPowerUsageFeatureProvider.getEnhancedBatteryPrediction(mContext); - } else { + } + + if (estimate == null) { estimate = new Estimate( PowerUtil.convertUsToMs(stats.computeBatteryTimeRemaining(elapsedRealtimeUs)), false /* isBasedOnUsage */, diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java index 7c455bbdd7b..a60460b8ce2 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java @@ -27,6 +27,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -38,7 +39,10 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -75,6 +79,8 @@ import java.util.List; @RunWith(RobolectricTestRunner.class) public class BatteryUtilsTest { + private static final String TAG = "BatteryUtilsTest"; + // unit that used to converted ms to us private static final long UNIT = 1000; private static final long TIME_STATE_TOP = 1500 * UNIT; @@ -160,6 +166,7 @@ public class BatteryUtilsTest { private FakeFeatureFactory mFeatureFactory; private PowerUsageFeatureProvider mProvider; private List mUsageList; + private Context mContext; @Before public void setUp() throws PackageManager.NameNotFoundException { @@ -214,10 +221,10 @@ public class BatteryUtilsTest { mIdleBatterySipper.drainType = BatterySipper.DrainType.IDLE; mIdleBatterySipper.totalPowerMah = BATTERY_IDLE_USAGE; - final Context shadowContext = spy(RuntimeEnvironment.application); - doReturn(mPackageManager).when(shadowContext).getPackageManager(); - doReturn(mAppOpsManager).when(shadowContext).getSystemService(Context.APP_OPS_SERVICE); - mBatteryUtils = spy(new BatteryUtils(shadowContext)); + mContext = spy(RuntimeEnvironment.application); + doReturn(mPackageManager).when(mContext).getPackageManager(); + doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE); + mBatteryUtils = spy(new BatteryUtils(mContext)); mBatteryUtils.mPowerUsageFeatureProvider = mProvider; doReturn(0L).when(mBatteryUtils) .getForegroundServiceTotalTimeUs(any(BatteryStats.Uid.class), anyLong()); @@ -710,4 +717,15 @@ public class BatteryUtilsTest { verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); } + + @Test + public void getBatteryInfo_providerNull_shouldNotCrash() { + when(mProvider.isEnhancedBatteryPredictionEnabled(mContext)).thenReturn(true); + when(mProvider.getEnhancedBatteryPrediction(mContext)).thenReturn(null); + when(mContext.registerReceiver(nullable(BroadcastReceiver.class), + any(IntentFilter.class))).thenReturn(new Intent()); + + //Should not crash + assertThat(mBatteryUtils.getBatteryInfo(mBatteryStatsHelper, TAG)).isNotNull(); + } }