Loading res/values/strings.xml +13 −2 Original line number Diff line number Diff line Loading @@ -4285,8 +4285,17 @@ <!-- Display time remaining until battery is charged [CHAR_LIMIT=60] --> <string name="power_charge_remaining"><xliff:g id="until_charged">%1$s</xliff:g> to charge</string> <!-- [CHAR_LIMIT=40] Label for list of apps using battery in power use UI --> <string name="power_usage_list_summary">Use since last full charge</string> <!-- Title for the screen usage in power use UI [CHAR_LIMIT=40] --> <string name="device_screen_usage">Screen usage</string> <!-- Title for the screen consumption in power use UI(i.e. Screen consumption: 30% of battery usage) [CHAR_LIMIT=40] --> <string name="device_screen_consumption">Screen consumption</string> <!-- Title for the cellular network in power use UI(i.e. Mobile network scanning: 30% of battery usage) [CHAR_LIMIT=40] --> <string name="device_cellular_network">Mobile network scanning</string> <!-- Label for list of apps using battery in power use UI [CHAR_LIMIT=60] --> <string name="power_usage_list_summary">App usage since last full charge</string> <!-- Label for list of different types using battery in power use UI [CHAR_LIMIT=60] --> <string name="device_usage_list_summary">Device usage since last full charge</string> <!-- Battery usage since unplugged --> <string name="battery_since_unplugged">Battery use since unplugged</string> <!-- Battery usage since user reset the stats --> Loading Loading @@ -4483,6 +4492,8 @@ <!-- Description for battery usage time for an app, i.e. Used for 30min. [CHAR LIMIT=60] --> <string name="battery_used_for">Used for %1$s</string> <!-- Description for percentage of battery usage for an app, i.e. Screen: 30% of overall battery. [CHAR LIMIT=60] --> <string name="battery_overall_usage">%1$s of overall battery</string> <!-- Description for battery usage detail information since last full charge. [CHAR LIMIT=120] --> <string name="battery_detail_since_full_charge">Usage breakdown since last full charge</string> Loading res/xml/power_usage_summary.xml +18 −0 Original line number Diff line number Diff line Loading @@ -55,4 +55,22 @@ android:key="app_list" android:title="@string/power_usage_list_summary"/> <PreferenceCategory android:key="device_usage_list" android:title="@string/device_usage_list_summary"> <Preference android:key="screen_usage" android:title="@string/device_screen_usage"/> <Preference android:key="screen_consumption" android:title="@string/device_screen_consumption"/> <Preference android:key="cellular_network" android:title="@string/device_cellular_network"/> </PreferenceCategory> </PreferenceScreen> src/com/android/settings/fuelgauge/PowerGaugePreference.java +1 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ public class PowerGaugePreference extends TintablePreference { } public void setPercent(double percentOfTotal) { mProgress = Utils.formatPercentage((int) (percentOfTotal + 0.5)); mProgress = Utils.formatPercentage(percentOfTotal, true); notifyChanged(); } Loading src/com/android/settings/fuelgauge/PowerUsageSummary.java +59 −2 Original line number Diff line number Diff line Loading @@ -78,11 +78,17 @@ public class PowerUsageSummary extends PowerUsageBase { private static final boolean USE_FAKE_DATA = false; private static final String KEY_APP_LIST = "app_list"; private static final String KEY_BATTERY_HEADER = "battery_header"; private static final int MIN_POWER_THRESHOLD_MILLI_AMP = 5; private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 10; private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10; private static final int SECONDS_IN_HOUR = 60 * 60; private static final String KEY_SCREEN_USAGE = "screen_usage"; private static final String KEY_SCREEN_CONSUMPTION = "screen_consumption"; private static final String KEY_CELLULAR_NETWORK = "cellular_network"; private static final int MENU_STATS_TYPE = Menu.FIRST; private static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 3; @VisibleForTesting Loading @@ -93,6 +99,13 @@ public class PowerUsageSummary extends PowerUsageBase { @VisibleForTesting boolean mShowAllApps = false; Preference mScreenUsagePref; @VisibleForTesting Preference mScreenConsumptionPref; @VisibleForTesting Preference mCellularNetworkPref; private LayoutPreference mBatteryLayoutPref; private PreferenceGroup mAppListGroup; Loading @@ -105,6 +118,9 @@ public class PowerUsageSummary extends PowerUsageBase { mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER); mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST); mScreenUsagePref = findPreference(KEY_SCREEN_USAGE); mScreenConsumptionPref = findPreference(KEY_SCREEN_CONSUMPTION); mCellularNetworkPref = findPreference(KEY_CELLULAR_NETWORK); } @Override Loading Loading @@ -384,6 +400,11 @@ public class PowerUsageSummary extends PowerUsageBase { context.getTheme().resolveAttribute(android.R.attr.colorControlNormal, value, true); final int colorControl = context.getColor(value.resourceId); final String usedTime = context.getString(R.string.battery_used_for); final int dischargeAmount = USE_FAKE_DATA ? 5000 : stats != null ? stats.getDischargeAmount(mStatsType) : 0; updateScreenPreference(dischargeAmount); updateCellularPreference(dischargeAmount); if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP || USE_FAKE_DATA) { final List<BatterySipper> usageList = getCoalescedUsageList( Loading @@ -391,8 +412,6 @@ public class PowerUsageSummary extends PowerUsageBase { double hiddenPowerMah = mShowAllApps ? 0 : removeHiddenBatterySippers(usageList); final int dischargeAmount = USE_FAKE_DATA ? 5000 : stats != null ? stats.getDischargeAmount(mStatsType) : 0; final int numSippers = usageList.size(); for (int i = 0; i < numSippers; i++) { final BatterySipper sipper = usageList.get(i); Loading Loading @@ -478,6 +497,39 @@ public class PowerUsageSummary extends PowerUsageBase { BatteryEntry.startRequestQueue(); } @VisibleForTesting BatterySipper findBatterySipperByType(List<BatterySipper> usageList, DrainType type) { for (int i = 0, size = usageList.size(); i < size; i++) { final BatterySipper sipper = usageList.get(i); if (sipper.drainType == type) { return sipper; } } return null; } @VisibleForTesting void updateScreenPreference(final int dischargeAmount) { final BatterySipper sipper = findBatterySipperByType( mStatsHelper.getUsageList(), DrainType.SCREEN); final Context context = getContext(); final double percentOfTotal = calculatePercentage(sipper.totalPowerMah, dischargeAmount); mScreenUsagePref.setSummary(getString(R.string.battery_used_for, Utils.formatElapsedTime(context, sipper.usageTimeMs, false))); mScreenConsumptionPref.setSummary(getString(R.string.battery_overall_usage, Utils.formatPercentage(percentOfTotal, true))); } @VisibleForTesting void updateCellularPreference(final int dischargeAmount) { final BatterySipper sipper = findBatterySipperByType( mStatsHelper.getUsageList(), DrainType.CELL); final double percentOfTotal = calculatePercentage(sipper.totalPowerMah, dischargeAmount); mCellularNetworkPref.setSummary(getString(R.string.battery_overall_usage, Utils.formatPercentage(percentOfTotal, true))); } @VisibleForTesting void updateHeaderPreference(BatteryInfo info) { final BatteryMeterView batteryView = (BatteryMeterView) mBatteryLayoutPref Loading @@ -502,6 +554,11 @@ public class PowerUsageSummary extends PowerUsageBase { batteryView.setBatteryInfo(info.mBatteryLevel); } @VisibleForTesting double calculatePercentage(double powerUsage, double dischargeAmount) { return ((powerUsage / mStatsHelper.getTotalPower()) * dischargeAmount); } @VisibleForTesting void setUsageSummary(Preference preference, String usedTimePrefix, long usageTimeMs) { // Only show summary when usage time is longer than one minute Loading tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java +99 −4 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settings.fuelgauge; import android.content.Context; import android.content.Intent; import android.os.Process; import android.support.v7.preference.Preference; import android.text.TextUtils; import android.text.format.DateUtils; import android.view.Menu; Loading @@ -26,9 +27,12 @@ import android.view.MenuItem; import android.view.View; import android.widget.TextView; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryStatsImpl; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.Utils; import com.android.settings.applications.LayoutPreference; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settingslib.BatteryInfo; Loading @@ -38,9 +42,8 @@ import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; Loading @@ -49,7 +52,10 @@ 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_TOGGLE_APPS; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; Loading @@ -59,7 +65,7 @@ import static org.mockito.Mockito.when; * Unit tests for {@link PowerUsageSummary}. */ // TODO: Improve this test class so that it starts up the real activity and fragment. @RunWith(RobolectricTestRunner.class) @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class PowerUsageSummaryTest { private static final String[] PACKAGE_NAMES = {"com.app1", "com.app2"}; Loading @@ -67,9 +73,13 @@ public class PowerUsageSummaryTest { private static final int UID = 123; private static final int POWER_MAH = 100; private static final long REMAINING_TIME_US = 100000; private static final int DISCHARGE_AMOUNT = 100; private static final long USAGE_TIME_MS = 10000; private static final double TOTAL_POWER = 200; private static final double BATTERY_SCREEN_USAGE = 300; private static final double BATTERY_SYSTEM_USAGE = 600; private static final double PRECISION = 0.001; private static final double POWER_USAGE_PERCENTAGE = 50; private static final Intent ADDITIONAL_BATTERY_INFO_INTENT = new Intent("com.example.app.ADDITIONAL_BATTERY_INFO"); Loading @@ -92,6 +102,8 @@ public class PowerUsageSummaryTest { @Mock private BatterySipper mSystemBatterySipper; @Mock private BatterySipper mCellBatterySipper; @Mock private PowerGaugePreference mPreference; @Mock private LayoutPreference mBatteryLayoutPref; Loading @@ -105,15 +117,26 @@ public class PowerUsageSummaryTest { private TextView mSummary2; @Mock private BatteryInfo mBatteryInfo; @Mock private Preference mScreenUsagePref; @Mock private Preference mScreenConsumptionPref; @Mock private Preference mCellularNetworkPref; @Mock private BatteryStatsHelper mBatteryHelper; private Context mRealContext; private TestFragment mFragment; private FakeFeatureFactory mFeatureFactory; private PowerUsageSummary mPowerUsageSummary; private List<BatterySipper> mUsageList; @Before public void setUp() { MockitoAnnotations.initMocks(this); mRealContext = RuntimeEnvironment.application; FakeFeatureFactory.setupForTest(mContext); mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); Loading @@ -129,13 +152,19 @@ public class PowerUsageSummaryTest { when(mToggleAppsMenu.getItemId()).thenReturn(MENU_TOGGLE_APPS); when(mFeatureFactory.powerUsageFeatureProvider.getAdditionalBatteryInfoIntent()) .thenReturn(ADDITIONAL_BATTERY_INFO_INTENT); when(mBatteryHelper.getTotalPower()).thenReturn(TOTAL_POWER); mPowerUsageSummary = spy(new PowerUsageSummary()); when(mPowerUsageSummary.getContext()).thenReturn(mContext); when(mPowerUsageSummary.getContext()).thenReturn(mRealContext); when(mNormalBatterySipper.getPackages()).thenReturn(PACKAGE_NAMES); when(mNormalBatterySipper.getUid()).thenReturn(UID); mNormalBatterySipper.totalPowerMah = POWER_MAH; mNormalBatterySipper.drainType = BatterySipper.DrainType.APP; mCellBatterySipper.drainType = BatterySipper.DrainType.CELL; mCellBatterySipper.totalPowerMah = POWER_MAH; when(mBatteryLayoutPref.findViewById(R.id.summary1)).thenReturn(mSummary1); when(mBatteryLayoutPref.findViewById(R.id.summary2)).thenReturn(mSummary2); when(mBatteryLayoutPref.findViewById(R.id.time)).thenReturn(mTimeText); Loading @@ -145,9 +174,19 @@ public class PowerUsageSummaryTest { mScreenBatterySipper.drainType = BatterySipper.DrainType.SCREEN; mScreenBatterySipper.totalPowerMah = BATTERY_SCREEN_USAGE; mScreenBatterySipper.usageTimeMs = USAGE_TIME_MS; mSystemBatterySipper.drainType = BatterySipper.DrainType.APP; mSystemBatterySipper.totalPowerMah = BATTERY_SYSTEM_USAGE; when(mSystemBatterySipper.getUid()).thenReturn(Process.SYSTEM_UID); mUsageList = new ArrayList<>(); mUsageList.add(mNormalBatterySipper); mUsageList.add(mScreenBatterySipper); mUsageList.add(mCellBatterySipper); mPowerUsageSummary.mStatsHelper = mBatteryHelper; when(mBatteryHelper.getUsageList()).thenReturn(mUsageList); } @Test Loading Loading @@ -326,6 +365,7 @@ public class PowerUsageSummaryTest { verify(mSummary1).setText(R.string.estimated_time_left); } private void testToggleAllApps(final boolean isShowApps) { mFragment.mShowAllApps = isShowApps; Loading @@ -333,6 +373,61 @@ public class PowerUsageSummaryTest { assertThat(mFragment.mShowAllApps).isEqualTo(!isShowApps); } @Test public void testFindBatterySipperByType_findTypeScreen() { BatterySipper sipper = mPowerUsageSummary.findBatterySipperByType(mUsageList, BatterySipper.DrainType.SCREEN); assertThat(sipper).isSameAs(mScreenBatterySipper); } @Test public void testFindBatterySipperByType_findTypeApp() { BatterySipper sipper = mPowerUsageSummary.findBatterySipperByType(mUsageList, BatterySipper.DrainType.APP); assertThat(sipper).isSameAs(mNormalBatterySipper); } @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)); doReturn(expectedSummary).when(mPowerUsageSummary) .getString(eq(R.string.battery_overall_usage), anyInt()); mPowerUsageSummary.updateCellularPreference(DISCHARGE_AMOUNT); verify(mCellularNetworkPref).setSummary(expectedSummary); } @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; final String expectedOverallUsage = mRealContext.getString(R.string.battery_overall_usage, Utils.formatPercentage((int) percent)); doReturn(expectedUsedTime).when(mPowerUsageSummary).getString( eq(R.string.battery_used_for), anyInt()); doReturn(expectedOverallUsage).when(mPowerUsageSummary).getString( eq(R.string.battery_overall_usage), anyInt()); mPowerUsageSummary.updateScreenPreference(DISCHARGE_AMOUNT); verify(mScreenUsagePref).setSummary(expectedUsedTime); verify(mScreenConsumptionPref).setSummary(expectedOverallUsage); } @Test public void testCalculatePercentage() { final double percent = mPowerUsageSummary.calculatePercentage(POWER_MAH, DISCHARGE_AMOUNT); assertThat(percent).isWithin(PRECISION).of(POWER_USAGE_PERCENTAGE); } public static class TestFragment extends PowerUsageSummary { private Context mContext; Loading Loading
res/values/strings.xml +13 −2 Original line number Diff line number Diff line Loading @@ -4285,8 +4285,17 @@ <!-- Display time remaining until battery is charged [CHAR_LIMIT=60] --> <string name="power_charge_remaining"><xliff:g id="until_charged">%1$s</xliff:g> to charge</string> <!-- [CHAR_LIMIT=40] Label for list of apps using battery in power use UI --> <string name="power_usage_list_summary">Use since last full charge</string> <!-- Title for the screen usage in power use UI [CHAR_LIMIT=40] --> <string name="device_screen_usage">Screen usage</string> <!-- Title for the screen consumption in power use UI(i.e. Screen consumption: 30% of battery usage) [CHAR_LIMIT=40] --> <string name="device_screen_consumption">Screen consumption</string> <!-- Title for the cellular network in power use UI(i.e. Mobile network scanning: 30% of battery usage) [CHAR_LIMIT=40] --> <string name="device_cellular_network">Mobile network scanning</string> <!-- Label for list of apps using battery in power use UI [CHAR_LIMIT=60] --> <string name="power_usage_list_summary">App usage since last full charge</string> <!-- Label for list of different types using battery in power use UI [CHAR_LIMIT=60] --> <string name="device_usage_list_summary">Device usage since last full charge</string> <!-- Battery usage since unplugged --> <string name="battery_since_unplugged">Battery use since unplugged</string> <!-- Battery usage since user reset the stats --> Loading Loading @@ -4483,6 +4492,8 @@ <!-- Description for battery usage time for an app, i.e. Used for 30min. [CHAR LIMIT=60] --> <string name="battery_used_for">Used for %1$s</string> <!-- Description for percentage of battery usage for an app, i.e. Screen: 30% of overall battery. [CHAR LIMIT=60] --> <string name="battery_overall_usage">%1$s of overall battery</string> <!-- Description for battery usage detail information since last full charge. [CHAR LIMIT=120] --> <string name="battery_detail_since_full_charge">Usage breakdown since last full charge</string> Loading
res/xml/power_usage_summary.xml +18 −0 Original line number Diff line number Diff line Loading @@ -55,4 +55,22 @@ android:key="app_list" android:title="@string/power_usage_list_summary"/> <PreferenceCategory android:key="device_usage_list" android:title="@string/device_usage_list_summary"> <Preference android:key="screen_usage" android:title="@string/device_screen_usage"/> <Preference android:key="screen_consumption" android:title="@string/device_screen_consumption"/> <Preference android:key="cellular_network" android:title="@string/device_cellular_network"/> </PreferenceCategory> </PreferenceScreen>
src/com/android/settings/fuelgauge/PowerGaugePreference.java +1 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ public class PowerGaugePreference extends TintablePreference { } public void setPercent(double percentOfTotal) { mProgress = Utils.formatPercentage((int) (percentOfTotal + 0.5)); mProgress = Utils.formatPercentage(percentOfTotal, true); notifyChanged(); } Loading
src/com/android/settings/fuelgauge/PowerUsageSummary.java +59 −2 Original line number Diff line number Diff line Loading @@ -78,11 +78,17 @@ public class PowerUsageSummary extends PowerUsageBase { private static final boolean USE_FAKE_DATA = false; private static final String KEY_APP_LIST = "app_list"; private static final String KEY_BATTERY_HEADER = "battery_header"; private static final int MIN_POWER_THRESHOLD_MILLI_AMP = 5; private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 10; private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10; private static final int SECONDS_IN_HOUR = 60 * 60; private static final String KEY_SCREEN_USAGE = "screen_usage"; private static final String KEY_SCREEN_CONSUMPTION = "screen_consumption"; private static final String KEY_CELLULAR_NETWORK = "cellular_network"; private static final int MENU_STATS_TYPE = Menu.FIRST; private static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 3; @VisibleForTesting Loading @@ -93,6 +99,13 @@ public class PowerUsageSummary extends PowerUsageBase { @VisibleForTesting boolean mShowAllApps = false; Preference mScreenUsagePref; @VisibleForTesting Preference mScreenConsumptionPref; @VisibleForTesting Preference mCellularNetworkPref; private LayoutPreference mBatteryLayoutPref; private PreferenceGroup mAppListGroup; Loading @@ -105,6 +118,9 @@ public class PowerUsageSummary extends PowerUsageBase { mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER); mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST); mScreenUsagePref = findPreference(KEY_SCREEN_USAGE); mScreenConsumptionPref = findPreference(KEY_SCREEN_CONSUMPTION); mCellularNetworkPref = findPreference(KEY_CELLULAR_NETWORK); } @Override Loading Loading @@ -384,6 +400,11 @@ public class PowerUsageSummary extends PowerUsageBase { context.getTheme().resolveAttribute(android.R.attr.colorControlNormal, value, true); final int colorControl = context.getColor(value.resourceId); final String usedTime = context.getString(R.string.battery_used_for); final int dischargeAmount = USE_FAKE_DATA ? 5000 : stats != null ? stats.getDischargeAmount(mStatsType) : 0; updateScreenPreference(dischargeAmount); updateCellularPreference(dischargeAmount); if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP || USE_FAKE_DATA) { final List<BatterySipper> usageList = getCoalescedUsageList( Loading @@ -391,8 +412,6 @@ public class PowerUsageSummary extends PowerUsageBase { double hiddenPowerMah = mShowAllApps ? 0 : removeHiddenBatterySippers(usageList); final int dischargeAmount = USE_FAKE_DATA ? 5000 : stats != null ? stats.getDischargeAmount(mStatsType) : 0; final int numSippers = usageList.size(); for (int i = 0; i < numSippers; i++) { final BatterySipper sipper = usageList.get(i); Loading Loading @@ -478,6 +497,39 @@ public class PowerUsageSummary extends PowerUsageBase { BatteryEntry.startRequestQueue(); } @VisibleForTesting BatterySipper findBatterySipperByType(List<BatterySipper> usageList, DrainType type) { for (int i = 0, size = usageList.size(); i < size; i++) { final BatterySipper sipper = usageList.get(i); if (sipper.drainType == type) { return sipper; } } return null; } @VisibleForTesting void updateScreenPreference(final int dischargeAmount) { final BatterySipper sipper = findBatterySipperByType( mStatsHelper.getUsageList(), DrainType.SCREEN); final Context context = getContext(); final double percentOfTotal = calculatePercentage(sipper.totalPowerMah, dischargeAmount); mScreenUsagePref.setSummary(getString(R.string.battery_used_for, Utils.formatElapsedTime(context, sipper.usageTimeMs, false))); mScreenConsumptionPref.setSummary(getString(R.string.battery_overall_usage, Utils.formatPercentage(percentOfTotal, true))); } @VisibleForTesting void updateCellularPreference(final int dischargeAmount) { final BatterySipper sipper = findBatterySipperByType( mStatsHelper.getUsageList(), DrainType.CELL); final double percentOfTotal = calculatePercentage(sipper.totalPowerMah, dischargeAmount); mCellularNetworkPref.setSummary(getString(R.string.battery_overall_usage, Utils.formatPercentage(percentOfTotal, true))); } @VisibleForTesting void updateHeaderPreference(BatteryInfo info) { final BatteryMeterView batteryView = (BatteryMeterView) mBatteryLayoutPref Loading @@ -502,6 +554,11 @@ public class PowerUsageSummary extends PowerUsageBase { batteryView.setBatteryInfo(info.mBatteryLevel); } @VisibleForTesting double calculatePercentage(double powerUsage, double dischargeAmount) { return ((powerUsage / mStatsHelper.getTotalPower()) * dischargeAmount); } @VisibleForTesting void setUsageSummary(Preference preference, String usedTimePrefix, long usageTimeMs) { // Only show summary when usage time is longer than one minute Loading
tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java +99 −4 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settings.fuelgauge; import android.content.Context; import android.content.Intent; import android.os.Process; import android.support.v7.preference.Preference; import android.text.TextUtils; import android.text.format.DateUtils; import android.view.Menu; Loading @@ -26,9 +27,12 @@ import android.view.MenuItem; import android.view.View; import android.widget.TextView; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryStatsImpl; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.Utils; import com.android.settings.applications.LayoutPreference; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settingslib.BatteryInfo; Loading @@ -38,9 +42,8 @@ import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; Loading @@ -49,7 +52,10 @@ 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_TOGGLE_APPS; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; Loading @@ -59,7 +65,7 @@ import static org.mockito.Mockito.when; * Unit tests for {@link PowerUsageSummary}. */ // TODO: Improve this test class so that it starts up the real activity and fragment. @RunWith(RobolectricTestRunner.class) @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class PowerUsageSummaryTest { private static final String[] PACKAGE_NAMES = {"com.app1", "com.app2"}; Loading @@ -67,9 +73,13 @@ public class PowerUsageSummaryTest { private static final int UID = 123; private static final int POWER_MAH = 100; private static final long REMAINING_TIME_US = 100000; private static final int DISCHARGE_AMOUNT = 100; private static final long USAGE_TIME_MS = 10000; private static final double TOTAL_POWER = 200; private static final double BATTERY_SCREEN_USAGE = 300; private static final double BATTERY_SYSTEM_USAGE = 600; private static final double PRECISION = 0.001; private static final double POWER_USAGE_PERCENTAGE = 50; private static final Intent ADDITIONAL_BATTERY_INFO_INTENT = new Intent("com.example.app.ADDITIONAL_BATTERY_INFO"); Loading @@ -92,6 +102,8 @@ public class PowerUsageSummaryTest { @Mock private BatterySipper mSystemBatterySipper; @Mock private BatterySipper mCellBatterySipper; @Mock private PowerGaugePreference mPreference; @Mock private LayoutPreference mBatteryLayoutPref; Loading @@ -105,15 +117,26 @@ public class PowerUsageSummaryTest { private TextView mSummary2; @Mock private BatteryInfo mBatteryInfo; @Mock private Preference mScreenUsagePref; @Mock private Preference mScreenConsumptionPref; @Mock private Preference mCellularNetworkPref; @Mock private BatteryStatsHelper mBatteryHelper; private Context mRealContext; private TestFragment mFragment; private FakeFeatureFactory mFeatureFactory; private PowerUsageSummary mPowerUsageSummary; private List<BatterySipper> mUsageList; @Before public void setUp() { MockitoAnnotations.initMocks(this); mRealContext = RuntimeEnvironment.application; FakeFeatureFactory.setupForTest(mContext); mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); Loading @@ -129,13 +152,19 @@ public class PowerUsageSummaryTest { when(mToggleAppsMenu.getItemId()).thenReturn(MENU_TOGGLE_APPS); when(mFeatureFactory.powerUsageFeatureProvider.getAdditionalBatteryInfoIntent()) .thenReturn(ADDITIONAL_BATTERY_INFO_INTENT); when(mBatteryHelper.getTotalPower()).thenReturn(TOTAL_POWER); mPowerUsageSummary = spy(new PowerUsageSummary()); when(mPowerUsageSummary.getContext()).thenReturn(mContext); when(mPowerUsageSummary.getContext()).thenReturn(mRealContext); when(mNormalBatterySipper.getPackages()).thenReturn(PACKAGE_NAMES); when(mNormalBatterySipper.getUid()).thenReturn(UID); mNormalBatterySipper.totalPowerMah = POWER_MAH; mNormalBatterySipper.drainType = BatterySipper.DrainType.APP; mCellBatterySipper.drainType = BatterySipper.DrainType.CELL; mCellBatterySipper.totalPowerMah = POWER_MAH; when(mBatteryLayoutPref.findViewById(R.id.summary1)).thenReturn(mSummary1); when(mBatteryLayoutPref.findViewById(R.id.summary2)).thenReturn(mSummary2); when(mBatteryLayoutPref.findViewById(R.id.time)).thenReturn(mTimeText); Loading @@ -145,9 +174,19 @@ public class PowerUsageSummaryTest { mScreenBatterySipper.drainType = BatterySipper.DrainType.SCREEN; mScreenBatterySipper.totalPowerMah = BATTERY_SCREEN_USAGE; mScreenBatterySipper.usageTimeMs = USAGE_TIME_MS; mSystemBatterySipper.drainType = BatterySipper.DrainType.APP; mSystemBatterySipper.totalPowerMah = BATTERY_SYSTEM_USAGE; when(mSystemBatterySipper.getUid()).thenReturn(Process.SYSTEM_UID); mUsageList = new ArrayList<>(); mUsageList.add(mNormalBatterySipper); mUsageList.add(mScreenBatterySipper); mUsageList.add(mCellBatterySipper); mPowerUsageSummary.mStatsHelper = mBatteryHelper; when(mBatteryHelper.getUsageList()).thenReturn(mUsageList); } @Test Loading Loading @@ -326,6 +365,7 @@ public class PowerUsageSummaryTest { verify(mSummary1).setText(R.string.estimated_time_left); } private void testToggleAllApps(final boolean isShowApps) { mFragment.mShowAllApps = isShowApps; Loading @@ -333,6 +373,61 @@ public class PowerUsageSummaryTest { assertThat(mFragment.mShowAllApps).isEqualTo(!isShowApps); } @Test public void testFindBatterySipperByType_findTypeScreen() { BatterySipper sipper = mPowerUsageSummary.findBatterySipperByType(mUsageList, BatterySipper.DrainType.SCREEN); assertThat(sipper).isSameAs(mScreenBatterySipper); } @Test public void testFindBatterySipperByType_findTypeApp() { BatterySipper sipper = mPowerUsageSummary.findBatterySipperByType(mUsageList, BatterySipper.DrainType.APP); assertThat(sipper).isSameAs(mNormalBatterySipper); } @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)); doReturn(expectedSummary).when(mPowerUsageSummary) .getString(eq(R.string.battery_overall_usage), anyInt()); mPowerUsageSummary.updateCellularPreference(DISCHARGE_AMOUNT); verify(mCellularNetworkPref).setSummary(expectedSummary); } @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; final String expectedOverallUsage = mRealContext.getString(R.string.battery_overall_usage, Utils.formatPercentage((int) percent)); doReturn(expectedUsedTime).when(mPowerUsageSummary).getString( eq(R.string.battery_used_for), anyInt()); doReturn(expectedOverallUsage).when(mPowerUsageSummary).getString( eq(R.string.battery_overall_usage), anyInt()); mPowerUsageSummary.updateScreenPreference(DISCHARGE_AMOUNT); verify(mScreenUsagePref).setSummary(expectedUsedTime); verify(mScreenConsumptionPref).setSummary(expectedOverallUsage); } @Test public void testCalculatePercentage() { final double percent = mPowerUsageSummary.calculatePercentage(POWER_MAH, DISCHARGE_AMOUNT); assertThat(percent).isWithin(PRECISION).of(POWER_USAGE_PERCENTAGE); } public static class TestFragment extends PowerUsageSummary { private Context mContext; Loading