diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1631e9c6c63..a2713211668 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4417,8 +4417,12 @@
Background activity
-
- Allow the app to run in the background
+
+ App can run in the background when not in use
+
+ App\'s background activity is limited when not in use
+
+ App not allowed to run in background
Screen usage since full charge
@@ -4632,13 +4636,25 @@
%1$s used by %2$s
- %1$s of overall battery
+ %1$s of overall battery
Breakdown since last full charge
Last full charge
Remaining battery time is approximate and can change based on usage
+
+ While using app
+
+ While in background
+
+ Battery usage
+
+ %1$s of total app usage (%2$dmAh)
+
+ Since full charge
+
+ Manage battery usage
Estimated time left
diff --git a/res/xml/power_usage_detail_ia.xml b/res/xml/power_usage_detail_ia.xml
new file mode 100644
index 00000000000..cfaa7124801
--- /dev/null
+++ b/res/xml/power_usage_detail_ia.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 909ddfe7f8f..4c8fb2d3414 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -74,6 +74,7 @@ import android.provider.ContactsContract.Profile;
import android.provider.ContactsContract.RawContacts;
import android.provider.Settings;
import android.service.persistentdata.PersistentDataBlockManager;
+import android.support.annotation.StringRes;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceManager;
@@ -1241,6 +1242,17 @@ public final class Utils extends com.android.settingslib.Utils {
return isVolumeValid(volume) ? volume : null;
}
+ /**
+ * Return the resource id to represent the install status for an app
+ */
+ @StringRes
+ public static int getInstallationStatus(ApplicationInfo info) {
+ if ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
+ return R.string.not_installed;
+ }
+ return info.enabled ? R.string.installed : R.string.disabled;
+ }
+
private static boolean isVolumeValid(VolumeInfo volume) {
return (volume != null) && (volume.getType() == VolumeInfo.TYPE_PRIVATE)
&& volume.isMountedReadable();
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index e00ba92bc6e..dac10e7f5a9 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -546,7 +546,7 @@ public class InstalledAppDetails extends AppInfoBase
.newAppHeaderController(this, appSnippet)
.setLabel(mAppEntry)
.setIcon(mAppEntry)
- .setSummary(getString(getInstallationStatus(mAppEntry.info)))
+ .setSummary(getString(Utils.getInstallationStatus(mAppEntry.info)))
.setIsInstantApp(AppUtils.isInstant(mPackageInfo.applicationInfo))
.done(false /* rebindActions */);
mVersionPreference.setSummary(getString(R.string.version_text, pkgInfo.versionName));
@@ -574,14 +574,6 @@ public class InstalledAppDetails extends AppInfoBase
return showIt;
}
- @VisibleForTesting
- int getInstallationStatus(ApplicationInfo info) {
- if ((info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
- return R.string.not_installed;
- }
- return info.enabled ? R.string.installed : R.string.disabled;
- }
-
private boolean signaturesMatch(String pkg1, String pkg2) {
if (pkg1 != null && pkg2 != null) {
try {
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
new file mode 100644
index 00000000000..ece6b78930c
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import android.content.Context;
+import android.os.BatteryStats;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.support.annotation.VisibleForTesting;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+import android.view.View;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+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.SettingsActivity;
+import com.android.settings.Utils;
+import com.android.settings.applications.AppHeaderController;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.applications.ApplicationsState;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Power usage detail fragment for each app, this fragment contains
+ *
+ * 1. Detail battery usage information for app(i.e. usage time, usage amount)
+ * 2. Battery related controls for app(i.e uninstall, force stop)
+ *
+ * This fragment will replace {@link PowerUsageDetail}
+ */
+public class AdvancedPowerUsageDetail extends PowerUsageBase {
+
+ public static final String TAG = "AdvancedPowerUsageDetail";
+ public static final String EXTRA_UID = "extra_uid";
+ public static final String EXTRA_PACKAGE_NAME = "extra_package_name";
+ public static final String EXTRA_FOREGROUND_TIME = "extra_foreground_time";
+ public static final String EXTRA_BACKGROUND_TIME = "extra_background_time";
+ public static final String EXTRA_LABEL = "extra_label";
+ public static final String EXTRA_ICON_ID = "extra_icon_id";
+ public static final String EXTRA_POWER_USAGE_PERCENT = "extra_power_usage_percent";
+ public static final String EXTRA_POWER_USAGE_AMOUNT = "extra_power_usage_amount";
+
+ private static final String KEY_PREF_FOREGROUND = "app_usage_foreground";
+ private static final String KEY_PREF_BACKGROUND = "app_usage_background";
+ private static final String KEY_PREF_POWER_USAGE = "app_power_usage";
+ private static final String KEY_PREF_HEADER = "header_view";
+
+ @VisibleForTesting
+ LayoutPreference mHeaderPreference;
+ @VisibleForTesting
+ ApplicationsState mState;
+ @VisibleForTesting
+ ApplicationsState.AppEntry mAppEntry;
+
+ private Preference mForegroundPreference;
+ private Preference mBackgroundPreference;
+ private Preference mPowerUsagePreference;
+
+ public static void startBatteryDetailPage(SettingsActivity caller, PreferenceFragment fragment,
+ BatteryStatsHelper helper, int which, BatteryEntry entry, String usagePercent) {
+ // Initialize mStats if necessary.
+ helper.getStats();
+
+ final Bundle args = new Bundle();
+ final BatterySipper sipper = entry.sipper;
+ final BatteryStats.Uid uid = sipper.uidObj;
+
+ final long backgroundTimeMs = BatteryUtils.getProcessTimeMs(
+ BatteryUtils.StatusType.BACKGROUND, uid, which);
+ final long foregroundTimeMs = BatteryUtils.getProcessTimeMs(
+ BatteryUtils.StatusType.FOREGROUND, uid, which);
+
+ if (ArrayUtils.isEmpty(sipper.mPackages)) {
+ // populate data for system app
+ args.putString(EXTRA_LABEL, entry.getLabel());
+ args.putInt(EXTRA_ICON_ID, entry.iconId);
+ args.putString(EXTRA_PACKAGE_NAME, null);
+ } else {
+ // populate data for normal app
+ args.putString(EXTRA_PACKAGE_NAME, sipper.mPackages[0]);
+ }
+
+ args.putInt(EXTRA_UID, sipper.getUid());
+ args.putLong(EXTRA_BACKGROUND_TIME, backgroundTimeMs);
+ args.putLong(EXTRA_FOREGROUND_TIME, foregroundTimeMs);
+ args.putString(EXTRA_POWER_USAGE_PERCENT, usagePercent);
+ args.putInt(EXTRA_POWER_USAGE_AMOUNT, (int) sipper.totalPowerMah);
+
+ caller.startPreferencePanelAsUser(fragment, AdvancedPowerUsageDetail.class.getName(), args,
+ R.string.details_title, null, new UserHandle(UserHandle.myUserId()));
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mForegroundPreference = findPreference(KEY_PREF_FOREGROUND);
+ mBackgroundPreference = findPreference(KEY_PREF_BACKGROUND);
+ mPowerUsagePreference = findPreference(KEY_PREF_POWER_USAGE);
+ mHeaderPreference = (LayoutPreference) findPreference(KEY_PREF_HEADER);
+ mState = ApplicationsState.getInstance(getActivity().getApplication());
+
+ final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME);
+ if (packageName != null) {
+ mAppEntry = mState.getEntry(packageName, UserHandle.myUserId());
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ initHeader();
+
+ final Bundle bundle = getArguments();
+ final Context context = getContext();
+
+ final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
+ final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
+ final String usagePercent = bundle.getString(EXTRA_POWER_USAGE_PERCENT);
+ final int powerMah = bundle.getInt(EXTRA_POWER_USAGE_AMOUNT);
+ mForegroundPreference.setSummary(Utils.formatElapsedTime(context, foregroundTimeMs, false));
+ mBackgroundPreference.setSummary(Utils.formatElapsedTime(context, backgroundTimeMs, false));
+ mPowerUsagePreference.setSummary(
+ getString(R.string.battery_detail_power_percentage, usagePercent, powerMah));
+ }
+
+ @VisibleForTesting
+ void initHeader() {
+ final View appSnippet = mHeaderPreference.findViewById(R.id.app_snippet);
+ final Context context = getContext();
+ final Bundle bundle = getArguments();
+ AppHeaderController controller = FeatureFactory.getFactory(context)
+ .getApplicationFeatureProvider(context)
+ .newAppHeaderController(this, appSnippet)
+ .setButtonActions(AppHeaderController.ActionType.ACTION_NONE,
+ AppHeaderController.ActionType.ACTION_NONE);
+
+ if (mAppEntry == null) {
+ controller.setLabel(bundle.getString(EXTRA_LABEL));
+ controller.setIcon(getContext().getDrawable(bundle.getInt(EXTRA_ICON_ID)));
+ } else {
+ mState.ensureIcon(mAppEntry);
+ controller.setLabel(mAppEntry);
+ controller.setIcon(mAppEntry);
+ controller.setSummary(getString(Utils.getInstallationStatus(mAppEntry.info)));
+ }
+
+ controller.done(true /* rebindActions */);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.FUELGAUGE_POWER_USAGE_DETAIL;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.power_usage_detail_ia;
+ }
+
+ @Override
+ protected List getPreferenceControllers(Context context) {
+ final List controllers = new ArrayList<>();
+ final Bundle bundle = getArguments();
+ final int uid = bundle.getInt(EXTRA_UID, 0);
+ final String packageName = bundle.getString(EXTRA_PACKAGE_NAME);
+
+ controllers.add(new BackgroundActivityPreferenceController(context, uid));
+ controllers.add(new BatteryOptimizationPreferenceController(
+ (SettingsActivity) getActivity(), this));
+ controllers.add(
+ new AppButtonsPreferenceController(getActivity(), getLifecycle(), packageName));
+
+ return controllers;
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
new file mode 100644
index 00000000000..b02c8c5edbf
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import android.app.Activity;
+import android.os.UserHandle;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnResume;
+import com.android.settingslib.applications.ApplicationsState;
+
+/**
+ * Controller to control the uninstall button and forcestop button
+ */
+//TODO(b/35810915): refine the button logic and make InstalledAppDetails use this controller
+//TODO(b/35810915): add test for this file
+public class AppButtonsPreferenceController extends PreferenceController implements
+ LifecycleObserver, OnResume {
+ private static final String KEY_ACTION_BUTTONS = "action_buttons";
+
+ private ApplicationsState.AppEntry mAppEntry;
+ private LayoutPreference mButtonsPref;
+ private Button mForceStopButton;
+ private Button mUninstallButton;
+
+ public AppButtonsPreferenceController(Activity activity, Lifecycle lifecycle,
+ String packageName) {
+ super(activity);
+
+ lifecycle.addObserver(this);
+ ApplicationsState state = ApplicationsState.getInstance(activity.getApplication());
+
+ if (packageName != null) {
+ mAppEntry = state.getEntry(packageName, UserHandle.myUserId());
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mAppEntry != null;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ if (isAvailable()) {
+ mButtonsPref = (LayoutPreference) screen.findPreference(KEY_ACTION_BUTTONS);
+
+ mUninstallButton = (Button) mButtonsPref.findViewById(R.id.left_button);
+ mUninstallButton.setText(R.string.uninstall_text);
+
+ mForceStopButton = (Button) mButtonsPref.findViewById(R.id.right_button);
+ mForceStopButton.setText(R.string.force_stop);
+ }
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_ACTION_BUTTONS;
+ }
+
+ @Override
+ public void onResume() {
+ //TODO(b/35810915): check and update the status of buttons
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
index 0f083985b68..c249676084a 100644
--- a/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceController.java
@@ -23,6 +23,8 @@ import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.util.Log;
+
+import com.android.settings.R;
import com.android.settings.core.PreferenceController;
/**
@@ -56,8 +58,12 @@ public class BackgroundActivityPreferenceController extends PreferenceController
if (mode == AppOpsManager.MODE_ERRORED) {
preference.setEnabled(false);
+ preference.setSummary(R.string.background_activity_summary_disabled);
} else {
- ((SwitchPreference) preference).setChecked(mode != AppOpsManager.MODE_IGNORED);
+ final boolean checked = mode != AppOpsManager.MODE_IGNORED;
+ ((SwitchPreference) preference).setChecked(checked);
+ preference.setSummary(checked ? R.string.background_activity_summary_on
+ : R.string.background_activity_summary_off);
}
}
diff --git a/src/com/android/settings/fuelgauge/BatteryOptimizationPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryOptimizationPreferenceController.java
new file mode 100644
index 00000000000..946a9b89292
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatteryOptimizationPreferenceController.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v7.preference.Preference;
+import android.text.TextUtils;
+
+import com.android.settings.R;
+import com.android.settings.Settings;
+import com.android.settings.SettingsActivity;
+import com.android.settings.applications.ManageApplications;
+import com.android.settings.core.PreferenceController;
+
+/**
+ * Controller that jumps to high power optimization fragment
+ */
+public class BatteryOptimizationPreferenceController extends PreferenceController {
+
+ private static final String KEY_BACKGROUND_ACTIVITY = "battery_optimization";
+
+ private Fragment mFragment;
+ private SettingsActivity mSettingsActivity;
+
+ public BatteryOptimizationPreferenceController(SettingsActivity settingsActivity,
+ Fragment fragment) {
+ super(settingsActivity);
+ mFragment = fragment;
+ mSettingsActivity = settingsActivity;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BACKGROUND_ACTIVITY;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (!KEY_BACKGROUND_ACTIVITY.equals(preference.getKey())) {
+ return false;
+ }
+
+ Bundle args = new Bundle(1);
+ args.putString(ManageApplications.EXTRA_CLASSNAME,
+ Settings.HighPowerApplicationsActivity.class.getName());
+ mSettingsActivity.startPreferencePanel(mFragment, ManageApplications.class.getName(), args,
+ R.string.high_power_apps, null, null, 0);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
new file mode 100644
index 00000000000..85bc0fda5f1
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.fuelgauge;
+
+import android.annotation.IntDef;
+import android.os.BatteryStats;
+import android.os.SystemClock;
+import android.support.annotation.Nullable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Utils for battery operation
+ */
+public class BatteryUtils {
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({StatusType.FOREGROUND,
+ StatusType.BACKGROUND,
+ StatusType.ALL
+ })
+ public @interface StatusType {
+ int FOREGROUND = 0;
+ int BACKGROUND = 1;
+ int ALL = 2;
+ }
+
+ public static long getProcessTimeMs(@StatusType int type, @Nullable BatteryStats.Uid uid,
+ int which) {
+ if (uid == null) {
+ return 0;
+ }
+
+ switch (type) {
+ case StatusType.FOREGROUND:
+ return getProcessForegroundTimeMs(uid, which);
+ case StatusType.BACKGROUND:
+ return getProcessBackgroundTimeMs(uid, which);
+ case StatusType.ALL:
+ return getProcessForegroundTimeMs(uid, which)
+ + getProcessBackgroundTimeMs(uid, which);
+ }
+ return 0;
+ }
+
+ private static long getProcessBackgroundTimeMs(BatteryStats.Uid uid, int which) {
+ final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
+ final long timeUs = uid.getProcessStateTime(
+ BatteryStats.Uid.PROCESS_STATE_BACKGROUND, rawRealTimeUs, which);
+ return convertUsToMs(timeUs);
+ }
+
+ private static long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) {
+ final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
+ final int foregroundTypes[] = {BatteryStats.Uid.PROCESS_STATE_TOP,
+ BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE,
+ BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING,
+ BatteryStats.Uid.PROCESS_STATE_FOREGROUND};
+ long timeUs = 0;
+ for (int type : foregroundTypes) {
+ timeUs += uid.getProcessStateTime(type, rawRealTimeUs, which);
+ }
+
+ return convertUsToMs(timeUs);
+ }
+
+ private static long convertUsToMs(long timeUs) {
+ return timeUs / 1000;
+ }
+
+ private static long convertMsToUs(long timeMs) {
+ return timeMs * 1000;
+ }
+
+}
+
diff --git a/src/com/android/settings/fuelgauge/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
index fe7ef6eea5a..d4f2dd2c6a2 100644
--- a/src/com/android/settings/fuelgauge/PowerGaugePreference.java
+++ b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
@@ -63,6 +63,10 @@ public class PowerGaugePreference extends TintablePreference {
notifyChanged();
}
+ public String getPercent() {
+ return mProgress.toString();
+ }
+
BatteryEntry getInfo() {
return mInfo;
}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
index 956b27935d4..f0d0a104a56 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
@@ -69,6 +69,7 @@ import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
+// TODO(b/35810915): Delete this page once ag/1971493 is done.
public class PowerUsageDetail extends PowerUsageBase implements Button.OnClickListener {
// Note: Must match the sequence of the DrainType
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 1ffc594b379..b0e8fb0aeaa 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -165,8 +165,8 @@ public class PowerUsageSummary extends PowerUsageBase {
}
PowerGaugePreference pgp = (PowerGaugePreference) preference;
BatteryEntry entry = pgp.getInfo();
- PowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(), this,
- mStatsHelper, mStatsType, entry, true, true);
+ AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
+ this, mStatsHelper, mStatsType, entry, pgp.getPercent());
return super.onPreferenceTreeClick(preference);
}
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index 778440d4990..240b8eb18fb 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -4,5 +4,6 @@ com.android.settings.notification.ZenModePrioritySettings
com.android.settings.inputmethod.InputAndGestureSettings
com.android.settings.accounts.AccountDetailDashboardFragment
com.android.settings.fuelgauge.PowerUsageDetail
+com.android.settings.fuelgauge.AdvancedPowerUsageDetail
com.android.settings.deviceinfo.StorageProfileFragment
com.android.settings.wifi.details.WifiNetworkDetailsFragment
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index 324e75104b5..8b7605c2384 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -9,6 +9,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -116,4 +117,28 @@ public class UtilsTest {
Utils.maybeInitializeVolume(storageManager, new Bundle());
}
+
+ @Test
+ public void getInstallationStatus_notInstalled_shouldReturnUninstalled() {
+ assertThat(Utils.getInstallationStatus(new ApplicationInfo()))
+ .isEqualTo(R.string.not_installed);
+ }
+
+ @Test
+ public void getInstallationStatus_enabled_shouldReturnInstalled() {
+ final ApplicationInfo info = new ApplicationInfo();
+ info.flags = ApplicationInfo.FLAG_INSTALLED;
+ info.enabled = true;
+
+ assertThat(Utils.getInstallationStatus(info)).isEqualTo(R.string.installed);
+ }
+
+ @Test
+ public void getInstallationStatus_disabled_shouldReturnDisabled() {
+ final ApplicationInfo info = new ApplicationInfo();
+ info.flags = ApplicationInfo.FLAG_INSTALLED;
+ info.enabled = false;
+
+ assertThat(Utils.getInstallationStatus(info)).isEqualTo(R.string.disabled);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
index b0cd8d5b9ef..bf00889ab0e 100644
--- a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
@@ -67,31 +67,6 @@ public final class InstalledAppDetailsTest {
mAppDetail = new InstalledAppDetails();
}
- @Test
- public void getInstallationStatus_notInstalled_shouldReturnUninstalled() {
-
- assertThat(mAppDetail.getInstallationStatus(new ApplicationInfo()))
- .isEqualTo(R.string.not_installed);
- }
-
- @Test
- public void getInstallationStatus_enabled_shouldReturnInstalled() {
- final ApplicationInfo info = new ApplicationInfo();
- info.flags = ApplicationInfo.FLAG_INSTALLED;
- info.enabled = true;
-
- assertThat(mAppDetail.getInstallationStatus(info)).isEqualTo(R.string.installed);
- }
-
- @Test
- public void getInstallationStatus_disabled_shouldReturnDisabled() {
- final ApplicationInfo info = new ApplicationInfo();
- info.flags = ApplicationInfo.FLAG_INSTALLED;
- info.enabled = false;
-
- assertThat(mAppDetail.getInstallationStatus(info)).isEqualTo(R.string.disabled);
- }
-
@Test
public void shouldShowUninstallForAll_installForOneOtherUserOnly_shouldReturnTrue() {
when(mDevicePolicyManager.packageHasActiveAdmins(anyString())).thenReturn(false);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
new file mode 100644
index 00000000000..8b5ce192d17
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.graphics.drawable.Drawable;
+import android.os.BatteryStats;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.view.View;
+
+import com.android.internal.os.BatterySipper;
+import com.android.internal.os.BatteryStatsHelper;
+import com.android.settings.SettingsActivity;
+import com.android.settings.TestConfig;
+import com.android.settings.applications.AppHeaderController;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.applications.ApplicationsState;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AdvancedPowerUsageDetailTest {
+ private static final String APP_LABEL = "app label";
+ private static final String SUMMARY = "summary";
+ private static final String[] PACKAGE_NAME = {"com.android.app"};
+ private static final String USAGE_PERCENT = "16";
+ private static final int ICON_ID = 123;
+ private static final int UID = 1;
+ private static final long BACKGROUND_TIME_US = 100 * 1000;
+ private static final long FOREGROUND_TIME_US = 200 * 1000;
+ private static final long BACKGROUND_TIME_MS = 100;
+ private static final long FOREGROUND_TIME_MS = 200;
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private AppHeaderController mAppHeaderController;
+ @Mock
+ private LayoutPreference mHeaderPreference;
+ @Mock
+ private ApplicationsState mState;
+ @Mock
+ private ApplicationsState.AppEntry mAppEntry;
+ @Mock
+ private Drawable mIconDrawable;
+ @Mock
+ private Bundle mBundle;
+ @Mock
+ private BatteryEntry mBatteryEntry;
+ @Mock
+ private BatterySipper mBatterySipper;
+ @Mock
+ private BatteryStatsHelper mBatteryStatsHelper;
+ @Mock
+ private BatteryStats.Uid mUid;
+ private Bundle mTestBundle;
+ private AdvancedPowerUsageDetail mFragment;
+ private FakeFeatureFactory mFeatureFactory;
+ private SettingsActivity mTestActivity;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest(mContext);
+ mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+
+ mFragment = spy(new AdvancedPowerUsageDetail());
+ doReturn(mContext).when(mFragment).getContext();
+ doReturn(SUMMARY).when(mFragment).getString(anyInt());
+ doReturn(APP_LABEL).when(mBundle).getString(anyString());
+ doReturn(mBundle).when(mFragment).getArguments();
+
+ doReturn(mAppHeaderController).when(mFeatureFactory.applicationFeatureProvider)
+ .newAppHeaderController(any(Fragment.class), any(View.class));
+ doReturn(mAppHeaderController).when(mAppHeaderController).setButtonActions(anyInt(),
+ anyInt());
+ doReturn(mAppHeaderController).when(mAppHeaderController).setIcon(any(Drawable.class));
+ doReturn(mAppHeaderController).when(mAppHeaderController).setIcon(any(
+ ApplicationsState.AppEntry.class));
+ doReturn(mAppHeaderController).when(mAppHeaderController).setLabel(anyString());
+ doReturn(mAppHeaderController).when(mAppHeaderController).setLabel(any(
+ ApplicationsState.AppEntry.class));
+ doReturn(mAppHeaderController).when(mAppHeaderController).setSummary(anyString());
+
+
+ doReturn(UID).when(mBatterySipper).getUid();
+ doReturn(APP_LABEL).when(mBatteryEntry).getLabel();
+ doReturn(BACKGROUND_TIME_US).when(mUid).getProcessStateTime(
+ eq(BatteryStats.Uid.PROCESS_STATE_BACKGROUND), anyLong(), anyInt());
+ doReturn(FOREGROUND_TIME_US).when(mUid).getProcessStateTime(
+ eq(BatteryStats.Uid.PROCESS_STATE_FOREGROUND), anyLong(), anyInt());
+ ReflectionHelpers.setField(mBatteryEntry, "sipper", mBatterySipper);
+ mBatteryEntry.iconId = ICON_ID;
+ mBatterySipper.uidObj = mUid;
+
+ mFragment.mHeaderPreference = mHeaderPreference;
+ mFragment.mState = mState;
+ mAppEntry.info = mock(ApplicationInfo.class);
+
+ mTestActivity = spy(new SettingsActivity());
+
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(Bundle.class);
+
+ Answer callable = new Answer() {
+ @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());
+ }
+
+ @Test
+ public void testInitHeader_NoAppEntry_BuildByBundle() {
+ mFragment.mAppEntry = null;
+ mFragment.initHeader();
+
+ verify(mAppHeaderController).setIcon(any(Drawable.class));
+ verify(mAppHeaderController).setLabel(APP_LABEL);
+ }
+
+ @Test
+ public void testInitHeader_HasAppEntry_BuildByAppEntry() {
+ mFragment.mAppEntry = mAppEntry;
+ mFragment.initHeader();
+
+ verify(mAppHeaderController).setIcon(mAppEntry);
+ verify(mAppHeaderController).setLabel(mAppEntry);
+ }
+
+ @Test
+ public void testStartBatteryDetailPage_hasBasicData() {
+ AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0,
+ mBatteryEntry, USAGE_PERCENT);
+
+ assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID);
+ assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME)).isEqualTo(
+ BACKGROUND_TIME_MS);
+ assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME)).isEqualTo(
+ FOREGROUND_TIME_MS);
+ assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_PERCENT)).isEqualTo(
+ USAGE_PERCENT);
+ }
+
+ @Test
+ public void testStartBatteryDetailPage_NormalApp() {
+ mBatterySipper.mPackages = PACKAGE_NAME;
+ AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0,
+ mBatteryEntry, USAGE_PERCENT);
+
+ assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo(
+ PACKAGE_NAME[0]);
+ }
+
+ @Test
+ public void testStartBatteryDetailPage_SystemApp() {
+ mBatterySipper.mPackages = null;
+ AdvancedPowerUsageDetail.startBatteryDetailPage(mTestActivity, null, mBatteryStatsHelper, 0,
+ mBatteryEntry, USAGE_PERCENT);
+
+ assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_LABEL)).isEqualTo(APP_LABEL);
+ assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_ICON_ID)).isEqualTo(ICON_ID);
+ assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo(null);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizationPreferenceControllerTest.java
new file mode 100644
index 00000000000..2c5296aca48
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizationPreferenceControllerTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.SettingsActivity;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BatteryOptimizationPreferenceControllerTest {
+ private static final String KEY_OPTIMIZATION = "battery_optimization";
+ private static final String KEY_OTHER = "other";
+ @Mock
+ private SettingsActivity mSettingsActivity;
+ @Mock
+ private Fragment mFragment;
+ @Mock
+ private Preference mPreference;
+
+ private BatteryOptimizationPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mController = new BatteryOptimizationPreferenceController(mSettingsActivity, mFragment);
+ }
+
+ @Test
+ public void testHandlePreferenceTreeClick_OptimizationPreference_HandleClick() {
+ when(mPreference.getKey()).thenReturn(KEY_OPTIMIZATION);
+
+ final boolean handled = mController.handlePreferenceTreeClick(mPreference);
+
+ assertThat(handled).isTrue();
+ verify(mSettingsActivity).startPreferencePanel(any(Fragment.class),
+ anyString(), any(Bundle.class), anyInt(), any(CharSequence.class),
+ any(Fragment.class), anyInt());
+ }
+
+ @Test
+ public void testHandlePreferenceTreeClick_OtherPreference_NotHandleClick() {
+ when(mPreference.getKey()).thenReturn(KEY_OTHER);
+
+ final boolean handled = mController.handlePreferenceTreeClick(mPreference);
+
+ assertThat(handled).isFalse();
+ verify(mSettingsActivity, never()).startPreferencePanel(any(Fragment.class),
+ anyString(), any(Bundle.class), anyInt(), any(CharSequence.class),
+ any(Fragment.class), anyInt());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
new file mode 100644
index 00000000000..672cc903fd4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.fuelgauge;
+
+import android.os.BatteryStats;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static android.os.BatteryStats.Uid.PROCESS_STATE_BACKGROUND;
+import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND;
+import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE;
+import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;
+import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Matchers.eq;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BatteryUtilsTest {
+ // unit that used to converted ms to us
+ private static final long UNIT = 1000;
+ private static final long TIME_STATE_TOP = 1500 * UNIT;
+ private static final long TIME_STATE_FOREGROUND_SERVICE = 2000 * UNIT;
+ private static final long TIME_STATE_TOP_SLEEPING = 2500 * UNIT;
+ private static final long TIME_STATE_FOREGROUND = 3000 * UNIT;
+ private static final long TIME_STATE_BACKGROUND = 6000 * UNIT;
+
+ private static final long TIME_EXPECTED_FOREGROUND = 9000;
+ private static final long TIME_EXPECTED_BACKGROUND = 6000;
+ private static final long TIME_EXPECTED_ALL = 15000;
+
+ @Mock
+ BatteryStats.Uid mUid;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ doReturn(TIME_STATE_TOP).when(mUid).getProcessStateTime(eq(PROCESS_STATE_TOP), anyLong(),
+ anyInt());
+ doReturn(TIME_STATE_FOREGROUND_SERVICE).when(mUid).getProcessStateTime(
+ eq(PROCESS_STATE_FOREGROUND_SERVICE), anyLong(), anyInt());
+ doReturn(TIME_STATE_TOP_SLEEPING).when(mUid).getProcessStateTime(
+ eq(PROCESS_STATE_TOP_SLEEPING), anyLong(), anyInt());
+ doReturn(TIME_STATE_FOREGROUND).when(mUid).getProcessStateTime(eq(PROCESS_STATE_FOREGROUND),
+ anyLong(), anyInt());
+ doReturn(TIME_STATE_BACKGROUND).when(mUid).getProcessStateTime(eq(PROCESS_STATE_BACKGROUND),
+ anyLong(), anyInt());
+ }
+
+ @Test
+ public void testGetProcessTimeMs_typeForeground_timeCorrect() {
+ final long time = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.FOREGROUND, mUid,
+ BatteryStats.STATS_SINCE_CHARGED);
+
+ assertThat(time).isEqualTo(TIME_EXPECTED_FOREGROUND);
+ }
+
+ @Test
+ public void testGetProcessTimeMs_typeBackground_timeCorrect() {
+ final long time = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.BACKGROUND, mUid,
+ BatteryStats.STATS_SINCE_CHARGED);
+
+ assertThat(time).isEqualTo(TIME_EXPECTED_BACKGROUND);
+ }
+
+ @Test
+ public void testGetProcessTimeMs_typeAll_timeCorrect() {
+ final long time = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, mUid,
+ BatteryStats.STATS_SINCE_CHARGED);
+
+ assertThat(time).isEqualTo(TIME_EXPECTED_ALL);
+ }
+
+ @Test
+ public void testGetProcessTimeMs_uidNull_returnZero() {
+ final long time = BatteryUtils.getProcessTimeMs(BatteryUtils.StatusType.ALL, null,
+ BatteryStats.STATS_SINCE_CHARGED);
+
+ assertThat(time).isEqualTo(0);
+ }
+}