Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/16221114 Change-Id: I4c9d5265d8abd4a73a19df2afc5c718d8827ddab
685 lines
31 KiB
Java
685 lines
31 KiB
Java
/*
|
|
* 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.UserIdInt;
|
|
import android.app.Activity;
|
|
import android.app.ActivityManager;
|
|
import android.app.settings.SettingsEnums;
|
|
import android.app.backup.BackupManager;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.pm.PackageManager;
|
|
import android.os.Bundle;
|
|
import android.os.UserHandle;
|
|
import android.text.TextUtils;
|
|
import android.text.format.DateUtils;
|
|
import android.util.Log;
|
|
import android.view.View;
|
|
|
|
import androidx.annotation.VisibleForTesting;
|
|
import androidx.preference.Preference;
|
|
|
|
import com.android.settings.R;
|
|
import com.android.settings.SettingsActivity;
|
|
import com.android.settings.Utils;
|
|
import com.android.settings.applications.appinfo.AppButtonsPreferenceController;
|
|
import com.android.settings.applications.appinfo.ButtonActionDialogFragment;
|
|
import com.android.settings.core.InstrumentedPreferenceFragment;
|
|
import com.android.settings.core.SubSettingLauncher;
|
|
import com.android.settings.dashboard.DashboardFragment;
|
|
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
|
|
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
|
import com.android.settings.overlay.FeatureFactory;
|
|
import com.android.settings.widget.EntityHeaderController;
|
|
import com.android.settingslib.HelpUtils;
|
|
import com.android.settingslib.applications.AppUtils;
|
|
import com.android.settingslib.applications.ApplicationsState;
|
|
import com.android.settingslib.core.AbstractPreferenceController;
|
|
import com.android.settingslib.utils.StringUtil;
|
|
import com.android.settingslib.widget.FooterPreference;
|
|
import com.android.settingslib.widget.LayoutPreference;
|
|
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
|
|
|
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)
|
|
*/
|
|
public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|
ButtonActionDialogFragment.AppButtonsDialogListener,
|
|
BatteryTipPreferenceController.BatteryTipListener,
|
|
SelectorWithWidgetPreference.OnClickListener {
|
|
|
|
public static final String TAG = "AdvancedPowerDetail";
|
|
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_SLOT_TIME = "extra_slot_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_HEADER = "header_view";
|
|
private static final String KEY_PREF_UNRESTRICTED = "unrestricted_pref";
|
|
private static final String KEY_PREF_OPTIMIZED = "optimized_pref";
|
|
private static final String KEY_PREF_RESTRICTED = "restricted_pref";
|
|
private static final String KEY_FOOTER_PREFERENCE = "app_usage_footer_preference";
|
|
private static final String PACKAGE_NAME_NONE = "none";
|
|
|
|
private static final int REQUEST_UNINSTALL = 0;
|
|
private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1;
|
|
|
|
@VisibleForTesting
|
|
LayoutPreference mHeaderPreference;
|
|
@VisibleForTesting
|
|
ApplicationsState mState;
|
|
@VisibleForTesting
|
|
ApplicationsState.AppEntry mAppEntry;
|
|
@VisibleForTesting
|
|
BatteryUtils mBatteryUtils;
|
|
@VisibleForTesting
|
|
BatteryOptimizeUtils mBatteryOptimizeUtils;
|
|
@VisibleForTesting
|
|
Preference mForegroundPreference;
|
|
@VisibleForTesting
|
|
Preference mBackgroundPreference;
|
|
@VisibleForTesting
|
|
FooterPreference mFooterPreference;
|
|
@VisibleForTesting
|
|
SelectorWithWidgetPreference mRestrictedPreference;
|
|
@VisibleForTesting
|
|
SelectorWithWidgetPreference mOptimizePreference;
|
|
@VisibleForTesting
|
|
SelectorWithWidgetPreference mUnrestrictedPreference;
|
|
@VisibleForTesting
|
|
boolean mEnableTriState = true;
|
|
@VisibleForTesting
|
|
@BatteryOptimizeUtils.OptimizationMode
|
|
int mOptimizationMode = BatteryOptimizeUtils.MODE_UNKNOWN;
|
|
@VisibleForTesting
|
|
BackupManager mBackupManager;
|
|
|
|
private AppButtonsPreferenceController mAppButtonsPreferenceController;
|
|
private BackgroundActivityPreferenceController mBackgroundActivityPreferenceController;
|
|
|
|
// A wrapper class to carry LaunchBatteryDetailPage required arguments.
|
|
private static final class LaunchBatteryDetailPageArgs {
|
|
private String mUsagePercent;
|
|
private String mPackageName;
|
|
private String mAppLabel;
|
|
private String mSlotInformation;
|
|
private int mUid;
|
|
private int mIconId;
|
|
private int mConsumedPower;
|
|
private long mForegroundTimeMs;
|
|
private long mBackgroundTimeMs;
|
|
private boolean mIsUserEntry;
|
|
}
|
|
|
|
/** Launches battery details page for an individual battery consumer. */
|
|
public static void startBatteryDetailPage(
|
|
Activity caller, InstrumentedPreferenceFragment fragment,
|
|
BatteryDiffEntry diffEntry, String usagePercent,
|
|
boolean isValidToShowSummary, String slotInformation) {
|
|
final BatteryHistEntry histEntry = diffEntry.mBatteryHistEntry;
|
|
final LaunchBatteryDetailPageArgs launchArgs = new LaunchBatteryDetailPageArgs();
|
|
// configure the launch argument.
|
|
launchArgs.mUsagePercent = usagePercent;
|
|
launchArgs.mPackageName = diffEntry.getPackageName();
|
|
launchArgs.mAppLabel = diffEntry.getAppLabel();
|
|
launchArgs.mSlotInformation = slotInformation;
|
|
launchArgs.mUid = (int) histEntry.mUid;
|
|
launchArgs.mIconId = diffEntry.getAppIconId();
|
|
launchArgs.mConsumedPower = (int) diffEntry.mConsumePower;
|
|
launchArgs.mForegroundTimeMs =
|
|
isValidToShowSummary ? diffEntry.mForegroundUsageTimeInMs : 0;
|
|
launchArgs.mBackgroundTimeMs =
|
|
isValidToShowSummary ? diffEntry.mBackgroundUsageTimeInMs : 0;
|
|
launchArgs.mIsUserEntry = histEntry.isUserEntry();
|
|
startBatteryDetailPage(caller, fragment, launchArgs);
|
|
}
|
|
|
|
/** Launches battery details page for an individual battery consumer. */
|
|
public static void startBatteryDetailPage(Activity caller,
|
|
InstrumentedPreferenceFragment fragment, BatteryEntry entry, String usagePercent,
|
|
boolean isValidToShowSummary) {
|
|
final LaunchBatteryDetailPageArgs launchArgs = new LaunchBatteryDetailPageArgs();
|
|
// configure the launch argument.
|
|
launchArgs.mUsagePercent = usagePercent;
|
|
launchArgs.mPackageName = entry.getDefaultPackageName();
|
|
launchArgs.mAppLabel = entry.getLabel();
|
|
launchArgs.mUid = entry.getUid();
|
|
launchArgs.mIconId = entry.iconId;
|
|
launchArgs.mConsumedPower = (int) entry.getConsumedPower();
|
|
launchArgs.mForegroundTimeMs = isValidToShowSummary ? entry.getTimeInForegroundMs() : 0;
|
|
launchArgs.mBackgroundTimeMs = isValidToShowSummary ? entry.getTimeInBackgroundMs() : 0;
|
|
launchArgs.mIsUserEntry = entry.isUserEntry();
|
|
startBatteryDetailPage(caller, fragment, launchArgs);
|
|
}
|
|
|
|
private static void startBatteryDetailPage(Activity caller,
|
|
InstrumentedPreferenceFragment fragment, LaunchBatteryDetailPageArgs launchArgs) {
|
|
final Bundle args = new Bundle();
|
|
if (launchArgs.mPackageName == null) {
|
|
// populate data for system app
|
|
args.putString(EXTRA_LABEL, launchArgs.mAppLabel);
|
|
args.putInt(EXTRA_ICON_ID, launchArgs.mIconId);
|
|
args.putString(EXTRA_PACKAGE_NAME, null);
|
|
} else {
|
|
// populate data for normal app
|
|
args.putString(EXTRA_PACKAGE_NAME, launchArgs.mPackageName);
|
|
}
|
|
|
|
args.putInt(EXTRA_UID, launchArgs.mUid);
|
|
args.putLong(EXTRA_BACKGROUND_TIME, launchArgs.mBackgroundTimeMs);
|
|
args.putLong(EXTRA_FOREGROUND_TIME, launchArgs.mForegroundTimeMs);
|
|
args.putString(EXTRA_SLOT_TIME, launchArgs.mSlotInformation);
|
|
args.putString(EXTRA_POWER_USAGE_PERCENT, launchArgs.mUsagePercent);
|
|
args.putInt(EXTRA_POWER_USAGE_AMOUNT, launchArgs.mConsumedPower);
|
|
final int userId = launchArgs.mIsUserEntry ? ActivityManager.getCurrentUser()
|
|
: UserHandle.getUserId(launchArgs.mUid);
|
|
|
|
new SubSettingLauncher(caller)
|
|
.setDestination(AdvancedPowerUsageDetail.class.getName())
|
|
.setTitleRes(R.string.battery_details_title)
|
|
.setArguments(args)
|
|
.setSourceMetricsCategory(fragment.getMetricsCategory())
|
|
.setUserHandle(new UserHandle(userId))
|
|
.launch();
|
|
}
|
|
|
|
private static @UserIdInt int getUserIdToLaunchAdvancePowerUsageDetail(
|
|
BatteryEntry batteryEntry) {
|
|
if (batteryEntry.isUserEntry()) {
|
|
return ActivityManager.getCurrentUser();
|
|
}
|
|
return UserHandle.getUserId(batteryEntry.getUid());
|
|
}
|
|
|
|
public static void startBatteryDetailPage(Activity caller,
|
|
InstrumentedPreferenceFragment fragment, String packageName) {
|
|
final Bundle args = new Bundle(3);
|
|
final PackageManager packageManager = caller.getPackageManager();
|
|
args.putString(EXTRA_PACKAGE_NAME, packageName);
|
|
args.putString(EXTRA_POWER_USAGE_PERCENT, Utils.formatPercentage(0));
|
|
try {
|
|
args.putInt(EXTRA_UID, packageManager.getPackageUid(packageName, 0 /* no flag */));
|
|
} catch (PackageManager.NameNotFoundException e) {
|
|
Log.w(TAG, "Cannot find package: " + packageName, e);
|
|
}
|
|
|
|
new SubSettingLauncher(caller)
|
|
.setDestination(AdvancedPowerUsageDetail.class.getName())
|
|
.setTitleRes(R.string.battery_details_title)
|
|
.setArguments(args)
|
|
.setSourceMetricsCategory(fragment.getMetricsCategory())
|
|
.launch();
|
|
}
|
|
|
|
@Override
|
|
public void onAttach(Activity activity) {
|
|
super.onAttach(activity);
|
|
|
|
mState = ApplicationsState.getInstance(getActivity().getApplication());
|
|
mBatteryUtils = BatteryUtils.getInstance(getContext());
|
|
}
|
|
|
|
@Override
|
|
public void onCreate(Bundle icicle) {
|
|
super.onCreate(icicle);
|
|
|
|
final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME);
|
|
if (mEnableTriState) {
|
|
onCreateForTriState(packageName);
|
|
} else {
|
|
mForegroundPreference = findPreference(KEY_PREF_FOREGROUND);
|
|
mBackgroundPreference = findPreference(KEY_PREF_BACKGROUND);
|
|
}
|
|
mHeaderPreference = findPreference(KEY_PREF_HEADER);
|
|
|
|
if (packageName != null) {
|
|
mAppEntry = mState.getEntry(packageName, UserHandle.myUserId());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
|
|
initHeader();
|
|
if (mEnableTriState) {
|
|
mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode();
|
|
initPreferenceForTriState(getContext());
|
|
final String packageName = mBatteryOptimizeUtils.getPackageName();
|
|
FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
|
|
.action(
|
|
getContext(),
|
|
SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
|
packageName);
|
|
} else {
|
|
initPreference(getContext());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
super.onPause();
|
|
if (mEnableTriState) {
|
|
final int selectedPreference = getSelectedPreference();
|
|
|
|
notifyBackupManager();
|
|
logMetricCategory(selectedPreference);
|
|
mBatteryOptimizeUtils.setAppUsageState(selectedPreference);
|
|
Log.d(TAG, "Leave with mode: " + selectedPreference);
|
|
}
|
|
}
|
|
|
|
@VisibleForTesting
|
|
void notifyBackupManager() {
|
|
if (mOptimizationMode != mBatteryOptimizeUtils.getAppOptimizationMode()) {
|
|
final BackupManager backupManager = mBackupManager != null
|
|
? mBackupManager : new BackupManager(getContext());
|
|
backupManager.dataChanged();
|
|
}
|
|
}
|
|
|
|
@VisibleForTesting
|
|
void initHeader() {
|
|
final View appSnippet = mHeaderPreference.findViewById(R.id.entity_header);
|
|
final Activity context = getActivity();
|
|
final Bundle bundle = getArguments();
|
|
EntityHeaderController controller = EntityHeaderController
|
|
.newInstance(context, this, appSnippet)
|
|
.setRecyclerView(getListView(), getSettingsLifecycle())
|
|
.setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
|
|
EntityHeaderController.ActionType.ACTION_NONE);
|
|
|
|
if (mAppEntry == null) {
|
|
controller.setLabel(bundle.getString(EXTRA_LABEL));
|
|
|
|
final int iconId = bundle.getInt(EXTRA_ICON_ID, 0);
|
|
if (iconId == 0) {
|
|
controller.setIcon(context.getPackageManager().getDefaultActivityIcon());
|
|
} else {
|
|
controller.setIcon(context.getDrawable(bundle.getInt(EXTRA_ICON_ID)));
|
|
}
|
|
} else {
|
|
mState.ensureIcon(mAppEntry);
|
|
controller.setLabel(mAppEntry);
|
|
controller.setIcon(mAppEntry);
|
|
controller.setIsInstantApp(AppUtils.isInstant(mAppEntry.info));
|
|
}
|
|
|
|
if (mEnableTriState) {
|
|
controller.setSummary(getAppActiveTime(bundle));
|
|
}
|
|
|
|
controller.done(context, true /* rebindActions */);
|
|
}
|
|
|
|
@VisibleForTesting
|
|
void initPreference(Context context) {
|
|
final Bundle bundle = getArguments();
|
|
final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
|
|
final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
|
|
mForegroundPreference.setSummary(
|
|
TextUtils.expandTemplate(getText(R.string.battery_used_for),
|
|
StringUtil.formatElapsedTime(
|
|
context,
|
|
foregroundTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false)));
|
|
mBackgroundPreference.setSummary(
|
|
TextUtils.expandTemplate(getText(R.string.battery_active_for),
|
|
StringUtil.formatElapsedTime(
|
|
context,
|
|
backgroundTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false)));
|
|
}
|
|
|
|
@VisibleForTesting
|
|
void initPreferenceForTriState(Context context) {
|
|
final String stateString;
|
|
final String footerString;
|
|
|
|
if (!mBatteryOptimizeUtils.isValidPackageName()) {
|
|
// Present optimized only string when the package name is invalid.
|
|
stateString = context.getString(R.string.manager_battery_usage_optimized_only);
|
|
footerString = context.getString(
|
|
R.string.manager_battery_usage_footer_limited, stateString);
|
|
} else if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) {
|
|
// Present unrestricted only string when the package is system or default active app.
|
|
stateString = context.getString(R.string.manager_battery_usage_unrestricted_only);
|
|
footerString = context.getString(
|
|
R.string.manager_battery_usage_footer_limited, stateString);
|
|
} else {
|
|
// Present default string to normal app.
|
|
footerString = context.getString(R.string.manager_battery_usage_footer);
|
|
}
|
|
mFooterPreference.setTitle(footerString);
|
|
final Intent helpIntent = HelpUtils.getHelpIntent(context, context.getString(
|
|
R.string.help_url_app_usage_settings), /*backupContext=*/ "");
|
|
if (helpIntent != null) {
|
|
mFooterPreference.setLearnMoreAction(v ->
|
|
startActivityForResult(helpIntent, /*requestCode=*/ 0));
|
|
mFooterPreference.setLearnMoreContentDescription(
|
|
context.getString(R.string.manager_battery_usage_link_a11y));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int getMetricsCategory() {
|
|
return SettingsEnums.FUELGAUGE_POWER_USAGE_DETAIL;
|
|
}
|
|
|
|
@Override
|
|
protected String getLogTag() {
|
|
return TAG;
|
|
}
|
|
|
|
@Override
|
|
protected int getPreferenceScreenResId() {
|
|
return mEnableTriState ? R.xml.power_usage_detail : R.xml.power_usage_detail_legacy;
|
|
}
|
|
|
|
@Override
|
|
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
|
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
|
final Bundle bundle = getArguments();
|
|
final int uid = bundle.getInt(EXTRA_UID, 0);
|
|
final String packageName = bundle.getString(EXTRA_PACKAGE_NAME);
|
|
|
|
mAppButtonsPreferenceController = new AppButtonsPreferenceController(
|
|
(SettingsActivity) getActivity(), this, getSettingsLifecycle(),
|
|
packageName, mState, REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN);
|
|
controllers.add(mAppButtonsPreferenceController);
|
|
if (mEnableTriState) {
|
|
controllers.add(new UnrestrictedPreferenceController(context, uid, packageName));
|
|
controllers.add(new OptimizedPreferenceController(context, uid, packageName));
|
|
controllers.add(new RestrictedPreferenceController(context, uid, packageName));
|
|
} else {
|
|
mBackgroundActivityPreferenceController = new BackgroundActivityPreferenceController(
|
|
context, this, uid, packageName);
|
|
controllers.add(mBackgroundActivityPreferenceController);
|
|
controllers.add(new BatteryOptimizationPreferenceController(
|
|
(SettingsActivity) getActivity(), this, packageName));
|
|
}
|
|
|
|
return controllers;
|
|
}
|
|
|
|
@Override
|
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
if (mAppButtonsPreferenceController != null) {
|
|
mAppButtonsPreferenceController.handleActivityResult(requestCode, resultCode, data);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void handleDialogClick(int id) {
|
|
if (mAppButtonsPreferenceController != null) {
|
|
mAppButtonsPreferenceController.handleDialogClick(id);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onBatteryTipHandled(BatteryTip batteryTip) {
|
|
mBackgroundActivityPreferenceController.updateSummary(
|
|
findPreference(mBackgroundActivityPreferenceController.getPreferenceKey()));
|
|
}
|
|
|
|
@Override
|
|
public void onRadioButtonClicked(SelectorWithWidgetPreference selected) {
|
|
final String selectedKey = selected.getKey();
|
|
updatePreferenceState(mUnrestrictedPreference, selectedKey);
|
|
updatePreferenceState(mOptimizePreference, selectedKey);
|
|
updatePreferenceState(mRestrictedPreference, selectedKey);
|
|
}
|
|
|
|
private void updatePreferenceState(SelectorWithWidgetPreference preference,
|
|
String selectedKey) {
|
|
preference.setChecked(selectedKey.equals(preference.getKey()));
|
|
}
|
|
|
|
private void logMetricCategory(int selectedKey) {
|
|
if (selectedKey == mOptimizationMode) {
|
|
return;
|
|
}
|
|
|
|
int metricCategory = 0;
|
|
switch (selectedKey) {
|
|
case BatteryOptimizeUtils.MODE_UNRESTRICTED:
|
|
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_UNRESTRICTED;
|
|
break;
|
|
case BatteryOptimizeUtils.MODE_OPTIMIZED:
|
|
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED;
|
|
break;
|
|
case BatteryOptimizeUtils.MODE_RESTRICTED:
|
|
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_RESTRICTED;
|
|
break;
|
|
}
|
|
|
|
if (metricCategory != 0) {
|
|
final String packageName = mBatteryOptimizeUtils.getPackageName();
|
|
FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
|
|
.action(
|
|
/* attribution */ SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
|
/* action */ metricCategory,
|
|
/* pageId */ SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
|
TextUtils.isEmpty(packageName) ? PACKAGE_NAME_NONE : packageName,
|
|
getArguments().getInt(EXTRA_POWER_USAGE_AMOUNT));
|
|
}
|
|
}
|
|
|
|
private void onCreateForTriState(String packageName) {
|
|
mUnrestrictedPreference = findPreference(KEY_PREF_UNRESTRICTED);
|
|
mOptimizePreference = findPreference(KEY_PREF_OPTIMIZED);
|
|
mRestrictedPreference = findPreference(KEY_PREF_RESTRICTED);
|
|
mFooterPreference = findPreference(KEY_FOOTER_PREFERENCE);
|
|
mUnrestrictedPreference.setOnClickListener(this);
|
|
mOptimizePreference.setOnClickListener(this);
|
|
mRestrictedPreference.setOnClickListener(this);
|
|
|
|
mBatteryOptimizeUtils = new BatteryOptimizeUtils(
|
|
getContext(), getArguments().getInt(EXTRA_UID), packageName);
|
|
}
|
|
|
|
private int getSelectedPreference() {
|
|
if (mRestrictedPreference.isChecked()) {
|
|
return BatteryOptimizeUtils.MODE_RESTRICTED;
|
|
} else if (mUnrestrictedPreference.isChecked()) {
|
|
return BatteryOptimizeUtils.MODE_UNRESTRICTED;
|
|
} else if (mOptimizePreference.isChecked()) {
|
|
return BatteryOptimizeUtils.MODE_OPTIMIZED;
|
|
} else {
|
|
return BatteryOptimizeUtils.MODE_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
private CharSequence getAppActiveTime(Bundle bundle) {
|
|
final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
|
|
final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
|
|
final int consumedPower = bundle.getInt(EXTRA_POWER_USAGE_AMOUNT);
|
|
final String slotTime = bundle.getString(EXTRA_SLOT_TIME, null);
|
|
final long totalTimeMs = foregroundTimeMs + backgroundTimeMs;
|
|
final CharSequence usageTimeSummary;
|
|
final PowerUsageFeatureProvider powerFeatureProvider =
|
|
FeatureFactory.getFactory(getContext()).getPowerUsageFeatureProvider(getContext());
|
|
|
|
if (totalTimeMs == 0) {
|
|
final int batteryWithoutUsageTime = consumedPower > 0
|
|
? R.string.battery_usage_without_time : R.string.battery_not_usage_24hr;
|
|
usageTimeSummary = getText(powerFeatureProvider.isChartGraphEnabled(getContext())
|
|
? batteryWithoutUsageTime : R.string.battery_not_usage);
|
|
} else if (slotTime == null) {
|
|
// Shows summary text with past 24 hr or full charge if slot time is null.
|
|
usageTimeSummary = powerFeatureProvider.isChartGraphEnabled(getContext())
|
|
? getAppPast24HrActiveSummary(foregroundTimeMs, backgroundTimeMs, totalTimeMs)
|
|
: getAppFullChargeActiveSummary(
|
|
foregroundTimeMs, backgroundTimeMs, totalTimeMs);
|
|
} else {
|
|
// Shows summary text with slot time.
|
|
usageTimeSummary = getAppActiveSummaryWithSlotTime(
|
|
foregroundTimeMs, backgroundTimeMs, totalTimeMs, slotTime);
|
|
}
|
|
return usageTimeSummary;
|
|
}
|
|
|
|
private CharSequence getAppFullChargeActiveSummary(
|
|
long foregroundTimeMs, long backgroundTimeMs, long totalTimeMs) {
|
|
// Shows background summary only if we don't have foreground usage time.
|
|
if (foregroundTimeMs == 0 && backgroundTimeMs != 0) {
|
|
return backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS ?
|
|
getText(R.string.battery_bg_usage_less_minute) :
|
|
TextUtils.expandTemplate(getText(R.string.battery_bg_usage),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
backgroundTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false));
|
|
// Shows total usage summary only if total usage time is small.
|
|
} else if (totalTimeMs < DateUtils.MINUTE_IN_MILLIS) {
|
|
return getText(R.string.battery_total_usage_less_minute);
|
|
// Shows different total usage summary when background usage time is small.
|
|
} else if (backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS) {
|
|
return TextUtils.expandTemplate(
|
|
getText(backgroundTimeMs == 0 ?
|
|
R.string.battery_total_usage :
|
|
R.string.battery_total_usage_and_bg_less_minute_usage),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
totalTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false));
|
|
// Shows default summary.
|
|
} else {
|
|
return TextUtils.expandTemplate(
|
|
getText(R.string.battery_total_and_bg_usage),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
totalTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
backgroundTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false));
|
|
}
|
|
}
|
|
|
|
private CharSequence getAppPast24HrActiveSummary(
|
|
long foregroundTimeMs, long backgroundTimeMs, long totalTimeMs) {
|
|
// Shows background summary only if we don't have foreground usage time.
|
|
if (foregroundTimeMs == 0 && backgroundTimeMs != 0) {
|
|
return backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS
|
|
? getText(R.string.battery_bg_usage_less_minute_24hr)
|
|
: TextUtils.expandTemplate(getText(R.string.battery_bg_usage_24hr),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
backgroundTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false));
|
|
// Shows total usage summary only if total usage time is small.
|
|
} else if (totalTimeMs < DateUtils.MINUTE_IN_MILLIS) {
|
|
return getText(R.string.battery_total_usage_less_minute_24hr);
|
|
// Shows different total usage summary when background usage time is small.
|
|
} else if (backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS) {
|
|
return TextUtils.expandTemplate(
|
|
getText(backgroundTimeMs == 0
|
|
? R.string.battery_total_usage_24hr
|
|
: R.string.battery_total_usage_and_bg_less_minute_usage_24hr),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
totalTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false));
|
|
// Shows default summary.
|
|
} else {
|
|
return TextUtils.expandTemplate(
|
|
getText(R.string.battery_total_and_bg_usage_24hr),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
totalTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
backgroundTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false));
|
|
}
|
|
}
|
|
|
|
private CharSequence getAppActiveSummaryWithSlotTime(
|
|
long foregroundTimeMs, long backgroundTimeMs, long totalTimeMs, String slotTime) {
|
|
// Shows background summary only if we don't have foreground usage time.
|
|
if (foregroundTimeMs == 0 && backgroundTimeMs != 0) {
|
|
return backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS ?
|
|
TextUtils.expandTemplate(
|
|
getText(R.string.battery_bg_usage_less_minute_with_period),
|
|
slotTime) :
|
|
TextUtils.expandTemplate(getText(R.string.battery_bg_usage_with_period),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
backgroundTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false), slotTime);
|
|
// Shows total usage summary only if total usage time is small.
|
|
} else if (totalTimeMs < DateUtils.MINUTE_IN_MILLIS) {
|
|
return TextUtils.expandTemplate(
|
|
getText(R.string.battery_total_usage_less_minute_with_period), slotTime);
|
|
// Shows different total usage summary when background usage time is small.
|
|
} else if (backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS) {
|
|
return TextUtils.expandTemplate(
|
|
getText(backgroundTimeMs == 0 ?
|
|
R.string.battery_total_usage_with_period :
|
|
R.string.battery_total_usage_and_bg_less_minute_usage_with_period),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
totalTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false), slotTime);
|
|
// Shows default summary.
|
|
} else {
|
|
return TextUtils.expandTemplate(
|
|
getText(R.string.battery_total_and_bg_usage_with_period),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
totalTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false),
|
|
StringUtil.formatElapsedTime(
|
|
getContext(),
|
|
backgroundTimeMs,
|
|
/* withSeconds */ false,
|
|
/* collapseTimeUnit */ false), slotTime);
|
|
}
|
|
}
|
|
}
|