Loading res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -5434,6 +5434,10 @@ <!-- Category title for battery background settings in power usage detail page [CHAR LIMIT=NONE] --> <string name="manager_battery_usage_category_title">Manage battery usage</string> <!-- Title for allow background usage [CHAR LIMIT=NONE] --> <string name="manager_battery_usage_allow_background_usage_title">Allow background usage</string> <!-- Summary for allow background usage [CHAR LIMIT=NONE] --> <string name="manager_battery_usage_allow_background_usage_summary">Enable for real-time updates, disable to save battery</string> <!-- Title for the battery unrestricted settings [CHAR_LIMIT=40] --> <string name="manager_battery_usage_unrestricted_title">Unrestricted</string> <!-- Title for the battery optimized settings [CHAR_LIMIT=40] --> Loading res/xml/power_background_usage_detail.xml 0 → 100644 +50 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2023 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. --> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/manager_battery_usage_allow_background_usage_title"> <com.android.settingslib.widget.LayoutPreference android:key="header_view" android:layout="@layout/settings_entity_header" android:selectable="false"/> <com.android.settingslib.widget.MainSwitchPreference android:key="allow_background_usage" android:title="@string/manager_battery_usage_allow_background_usage_title" settings:controller="com.android.settings.fuelgauge.AllowBackgroundPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="optimized_preference" android:title="@string/manager_battery_usage_optimized_title" android:summary="@string/manager_battery_usage_optimized_summary" settings:controller="com.android.settings.fuelgauge.OptimizedPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="unrestricted_preference" android:title="@string/manager_battery_usage_unrestricted_title" android:summary="@string/manager_battery_usage_unrestricted_summary" settings:controller="com.android.settings.fuelgauge.UnrestrictedPreferenceController"/> <com.android.settingslib.widget.FooterPreference android:key="app_usage_footer_preference" android:title="@string/manager_battery_usage_footer" android:selectable="false" settings:searchable="false"/> </PreferenceScreen> No newline at end of file res/xml/power_usage_detail.xml +4 −23 Original line number Diff line number Diff line Loading @@ -50,30 +50,11 @@ android:title="@string/manager_battery_usage_category_title" android:key="manage_battery_usage_category"> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="unrestricted_pref" android:summary="@string/manager_battery_usage_unrestricted_summary" android:title="@string/manager_battery_usage_unrestricted_title" settings:controller="com.android.settings.fuelgauge.UnrestrictedPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="optimized_pref" android:summary="@string/manager_battery_usage_optimized_summary" android:title="@string/manager_battery_usage_optimized_title" settings:controller="com.android.settings.fuelgauge.OptimizedPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="restricted_pref" android:summary="@string/manager_battery_usage_restricted_summary" android:title="@string/manager_battery_usage_restricted_title" settings:controller="com.android.settings.fuelgauge.RestrictedPreferenceController"/> <com.android.settingslib.PrimarySwitchPreference android:key="allow_background_usage" android:title="@string/manager_battery_usage_allow_background_usage_title" settings:controller="com.android.settings.fuelgauge.AllowBackgroundPreferenceController"/> </PreferenceCategory> <com.android.settingslib.widget.FooterPreference android:key="app_usage_footer_preference" android:title="@string/manager_battery_usage_footer" android:selectable="false" settings:searchable="false"/> </PreferenceScreen> No newline at end of file src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +70 −96 Original line number Diff line number Diff line Loading @@ -27,10 +27,13 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.SettingsActivity; Loading @@ -45,14 +48,12 @@ import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry; import com.android.settings.fuelgauge.batteryusage.BatteryEntry; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.HelpUtils; import com.android.settingslib.PrimarySwitchPreference; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.instrumentation.Instrumentable; 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; Loading @@ -67,8 +68,8 @@ import java.util.concurrent.Executors; */ public class AdvancedPowerUsageDetail extends DashboardFragment implements ButtonActionDialogFragment.AppButtonsDialogListener, SelectorWithWidgetPreference.OnClickListener { Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener { public static final String TAG = "AdvancedPowerDetail"; public static final String EXTRA_UID = "extra_uid"; public static final String EXTRA_PACKAGE_NAME = "extra_package_name"; Loading @@ -85,19 +86,16 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements public static final String EXTRA_POWER_USAGE_AMOUNT = "extra_power_usage_amount"; 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 String HEADER_SUMMARY_FORMAT = "%s\n(%s)"; private static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage"; private static final int REQUEST_UNINSTALL = 0; private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1; private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); private AppButtonsPreferenceController mAppButtonsPreferenceController; private PowerUsageTimeController mPowerUsageTimeController; @VisibleForTesting LayoutPreference mHeaderPreference; @VisibleForTesting Loading @@ -107,13 +105,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; @VisibleForTesting FooterPreference mFooterPreference; @VisibleForTesting SelectorWithWidgetPreference mRestrictedPreference; @VisibleForTesting SelectorWithWidgetPreference mOptimizePreference; @VisibleForTesting SelectorWithWidgetPreference mUnrestrictedPreference; PrimarySwitchPreference mAllowBackgroundUsagePreference; @VisibleForTesting @BatteryOptimizeUtils.OptimizationMode int mOptimizationMode = BatteryOptimizeUtils.MODE_UNKNOWN; Loading @@ -122,9 +114,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements @VisibleForTesting StringBuilder mLogStringBuilder; private AppButtonsPreferenceController mAppButtonsPreferenceController; private PowerUsageTimeController mPowerUsageTimeController; // A wrapper class to carry LaunchBatteryDetailPage required arguments. private static final class LaunchBatteryDetailPageArgs { private String mUsagePercent; Loading Loading @@ -257,7 +246,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements super.onCreate(icicle); final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME); onCreateForTriState(packageName); onCreateBackgroundUsageState(packageName); mHeaderPreference = findPreference(KEY_PREF_HEADER); if (packageName != null) { Loading @@ -271,10 +260,10 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements initHeader(); mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode(); initPreferenceForTriState(getContext()); initFooter(); mExecutor.execute(() -> { String packageName = getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); final String packageName = BatteryUtils .getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); FeatureFactory.getFeatureFactory().getMetricsFeatureProvider() .action( getContext(), Loading @@ -288,11 +277,10 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements public void onPause() { super.onPause(); final int selectedPreference = getSelectedPreference(); notifyBackupManager(); mLogStringBuilder.append(", onPause mode = ").append(selectedPreference); logMetricCategory(selectedPreference); final int currentOptimizeMode = mBatteryOptimizeUtils.getAppOptimizationMode(); mLogStringBuilder.append(", onPause mode = ").append(currentOptimizeMode); logMetricCategory(currentOptimizeMode); mExecutor.execute(() -> { BatteryOptimizeLogUtils.writeLog( Loading @@ -302,7 +290,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements mBatteryOptimizeUtils.getPackageName(), UserHandle.myUserId()), mLogStringBuilder.toString()); }); Log.d(TAG, "Leave with mode: " + selectedPreference); Log.d(TAG, "Leave with mode: " + currentOptimizeMode); } @VisibleForTesting Loading Loading @@ -353,33 +341,28 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements } @VisibleForTesting void initPreferenceForTriState(Context context) { void initFooter() { final String stateString; final String footerString; final String detailInfoString; final Context context = getContext(); if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) { // 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); detailInfoString = 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); detailInfoString = 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.setLearnMoreText( context.getString(R.string.manager_battery_usage_link_a11y)); detailInfoString = context.getString( R.string.manager_battery_usage_allow_background_usage_summary); } mAllowBackgroundUsagePreference.setSummary(detailInfoString); } @Override Loading Loading @@ -412,9 +395,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements controllers.add(mPowerUsageTimeController); } controllers.add(mAppButtonsPreferenceController); controllers.add(new UnrestrictedPreferenceController(context, uid, packageName)); controllers.add(new OptimizedPreferenceController(context, uid, packageName)); controllers.add(new RestrictedPreferenceController(context, uid, packageName)); controllers.add(new AllowBackgroundPreferenceController(context, uid, packageName)); return controllers; } Loading @@ -435,34 +416,45 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements } @Override public void onRadioButtonClicked(SelectorWithWidgetPreference selected) { final String selectedKey = selected.getKey(); updatePreferenceState(mUnrestrictedPreference, selectedKey); updatePreferenceState(mOptimizePreference, selectedKey); updatePreferenceState(mRestrictedPreference, selectedKey); mBatteryOptimizeUtils.setAppUsageState(getSelectedPreference(), Action.APPLY); public boolean onPreferenceClick(Preference preference) { if (!(preference instanceof PrimarySwitchPreference) || !TextUtils.equals(preference.getKey(), KEY_ALLOW_BACKGROUND_USAGE)) { return false; } PowerBackgroundUsageDetail.startPowerBackgroundUsageDetailPage( getContext(), getArguments()); return true; } private void updatePreferenceState(SelectorWithWidgetPreference preference, String selectedKey) { preference.setChecked(selectedKey.equals(preference.getKey())); @Override public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) { if (!(preference instanceof PrimarySwitchPreference) || !TextUtils.equals(preference.getKey(), KEY_ALLOW_BACKGROUND_USAGE)) { return false; } if (newValue instanceof Boolean) { final boolean isAllowBackgroundUsage = (boolean) newValue; mBatteryOptimizeUtils.setAppUsageState( isAllowBackgroundUsage ? BatteryOptimizeUtils.MODE_OPTIMIZED : BatteryOptimizeUtils.MODE_RESTRICTED, Action.APPLY); } return true; } private void logMetricCategory(int selectedKey) { if (selectedKey == mOptimizationMode) { private void logMetricCategory(int currentOptimizeMode) { if (currentOptimizeMode == mOptimizationMode) { return; } int metricCategory = 0; switch (selectedKey) { switch (currentOptimizeMode) { case BatteryOptimizeUtils.MODE_UNRESTRICTED: metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_UNRESTRICTED; break; case BatteryOptimizeUtils.MODE_OPTIMIZED: metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED; metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_ALLOW_BACKGROUND; break; case BatteryOptimizeUtils.MODE_RESTRICTED: metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_RESTRICTED; metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_DISABLE_BACKGROUND; break; } if (metricCategory == 0) { Loading @@ -470,8 +462,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements } int finalMetricCategory = metricCategory; mExecutor.execute(() -> { String packageName = getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); String packageName = BatteryUtils .getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); FeatureFactory.getFeatureFactory().getMetricsFeatureProvider() .action( /* attribution */ SettingsEnums.OPEN_APP_BATTERY_USAGE, Loading @@ -482,33 +474,15 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements }); } 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 void onCreateBackgroundUsageState(String packageName) { mAllowBackgroundUsagePreference = findPreference(KEY_ALLOW_BACKGROUND_USAGE); if (mAllowBackgroundUsagePreference != null) { mAllowBackgroundUsagePreference.setOnPreferenceClickListener(this); mAllowBackgroundUsagePreference.setOnPreferenceChangeListener(this); } private static String getLoggingPackageName(Context context, String originalPackingName) { return BatteryUtils.isAppInstalledFromGooglePlayStore(context, originalPackingName) ? originalPackingName : PACKAGE_NAME_NONE; mBatteryOptimizeUtils = new BatteryOptimizeUtils( getContext(), getArguments().getInt(EXTRA_UID), packageName); } } src/com/android/settings/fuelgauge/RestrictedPreferenceController.java→src/com/android/settings/fuelgauge/AllowBackgroundPreferenceController.java +22 −27 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * Copyright (C) 2023 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. Loading @@ -17,50 +17,45 @@ package com.android.settings.fuelgauge; import android.content.Context; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.PrimarySwitchPreference; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.widget.SelectorWithWidgetPreference; import com.android.settingslib.widget.MainSwitchPreference; public class RestrictedPreferenceController extends AbstractPreferenceController /** Controller to update the app background usage state */ public class AllowBackgroundPreferenceController extends AbstractPreferenceController implements PreferenceControllerMixin { private static final String TAG = "RESTRICTED_PREF"; private static final String TAG = "AllowBackgroundPreferenceController"; @VisibleForTesting static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage"; @VisibleForTesting String KEY_RESTRICTED_PREF = "restricted_pref"; @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; public RestrictedPreferenceController(Context context, int uid, String packageName) { public AllowBackgroundPreferenceController(Context context, int uid, String packageName) { super(context); mBatteryOptimizeUtils = new BatteryOptimizeUtils(context, uid, packageName); } private void setChecked(Preference preference, boolean checked) { if (preference instanceof PrimarySwitchPreference) { ((PrimarySwitchPreference) preference).setChecked(checked); } else if (preference instanceof MainSwitchPreference) { ((MainSwitchPreference) preference).setChecked(checked); } } @Override public void updateState(Preference preference) { preference.setEnabled(mBatteryOptimizeUtils.isOptimizeModeMutable()); if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) { Log.d(TAG, "disable preference for " + mBatteryOptimizeUtils.getPackageName()); preference.setEnabled(false); return; } else { preference.setEnabled(true); } if (mBatteryOptimizeUtils.getAppOptimizationMode() == BatteryOptimizeUtils.MODE_RESTRICTED) { Log.d(TAG, "is restricted states"); ((SelectorWithWidgetPreference) preference).setChecked(true); } else { ((SelectorWithWidgetPreference) preference).setChecked(false); if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) { Log.d(TAG, "is system or default app, disable pref"); preference.setEnabled(false); } } final boolean isAllowBackground = mBatteryOptimizeUtils.getAppOptimizationMode() != BatteryOptimizeUtils.MODE_RESTRICTED; setChecked(preference, isAllowBackground); } @Override Loading @@ -70,7 +65,7 @@ public class RestrictedPreferenceController extends AbstractPreferenceController @Override public String getPreferenceKey() { return KEY_RESTRICTED_PREF; return KEY_ALLOW_BACKGROUND_USAGE; } @Override Loading Loading
res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -5434,6 +5434,10 @@ <!-- Category title for battery background settings in power usage detail page [CHAR LIMIT=NONE] --> <string name="manager_battery_usage_category_title">Manage battery usage</string> <!-- Title for allow background usage [CHAR LIMIT=NONE] --> <string name="manager_battery_usage_allow_background_usage_title">Allow background usage</string> <!-- Summary for allow background usage [CHAR LIMIT=NONE] --> <string name="manager_battery_usage_allow_background_usage_summary">Enable for real-time updates, disable to save battery</string> <!-- Title for the battery unrestricted settings [CHAR_LIMIT=40] --> <string name="manager_battery_usage_unrestricted_title">Unrestricted</string> <!-- Title for the battery optimized settings [CHAR_LIMIT=40] --> Loading
res/xml/power_background_usage_detail.xml 0 → 100644 +50 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2023 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. --> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/manager_battery_usage_allow_background_usage_title"> <com.android.settingslib.widget.LayoutPreference android:key="header_view" android:layout="@layout/settings_entity_header" android:selectable="false"/> <com.android.settingslib.widget.MainSwitchPreference android:key="allow_background_usage" android:title="@string/manager_battery_usage_allow_background_usage_title" settings:controller="com.android.settings.fuelgauge.AllowBackgroundPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="optimized_preference" android:title="@string/manager_battery_usage_optimized_title" android:summary="@string/manager_battery_usage_optimized_summary" settings:controller="com.android.settings.fuelgauge.OptimizedPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="unrestricted_preference" android:title="@string/manager_battery_usage_unrestricted_title" android:summary="@string/manager_battery_usage_unrestricted_summary" settings:controller="com.android.settings.fuelgauge.UnrestrictedPreferenceController"/> <com.android.settingslib.widget.FooterPreference android:key="app_usage_footer_preference" android:title="@string/manager_battery_usage_footer" android:selectable="false" settings:searchable="false"/> </PreferenceScreen> No newline at end of file
res/xml/power_usage_detail.xml +4 −23 Original line number Diff line number Diff line Loading @@ -50,30 +50,11 @@ android:title="@string/manager_battery_usage_category_title" android:key="manage_battery_usage_category"> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="unrestricted_pref" android:summary="@string/manager_battery_usage_unrestricted_summary" android:title="@string/manager_battery_usage_unrestricted_title" settings:controller="com.android.settings.fuelgauge.UnrestrictedPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="optimized_pref" android:summary="@string/manager_battery_usage_optimized_summary" android:title="@string/manager_battery_usage_optimized_title" settings:controller="com.android.settings.fuelgauge.OptimizedPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="restricted_pref" android:summary="@string/manager_battery_usage_restricted_summary" android:title="@string/manager_battery_usage_restricted_title" settings:controller="com.android.settings.fuelgauge.RestrictedPreferenceController"/> <com.android.settingslib.PrimarySwitchPreference android:key="allow_background_usage" android:title="@string/manager_battery_usage_allow_background_usage_title" settings:controller="com.android.settings.fuelgauge.AllowBackgroundPreferenceController"/> </PreferenceCategory> <com.android.settingslib.widget.FooterPreference android:key="app_usage_footer_preference" android:title="@string/manager_battery_usage_footer" android:selectable="false" settings:searchable="false"/> </PreferenceScreen> No newline at end of file
src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +70 −96 Original line number Diff line number Diff line Loading @@ -27,10 +27,13 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.SettingsActivity; Loading @@ -45,14 +48,12 @@ import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry; import com.android.settings.fuelgauge.batteryusage.BatteryEntry; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.HelpUtils; import com.android.settingslib.PrimarySwitchPreference; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.instrumentation.Instrumentable; 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; Loading @@ -67,8 +68,8 @@ import java.util.concurrent.Executors; */ public class AdvancedPowerUsageDetail extends DashboardFragment implements ButtonActionDialogFragment.AppButtonsDialogListener, SelectorWithWidgetPreference.OnClickListener { Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener { public static final String TAG = "AdvancedPowerDetail"; public static final String EXTRA_UID = "extra_uid"; public static final String EXTRA_PACKAGE_NAME = "extra_package_name"; Loading @@ -85,19 +86,16 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements public static final String EXTRA_POWER_USAGE_AMOUNT = "extra_power_usage_amount"; 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 String HEADER_SUMMARY_FORMAT = "%s\n(%s)"; private static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage"; private static final int REQUEST_UNINSTALL = 0; private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1; private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); private AppButtonsPreferenceController mAppButtonsPreferenceController; private PowerUsageTimeController mPowerUsageTimeController; @VisibleForTesting LayoutPreference mHeaderPreference; @VisibleForTesting Loading @@ -107,13 +105,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; @VisibleForTesting FooterPreference mFooterPreference; @VisibleForTesting SelectorWithWidgetPreference mRestrictedPreference; @VisibleForTesting SelectorWithWidgetPreference mOptimizePreference; @VisibleForTesting SelectorWithWidgetPreference mUnrestrictedPreference; PrimarySwitchPreference mAllowBackgroundUsagePreference; @VisibleForTesting @BatteryOptimizeUtils.OptimizationMode int mOptimizationMode = BatteryOptimizeUtils.MODE_UNKNOWN; Loading @@ -122,9 +114,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements @VisibleForTesting StringBuilder mLogStringBuilder; private AppButtonsPreferenceController mAppButtonsPreferenceController; private PowerUsageTimeController mPowerUsageTimeController; // A wrapper class to carry LaunchBatteryDetailPage required arguments. private static final class LaunchBatteryDetailPageArgs { private String mUsagePercent; Loading Loading @@ -257,7 +246,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements super.onCreate(icicle); final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME); onCreateForTriState(packageName); onCreateBackgroundUsageState(packageName); mHeaderPreference = findPreference(KEY_PREF_HEADER); if (packageName != null) { Loading @@ -271,10 +260,10 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements initHeader(); mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode(); initPreferenceForTriState(getContext()); initFooter(); mExecutor.execute(() -> { String packageName = getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); final String packageName = BatteryUtils .getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); FeatureFactory.getFeatureFactory().getMetricsFeatureProvider() .action( getContext(), Loading @@ -288,11 +277,10 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements public void onPause() { super.onPause(); final int selectedPreference = getSelectedPreference(); notifyBackupManager(); mLogStringBuilder.append(", onPause mode = ").append(selectedPreference); logMetricCategory(selectedPreference); final int currentOptimizeMode = mBatteryOptimizeUtils.getAppOptimizationMode(); mLogStringBuilder.append(", onPause mode = ").append(currentOptimizeMode); logMetricCategory(currentOptimizeMode); mExecutor.execute(() -> { BatteryOptimizeLogUtils.writeLog( Loading @@ -302,7 +290,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements mBatteryOptimizeUtils.getPackageName(), UserHandle.myUserId()), mLogStringBuilder.toString()); }); Log.d(TAG, "Leave with mode: " + selectedPreference); Log.d(TAG, "Leave with mode: " + currentOptimizeMode); } @VisibleForTesting Loading Loading @@ -353,33 +341,28 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements } @VisibleForTesting void initPreferenceForTriState(Context context) { void initFooter() { final String stateString; final String footerString; final String detailInfoString; final Context context = getContext(); if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) { // 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); detailInfoString = 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); detailInfoString = 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.setLearnMoreText( context.getString(R.string.manager_battery_usage_link_a11y)); detailInfoString = context.getString( R.string.manager_battery_usage_allow_background_usage_summary); } mAllowBackgroundUsagePreference.setSummary(detailInfoString); } @Override Loading Loading @@ -412,9 +395,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements controllers.add(mPowerUsageTimeController); } controllers.add(mAppButtonsPreferenceController); controllers.add(new UnrestrictedPreferenceController(context, uid, packageName)); controllers.add(new OptimizedPreferenceController(context, uid, packageName)); controllers.add(new RestrictedPreferenceController(context, uid, packageName)); controllers.add(new AllowBackgroundPreferenceController(context, uid, packageName)); return controllers; } Loading @@ -435,34 +416,45 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements } @Override public void onRadioButtonClicked(SelectorWithWidgetPreference selected) { final String selectedKey = selected.getKey(); updatePreferenceState(mUnrestrictedPreference, selectedKey); updatePreferenceState(mOptimizePreference, selectedKey); updatePreferenceState(mRestrictedPreference, selectedKey); mBatteryOptimizeUtils.setAppUsageState(getSelectedPreference(), Action.APPLY); public boolean onPreferenceClick(Preference preference) { if (!(preference instanceof PrimarySwitchPreference) || !TextUtils.equals(preference.getKey(), KEY_ALLOW_BACKGROUND_USAGE)) { return false; } PowerBackgroundUsageDetail.startPowerBackgroundUsageDetailPage( getContext(), getArguments()); return true; } private void updatePreferenceState(SelectorWithWidgetPreference preference, String selectedKey) { preference.setChecked(selectedKey.equals(preference.getKey())); @Override public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) { if (!(preference instanceof PrimarySwitchPreference) || !TextUtils.equals(preference.getKey(), KEY_ALLOW_BACKGROUND_USAGE)) { return false; } if (newValue instanceof Boolean) { final boolean isAllowBackgroundUsage = (boolean) newValue; mBatteryOptimizeUtils.setAppUsageState( isAllowBackgroundUsage ? BatteryOptimizeUtils.MODE_OPTIMIZED : BatteryOptimizeUtils.MODE_RESTRICTED, Action.APPLY); } return true; } private void logMetricCategory(int selectedKey) { if (selectedKey == mOptimizationMode) { private void logMetricCategory(int currentOptimizeMode) { if (currentOptimizeMode == mOptimizationMode) { return; } int metricCategory = 0; switch (selectedKey) { switch (currentOptimizeMode) { case BatteryOptimizeUtils.MODE_UNRESTRICTED: metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_UNRESTRICTED; break; case BatteryOptimizeUtils.MODE_OPTIMIZED: metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED; metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_ALLOW_BACKGROUND; break; case BatteryOptimizeUtils.MODE_RESTRICTED: metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_RESTRICTED; metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_DISABLE_BACKGROUND; break; } if (metricCategory == 0) { Loading @@ -470,8 +462,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements } int finalMetricCategory = metricCategory; mExecutor.execute(() -> { String packageName = getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); String packageName = BatteryUtils .getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName()); FeatureFactory.getFeatureFactory().getMetricsFeatureProvider() .action( /* attribution */ SettingsEnums.OPEN_APP_BATTERY_USAGE, Loading @@ -482,33 +474,15 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements }); } 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 void onCreateBackgroundUsageState(String packageName) { mAllowBackgroundUsagePreference = findPreference(KEY_ALLOW_BACKGROUND_USAGE); if (mAllowBackgroundUsagePreference != null) { mAllowBackgroundUsagePreference.setOnPreferenceClickListener(this); mAllowBackgroundUsagePreference.setOnPreferenceChangeListener(this); } private static String getLoggingPackageName(Context context, String originalPackingName) { return BatteryUtils.isAppInstalledFromGooglePlayStore(context, originalPackingName) ? originalPackingName : PACKAGE_NAME_NONE; mBatteryOptimizeUtils = new BatteryOptimizeUtils( getContext(), getArguments().getInt(EXTRA_UID), packageName); } }
src/com/android/settings/fuelgauge/RestrictedPreferenceController.java→src/com/android/settings/fuelgauge/AllowBackgroundPreferenceController.java +22 −27 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * Copyright (C) 2023 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. Loading @@ -17,50 +17,45 @@ package com.android.settings.fuelgauge; import android.content.Context; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.PrimarySwitchPreference; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.widget.SelectorWithWidgetPreference; import com.android.settingslib.widget.MainSwitchPreference; public class RestrictedPreferenceController extends AbstractPreferenceController /** Controller to update the app background usage state */ public class AllowBackgroundPreferenceController extends AbstractPreferenceController implements PreferenceControllerMixin { private static final String TAG = "RESTRICTED_PREF"; private static final String TAG = "AllowBackgroundPreferenceController"; @VisibleForTesting static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage"; @VisibleForTesting String KEY_RESTRICTED_PREF = "restricted_pref"; @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; public RestrictedPreferenceController(Context context, int uid, String packageName) { public AllowBackgroundPreferenceController(Context context, int uid, String packageName) { super(context); mBatteryOptimizeUtils = new BatteryOptimizeUtils(context, uid, packageName); } private void setChecked(Preference preference, boolean checked) { if (preference instanceof PrimarySwitchPreference) { ((PrimarySwitchPreference) preference).setChecked(checked); } else if (preference instanceof MainSwitchPreference) { ((MainSwitchPreference) preference).setChecked(checked); } } @Override public void updateState(Preference preference) { preference.setEnabled(mBatteryOptimizeUtils.isOptimizeModeMutable()); if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) { Log.d(TAG, "disable preference for " + mBatteryOptimizeUtils.getPackageName()); preference.setEnabled(false); return; } else { preference.setEnabled(true); } if (mBatteryOptimizeUtils.getAppOptimizationMode() == BatteryOptimizeUtils.MODE_RESTRICTED) { Log.d(TAG, "is restricted states"); ((SelectorWithWidgetPreference) preference).setChecked(true); } else { ((SelectorWithWidgetPreference) preference).setChecked(false); if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) { Log.d(TAG, "is system or default app, disable pref"); preference.setEnabled(false); } } final boolean isAllowBackground = mBatteryOptimizeUtils.getAppOptimizationMode() != BatteryOptimizeUtils.MODE_RESTRICTED; setChecked(preference, isAllowBackground); } @Override Loading @@ -70,7 +65,7 @@ public class RestrictedPreferenceController extends AbstractPreferenceController @Override public String getPreferenceKey() { return KEY_RESTRICTED_PREF; return KEY_ALLOW_BACKGROUND_USAGE; } @Override Loading