Clean up legacy "optimization mode" design.

We have two different "Optimization mode" page design in the android R to support bi-state for AOSP and tri-state for Pixel device. From android T, we always show tri-state for both AOSP and Pixel. So it's time to clean up the legacy design for bi-state.
This change doesn't include string resources cleanup, which will be
included in a separated cl.

Bug: 232037602
Test: make RunSettingsRoboTests
Change-Id: I5194201d0b11e2dcea958d49bf07ed837a386465
This commit is contained in:
Kuan Wang
2022-06-02 17:27:33 +08:00
parent d75d0609d2
commit 02b6451258
7 changed files with 19 additions and 784 deletions

View File

@@ -1,64 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto">
<com.android.settingslib.widget.LayoutPreference
android:key="header_view"
android:layout="@layout/settings_entity_header"
android:selectable="false"
android:order="-10000"/>
<com.android.settingslib.widget.ActionButtonsPreference
android:key="action_buttons"
android:order="-9999"/>
<PreferenceCategory
android:title="@string/battery_detail_manage_title">
<com.android.settingslib.RestrictedPreference
android:key="background_activity"
android:title="@string/background_activity_title"
android:selectable="true"
settings:userRestriction="no_control_apps"/>
<Preference
android:key="battery_optimization"
android:title="@string/high_power_apps"
android:summary="@string/high_power_off"
android:selectable="true"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/battery_detail_info_title">
<Preference
android:key="app_usage_foreground"
android:title="@string/battery_detail_foreground"
android:selectable="false"/>
<Preference
android:key="app_usage_background"
android:title="@string/battery_detail_background"
android:selectable="false"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -32,7 +32,6 @@ import android.util.Log;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -42,8 +41,6 @@ import com.android.settings.applications.appinfo.ButtonActionDialogFragment;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.HelpUtils;
@@ -66,7 +63,6 @@ import java.util.List;
*/
public class AdvancedPowerUsageDetail extends DashboardFragment implements
ButtonActionDialogFragment.AppButtonsDialogListener,
BatteryTipPreferenceController.BatteryTipListener,
SelectorWithWidgetPreference.OnClickListener {
public static final String TAG = "AdvancedPowerDetail";
@@ -80,8 +76,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
public static final String EXTRA_POWER_USAGE_PERCENT = "extra_power_usage_percent";
public static final String EXTRA_POWER_USAGE_AMOUNT = "extra_power_usage_amount";
private static final String KEY_PREF_FOREGROUND = "app_usage_foreground";
private static final String KEY_PREF_BACKGROUND = "app_usage_background";
private static final String KEY_PREF_HEADER = "header_view";
private static final String KEY_PREF_UNRESTRICTED = "unrestricted_pref";
private static final String KEY_PREF_OPTIMIZED = "optimized_pref";
@@ -103,10 +97,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
@VisibleForTesting
BatteryOptimizeUtils mBatteryOptimizeUtils;
@VisibleForTesting
Preference mForegroundPreference;
@VisibleForTesting
Preference mBackgroundPreference;
@VisibleForTesting
FooterPreference mFooterPreference;
@VisibleForTesting
SelectorWithWidgetPreference mRestrictedPreference;
@@ -115,15 +105,12 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
@VisibleForTesting
SelectorWithWidgetPreference mUnrestrictedPreference;
@VisibleForTesting
boolean mEnableTriState = true;
@VisibleForTesting
@BatteryOptimizeUtils.OptimizationMode
int mOptimizationMode = BatteryOptimizeUtils.MODE_UNKNOWN;
@VisibleForTesting
BackupManager mBackupManager;
private AppButtonsPreferenceController mAppButtonsPreferenceController;
private BackgroundActivityPreferenceController mBackgroundActivityPreferenceController;
// A wrapper class to carry LaunchBatteryDetailPage required arguments.
private static final class LaunchBatteryDetailPageArgs {
@@ -252,12 +239,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
super.onCreate(icicle);
final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME);
if (mEnableTriState) {
onCreateForTriState(packageName);
} else {
mForegroundPreference = findPreference(KEY_PREF_FOREGROUND);
mBackgroundPreference = findPreference(KEY_PREF_BACKGROUND);
}
onCreateForTriState(packageName);
mHeaderPreference = findPreference(KEY_PREF_HEADER);
if (packageName != null) {
@@ -270,31 +252,26 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
super.onResume();
initHeader();
if (mEnableTriState) {
mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode();
initPreferenceForTriState(getContext());
final String packageName = mBatteryOptimizeUtils.getPackageName();
FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode();
initPreferenceForTriState(getContext());
final String packageName = mBatteryOptimizeUtils.getPackageName();
FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
.action(
getContext(),
SettingsEnums.OPEN_APP_BATTERY_USAGE,
packageName);
} else {
initPreference(getContext());
}
getContext(),
SettingsEnums.OPEN_APP_BATTERY_USAGE,
packageName);
}
@Override
public void onPause() {
super.onPause();
if (mEnableTriState) {
final int selectedPreference = getSelectedPreference();
notifyBackupManager();
logMetricCategory(selectedPreference);
mBatteryOptimizeUtils.setAppUsageState(selectedPreference);
Log.d(TAG, "Leave with mode: " + selectedPreference);
}
final int selectedPreference = getSelectedPreference();
notifyBackupManager();
logMetricCategory(selectedPreference);
mBatteryOptimizeUtils.setAppUsageState(selectedPreference);
Log.d(TAG, "Leave with mode: " + selectedPreference);
}
@VisibleForTesting
@@ -333,34 +310,10 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
controller.setIsInstantApp(AppUtils.isInstant(mAppEntry.info));
}
if (mEnableTriState) {
controller.setSummary(getAppActiveTime(bundle));
}
controller.setSummary(getAppActiveTime(bundle));
controller.done(context, true /* rebindActions */);
}
@VisibleForTesting
void initPreference(Context context) {
final Bundle bundle = getArguments();
final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
mForegroundPreference.setSummary(
TextUtils.expandTemplate(getText(R.string.battery_used_for),
StringUtil.formatElapsedTime(
context,
foregroundTimeMs,
/* withSeconds */ false,
/* collapseTimeUnit */ false)));
mBackgroundPreference.setSummary(
TextUtils.expandTemplate(getText(R.string.battery_active_for),
StringUtil.formatElapsedTime(
context,
backgroundTimeMs,
/* withSeconds */ false,
/* collapseTimeUnit */ false)));
}
@VisibleForTesting
void initPreferenceForTriState(Context context) {
final String stateString;
@@ -403,7 +356,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
@Override
protected int getPreferenceScreenResId() {
return mEnableTriState ? R.xml.power_usage_detail : R.xml.power_usage_detail_legacy;
return R.xml.power_usage_detail;
}
@Override
@@ -417,17 +370,9 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
(SettingsActivity) getActivity(), this, getSettingsLifecycle(),
packageName, mState, REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN);
controllers.add(mAppButtonsPreferenceController);
if (mEnableTriState) {
controllers.add(new UnrestrictedPreferenceController(context, uid, packageName));
controllers.add(new OptimizedPreferenceController(context, uid, packageName));
controllers.add(new RestrictedPreferenceController(context, uid, packageName));
} else {
mBackgroundActivityPreferenceController = new BackgroundActivityPreferenceController(
context, this, uid, packageName);
controllers.add(mBackgroundActivityPreferenceController);
controllers.add(new BatteryOptimizationPreferenceController(
(SettingsActivity) getActivity(), this, packageName));
}
controllers.add(new UnrestrictedPreferenceController(context, uid, packageName));
controllers.add(new OptimizedPreferenceController(context, uid, packageName));
controllers.add(new RestrictedPreferenceController(context, uid, packageName));
return controllers;
}
@@ -447,12 +392,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
}
}
@Override
public void onBatteryTipHandled(BatteryTip batteryTip) {
mBackgroundActivityPreferenceController.updateSummary(
findPreference(mBackgroundActivityPreferenceController.getPreferenceKey()));
}
@Override
public void onRadioButtonClicked(SelectorWithWidgetPreference selected) {
final String selectedKey = selected.getKey();

View File

@@ -1,151 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.android.settings.fuelgauge;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.UserManager;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.fuelgauge.batterytip.AppInfo;
import com.android.settings.fuelgauge.batterytip.BatteryTipDialogFragment;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
/**
* Controller to control whether an app can run in the background
*/
public class BackgroundActivityPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin {
private static final String TAG = "BgActivityPrefContr";
@VisibleForTesting
static final String KEY_BACKGROUND_ACTIVITY = "background_activity";
private final AppOpsManager mAppOpsManager;
private final UserManager mUserManager;
private final int mUid;
@VisibleForTesting
DevicePolicyManager mDpm;
@VisibleForTesting
BatteryUtils mBatteryUtils;
private InstrumentedPreferenceFragment mFragment;
private String mTargetPackage;
private PowerAllowlistBackend mPowerAllowlistBackend;
public BackgroundActivityPreferenceController(Context context,
InstrumentedPreferenceFragment fragment, int uid, String packageName) {
this(context, fragment, uid, packageName, PowerAllowlistBackend.getInstance(context));
}
@VisibleForTesting
BackgroundActivityPreferenceController(Context context, InstrumentedPreferenceFragment fragment,
int uid, String packageName, PowerAllowlistBackend backend) {
super(context);
mPowerAllowlistBackend = backend;
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
mDpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mUid = uid;
mFragment = fragment;
mTargetPackage = packageName;
mBatteryUtils = BatteryUtils.getInstance(context);
}
@Override
public void updateState(Preference preference) {
final RestrictedPreference restrictedPreference = (RestrictedPreference) preference;
if (restrictedPreference.isDisabledByAdmin()) {
// If disabled, let RestrictedPreference handle it and do nothing here
return;
}
final int mode = mAppOpsManager
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage);
final boolean allowlisted = mPowerAllowlistBackend.isAllowlisted(mTargetPackage);
if (allowlisted || mode == AppOpsManager.MODE_ERRORED
|| Utils.isProfileOrDeviceOwner(mUserManager, mDpm, mTargetPackage)) {
preference.setEnabled(false);
} else {
preference.setEnabled(true);
}
updateSummary(preference);
}
@Override
public boolean isAvailable() {
return mTargetPackage != null;
}
@Override
public String getPreferenceKey() {
return KEY_BACKGROUND_ACTIVITY;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (KEY_BACKGROUND_ACTIVITY.equals(preference.getKey())) {
final int mode = mAppOpsManager
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage);
final boolean restricted = mode == AppOpsManager.MODE_IGNORED;
showDialog(restricted);
}
return false;
}
public void updateSummary(Preference preference) {
if (mPowerAllowlistBackend.isAllowlisted(mTargetPackage)) {
preference.setSummary(R.string.background_activity_summary_allowlisted);
return;
}
final int mode = mAppOpsManager
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage);
if (mode == AppOpsManager.MODE_ERRORED) {
preference.setSummary(R.string.background_activity_summary_disabled);
} else {
final boolean restricted = mode == AppOpsManager.MODE_IGNORED;
preference.setSummary(restricted ? R.string.restricted_true_label
: R.string.restricted_false_label);
}
}
@VisibleForTesting
void showDialog(boolean restricted) {
final AppInfo appInfo = new AppInfo.Builder()
.setUid(mUid)
.setPackageName(mTargetPackage)
.build();
BatteryTip tip = restricted
? new UnrestrictAppTip(BatteryTip.StateType.NEW, appInfo)
: new RestrictAppTip(BatteryTip.StateType.NEW, appInfo);
final BatteryTipDialogFragment dialogFragment = BatteryTipDialogFragment.newInstance(tip,
mFragment.getMetricsCategory());
dialogFragment.setTargetFragment(mFragment, 0 /* requestCode */);
dialogFragment.show(mFragment.getFragmentManager(), TAG);
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.android.settings.fuelgauge;
import android.os.Bundle;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.SettingsActivity;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
/**
* Controller that jumps to high power optimization fragment
*/
public class BatteryOptimizationPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin {
private static final String KEY_BACKGROUND_ACTIVITY = "battery_optimization";
private PowerAllowlistBackend mBackend;
private DashboardFragment mFragment;
private SettingsActivity mSettingsActivity;
private String mPackageName;
public BatteryOptimizationPreferenceController(SettingsActivity settingsActivity,
DashboardFragment fragment, String packageName) {
super(settingsActivity);
mFragment = fragment;
mSettingsActivity = settingsActivity;
mPackageName = packageName;
mBackend = PowerAllowlistBackend.getInstance(mSettingsActivity);
}
@VisibleForTesting
BatteryOptimizationPreferenceController(SettingsActivity settingsActivity,
DashboardFragment fragment, String packageName, PowerAllowlistBackend backend) {
super(settingsActivity);
mFragment = fragment;
mSettingsActivity = settingsActivity;
mPackageName = packageName;
mBackend = backend;
}
@Override
public boolean isAvailable() {
return true;
}
@Override
public void updateState(Preference preference) {
mBackend.refreshList();
final boolean isAllowlisted = mBackend.isAllowlisted(mPackageName);
preference.setSummary(isAllowlisted ? R.string.high_power_on : R.string.high_power_off);
}
@Override
public String getPreferenceKey() {
return KEY_BACKGROUND_ACTIVITY;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!KEY_BACKGROUND_ACTIVITY.equals(preference.getKey())) {
return false;
}
final Bundle args = new Bundle();
args.putString(ManageApplications.EXTRA_CLASSNAME,
Settings.HighPowerApplicationsActivity.class.getName());
new SubSettingLauncher(mSettingsActivity)
.setDestination(ManageApplications.class.getName())
.setArguments(args)
.setTitleRes(R.string.high_power_apps)
.setSourceMetricsCategory(mFragment.getMetricsCategory())
.launch();
return true;
}
}

View File

@@ -45,11 +45,9 @@ import android.os.BatteryStats;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.util.Pair;
import androidx.fragment.app.FragmentActivity;
import androidx.loader.app.LoaderManager;
import androidx.preference.Preference;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
@@ -130,8 +128,6 @@ public class AdvancedPowerUsageDetailTest {
private BackupManager mBackupManager;
private Context mContext;
private Preference mForegroundPreference;
private Preference mBackgroundPreference;
private FooterPreference mFooterPreference;
private SelectorWithWidgetPreference mRestrictedPreference;
private SelectorWithWidgetPreference mOptimizePreference;
@@ -186,7 +182,6 @@ public class AdvancedPowerUsageDetailTest {
mFragment.mHeaderPreference = mHeaderPreference;
mFragment.mState = mState;
mFragment.mEnableTriState = true;
mFragment.mBatteryUtils = new BatteryUtils(RuntimeEnvironment.application);
mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
mFragment.mBackupManager = mBackupManager;
@@ -212,14 +207,10 @@ public class AdvancedPowerUsageDetailTest {
nullable(UserHandle.class));
doAnswer(callable).when(mActivity).startActivity(captor.capture());
mForegroundPreference = new Preference(mContext);
mBackgroundPreference = new Preference(mContext);
mFooterPreference = new FooterPreference(mContext);
mRestrictedPreference = new SelectorWithWidgetPreference(mContext);
mOptimizePreference = new SelectorWithWidgetPreference(mContext);
mUnrestrictedPreference = new SelectorWithWidgetPreference(mContext);
mFragment.mForegroundPreference = mForegroundPreference;
mFragment.mBackgroundPreference = mBackgroundPreference;
mFragment.mFooterPreference = mFooterPreference;
mFragment.mRestrictedPreference = mRestrictedPreference;
mFragment.mOptimizePreference = mOptimizePreference;
@@ -236,12 +227,6 @@ public class AdvancedPowerUsageDetailTest {
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(R.xml.power_usage_detail);
}
@Test
public void testGetPreferenceScreenResId_disableTriState_returnLegacyLayout() {
mFragment.mEnableTriState = false;
assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(R.xml.power_usage_detail_legacy);
}
@Test
public void testInitHeader_NoAppEntry_BuildByBundle() {
mFragment.mAppEntry = null;
@@ -765,26 +750,6 @@ public class AdvancedPowerUsageDetailTest {
assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID);
}
@Test
public void testInitPreference_hasCorrectSummary() {
Bundle bundle = new Bundle(4);
bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, BACKGROUND_TIME_MS);
bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, FOREGROUND_TIME_MS);
bundle.putString(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_PERCENT, USAGE_PERCENT);
bundle.putInt(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_AMOUNT, POWER_MAH);
when(mFragment.getArguments()).thenReturn(bundle);
doReturn(mContext.getText(R.string.battery_used_for)).when(mFragment).getText(
R.string.battery_used_for);
doReturn(mContext.getText(R.string.battery_active_for)).when(mFragment).getText(
R.string.battery_active_for);
mFragment.initPreference(mContext);
assertThat(mForegroundPreference.getSummary().toString()).isEqualTo("Used for 0 min");
assertThat(mBackgroundPreference.getSummary().toString()).isEqualTo("Active for 0 min");
}
@Test
public void testInitPreferenceForTriState_isValidPackageName_hasCorrectString() {
when(mBatteryOptimizeUtils.isValidPackageName()).thenReturn(false);
@@ -882,16 +847,4 @@ public class AdvancedPowerUsageDetailTest {
verify(mBackupManager).dataChanged();
}
@Test
public void notifyBackupManager_triStateIsNotEnabled_notInvokeDataChanged() {
mFragment.mOptimizationMode = BatteryOptimizeUtils.MODE_RESTRICTED;
when(mBatteryOptimizeUtils.getAppOptimizationMode())
.thenReturn(BatteryOptimizeUtils.MODE_UNRESTRICTED);
mFragment.mEnableTriState = false;
mFragment.onPause();
verifyZeroInteractions(mBackupManager);
}
}

View File

@@ -1,205 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doNothing;
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 static org.mockito.Mockito.when;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.UserManager;
import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowFragment.class)
public class BackgroundActivityPreferenceControllerTest {
private static final int UID_LOW_SDK = 1234;
private static final String HIGH_SDK_PACKAGE = "com.android.package.high";
private static final String LOW_SDK_PACKAGE = "com.android.package.low";
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private PackageManager mPackageManager;
@Mock
private AppOpsManager mAppOpsManager;
@Mock
private ApplicationInfo mHighApplicationInfo;
@Mock
private ApplicationInfo mLowApplicationInfo;
@Mock
private UserManager mUserManager;
@Mock
private DevicePolicyManager mDevicePolicyManager;
@Mock
private DevicePolicyManager mDevicePolicyManagerWrapper;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AdvancedPowerUsageDetail mFragment;
@Mock
private PowerAllowlistBackend mPowerAllowlistBackend;
private BackgroundActivityPreferenceController mController;
private RestrictedPreference mPreference;
private Context mShadowContext;
private BatteryUtils mBatteryUtils;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mShadowContext = RuntimeEnvironment.application;
FakeFeatureFactory.setupForTest();
when(mContext.getApplicationContext()).thenReturn(mContext);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
mDevicePolicyManager);
when(mPackageManager.getApplicationInfo(HIGH_SDK_PACKAGE, PackageManager.GET_META_DATA))
.thenReturn(mHighApplicationInfo);
when(mPackageManager.getApplicationInfo(LOW_SDK_PACKAGE, PackageManager.GET_META_DATA))
.thenReturn(mLowApplicationInfo);
when(mPowerAllowlistBackend.isAllowlisted(LOW_SDK_PACKAGE)).thenReturn(false);
mHighApplicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
mLowApplicationInfo.targetSdkVersion = Build.VERSION_CODES.L;
mBatteryUtils = spy(new BatteryUtils(mShadowContext));
doNothing().when(mBatteryUtils).setForceAppStandby(anyInt(), anyString(), anyInt());
mPreference = spy(new RestrictedPreference(mShadowContext, null /* attrs */));
mPreference.setKey(BackgroundActivityPreferenceController.KEY_BACKGROUND_ACTIVITY);
mController = spy(new BackgroundActivityPreferenceController(
mContext, mFragment, UID_LOW_SDK, LOW_SDK_PACKAGE, mPowerAllowlistBackend));
mController.mDpm = mDevicePolicyManagerWrapper;
mController.mBatteryUtils = mBatteryUtils;
}
@Test
public void handlePreferenceTreeClick_restrictApp_showDialog() {
doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
.checkOpNoThrow(anyInt(), anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference);
verify(mController).showDialog(false /* restrict */);
}
@Test
public void handlePreferenceTreeClick_unRestrictApp_showDialog() {
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
.checkOpNoThrow(anyInt(), anyInt(), anyString());
mController.handlePreferenceTreeClick(mPreference);
verify(mController).showDialog(true /* restrict */);
}
@Test
public void updateState_noError_setEnabled() {
when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
LOW_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_ALLOWED);
mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isTrue();
verify(mController).updateSummary(mPreference);
}
@Test
public void updateState_allowlisted() {
when(mPowerAllowlistBackend.isAllowlisted(LOW_SDK_PACKAGE)).thenReturn(true);
mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isFalse();
assertThat(mPreference.getSummary()).isEqualTo(
mShadowContext.getText(R.string.background_activity_summary_allowlisted));
}
@Test
public void updateState_disabledByAdmin_doNothing() {
doReturn(true).when(mPreference).isDisabledByAdmin();
mController.updateState(mPreference);
verify(mPreference, never()).setEnabled(anyBoolean());
}
@Test
public void updateSummary_modeError_showSummaryDisabled() {
when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
LOW_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_ERRORED);
final CharSequence expectedSummary = mShadowContext.getText(
R.string.background_activity_summary_disabled);
mController.updateSummary(mPreference);
assertThat(mPreference.getSummary()).isEqualTo(expectedSummary);
}
@Test
public void updateSummary_modeDefault_showNotRestricted() {
when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
LOW_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_DEFAULT);
mController.updateSummary(mPreference);
assertThat(mPreference.getSummary()).isEqualTo("App can use battery in background");
}
@Test
public void updateSummary_modeIgnored_showRestricted() {
when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID_LOW_SDK,
LOW_SDK_PACKAGE)).thenReturn(AppOpsManager.MODE_IGNORED);
mController.updateSummary(mPreference);
assertThat(mPreference.getSummary()).isEqualTo("Restricted");
}
@Test
public void isAvailable_ReturnTrue() {
assertThat(mController.isAvailable()).isTrue();
}
}

View File

@@ -1,136 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
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 android.content.Intent;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
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 BatteryOptimizationPreferenceControllerTest {
private static final String PKG_IN_ALLOWLIST = "com.pkg.in.allowlist";
private static final String PKG_NOT_IN_ALLOWLIST = "com.pkg.not.in.allowlist";
private static final String KEY_OPTIMIZATION = "battery_optimization";
private static final String KEY_OTHER = "other";
@Mock
private SettingsActivity mSettingsActivity;
@Mock
private DashboardFragment mFragment;
@Mock
private TestPowerAllowlistBackend mBackend;
private BatteryOptimizationPreferenceController mController;
private Preference mPreference;
private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
doReturn(false).when(mBackend).isAllowlisted(PKG_NOT_IN_ALLOWLIST);
doReturn(true).when(mBackend).isAllowlisted(PKG_IN_ALLOWLIST);
mPreference = new SwitchPreference(mContext);
mController = spy(new BatteryOptimizationPreferenceController(mSettingsActivity, mFragment,
PKG_NOT_IN_ALLOWLIST, mBackend));
}
@Test
public void testHandlePreferenceTreeClick_OptimizationPreference_HandleClick() {
mPreference.setKey(KEY_OPTIMIZATION);
final boolean handled = mController.handlePreferenceTreeClick(mPreference);
assertThat(handled).isTrue();
verify(mSettingsActivity).startActivity(any(Intent.class));
}
@Test
public void testHandlePreferenceTreeClick_OtherPreference_NotHandleClick() {
mPreference.setKey(KEY_OTHER);
final boolean handled = mController.handlePreferenceTreeClick(mPreference);
assertThat(handled).isFalse();
verify(mSettingsActivity, never()).startActivity(any(Intent.class));
}
@Test
public void testUpdateState_appInAllowlist_showSummaryNotOptimized() {
BatteryOptimizationPreferenceController controller =
new BatteryOptimizationPreferenceController(mSettingsActivity, mFragment,
PKG_IN_ALLOWLIST, mBackend);
controller.updateState(mPreference);
assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(R.string.high_power_on));
}
@Test
public void testUpdateState_appNotInAllowlist_showSummaryOptimized() {
mController.updateState(mPreference);
assertThat(mPreference.getSummary()).isEqualTo(mContext.getString(R.string.high_power_off));
}
@Test
public void testUpdateState_refreshList() {
mController.updateState(mPreference);
verify(mBackend).refreshList();
}
/**
* Create this test class so we could mock it
*/
public static class TestPowerAllowlistBackend extends PowerAllowlistBackend {
public TestPowerAllowlistBackend(Context context) {
super(context);
}
@Override
public void refreshList() {
// Do nothing so we could mock it without error
}
}
}