diff --git a/res/xml/power_usage_advanced.xml b/res/xml/power_usage_advanced.xml index 6422a75647b..3deec0954dd 100644 --- a/res/xml/power_usage_advanced.xml +++ b/res/xml/power_usage_advanced.xml @@ -25,40 +25,6 @@ - - - - - - - - - - - - - - - - - - + android:title="@string/battery_detail_since_full_charge"/> diff --git a/src/com/android/settings/fuelgauge/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/PowerGaugePreference.java index 1d3d62b6e8e..b067edf6b07 100644 --- a/src/com/android/settings/fuelgauge/PowerGaugePreference.java +++ b/src/com/android/settings/fuelgauge/PowerGaugePreference.java @@ -49,13 +49,8 @@ public class PowerGaugePreference extends TintablePreference { mIconSize = context.getResources().getDimensionPixelSize(R.dimen.app_icon_size); } - public PowerGaugePreference(Context context, AttributeSet attrs) { - super(context, attrs); - final Drawable icon = context.getDrawable(R.drawable.ic_battery_circle); - - setIcon(icon); - setWidgetLayoutResource(R.layout.preference_widget_summary); - mIconSize = icon.getIntrinsicWidth(); + public PowerGaugePreference(Context context) { + this(context, null, null, null); } public void setContentDescription(String name) { diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java index 4ccf9f7437e..f9f914c5636 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java +++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java @@ -19,8 +19,10 @@ import android.os.Process; import android.provider.SearchIndexableResource; import android.support.annotation.ColorInt; import android.support.annotation.IntDef; +import android.support.annotation.NonNull; +import android.support.annotation.StringRes; import android.support.annotation.VisibleForTesting; -import android.util.SparseArray; +import android.support.v7.preference.PreferenceGroup; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatterySipper.DrainType; @@ -35,32 +37,37 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; public class PowerUsageAdvanced extends PowerUsageBase { private static final String TAG = "AdvancedBatteryUsage"; private static final String KEY_BATTERY_GRAPH = "battery_graph"; - private static final String KEY_BATTERY_APPS = "battery_apps"; - private static final String KEY_BATTERY_WIFI = "battery_wifi"; - private static final String KEY_BATTERY_CELL = "battery_cell"; - private static final String KEY_BATTERY_BLUETOOTH = "battery_bluetooth"; - private static final String KEY_BATTERY_IDLE = "battery_idle"; - private static final String KEY_BATTERY_SERVICE = "battery_service"; - private static final String KEY_BATTERY_SYSTEM = "battery_system"; - private static final String KEY_BATTERY_USER = "battery_user"; + private static final String KEY_BATTERY_USAGE_LIST = "battery_usage_list"; - private BatteryHistoryPreference mHistPref; @VisibleForTesting - SparseArray mUsageTypeMap; + final int[] mUsageTypes = { + UsageType.WIFI, + UsageType.CELL, + UsageType.SERVICE, + UsageType.SYSTEM, + UsageType.BLUETOOTH, + UsageType.USER, + UsageType.IDLE, + UsageType.APP}; + private BatteryHistoryPreference mHistPref; + private PreferenceGroup mUsageListGroup; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_GRAPH); - init(); + mUsageListGroup = (PreferenceGroup) findPreference(KEY_BATTERY_USAGE_LIST); } @Override @@ -96,12 +103,15 @@ public class PowerUsageAdvanced extends PowerUsageBase { updatePreference(mHistPref); List dataList = parsePowerUsageData(mStatsHelper); + mUsageListGroup.removeAll(); for (int i = 0, size = dataList.size(); i < size; i++) { - final PowerUsageData data = dataList.get(i); - final String key = mUsageTypeMap.get(data.usageType); - if (key != null) { - bindData(key, data); - } + final PowerUsageData batteryData = dataList.get(i); + final PowerGaugePreference pref = new PowerGaugePreference(getContext()); + + pref.setTitle(batteryData.titleResId); + pref.setSummary(batteryData.summary); + pref.setPercent(batteryData.percentage); + mUsageListGroup.addPreference(pref); } } @@ -128,28 +138,13 @@ public class PowerUsageAdvanced extends PowerUsageBase { } } - @VisibleForTesting - void init() { - // Store projection from UsageType to preference key - mUsageTypeMap = new SparseArray<>(); - mUsageTypeMap.put(UsageType.APP, KEY_BATTERY_APPS); - mUsageTypeMap.put(UsageType.WIFI, KEY_BATTERY_WIFI); - mUsageTypeMap.put(UsageType.CELL, KEY_BATTERY_CELL); - mUsageTypeMap.put(UsageType.BLUETOOTH, KEY_BATTERY_BLUETOOTH); - mUsageTypeMap.put(UsageType.IDLE, KEY_BATTERY_IDLE); - mUsageTypeMap.put(UsageType.SERVICE, KEY_BATTERY_SERVICE); - mUsageTypeMap.put(UsageType.USER, KEY_BATTERY_USER); - mUsageTypeMap.put(UsageType.SYSTEM, KEY_BATTERY_SYSTEM); - } - @VisibleForTesting List parsePowerUsageData(BatteryStatsHelper statusHelper) { final List batterySippers = statusHelper.getUsageList(); final Map batteryDataMap = new HashMap<>(); - for (int i = 0, size = mUsageTypeMap.size(); i < size; i++) { - @UsageType final int type = mUsageTypeMap.keyAt(i); - batteryDataMap.put(type, PowerUsageData.createBatteryUsageData(type)); + for (final @UsageType Integer type : mUsageTypes) { + batteryDataMap.put(type, new PowerUsageData(type)); } // Accumulate power usage based on usage type @@ -165,21 +160,17 @@ public class PowerUsageAdvanced extends PowerUsageBase { usageData.percentage = (usageData.totalPowerMah / totalPower) * 100; } + Collections.sort(batteryDataList); + return batteryDataList; } - private void bindData(String key, PowerUsageData batteryData) { - final PowerGaugePreference pref = (PowerGaugePreference) findPreference(key); - - pref.setSummary(batteryData.summary); - pref.setPercent(batteryData.percentage); - } - /** * Class that contains data used in {@link PowerGaugePreference}. */ @VisibleForTesting - static class PowerUsageData { + static class PowerUsageData implements Comparable { + @Retention(RetentionPolicy.SOURCE) @IntDef({UsageType.APP, UsageType.WIFI, @@ -200,6 +191,8 @@ public class PowerUsageAdvanced extends PowerUsageBase { int IDLE = 7; } + @StringRes + public int titleResId; public String summary; public double percentage; public double totalPowerMah; @@ -208,14 +201,43 @@ public class PowerUsageAdvanced extends PowerUsageBase { @UsageType public int usageType; - private PowerUsageData(@UsageType int usageType) { - this.usageType = usageType; - totalPowerMah = 0; + public PowerUsageData(@UsageType int usageType) { + this(usageType, 0); } - public static PowerUsageData createBatteryUsageData(@UsageType int usageType) { - // TODO(b/34385770): add color logic in this part - return new PowerUsageData(usageType); + public PowerUsageData(@UsageType int usageType, double totalPower) { + this.usageType = usageType; + totalPowerMah = 0; + titleResId = getTitleResId(usageType); + totalPowerMah = totalPower; + } + + private int getTitleResId(@UsageType int usageType) { + switch (usageType) { + case UsageType.WIFI: + return R.string.power_wifi; + case UsageType.CELL: + return R.string.power_cell; + case UsageType.SERVICE: + return R.string.power_service; + case UsageType.SYSTEM: + return R.string.power_system; + case UsageType.BLUETOOTH: + return R.string.power_bluetooth; + case UsageType.USER: + return R.string.power_user; + case UsageType.IDLE: + return R.string.power_idle; + case UsageType.APP: + default: + return R.string.power_apps; + } + } + + @Override + public int compareTo(@NonNull PowerUsageData powerUsageData) { + final int diff = Double.compare(powerUsageData.totalPowerMah, totalPowerMah); + return diff != 0 ? diff : usageType - powerUsageData.usageType; } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java index 17cd223fc08..f6b76e9f7ed 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java @@ -1,7 +1,6 @@ package com.android.settings.fuelgauge; import android.os.Process; -import android.util.SparseArray; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatterySipper.DrainType; import com.android.internal.os.BatteryStatsHelper; @@ -17,7 +16,9 @@ import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Set; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; @@ -33,7 +34,6 @@ public class PowerUsageAdvancedTest { private static final double TOTAL_USAGE = TYPE_APP_USAGE * 2 + TYPE_BLUETOOTH_USAGE + TYPE_WIFI_USAGE; private static final double PRECISION = 0.001; - private static final String STRING_NOT_FOUND = "not_found"; @Mock private BatterySipper mBatterySipper; @Mock @@ -92,7 +92,6 @@ public class PowerUsageAdvancedTest { final double percentWifi = TYPE_WIFI_USAGE / TOTAL_USAGE * 100; final double percentBluetooth = TYPE_BLUETOOTH_USAGE / TOTAL_USAGE * 100; - mPowerUsageAdvanced.init(); List batteryData = mPowerUsageAdvanced.parsePowerUsageData(mBatteryStatsHelper); for (PowerUsageData data : batteryData) { @@ -114,24 +113,24 @@ public class PowerUsageAdvancedTest { @Test public void testInit_ContainsAllUsageType() { - mPowerUsageAdvanced.init(); - final SparseArray array = mPowerUsageAdvanced.mUsageTypeMap; + final int[] usageTypeSet = mPowerUsageAdvanced.mUsageTypes; - assertThat(array.get(UsageType.APP, STRING_NOT_FOUND)) - .isNotEqualTo(STRING_NOT_FOUND); - assertThat(array.get(UsageType.WIFI, STRING_NOT_FOUND)) - .isNotEqualTo(STRING_NOT_FOUND); - assertThat(array.get(UsageType.CELL, STRING_NOT_FOUND)) - .isNotEqualTo(STRING_NOT_FOUND); - assertThat(array.get(UsageType.BLUETOOTH, STRING_NOT_FOUND)) - .isNotEqualTo(STRING_NOT_FOUND); - assertThat(array.get(UsageType.IDLE, STRING_NOT_FOUND)) - .isNotEqualTo(STRING_NOT_FOUND); - assertThat(array.get(UsageType.SERVICE, STRING_NOT_FOUND)) - .isNotEqualTo(STRING_NOT_FOUND); - assertThat(array.get(UsageType.USER, STRING_NOT_FOUND)) - .isNotEqualTo(STRING_NOT_FOUND); - assertThat(array.get(UsageType.SYSTEM, STRING_NOT_FOUND)) - .isNotEqualTo(STRING_NOT_FOUND); + assertThat(usageTypeSet).asList().containsExactly(UsageType.APP, UsageType.WIFI, + UsageType.CELL, UsageType.BLUETOOTH, UsageType.IDLE, UsageType.SERVICE, + UsageType.USER, UsageType.SYSTEM); + } + + @Test + public void testPowerUsageData_SortedByUsage() { + List dataList = new ArrayList<>(); + + dataList.add(new PowerUsageData(UsageType.WIFI, TYPE_WIFI_USAGE)); + dataList.add(new PowerUsageData(UsageType.BLUETOOTH, TYPE_BLUETOOTH_USAGE)); + dataList.add(new PowerUsageData(UsageType.APP, TYPE_APP_USAGE)); + Collections.sort(dataList); + + for (int i = 1, size = dataList.size(); i < size; i++) { + assertThat(dataList.get(i - 1).totalPowerMah).isAtLeast(dataList.get(i).totalPowerMah); + } } }