From 6147e0fa5c55a295e0967ee8087aa4725f2f81f8 Mon Sep 17 00:00:00 2001 From: Tiffany Nguyen Date: Wed, 20 Jul 2022 18:21:46 +0000 Subject: [PATCH 1/4] Add Apps > Battery optimization page implementation. Moving the old restricted page to the new optimization page will happen in a follow-up CL. Test: Unit, manual Bug: 238026672 Change-Id: I5fee9ebe03284a013da6bfca9ada8b166c6af91c (cherry picked from commit 5ecb1a1d69b32b6e92ce9a17c4f77bca220292a6) Merged-In: I5fee9ebe03284a013da6bfca9ada8b166c6af91c --- res/values/strings.xml | 15 ++ src/com/android/settings/Settings.java | 2 + .../AppStateBatteryOptimizationBridge.java | 180 ++++++++++++++++++ .../manageapplications/AppFilterRegistry.java | 80 +++++--- .../ManageApplications.java | 53 +++++- .../fuelgauge/AdvancedPowerUsageDetail.java | 12 +- .../AppFilterRegistryTest.java | 4 + 7 files changed, 315 insertions(+), 31 deletions(-) create mode 100644 src/com/android/settings/applications/AppStateBatteryOptimizationBridge.java diff --git a/res/values/strings.xml b/res/values/strings.xml index a1a27042221..651ead1b161 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11794,6 +11794,21 @@ Not using battery optimization + + Manage battery usage + + + Set battery usage for apps + + + Unrestricted + + + Optimized + + + Restricted + If device is locked, prevent typing replies or other text in notifications diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index c3ab8e25b35..f7ba01700fc 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -326,6 +326,8 @@ public class Settings extends SettingsActivity { public static class ChangeWifiStateActivity extends SettingsActivity { /* empty */ } public static class AppDrawOverlaySettingsActivity extends SettingsActivity { /* empty */ } public static class AppWriteSettingsActivity extends SettingsActivity { /* empty */ } + /** Activity to manage app battery optimization details. */ + public static class AppBatteryOptimizationActivity extends SettingsActivity { /* empty */ } public static class ManageExternalSourcesActivity extends SettingsActivity {/* empty */ } public static class ManageAppExternalSourcesActivity extends SettingsActivity { /* empty */ } diff --git a/src/com/android/settings/applications/AppStateBatteryOptimizationBridge.java b/src/com/android/settings/applications/AppStateBatteryOptimizationBridge.java new file mode 100644 index 00000000000..6301c857692 --- /dev/null +++ b/src/com/android/settings/applications/AppStateBatteryOptimizationBridge.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2022 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.applications; + +import android.annotation.IntDef; +import android.app.AppOpsManager; +import android.content.Context; +import android.os.Build; +import android.util.Log; + +import com.android.settingslib.applications.ApplicationsState; +import com.android.settingslib.applications.ApplicationsState.AppEntry; +import com.android.settingslib.applications.ApplicationsState.AppFilter; +import com.android.settingslib.fuelgauge.PowerAllowlistBackend; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Class for bridging the Battery optimization information to ApplicationState. + */ +public class AppStateBatteryOptimizationBridge extends AppStateBaseBridge { + private static final String TAG = AppStateBatteryOptimizationBridge.class.getSimpleName(); + static final boolean DEBUG = Build.IS_DEBUGGABLE; + + private final Context mContext; + private final AppOpsManager mAppOpsManager; + private final PowerAllowlistBackend mPowerAllowlistBackend; + + private static final int MODE_UNKNOWN = 0; + private static final int MODE_UNRESTRICTED = 1; + private static final int MODE_OPTIMIZED = 2; + private static final int MODE_RESTRICTED = 3; + + @IntDef( + prefix = {"MODE_"}, + value = { + MODE_UNKNOWN, + MODE_RESTRICTED, + MODE_UNRESTRICTED, + MODE_OPTIMIZED, + }) + @Retention(RetentionPolicy.SOURCE) + @interface OptimizationMode { + } + + public AppStateBatteryOptimizationBridge( + Context context, ApplicationsState appState, Callback callback) { + super(appState, callback); + mContext = context; + mAppOpsManager = context.getSystemService(AppOpsManager.class); + mPowerAllowlistBackend = PowerAllowlistBackend.getInstance(mContext); + } + + @Override + protected void updateExtraInfo(AppEntry app, String pkg, int uid) { + app.extraInfo = getAppBatteryOptimizationState(pkg, uid); + } + + @Override + protected void loadAllExtraInfo() { + if (DEBUG) { + Log.d(TAG, "Start loadAllExtraInfo()"); + } + mAppSession.getAllApps().stream().forEach(appEntry -> + updateExtraInfo(appEntry, appEntry.info.packageName, appEntry.info.uid)); + if (DEBUG) { + Log.d(TAG, "End loadAllExtraInfo()"); + } + } + + protected Object getAppBatteryOptimizationState(String pkg, int uid) { + // Restricted = AppOpsManager.MODE_IGNORED + !allowListed + // Unrestricted = AppOpsManager.MODE_ALLOWED + allowListed + // Optimized = AppOpsManager.MODE_ALLOWED + !allowListed + + boolean allowListed = mPowerAllowlistBackend.isAllowlisted(pkg); + int aomMode = + mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, pkg); + @OptimizationMode int mode = MODE_UNKNOWN; + String modeName = ""; + if (aomMode == AppOpsManager.MODE_IGNORED && !allowListed) { + mode = MODE_RESTRICTED; + if (DEBUG) { + modeName = "RESTRICTED"; + } + } else if (aomMode == AppOpsManager.MODE_ALLOWED) { + mode = allowListed ? MODE_UNRESTRICTED : MODE_OPTIMIZED; + if (DEBUG) { + modeName = allowListed ? "UNRESTRICTED" : "OPTIMIZED"; + } + } + if (DEBUG) { + Log.d(TAG, "Pkg: " + pkg + ", mode: " + modeName); + } + return new BatteryOptimizationDetails(mode); + } + + @OptimizationMode + private static int getBatteryOptimizationDetailsMode(AppEntry entry) { + if (entry == null || entry.extraInfo == null) { + return MODE_UNKNOWN; + } + + return entry.extraInfo instanceof BatteryOptimizationDetails + ? ((BatteryOptimizationDetails) entry.extraInfo).mMode + : MODE_UNKNOWN; + } + + /** + * Used by {@link com.android.settings.applications.manageapplications.AppFilterRegistry} to + * determine which apps are unrestricted. + */ + public static final AppFilter FILTER_BATTERY_UNRESTRICTED_APPS = + new AppFilter() { + @Override + public void init() {} + + @Override + public boolean filterApp(AppEntry info) { + return getBatteryOptimizationDetailsMode(info) == MODE_UNRESTRICTED; + } + }; + + /** + * Used by {@link com.android.settings.applications.manageapplications.AppFilterRegistry} to + * determine which apps are optimized. + */ + public static final AppFilter FILTER_BATTERY_OPTIMIZED_APPS = + new AppFilter() { + @Override + public void init() {} + + @Override + public boolean filterApp(AppEntry info) { + return getBatteryOptimizationDetailsMode(info) == MODE_OPTIMIZED; + } + }; + + /** + * Used by {@link com.android.settings.applications.manageapplications.AppFilterRegistry} to + * determine which apps are restricted. + */ + public static final AppFilter FILTER_BATTERY_RESTRICTED_APPS = + new AppFilter() { + @Override + public void init() {} + + @Override + public boolean filterApp(AppEntry info) { + return getBatteryOptimizationDetailsMode(info) == MODE_RESTRICTED; + } + }; + + /** + * Extra details for battery optimization app data. + */ + static final class BatteryOptimizationDetails { + @OptimizationMode + int mMode; + + BatteryOptimizationDetails(@OptimizationMode int mode) { + mMode = mode; + } + } +} diff --git a/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java b/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java index 3c00b73570c..35de16ea070 100644 --- a/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java +++ b/src/com/android/settings/applications/manageapplications/AppFilterRegistry.java @@ -20,6 +20,7 @@ import androidx.annotation.IntDef; import com.android.settings.R; import com.android.settings.applications.AppStateAlarmsAndRemindersBridge; +import com.android.settings.applications.AppStateBatteryOptimizationBridge; import com.android.settings.applications.AppStateInstallAppsBridge; import com.android.settings.applications.AppStateLocaleBridge; import com.android.settings.applications.AppStateManageExternalStorageBridge; @@ -37,28 +38,31 @@ import com.android.settingslib.applications.ApplicationsState; */ public class AppFilterRegistry { - @IntDef(value = { - FILTER_APPS_POWER_ALLOWLIST, - FILTER_APPS_POWER_ALLOWLIST_ALL, - FILTER_APPS_ALL, - FILTER_APPS_ENABLED, - FILTER_APPS_INSTANT, - FILTER_APPS_DISABLED, - FILTER_APPS_RECENT, - FILTER_APPS_FREQUENT, - FILTER_APPS_PERSONAL, - FILTER_APPS_WORK, - FILTER_APPS_USAGE_ACCESS, - FILTER_APPS_WITH_OVERLAY, - FILTER_APPS_WRITE_SETTINGS, - FILTER_APPS_INSTALL_SOURCES, - FILTER_APPS_BLOCKED, - FILTER_ALARMS_AND_REMINDERS, - FILTER_APPS_MEDIA_MANAGEMENT, - FILTER_APPS_LOCALE, - }) - @interface FilterType { - } + @IntDef( + value = { + FILTER_APPS_POWER_ALLOWLIST, + FILTER_APPS_POWER_ALLOWLIST_ALL, + FILTER_APPS_ALL, + FILTER_APPS_ENABLED, + FILTER_APPS_INSTANT, + FILTER_APPS_DISABLED, + FILTER_APPS_RECENT, + FILTER_APPS_FREQUENT, + FILTER_APPS_PERSONAL, + FILTER_APPS_WORK, + FILTER_APPS_USAGE_ACCESS, + FILTER_APPS_WITH_OVERLAY, + FILTER_APPS_WRITE_SETTINGS, + FILTER_APPS_INSTALL_SOURCES, + FILTER_APPS_BLOCKED, + FILTER_ALARMS_AND_REMINDERS, + FILTER_APPS_MEDIA_MANAGEMENT, + FILTER_APPS_LOCALE, + FILTER_APPS_BATTERY_UNRESTRICTED, + FILTER_APPS_BATTERY_OPTIMIZED, + FILTER_APPS_BATTERY_RESTRICTED, + }) + @interface FilterType {} // Filter options used for displayed list of applications // Filters will appear sorted based on their value defined here. @@ -82,14 +86,18 @@ public class AppFilterRegistry { public static final int FILTER_ALARMS_AND_REMINDERS = 18; public static final int FILTER_APPS_MEDIA_MANAGEMENT = 19; public static final int FILTER_APPS_LOCALE = 20; - // Next id: 21. If you add an entry here, length of mFilters should be updated + public static final int FILTER_APPS_BATTERY_UNRESTRICTED = 21; + public static final int FILTER_APPS_BATTERY_OPTIMIZED = 22; + public static final int FILTER_APPS_BATTERY_RESTRICTED = 23; + // Next id: 24. If you add an entry here, please change NUM_FILTER_ENTRIES. + private static final int NUM_FILTER_ENTRIES = 24; private static AppFilterRegistry sRegistry; private final AppFilterItem[] mFilters; private AppFilterRegistry() { - mFilters = new AppFilterItem[21]; + mFilters = new AppFilterItem[NUM_FILTER_ENTRIES]; // High power allowlist, on mFilters[FILTER_APPS_POWER_ALLOWLIST] = new AppFilterItem( @@ -212,6 +220,28 @@ public class AppFilterRegistry { AppStateLocaleBridge.FILTER_APPS_LOCALE, FILTER_APPS_LOCALE, R.string.app_locale_picker_title); + + // Battery optimization app states: + // Unrestricted + mFilters[FILTER_APPS_BATTERY_UNRESTRICTED] = + new AppFilterItem( + AppStateBatteryOptimizationBridge.FILTER_BATTERY_UNRESTRICTED_APPS, + FILTER_APPS_BATTERY_UNRESTRICTED, + R.string.filter_battery_unrestricted_title); + + // Optimized + mFilters[FILTER_APPS_BATTERY_OPTIMIZED] = + new AppFilterItem( + AppStateBatteryOptimizationBridge.FILTER_BATTERY_OPTIMIZED_APPS, + FILTER_APPS_BATTERY_OPTIMIZED, + R.string.filter_battery_optimized_title); + + // Unrestricted + mFilters[FILTER_APPS_BATTERY_RESTRICTED] = + new AppFilterItem( + AppStateBatteryOptimizationBridge.FILTER_BATTERY_RESTRICTED_APPS, + FILTER_APPS_BATTERY_RESTRICTED, + R.string.filter_battery_restricted_title); } @@ -248,6 +278,8 @@ public class AppFilterRegistry { return FILTER_APPS_MEDIA_MANAGEMENT; case ManageApplications.LIST_TYPE_APPS_LOCALE: return FILTER_APPS_LOCALE; + case ManageApplications.LIST_TYPE_BATTERY_OPTIMIZATION: + return FILTER_APPS_BATTERY_OPTIMIZED; default: return FILTER_APPS_ALL; } diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index 30d4a717087..92561409d67 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -20,6 +20,9 @@ import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE; import static com.android.settings.ChangeIds.CHANGE_RESTRICT_SAW_INTENT; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL; +import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_BATTERY_OPTIMIZED; +import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_BATTERY_RESTRICTED; +import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_BATTERY_UNRESTRICTED; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_BLOCKED; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_DISABLED; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ENABLED; @@ -94,6 +97,7 @@ import com.android.settings.applications.AppInfoBase; import com.android.settings.applications.AppStateAlarmsAndRemindersBridge; import com.android.settings.applications.AppStateAppOpsBridge.PermissionState; import com.android.settings.applications.AppStateBaseBridge; +import com.android.settings.applications.AppStateBatteryOptimizationBridge; import com.android.settings.applications.AppStateInstallAppsBridge; import com.android.settings.applications.AppStateLocaleBridge; import com.android.settings.applications.AppStateManageExternalStorageBridge; @@ -118,6 +122,7 @@ import com.android.settings.applications.appinfo.WriteSettingsDetails; import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.SubSettingLauncher; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; +import com.android.settings.fuelgauge.AdvancedPowerUsageDetail; import com.android.settings.fuelgauge.HighPowerDetail; import com.android.settings.localepicker.AppLocalePickerActivity; import com.android.settings.notification.ConfigureNotificationSettings; @@ -229,6 +234,7 @@ public class ManageApplications extends InstrumentedFragment public static final int LIST_TYPE_ALARMS_AND_REMINDERS = 12; public static final int LIST_TYPE_MEDIA_MANAGEMENT_APPS = 13; public static final int LIST_TYPE_APPS_LOCALE = 14; + public static final int LIST_TYPE_BATTERY_OPTIMIZATION = 15; // List types that should show instant apps. public static final Set LIST_TYPES_WITH_INSTANT = new ArraySet<>(Arrays.asList( @@ -327,6 +333,8 @@ public class ManageApplications extends InstrumentedFragment } } else if (className.equals(AppLocaleDetails.class.getName())) { mListType = LIST_TYPE_APPS_LOCALE; + } else if (className.equals(Settings.AppBatteryOptimizationActivity.class.getName())) { + mListType = LIST_TYPE_BATTERY_OPTIMIZATION; } else { mListType = LIST_TYPE_MAIN; } @@ -460,6 +468,12 @@ public class ManageApplications extends InstrumentedFragment if (mListType == LIST_TYPE_HIGH_POWER) { mFilterAdapter.enableFilter(FILTER_APPS_POWER_ALLOWLIST_ALL); } + if (mListType == LIST_TYPE_BATTERY_OPTIMIZATION) { + mFilterAdapter.enableFilter(FILTER_APPS_ALL); + mFilterAdapter.enableFilter(FILTER_APPS_BATTERY_UNRESTRICTED); + mFilterAdapter.enableFilter(FILTER_APPS_BATTERY_OPTIMIZED); + mFilterAdapter.enableFilter(FILTER_APPS_BATTERY_RESTRICTED); + } setCompositeFilter(); } @@ -511,6 +525,8 @@ public class ManageApplications extends InstrumentedFragment return SettingsEnums.MEDIA_MANAGEMENT_APPS; case LIST_TYPE_APPS_LOCALE: return SettingsEnums.APPS_LOCALE_LIST; + case LIST_TYPE_BATTERY_OPTIMIZATION: + return SettingsEnums.BATTERY_OPTIMIZED_APPS_LIST; default: return SettingsEnums.PAGE_UNKNOWN; } @@ -641,6 +657,10 @@ public class ManageApplications extends InstrumentedFragment intent.putExtra(AppInfoBase.ARG_PACKAGE_UID, mCurrentUid); startActivity(intent); break; + case LIST_TYPE_BATTERY_OPTIMIZATION: + AdvancedPowerUsageDetail.startBatteryDetailPage( + getActivity(), this, mCurrentPkgName); + break; // TODO: Figure out if there is a way where we can spin up the profile's settings // process ahead of time, to avoid a long load of data when user clicks on a managed // app. Maybe when they load the list of apps that contains managed profile apps. @@ -934,6 +954,8 @@ public class ManageApplications extends InstrumentedFragment screenTitle = R.string.app_notifications_title; } else if (className.equals(AppLocaleDetails.class.getName())) { screenTitle = R.string.app_locales_picker_menu_title; + } else if (className.equals(Settings.AppBatteryOptimizationActivity.class.getName())) { + screenTitle = R.string.app_battery_optimization_title; } else { if (screenTitle == -1) { screenTitle = R.string.all_apps; @@ -1126,6 +1148,8 @@ public class ManageApplications extends InstrumentedFragment mExtraInfoBridge = new AppStateMediaManagementAppsBridge(mContext, mState, this); } else if (mManageApplications.mListType == LIST_TYPE_APPS_LOCALE) { mExtraInfoBridge = new AppStateLocaleBridge(mContext, mState, this); + } else if (mManageApplications.mListType == LIST_TYPE_BATTERY_OPTIMIZATION) { + mExtraInfoBridge = new AppStateBatteryOptimizationBridge(mContext, mState, this); } else { mExtraInfoBridge = null; } @@ -1157,18 +1181,21 @@ public class ManageApplications extends InstrumentedFragment public void setFilter(AppFilterItem appFilter) { mAppFilter = appFilter; + final int filterType = appFilter.getFilterType(); // Notification filters require resorting the list if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) { - if (FILTER_APPS_FREQUENT == appFilter.getFilterType()) { + if (FILTER_APPS_FREQUENT == filterType) { rebuild(R.id.sort_order_frequent_notification, false); - } else if (FILTER_APPS_RECENT == appFilter.getFilterType()) { + } else if (FILTER_APPS_RECENT == filterType) { rebuild(R.id.sort_order_recent_notification, false); - } else if (FILTER_APPS_BLOCKED == appFilter.getFilterType()) { + } else if (FILTER_APPS_BLOCKED == filterType) { rebuild(R.id.sort_order_alpha, true); } else { rebuild(R.id.sort_order_alpha, true); } + } else if (mManageApplications.mListType == LIST_TYPE_BATTERY_OPTIMIZATION) { + logBatteryOptimization(filterType); } else { rebuild(); } @@ -1305,6 +1332,26 @@ public class ManageApplications extends InstrumentedFragment }); } + private void logBatteryOptimization(int filterType) { + switch(filterType) { + case FILTER_APPS_BATTERY_UNRESTRICTED: + logAction(SettingsEnums.ACTION_BATTERY_OPTIMIZED_APPS_FILTER_UNRESTRICTED); + break; + case FILTER_APPS_BATTERY_OPTIMIZED: + logAction(SettingsEnums.ACTION_BATTERY_OPTIMIZED_APPS_FILTER_OPTIMIZED); + break; + case FILTER_APPS_BATTERY_RESTRICTED: + logAction(SettingsEnums.ACTION_BATTERY_OPTIMIZED_APPS_FILTER_RESTRICTED); + break; + default: + logAction(SettingsEnums.ACTION_BATTERY_OPTIMIZED_APPS_FILTER_ALL_APPS); + } + } + + private void logAction(int action) { + mManageApplications.mMetricsFeatureProvider.action(mContext, action); + } + @VisibleForTesting void filterSearch(String query) { if (mSearchFilter == null) { diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index db98a4c6376..f6ed2a1a320 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -44,15 +44,16 @@ 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.fuelgauge.batteryusage.BatteryDiffEntry; import com.android.settings.fuelgauge.batteryusage.BatteryEntry; import com.android.settings.fuelgauge.batteryusage.BatteryHistEntry; +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.core.instrumentation.Instrumentable; import com.android.settingslib.utils.StringUtil; import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.LayoutPreference; @@ -222,8 +223,11 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements return UserHandle.getUserId(batteryEntry.getUid()); } - public static void startBatteryDetailPage(Activity caller, - InstrumentedPreferenceFragment fragment, String packageName) { + /** + * Start packageName's battery detail page. + */ + public static void startBatteryDetailPage( + Activity caller, Instrumentable instrumentable, String packageName) { final Bundle args = new Bundle(3); final PackageManager packageManager = caller.getPackageManager(); args.putString(EXTRA_PACKAGE_NAME, packageName); @@ -238,7 +242,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements .setDestination(AdvancedPowerUsageDetail.class.getName()) .setTitleRes(R.string.battery_details_title) .setArguments(args) - .setSourceMetricsCategory(fragment.getMetricsCategory()) + .setSourceMetricsCategory(instrumentable.getMetricsCategory()) .launch(); } diff --git a/tests/unit/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java b/tests/unit/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java index 4c271c64e52..13bc3dba014 100644 --- a/tests/unit/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java +++ b/tests/unit/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java @@ -18,6 +18,7 @@ package com.android.settings.applications.manageapplications; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_ALARMS_AND_REMINDERS; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL; +import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_BATTERY_OPTIMIZED; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_INSTALL_SOURCES; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_MEDIA_MANAGEMENT; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_POWER_ALLOWLIST; @@ -26,6 +27,7 @@ import static com.android.settings.applications.manageapplications.AppFilterRegi import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_WITH_OVERLAY; import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_WRITE_SETTINGS; import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_ALARMS_AND_REMINDERS; +import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_BATTERY_OPTIMIZATION; import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_GAMES; import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_HIGH_POWER; import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN; @@ -66,6 +68,8 @@ public class AppFilterRegistryTest { assertThat(registry.getDefaultFilterType(LIST_TYPE_MEDIA_MANAGEMENT_APPS)) .isEqualTo(FILTER_APPS_MEDIA_MANAGEMENT); + assertThat(registry.getDefaultFilterType(LIST_TYPE_BATTERY_OPTIMIZATION)) + .isEqualTo(FILTER_APPS_BATTERY_OPTIMIZED); assertThat(registry.getDefaultFilterType(LIST_TYPE_MAIN)).isEqualTo(FILTER_APPS_ALL); assertThat(registry.getDefaultFilterType(LIST_TYPE_NOTIFICATION)) From 032649b4f866b2d938b2f084670efe3e31aa56f7 Mon Sep 17 00:00:00 2001 From: Tiffany Nguyen Date: Tue, 2 Aug 2022 17:26:10 +0000 Subject: [PATCH 2/4] Move restricted apps page to new battery optimization page. New entry: https://screenshot.googleplex.com/BbU6RnQhBbpnBc3.png Restricted: https://screenshot.googleplex.com/5ggid7TcSsH9CUF.png Old entry: https://screenshot.googleplex.com/7JgZpSfKs5zZb3Z.png Bug: 240711616 Test: manual Change-Id: I03d17beac0fb85a3d17acd7d0d581feb35e9582b (cherry picked from commit 3acd34fe4a19737f35f35efe1bee6d8055d09c64) Merged-In: I03d17beac0fb85a3d17acd7d0d581feb35e9582b --- res/values/config.xml | 3 ++ res/xml/apps.xml | 12 +++++ src/com/android/settings/Settings.java | 4 +- .../AppBatteryUsagePreferenceController.java | 46 +++++++++++++++++++ ...ava => AppStateAppBatteryUsageBridge.java} | 32 ++++++------- .../manageapplications/AppFilterRegistry.java | 8 ++-- .../ManageApplications.java | 12 ++--- .../RestrictAppPreferenceController.java | 6 ++- .../BatteryManagerPreferenceController.java | 10 +++- 9 files changed, 102 insertions(+), 31 deletions(-) create mode 100644 src/com/android/settings/applications/AppBatteryUsagePreferenceController.java rename src/com/android/settings/applications/{AppStateBatteryOptimizationBridge.java => AppStateAppBatteryUsageBridge.java} (82%) diff --git a/res/values/config.xml b/res/values/config.xml index 4180154bbe6..ca2cc0ff650 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -633,4 +633,7 @@ @string/config_settingsintelligence_package_name android.uid.system:1000 + + + false diff --git a/res/xml/apps.xml b/res/xml/apps.xml index ea1e6921363..7ce4d619ad5 100644 --- a/res/xml/apps.xml +++ b/res/xml/apps.xml @@ -76,6 +76,18 @@ + + + + 0 ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; + return mAppInfos.size() > 0 && !mEnableAppBatteryUsagePage ? AVAILABLE + : CONDITIONALLY_UNAVAILABLE; } @Override diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java b/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java index d920a8ef777..d508603c772 100644 --- a/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java +++ b/src/com/android/settings/fuelgauge/batterytip/BatteryManagerPreferenceController.java @@ -36,6 +36,7 @@ public class BatteryManagerPreferenceController extends BasePreferenceController private PowerUsageFeatureProvider mPowerUsageFeatureProvider; private AppOpsManager mAppOpsManager; private UserManager mUserManager; + private boolean mEnableAppBatteryUsagePage; public BatteryManagerPreferenceController(Context context) { super(context, KEY_BATTERY_MANAGER); @@ -43,6 +44,8 @@ public class BatteryManagerPreferenceController extends BasePreferenceController context).getPowerUsageFeatureProvider(context); mAppOpsManager = context.getSystemService(AppOpsManager.class); mUserManager = context.getSystemService(UserManager.class); + mEnableAppBatteryUsagePage = + mContext.getResources().getBoolean(R.bool.config_app_battery_usage_list_enabled); } @Override @@ -53,9 +56,12 @@ public class BatteryManagerPreferenceController extends BasePreferenceController @Override public void updateState(Preference preference) { super.updateState(preference); - final int num = BatteryTipUtils.getRestrictedAppsList(mAppOpsManager, mUserManager).size(); + if (!mEnableAppBatteryUsagePage) { + final int num = BatteryTipUtils.getRestrictedAppsList(mAppOpsManager, + mUserManager).size(); - updateSummary(preference, num); + updateSummary(preference, num); + } } @VisibleForTesting From c2ad30d432131c126bad64db1d074408d7155ac6 Mon Sep 17 00:00:00 2001 From: Tiffany Nguyen Date: Wed, 10 Aug 2022 17:12:36 +0000 Subject: [PATCH 3/4] Align strings and UX across the different pages. https://screenshot.googleplex.com/ercwXXcfg2QHkAW.png https://screenshot.googleplex.com/AWfsrNWsJUbdF8x.png Bug: 240711618 Test: Manual Change-Id: I3d1083a7b50adffb67592b2e42914adf755bd6cd (cherry picked from commit 1d1b11578564dde236822d8d7ee1338aec17600b) Merged-In: I3d1083a7b50adffb67592b2e42914adf755bd6cd --- res/values/strings.xml | 10 +++--- res/xml/app_info_settings.xml | 2 +- res/xml/apps.xml | 4 +-- res/xml/power_usage_detail.xml | 35 ++++++++----------- .../ManageApplications.java | 5 ++- 5 files changed, 27 insertions(+), 29 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 651ead1b161..2fef457b9cd 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6368,7 +6368,7 @@ View usage from last full charge - Battery usage + App battery usage Use details @@ -11794,11 +11794,11 @@ Not using battery optimization - - Manage battery usage + + App battery usage - - Set battery usage for apps + + Set battery usage for apps Unrestricted diff --git a/res/xml/app_info_settings.xml b/res/xml/app_info_settings.xml index a310af59ea6..2bb05d000ae 100644 --- a/res/xml/app_info_settings.xml +++ b/res/xml/app_info_settings.xml @@ -85,7 +85,7 @@ - + - + - - - - - + Date: Tue, 23 Aug 2022 01:29:14 +0000 Subject: [PATCH 4/4] Fix loading bug when switching filters. Also auto fix some lint issues. Bug: 243337537 Test: Manual Change-Id: I55a393517ae01d6a8c17106a3e7750323838cebb (cherry picked from commit 67599bce4e8c3f2cfe3ca028cbca61534b954d1d) Merged-In: I55a393517ae01d6a8c17106a3e7750323838cebb --- .../manageapplications/ManageApplications.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index a8f224991b9..018fda51e12 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -318,7 +318,7 @@ public class ManageApplications extends InstrumentedFragment mListType = LIST_TYPE_ALARMS_AND_REMINDERS; } else if (className.equals(Settings.NotificationAppListActivity.class.getName()) || className.equals( - Settings.NotificationReviewPermissionsActivity.class.getName())) { + Settings.NotificationReviewPermissionsActivity.class.getName())) { mListType = LIST_TYPE_NOTIFICATION; mUsageStatsManager = IUsageStatsManager.Stub.asInterface( ServiceManager.getService(Context.USAGE_STATS_SERVICE)); @@ -920,8 +920,9 @@ public class ManageApplications extends InstrumentedFragment /** * Returns a resource ID of title based on what type of app list is + * * @param intent the intent of the activity that might include a specified title - * @param args the args that includes a class name of app list + * @param args the args that includes a class name of app list */ public static int getTitleResId(@NonNull Intent intent, Bundle args) { int screenTitle = intent.getIntExtra( @@ -944,13 +945,13 @@ public class ManageApplications extends InstrumentedFragment screenTitle = R.string.change_wifi_state_title; } else if (className.equals(Settings.ManageExternalStorageActivity.class.getName())) { screenTitle = R.string.manage_external_storage_title; - } else if (className.equals(Settings.MediaManagementAppsActivity.class.getName())) { + } else if (className.equals(Settings.MediaManagementAppsActivity.class.getName())) { screenTitle = R.string.media_management_apps_title; } else if (className.equals(Settings.AlarmsAndRemindersActivity.class.getName())) { screenTitle = R.string.alarms_and_reminders_title; } else if (className.equals(Settings.NotificationAppListActivity.class.getName()) || className.equals( - Settings.NotificationReviewPermissionsActivity.class.getName())) { + Settings.NotificationReviewPermissionsActivity.class.getName())) { screenTitle = R.string.app_notifications_title; } else if (className.equals(AppLocaleDetails.class.getName())) { screenTitle = R.string.app_locales_picker_menu_title; @@ -1194,11 +1195,11 @@ public class ManageApplications extends InstrumentedFragment } else { rebuild(R.id.sort_order_alpha, true); } + return; } else if (mManageApplications.mListType == LIST_TYPE_BATTERY_OPTIMIZATION) { logAppBatteryUsage(filterType); - } else { - rebuild(); } + rebuild(); } public void resume(int sort) { @@ -1333,7 +1334,7 @@ public class ManageApplications extends InstrumentedFragment } private void logAppBatteryUsage(int filterType) { - switch(filterType) { + switch (filterType) { case FILTER_APPS_BATTERY_UNRESTRICTED: logAction(SettingsEnums.ACTION_BATTERY_OPTIMIZED_APPS_FILTER_UNRESTRICTED); break; @@ -1558,6 +1559,7 @@ public class ManageApplications extends InstrumentedFragment /** * Check item in the list shall enable or disable. + * * @param position The item position in the list */ public boolean isEnabled(int position) {