Distribute battery cost of screen to all the other apps.

It doesn't make sense to show battery cost of "SCREEN". In this cl, I
attribute this cost to all the other apps/services.

Bug: 34390125
Test: RunSettingsRoboTests
Change-Id: Ia6ff39d5fa21eacf1ff97a28e2ff59d1cf169885
This commit is contained in:
jackqdyulei
2017-01-18 17:08:33 -08:00
parent 2ecdc2514f
commit aedeb71d84
2 changed files with 76 additions and 33 deletions

View File

@@ -209,6 +209,7 @@ public class PowerUsageSummary extends PowerUsageBase {
* We want to coalesce some UIDs. For example, dex2oat runs under a shared gid that * We want to coalesce some UIDs. For example, dex2oat runs under a shared gid that
* exists for all users of the same app. We detect this case and merge the power use * exists for all users of the same app. We detect this case and merge the power use
* for dex2oat to the device OWNER's use of the app. * for dex2oat to the device OWNER's use of the app.
*
* @return A sorted list of apps using power. * @return A sorted list of apps using power.
*/ */
private static List<BatterySipper> getCoalescedUsageList(final List<BatterySipper> sippers) { private static List<BatterySipper> getCoalescedUsageList(final List<BatterySipper> sippers) {
@@ -314,6 +315,8 @@ public class PowerUsageSummary extends PowerUsageBase {
final List<BatterySipper> usageList = getCoalescedUsageList( final List<BatterySipper> usageList = getCoalescedUsageList(
USE_FAKE_DATA ? getFakeStats() : mStatsHelper.getUsageList()); USE_FAKE_DATA ? getFakeStats() : mStatsHelper.getUsageList());
final double screenPowerMah = removeScreenBatterySipper(usageList);
final int dischargeAmount = USE_FAKE_DATA ? 5000 final int dischargeAmount = USE_FAKE_DATA ? 5000
: stats != null ? stats.getDischargeAmount(mStatsType) : 0; : stats != null ? stats.getDischargeAmount(mStatsType) : 0;
final int numSippers = usageList.size(); final int numSippers = usageList.size();
@@ -322,9 +325,16 @@ public class PowerUsageSummary extends PowerUsageBase {
if (shouldHideSipper(sipper)) { if (shouldHideSipper(sipper)) {
continue; continue;
} }
double totalPower = USE_FAKE_DATA ? 4000 : mStatsHelper.getTotalPower();
// Deduct the screen power from total power, used to calculate percentOfTotal
double totalPower = USE_FAKE_DATA ?
4000 : mStatsHelper.getTotalPower() - screenPowerMah;
// With deduction in totalPower, percentOfTotal is higher because it adds the part
// used in screen
final double percentOfTotal = final double percentOfTotal =
((sipper.totalPowerMah / totalPower) * dischargeAmount); ((sipper.totalPowerMah / totalPower) * dischargeAmount);
if (((int) (percentOfTotal + .5)) < 1) { if (((int) (percentOfTotal + .5)) < 1) {
continue; continue;
} }
@@ -419,6 +429,19 @@ public class PowerUsageSummary extends PowerUsageBase {
} }
} }
@VisibleForTesting
double removeScreenBatterySipper(List<BatterySipper> sippers) {
for (int i = 0, size = sippers.size(); i < size; i++) {
final BatterySipper sipper = sippers.get(i);
if (sipper.drainType == DrainType.SCREEN) {
sippers.remove(i);
return sipper.totalPowerMah;
}
}
return 0;
}
private static List<BatterySipper> getFakeStats() { private static List<BatterySipper> getFakeStats() {
ArrayList<BatterySipper> stats = new ArrayList<>(); ArrayList<BatterySipper> stats = new ArrayList<>();
float use = 5; float use = 5;

View File

@@ -36,6 +36,9 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
import static com.android.settings.fuelgauge.PowerUsageBase.MENU_STATS_REFRESH; import static com.android.settings.fuelgauge.PowerUsageBase.MENU_STATS_REFRESH;
import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_ADDITIONAL_BATTERY_INFO; import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_ADDITIONAL_BATTERY_INFO;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
@@ -53,7 +56,8 @@ public class PowerUsageSummaryTest {
private static final String[] PACKAGE_NAMES = {"com.app1", "com.app2"}; private static final String[] PACKAGE_NAMES = {"com.app1", "com.app2"};
private static final int UID = 123; private static final int UID = 123;
private static final int POWER_MAH = 100; private static final int POWER_MAH = 100;
private static final double BATTERY_SCREEN_USAGE = 300;
private static final double PRECISION = 0.001;
private static final Intent ADDITIONAL_BATTERY_INFO_INTENT = private static final Intent ADDITIONAL_BATTERY_INFO_INTENT =
new Intent("com.example.app.ADDITIONAL_BATTERY_INFO"); new Intent("com.example.app.ADDITIONAL_BATTERY_INFO");
@@ -68,7 +72,9 @@ public class PowerUsageSummaryTest {
@Mock @Mock
private MenuInflater mMenuInflater; private MenuInflater mMenuInflater;
@Mock @Mock
private BatterySipper mBatterySipper; private BatterySipper mNormalBatterySipper;
@Mock
private BatterySipper mScreenBatterySipper;
private TestFragment mFragment; private TestFragment mFragment;
private FakeFeatureFactory mFeatureFactory; private FakeFeatureFactory mFeatureFactory;
@@ -95,9 +101,12 @@ public class PowerUsageSummaryTest {
mPowerUsageSummary = new PowerUsageSummary(); mPowerUsageSummary = new PowerUsageSummary();
when(mBatterySipper.getPackages()).thenReturn(PACKAGE_NAMES); when(mNormalBatterySipper.getPackages()).thenReturn(PACKAGE_NAMES);
when(mBatterySipper.getUid()).thenReturn(UID); when(mNormalBatterySipper.getUid()).thenReturn(UID);
mBatterySipper.totalPowerMah = POWER_MAH; mNormalBatterySipper.totalPowerMah = POWER_MAH;
mScreenBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
mScreenBatterySipper.totalPowerMah = BATTERY_SCREEN_USAGE;
} }
@Test @Test
@@ -129,62 +138,73 @@ public class PowerUsageSummaryTest {
@Test @Test
public void testExtractKeyFromSipper_TypeAPPUidObjectNull_ReturnPackageNames() { public void testExtractKeyFromSipper_TypeAPPUidObjectNull_ReturnPackageNames() {
mBatterySipper.uidObj = null; mNormalBatterySipper.uidObj = null;
mBatterySipper.drainType = BatterySipper.DrainType.APP; mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
final String key = mPowerUsageSummary.extractKeyFromSipper(mBatterySipper); final String key = mPowerUsageSummary.extractKeyFromSipper(mNormalBatterySipper);
assertThat(key).isEqualTo(TextUtils.concat(mBatterySipper.getPackages()).toString()); assertThat(key).isEqualTo(TextUtils.concat(mNormalBatterySipper.getPackages()).toString());
} }
@Test @Test
public void testExtractKeyFromSipper_TypeOther_ReturnDrainType() { public void testExtractKeyFromSipper_TypeOther_ReturnDrainType() {
mBatterySipper.uidObj = null; mNormalBatterySipper.uidObj = null;
mBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH; mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
final String key = mPowerUsageSummary.extractKeyFromSipper(mBatterySipper); final String key = mPowerUsageSummary.extractKeyFromSipper(mNormalBatterySipper);
assertThat(key).isEqualTo(mBatterySipper.drainType.toString()); assertThat(key).isEqualTo(mNormalBatterySipper.drainType.toString());
}
@Test
public void testRemoveScreenBatterySipper_ContainsScreenSipper_RemoveAndReturnValue() {
final List<BatterySipper> sippers = new ArrayList<>();
sippers.add(mNormalBatterySipper);
sippers.add(mScreenBatterySipper);
final double screenUsage = mPowerUsageSummary.removeScreenBatterySipper(sippers);
assertThat(sippers).containsExactly(mNormalBatterySipper);
assertThat(screenUsage).isWithin(PRECISION).of(BATTERY_SCREEN_USAGE);
} }
@Test @Test
public void testExtractKeyFromSipper_TypeAPPUidObjectNotNull_ReturnUid() { public void testExtractKeyFromSipper_TypeAPPUidObjectNotNull_ReturnUid() {
mBatterySipper.uidObj = new BatteryStatsImpl.Uid(new BatteryStatsImpl(), UID); mNormalBatterySipper.uidObj = new BatteryStatsImpl.Uid(new BatteryStatsImpl(), UID);
mBatterySipper.drainType = BatterySipper.DrainType.APP; mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
final String key = mPowerUsageSummary.extractKeyFromSipper(mBatterySipper); final String key = mPowerUsageSummary.extractKeyFromSipper(mNormalBatterySipper);
assertThat(key).isEqualTo(Integer.toString(mBatterySipper.getUid())); assertThat(key).isEqualTo(Integer.toString(mNormalBatterySipper.getUid()));
} }
@Test @Test
public void testShouldHideSipper_TypeIdle_ReturnTrue() { public void testShouldHideSipper_TypeIdle_ReturnTrue() {
mBatterySipper.drainType = BatterySipper.DrainType.IDLE; mNormalBatterySipper.drainType = BatterySipper.DrainType.IDLE;
assertThat(mPowerUsageSummary.shouldHideSipper(mBatterySipper)).isTrue(); assertThat(mPowerUsageSummary.shouldHideSipper(mNormalBatterySipper)).isTrue();
} }
@Test @Test
public void testShouldHideSipper_TypeCell_ReturnTrue() { public void testShouldHideSipper_TypeCell_ReturnTrue() {
mBatterySipper.drainType = BatterySipper.DrainType.CELL; mNormalBatterySipper.drainType = BatterySipper.DrainType.CELL;
assertThat(mPowerUsageSummary.shouldHideSipper(mBatterySipper)).isTrue(); assertThat(mPowerUsageSummary.shouldHideSipper(mNormalBatterySipper)).isTrue();
} }
@Test @Test
public void testShouldHideSipper_UidRoot_ReturnTrue() { public void testShouldHideSipper_UidRoot_ReturnTrue() {
mBatterySipper.drainType = BatterySipper.DrainType.APP; mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
when(mBatterySipper.getUid()).thenReturn(Process.ROOT_UID); when(mNormalBatterySipper.getUid()).thenReturn(Process.ROOT_UID);
assertThat(mPowerUsageSummary.shouldHideSipper(mBatterySipper)).isTrue(); assertThat(mPowerUsageSummary.shouldHideSipper(mNormalBatterySipper)).isTrue();
} }
@Test @Test
public void testShouldHideSipper_UidSystem_ReturnTrue() { public void testShouldHideSipper_UidSystem_ReturnTrue() {
mBatterySipper.drainType = BatterySipper.DrainType.APP; mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
when(mBatterySipper.getUid()).thenReturn(Process.SYSTEM_UID); when(mNormalBatterySipper.getUid()).thenReturn(Process.SYSTEM_UID);
assertThat(mPowerUsageSummary.shouldHideSipper(mBatterySipper)).isTrue(); assertThat(mPowerUsageSummary.shouldHideSipper(mNormalBatterySipper)).isTrue();
} }
@Test @Test
public void testShouldHideSipper_UidNormal_ReturnFalse() { public void testShouldHideSipper_UidNormal_ReturnFalse() {
mBatterySipper.drainType = BatterySipper.DrainType.APP; mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
when(mBatterySipper.getUid()).thenReturn(UID); when(mNormalBatterySipper.getUid()).thenReturn(UID);
assertThat(mPowerUsageSummary.shouldHideSipper(mBatterySipper)).isFalse(); assertThat(mPowerUsageSummary.shouldHideSipper(mNormalBatterySipper)).isFalse();
} }
public static class TestFragment extends PowerUsageSummary { public static class TestFragment extends PowerUsageSummary {