Make "Battery usage" accessible at any time

Before this cl, user could go to "Battery usage" page only if
related app has battery usage. This cl breaks this rule so we
could open "Battery usage" without battery data.

Bug: 38497822
Test: RunSettingsRoboTests
Change-Id: Ic53c33b7dcbac82de58f31cf96e0bd8fa54e53ea
This commit is contained in:
jackqdyulei
2017-05-22 15:40:19 -07:00
parent 4d815d93ad
commit 2a95a63466
4 changed files with 104 additions and 13 deletions

View File

@@ -192,6 +192,8 @@ public class InstalledAppDetails extends AppInfoBase
BatterySipper mSipper; BatterySipper mSipper;
@VisibleForTesting @VisibleForTesting
BatteryStatsHelper mBatteryHelper; BatteryStatsHelper mBatteryHelper;
@VisibleForTesting
BatteryUtils mBatteryUtils;
protected ProcStatsData mStatsManager; protected ProcStatsData mStatsManager;
protected ProcStatsPackageEntry mStats; protected ProcStatsPackageEntry mStats;
@@ -200,7 +202,6 @@ public class InstalledAppDetails extends AppInfoBase
private AppStorageStats mLastResult; private AppStorageStats mLastResult;
private String mBatteryPercent; private String mBatteryPercent;
private BatteryUtils mBatteryUtils;
private final LoaderCallbacks<BatteryStatsHelper> mBatteryCallbacks = private final LoaderCallbacks<BatteryStatsHelper> mBatteryCallbacks =
new LoaderCallbacks<BatteryStatsHelper>() { new LoaderCallbacks<BatteryStatsHelper>() {
@@ -722,8 +723,6 @@ public class InstalledAppDetails extends AppInfoBase
mDataPreference.setSummary(getDataSummary()); mDataPreference.setSummary(getDataSummary());
} }
updateBattery();
if (!mInitialized) { if (!mInitialized) {
// First time init: are we displaying an uninstalled app? // First time init: are we displaying an uninstalled app?
mInitialized = true; mInitialized = true;
@@ -750,9 +749,10 @@ public class InstalledAppDetails extends AppInfoBase
return true; return true;
} }
private void updateBattery() { @VisibleForTesting
if (mSipper != null && mBatteryHelper != null) { void updateBattery() {
mBatteryPreference.setEnabled(true); mBatteryPreference.setEnabled(true);
if (isBatteryStatsAvailable()) {
final int dischargeAmount = mBatteryHelper.getStats().getDischargeAmount( final int dischargeAmount = mBatteryHelper.getStats().getDischargeAmount(
BatteryStats.STATS_SINCE_CHARGED); BatteryStats.STATS_SINCE_CHARGED);
@@ -764,7 +764,6 @@ public class InstalledAppDetails extends AppInfoBase
mBatteryPercent = Utils.formatPercentage(percentOfMax); mBatteryPercent = Utils.formatPercentage(percentOfMax);
mBatteryPreference.setSummary(getString(R.string.battery_summary, mBatteryPercent)); mBatteryPreference.setSummary(getString(R.string.battery_summary, mBatteryPercent));
} else { } else {
mBatteryPreference.setEnabled(false);
mBatteryPreference.setSummary(getString(R.string.no_battery_summary)); mBatteryPreference.setSummary(getString(R.string.no_battery_summary));
} }
} }
@@ -798,6 +797,11 @@ public class InstalledAppDetails extends AppInfoBase
} }
} }
@VisibleForTesting
boolean isBatteryStatsAvailable() {
return mBatteryHelper != null && mSipper != null;
}
private static CharSequence getSize(Context context, AppStorageStats stats) { private static CharSequence getSize(Context context, AppStorageStats stats) {
return Formatter.formatFileSize(context, stats.getTotalBytes()); return Formatter.formatFileSize(context, stats.getTotalBytes());
} }
@@ -1036,9 +1040,15 @@ public class InstalledAppDetails extends AppInfoBase
} else if (preference == mDataPreference) { } else if (preference == mDataPreference) {
startAppInfoFragment(AppDataUsage.class, getString(R.string.app_data_usage)); startAppInfoFragment(AppDataUsage.class, getString(R.string.app_data_usage));
} else if (preference == mBatteryPreference) { } else if (preference == mBatteryPreference) {
BatteryEntry entry = new BatteryEntry(getContext(), null, mUserManager, mSipper); if (isBatteryStatsAvailable()) {
AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(), this, BatteryEntry entry = new BatteryEntry(getContext(), null, mUserManager, mSipper);
mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, mBatteryPercent); AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
this, mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry,
mBatteryPercent);
} else {
AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
this, mPackageName);
}
} else { } else {
return false; return false;
} }

View File

@@ -132,6 +132,16 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
new UserHandle(UserHandle.getUserId(sipper.getUid()))); new UserHandle(UserHandle.getUserId(sipper.getUid())));
} }
public static void startBatteryDetailPage(SettingsActivity caller, PreferenceFragment fragment,
String packageName) {
final Bundle args = new Bundle(2);
args.putString(EXTRA_PACKAGE_NAME, packageName);
args.putString(EXTRA_POWER_USAGE_PERCENT, Utils.formatPercentage(0));
caller.startPreferencePanelAsUser(fragment, AdvancedPowerUsageDetail.class.getName(), args,
R.string.battery_details_title, null, new UserHandle(UserHandle.myUserId()));
}
@Override @Override
public void onAttach(Activity activity) { public void onAttach(Activity activity) {
super.onAttach(activity); super.onAttach(activity);

View File

@@ -20,6 +20,8 @@ package com.android.settings.applications;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyDouble;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@@ -46,10 +48,12 @@ import android.widget.Button;
import com.android.internal.os.BatterySipper; import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.applications.instantapps.InstantAppButtonsController; import com.android.settings.applications.instantapps.InstantAppButtonsController;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -77,6 +81,8 @@ public final class InstalledAppDetailsTest {
private static final String PACKAGE_NAME = "test_package_name"; private static final String PACKAGE_NAME = "test_package_name";
private static final int TARGET_UID = 111; private static final int TARGET_UID = 111;
private static final int OTHER_UID = 222; private static final int OTHER_UID = 222;
private static final double BATTERY_LEVEL = 60;
private static final String BATTERY_LEVEL_STRING = "60%";
@Mock(answer = Answers.RETURNS_DEEP_STUBS) @Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext; private Context mContext;
@@ -89,20 +95,21 @@ public final class InstalledAppDetailsTest {
@Mock @Mock
private DevicePolicyManager mDevicePolicyManager; private DevicePolicyManager mDevicePolicyManager;
@Mock @Mock
private Preference mBatteryPreference;
@Mock
private BatterySipper mBatterySipper; private BatterySipper mBatterySipper;
@Mock @Mock
private BatterySipper mOtherBatterySipper; private BatterySipper mOtherBatterySipper;
@Mock @Mock(answer = Answers.RETURNS_DEEP_STUBS)
private BatteryStatsHelper mBatteryStatsHelper; private BatteryStatsHelper mBatteryStatsHelper;
@Mock @Mock
private BatteryStats.Uid mUid; private BatteryStats.Uid mUid;
@Mock @Mock
private PackageManager mPackageManager; private PackageManager mPackageManager;
@Mock
private BatteryUtils mBatteryUtils;
private InstalledAppDetails mAppDetail; private InstalledAppDetails mAppDetail;
private Context mShadowContext; private Context mShadowContext;
private Preference mBatteryPreference;
@Before @Before
public void setUp() { public void setUp() {
@@ -110,6 +117,10 @@ public final class InstalledAppDetailsTest {
mShadowContext = RuntimeEnvironment.application; mShadowContext = RuntimeEnvironment.application;
mAppDetail = spy(new InstalledAppDetails()); mAppDetail = spy(new InstalledAppDetails());
mAppDetail.mBatteryUtils = mBatteryUtils;
mBatteryPreference = new Preference(mShadowContext);
mAppDetail.mBatteryPreference = mBatteryPreference;
mBatterySipper.drainType = BatterySipper.DrainType.IDLE; mBatterySipper.drainType = BatterySipper.DrainType.IDLE;
mBatterySipper.uidObj = mUid; mBatterySipper.uidObj = mUid;
@@ -409,4 +420,42 @@ public final class InstalledAppDetailsTest {
assertThat(mAppDetail.findTargetSipper(mBatteryStatsHelper, TARGET_UID)).isEqualTo( assertThat(mAppDetail.findTargetSipper(mBatteryStatsHelper, TARGET_UID)).isEqualTo(
mBatterySipper); mBatterySipper);
} }
@Test
public void updateBattery_noBatteryStats_summaryNo() {
doReturn(mShadowContext.getString(R.string.no_battery_summary)).when(mAppDetail).getString(
R.string.no_battery_summary);
mAppDetail.updateBattery();
assertThat(mBatteryPreference.getSummary()).isEqualTo(
"No battery use since last full charge");
}
@Test
public void updateBattery_hasBatteryStats_summaryPercent() {
mAppDetail.mBatteryHelper = mBatteryStatsHelper;
mAppDetail.mSipper = mBatterySipper;
doReturn(BATTERY_LEVEL).when(mBatteryUtils).calculateBatteryPercent(anyDouble(),
anyDouble(), anyDouble(), anyInt());
doReturn(mShadowContext.getString(R.string.battery_summary, BATTERY_LEVEL_STRING)).when(
mAppDetail).getString(R.string.battery_summary, BATTERY_LEVEL_STRING);
doReturn(new ArrayList<>()).when(mBatteryStatsHelper).getUsageList();
mAppDetail.updateBattery();
assertThat(mBatteryPreference.getSummary()).isEqualTo("60% use since last full charge");
}
@Test
public void isBatteryStatsAvailable_hasBatteryStatsHelperAndSipper_returnTrue() {
mAppDetail.mBatteryHelper = mBatteryStatsHelper;
mAppDetail.mSipper = mBatterySipper;
assertThat(mAppDetail.isBatteryStatsAvailable()).isTrue();
}
@Test
public void isBatteryStatsAvailable_parametersNull_returnFalse() {
assertThat(mAppDetail.isBatteryStatsAvailable()).isFalse();
}
} }

View File

@@ -283,4 +283,26 @@ public class AdvancedPowerUsageDetailTest {
verify(mTestActivity).startPreferencePanelAsUser( verify(mTestActivity).startPreferencePanelAsUser(
any(), anyString(), any(), anyInt(), any(), eq(new UserHandle(10))); any(), anyString(), any(), anyInt(), any(), eq(new UserHandle(10)));
} }
@Test
public void testStartBatteryDetailPage_noBatteryUsage_hasBasicData() {
final ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
Answer<Void> callable = new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Exception {
mBundle = captor.getValue();
return null;
}
};
doAnswer(callable).when(mTestActivity).startPreferencePanelAsUser(any(), anyString(),
captor.capture(), anyInt(), any(), any());
AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, PACKAGE_NAME[0]);
assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo(
PACKAGE_NAME[0]);
assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_PERCENT)).isEqualTo(
"0%");
}
} }