Merge changes Iced0fa59,Ic354ac91,I0b4cb6ca,I9c1d3761 into sc-dev
* changes: Add footer to app usage page Update app usage page with 3 radio button control Add 3 controller for app usage page radio buttons Add utils class for app usage operation
This commit is contained in:
@@ -30,6 +30,30 @@
|
|||||||
android:key="action_buttons"
|
android:key="action_buttons"
|
||||||
android:order="-9999"/>
|
android:order="-9999"/>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="@string/battery_detail_manage_title"
|
||||||
|
settings:allowDividerAbove="true">
|
||||||
|
|
||||||
|
<com.android.settingslib.widget.RadioButtonPreference
|
||||||
|
android:key="unrestricted_pref"
|
||||||
|
android:summary="@string/manager_battery_usage_unrestricted_summary"
|
||||||
|
android:title="@string/manager_battery_usage_unrestricted_title"
|
||||||
|
settings:controller="com.android.settings.fuelgauge.UnrestrictedPreferenceController"/>
|
||||||
|
|
||||||
|
<com.android.settingslib.widget.RadioButtonPreference
|
||||||
|
android:key="optimized_pref"
|
||||||
|
android:summary="@string/manager_battery_usage_optimized_summary"
|
||||||
|
android:title="@string/manager_battery_usage_optimized_title"
|
||||||
|
settings:controller="com.android.settings.fuelgauge.OptimizedPreferenceController"/>
|
||||||
|
|
||||||
|
<com.android.settingslib.widget.RadioButtonPreference
|
||||||
|
android:key="restricted_pref"
|
||||||
|
android:summary="@string/manager_battery_usage_restricted_summary"
|
||||||
|
android:title="@string/restricted_true_label"
|
||||||
|
settings:controller="com.android.settings.fuelgauge.RestrictedPreferenceController"/>
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/battery_detail_manage_title"
|
android:title="@string/battery_detail_manage_title"
|
||||||
settings:allowDividerAbove="true">
|
settings:allowDividerAbove="true">
|
||||||
@@ -63,4 +87,11 @@
|
|||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<com.android.settingslib.widget.FooterPreference
|
||||||
|
android:order="100"
|
||||||
|
android:key="app_usage_footer_preference"
|
||||||
|
android:title="@string/manager_battery_usage_footer"
|
||||||
|
android:selectable="true"
|
||||||
|
settings:searchable="false"/>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
@@ -25,6 +25,7 @@ import android.content.Intent;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.text.Html;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -48,6 +49,7 @@ import com.android.settingslib.applications.ApplicationsState;
|
|||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
import com.android.settingslib.utils.StringUtil;
|
import com.android.settingslib.utils.StringUtil;
|
||||||
import com.android.settingslib.widget.LayoutPreference;
|
import com.android.settingslib.widget.LayoutPreference;
|
||||||
|
import com.android.settingslib.widget.RadioButtonPreference;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -60,7 +62,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
||||||
ButtonActionDialogFragment.AppButtonsDialogListener,
|
ButtonActionDialogFragment.AppButtonsDialogListener,
|
||||||
BatteryTipPreferenceController.BatteryTipListener {
|
BatteryTipPreferenceController.BatteryTipListener, RadioButtonPreference.OnClickListener {
|
||||||
|
|
||||||
public static final String TAG = "AdvancedPowerDetail";
|
public static final String TAG = "AdvancedPowerDetail";
|
||||||
public static final String EXTRA_UID = "extra_uid";
|
public static final String EXTRA_UID = "extra_uid";
|
||||||
@@ -75,6 +77,10 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
private static final String KEY_PREF_FOREGROUND = "app_usage_foreground";
|
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_BACKGROUND = "app_usage_background";
|
||||||
private static final String KEY_PREF_HEADER = "header_view";
|
private static final String KEY_PREF_HEADER = "header_view";
|
||||||
|
private static final String KEY_PREF_UNRESTRICTED = "unrestricted_pref";
|
||||||
|
private static final String KEY_PREF_OPTIMIZED = "optimized_pref";
|
||||||
|
private static final String KEY_PREF_RESTRICTED = "restricted_pref";
|
||||||
|
private static final String KEY_FOOTER_PREFERENCE = "app_usage_footer_preference";
|
||||||
|
|
||||||
private static final int REQUEST_UNINSTALL = 0;
|
private static final int REQUEST_UNINSTALL = 0;
|
||||||
private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1;
|
private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1;
|
||||||
@@ -87,13 +93,26 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
ApplicationsState.AppEntry mAppEntry;
|
ApplicationsState.AppEntry mAppEntry;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
BatteryUtils mBatteryUtils;
|
BatteryUtils mBatteryUtils;
|
||||||
|
@VisibleForTesting
|
||||||
|
BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Preference mForegroundPreference;
|
Preference mForegroundPreference;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Preference mBackgroundPreference;
|
Preference mBackgroundPreference;
|
||||||
|
@VisibleForTesting
|
||||||
|
Preference mFooterPreference;
|
||||||
|
@VisibleForTesting
|
||||||
|
RadioButtonPreference mRestrictedPreference;
|
||||||
|
@VisibleForTesting
|
||||||
|
RadioButtonPreference mOptimizePreference;
|
||||||
|
@VisibleForTesting
|
||||||
|
RadioButtonPreference mUnrestrictedPreference;
|
||||||
private AppButtonsPreferenceController mAppButtonsPreferenceController;
|
private AppButtonsPreferenceController mAppButtonsPreferenceController;
|
||||||
private BackgroundActivityPreferenceController mBackgroundActivityPreferenceController;
|
private BackgroundActivityPreferenceController mBackgroundActivityPreferenceController;
|
||||||
|
private UnrestrictedPreferenceController mUnrestrictedPreferenceController;
|
||||||
|
private OptimizedPreferenceController mOptimizedPreferenceController;
|
||||||
|
private RestrictedPreferenceController mRestrictedPreferenceController;
|
||||||
|
|
||||||
private String mPackageName;
|
private String mPackageName;
|
||||||
|
|
||||||
@@ -174,8 +193,19 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
mPackageName = getArguments().getString(EXTRA_PACKAGE_NAME);
|
mPackageName = getArguments().getString(EXTRA_PACKAGE_NAME);
|
||||||
mForegroundPreference = findPreference(KEY_PREF_FOREGROUND);
|
mForegroundPreference = findPreference(KEY_PREF_FOREGROUND);
|
||||||
mBackgroundPreference = findPreference(KEY_PREF_BACKGROUND);
|
mBackgroundPreference = findPreference(KEY_PREF_BACKGROUND);
|
||||||
|
mFooterPreference = findPreference(KEY_FOOTER_PREFERENCE);
|
||||||
mHeaderPreference = (LayoutPreference) findPreference(KEY_PREF_HEADER);
|
mHeaderPreference = (LayoutPreference) findPreference(KEY_PREF_HEADER);
|
||||||
|
|
||||||
|
mUnrestrictedPreference = findPreference(KEY_PREF_UNRESTRICTED);
|
||||||
|
mOptimizePreference = findPreference(KEY_PREF_OPTIMIZED);
|
||||||
|
mRestrictedPreference = findPreference(KEY_PREF_RESTRICTED);
|
||||||
|
mUnrestrictedPreference.setOnClickListener(this);
|
||||||
|
mOptimizePreference.setOnClickListener(this);
|
||||||
|
mRestrictedPreference.setOnClickListener(this);
|
||||||
|
|
||||||
|
mBatteryOptimizeUtils = new BatteryOptimizeUtils(
|
||||||
|
getContext(), getArguments().getInt(EXTRA_UID), mPackageName);
|
||||||
|
|
||||||
if (mPackageName != null) {
|
if (mPackageName != null) {
|
||||||
mAppEntry = mState.getEntry(mPackageName, UserHandle.myUserId());
|
mAppEntry = mState.getEntry(mPackageName, UserHandle.myUserId());
|
||||||
}
|
}
|
||||||
@@ -241,6 +271,26 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
backgroundTimeMs,
|
backgroundTimeMs,
|
||||||
/* withSeconds */ false,
|
/* withSeconds */ false,
|
||||||
/* collapseTimeUnit */ false)));
|
/* collapseTimeUnit */ false)));
|
||||||
|
|
||||||
|
final String stateString;
|
||||||
|
final String footerString;
|
||||||
|
//TODO(b/178197718) Update strings
|
||||||
|
if (!mBatteryOptimizeUtils.isValidPackageName()) {
|
||||||
|
//Present optimized only string when the package name is invalid.
|
||||||
|
stateString = context.getString(R.string.manager_battery_usage_optimized_title);
|
||||||
|
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_title);
|
||||||
|
footerString = context.getString(
|
||||||
|
R.string.manager_battery_usage_footer_limited, stateString);
|
||||||
|
} else {
|
||||||
|
//Present default string to normal app.
|
||||||
|
footerString = context.getString(R.string.manager_battery_usage_footer);
|
||||||
|
|
||||||
|
}
|
||||||
|
mFooterPreference.setTitle(Html.fromHtml(footerString, Html.FROM_HTML_MODE_COMPACT));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -274,6 +324,15 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
(SettingsActivity) getActivity(), this, getSettingsLifecycle(), packageName, mState,
|
(SettingsActivity) getActivity(), this, getSettingsLifecycle(), packageName, mState,
|
||||||
REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN);
|
REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN);
|
||||||
controllers.add(mAppButtonsPreferenceController);
|
controllers.add(mAppButtonsPreferenceController);
|
||||||
|
mUnrestrictedPreferenceController =
|
||||||
|
new UnrestrictedPreferenceController(context, uid, packageName);
|
||||||
|
mOptimizedPreferenceController =
|
||||||
|
new OptimizedPreferenceController(context, uid, packageName);
|
||||||
|
mRestrictedPreferenceController =
|
||||||
|
new RestrictedPreferenceController(context, uid, packageName);
|
||||||
|
controllers.add(mUnrestrictedPreferenceController);
|
||||||
|
controllers.add(mOptimizedPreferenceController);
|
||||||
|
controllers.add(mRestrictedPreferenceController);
|
||||||
|
|
||||||
return controllers;
|
return controllers;
|
||||||
}
|
}
|
||||||
@@ -298,4 +357,15 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
mBackgroundActivityPreferenceController.updateSummary(
|
mBackgroundActivityPreferenceController.updateSummary(
|
||||||
findPreference(mBackgroundActivityPreferenceController.getPreferenceKey()));
|
findPreference(mBackgroundActivityPreferenceController.getPreferenceKey()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRadioButtonClicked(RadioButtonPreference selected) {
|
||||||
|
updatePreferenceState(mUnrestrictedPreference, selected.getKey());
|
||||||
|
updatePreferenceState(mOptimizePreference, selected.getKey());
|
||||||
|
updatePreferenceState(mRestrictedPreference, selected.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePreferenceState(RadioButtonPreference preference, String selectedKey) {
|
||||||
|
preference.setChecked(selectedKey.equals(preference.getKey()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
121
src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
Normal file
121
src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* 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.app.AppOpsManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
|
||||||
|
|
||||||
|
/** A utility class for application usage operation. */
|
||||||
|
public class BatteryOptimizeUtils {
|
||||||
|
private static final String TAG = "BatteryOptimizeUtils";
|
||||||
|
|
||||||
|
@VisibleForTesting AppOpsManager mAppOpsManager;
|
||||||
|
@VisibleForTesting BatteryUtils mBatteryUtils;
|
||||||
|
@VisibleForTesting PowerAllowlistBackend mPowerAllowListBackend;
|
||||||
|
private final String mPackageName;
|
||||||
|
private final int mUid;
|
||||||
|
|
||||||
|
private int mMode;
|
||||||
|
private boolean mAllowListed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage type of application.
|
||||||
|
*/
|
||||||
|
public enum AppUsageState {
|
||||||
|
UNKNOWN,
|
||||||
|
RESTRICTED,
|
||||||
|
UNRESTRICTED,
|
||||||
|
OPTIMIZED,
|
||||||
|
}
|
||||||
|
|
||||||
|
public BatteryOptimizeUtils(Context context, int uid, String packageName) {
|
||||||
|
mUid = uid;
|
||||||
|
mPackageName = packageName;
|
||||||
|
mAppOpsManager = context.getSystemService(AppOpsManager.class);
|
||||||
|
mBatteryUtils = BatteryUtils.getInstance(context);
|
||||||
|
mPowerAllowListBackend = PowerAllowlistBackend.getInstance(context);
|
||||||
|
mMode = mAppOpsManager
|
||||||
|
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mPackageName);
|
||||||
|
mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppUsageState getAppUsageState() {
|
||||||
|
refreshState();
|
||||||
|
if (!mAllowListed && mMode == AppOpsManager.MODE_IGNORED) {
|
||||||
|
return AppUsageState.RESTRICTED;
|
||||||
|
} else if (mAllowListed && mMode == AppOpsManager.MODE_ALLOWED) {
|
||||||
|
return AppUsageState.UNRESTRICTED;
|
||||||
|
} else if (!mAllowListed && mMode == AppOpsManager.MODE_ALLOWED) {
|
||||||
|
return AppUsageState.OPTIMIZED;
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "get unknown app usage state.");
|
||||||
|
return AppUsageState.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppUsageState(AppUsageState state) {
|
||||||
|
switch (state) {
|
||||||
|
case RESTRICTED:
|
||||||
|
mBatteryUtils.setForceAppStandby(mUid, mPackageName, AppOpsManager.MODE_IGNORED);
|
||||||
|
mPowerAllowListBackend.removeApp(mPackageName);
|
||||||
|
break;
|
||||||
|
case UNRESTRICTED:
|
||||||
|
mBatteryUtils.setForceAppStandby(mUid, mPackageName, AppOpsManager.MODE_ALLOWED);
|
||||||
|
mPowerAllowListBackend.addApp(mPackageName);
|
||||||
|
break;
|
||||||
|
case OPTIMIZED:
|
||||||
|
mBatteryUtils.setForceAppStandby(mUid, mPackageName, AppOpsManager.MODE_ALLOWED);
|
||||||
|
mPowerAllowListBackend.removeApp(mPackageName);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.d(TAG, "set unknown app usage state.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return {@code true} if package name is valid (can get an uid).
|
||||||
|
*/
|
||||||
|
public boolean isValidPackageName() {
|
||||||
|
return mBatteryUtils.getPackageUid(mPackageName) != BatteryUtils.UID_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return {@code true} if this package is system or default active app.
|
||||||
|
*/
|
||||||
|
public boolean isSystemOrDefaultApp() {
|
||||||
|
mPowerAllowListBackend.refreshList();
|
||||||
|
|
||||||
|
return mPowerAllowListBackend.isSysAllowlisted(mPackageName)
|
||||||
|
|| mPowerAllowListBackend.isDefaultActiveApp(mPackageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshState() {
|
||||||
|
mPowerAllowListBackend.refreshList();
|
||||||
|
mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName);
|
||||||
|
mMode = mAppOpsManager
|
||||||
|
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mPackageName);
|
||||||
|
Log.d(TAG, String.format("refresh %s state, allowlisted = %s, mode = %d",
|
||||||
|
mPackageName,
|
||||||
|
mAllowListed,
|
||||||
|
mMode));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* 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.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState.OPTIMIZED;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.widget.RadioButtonPreference;
|
||||||
|
|
||||||
|
public class OptimizedPreferenceController extends AbstractPreferenceController
|
||||||
|
implements PreferenceControllerMixin {
|
||||||
|
|
||||||
|
private static final String TAG = "OPTIMIZED_PREF";
|
||||||
|
|
||||||
|
@VisibleForTesting String KEY_OPTIMIZED_PREF = "optimized_pref";
|
||||||
|
@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) {
|
||||||
|
if (!mBatteryOptimizeUtils.isValidPackageName()) {
|
||||||
|
Log.d(TAG, "invalid package name, optimized states only");
|
||||||
|
preference.setEnabled(true);
|
||||||
|
((RadioButtonPreference) preference).setChecked(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) {
|
||||||
|
Log.d(TAG, "is system or default app, disable pref");
|
||||||
|
((RadioButtonPreference) preference).setChecked(false);
|
||||||
|
preference.setEnabled(false);
|
||||||
|
} else if (mBatteryOptimizeUtils.getAppUsageState() == OPTIMIZED) {
|
||||||
|
Log.d(TAG, "is optimized states");
|
||||||
|
((RadioButtonPreference) preference).setChecked(true);
|
||||||
|
} else {
|
||||||
|
((RadioButtonPreference) preference).setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return KEY_OPTIMIZED_PREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||||
|
if (!KEY_OPTIMIZED_PREF.equals(preference.getKey())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBatteryOptimizeUtils.setAppUsageState(OPTIMIZED);
|
||||||
|
Log.d(TAG, "Set optimized");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* 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.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState.RESTRICTED;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.widget.RadioButtonPreference;
|
||||||
|
|
||||||
|
public class RestrictedPreferenceController extends AbstractPreferenceController
|
||||||
|
implements PreferenceControllerMixin {
|
||||||
|
|
||||||
|
private static final String TAG = "RESTRICTED_PREF";
|
||||||
|
|
||||||
|
@VisibleForTesting String KEY_RESTRICTED_PREF = "restricted_pref";
|
||||||
|
@VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
|
public RestrictedPreferenceController(Context context, int uid, String packageName) {
|
||||||
|
super(context);
|
||||||
|
mBatteryOptimizeUtils = new BatteryOptimizeUtils(context, uid, packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(Preference preference) {
|
||||||
|
|
||||||
|
if (!mBatteryOptimizeUtils.isValidPackageName()) {
|
||||||
|
Log.d(TAG, "invalid package name, disable pref");
|
||||||
|
preference.setEnabled(false);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
preference.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) {
|
||||||
|
Log.d(TAG, "is system or default app, disable pref");
|
||||||
|
((RadioButtonPreference) preference).setChecked(false);
|
||||||
|
preference.setEnabled(false);
|
||||||
|
} else if (mBatteryOptimizeUtils.getAppUsageState() == RESTRICTED) {
|
||||||
|
Log.d(TAG, "is restricted states");
|
||||||
|
((RadioButtonPreference) preference).setChecked(true);
|
||||||
|
} else {
|
||||||
|
((RadioButtonPreference) preference).setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return KEY_RESTRICTED_PREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||||
|
if (!KEY_RESTRICTED_PREF.equals(preference.getKey())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBatteryOptimizeUtils.setAppUsageState(RESTRICTED);
|
||||||
|
Log.d(TAG, "Set restricted");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState.UNRESTRICTED;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.widget.RadioButtonPreference;
|
||||||
|
|
||||||
|
public class UnrestrictedPreferenceController extends AbstractPreferenceController
|
||||||
|
implements PreferenceControllerMixin {
|
||||||
|
|
||||||
|
private static final String TAG = "UNRESTRICTED_PREF";
|
||||||
|
|
||||||
|
@VisibleForTesting String KEY_UNRESTRICTED_PREF = "unrestricted_pref";
|
||||||
|
@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) {
|
||||||
|
|
||||||
|
if (!mBatteryOptimizeUtils.isValidPackageName()) {
|
||||||
|
Log.d(TAG, "invalid package name, disable pref");
|
||||||
|
preference.setEnabled(false);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
preference.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) {
|
||||||
|
Log.d(TAG, "is system or default app, unrestricted states only");
|
||||||
|
((RadioButtonPreference) preference).setChecked(true);
|
||||||
|
} else if (mBatteryOptimizeUtils.getAppUsageState() == UNRESTRICTED) {
|
||||||
|
Log.d(TAG, "is unrestricted states");
|
||||||
|
((RadioButtonPreference) preference).setChecked(true);
|
||||||
|
} else {
|
||||||
|
((RadioButtonPreference) preference).setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return KEY_UNRESTRICTED_PREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||||
|
if (!KEY_UNRESTRICTED_PREF.equals(preference.getKey())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBatteryOptimizeUtils.setAppUsageState(UNRESTRICTED);
|
||||||
|
Log.d(TAG, "Set unrestricted");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@@ -23,6 +23,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.ArgumentMatchers.nullable;
|
import static org.mockito.ArgumentMatchers.nullable;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
@@ -58,6 +59,7 @@ import com.android.settingslib.applications.ApplicationsState;
|
|||||||
import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
|
import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
import com.android.settingslib.widget.LayoutPreference;
|
import com.android.settingslib.widget.LayoutPreference;
|
||||||
|
import com.android.settingslib.widget.RadioButtonPreference;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -96,6 +98,9 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
private static final long PROCSTATE_TOP_TIME_US = PROCSTATE_TOP_TIME_MS * 1000;
|
private static final long PROCSTATE_TOP_TIME_US = PROCSTATE_TOP_TIME_MS * 1000;
|
||||||
private static final long PHONE_FOREGROUND_TIME_MS = 250 * 1000;
|
private static final long PHONE_FOREGROUND_TIME_MS = 250 * 1000;
|
||||||
private static final long PHONE_BACKGROUND_TIME_MS = 0;
|
private static final long PHONE_BACKGROUND_TIME_MS = 0;
|
||||||
|
private static final String KEY_PREF_UNRESTRICTED = "unrestricted_pref";
|
||||||
|
private static final String KEY_PREF_OPTIMIZED = "optimized_pref";
|
||||||
|
private static final String KEY_PREF_RESTRICTED = "restricted_pref";
|
||||||
|
|
||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
private FragmentActivity mActivity;
|
private FragmentActivity mActivity;
|
||||||
@@ -121,9 +126,15 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
private BatteryStats.Timer mForegroundActivityTimer;
|
private BatteryStats.Timer mForegroundActivityTimer;
|
||||||
@Mock
|
@Mock
|
||||||
private BatteryUtils mBatteryUtils;
|
private BatteryUtils mBatteryUtils;
|
||||||
|
@Mock
|
||||||
|
private BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private Preference mForegroundPreference;
|
private Preference mForegroundPreference;
|
||||||
private Preference mBackgroundPreference;
|
private Preference mBackgroundPreference;
|
||||||
|
private Preference mFooterPreference;
|
||||||
|
private RadioButtonPreference mRestrictedPreference;
|
||||||
|
private RadioButtonPreference mOptimizePreference;
|
||||||
|
private RadioButtonPreference mUnrestrictedPreference;
|
||||||
private AdvancedPowerUsageDetail mFragment;
|
private AdvancedPowerUsageDetail mFragment;
|
||||||
private SettingsActivity mTestActivity;
|
private SettingsActivity mTestActivity;
|
||||||
|
|
||||||
@@ -170,6 +181,7 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
mFragment.mHeaderPreference = mHeaderPreference;
|
mFragment.mHeaderPreference = mHeaderPreference;
|
||||||
mFragment.mState = mState;
|
mFragment.mState = mState;
|
||||||
mFragment.mBatteryUtils = new BatteryUtils(RuntimeEnvironment.application);
|
mFragment.mBatteryUtils = new BatteryUtils(RuntimeEnvironment.application);
|
||||||
|
mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
|
||||||
mAppEntry.info = mock(ApplicationInfo.class);
|
mAppEntry.info = mock(ApplicationInfo.class);
|
||||||
|
|
||||||
mTestActivity = spy(new SettingsActivity());
|
mTestActivity = spy(new SettingsActivity());
|
||||||
@@ -194,8 +206,16 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
|
|
||||||
mForegroundPreference = new Preference(mContext);
|
mForegroundPreference = new Preference(mContext);
|
||||||
mBackgroundPreference = new Preference(mContext);
|
mBackgroundPreference = new Preference(mContext);
|
||||||
|
mFooterPreference = new Preference(mContext);
|
||||||
|
mRestrictedPreference = new RadioButtonPreference(mContext);
|
||||||
|
mOptimizePreference = new RadioButtonPreference(mContext);
|
||||||
|
mUnrestrictedPreference = new RadioButtonPreference(mContext);
|
||||||
mFragment.mForegroundPreference = mForegroundPreference;
|
mFragment.mForegroundPreference = mForegroundPreference;
|
||||||
mFragment.mBackgroundPreference = mBackgroundPreference;
|
mFragment.mBackgroundPreference = mBackgroundPreference;
|
||||||
|
mFragment.mFooterPreference = mFooterPreference;
|
||||||
|
mFragment.mRestrictedPreference = mRestrictedPreference;
|
||||||
|
mFragment.mOptimizePreference = mOptimizePreference;
|
||||||
|
mFragment.mUnrestrictedPreference = mUnrestrictedPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@@ -352,4 +372,48 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
assertThat(mForegroundPreference.getSummary().toString()).isEqualTo("Used for 0 min");
|
assertThat(mForegroundPreference.getSummary().toString()).isEqualTo("Used for 0 min");
|
||||||
assertThat(mBackgroundPreference.getSummary().toString()).isEqualTo("Active for 0 min");
|
assertThat(mBackgroundPreference.getSummary().toString()).isEqualTo("Active for 0 min");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInitPreference_isValidPackageName_hasCorrectString() {
|
||||||
|
when(mBatteryOptimizeUtils.isValidPackageName()).thenReturn(false);
|
||||||
|
|
||||||
|
mFragment.initPreference();
|
||||||
|
|
||||||
|
assertThat(mFooterPreference.getTitle().toString())
|
||||||
|
.isEqualTo("This app requires Optimized battery usage.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInitPreference_isSystemOrDefaultApp_hasCorrectString() {
|
||||||
|
when(mBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
||||||
|
|
||||||
|
mFragment.initPreference();
|
||||||
|
|
||||||
|
assertThat(mFooterPreference.getTitle()
|
||||||
|
.toString()).isEqualTo("This app requires Unrestricted battery usage.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInitPreference_hasCorrectString() {
|
||||||
|
when(mBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false);
|
||||||
|
|
||||||
|
mFragment.initPreference();
|
||||||
|
|
||||||
|
assertThat(mFooterPreference.getTitle().toString())
|
||||||
|
.isEqualTo("Changing how an app uses your battery can affect its performance.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnRadioButtonClicked_clickOptimizePref_optimizePreferenceChecked() {
|
||||||
|
mOptimizePreference.setKey(KEY_PREF_OPTIMIZED);
|
||||||
|
mRestrictedPreference.setKey(KEY_PREF_RESTRICTED);
|
||||||
|
mUnrestrictedPreference.setKey(KEY_PREF_UNRESTRICTED);
|
||||||
|
mFragment.onRadioButtonClicked(mOptimizePreference);
|
||||||
|
|
||||||
|
assertThat(mOptimizePreference.isChecked()).isTrue();
|
||||||
|
assertThat(mRestrictedPreference.isChecked()).isFalse();
|
||||||
|
assertThat(mUnrestrictedPreference.isChecked()).isFalse();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* 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.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState.OPTIMIZED;
|
||||||
|
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState.RESTRICTED;
|
||||||
|
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState.UNRESTRICTED;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.AppOpsManager;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
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 BatteryOptimizeUtilsTest {
|
||||||
|
|
||||||
|
private static final int UID = 12345;
|
||||||
|
private static final String PACKAGE_NAME = "com.android.app";
|
||||||
|
|
||||||
|
@Mock BatteryUtils mockBatteryUtils;
|
||||||
|
@Mock AppOpsManager mockAppOpsManager;
|
||||||
|
@Mock PowerAllowlistBackend mockBackend;
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
|
mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(mContext, UID, PACKAGE_NAME));
|
||||||
|
mBatteryOptimizeUtils.mAppOpsManager = mockAppOpsManager;
|
||||||
|
mBatteryOptimizeUtils.mBatteryUtils = mockBatteryUtils;
|
||||||
|
mBatteryOptimizeUtils.mPowerAllowListBackend = mockBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAppUsageState_returnRestricted() {
|
||||||
|
when(mockBackend.isAllowlisted(anyString())).thenReturn(false);
|
||||||
|
when(mockAppOpsManager.checkOpNoThrow(anyInt(), anyInt(), anyString()))
|
||||||
|
.thenReturn(AppOpsManager.MODE_IGNORED);
|
||||||
|
|
||||||
|
assertThat(mBatteryOptimizeUtils.getAppUsageState()).isEqualTo(RESTRICTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAppUsageState_returnUnrestricted() {
|
||||||
|
when(mockBackend.isAllowlisted(anyString())).thenReturn(true);
|
||||||
|
when(mockAppOpsManager.checkOpNoThrow(anyInt(), anyInt(), anyString()))
|
||||||
|
.thenReturn(AppOpsManager.MODE_ALLOWED);
|
||||||
|
|
||||||
|
assertThat(mBatteryOptimizeUtils.getAppUsageState()).isEqualTo(UNRESTRICTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAppUsageState_returnOptimized() {
|
||||||
|
when(mockBackend.isAllowlisted(anyString())).thenReturn(false);
|
||||||
|
when(mockAppOpsManager.checkOpNoThrow(anyInt(), anyInt(), anyString()))
|
||||||
|
.thenReturn(AppOpsManager.MODE_ALLOWED);
|
||||||
|
|
||||||
|
assertThat(mBatteryOptimizeUtils.getAppUsageState()).isEqualTo(OPTIMIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsSystemOrDefaultApp_isSystemOrDefaultApp_returnTrue() {
|
||||||
|
when(mockBackend.isAllowlisted(anyString())).thenReturn(true);
|
||||||
|
when(mockBackend.isDefaultActiveApp(anyString())).thenReturn(true);
|
||||||
|
|
||||||
|
assertThat(mBatteryOptimizeUtils.isSystemOrDefaultApp()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsSystemOrDefaultApp_notSystemOrDefaultApp_returnFalse() {
|
||||||
|
assertThat(mBatteryOptimizeUtils.isSystemOrDefaultApp()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsValidPackageName_InvalidPackageName_returnFalse() {
|
||||||
|
final BatteryOptimizeUtils testBatteryOptimizeUtils =
|
||||||
|
new BatteryOptimizeUtils(mContext, UID, null);
|
||||||
|
|
||||||
|
assertThat(testBatteryOptimizeUtils.isValidPackageName()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsValidPackageName_validPackageName_returnTrue() {
|
||||||
|
assertThat(mBatteryOptimizeUtils.isValidPackageName()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetAppUsageState_Restricted_verifyAction() {
|
||||||
|
mBatteryOptimizeUtils.setAppUsageState(RESTRICTED);
|
||||||
|
|
||||||
|
verify(mockBatteryUtils).setForceAppStandby(UID,
|
||||||
|
PACKAGE_NAME, AppOpsManager.MODE_IGNORED);
|
||||||
|
verify(mockBackend).removeApp(PACKAGE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetAppUsageState_Unrestricted_verifyAction() {
|
||||||
|
mBatteryOptimizeUtils.setAppUsageState(UNRESTRICTED);
|
||||||
|
|
||||||
|
verify(mockBatteryUtils).setForceAppStandby(UID,
|
||||||
|
PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
|
||||||
|
verify(mockBackend).addApp(PACKAGE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetAppUsageState_Optimized_verifyAction() {
|
||||||
|
mBatteryOptimizeUtils.setAppUsageState(OPTIMIZED);
|
||||||
|
|
||||||
|
verify(mockBatteryUtils).setForceAppStandby(UID,
|
||||||
|
PACKAGE_NAME, AppOpsManager.MODE_ALLOWED);
|
||||||
|
verify(mockBackend).removeApp(PACKAGE_NAME);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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.verify;
|
||||||
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import com.android.settingslib.widget.RadioButtonPreference;
|
||||||
|
|
||||||
|
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 RadioButtonPreference mPreference;
|
||||||
|
|
||||||
|
@Mock BatteryOptimizeUtils mockBatteryOptimizeUtils;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
mController = new OptimizedPreferenceController(
|
||||||
|
RuntimeEnvironment.application, UID, PACKAGE_NAME);
|
||||||
|
mPreference = new RadioButtonPreference(RuntimeEnvironment.application);
|
||||||
|
mController.mBatteryOptimizeUtils = mockBatteryOptimizeUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_invalidPackage_prefEnabled() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(false);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isEnabled()).isTrue();
|
||||||
|
assertThat(mPreference.isChecked()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isChecked()).isFalse();
|
||||||
|
assertThat(mPreference.isEnabled()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_isOptimizedStates_prefChecked() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
when(mockBatteryOptimizeUtils.getAppUsageState()).thenReturn(
|
||||||
|
BatteryOptimizeUtils.AppUsageState.OPTIMIZED);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isChecked()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_prefUnchecked() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isChecked()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandlePreferenceTreeClick_samePrefKey_verifyAction() {
|
||||||
|
mPreference.setKey(mController.KEY_OPTIMIZED_PREF);
|
||||||
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
|
|
||||||
|
verify(mockBatteryOptimizeUtils).setAppUsageState(
|
||||||
|
BatteryOptimizeUtils.AppUsageState.OPTIMIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() {
|
||||||
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockBatteryOptimizeUtils);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* 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.verify;
|
||||||
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import com.android.settingslib.widget.RadioButtonPreference;
|
||||||
|
|
||||||
|
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 RestrictedPreferenceControllerTest {
|
||||||
|
private static final int UID = 12345;
|
||||||
|
private static final String PACKAGE_NAME = "com.android.app";
|
||||||
|
|
||||||
|
private RestrictedPreferenceController mController;
|
||||||
|
private RadioButtonPreference mPreference;
|
||||||
|
|
||||||
|
@Mock BatteryOptimizeUtils mockBatteryOptimizeUtils;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
mController = new RestrictedPreferenceController(
|
||||||
|
RuntimeEnvironment.application, UID, PACKAGE_NAME);
|
||||||
|
mPreference = new RadioButtonPreference(RuntimeEnvironment.application);
|
||||||
|
mController.mBatteryOptimizeUtils = mockBatteryOptimizeUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_isValidPackage_prefEnabled() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isEnabled()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_invalidPackage_prefDisabled() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(false);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isEnabled()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_isSystemOrDefaultApp_prefChecked() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isChecked()).isFalse();
|
||||||
|
assertThat(mPreference.isEnabled()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_isRestrictedStates_prefChecked() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
when(mockBatteryOptimizeUtils.getAppUsageState()).thenReturn(
|
||||||
|
BatteryOptimizeUtils.AppUsageState.RESTRICTED);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isChecked()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_prefUnchecked() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isChecked()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandlePreferenceTreeClick_samePrefKey_verifyAction() {
|
||||||
|
mPreference.setKey(mController.KEY_RESTRICTED_PREF);
|
||||||
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
|
|
||||||
|
verify(mockBatteryOptimizeUtils).setAppUsageState(
|
||||||
|
BatteryOptimizeUtils.AppUsageState.RESTRICTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() {
|
||||||
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockBatteryOptimizeUtils);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* 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.verify;
|
||||||
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import com.android.settingslib.widget.RadioButtonPreference;
|
||||||
|
|
||||||
|
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 RadioButtonPreference mPreference;
|
||||||
|
|
||||||
|
@Mock BatteryOptimizeUtils mockBatteryOptimizeUtils;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
mController = new UnrestrictedPreferenceController(
|
||||||
|
RuntimeEnvironment.application, UID, PACKAGE_NAME);
|
||||||
|
mPreference = new RadioButtonPreference(RuntimeEnvironment.application);
|
||||||
|
mController.mBatteryOptimizeUtils = mockBatteryOptimizeUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_isValidPackage_prefEnabled() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isEnabled()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_invalidPackage_prefDisabled() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(false);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isEnabled()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_isSystemOrDefaultApp_prefChecked() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isChecked()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_isUnrestrictedStates_prefChecked() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
when(mockBatteryOptimizeUtils.getAppUsageState()).thenReturn(
|
||||||
|
BatteryOptimizeUtils.AppUsageState.UNRESTRICTED);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isChecked()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateState_prefUnchecked() {
|
||||||
|
when(mockBatteryOptimizeUtils.isValidPackageName()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isChecked()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandlePreferenceTreeClick_samePrefKey_verifyAction() {
|
||||||
|
mPreference.setKey(mController.KEY_UNRESTRICTED_PREF);
|
||||||
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
|
|
||||||
|
verify(mockBatteryOptimizeUtils).setAppUsageState(
|
||||||
|
BatteryOptimizeUtils.AppUsageState.UNRESTRICTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() {
|
||||||
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockBatteryOptimizeUtils);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user