Loading src/com/android/settings/fuelgauge/BatteryUtils.java +17 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.os.BatteryStats; import android.os.SystemClock; import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import android.support.annotation.VisibleForTesting; import android.text.format.DateUtils; import android.util.Log; Loading @@ -29,6 +30,8 @@ import android.util.SparseLongArray; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; import java.lang.annotation.Retention; Loading Loading @@ -291,6 +294,20 @@ public class BatteryUtils { } } @StringRes public int getSummaryResIdFromAnomalyType(@Anomaly.AnomalyType int type) { switch (type) { case Anomaly.AnomalyType.WAKE_LOCK: return R.string.battery_abnormal_wakelock_summary; case Anomaly.AnomalyType.WAKEUP_ALARM: return R.string.battery_abnormal_wakeup_alarm_summary; case Anomaly.AnomalyType.BLUETOOTH_SCAN: return R.string.battery_abnormal_location_summary; default: throw new IllegalArgumentException("Incorrect anomaly type: " + type); } } public long convertUsToMs(long timeUs) { return timeUs / 1000; } Loading src/com/android/settings/fuelgauge/PowerUsageAnomalyDetails.java +5 −2 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ public class PowerUsageAnomalyDetails extends DashboardFragment implements PreferenceGroup mAbnormalListGroup; @VisibleForTesting PackageManager mPackageManager; @VisibleForTesting BatteryUtils mBatteryUtils; IconDrawableFactory mIconDrawableFactory; public static void startBatteryAbnormalPage(SettingsActivity caller, Loading @@ -78,6 +80,7 @@ public class PowerUsageAnomalyDetails extends DashboardFragment implements mAbnormalListGroup = (PreferenceGroup) findPreference(KEY_PREF_ANOMALY_LIST); mPackageManager = context.getPackageManager(); mIconDrawableFactory = IconDrawableFactory.newInstance(context, false /* EmbedShadow */); mBatteryUtils = BatteryUtils.getInstance(context); } @Override Loading Loading @@ -126,16 +129,16 @@ public class PowerUsageAnomalyDetails extends DashboardFragment implements } void refreshUi() { //TODO(b/37681665): cache the preference so we don't need to create new one every time. mAbnormalListGroup.removeAll(); for (int i = 0, size = mAnomalies.size(); i < size; i++) { final Anomaly anomaly = mAnomalies.get(i); Preference pref = new AnomalyPreference(getPrefContext(), anomaly); pref.setSummary(mBatteryUtils.getSummaryResIdFromAnomalyType(anomaly.type)); Drawable icon = getIconFromPackageName(anomaly.packageName); if (icon != null) { pref.setIcon(icon); } mAbnormalListGroup.addPreference(pref); } } Loading src/com/android/settings/fuelgauge/anomaly/AnomalyPreference.java +0 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,6 @@ public class AnomalyPreference extends Preference { public AnomalyPreference(Context context, Anomaly anomaly) { super(context); mAnomaly = anomaly; setLayoutResource(R.layout.preference_app); if (anomaly != null) { setTitle(anomaly.displayName); Loading tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.text.format.DateUtils; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.R; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.FakeFeatureFactory; Loading Loading @@ -315,6 +317,16 @@ public class BatteryUtilsTest { mBatteryStatsHelper, currentTimeMs)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS); } @Test public void testGetSummaryResIdFromAnomalyType() { assertThat(mBatteryUtils.getSummaryResIdFromAnomalyType(Anomaly.AnomalyType.WAKE_LOCK)) .isEqualTo(R.string.battery_abnormal_wakelock_summary); assertThat(mBatteryUtils.getSummaryResIdFromAnomalyType(Anomaly.AnomalyType.WAKEUP_ALARM)) .isEqualTo(R.string.battery_abnormal_wakeup_alarm_summary); assertThat(mBatteryUtils.getSummaryResIdFromAnomalyType(Anomaly.AnomalyType.BLUETOOTH_SCAN)) .isEqualTo(R.string.battery_abnormal_location_summary); } private BatterySipper createTestSmearBatterySipper(long activityTime, double totalPowerMah, int uidCode, boolean isUidNull) { final BatterySipper sipper = mock(BatterySipper.class); Loading tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetailsTest.java +26 −7 Original line number Diff line number Diff line Loading @@ -60,8 +60,10 @@ import java.util.List; public class PowerUsageAnomalyDetailsTest { private static final String NAME_APP_1 = "app1"; private static final String NAME_APP_2 = "app2"; private static final String NAME_APP_3 = "app3"; private static final String PACKAGE_NAME_1 = "com.android.app1"; private static final String PACKAGE_NAME_2 = "com.android.app2"; private static final String PACKAGE_NAME_3 = "com.android.app3"; @Mock private SettingsActivity mSettingsActivity; Loading @@ -71,6 +73,8 @@ public class PowerUsageAnomalyDetailsTest { private Drawable mDrawable1; @Mock private Drawable mDrawable2; @Mock private Drawable mDrawable3; private Context mContext; private PowerUsageAnomalyDetails mFragment; private PreferenceGroup mAbnormalListGroup; Loading @@ -92,30 +96,36 @@ public class PowerUsageAnomalyDetailsTest { .build(); mAnomalyList.add(anomaly1); Anomaly anomaly2 = new Anomaly.Builder() .setType(Anomaly.AnomalyType.WAKE_LOCK) .setType(Anomaly.AnomalyType.WAKEUP_ALARM) .setPackageName(PACKAGE_NAME_2) .setDisplayName(NAME_APP_2) .build(); mAnomalyList.add(anomaly2); Anomaly anomaly3 = new Anomaly.Builder() .setType(Anomaly.AnomalyType.BLUETOOTH_SCAN) .setPackageName(PACKAGE_NAME_3) .setDisplayName(NAME_APP_3) .build(); mAnomalyList.add(anomaly3); mFragment = spy(new PowerUsageAnomalyDetails()); doReturn(null).when(mFragment).getIconFromPackageName(any()); mFragment.mAbnormalListGroup = mAbnormalListGroup; mFragment.mAnomalies = mAnomalyList; mFragment.mBatteryUtils = new BatteryUtils(mContext); doReturn(mPreferenceManager).when(mFragment).getPreferenceManager(); doReturn(mContext).when(mPreferenceManager).getContext(); } @Test public void testRefreshUi_dataCorrect() { final List<Anomaly> testAnomalyList = new ArrayList<>(); public void testRefreshUi_displayCorrectTitleAndSummary() { final List<Preference> testPreferences = new ArrayList<>(); final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass( Preference.class); Answer<Void> prefCallable = new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { testAnomalyList.add( ((AnomalyPreference) preferenceCaptor.getValue()).getAnomaly()); testPreferences.add(preferenceCaptor.getValue()); return null; } }; Loading @@ -123,13 +133,22 @@ public class PowerUsageAnomalyDetailsTest { mFragment.refreshUi(); assertThat(testAnomalyList).containsExactlyElementsIn(mAnomalyList); final Preference wakelockPreference = testPreferences.get(0); assertThat(wakelockPreference.getTitle()).isEqualTo(NAME_APP_1); assertThat(wakelockPreference.getSummary()).isEqualTo("Keeping device awake"); final Preference wakeupPreference = testPreferences.get(1); assertThat(wakeupPreference.getTitle()).isEqualTo(NAME_APP_2); assertThat(wakeupPreference.getSummary()).isEqualTo("Waking up device in background"); final Preference bluetoothPreference = testPreferences.get(2); assertThat(bluetoothPreference.getTitle()).isEqualTo(NAME_APP_3); assertThat(bluetoothPreference.getSummary()).isEqualTo("Requesting location frequently"); } @Test public void testRefreshUi_iconCorrect() { doReturn(mDrawable1).when(mFragment).getIconFromPackageName(PACKAGE_NAME_1); doReturn(mDrawable2).when(mFragment).getIconFromPackageName(PACKAGE_NAME_2); doReturn(mDrawable3).when(mFragment).getIconFromPackageName(PACKAGE_NAME_3); final List<Drawable> testIcons = new ArrayList<>(); final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass( Loading @@ -145,7 +164,7 @@ public class PowerUsageAnomalyDetailsTest { mFragment.refreshUi(); assertThat(testIcons).containsExactly(mDrawable1, mDrawable2); assertThat(testIcons).containsExactly(mDrawable1, mDrawable2, mDrawable3); } @Test Loading Loading
src/com/android/settings/fuelgauge/BatteryUtils.java +17 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.os.BatteryStats; import android.os.SystemClock; import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.support.annotation.StringRes; import android.support.annotation.VisibleForTesting; import android.text.format.DateUtils; import android.util.Log; Loading @@ -29,6 +30,8 @@ import android.util.SparseLongArray; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.overlay.FeatureFactory; import java.lang.annotation.Retention; Loading Loading @@ -291,6 +294,20 @@ public class BatteryUtils { } } @StringRes public int getSummaryResIdFromAnomalyType(@Anomaly.AnomalyType int type) { switch (type) { case Anomaly.AnomalyType.WAKE_LOCK: return R.string.battery_abnormal_wakelock_summary; case Anomaly.AnomalyType.WAKEUP_ALARM: return R.string.battery_abnormal_wakeup_alarm_summary; case Anomaly.AnomalyType.BLUETOOTH_SCAN: return R.string.battery_abnormal_location_summary; default: throw new IllegalArgumentException("Incorrect anomaly type: " + type); } } public long convertUsToMs(long timeUs) { return timeUs / 1000; } Loading
src/com/android/settings/fuelgauge/PowerUsageAnomalyDetails.java +5 −2 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ public class PowerUsageAnomalyDetails extends DashboardFragment implements PreferenceGroup mAbnormalListGroup; @VisibleForTesting PackageManager mPackageManager; @VisibleForTesting BatteryUtils mBatteryUtils; IconDrawableFactory mIconDrawableFactory; public static void startBatteryAbnormalPage(SettingsActivity caller, Loading @@ -78,6 +80,7 @@ public class PowerUsageAnomalyDetails extends DashboardFragment implements mAbnormalListGroup = (PreferenceGroup) findPreference(KEY_PREF_ANOMALY_LIST); mPackageManager = context.getPackageManager(); mIconDrawableFactory = IconDrawableFactory.newInstance(context, false /* EmbedShadow */); mBatteryUtils = BatteryUtils.getInstance(context); } @Override Loading Loading @@ -126,16 +129,16 @@ public class PowerUsageAnomalyDetails extends DashboardFragment implements } void refreshUi() { //TODO(b/37681665): cache the preference so we don't need to create new one every time. mAbnormalListGroup.removeAll(); for (int i = 0, size = mAnomalies.size(); i < size; i++) { final Anomaly anomaly = mAnomalies.get(i); Preference pref = new AnomalyPreference(getPrefContext(), anomaly); pref.setSummary(mBatteryUtils.getSummaryResIdFromAnomalyType(anomaly.type)); Drawable icon = getIconFromPackageName(anomaly.packageName); if (icon != null) { pref.setIcon(icon); } mAbnormalListGroup.addPreference(pref); } } Loading
src/com/android/settings/fuelgauge/anomaly/AnomalyPreference.java +0 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,6 @@ public class AnomalyPreference extends Preference { public AnomalyPreference(Context context, Anomaly anomaly) { super(context); mAnomaly = anomaly; setLayoutResource(R.layout.preference_app); if (anomaly != null) { setTitle(anomaly.displayName); Loading
tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.text.format.DateUtils; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.R; import com.android.settings.fuelgauge.anomaly.Anomaly; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.testutils.FakeFeatureFactory; Loading Loading @@ -315,6 +317,16 @@ public class BatteryUtilsTest { mBatteryStatsHelper, currentTimeMs)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS); } @Test public void testGetSummaryResIdFromAnomalyType() { assertThat(mBatteryUtils.getSummaryResIdFromAnomalyType(Anomaly.AnomalyType.WAKE_LOCK)) .isEqualTo(R.string.battery_abnormal_wakelock_summary); assertThat(mBatteryUtils.getSummaryResIdFromAnomalyType(Anomaly.AnomalyType.WAKEUP_ALARM)) .isEqualTo(R.string.battery_abnormal_wakeup_alarm_summary); assertThat(mBatteryUtils.getSummaryResIdFromAnomalyType(Anomaly.AnomalyType.BLUETOOTH_SCAN)) .isEqualTo(R.string.battery_abnormal_location_summary); } private BatterySipper createTestSmearBatterySipper(long activityTime, double totalPowerMah, int uidCode, boolean isUidNull) { final BatterySipper sipper = mock(BatterySipper.class); Loading
tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAnomalyDetailsTest.java +26 −7 Original line number Diff line number Diff line Loading @@ -60,8 +60,10 @@ import java.util.List; public class PowerUsageAnomalyDetailsTest { private static final String NAME_APP_1 = "app1"; private static final String NAME_APP_2 = "app2"; private static final String NAME_APP_3 = "app3"; private static final String PACKAGE_NAME_1 = "com.android.app1"; private static final String PACKAGE_NAME_2 = "com.android.app2"; private static final String PACKAGE_NAME_3 = "com.android.app3"; @Mock private SettingsActivity mSettingsActivity; Loading @@ -71,6 +73,8 @@ public class PowerUsageAnomalyDetailsTest { private Drawable mDrawable1; @Mock private Drawable mDrawable2; @Mock private Drawable mDrawable3; private Context mContext; private PowerUsageAnomalyDetails mFragment; private PreferenceGroup mAbnormalListGroup; Loading @@ -92,30 +96,36 @@ public class PowerUsageAnomalyDetailsTest { .build(); mAnomalyList.add(anomaly1); Anomaly anomaly2 = new Anomaly.Builder() .setType(Anomaly.AnomalyType.WAKE_LOCK) .setType(Anomaly.AnomalyType.WAKEUP_ALARM) .setPackageName(PACKAGE_NAME_2) .setDisplayName(NAME_APP_2) .build(); mAnomalyList.add(anomaly2); Anomaly anomaly3 = new Anomaly.Builder() .setType(Anomaly.AnomalyType.BLUETOOTH_SCAN) .setPackageName(PACKAGE_NAME_3) .setDisplayName(NAME_APP_3) .build(); mAnomalyList.add(anomaly3); mFragment = spy(new PowerUsageAnomalyDetails()); doReturn(null).when(mFragment).getIconFromPackageName(any()); mFragment.mAbnormalListGroup = mAbnormalListGroup; mFragment.mAnomalies = mAnomalyList; mFragment.mBatteryUtils = new BatteryUtils(mContext); doReturn(mPreferenceManager).when(mFragment).getPreferenceManager(); doReturn(mContext).when(mPreferenceManager).getContext(); } @Test public void testRefreshUi_dataCorrect() { final List<Anomaly> testAnomalyList = new ArrayList<>(); public void testRefreshUi_displayCorrectTitleAndSummary() { final List<Preference> testPreferences = new ArrayList<>(); final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass( Preference.class); Answer<Void> prefCallable = new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { testAnomalyList.add( ((AnomalyPreference) preferenceCaptor.getValue()).getAnomaly()); testPreferences.add(preferenceCaptor.getValue()); return null; } }; Loading @@ -123,13 +133,22 @@ public class PowerUsageAnomalyDetailsTest { mFragment.refreshUi(); assertThat(testAnomalyList).containsExactlyElementsIn(mAnomalyList); final Preference wakelockPreference = testPreferences.get(0); assertThat(wakelockPreference.getTitle()).isEqualTo(NAME_APP_1); assertThat(wakelockPreference.getSummary()).isEqualTo("Keeping device awake"); final Preference wakeupPreference = testPreferences.get(1); assertThat(wakeupPreference.getTitle()).isEqualTo(NAME_APP_2); assertThat(wakeupPreference.getSummary()).isEqualTo("Waking up device in background"); final Preference bluetoothPreference = testPreferences.get(2); assertThat(bluetoothPreference.getTitle()).isEqualTo(NAME_APP_3); assertThat(bluetoothPreference.getSummary()).isEqualTo("Requesting location frequently"); } @Test public void testRefreshUi_iconCorrect() { doReturn(mDrawable1).when(mFragment).getIconFromPackageName(PACKAGE_NAME_1); doReturn(mDrawable2).when(mFragment).getIconFromPackageName(PACKAGE_NAME_2); doReturn(mDrawable3).when(mFragment).getIconFromPackageName(PACKAGE_NAME_3); final List<Drawable> testIcons = new ArrayList<>(); final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass( Loading @@ -145,7 +164,7 @@ public class PowerUsageAnomalyDetailsTest { mFragment.refreshUi(); assertThat(testIcons).containsExactly(mDrawable1, mDrawable2); assertThat(testIcons).containsExactly(mDrawable1, mDrawable2, mDrawable3); } @Test Loading