From 1732fa8db02f9e270067a707e836308159683388 Mon Sep 17 00:00:00 2001 From: mxyyiyi Date: Wed, 16 Oct 2024 12:52:11 +0800 Subject: [PATCH] Redesign the update logic of Allow Background Usage Page. - Use one Controller to manage preferences related to battery Optimization Mode. - Move optimization mode & preferences status update logic from Fragment to Controller. Bug: 373544647 Test: atest AdvancedPowerUsageDetailTest PowerBackgroundUsageDetailTest BatteryOptimizationModePreferenceControllerTest BackgroundUsageAllowabilityPreferenceControllerTest Flag: EXEMPT for simple fix Change-Id: I2b1fed837fb4904e4118ab51c1d0cda36c0f6198 --- res/xml/power_background_usage_detail.xml | 31 +-- res/xml/power_usage_detail.xml | 8 +- .../fuelgauge/AdvancedPowerUsageDetail.java | 104 ++------- .../AllowBackgroundPreferenceController.java | 85 -------- ...UsageAllowabilityPreferenceController.java | 140 ++++++++++++ ...yOptimizationModePreferenceController.java | 136 ++++++++++++ .../OptimizedPreferenceController.java | 66 ------ .../fuelgauge/PowerBackgroundUsageDetail.java | 133 +++--------- .../UnrestrictedPreferenceController.java | 66 ------ .../AdvancedPowerUsageDetailTest.java | 129 ++++------- ...lowBackgroundPreferenceControllerTest.java | 150 ------------- ...eAllowabilityPreferenceControllerTest.java | 202 ++++++++++++++++++ ...imizationModePreferenceControllerTest.java | 179 ++++++++++++++++ .../OptimizedPreferenceControllerTest.java | 130 ----------- .../PowerBackgroundUsageDetailTest.java | 149 +++++-------- .../UnrestrictedPreferenceControllerTest.java | 148 ------------- 16 files changed, 816 insertions(+), 1040 deletions(-) delete mode 100644 src/com/android/settings/fuelgauge/AllowBackgroundPreferenceController.java create mode 100644 src/com/android/settings/fuelgauge/BackgroundUsageAllowabilityPreferenceController.java create mode 100644 src/com/android/settings/fuelgauge/BatteryOptimizationModePreferenceController.java delete mode 100644 src/com/android/settings/fuelgauge/OptimizedPreferenceController.java delete mode 100644 src/com/android/settings/fuelgauge/UnrestrictedPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/fuelgauge/AllowBackgroundPreferenceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/BackgroundUsageAllowabilityPreferenceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizationModePreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/fuelgauge/OptimizedPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/fuelgauge/UnrestrictedPreferenceControllerTest.java diff --git a/res/xml/power_background_usage_detail.xml b/res/xml/power_background_usage_detail.xml index 5c7b6a5235a..32d80b52ecb 100644 --- a/res/xml/power_background_usage_detail.xml +++ b/res/xml/power_background_usage_detail.xml @@ -25,22 +25,25 @@ android:layout="@layout/settings_entity_header" android:selectable="false"/> - + - + - + + + + + android:key="background_usage_allowability_category" + settings:controller="com.android.settings.fuelgauge.BackgroundUsageAllowabilityPreferenceController"> + android:key="background_usage_allowability_switch" + android:title="@string/manager_battery_usage_allow_background_usage_title"/> diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index e922f7058be..28d7d58bee3 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -26,13 +26,10 @@ 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; @@ -48,7 +45,6 @@ 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.PrimarySwitchPreference; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.core.AbstractPreferenceController; @@ -67,9 +63,7 @@ import java.util.concurrent.Executors; * 2. Battery related controls for app(i.e uninstall, force stop) */ public class AdvancedPowerUsageDetail extends DashboardFragment - implements ButtonActionDialogFragment.AppButtonsDialogListener, - Preference.OnPreferenceClickListener, - Preference.OnPreferenceChangeListener { + implements ButtonActionDialogFragment.AppButtonsDialogListener { public static final String TAG = "AdvancedPowerDetail"; public static final String EXTRA_UID = "extra_uid"; public static final String EXTRA_PACKAGE_NAME = "extra_package_name"; @@ -86,7 +80,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment 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_ALLOW_BACKGROUND_USAGE = "allow_background_usage"; + private static final String KEY_BACKGROUND_USAGE_ALLOWABILITY_CATEGORY = + "background_usage_allowability_category"; private static final int REQUEST_UNINSTALL = 0; private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1; @@ -96,11 +91,9 @@ public class AdvancedPowerUsageDetail extends DashboardFragment private AppButtonsPreferenceController mAppButtonsPreferenceController; private PowerUsageTimeController mPowerUsageTimeController; - @VisibleForTesting LayoutPreference mHeaderPreference; @VisibleForTesting ApplicationsState mState; @VisibleForTesting ApplicationsState.AppEntry mAppEntry; @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; - @VisibleForTesting PrimarySwitchPreference mAllowBackgroundUsagePreference; @VisibleForTesting @BatteryOptimizeUtils.OptimizationMode int mOptimizationMode = BatteryOptimizeUtils.MODE_UNKNOWN; @@ -242,17 +235,11 @@ public class AdvancedPowerUsageDetail extends DashboardFragment public void onAttach(Activity activity) { super.onAttach(activity); + final Bundle bundle = getArguments(); + final int uid = bundle.getInt(EXTRA_UID, 0); + final String packageName = bundle.getString(EXTRA_PACKAGE_NAME); + mBatteryOptimizeUtils = new BatteryOptimizeUtils(getContext(), uid, packageName); mState = ApplicationsState.getInstance(getActivity().getApplication()); - } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME); - onCreateBackgroundUsageState(packageName); - mHeaderPreference = findPreference(KEY_PREF_HEADER); - if (packageName != null) { mAppEntry = mState.getEntry(packageName, UserHandle.myUserId()); } @@ -264,7 +251,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment initHeader(); mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode(); - initFooter(); mLogStringBuilder = new StringBuilder("onResume mode = ").append(mOptimizationMode); } @@ -299,7 +285,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment @VisibleForTesting void initHeader() { - final View appSnippet = mHeaderPreference.findViewById(R.id.entity_header); + final LayoutPreference headerPreference = findPreference(KEY_PREF_HEADER); + final View appSnippet = headerPreference.findViewById(R.id.entity_header); final Activity context = getActivity(); final Bundle bundle = getArguments(); EntityHeaderController controller = @@ -340,31 +327,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment controller.done(true /* rebindActions */); } - @VisibleForTesting - void initFooter() { - final String stateString; - 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); - 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); - detailInfoString = - context.getString(R.string.manager_battery_usage_footer_limited, stateString); - } else { - // Present default string to normal app. - detailInfoString = - context.getString( - R.string.manager_battery_usage_allow_background_usage_summary); - } - mAllowBackgroundUsagePreference.setSummary(detailInfoString); - } - @Override public int getMetricsCategory() { return SettingsEnums.FUELGAUGE_POWER_USAGE_DETAIL; @@ -384,7 +346,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment protected List createPreferenceControllers(Context context) { final List controllers = new ArrayList<>(); final Bundle bundle = getArguments(); - final int uid = bundle.getInt(EXTRA_UID, 0); final String packageName = bundle.getString(EXTRA_PACKAGE_NAME); mAppButtonsPreferenceController = @@ -401,7 +362,12 @@ public class AdvancedPowerUsageDetail extends DashboardFragment controllers.add(mPowerUsageTimeController); } controllers.add(mAppButtonsPreferenceController); - controllers.add(new AllowBackgroundPreferenceController(context, uid, packageName)); + controllers.add( + new BackgroundUsageAllowabilityPreferenceController( + context, + /* dashboardFragment= */ this, + KEY_BACKGROUND_USAGE_ALLOWABILITY_CATEGORY, + mBatteryOptimizeUtils)); return controllers; } @@ -421,34 +387,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment } } - @Override - 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; - } - - @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 currentOptimizeMode) { if (currentOptimizeMode == mOptimizationMode) { return; @@ -482,16 +420,4 @@ public class AdvancedPowerUsageDetail extends DashboardFragment getArguments().getInt(EXTRA_POWER_USAGE_AMOUNT)); }); } - - private void onCreateBackgroundUsageState(String packageName) { - mAllowBackgroundUsagePreference = findPreference(KEY_ALLOW_BACKGROUND_USAGE); - if (mAllowBackgroundUsagePreference != null) { - mAllowBackgroundUsagePreference.setOnPreferenceClickListener(this); - mAllowBackgroundUsagePreference.setOnPreferenceChangeListener(this); - } - - mBatteryOptimizeUtils = - new BatteryOptimizeUtils( - getContext(), getArguments().getInt(EXTRA_UID), packageName); - } } diff --git a/src/com/android/settings/fuelgauge/AllowBackgroundPreferenceController.java b/src/com/android/settings/fuelgauge/AllowBackgroundPreferenceController.java deleted file mode 100644 index 52cec79599a..00000000000 --- a/src/com/android/settings/fuelgauge/AllowBackgroundPreferenceController.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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. - */ - -package com.android.settings.fuelgauge; - -import android.content.Context; - -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.MainSwitchPreference; - -/** Controller to update the app background usage state */ -public class AllowBackgroundPreferenceController extends AbstractPreferenceController - implements PreferenceControllerMixin { - - private static final String TAG = "AllowBackgroundPreferenceController"; - - @VisibleForTesting static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage"; - - @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; - - 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); - } - } - - private void setEnabled(Preference preference, boolean enabled) { - if (preference instanceof PrimarySwitchPreference) { - ((PrimarySwitchPreference) preference).setEnabled(enabled); - ((PrimarySwitchPreference) preference).setSwitchEnabled(enabled); - } else if (preference instanceof MainSwitchPreference) { - ((MainSwitchPreference) preference).setEnabled(enabled); - } - } - - @Override - public void updateState(Preference preference) { - setEnabled(preference, mBatteryOptimizeUtils.isOptimizeModeMutable()); - - final boolean isAllowBackground = - mBatteryOptimizeUtils.getAppOptimizationMode() - != BatteryOptimizeUtils.MODE_RESTRICTED; - setChecked(preference, isAllowBackground); - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public String getPreferenceKey() { - return KEY_ALLOW_BACKGROUND_USAGE; - } - - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - return getPreferenceKey().equals(preference.getKey()); - } -} diff --git a/src/com/android/settings/fuelgauge/BackgroundUsageAllowabilityPreferenceController.java b/src/com/android/settings/fuelgauge/BackgroundUsageAllowabilityPreferenceController.java new file mode 100644 index 00000000000..bce439bad1f --- /dev/null +++ b/src/com/android/settings/fuelgauge/BackgroundUsageAllowabilityPreferenceController.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.fuelgauge; + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.PrimarySwitchPreference; + +/** Controller to update the manage battery usage preference in App Battery Usage page */ +public class BackgroundUsageAllowabilityPreferenceController extends BasePreferenceController + implements PreferenceControllerMixin { + + @VisibleForTesting + static final String KEY_BACKGROUND_USAGE_ALLOWABILITY_SWITCH = + "background_usage_allowability_switch"; + + private final BatteryOptimizeUtils mBatteryOptimizeUtils; + private final DashboardFragment mDashboardFragment; + @Nullable @VisibleForTesting PrimarySwitchPreference mBackgroundUsageAllowabilityPreference; + + public BackgroundUsageAllowabilityPreferenceController( + @NonNull Context context, + @NonNull DashboardFragment dashboardFragment, + @NonNull String preferenceKey, + @NonNull BatteryOptimizeUtils batteryOptimizeUtils) { + super(context, preferenceKey); + mDashboardFragment = dashboardFragment; + mBatteryOptimizeUtils = batteryOptimizeUtils; + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void updateState(@NonNull Preference preference) { + updatePreferences(mBatteryOptimizeUtils.getAppOptimizationMode()); + } + + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mBackgroundUsageAllowabilityPreference = + screen.findPreference(KEY_BACKGROUND_USAGE_ALLOWABILITY_SWITCH); + initPreferences(); + } + + @VisibleForTesting + void initPreferences() { + if (mBackgroundUsageAllowabilityPreference == null) { + return; + } + final String stateString; + final String detailInfoString; + boolean isPreferenceEnabled = true; + if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) { + // Present "Optimized" only string if the package name is invalid. + stateString = mContext.getString(R.string.manager_battery_usage_optimized_only); + detailInfoString = + mContext.getString(R.string.manager_battery_usage_footer_limited, stateString); + isPreferenceEnabled = false; + } else if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) { + // Present "Unrestricted" only string if the package is system important apps. + stateString = mContext.getString(R.string.manager_battery_usage_unrestricted_only); + detailInfoString = + mContext.getString(R.string.manager_battery_usage_footer_limited, stateString); + isPreferenceEnabled = false; + } else { + // Present default string to normal app. + detailInfoString = + mContext.getString( + R.string.manager_battery_usage_allow_background_usage_summary); + } + mBackgroundUsageAllowabilityPreference.setEnabled(isPreferenceEnabled); + mBackgroundUsageAllowabilityPreference.setSwitchEnabled(isPreferenceEnabled); + mBackgroundUsageAllowabilityPreference.setSummary(detailInfoString); + if (isPreferenceEnabled) { + mBackgroundUsageAllowabilityPreference.setOnPreferenceClickListener( + preference -> { + PowerBackgroundUsageDetail.startPowerBackgroundUsageDetailPage( + mContext, mDashboardFragment.getArguments()); + return true; + }); + mBackgroundUsageAllowabilityPreference.setOnPreferenceChangeListener( + (preference, isAllowBackground) -> { + handleBatteryOptimizeModeUpdated( + (boolean) isAllowBackground + ? BatteryOptimizeUtils.MODE_OPTIMIZED + : BatteryOptimizeUtils.MODE_RESTRICTED); + return true; + }); + } + } + + @VisibleForTesting + void handleBatteryOptimizeModeUpdated(int newBatteryOptimizeMode) { + if (mBatteryOptimizeUtils.getAppOptimizationMode() == newBatteryOptimizeMode) { + Log.w(TAG, "ignore same mode for: " + mBatteryOptimizeUtils.getPackageName()); + return; + } + mBatteryOptimizeUtils.setAppUsageState( + newBatteryOptimizeMode, BatteryOptimizeHistoricalLogEntry.Action.APPLY); + updatePreferences(newBatteryOptimizeMode); + } + + @VisibleForTesting + void updatePreferences(int optimizationMode) { + if (mBackgroundUsageAllowabilityPreference == null) { + return; + } + mBackgroundUsageAllowabilityPreference.setChecked( + optimizationMode != BatteryOptimizeUtils.MODE_RESTRICTED); + } +} diff --git a/src/com/android/settings/fuelgauge/BatteryOptimizationModePreferenceController.java b/src/com/android/settings/fuelgauge/BatteryOptimizationModePreferenceController.java new file mode 100644 index 00000000000..0a4cbac4dd6 --- /dev/null +++ b/src/com/android/settings/fuelgauge/BatteryOptimizationModePreferenceController.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.fuelgauge; + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.widget.MainSwitchPreference; +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +/** Controller to update the app background usage mode state in Allow background usage page */ +public class BatteryOptimizationModePreferenceController extends BasePreferenceController + implements PreferenceControllerMixin { + + @VisibleForTesting + static final String KEY_BACKGROUND_USAGE_ALLOWABILITY_SWITCH = + "background_usage_allowability_switch"; + + @VisibleForTesting static final String KEY_OPTIMIZED_PREF = "optimized_preference"; + @VisibleForTesting static final String KEY_UNRESTRICTED_PREF = "unrestricted_preference"; + + private final BatteryOptimizeUtils mBatteryOptimizeUtils; + @Nullable @VisibleForTesting MainSwitchPreference mBackgroundUsageAllowabilityPreference; + @Nullable @VisibleForTesting SelectorWithWidgetPreference mOptimizedPreference; + @Nullable @VisibleForTesting SelectorWithWidgetPreference mUnrestrictedPreference; + + public BatteryOptimizationModePreferenceController( + @NonNull Context context, + @NonNull String preferenceKey, + @NonNull BatteryOptimizeUtils batteryOptimizeUtils) { + super(context, preferenceKey); + mBatteryOptimizeUtils = batteryOptimizeUtils; + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void updateState(@NonNull Preference preference) { + updatePreferences(mBatteryOptimizeUtils.getAppOptimizationMode()); + } + + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mBackgroundUsageAllowabilityPreference = + screen.findPreference(KEY_BACKGROUND_USAGE_ALLOWABILITY_SWITCH); + mOptimizedPreference = screen.findPreference(KEY_OPTIMIZED_PREF); + mUnrestrictedPreference = screen.findPreference(KEY_UNRESTRICTED_PREF); + initPreferences(); + } + + @VisibleForTesting + void initPreferences() { + if (mBackgroundUsageAllowabilityPreference == null + || mOptimizedPreference == null + || mUnrestrictedPreference == null) { + return; + } + final boolean isEnabled = mBatteryOptimizeUtils.isOptimizeModeMutable(); + mBackgroundUsageAllowabilityPreference.setEnabled(isEnabled); + mOptimizedPreference.setEnabled(isEnabled); + mUnrestrictedPreference.setEnabled(isEnabled); + if (isEnabled) { + mBackgroundUsageAllowabilityPreference.setOnPreferenceChangeListener( + (preference, isAllowBackground) -> { + handleBatteryOptimizeModeUpdated( + (boolean) isAllowBackground + ? BatteryOptimizeUtils.MODE_OPTIMIZED + : BatteryOptimizeUtils.MODE_RESTRICTED); + return true; + }); + mOptimizedPreference.setOnPreferenceClickListener( + preference -> { + handleBatteryOptimizeModeUpdated(BatteryOptimizeUtils.MODE_OPTIMIZED); + return true; + }); + mUnrestrictedPreference.setOnPreferenceClickListener( + preference -> { + handleBatteryOptimizeModeUpdated(BatteryOptimizeUtils.MODE_UNRESTRICTED); + return true; + }); + } + } + + @VisibleForTesting + void updatePreferences(int optimizationMode) { + if (mBackgroundUsageAllowabilityPreference == null + || mOptimizedPreference == null + || mUnrestrictedPreference == null) { + return; + } + final boolean isAllowBackground = optimizationMode != BatteryOptimizeUtils.MODE_RESTRICTED; + mBackgroundUsageAllowabilityPreference.setChecked(isAllowBackground); + mOptimizedPreference.setEnabled(isAllowBackground); + mUnrestrictedPreference.setEnabled(isAllowBackground); + mOptimizedPreference.setChecked(optimizationMode == BatteryOptimizeUtils.MODE_OPTIMIZED); + mUnrestrictedPreference.setChecked( + optimizationMode == BatteryOptimizeUtils.MODE_UNRESTRICTED); + } + + @VisibleForTesting + void handleBatteryOptimizeModeUpdated(int newBatteryOptimizeMode) { + if (mBatteryOptimizeUtils.getAppOptimizationMode() == newBatteryOptimizeMode) { + Log.w(TAG, "ignore same mode for: " + mBatteryOptimizeUtils.getPackageName()); + return; + } + mBatteryOptimizeUtils.setAppUsageState( + newBatteryOptimizeMode, BatteryOptimizeHistoricalLogEntry.Action.APPLY); + updatePreferences(newBatteryOptimizeMode); + } +} diff --git a/src/com/android/settings/fuelgauge/OptimizedPreferenceController.java b/src/com/android/settings/fuelgauge/OptimizedPreferenceController.java deleted file mode 100644 index a26ab7a58e4..00000000000 --- a/src/com/android/settings/fuelgauge/OptimizedPreferenceController.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.fuelgauge; - -import android.content.Context; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; - -import com.android.settings.core.PreferenceControllerMixin; -import com.android.settingslib.core.AbstractPreferenceController; -import com.android.settingslib.widget.SelectorWithWidgetPreference; - -public class OptimizedPreferenceController extends AbstractPreferenceController - implements PreferenceControllerMixin { - - private static final String TAG = "OPTIMIZED_PREF"; - - @VisibleForTesting static final String KEY_OPTIMIZED_PREF = "optimized_preference"; - @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; - - public OptimizedPreferenceController(Context context, int uid, String packageName) { - super(context); - mBatteryOptimizeUtils = new BatteryOptimizeUtils(context, uid, packageName); - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public void updateState(Preference preference) { - preference.setEnabled(mBatteryOptimizeUtils.isSelectorPreferenceEnabled()); - - final boolean isOptimized = - mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly() - || mBatteryOptimizeUtils.getAppOptimizationMode() - == BatteryOptimizeUtils.MODE_OPTIMIZED; - ((SelectorWithWidgetPreference) preference).setChecked(isOptimized); - } - - @Override - public String getPreferenceKey() { - return KEY_OPTIMIZED_PREF; - } - - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - return getPreferenceKey().equals(preference.getKey()); - } -} diff --git a/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java b/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java index e59cc4add46..dadf2e89fbe 100644 --- a/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java +++ b/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java @@ -24,11 +24,8 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.UserHandle; -import android.text.TextUtils; import android.util.Log; import android.view.View; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; import androidx.annotation.VisibleForTesting; @@ -44,8 +41,6 @@ import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.LayoutPreference; -import com.android.settingslib.widget.MainSwitchPreference; -import com.android.settingslib.widget.SelectorWithWidgetPreference; import java.util.ArrayList; import java.util.List; @@ -53,8 +48,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** Allow background usage fragment for each app */ -public class PowerBackgroundUsageDetail extends DashboardFragment - implements SelectorWithWidgetPreference.OnClickListener, OnCheckedChangeListener { +public class PowerBackgroundUsageDetail extends DashboardFragment { private static final String TAG = "PowerBackgroundUsageDetail"; public static final String EXTRA_UID = "extra_uid"; @@ -63,21 +57,15 @@ public class PowerBackgroundUsageDetail extends DashboardFragment public static final String EXTRA_POWER_USAGE_AMOUNT = "extra_power_usage_amount"; public static final String EXTRA_ICON_ID = "extra_icon_id"; private static final String KEY_PREF_HEADER = "header_view"; - private static final String KEY_PREF_UNRESTRICTED = "unrestricted_preference"; - private static final String KEY_PREF_OPTIMIZED = "optimized_preference"; - private static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage"; private static final String KEY_FOOTER_PREFERENCE = "app_usage_footer_preference"; + private static final String KEY_BATTERY_OPTIMIZATION_MODE_CATEGORY = + "battery_optimization_mode_category"; private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); - @VisibleForTesting LayoutPreference mHeaderPreference; @VisibleForTesting ApplicationsState mState; @VisibleForTesting ApplicationsState.AppEntry mAppEntry; @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; - @VisibleForTesting SelectorWithWidgetPreference mOptimizePreference; - @VisibleForTesting SelectorWithWidgetPreference mUnrestrictedPreference; - @VisibleForTesting MainSwitchPreference mMainSwitchPreference; - @VisibleForTesting FooterPreference mFooterPreference; @VisibleForTesting StringBuilder mLogStringBuilder; @VisibleForTesting @BatteryOptimizeUtils.OptimizationMode @@ -87,17 +75,11 @@ public class PowerBackgroundUsageDetail extends DashboardFragment public void onAttach(Activity activity) { super.onAttach(activity); + final Bundle bundle = getArguments(); + final int uid = bundle.getInt(EXTRA_UID, 0); + final String packageName = bundle.getString(EXTRA_PACKAGE_NAME); + mBatteryOptimizeUtils = new BatteryOptimizeUtils(getContext(), uid, packageName); mState = ApplicationsState.getInstance(getActivity().getApplication()); - } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME); - onCreateBackgroundUsageState(packageName); - mHeaderPreference = findPreference(KEY_PREF_HEADER); - if (packageName != null) { mAppEntry = mState.getEntry(packageName, UserHandle.myUserId()); } @@ -107,8 +89,8 @@ public class PowerBackgroundUsageDetail extends DashboardFragment public void onResume() { super.onResume(); initHeader(); - mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode(); initFooter(); + mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode(); mLogStringBuilder = new StringBuilder("onResume mode = ").append(mOptimizationMode); } @@ -136,20 +118,6 @@ public class PowerBackgroundUsageDetail extends DashboardFragment Log.d(TAG, "Leave with mode: " + currentOptimizeMode); } - @Override - public void onRadioButtonClicked(SelectorWithWidgetPreference selected) { - final String selectedKey = selected == null ? null : selected.getKey(); - updateSelectorPreferenceState(mUnrestrictedPreference, selectedKey); - updateSelectorPreferenceState(mOptimizePreference, selectedKey); - mBatteryOptimizeUtils.setAppUsageState(getSelectedPreference(), Action.APPLY); - } - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mMainSwitchPreference.setChecked(isChecked); - updateSelectorPreference(isChecked); - } - @Override public int getMetricsCategory() { return SettingsEnums.FUELGAUGE_POWER_USAGE_MANAGE_BACKGROUND; @@ -157,14 +125,10 @@ public class PowerBackgroundUsageDetail extends DashboardFragment @Override protected List createPreferenceControllers(Context context) { - final List controllers = new ArrayList<>(); - final Bundle bundle = getArguments(); - final int uid = bundle.getInt(EXTRA_UID, 0); - final String packageName = bundle.getString(EXTRA_PACKAGE_NAME); - - controllers.add(new AllowBackgroundPreferenceController(context, uid, packageName)); - controllers.add(new OptimizedPreferenceController(context, uid, packageName)); - controllers.add(new UnrestrictedPreferenceController(context, uid, packageName)); + final List controllers = new ArrayList<>(1); + controllers.add( + new BatteryOptimizationModePreferenceController( + context, KEY_BATTERY_OPTIMIZATION_MODE_CATEGORY, mBatteryOptimizeUtils)); return controllers; } @@ -179,26 +143,6 @@ public class PowerBackgroundUsageDetail extends DashboardFragment return TAG; } - @VisibleForTesting - void updateSelectorPreference(boolean isEnabled) { - mOptimizePreference.setEnabled(isEnabled); - mUnrestrictedPreference.setEnabled(isEnabled); - onRadioButtonClicked(isEnabled ? mOptimizePreference : null); - } - - @VisibleForTesting - int getSelectedPreference() { - if (!mMainSwitchPreference.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; - } - } - static void startPowerBackgroundUsageDetailPage(Context context, Bundle args) { new SubSettingLauncher(context) .setDestination(PowerBackgroundUsageDetail.class.getName()) @@ -209,7 +153,11 @@ public class PowerBackgroundUsageDetail extends DashboardFragment @VisibleForTesting void initHeader() { - final View appSnippet = mHeaderPreference.findViewById(R.id.entity_header); + final LayoutPreference headerPreference = findPreference(KEY_PREF_HEADER); + if (headerPreference == null) { + return; + } + final View appSnippet = headerPreference.findViewById(R.id.entity_header); final Activity context = getActivity(); final Bundle bundle = getArguments(); EntityHeaderController controller = @@ -239,58 +187,25 @@ public class PowerBackgroundUsageDetail extends DashboardFragment @VisibleForTesting void initFooter() { - final String stateString; - final String footerString; - 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); - } 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); + final FooterPreference footerPreference = findPreference(KEY_FOOTER_PREFERENCE); + if (footerPreference == null) { + return; } - mFooterPreference.setTitle(footerString); + final Context context = getContext(); + footerPreference.setTitle(context.getString(R.string.manager_battery_usage_footer)); final Intent helpIntent = HelpUtils.getHelpIntent( context, context.getString(R.string.help_url_app_usage_settings), /* backupContext= */ ""); if (helpIntent != null) { - mFooterPreference.setLearnMoreAction( + footerPreference.setLearnMoreAction( v -> startActivityForResult(helpIntent, /* requestCode= */ 0)); - mFooterPreference.setLearnMoreText( + footerPreference.setLearnMoreText( context.getString(R.string.manager_battery_usage_link_a11y)); } } - private void onCreateBackgroundUsageState(String packageName) { - mOptimizePreference = findPreference(KEY_PREF_OPTIMIZED); - mUnrestrictedPreference = findPreference(KEY_PREF_UNRESTRICTED); - mMainSwitchPreference = findPreference(KEY_ALLOW_BACKGROUND_USAGE); - mFooterPreference = findPreference(KEY_FOOTER_PREFERENCE); - - mOptimizePreference.setOnClickListener(this); - mUnrestrictedPreference.setOnClickListener(this); - mMainSwitchPreference.addOnSwitchChangeListener(this); - - mBatteryOptimizeUtils = - new BatteryOptimizeUtils( - getContext(), getArguments().getInt(EXTRA_UID), packageName); - } - - private void updateSelectorPreferenceState( - SelectorWithWidgetPreference preference, String selectedKey) { - preference.setChecked(TextUtils.equals(selectedKey, preference.getKey())); - } - private void logMetricCategory(int currentOptimizeMode) { if (currentOptimizeMode == mOptimizationMode) { return; diff --git a/src/com/android/settings/fuelgauge/UnrestrictedPreferenceController.java b/src/com/android/settings/fuelgauge/UnrestrictedPreferenceController.java deleted file mode 100644 index 652941b2544..00000000000 --- a/src/com/android/settings/fuelgauge/UnrestrictedPreferenceController.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.fuelgauge; - -import android.content.Context; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; - -import com.android.settings.core.PreferenceControllerMixin; -import com.android.settingslib.core.AbstractPreferenceController; -import com.android.settingslib.widget.SelectorWithWidgetPreference; - -public class UnrestrictedPreferenceController extends AbstractPreferenceController - implements PreferenceControllerMixin { - - private static final String TAG = "UNRESTRICTED_PREF"; - - @VisibleForTesting static final String KEY_UNRESTRICTED_PREF = "unrestricted_preference"; - - @VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils; - - public UnrestrictedPreferenceController(Context context, int uid, String packageName) { - super(context); - mBatteryOptimizeUtils = new BatteryOptimizeUtils(context, uid, packageName); - } - - @Override - public void updateState(Preference preference) { - preference.setEnabled(mBatteryOptimizeUtils.isSelectorPreferenceEnabled()); - - final boolean isUnrestricted = - mBatteryOptimizeUtils.getAppOptimizationMode() - == BatteryOptimizeUtils.MODE_UNRESTRICTED; - ((SelectorWithWidgetPreference) preference).setChecked(isUnrestricted); - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public String getPreferenceKey() { - return KEY_UNRESTRICTED_PREF; - } - - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - return getPreferenceKey().equals(preference.getKey()); - } -} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java index 1bc00a1fdff..f3848b3fbb2 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java @@ -17,10 +17,10 @@ package com.android.settings.fuelgauge; import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS; -import static com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.nullable; @@ -49,13 +49,13 @@ import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action; import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry; import com.android.settings.fuelgauge.batteryusage.BatteryEntry; import com.android.settings.fuelgauge.batteryusage.ConvertUtils; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowEntityHeaderController; import com.android.settings.widget.EntityHeaderController; -import com.android.settingslib.PrimarySwitchPreference; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.instantapps.InstantAppDataProvider; @@ -87,12 +87,12 @@ import java.util.concurrent.TimeUnit; }) public class AdvancedPowerUsageDetailTest { - @Rule - public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); private static final String APP_LABEL = "app label"; private static final String SUMMARY = "summary"; - private static final String[] PACKAGE_NAME = {"com.android.app"}; + private static final String PACKAGE_NAME = "com.android.app"; + private static final String INITIATING_PACKAGE_NAME = "com.android.vending"; private static final String USAGE_PERCENT = "16%"; private static final int ICON_ID = 123; private static final int UID = 1; @@ -100,39 +100,43 @@ public class AdvancedPowerUsageDetailTest { private static final long FOREGROUND_SERVICE_TIME_MS = 123; private static final long BACKGROUND_TIME_MS = 100; private static final long SCREEN_ON_TIME_MS = 321; - private static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage"; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private FragmentActivity mActivity; @Mock private EntityHeaderController mEntityHeaderController; - @Mock private LayoutPreference mHeaderPreference; @Mock private ApplicationsState mState; @Mock private ApplicationsState.AppEntry mAppEntry; @Mock private BatteryEntry mBatteryEntry; @Mock private PackageManager mPackageManager; @Mock private InstallSourceInfo mInstallSourceInfo; + @Mock private LayoutPreference mLayoutPreference; @Mock private AppOpsManager mAppOpsManager; @Mock private LoaderManager mLoaderManager; - @Mock private BatteryOptimizeUtils mBatteryOptimizeUtils; + private int mTestMode; private Context mContext; - private PrimarySwitchPreference mAllowBackgroundUsagePreference; private AdvancedPowerUsageDetail mFragment; private SettingsActivity mTestActivity; private FakeFeatureFactory mFeatureFactory; private MetricsFeatureProvider mMetricsFeatureProvider; private BatteryDiffEntry mBatteryDiffEntry; private Bundle mBundle; + private BatteryOptimizeUtils mBatteryOptimizeUtils; @Before - public void setUp() { + public void setUp() throws Exception { mContext = spy(ApplicationProvider.getApplicationContext()); - when(mContext.getPackageName()).thenReturn("foo"); + when(mContext.getPackageName()).thenReturn(PACKAGE_NAME); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo); mFeatureFactory = FakeFeatureFactory.setupForTest(); mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider; + prepareTestBatteryOptimizationUtils(); mFragment = spy(new AdvancedPowerUsageDetail()); + mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils; + doReturn(mLayoutPreference).when(mFragment).findPreference(any()); mBundle = spy(new Bundle()); doReturn(mContext).when(mFragment).getContext(); doReturn(mActivity).when(mFragment).getActivity(); @@ -195,7 +199,6 @@ public class AdvancedPowerUsageDetailTest { when(mBatteryDiffEntry.getAppLabel()).thenReturn(APP_LABEL); when(mBatteryDiffEntry.getAppIconId()).thenReturn(ICON_ID); - mFragment.mHeaderPreference = mHeaderPreference; mFragment.mState = mState; mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils; mFragment.mLogStringBuilder = new StringBuilder(); @@ -219,10 +222,6 @@ public class AdvancedPowerUsageDetailTest { .startActivityAsUser(captor.capture(), nullable(UserHandle.class)); doAnswer(callable).when(mActivity).startActivity(captor.capture()); doAnswer(callable).when(mContext).startActivity(captor.capture()); - - mAllowBackgroundUsagePreference = new PrimarySwitchPreference(mContext); - mAllowBackgroundUsagePreference.setKey(KEY_ALLOW_BACKGROUND_USAGE); - mFragment.mAllowBackgroundUsagePreference = mAllowBackgroundUsagePreference; } @After @@ -320,17 +319,15 @@ public class AdvancedPowerUsageDetailTest { .isEqualTo(SCREEN_ON_TIME_MS); assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_PERCENT)) .isEqualTo(USAGE_PERCENT); - assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_SLOT_TIME)) - .isEqualTo(null); + assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_SLOT_TIME)).isNull(); } - @Test public void startBatteryDetailPage_noBatteryUsage_hasBasicData() { final ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); AdvancedPowerUsageDetail.startBatteryDetailPage( - mActivity, mFragment, PACKAGE_NAME[0], UserHandle.OWNER); + mActivity, mFragment, PACKAGE_NAME, UserHandle.OWNER); verify(mActivity).startActivity(captor.capture()); @@ -338,7 +335,7 @@ public class AdvancedPowerUsageDetailTest { captor.getValue() .getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS) .getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)) - .isEqualTo(PACKAGE_NAME[0]); + .isEqualTo(PACKAGE_NAME); assertThat( captor.getValue() @@ -351,62 +348,21 @@ public class AdvancedPowerUsageDetailTest { public void startBatteryDetailPage_batteryEntryNotExisted_extractUidFromPackageName() throws PackageManager.NameNotFoundException { mBundle.clear(); - doReturn(UID).when(mPackageManager).getPackageUid(PACKAGE_NAME[0], 0 /* no flag */); + doReturn(UID).when(mPackageManager).getPackageUid(PACKAGE_NAME, 0 /* no flag */); AdvancedPowerUsageDetail.startBatteryDetailPage( - mActivity, mFragment, PACKAGE_NAME[0], UserHandle.OWNER); + mActivity, mFragment, PACKAGE_NAME, UserHandle.OWNER); assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID); } @Test - public void initFooter_isValidPackageName_hasCorrectString() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true); + public void onPause_optimizationModeIsChanged_logPreference() throws Exception { + mFragment.mOptimizationMode = BatteryOptimizeUtils.MODE_RESTRICTED; + when(mBatteryOptimizeUtils.getPackageName()).thenReturn(PACKAGE_NAME); + when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn(INITIATING_PACKAGE_NAME); - mFragment.initFooter(); - - assertThat(mAllowBackgroundUsagePreference.getSummary().toString()) - .isEqualTo("This app requires optimized battery usage."); - } - - @Test - public void initFooter_isSystemOrDefaultApp_hasCorrectString() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true); - - mFragment.initFooter(); - - assertThat(mAllowBackgroundUsagePreference.getSummary().toString()) - .isEqualTo("This app requires unrestricted battery usage."); - } - - @Test - public void initFooter_hasCorrectString() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false); - - mFragment.initFooter(); - - assertThat(mAllowBackgroundUsagePreference.getSummary().toString()) - .isEqualTo("Enable for real-time updates, disable to save battery"); - } - - @Test - public void onPause_optimizationModeChanged_logPreference() - throws PackageManager.NameNotFoundException, InterruptedException { - final String packageName = "testPackageName"; - final int restrictedMode = BatteryOptimizeUtils.MODE_RESTRICTED; - final int optimizedMode = BatteryOptimizeUtils.MODE_OPTIMIZED; - mFragment.mOptimizationMode = restrictedMode; - when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(restrictedMode); - when(mBatteryOptimizeUtils.getPackageName()).thenReturn(packageName); - when(mContext.getPackageManager()).thenReturn(mPackageManager); - when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo); - when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending"); - - mFragment.onPreferenceChange(mAllowBackgroundUsagePreference, true); - verify(mBatteryOptimizeUtils).setAppUsageState(optimizedMode, Action.APPLY); - when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(optimizedMode); + mBatteryOptimizeUtils.setAppUsageState(BatteryOptimizeUtils.MODE_OPTIMIZED, Action.APPLY); mFragment.onPause(); TimeUnit.SECONDS.sleep(1); @@ -415,27 +371,18 @@ public class AdvancedPowerUsageDetailTest { SettingsEnums.LEAVE_APP_BATTERY_USAGE, SettingsEnums.ACTION_APP_BATTERY_USAGE_ALLOW_BACKGROUND, SettingsEnums.FUELGAUGE_POWER_USAGE_DETAIL, - packageName, + PACKAGE_NAME, /* consumed battery */ 0); } @Test - public void onPause_optimizationModeIsNotChanged_notInvokeLogging() - throws PackageManager.NameNotFoundException, InterruptedException { - final int restrictedMode = BatteryOptimizeUtils.MODE_RESTRICTED; - final int optimizedMode = BatteryOptimizeUtils.MODE_OPTIMIZED; - mFragment.mOptimizationMode = restrictedMode; - when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(restrictedMode); - when(mContext.getPackageManager()).thenReturn(mPackageManager); - when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo); - when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending"); + public void onPause_optimizationModeIsNotChanged_notInvokeLogging() throws Exception { + mFragment.mOptimizationMode = BatteryOptimizeUtils.MODE_RESTRICTED; + when(mBatteryOptimizeUtils.getPackageName()).thenReturn(PACKAGE_NAME); + when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn(INITIATING_PACKAGE_NAME); - mFragment.onPreferenceChange(mAllowBackgroundUsagePreference, true); - verify(mBatteryOptimizeUtils).setAppUsageState(optimizedMode, Action.APPLY); - when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(optimizedMode); - mFragment.onPreferenceChange(mAllowBackgroundUsagePreference, false); - verify(mBatteryOptimizeUtils).setAppUsageState(restrictedMode, Action.APPLY); - when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(restrictedMode); + mBatteryOptimizeUtils.setAppUsageState(BatteryOptimizeUtils.MODE_OPTIMIZED, Action.APPLY); + mBatteryOptimizeUtils.setAppUsageState(BatteryOptimizeUtils.MODE_RESTRICTED, Action.APPLY); mFragment.onPause(); TimeUnit.SECONDS.sleep(1); @@ -446,4 +393,16 @@ public class AdvancedPowerUsageDetailTest { public void shouldSkipForInitialSUW_returnTrue() { assertThat(mFragment.shouldSkipForInitialSUW()).isTrue(); } + + private void prepareTestBatteryOptimizationUtils() { + mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(mContext, UID, PACKAGE_NAME)); + Answer setTestMode = + invocation -> { + mTestMode = invocation.getArgument(0); + return null; + }; + doAnswer(setTestMode).when(mBatteryOptimizeUtils).setAppUsageState(anyInt(), any()); + Answer getTestMode = invocation -> mTestMode; + doAnswer(getTestMode).when(mBatteryOptimizeUtils).getAppOptimizationMode(); + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AllowBackgroundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AllowBackgroundPreferenceControllerTest.java deleted file mode 100644 index 261a3151531..00000000000 --- a/tests/robotests/src/com/android/settings/fuelgauge/AllowBackgroundPreferenceControllerTest.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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. - */ - -package com.android.settings.fuelgauge; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.PackageManager; - -import com.android.settingslib.widget.MainSwitchPreference; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class AllowBackgroundPreferenceControllerTest { - private static final int UID = 12345; - private static final String PACKAGE_NAME = "com.android.app"; - - private AllowBackgroundPreferenceController mController; - private MainSwitchPreference mMainSwitchPreference; - private BatteryOptimizeUtils mBatteryOptimizeUtils; - - @Mock private PackageManager mMockPackageManager; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - Context context = spy(RuntimeEnvironment.application); - BatteryUtils.getInstance(context).reset(); - doReturn(UID) - .when(mMockPackageManager) - .getPackageUid(PACKAGE_NAME, PackageManager.GET_META_DATA); - - mController = new AllowBackgroundPreferenceController(context, UID, PACKAGE_NAME); - mMainSwitchPreference = new MainSwitchPreference(RuntimeEnvironment.application); - mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(context, UID, PACKAGE_NAME)); - mController.mBatteryOptimizeUtils = mBatteryOptimizeUtils; - } - - @Test - public void testUpdateState_isValidPackage_prefEnabled() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false); - - mController.updateState(mMainSwitchPreference); - - assertThat(mBatteryOptimizeUtils.isOptimizeModeMutable()).isTrue(); - assertThat(mMainSwitchPreference.isEnabled()).isTrue(); - } - - @Test - public void testUpdateState_invalidPackage_prefDisabled() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false); - - mController.updateState(mMainSwitchPreference); - - assertThat(mBatteryOptimizeUtils.isOptimizeModeMutable()).isFalse(); - assertThat(mMainSwitchPreference.isEnabled()).isFalse(); - } - - @Test - public void testUpdateState_isSystemOrDefaultAppAndRestrictedStates_prefChecked() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_RESTRICTED); - - mController.updateState(mMainSwitchPreference); - - assertThat(mMainSwitchPreference.isEnabled()).isFalse(); - assertThat(mMainSwitchPreference.isChecked()).isFalse(); - } - - @Test - public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_OPTIMIZED); - - mController.updateState(mMainSwitchPreference); - - assertThat(mMainSwitchPreference.isEnabled()).isFalse(); - assertThat(mMainSwitchPreference.isChecked()).isTrue(); - } - - @Test - public void testUpdateState_isRestrictedStates_prefChecked() { - when(mBatteryOptimizeUtils.isOptimizeModeMutable()).thenReturn(true); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_RESTRICTED); - - mController.updateState(mMainSwitchPreference); - - assertThat(mMainSwitchPreference.isEnabled()).isTrue(); - assertThat(mMainSwitchPreference.isChecked()).isFalse(); - } - - @Test - public void testUpdateState_prefUnchecked() { - when(mBatteryOptimizeUtils.isOptimizeModeMutable()).thenReturn(true); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_OPTIMIZED); - - mController.updateState(mMainSwitchPreference); - - assertThat(mMainSwitchPreference.isEnabled()).isTrue(); - assertThat(mMainSwitchPreference.isChecked()).isTrue(); - } - - @Test - public void testHandlePreferenceTreeClick_samePrefKey_verifyAction() { - mMainSwitchPreference.setKey( - AllowBackgroundPreferenceController.KEY_ALLOW_BACKGROUND_USAGE); - mController.handlePreferenceTreeClick(mMainSwitchPreference); - - assertThat(mController.handlePreferenceTreeClick(mMainSwitchPreference)).isTrue(); - } - - @Test - public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() { - assertThat(mController.handlePreferenceTreeClick(mMainSwitchPreference)).isFalse(); - } -} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundUsageAllowabilityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundUsageAllowabilityPreferenceControllerTest.java new file mode 100644 index 00000000000..190446ed116 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundUsageAllowabilityPreferenceControllerTest.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.fuelgauge; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.content.Context; + +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action; +import com.android.settingslib.PrimarySwitchPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.stubbing.Answer; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class BackgroundUsageAllowabilityPreferenceControllerTest { + private static final int UID = 12345; + private static final String PACKAGE_NAME = "com.android.app"; + + private int mTestMode; + private Context mContext; + private BackgroundUsageAllowabilityPreferenceController mBackgroundUsageController; + private BatteryOptimizeUtils mBatteryOptimizeUtils; + + @Mock DashboardFragment mDashboardFragment; + @Mock PrimarySwitchPreference mBackgroundUsageAllowabilityPreference; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mContext = spy(ApplicationProvider.getApplicationContext()); + prepareTestBatteryOptimizationUtils(); + mBackgroundUsageController = + spy( + new BackgroundUsageAllowabilityPreferenceController( + mContext, + mDashboardFragment, + /* preferenceKey= */ "test", + mBatteryOptimizeUtils)); + mBackgroundUsageController.mBackgroundUsageAllowabilityPreference = + mBackgroundUsageAllowabilityPreference; + } + + @Test + public void initPreferences_immutableOptimized_setExpectedContent() { + doReturn(false).when(mBatteryOptimizeUtils).isOptimizeModeMutable(); + doReturn(true).when(mBatteryOptimizeUtils).isDisabledForOptimizeModeOnly(); + + mBackgroundUsageController.initPreferences(); + + verify(mBackgroundUsageAllowabilityPreference).setEnabled(false); + verify(mBackgroundUsageAllowabilityPreference).setSwitchEnabled(false); + verify(mBackgroundUsageAllowabilityPreference) + .setSummary( + mContext.getString( + R.string.manager_battery_usage_footer_limited, + mContext.getString(R.string.manager_battery_usage_optimized_only))); + verify(mBackgroundUsageAllowabilityPreference, never()) + .setOnPreferenceChangeListener(any()); + verify(mBackgroundUsageAllowabilityPreference, never()).setOnPreferenceClickListener(any()); + } + + @Test + public void initPreferences_immutableUnrestricted_setExpectedContent() { + doReturn(false).when(mBatteryOptimizeUtils).isOptimizeModeMutable(); + doReturn(false).when(mBatteryOptimizeUtils).isDisabledForOptimizeModeOnly(); + doReturn(true).when(mBatteryOptimizeUtils).isSystemOrDefaultApp(); + + mBackgroundUsageController.initPreferences(); + + verify(mBackgroundUsageAllowabilityPreference).setEnabled(false); + verify(mBackgroundUsageAllowabilityPreference).setSwitchEnabled(false); + verify(mBackgroundUsageAllowabilityPreference) + .setSummary( + mContext.getString( + R.string.manager_battery_usage_footer_limited, + mContext.getString( + R.string.manager_battery_usage_unrestricted_only))); + verify(mBackgroundUsageAllowabilityPreference, never()) + .setOnPreferenceChangeListener(any()); + verify(mBackgroundUsageAllowabilityPreference, never()).setOnPreferenceClickListener(any()); + } + + @Test + public void initPreferences_mutableMode_setExpectedContent() { + doReturn(true).when(mBatteryOptimizeUtils).isOptimizeModeMutable(); + doReturn(false).when(mBatteryOptimizeUtils).isDisabledForOptimizeModeOnly(); + doReturn(false).when(mBatteryOptimizeUtils).isSystemOrDefaultApp(); + + mBackgroundUsageController.initPreferences(); + + verify(mBackgroundUsageAllowabilityPreference).setEnabled(true); + verify(mBackgroundUsageAllowabilityPreference).setSwitchEnabled(true); + verify(mBackgroundUsageAllowabilityPreference) + .setSummary( + mContext.getString( + R.string.manager_battery_usage_allow_background_usage_summary)); + verify(mBackgroundUsageAllowabilityPreference).setOnPreferenceChangeListener(any()); + verify(mBackgroundUsageAllowabilityPreference).setOnPreferenceClickListener(any()); + } + + @Test + public void updatePreferences_setIntoUnrestrictedMode_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_UNRESTRICTED; + + mBackgroundUsageController.updatePreferences(mTestMode); + + verifyPreferences(mTestMode); + } + + @Test + public void updatePreferences_setIntoOptimizedMode_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_OPTIMIZED; + + mBackgroundUsageController.updatePreferences(mTestMode); + + verifyPreferences(mTestMode); + } + + @Test + public void updatePreferences_setIntoRestrictedMode_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_RESTRICTED; + + mBackgroundUsageController.updatePreferences(mTestMode); + + verifyPreferences(mTestMode); + } + + @Test + public void handleBatteryOptimizeModeUpdated_modeChange_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_RESTRICTED; + + mBackgroundUsageController.handleBatteryOptimizeModeUpdated( + BatteryOptimizeUtils.MODE_OPTIMIZED); + + verify(mBatteryOptimizeUtils) + .setAppUsageState(BatteryOptimizeUtils.MODE_OPTIMIZED, Action.APPLY); + assertThat(mTestMode).isEqualTo(BatteryOptimizeUtils.MODE_OPTIMIZED); + verifyPreferences(mTestMode); + } + + @Test + public void handleBatteryOptimizeModeUpdated_modeNotChange_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_RESTRICTED; + + mBackgroundUsageController.handleBatteryOptimizeModeUpdated( + BatteryOptimizeUtils.MODE_RESTRICTED); + + verify(mBatteryOptimizeUtils, never()).setAppUsageState(anyInt(), any()); + assertThat(mTestMode).isEqualTo(BatteryOptimizeUtils.MODE_RESTRICTED); + verify(mBackgroundUsageController, never()).updatePreferences(mTestMode); + } + + private void prepareTestBatteryOptimizationUtils() { + mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(mContext, UID, PACKAGE_NAME)); + Answer setTestMode = + invocation -> { + mTestMode = invocation.getArgument(0); + return null; + }; + doAnswer(setTestMode).when(mBatteryOptimizeUtils).setAppUsageState(anyInt(), any()); + Answer getTestMode = invocation -> mTestMode; + doAnswer(getTestMode).when(mBatteryOptimizeUtils).getAppOptimizationMode(); + } + + private void verifyPreferences(int mode) { + boolean isAllowBackground = mode != BatteryOptimizeUtils.MODE_RESTRICTED; + verify(mBackgroundUsageAllowabilityPreference).setChecked(isAllowBackground); + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizationModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizationModePreferenceControllerTest.java new file mode 100644 index 00000000000..2ddc7ebbc72 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizationModePreferenceControllerTest.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.fuelgauge; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.content.Context; + +import androidx.test.core.app.ApplicationProvider; + +import com.android.settingslib.widget.MainSwitchPreference; +import com.android.settingslib.widget.SelectorWithWidgetPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.stubbing.Answer; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class BatteryOptimizationModePreferenceControllerTest { + private static final int UID = 12345; + private static final String PACKAGE_NAME = "com.android.app"; + + private int mTestMode; + private Context mContext; + private BatteryOptimizationModePreferenceController mBackgroundUsageController; + private BatteryOptimizeUtils mBatteryOptimizeUtils; + + @Mock MainSwitchPreference mBackgroundUsageAllowabilityPreference; + @Mock SelectorWithWidgetPreference mOptimizedPreference; + @Mock SelectorWithWidgetPreference mUnrestrictedPreference; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mContext = spy(ApplicationProvider.getApplicationContext()); + prepareTestBatteryOptimizationUtils(); + mBackgroundUsageController = + spy( + new BatteryOptimizationModePreferenceController( + mContext, "test", mBatteryOptimizeUtils)); + mBackgroundUsageController.mBackgroundUsageAllowabilityPreference = + mBackgroundUsageAllowabilityPreference; + mBackgroundUsageController.mOptimizedPreference = mOptimizedPreference; + mBackgroundUsageController.mUnrestrictedPreference = mUnrestrictedPreference; + } + + @Test + public void initPreferences_mutableMode_setEnabled() { + doReturn(true).when(mBatteryOptimizeUtils).isOptimizeModeMutable(); + + mBackgroundUsageController.initPreferences(); + + verify(mBackgroundUsageAllowabilityPreference).setEnabled(true); + verify(mOptimizedPreference).setEnabled(true); + verify(mUnrestrictedPreference).setEnabled(true); + verify(mBackgroundUsageAllowabilityPreference, never()).setOnPreferenceClickListener(any()); + verify(mBackgroundUsageAllowabilityPreference).setOnPreferenceChangeListener(any()); + verify(mOptimizedPreference).setOnPreferenceClickListener(any()); + verify(mUnrestrictedPreference).setOnPreferenceClickListener(any()); + } + + @Test + public void initPreferences_immutableMode_setDisabledAndSkipSetListeners() { + doReturn(false).when(mBatteryOptimizeUtils).isOptimizeModeMutable(); + + mBackgroundUsageController.initPreferences(); + + verify(mBackgroundUsageAllowabilityPreference).setEnabled(false); + verify(mOptimizedPreference).setEnabled(false); + verify(mUnrestrictedPreference).setEnabled(false); + verify(mBackgroundUsageAllowabilityPreference, never()).setOnPreferenceClickListener(any()); + verify(mBackgroundUsageAllowabilityPreference, never()) + .setOnPreferenceChangeListener(any()); + verify(mOptimizedPreference, never()).setOnPreferenceClickListener(any()); + verify(mUnrestrictedPreference, never()).setOnPreferenceClickListener(any()); + } + + @Test + public void updatePreferences_setIntoUnrestrictedMode_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_UNRESTRICTED; + + mBackgroundUsageController.updatePreferences(mTestMode); + + verifyPreferences(mTestMode); + } + + @Test + public void updatePreferences_setIntoOptimizedMode_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_OPTIMIZED; + + mBackgroundUsageController.updatePreferences(mTestMode); + + verifyPreferences(mTestMode); + } + + @Test + public void updatePreferences_setIntoRestrictedMode_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_RESTRICTED; + + mBackgroundUsageController.updatePreferences(mTestMode); + + verifyPreferences(mTestMode); + } + + @Test + public void handleBatteryOptimizeModeUpdated_modeChange_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_RESTRICTED; + + mBackgroundUsageController.handleBatteryOptimizeModeUpdated( + BatteryOptimizeUtils.MODE_OPTIMIZED); + + verify(mBatteryOptimizeUtils) + .setAppUsageState( + BatteryOptimizeUtils.MODE_OPTIMIZED, + BatteryOptimizeHistoricalLogEntry.Action.APPLY); + assertThat(mTestMode).isEqualTo(BatteryOptimizeUtils.MODE_OPTIMIZED); + verifyPreferences(mBatteryOptimizeUtils.getAppOptimizationMode()); + } + + @Test + public void handleBatteryOptimizeModeUpdated_modeNotChange_setExpectedPrefStatus() { + mTestMode = BatteryOptimizeUtils.MODE_RESTRICTED; + + mBackgroundUsageController.handleBatteryOptimizeModeUpdated( + BatteryOptimizeUtils.MODE_RESTRICTED); + + verify(mBatteryOptimizeUtils, never()).setAppUsageState(anyInt(), any()); + assertThat(mTestMode).isEqualTo(BatteryOptimizeUtils.MODE_RESTRICTED); + verify(mBackgroundUsageController, never()).updatePreferences(anyInt()); + } + + private void prepareTestBatteryOptimizationUtils() { + mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(mContext, UID, PACKAGE_NAME)); + Answer setTestMode = + invocation -> { + mTestMode = invocation.getArgument(0); + return null; + }; + doAnswer(setTestMode).when(mBatteryOptimizeUtils).setAppUsageState(anyInt(), any()); + Answer getTestMode = invocation -> mTestMode; + doAnswer(getTestMode).when(mBatteryOptimizeUtils).getAppOptimizationMode(); + } + + private void verifyPreferences(int mode) { + boolean isAllowBackground = mode != BatteryOptimizeUtils.MODE_RESTRICTED; + verify(mBackgroundUsageAllowabilityPreference).setChecked(isAllowBackground); + verify(mOptimizedPreference).setEnabled(isAllowBackground); + verify(mUnrestrictedPreference).setEnabled(isAllowBackground); + verify(mOptimizedPreference).setChecked(mode == BatteryOptimizeUtils.MODE_OPTIMIZED); + verify(mUnrestrictedPreference).setChecked(mode == BatteryOptimizeUtils.MODE_UNRESTRICTED); + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/OptimizedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/OptimizedPreferenceControllerTest.java deleted file mode 100644 index 66564718d0e..00000000000 --- a/tests/robotests/src/com/android/settings/fuelgauge/OptimizedPreferenceControllerTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.fuelgauge; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.PackageManager; - -import com.android.settingslib.widget.SelectorWithWidgetPreference; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class OptimizedPreferenceControllerTest { - private static final int UID = 12345; - private static final String PACKAGE_NAME = "com.android.app"; - - private OptimizedPreferenceController mController; - private SelectorWithWidgetPreference mPreference; - private BatteryOptimizeUtils mBatteryOptimizeUtils; - - @Mock PackageManager mMockPackageManager; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - Context context = spy(RuntimeEnvironment.application); - BatteryUtils.getInstance(context).reset(); - doReturn(UID) - .when(mMockPackageManager) - .getPackageUid(PACKAGE_NAME, PackageManager.GET_META_DATA); - - mController = new OptimizedPreferenceController(context, UID, PACKAGE_NAME); - mPreference = new SelectorWithWidgetPreference(RuntimeEnvironment.application); - mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(context, UID, PACKAGE_NAME)); - mController.mBatteryOptimizeUtils = mBatteryOptimizeUtils; - } - - @Test - public void testUpdateState_invalidPackage_prefEnabled() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true); - - mController.updateState(mPreference); - - assertThat(mPreference.isEnabled()).isFalse(); - assertThat(mPreference.isChecked()).isTrue(); - } - - @Test - public void testUpdateState_isSystemOrDefaultAppAndOptimizeStates_prefChecked() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_OPTIMIZED); - - mController.updateState(mPreference); - - assertThat(mPreference.isChecked()).isTrue(); - } - - @Test - public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true); - - mController.updateState(mPreference); - - assertThat(mPreference.isChecked()).isFalse(); - assertThat(mPreference.isEnabled()).isFalse(); - } - - @Test - public void testUpdateState_isOptimizedStates_prefChecked() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_OPTIMIZED); - - mController.updateState(mPreference); - - assertThat(mPreference.isChecked()).isTrue(); - } - - @Test - public void testUpdateState_prefUnchecked() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - - mController.updateState(mPreference); - - assertThat(mPreference.isChecked()).isFalse(); - } - - @Test - public void testHandlePreferenceTreeClick_samePrefKey_verifyAction() { - mPreference.setKey(mController.KEY_OPTIMIZED_PREF); - mController.handlePreferenceTreeClick(mPreference); - - assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue(); - } - - @Test - public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() { - assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse(); - } -} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java index 90611178fdb..9f98d78541e 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java @@ -17,10 +17,10 @@ package com.android.settings.fuelgauge; import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS; -import static com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.nullable; @@ -42,16 +42,17 @@ import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; -import android.widget.CompoundButton; import androidx.fragment.app.FragmentActivity; import androidx.loader.app.LoaderManager; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.fuelgauge.batteryusage.BatteryEntry; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowEntityHeaderController; +import com.android.settings.testutils.shadow.ShadowHelpUtils; import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; @@ -59,8 +60,6 @@ import com.android.settingslib.applications.instantapps.InstantAppDataProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.LayoutPreference; -import com.android.settingslib.widget.MainSwitchPreference; -import com.android.settingslib.widget.SelectorWithWidgetPreference; import org.junit.After; import org.junit.Before; @@ -83,36 +82,33 @@ import java.util.concurrent.TimeUnit; @Config( shadows = { ShadowEntityHeaderController.class, + ShadowHelpUtils.class, com.android.settings.testutils.shadow.ShadowFragment.class, }) public class PowerBackgroundUsageDetailTest { - @Rule - public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); private static final String APP_LABEL = "app label"; private static final String SUMMARY = "summary"; private static final int ICON_ID = 123; private static final int UID = 1; - private static final String KEY_PREF_UNRESTRICTED = "unrestricted_preference"; - private static final String KEY_PREF_OPTIMIZED = "optimized_preference"; - private static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage"; + private static final String PACKAGE_NAME = "com.android.app"; + private static final String KEY_PREF_HEADER = "header_view"; + private static final String KEY_FOOTER_PREFERENCE = "app_usage_footer_preference"; + private static final String INITIATING_PACKAGE_NAME = "com.android.vending"; + private int mTestMode; private Context mContext; private PowerBackgroundUsageDetail mFragment; - private FooterPreference mFooterPreference; - private MainSwitchPreference mMainSwitchPreference; private MetricsFeatureProvider mMetricsFeatureProvider; - private SelectorWithWidgetPreference mOptimizePreference; - private SelectorWithWidgetPreference mUnrestrictedPreference; private SettingsActivity mTestActivity; + private BatteryOptimizeUtils mBatteryOptimizeUtils; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private FragmentActivity mActivity; @Mock private EntityHeaderController mEntityHeaderController; - @Mock private BatteryOptimizeUtils mBatteryOptimizeUtils; - @Mock private LayoutPreference mHeaderPreference; @Mock private ApplicationsState mState; @Mock private Bundle mBundle; @Mock private LoaderManager mLoaderManager; @@ -120,21 +116,26 @@ public class PowerBackgroundUsageDetailTest { @Mock private BatteryEntry mBatteryEntry; @Mock private PackageManager mPackageManager; @Mock private AppOpsManager mAppOpsManager; - @Mock private CompoundButton mMockSwitch; @Mock private InstallSourceInfo mInstallSourceInfo; + @Mock private LayoutPreference mLayoutPreference; + @Mock private FooterPreference mFooterPreference; @Before public void setUp() throws Exception { mContext = spy(ApplicationProvider.getApplicationContext()); - when(mContext.getPackageName()).thenReturn("foo"); + when(mContext.getPackageName()).thenReturn(PACKAGE_NAME); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo); final FakeFeatureFactory fakeFeatureFactory = FakeFeatureFactory.setupForTest(); mMetricsFeatureProvider = fakeFeatureFactory.metricsFeatureProvider; + prepareTestBatteryOptimizationUtils(); mFragment = spy(new PowerBackgroundUsageDetail()); + mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils; mFragment.mLogStringBuilder = new StringBuilder(); + doReturn(mLayoutPreference).when(mFragment).findPreference(KEY_PREF_HEADER); + doReturn(mFooterPreference).when(mFragment).findPreference(KEY_FOOTER_PREFERENCE); doReturn(mContext).when(mFragment).getContext(); doReturn(mActivity).when(mFragment).getActivity(); doReturn(SUMMARY).when(mFragment).getString(anyInt()); @@ -169,9 +170,7 @@ public class PowerBackgroundUsageDetailTest { when(mBatteryEntry.getLabel()).thenReturn(APP_LABEL); mBatteryEntry.mIconId = ICON_ID; - mFragment.mHeaderPreference = mHeaderPreference; mFragment.mState = mState; - mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils; mAppEntry.info = mock(ApplicationInfo.class); mTestActivity = spy(new SettingsActivity()); @@ -191,23 +190,12 @@ public class PowerBackgroundUsageDetailTest { .when(mActivity) .startActivityAsUser(captor.capture(), nullable(UserHandle.class)); doAnswer(callable).when(mActivity).startActivity(captor.capture()); - - mFooterPreference = spy(new FooterPreference(mContext)); - mMainSwitchPreference = spy(new MainSwitchPreference(mContext)); - mMainSwitchPreference.setKey(KEY_ALLOW_BACKGROUND_USAGE); - mOptimizePreference = spy(new SelectorWithWidgetPreference(mContext)); - mOptimizePreference.setKey(KEY_PREF_OPTIMIZED); - mUnrestrictedPreference = spy(new SelectorWithWidgetPreference(mContext)); - mUnrestrictedPreference.setKey(KEY_PREF_UNRESTRICTED); - mFragment.mFooterPreference = mFooterPreference; - mFragment.mMainSwitchPreference = mMainSwitchPreference; - mFragment.mOptimizePreference = mOptimizePreference; - mFragment.mUnrestrictedPreference = mUnrestrictedPreference; } @After public void reset() { ShadowEntityHeaderController.reset(); + ShadowHelpUtils.reset(); } @Test @@ -258,91 +246,64 @@ public class PowerBackgroundUsageDetailTest { } @Test - public void initFooter_hasCorrectString() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false); - + public void initFooter_setExpectedFooterContent() { mFragment.initFooter(); - assertThat(mFooterPreference.getTitle().toString()) - .isEqualTo("Changing how an app uses your battery can affect its performance."); + verify(mFooterPreference) + .setTitle(mContext.getString(R.string.manager_battery_usage_footer)); + verify(mFooterPreference).setLearnMoreAction(any()); + verify(mFooterPreference) + .setLearnMoreText(mContext.getString(R.string.manager_battery_usage_link_a11y)); } @Test - public void onSwitchChanged_fromUnrestrictedModeSetDisabled_becomeRestrictedMode() { - final int restrictedMode = BatteryOptimizeUtils.MODE_RESTRICTED; - final int optimizedMode = BatteryOptimizeUtils.MODE_OPTIMIZED; - mFragment.mOptimizationMode = optimizedMode; + public void onPause_optimizationModeIsChanged_logPreference() throws Exception { + mFragment.mOptimizationMode = BatteryOptimizeUtils.MODE_OPTIMIZED; + when(mBatteryOptimizeUtils.getPackageName()).thenReturn(PACKAGE_NAME); + when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn(INITIATING_PACKAGE_NAME); - mFragment.onCheckedChanged(mMockSwitch, /* isChecked= */ false); - - verify(mOptimizePreference).setEnabled(false); - verify(mUnrestrictedPreference).setEnabled(false); - verify(mFragment).onRadioButtonClicked(null); - verify(mMainSwitchPreference).setChecked(false); - assertThat(mFragment.getSelectedPreference()).isEqualTo(restrictedMode); - verify(mBatteryOptimizeUtils).setAppUsageState(restrictedMode, Action.APPLY); - } - - @Test - public void onSwitchChanged_fromRestrictedModeSetEnabled_becomeOptimizedMode() { - final int restrictedMode = BatteryOptimizeUtils.MODE_RESTRICTED; - final int optimizedMode = BatteryOptimizeUtils.MODE_OPTIMIZED; - mFragment.mOptimizationMode = restrictedMode; - - mFragment.onCheckedChanged(mMockSwitch, /* isChecked= */ true); - - verify(mOptimizePreference).setEnabled(true); - verify(mUnrestrictedPreference).setEnabled(true); - verify(mFragment).onRadioButtonClicked(mOptimizePreference); - verify(mMainSwitchPreference).setChecked(true); - verify(mOptimizePreference).setChecked(true); - assertThat(mFragment.getSelectedPreference()).isEqualTo(optimizedMode); - verify(mBatteryOptimizeUtils).setAppUsageState(optimizedMode, Action.APPLY); - } - - @Test - public void onPause_optimizationModeChanged_logPreference() throws Exception { - final String packageName = "testPackageName"; - final int restrictedMode = BatteryOptimizeUtils.MODE_RESTRICTED; - final int optimizedMode = BatteryOptimizeUtils.MODE_OPTIMIZED; - mFragment.mOptimizationMode = restrictedMode; - when(mBatteryOptimizeUtils.getPackageName()).thenReturn(packageName); - when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending"); - - mFragment.onCheckedChanged(mMockSwitch, /* isChecked= */ true); - verify(mBatteryOptimizeUtils).setAppUsageState(optimizedMode, Action.APPLY); - when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(optimizedMode); + mTestMode = BatteryOptimizeUtils.MODE_UNRESTRICTED; + assertThat(mBatteryOptimizeUtils.getAppOptimizationMode()) + .isEqualTo(BatteryOptimizeUtils.MODE_UNRESTRICTED); mFragment.onPause(); TimeUnit.SECONDS.sleep(1); verify(mMetricsFeatureProvider) .action( SettingsEnums.LEAVE_POWER_USAGE_MANAGE_BACKGROUND, - SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED, + SettingsEnums.ACTION_APP_BATTERY_USAGE_UNRESTRICTED, SettingsEnums.FUELGAUGE_POWER_USAGE_MANAGE_BACKGROUND, - packageName, + PACKAGE_NAME, /* consumed battery */ 0); } @Test public void onPause_optimizationModeIsNotChanged_notInvokeLogging() throws Exception { - final String packageName = "testPackageName"; - final int restrictedMode = BatteryOptimizeUtils.MODE_RESTRICTED; - final int optimizedMode = BatteryOptimizeUtils.MODE_OPTIMIZED; - mFragment.mOptimizationMode = restrictedMode; - when(mBatteryOptimizeUtils.getPackageName()).thenReturn(packageName); - when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending"); + mFragment.mOptimizationMode = BatteryOptimizeUtils.MODE_OPTIMIZED; + when(mBatteryOptimizeUtils.getPackageName()).thenReturn(PACKAGE_NAME); + when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn(INITIATING_PACKAGE_NAME); - mFragment.onCheckedChanged(mMockSwitch, /* isChecked= */ true); - verify(mBatteryOptimizeUtils).setAppUsageState(optimizedMode, Action.APPLY); - when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(optimizedMode); - mFragment.onCheckedChanged(mMockSwitch, /* isChecked= */ false); - verify(mBatteryOptimizeUtils).setAppUsageState(restrictedMode, Action.APPLY); - when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(restrictedMode); + mTestMode = BatteryOptimizeUtils.MODE_UNRESTRICTED; + assertThat(mBatteryOptimizeUtils.getAppOptimizationMode()) + .isEqualTo(BatteryOptimizeUtils.MODE_UNRESTRICTED); + mTestMode = BatteryOptimizeUtils.MODE_OPTIMIZED; + assertThat(mBatteryOptimizeUtils.getAppOptimizationMode()) + .isEqualTo(BatteryOptimizeUtils.MODE_OPTIMIZED); mFragment.onPause(); TimeUnit.SECONDS.sleep(1); verifyNoInteractions(mMetricsFeatureProvider); } + + private void prepareTestBatteryOptimizationUtils() { + mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(mContext, UID, PACKAGE_NAME)); + Answer setTestMode = + invocation -> { + mTestMode = invocation.getArgument(0); + return null; + }; + doAnswer(setTestMode).when(mBatteryOptimizeUtils).setAppUsageState(anyInt(), any()); + Answer getTestMode = invocation -> mTestMode; + doAnswer(getTestMode).when(mBatteryOptimizeUtils).getAppOptimizationMode(); + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/UnrestrictedPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/UnrestrictedPreferenceControllerTest.java deleted file mode 100644 index 0c6f7da2109..00000000000 --- a/tests/robotests/src/com/android/settings/fuelgauge/UnrestrictedPreferenceControllerTest.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.fuelgauge; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.PackageManager; - -import com.android.settingslib.widget.SelectorWithWidgetPreference; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class UnrestrictedPreferenceControllerTest { - private static final int UID = 12345; - private static final String PACKAGE_NAME = "com.android.app"; - - private UnrestrictedPreferenceController mController; - private SelectorWithWidgetPreference mPreference; - private BatteryOptimizeUtils mBatteryOptimizeUtils; - - @Mock PackageManager mMockPackageManager; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - Context context = spy(RuntimeEnvironment.application); - BatteryUtils.getInstance(context).reset(); - doReturn(UID) - .when(mMockPackageManager) - .getPackageUid(PACKAGE_NAME, PackageManager.GET_META_DATA); - - mController = new UnrestrictedPreferenceController(context, UID, PACKAGE_NAME); - mPreference = new SelectorWithWidgetPreference(RuntimeEnvironment.application); - mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(context, UID, PACKAGE_NAME)); - mController.mBatteryOptimizeUtils = mBatteryOptimizeUtils; - } - - @Test - public void testUpdateState_isValidPackage_prefEnabled() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false); - - mController.updateState(mPreference); - - assertThat(mBatteryOptimizeUtils.isOptimizeModeMutable()).isTrue(); - assertThat(mPreference.isEnabled()).isTrue(); - } - - @Test - public void testUpdateState_invalidPackage_prefDisabled() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false); - - mController.updateState(mPreference); - - assertThat(mBatteryOptimizeUtils.isOptimizeModeMutable()).isFalse(); - assertThat(mPreference.isEnabled()).isFalse(); - } - - @Test - public void testUpdateState_isSystemOrDefaultAppAndUnrestrictedStates_prefChecked() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_UNRESTRICTED); - - mController.updateState(mPreference); - - assertThat(mPreference.isChecked()).isTrue(); - } - - @Test - public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() { - when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false); - when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_OPTIMIZED); - - mController.updateState(mPreference); - - assertThat(mPreference.isEnabled()).isFalse(); - assertThat(mPreference.isChecked()).isFalse(); - } - - @Test - public void testUpdateState_isUnrestrictedStates_prefChecked() { - when(mBatteryOptimizeUtils.isOptimizeModeMutable()).thenReturn(true); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_UNRESTRICTED); - - mController.updateState(mPreference); - - assertThat(mPreference.isEnabled()).isTrue(); - assertThat(mPreference.isChecked()).isTrue(); - } - - @Test - public void testUpdateState_prefUnchecked() { - when(mBatteryOptimizeUtils.isOptimizeModeMutable()).thenReturn(true); - when(mBatteryOptimizeUtils.getAppOptimizationMode()) - .thenReturn(BatteryOptimizeUtils.MODE_OPTIMIZED); - - mController.updateState(mPreference); - - assertThat(mPreference.isEnabled()).isTrue(); - assertThat(mPreference.isChecked()).isFalse(); - } - - @Test - public void testHandlePreferenceTreeClick_samePrefKey_verifyAction() { - mPreference.setKey(mController.KEY_UNRESTRICTED_PREF); - mController.handlePreferenceTreeClick(mPreference); - - assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue(); - } - - @Test - public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() { - assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse(); - } -}