Loading src/com/android/settings/fuelgauge/PowerUsageAdvanced.java +100 −2 Original line number Diff line number Diff line Loading @@ -13,22 +13,29 @@ */ package com.android.settings.fuelgauge; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.os.BatteryStats; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.UserManager; 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.support.v7.preference.Preference; 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; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.core.PreferenceController; import com.android.settings.fuelgauge.PowerUsageAdvanced.PowerUsageData.UsageType; import com.android.settings.overlay.FeatureFactory; Loading Loading @@ -64,6 +71,38 @@ public class PowerUsageAdvanced extends PowerUsageBase { private PreferenceGroup mUsageListGroup; private PowerUsageFeatureProvider mPowerUsageFeatureProvider; private PackageManager mPackageManager; private UserManager mUserManager; private Map<Integer, PowerUsageData> mBatteryDataMap; Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case BatteryEntry.MSG_UPDATE_NAME_ICON: final int dischargeAmount = mStatsHelper.getStats().getDischargeAmount( STATUS_TYPE); final double totalPower = mStatsHelper.getTotalPower(); final BatteryEntry entry = (BatteryEntry) msg.obj; final int usageType = extractUsageType(entry.sipper); PowerUsageData usageData = mBatteryDataMap.get(usageType); Preference pref = findPreference(String.valueOf(usageType)); if (pref != null && usageData != null) { updateUsageDataSummary(usageData, totalPower, dischargeAmount); pref.setSummary(usageData.summary); } break; case BatteryEntry.MSG_REPORT_FULLY_DRAWN: Activity activity = getActivity(); if (activity != null) { activity.reportFullyDrawn(); } break; } super.handleMessage(msg); } }; @Override public void onCreate(Bundle icicle) { Loading @@ -76,6 +115,7 @@ public class PowerUsageAdvanced extends PowerUsageBase { mPowerUsageFeatureProvider = FeatureFactory.getFactory(context) .getPowerUsageFeatureProvider(context); mPackageManager = context.getPackageManager(); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); } @Override Loading @@ -84,6 +124,21 @@ public class PowerUsageAdvanced extends PowerUsageBase { refreshStats(); } @Override public void onPause() { BatteryEntry.stopRequestQueue(); mHandler.removeMessages(BatteryEntry.MSG_UPDATE_NAME_ICON); super.onPause(); } @Override public void onDestroy() { super.onDestroy(); if (getActivity().isChangingConfigurations()) { BatteryEntry.clearUidCache(); } } @Override public int getMetricsCategory() { return MetricsProto.MetricsEvent.FUELGAUGE_BATTERY_HISTORY_DETAIL; Loading Loading @@ -116,15 +171,19 @@ public class PowerUsageAdvanced extends PowerUsageBase { final PowerUsageData batteryData = dataList.get(i); final PowerGaugePreference pref = new PowerGaugePreference(getPrefContext()); pref.setKey(String.valueOf(batteryData.usageType)); pref.setTitle(batteryData.titleResId); pref.setSummary(batteryData.summary); pref.setPercent(batteryData.percentage); mUsageListGroup.addPreference(pref); } BatteryEntry.startRequestQueue(); } @VisibleForTesting @UsageType int extractUsageType(BatterySipper sipper) { @UsageType int extractUsageType(BatterySipper sipper) { final DrainType drainType = sipper.drainType; final int uid = sipper.getUid(); Loading Loading @@ -163,21 +222,56 @@ public class PowerUsageAdvanced extends PowerUsageBase { sipper.mPackages = mPackageManager.getPackagesForUid(sipper.getUid()); final PowerUsageData usageData = batteryDataMap.get(extractUsageType(sipper)); usageData.totalPowerMah += sipper.totalPowerMah; if (sipper.drainType == DrainType.APP && sipper.usageTimeMs != 0) { sipper.usageTimeMs = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, sipper.uidObj, STATUS_TYPE); } usageData.totalUsageTimeMs += sipper.usageTimeMs; usageData.usageList.add(sipper); } // TODO(b/35396770): add logic to extract the summary final List<PowerUsageData> batteryDataList = new ArrayList<>(batteryDataMap.values()); final int dischargeAmount = statusHelper.getStats().getDischargeAmount(STATUS_TYPE); final double totalPower = statusHelper.getTotalPower(); for (final PowerUsageData usageData : batteryDataList) { usageData.percentage = (usageData.totalPowerMah / totalPower) * dischargeAmount; updateUsageDataSummary(usageData, totalPower, dischargeAmount); } Collections.sort(batteryDataList); mBatteryDataMap = batteryDataMap; return batteryDataList; } @VisibleForTesting void updateUsageDataSummary(PowerUsageData usageData, double totalPower, int dischargeAmount) { if (usageData.usageList.size() <= 1) { usageData.summary = getString(R.string.battery_used_for, Utils.formatElapsedTime(getContext(), usageData.totalUsageTimeMs, false)); } else { BatterySipper sipper = findBatterySipperWithMaxBatteryUsage(usageData.usageList); BatteryEntry batteryEntry = new BatteryEntry(getContext(), mHandler, mUserManager, sipper); final double percentage = (sipper.totalPowerMah / totalPower) * dischargeAmount; usageData.summary = getString(R.string.battery_used_by, Utils.formatPercentage(percentage, true), batteryEntry.name); } } @VisibleForTesting BatterySipper findBatterySipperWithMaxBatteryUsage(List<BatterySipper> usageList) { BatterySipper sipper = usageList.get(0); for (int i = 1, size = usageList.size(); i < size; i++) { final BatterySipper comparedSipper = usageList.get(i); if (comparedSipper.totalPowerMah > sipper.totalPowerMah) { sipper = comparedSipper; } } return sipper; } @VisibleForTesting void setPackageManager(PackageManager packageManager) { mPackageManager = packageManager; Loading Loading @@ -221,10 +315,12 @@ public class PowerUsageAdvanced extends PowerUsageBase { public String summary; public double percentage; public double totalPowerMah; public long totalUsageTimeMs; @ColorInt public int iconColor; @UsageType public int usageType; public List<BatterySipper> usageList; public PowerUsageData(@UsageType int usageType) { this(usageType, 0); Loading @@ -233,8 +329,10 @@ public class PowerUsageAdvanced extends PowerUsageBase { public PowerUsageData(@UsageType int usageType, double totalPower) { this.usageType = usageType; totalPowerMah = 0; totalUsageTimeMs = 0; titleResId = getTitleResId(usageType); totalPowerMah = totalPower; usageList = new ArrayList<>(); } private int getTitleResId(@UsageType int usageType) { Loading src/com/android/settings/fuelgauge/PowerUsageSummary.java +4 −0 Original line number Diff line number Diff line Loading @@ -489,6 +489,10 @@ public class PowerUsageSummary extends PowerUsageBase { pref.setTitle(entry.getLabel()); pref.setOrder(i + 1); pref.setPercent(percentOfTotal); if (sipper.usageTimeMs == 0 && sipper.drainType == DrainType.APP) { sipper.usageTimeMs = BatteryUtils.getProcessTimeMs( BatteryUtils.StatusType.FOREGROUND, sipper.uidObj, mStatsType); } setUsageSummary(pref, usedTime, sipper.usageTimeMs); if ((sipper.drainType != DrainType.APP || sipper.uidObj.getUid() == Process.ROOT_UID) Loading tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java +66 −11 Original line number Diff line number Diff line Loading @@ -15,31 +15,40 @@ */ package com.android.settings.fuelgauge; import android.content.Context; import android.content.pm.PackageManager; import android.os.Process; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatterySipper.DrainType; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.Utils; import com.android.settings.fuelgauge.PowerUsageAdvanced.PowerUsageData; import com.android.settings.fuelgauge.PowerUsageAdvanced.PowerUsageData.UsageType; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; 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.Matchers.eq; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(SettingsRobolectricTestRunner.class) Loading @@ -53,9 +62,13 @@ public class PowerUsageAdvancedTest { private static final double TYPE_WIFI_USAGE = 0; private static final double TOTAL_USAGE = TYPE_APP_USAGE * 2 + TYPE_BLUETOOTH_USAGE + TYPE_WIFI_USAGE; private static final double TOTAL_POWER = 500; private static final double PRECISION = 0.001; private static final String STUB_STRING = "stub_string"; @Mock private BatterySipper mNormalBatterySipper; @Mock private BatterySipper mBatterySipper; private BatterySipper mMaxBatterySipper; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private BatteryStatsHelper mBatteryStatsHelper; @Mock Loading @@ -63,11 +76,14 @@ public class PowerUsageAdvancedTest { @Mock private PackageManager mPackageManager; private PowerUsageAdvanced mPowerUsageAdvanced; private PowerUsageData mPowerUsageData; private Context mShadowContext; @Before public void setUp() { MockitoAnnotations.initMocks(this); mPowerUsageAdvanced = new PowerUsageAdvanced(); mShadowContext = RuntimeEnvironment.application; mPowerUsageAdvanced = spy(new PowerUsageAdvanced()); List<BatterySipper> batterySippers = new ArrayList<>(); batterySippers.add(new BatterySipper(DrainType.APP, Loading @@ -83,16 +99,24 @@ public class PowerUsageAdvancedTest { DISCHARGE_AMOUNT); when(mBatteryStatsHelper.getUsageList()).thenReturn(batterySippers); when(mBatteryStatsHelper.getTotalPower()).thenReturn(TOTAL_USAGE); when(mPowerUsageAdvanced.getContext()).thenReturn(mShadowContext); doReturn(STUB_STRING).when(mPowerUsageAdvanced).getString(anyInt(), any(), any()); doReturn(STUB_STRING).when(mPowerUsageAdvanced).getString(anyInt(), any()); mPowerUsageAdvanced.setPackageManager(mPackageManager); mPowerUsageAdvanced.setPowerUsageFeatureProvider(mPowerUsageFeatureProvider); mPowerUsageData = new PowerUsageData(UsageType.APP); mMaxBatterySipper.totalPowerMah = TYPE_BLUETOOTH_USAGE; mMaxBatterySipper.drainType = DrainType.BLUETOOTH; mNormalBatterySipper.drainType = DrainType.SCREEN; } @Test public void testExtractUsageType_TypeSystem_ReturnSystem() { mBatterySipper.drainType = DrainType.APP; mNormalBatterySipper.drainType = DrainType.APP; when(mPowerUsageFeatureProvider.isTypeSystem(any())).thenReturn(true); assertThat(mPowerUsageAdvanced.extractUsageType(mBatterySipper)) assertThat(mPowerUsageAdvanced.extractUsageType(mNormalBatterySipper)) .isEqualTo(UsageType.SYSTEM); } Loading @@ -105,19 +129,19 @@ public class PowerUsageAdvancedTest { assertThat(drainTypes.length).isEqualTo(usageTypes.length); for (int i = 0, size = drainTypes.length; i < size; i++) { mBatterySipper.drainType = drainTypes[i]; assertThat(mPowerUsageAdvanced.extractUsageType(mBatterySipper)) mNormalBatterySipper.drainType = drainTypes[i]; assertThat(mPowerUsageAdvanced.extractUsageType(mNormalBatterySipper)) .isEqualTo(usageTypes[i]); } } @Test public void testExtractUsageType_TypeService_ReturnService() { mBatterySipper.drainType = DrainType.APP; when(mBatterySipper.getUid()).thenReturn(FAKE_UID_1); mNormalBatterySipper.drainType = DrainType.APP; when(mNormalBatterySipper.getUid()).thenReturn(FAKE_UID_1); when(mPowerUsageFeatureProvider.isTypeService(any())).thenReturn(true); assertThat(mPowerUsageAdvanced.extractUsageType(mBatterySipper)) assertThat(mPowerUsageAdvanced.extractUsageType(mNormalBatterySipper)) .isEqualTo(UsageType.SERVICE); } Loading Loading @@ -146,6 +170,37 @@ public class PowerUsageAdvancedTest { } } @Test public void testUpdateUsageDataSummary_onlyOneApp_showUsageTime() { mPowerUsageData.usageList.add(mNormalBatterySipper); mPowerUsageAdvanced.updateUsageDataSummary(mPowerUsageData, TOTAL_POWER, DISCHARGE_AMOUNT); verify(mPowerUsageAdvanced).getString(eq(R.string.battery_used_for), any()); } @Test public void testUpdateUsageDataSummary_moreThanOneApp_showMaxUsageApp() { mPowerUsageData.usageList.add(mNormalBatterySipper); mPowerUsageData.usageList.add(mMaxBatterySipper); doReturn(mMaxBatterySipper).when(mPowerUsageAdvanced).findBatterySipperWithMaxBatteryUsage( mPowerUsageData.usageList); final double percentage = (TYPE_BLUETOOTH_USAGE / TOTAL_POWER) * DISCHARGE_AMOUNT; mPowerUsageAdvanced.updateUsageDataSummary(mPowerUsageData, TOTAL_POWER, DISCHARGE_AMOUNT); verify(mPowerUsageAdvanced).getString(eq(R.string.battery_used_by), eq(Utils.formatPercentage(percentage, true)), any()); } @Test public void testFindBatterySipperWithMaxBatteryUsage_findCorrectOne() { mPowerUsageData.usageList.add(mNormalBatterySipper); mPowerUsageData.usageList.add(mMaxBatterySipper); BatterySipper sipper = mPowerUsageAdvanced.findBatterySipperWithMaxBatteryUsage( mPowerUsageData.usageList); assertThat(sipper).isEqualTo(mMaxBatterySipper); } @Test public void testInit_ContainsAllUsageType() { final int[] usageTypeSet = mPowerUsageAdvanced.mUsageTypes; Loading Loading
src/com/android/settings/fuelgauge/PowerUsageAdvanced.java +100 −2 Original line number Diff line number Diff line Loading @@ -13,22 +13,29 @@ */ package com.android.settings.fuelgauge; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.os.BatteryStats; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.UserManager; 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.support.v7.preference.Preference; 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; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.core.PreferenceController; import com.android.settings.fuelgauge.PowerUsageAdvanced.PowerUsageData.UsageType; import com.android.settings.overlay.FeatureFactory; Loading Loading @@ -64,6 +71,38 @@ public class PowerUsageAdvanced extends PowerUsageBase { private PreferenceGroup mUsageListGroup; private PowerUsageFeatureProvider mPowerUsageFeatureProvider; private PackageManager mPackageManager; private UserManager mUserManager; private Map<Integer, PowerUsageData> mBatteryDataMap; Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case BatteryEntry.MSG_UPDATE_NAME_ICON: final int dischargeAmount = mStatsHelper.getStats().getDischargeAmount( STATUS_TYPE); final double totalPower = mStatsHelper.getTotalPower(); final BatteryEntry entry = (BatteryEntry) msg.obj; final int usageType = extractUsageType(entry.sipper); PowerUsageData usageData = mBatteryDataMap.get(usageType); Preference pref = findPreference(String.valueOf(usageType)); if (pref != null && usageData != null) { updateUsageDataSummary(usageData, totalPower, dischargeAmount); pref.setSummary(usageData.summary); } break; case BatteryEntry.MSG_REPORT_FULLY_DRAWN: Activity activity = getActivity(); if (activity != null) { activity.reportFullyDrawn(); } break; } super.handleMessage(msg); } }; @Override public void onCreate(Bundle icicle) { Loading @@ -76,6 +115,7 @@ public class PowerUsageAdvanced extends PowerUsageBase { mPowerUsageFeatureProvider = FeatureFactory.getFactory(context) .getPowerUsageFeatureProvider(context); mPackageManager = context.getPackageManager(); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); } @Override Loading @@ -84,6 +124,21 @@ public class PowerUsageAdvanced extends PowerUsageBase { refreshStats(); } @Override public void onPause() { BatteryEntry.stopRequestQueue(); mHandler.removeMessages(BatteryEntry.MSG_UPDATE_NAME_ICON); super.onPause(); } @Override public void onDestroy() { super.onDestroy(); if (getActivity().isChangingConfigurations()) { BatteryEntry.clearUidCache(); } } @Override public int getMetricsCategory() { return MetricsProto.MetricsEvent.FUELGAUGE_BATTERY_HISTORY_DETAIL; Loading Loading @@ -116,15 +171,19 @@ public class PowerUsageAdvanced extends PowerUsageBase { final PowerUsageData batteryData = dataList.get(i); final PowerGaugePreference pref = new PowerGaugePreference(getPrefContext()); pref.setKey(String.valueOf(batteryData.usageType)); pref.setTitle(batteryData.titleResId); pref.setSummary(batteryData.summary); pref.setPercent(batteryData.percentage); mUsageListGroup.addPreference(pref); } BatteryEntry.startRequestQueue(); } @VisibleForTesting @UsageType int extractUsageType(BatterySipper sipper) { @UsageType int extractUsageType(BatterySipper sipper) { final DrainType drainType = sipper.drainType; final int uid = sipper.getUid(); Loading Loading @@ -163,21 +222,56 @@ public class PowerUsageAdvanced extends PowerUsageBase { sipper.mPackages = mPackageManager.getPackagesForUid(sipper.getUid()); final PowerUsageData usageData = batteryDataMap.get(extractUsageType(sipper)); usageData.totalPowerMah += sipper.totalPowerMah; if (sipper.drainType == DrainType.APP && sipper.usageTimeMs != 0) { sipper.usageTimeMs = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, sipper.uidObj, STATUS_TYPE); } usageData.totalUsageTimeMs += sipper.usageTimeMs; usageData.usageList.add(sipper); } // TODO(b/35396770): add logic to extract the summary final List<PowerUsageData> batteryDataList = new ArrayList<>(batteryDataMap.values()); final int dischargeAmount = statusHelper.getStats().getDischargeAmount(STATUS_TYPE); final double totalPower = statusHelper.getTotalPower(); for (final PowerUsageData usageData : batteryDataList) { usageData.percentage = (usageData.totalPowerMah / totalPower) * dischargeAmount; updateUsageDataSummary(usageData, totalPower, dischargeAmount); } Collections.sort(batteryDataList); mBatteryDataMap = batteryDataMap; return batteryDataList; } @VisibleForTesting void updateUsageDataSummary(PowerUsageData usageData, double totalPower, int dischargeAmount) { if (usageData.usageList.size() <= 1) { usageData.summary = getString(R.string.battery_used_for, Utils.formatElapsedTime(getContext(), usageData.totalUsageTimeMs, false)); } else { BatterySipper sipper = findBatterySipperWithMaxBatteryUsage(usageData.usageList); BatteryEntry batteryEntry = new BatteryEntry(getContext(), mHandler, mUserManager, sipper); final double percentage = (sipper.totalPowerMah / totalPower) * dischargeAmount; usageData.summary = getString(R.string.battery_used_by, Utils.formatPercentage(percentage, true), batteryEntry.name); } } @VisibleForTesting BatterySipper findBatterySipperWithMaxBatteryUsage(List<BatterySipper> usageList) { BatterySipper sipper = usageList.get(0); for (int i = 1, size = usageList.size(); i < size; i++) { final BatterySipper comparedSipper = usageList.get(i); if (comparedSipper.totalPowerMah > sipper.totalPowerMah) { sipper = comparedSipper; } } return sipper; } @VisibleForTesting void setPackageManager(PackageManager packageManager) { mPackageManager = packageManager; Loading Loading @@ -221,10 +315,12 @@ public class PowerUsageAdvanced extends PowerUsageBase { public String summary; public double percentage; public double totalPowerMah; public long totalUsageTimeMs; @ColorInt public int iconColor; @UsageType public int usageType; public List<BatterySipper> usageList; public PowerUsageData(@UsageType int usageType) { this(usageType, 0); Loading @@ -233,8 +329,10 @@ public class PowerUsageAdvanced extends PowerUsageBase { public PowerUsageData(@UsageType int usageType, double totalPower) { this.usageType = usageType; totalPowerMah = 0; totalUsageTimeMs = 0; titleResId = getTitleResId(usageType); totalPowerMah = totalPower; usageList = new ArrayList<>(); } private int getTitleResId(@UsageType int usageType) { Loading
src/com/android/settings/fuelgauge/PowerUsageSummary.java +4 −0 Original line number Diff line number Diff line Loading @@ -489,6 +489,10 @@ public class PowerUsageSummary extends PowerUsageBase { pref.setTitle(entry.getLabel()); pref.setOrder(i + 1); pref.setPercent(percentOfTotal); if (sipper.usageTimeMs == 0 && sipper.drainType == DrainType.APP) { sipper.usageTimeMs = BatteryUtils.getProcessTimeMs( BatteryUtils.StatusType.FOREGROUND, sipper.uidObj, mStatsType); } setUsageSummary(pref, usedTime, sipper.usageTimeMs); if ((sipper.drainType != DrainType.APP || sipper.uidObj.getUid() == Process.ROOT_UID) Loading
tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java +66 −11 Original line number Diff line number Diff line Loading @@ -15,31 +15,40 @@ */ package com.android.settings.fuelgauge; import android.content.Context; import android.content.pm.PackageManager; import android.os.Process; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatterySipper.DrainType; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.Utils; import com.android.settings.fuelgauge.PowerUsageAdvanced.PowerUsageData; import com.android.settings.fuelgauge.PowerUsageAdvanced.PowerUsageData.UsageType; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; 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.Matchers.eq; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(SettingsRobolectricTestRunner.class) Loading @@ -53,9 +62,13 @@ public class PowerUsageAdvancedTest { private static final double TYPE_WIFI_USAGE = 0; private static final double TOTAL_USAGE = TYPE_APP_USAGE * 2 + TYPE_BLUETOOTH_USAGE + TYPE_WIFI_USAGE; private static final double TOTAL_POWER = 500; private static final double PRECISION = 0.001; private static final String STUB_STRING = "stub_string"; @Mock private BatterySipper mNormalBatterySipper; @Mock private BatterySipper mBatterySipper; private BatterySipper mMaxBatterySipper; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private BatteryStatsHelper mBatteryStatsHelper; @Mock Loading @@ -63,11 +76,14 @@ public class PowerUsageAdvancedTest { @Mock private PackageManager mPackageManager; private PowerUsageAdvanced mPowerUsageAdvanced; private PowerUsageData mPowerUsageData; private Context mShadowContext; @Before public void setUp() { MockitoAnnotations.initMocks(this); mPowerUsageAdvanced = new PowerUsageAdvanced(); mShadowContext = RuntimeEnvironment.application; mPowerUsageAdvanced = spy(new PowerUsageAdvanced()); List<BatterySipper> batterySippers = new ArrayList<>(); batterySippers.add(new BatterySipper(DrainType.APP, Loading @@ -83,16 +99,24 @@ public class PowerUsageAdvancedTest { DISCHARGE_AMOUNT); when(mBatteryStatsHelper.getUsageList()).thenReturn(batterySippers); when(mBatteryStatsHelper.getTotalPower()).thenReturn(TOTAL_USAGE); when(mPowerUsageAdvanced.getContext()).thenReturn(mShadowContext); doReturn(STUB_STRING).when(mPowerUsageAdvanced).getString(anyInt(), any(), any()); doReturn(STUB_STRING).when(mPowerUsageAdvanced).getString(anyInt(), any()); mPowerUsageAdvanced.setPackageManager(mPackageManager); mPowerUsageAdvanced.setPowerUsageFeatureProvider(mPowerUsageFeatureProvider); mPowerUsageData = new PowerUsageData(UsageType.APP); mMaxBatterySipper.totalPowerMah = TYPE_BLUETOOTH_USAGE; mMaxBatterySipper.drainType = DrainType.BLUETOOTH; mNormalBatterySipper.drainType = DrainType.SCREEN; } @Test public void testExtractUsageType_TypeSystem_ReturnSystem() { mBatterySipper.drainType = DrainType.APP; mNormalBatterySipper.drainType = DrainType.APP; when(mPowerUsageFeatureProvider.isTypeSystem(any())).thenReturn(true); assertThat(mPowerUsageAdvanced.extractUsageType(mBatterySipper)) assertThat(mPowerUsageAdvanced.extractUsageType(mNormalBatterySipper)) .isEqualTo(UsageType.SYSTEM); } Loading @@ -105,19 +129,19 @@ public class PowerUsageAdvancedTest { assertThat(drainTypes.length).isEqualTo(usageTypes.length); for (int i = 0, size = drainTypes.length; i < size; i++) { mBatterySipper.drainType = drainTypes[i]; assertThat(mPowerUsageAdvanced.extractUsageType(mBatterySipper)) mNormalBatterySipper.drainType = drainTypes[i]; assertThat(mPowerUsageAdvanced.extractUsageType(mNormalBatterySipper)) .isEqualTo(usageTypes[i]); } } @Test public void testExtractUsageType_TypeService_ReturnService() { mBatterySipper.drainType = DrainType.APP; when(mBatterySipper.getUid()).thenReturn(FAKE_UID_1); mNormalBatterySipper.drainType = DrainType.APP; when(mNormalBatterySipper.getUid()).thenReturn(FAKE_UID_1); when(mPowerUsageFeatureProvider.isTypeService(any())).thenReturn(true); assertThat(mPowerUsageAdvanced.extractUsageType(mBatterySipper)) assertThat(mPowerUsageAdvanced.extractUsageType(mNormalBatterySipper)) .isEqualTo(UsageType.SERVICE); } Loading Loading @@ -146,6 +170,37 @@ public class PowerUsageAdvancedTest { } } @Test public void testUpdateUsageDataSummary_onlyOneApp_showUsageTime() { mPowerUsageData.usageList.add(mNormalBatterySipper); mPowerUsageAdvanced.updateUsageDataSummary(mPowerUsageData, TOTAL_POWER, DISCHARGE_AMOUNT); verify(mPowerUsageAdvanced).getString(eq(R.string.battery_used_for), any()); } @Test public void testUpdateUsageDataSummary_moreThanOneApp_showMaxUsageApp() { mPowerUsageData.usageList.add(mNormalBatterySipper); mPowerUsageData.usageList.add(mMaxBatterySipper); doReturn(mMaxBatterySipper).when(mPowerUsageAdvanced).findBatterySipperWithMaxBatteryUsage( mPowerUsageData.usageList); final double percentage = (TYPE_BLUETOOTH_USAGE / TOTAL_POWER) * DISCHARGE_AMOUNT; mPowerUsageAdvanced.updateUsageDataSummary(mPowerUsageData, TOTAL_POWER, DISCHARGE_AMOUNT); verify(mPowerUsageAdvanced).getString(eq(R.string.battery_used_by), eq(Utils.formatPercentage(percentage, true)), any()); } @Test public void testFindBatterySipperWithMaxBatteryUsage_findCorrectOne() { mPowerUsageData.usageList.add(mNormalBatterySipper); mPowerUsageData.usageList.add(mMaxBatterySipper); BatterySipper sipper = mPowerUsageAdvanced.findBatterySipperWithMaxBatteryUsage( mPowerUsageData.usageList); assertThat(sipper).isEqualTo(mMaxBatterySipper); } @Test public void testInit_ContainsAllUsageType() { final int[] usageTypeSet = mPowerUsageAdvanced.mUsageTypes; Loading