From 906055e38338dd1b1cf82a622c358fb157ac7af3 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Fri, 24 Feb 2017 13:03:35 -0800 Subject: [PATCH] Add NPE check for screen and cellular update. When battery is full of charge, usageList in BatteryStatsHelper will be empty. As a result, we cannot find BatterySipper with type screen and cell, which creates the null pointer error. In this cl, I add NPE check for sipper. When sipper is null, all data will be set to default value. I also add check for totalPower so we won't have divided by zero error. Bug: 35757789 Test: RunSettingsRoboTests Change-Id: I80f3c0c542e0a50868e7c314a8d9b3c17999d8c6 --- .../android/settings/fuelgauge/PowerUsageSummary.java | 15 ++++++++++----- .../settings/fuelgauge/PowerUsageSummaryTest.java | 17 ++++++++++++++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index c44a3735d1..180618dd07 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -422,7 +422,7 @@ public class PowerUsageSummary extends PowerUsageBase { // With deduction in totalPower, percentOfTotal is higher because it adds the part // used in screen, system, etc - final double percentOfTotal = + final double percentOfTotal = totalPower == 0 ? 0 : ((sipper.totalPowerMah / totalPower) * dischargeAmount); if (((int) (percentOfTotal + .5)) < 1) { @@ -513,10 +513,12 @@ public class PowerUsageSummary extends PowerUsageBase { final BatterySipper sipper = findBatterySipperByType( mStatsHelper.getUsageList(), DrainType.SCREEN); final Context context = getContext(); - final double percentOfTotal = calculatePercentage(sipper.totalPowerMah, dischargeAmount); + final double totalPowerMah = sipper != null ? sipper.totalPowerMah : 0; + final long usageTimeMs = sipper != null ? sipper.usageTimeMs : 0; + final double percentOfTotal = calculatePercentage(totalPowerMah, dischargeAmount); mScreenUsagePref.setSummary(getString(R.string.battery_used_for, - Utils.formatElapsedTime(context, sipper.usageTimeMs, false))); + Utils.formatElapsedTime(context, usageTimeMs, false))); mScreenConsumptionPref.setSummary(getString(R.string.battery_overall_usage, Utils.formatPercentage(percentOfTotal, true))); } @@ -525,7 +527,8 @@ public class PowerUsageSummary extends PowerUsageBase { void updateCellularPreference(final int dischargeAmount) { final BatterySipper sipper = findBatterySipperByType( mStatsHelper.getUsageList(), DrainType.CELL); - final double percentOfTotal = calculatePercentage(sipper.totalPowerMah, dischargeAmount); + final double totalPowerMah = sipper != null ? sipper.totalPowerMah : 0; + final double percentOfTotal = calculatePercentage(totalPowerMah, dischargeAmount); mCellularNetworkPref.setSummary(getString(R.string.battery_overall_usage, Utils.formatPercentage(percentOfTotal, true))); } @@ -556,7 +559,9 @@ public class PowerUsageSummary extends PowerUsageBase { @VisibleForTesting double calculatePercentage(double powerUsage, double dischargeAmount) { - return ((powerUsage / mStatsHelper.getTotalPower()) * dischargeAmount); + final double totalPower = mStatsHelper.getTotalPower(); + return totalPower == 0 ? 0 : + ((powerUsage / totalPower) * dischargeAmount); } @VisibleForTesting diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java index dab39e4c26..4e7b715377 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java @@ -40,6 +40,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; +import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; @@ -180,6 +181,9 @@ public class PowerUsageSummaryTest { mPowerUsageSummary.mStatsHelper = mBatteryHelper; when(mBatteryHelper.getUsageList()).thenReturn(mUsageList); + mPowerUsageSummary.mScreenUsagePref = mScreenUsagePref; + mPowerUsageSummary.mScreenConsumptionPref = mScreenConsumptionPref; + mPowerUsageSummary.mCellularNetworkPref = mCellularNetworkPref; } @Test @@ -384,7 +388,6 @@ public class PowerUsageSummaryTest { @Test public void testUpdateCellularPreference_ShowCorrectSummary() { - mPowerUsageSummary.mCellularNetworkPref = mCellularNetworkPref; final double percent = POWER_MAH / TOTAL_POWER * DISCHARGE_AMOUNT; final String expectedSummary = mRealContext.getString(R.string.battery_overall_usage, Utils.formatPercentage((int) percent)); @@ -397,8 +400,6 @@ public class PowerUsageSummaryTest { @Test public void testUpdateScreenPreference_ShowCorrectSummary() { - mPowerUsageSummary.mScreenUsagePref = mScreenUsagePref; - mPowerUsageSummary.mScreenConsumptionPref = mScreenConsumptionPref; final String expectedUsedTime = mRealContext.getString(R.string.battery_used_for, Utils.formatElapsedTime(mRealContext, USAGE_TIME_MS, false)); final double percent = BATTERY_SCREEN_USAGE / TOTAL_POWER * DISCHARGE_AMOUNT; @@ -416,6 +417,16 @@ public class PowerUsageSummaryTest { } @Test + public void testUpdatePreference_UsageListEmpty_ShouldNotCrash() { + when(mBatteryHelper.getUsageList()).thenReturn(new ArrayList()); + doReturn("").when(mPowerUsageSummary).getString(anyInt(), Matchers.anyObject()); + + // Should not crash when update + mPowerUsageSummary.updateScreenPreference(DISCHARGE_AMOUNT); + mPowerUsageSummary.updateCellularPreference(DISCHARGE_AMOUNT); + } + + @Test public void testCalculatePercentage() { final double percent = mPowerUsageSummary.calculatePercentage(POWER_MAH, DISCHARGE_AMOUNT); assertThat(percent).isWithin(PRECISION).of(POWER_USAGE_PERCENTAGE); -- 2.11.0