Refactor background optimization mode in Power Usage Detail page.
[Screenshot]: before: https://screenshot.googleplex.com/6m5jYWHofY2pFov after: [App battery usage] - [normal] https://screenshot.googleplex.com/7aurWk7cHKaWds7 - [always unrestried/optimized] https://screenshot.googleplex.com/3rGAh4ccUYTKBAr [Allow Background usage] - [Restricted]: https://screenshot.googleplex.com/MPXjQe5kPWw2nhr - [Optimized]: https://screenshot.googleplex.com/6w4zTT6r34APnGc - [Unrestricted]: https://screenshot.googleplex.com/97FgvHWMrwASqYH Bug: 302063050 Bug: 306295660 Bug: 308359833 Test: manual Change-Id: I3237d015549fe26e62d6d68c13403cc2cbdf0017
This commit is contained in:
@@ -5430,6 +5430,10 @@
|
|||||||
|
|
||||||
<!-- Category title for battery background settings in power usage detail page [CHAR LIMIT=NONE] -->
|
<!-- Category title for battery background settings in power usage detail page [CHAR LIMIT=NONE] -->
|
||||||
<string name="manager_battery_usage_category_title">Manage battery usage</string>
|
<string name="manager_battery_usage_category_title">Manage battery usage</string>
|
||||||
|
<!-- Title for allow background usage [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="manager_battery_usage_allow_background_usage_title">Allow background usage</string>
|
||||||
|
<!-- Summary for allow background usage [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="manager_battery_usage_allow_background_usage_summary">Enable for real-time updates, disable to save battery</string>
|
||||||
<!-- Title for the battery unrestricted settings [CHAR_LIMIT=40] -->
|
<!-- Title for the battery unrestricted settings [CHAR_LIMIT=40] -->
|
||||||
<string name="manager_battery_usage_unrestricted_title">Unrestricted</string>
|
<string name="manager_battery_usage_unrestricted_title">Unrestricted</string>
|
||||||
<!-- Title for the battery optimized settings [CHAR_LIMIT=40] -->
|
<!-- Title for the battery optimized settings [CHAR_LIMIT=40] -->
|
||||||
|
50
res/xml/power_background_usage_detail.xml
Normal file
50
res/xml/power_background_usage_detail.xml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2023 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<PreferenceScreen
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:title="@string/manager_battery_usage_allow_background_usage_title">
|
||||||
|
|
||||||
|
<com.android.settingslib.widget.LayoutPreference
|
||||||
|
android:key="header_view"
|
||||||
|
android:layout="@layout/settings_entity_header"
|
||||||
|
android:selectable="false"/>
|
||||||
|
|
||||||
|
<com.android.settingslib.widget.MainSwitchPreference
|
||||||
|
android:key="allow_background_usage"
|
||||||
|
android:title="@string/manager_battery_usage_allow_background_usage_title"
|
||||||
|
settings:controller="com.android.settings.fuelgauge.AllowBackgroundPreferenceController"/>
|
||||||
|
|
||||||
|
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
||||||
|
android:key="optimized_preference"
|
||||||
|
android:title="@string/manager_battery_usage_optimized_title"
|
||||||
|
android:summary="@string/manager_battery_usage_optimized_summary"
|
||||||
|
settings:controller="com.android.settings.fuelgauge.OptimizedPreferenceController"/>
|
||||||
|
|
||||||
|
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
||||||
|
android:key="unrestricted_preference"
|
||||||
|
android:title="@string/manager_battery_usage_unrestricted_title"
|
||||||
|
android:summary="@string/manager_battery_usage_unrestricted_summary"
|
||||||
|
settings:controller="com.android.settings.fuelgauge.UnrestrictedPreferenceController"/>
|
||||||
|
|
||||||
|
<com.android.settingslib.widget.FooterPreference
|
||||||
|
android:key="app_usage_footer_preference"
|
||||||
|
android:title="@string/manager_battery_usage_footer"
|
||||||
|
android:selectable="false"
|
||||||
|
settings:searchable="false"/>
|
||||||
|
</PreferenceScreen>
|
@@ -50,30 +50,11 @@
|
|||||||
android:title="@string/manager_battery_usage_category_title"
|
android:title="@string/manager_battery_usage_category_title"
|
||||||
android:key="manage_battery_usage_category">
|
android:key="manage_battery_usage_category">
|
||||||
|
|
||||||
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
<com.android.settingslib.PrimarySwitchPreference
|
||||||
android:key="unrestricted_pref"
|
android:key="allow_background_usage"
|
||||||
android:summary="@string/manager_battery_usage_unrestricted_summary"
|
android:title="@string/manager_battery_usage_allow_background_usage_title"
|
||||||
android:title="@string/manager_battery_usage_unrestricted_title"
|
settings:controller="com.android.settings.fuelgauge.AllowBackgroundPreferenceController"/>
|
||||||
settings:controller="com.android.settings.fuelgauge.UnrestrictedPreferenceController"/>
|
|
||||||
|
|
||||||
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
|
||||||
android:key="optimized_pref"
|
|
||||||
android:summary="@string/manager_battery_usage_optimized_summary"
|
|
||||||
android:title="@string/manager_battery_usage_optimized_title"
|
|
||||||
settings:controller="com.android.settings.fuelgauge.OptimizedPreferenceController"/>
|
|
||||||
|
|
||||||
<com.android.settingslib.widget.SelectorWithWidgetPreference
|
|
||||||
android:key="restricted_pref"
|
|
||||||
android:summary="@string/manager_battery_usage_restricted_summary"
|
|
||||||
android:title="@string/manager_battery_usage_restricted_title"
|
|
||||||
settings:controller="com.android.settings.fuelgauge.RestrictedPreferenceController"/>
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<com.android.settingslib.widget.FooterPreference
|
|
||||||
android:key="app_usage_footer_preference"
|
|
||||||
android:title="@string/manager_battery_usage_footer"
|
|
||||||
android:selectable="false"
|
|
||||||
settings:searchable="false"/>
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
@@ -27,10 +27,13 @@ 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.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
@@ -45,14 +48,12 @@ import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry;
|
|||||||
import com.android.settings.fuelgauge.batteryusage.BatteryEntry;
|
import com.android.settings.fuelgauge.batteryusage.BatteryEntry;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.widget.EntityHeaderController;
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
import com.android.settingslib.HelpUtils;
|
import com.android.settingslib.PrimarySwitchPreference;
|
||||||
import com.android.settingslib.applications.AppUtils;
|
import com.android.settingslib.applications.AppUtils;
|
||||||
import com.android.settingslib.applications.ApplicationsState;
|
import com.android.settingslib.applications.ApplicationsState;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
import com.android.settingslib.core.instrumentation.Instrumentable;
|
import com.android.settingslib.core.instrumentation.Instrumentable;
|
||||||
import com.android.settingslib.widget.FooterPreference;
|
|
||||||
import com.android.settingslib.widget.LayoutPreference;
|
import com.android.settingslib.widget.LayoutPreference;
|
||||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -67,8 +68,8 @@ import java.util.concurrent.Executors;
|
|||||||
*/
|
*/
|
||||||
public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
||||||
ButtonActionDialogFragment.AppButtonsDialogListener,
|
ButtonActionDialogFragment.AppButtonsDialogListener,
|
||||||
SelectorWithWidgetPreference.OnClickListener {
|
Preference.OnPreferenceClickListener,
|
||||||
|
Preference.OnPreferenceChangeListener {
|
||||||
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";
|
||||||
public static final String EXTRA_PACKAGE_NAME = "extra_package_name";
|
public static final String EXTRA_PACKAGE_NAME = "extra_package_name";
|
||||||
@@ -85,19 +86,16 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
public static final String EXTRA_POWER_USAGE_AMOUNT = "extra_power_usage_amount";
|
public static final String EXTRA_POWER_USAGE_AMOUNT = "extra_power_usage_amount";
|
||||||
|
|
||||||
private static final String KEY_PREF_HEADER = "header_view";
|
private static final String KEY_PREF_HEADER = "header_view";
|
||||||
private static final String KEY_PREF_UNRESTRICTED = "unrestricted_pref";
|
private static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage";
|
||||||
private static final String KEY_PREF_OPTIMIZED = "optimized_pref";
|
|
||||||
private static final String KEY_PREF_RESTRICTED = "restricted_pref";
|
|
||||||
private static final String KEY_FOOTER_PREFERENCE = "app_usage_footer_preference";
|
|
||||||
private static final String PACKAGE_NAME_NONE = "none";
|
|
||||||
|
|
||||||
private static final String HEADER_SUMMARY_FORMAT = "%s\n(%s)";
|
|
||||||
|
|
||||||
private static final 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;
|
||||||
|
|
||||||
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
|
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
|
private AppButtonsPreferenceController mAppButtonsPreferenceController;
|
||||||
|
private PowerUsageTimeController mPowerUsageTimeController;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
LayoutPreference mHeaderPreference;
|
LayoutPreference mHeaderPreference;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -107,13 +105,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
BatteryOptimizeUtils mBatteryOptimizeUtils;
|
BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
FooterPreference mFooterPreference;
|
PrimarySwitchPreference mAllowBackgroundUsagePreference;
|
||||||
@VisibleForTesting
|
|
||||||
SelectorWithWidgetPreference mRestrictedPreference;
|
|
||||||
@VisibleForTesting
|
|
||||||
SelectorWithWidgetPreference mOptimizePreference;
|
|
||||||
@VisibleForTesting
|
|
||||||
SelectorWithWidgetPreference mUnrestrictedPreference;
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@BatteryOptimizeUtils.OptimizationMode
|
@BatteryOptimizeUtils.OptimizationMode
|
||||||
int mOptimizationMode = BatteryOptimizeUtils.MODE_UNKNOWN;
|
int mOptimizationMode = BatteryOptimizeUtils.MODE_UNKNOWN;
|
||||||
@@ -122,9 +114,6 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
StringBuilder mLogStringBuilder;
|
StringBuilder mLogStringBuilder;
|
||||||
|
|
||||||
private AppButtonsPreferenceController mAppButtonsPreferenceController;
|
|
||||||
private PowerUsageTimeController mPowerUsageTimeController;
|
|
||||||
|
|
||||||
// A wrapper class to carry LaunchBatteryDetailPage required arguments.
|
// A wrapper class to carry LaunchBatteryDetailPage required arguments.
|
||||||
private static final class LaunchBatteryDetailPageArgs {
|
private static final class LaunchBatteryDetailPageArgs {
|
||||||
private String mUsagePercent;
|
private String mUsagePercent;
|
||||||
@@ -209,7 +198,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
args.putString(EXTRA_ANOMALY_HINT_PREF_KEY, launchArgs.mAnomalyHintPrefKey);
|
args.putString(EXTRA_ANOMALY_HINT_PREF_KEY, launchArgs.mAnomalyHintPrefKey);
|
||||||
args.putString(EXTRA_ANOMALY_HINT_TEXT, launchArgs.mAnomalyHintText);
|
args.putString(EXTRA_ANOMALY_HINT_TEXT, launchArgs.mAnomalyHintText);
|
||||||
final int userId = launchArgs.mIsUserEntry ? ActivityManager.getCurrentUser()
|
final int userId = launchArgs.mIsUserEntry ? ActivityManager.getCurrentUser()
|
||||||
: UserHandle.getUserId(launchArgs.mUid);
|
: UserHandle.getUserId(launchArgs.mUid);
|
||||||
|
|
||||||
new SubSettingLauncher(context)
|
new SubSettingLauncher(context)
|
||||||
.setDestination(AdvancedPowerUsageDetail.class.getName())
|
.setDestination(AdvancedPowerUsageDetail.class.getName())
|
||||||
@@ -257,7 +246,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
|
|
||||||
final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME);
|
final String packageName = getArguments().getString(EXTRA_PACKAGE_NAME);
|
||||||
onCreateForTriState(packageName);
|
onCreateBackgroundUsageState(packageName);
|
||||||
mHeaderPreference = findPreference(KEY_PREF_HEADER);
|
mHeaderPreference = findPreference(KEY_PREF_HEADER);
|
||||||
|
|
||||||
if (packageName != null) {
|
if (packageName != null) {
|
||||||
@@ -271,10 +260,10 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
|
|
||||||
initHeader();
|
initHeader();
|
||||||
mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode();
|
mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode();
|
||||||
initPreferenceForTriState(getContext());
|
initFooter();
|
||||||
mExecutor.execute(() -> {
|
mExecutor.execute(() -> {
|
||||||
String packageName =
|
final String packageName = BatteryUtils
|
||||||
getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName());
|
.getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName());
|
||||||
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
||||||
.action(
|
.action(
|
||||||
getContext(),
|
getContext(),
|
||||||
@@ -288,11 +277,10 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
||||||
final int selectedPreference = getSelectedPreference();
|
|
||||||
|
|
||||||
notifyBackupManager();
|
notifyBackupManager();
|
||||||
mLogStringBuilder.append(", onPause mode = ").append(selectedPreference);
|
final int currentOptimizeMode = mBatteryOptimizeUtils.getAppOptimizationMode();
|
||||||
logMetricCategory(selectedPreference);
|
mLogStringBuilder.append(", onPause mode = ").append(currentOptimizeMode);
|
||||||
|
logMetricCategory(currentOptimizeMode);
|
||||||
|
|
||||||
mExecutor.execute(() -> {
|
mExecutor.execute(() -> {
|
||||||
BatteryOptimizeLogUtils.writeLog(
|
BatteryOptimizeLogUtils.writeLog(
|
||||||
@@ -302,7 +290,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
mBatteryOptimizeUtils.getPackageName(), UserHandle.myUserId()),
|
mBatteryOptimizeUtils.getPackageName(), UserHandle.myUserId()),
|
||||||
mLogStringBuilder.toString());
|
mLogStringBuilder.toString());
|
||||||
});
|
});
|
||||||
Log.d(TAG, "Leave with mode: " + selectedPreference);
|
Log.d(TAG, "Leave with mode: " + currentOptimizeMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -353,33 +341,28 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void initPreferenceForTriState(Context context) {
|
void initFooter() {
|
||||||
final String stateString;
|
final String stateString;
|
||||||
final String footerString;
|
final String detailInfoString;
|
||||||
|
final Context context = getContext();
|
||||||
|
|
||||||
if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) {
|
if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) {
|
||||||
// Present optimized only string when the package name is invalid.
|
// Present optimized only string when the package name is invalid.
|
||||||
stateString = context.getString(R.string.manager_battery_usage_optimized_only);
|
stateString = context.getString(R.string.manager_battery_usage_optimized_only);
|
||||||
footerString = context.getString(
|
detailInfoString =
|
||||||
R.string.manager_battery_usage_footer_limited, stateString);
|
context.getString(R.string.manager_battery_usage_footer_limited, stateString);
|
||||||
} else if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) {
|
} else if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) {
|
||||||
// Present unrestricted only string when the package is system or default active app.
|
// Present unrestricted only string when the package is system or default active app.
|
||||||
stateString = context.getString(R.string.manager_battery_usage_unrestricted_only);
|
stateString = context.getString(R.string.manager_battery_usage_unrestricted_only);
|
||||||
footerString = context.getString(
|
detailInfoString =
|
||||||
R.string.manager_battery_usage_footer_limited, stateString);
|
context.getString(R.string.manager_battery_usage_footer_limited, stateString);
|
||||||
} else {
|
} else {
|
||||||
// Present default string to normal app.
|
// Present default string to normal app.
|
||||||
footerString = context.getString(R.string.manager_battery_usage_footer);
|
detailInfoString =
|
||||||
}
|
context.getString(
|
||||||
mFooterPreference.setTitle(footerString);
|
R.string.manager_battery_usage_allow_background_usage_summary);
|
||||||
final Intent helpIntent = HelpUtils.getHelpIntent(context, context.getString(
|
|
||||||
R.string.help_url_app_usage_settings), /*backupContext=*/ "");
|
|
||||||
if (helpIntent != null) {
|
|
||||||
mFooterPreference.setLearnMoreAction(v ->
|
|
||||||
startActivityForResult(helpIntent, /*requestCode=*/ 0));
|
|
||||||
mFooterPreference.setLearnMoreText(
|
|
||||||
context.getString(R.string.manager_battery_usage_link_a11y));
|
|
||||||
}
|
}
|
||||||
|
mAllowBackgroundUsagePreference.setSummary(detailInfoString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -412,9 +395,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
controllers.add(mPowerUsageTimeController);
|
controllers.add(mPowerUsageTimeController);
|
||||||
}
|
}
|
||||||
controllers.add(mAppButtonsPreferenceController);
|
controllers.add(mAppButtonsPreferenceController);
|
||||||
controllers.add(new UnrestrictedPreferenceController(context, uid, packageName));
|
controllers.add(new AllowBackgroundPreferenceController(context, uid, packageName));
|
||||||
controllers.add(new OptimizedPreferenceController(context, uid, packageName));
|
|
||||||
controllers.add(new RestrictedPreferenceController(context, uid, packageName));
|
|
||||||
|
|
||||||
return controllers;
|
return controllers;
|
||||||
}
|
}
|
||||||
@@ -435,34 +416,45 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRadioButtonClicked(SelectorWithWidgetPreference selected) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
final String selectedKey = selected.getKey();
|
if (!(preference instanceof PrimarySwitchPreference)
|
||||||
updatePreferenceState(mUnrestrictedPreference, selectedKey);
|
|| !TextUtils.equals(preference.getKey(), KEY_ALLOW_BACKGROUND_USAGE)) {
|
||||||
updatePreferenceState(mOptimizePreference, selectedKey);
|
return false;
|
||||||
updatePreferenceState(mRestrictedPreference, selectedKey);
|
}
|
||||||
mBatteryOptimizeUtils.setAppUsageState(getSelectedPreference(), Action.APPLY);
|
PowerBackgroundUsageDetail.startPowerBackgroundUsageDetailPage(
|
||||||
|
getContext(), getArguments());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePreferenceState(SelectorWithWidgetPreference preference,
|
@Override
|
||||||
String selectedKey) {
|
public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) {
|
||||||
preference.setChecked(selectedKey.equals(preference.getKey()));
|
if (!(preference instanceof PrimarySwitchPreference)
|
||||||
|
|| !TextUtils.equals(preference.getKey(), KEY_ALLOW_BACKGROUND_USAGE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (newValue instanceof Boolean) {
|
||||||
|
final boolean isAllowBackgroundUsage = (boolean) newValue;
|
||||||
|
mBatteryOptimizeUtils.setAppUsageState(
|
||||||
|
isAllowBackgroundUsage
|
||||||
|
? BatteryOptimizeUtils.MODE_OPTIMIZED
|
||||||
|
: BatteryOptimizeUtils.MODE_RESTRICTED,
|
||||||
|
Action.APPLY);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logMetricCategory(int selectedKey) {
|
private void logMetricCategory(int currentOptimizeMode) {
|
||||||
if (selectedKey == mOptimizationMode) {
|
if (currentOptimizeMode == mOptimizationMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int metricCategory = 0;
|
int metricCategory = 0;
|
||||||
switch (selectedKey) {
|
switch (currentOptimizeMode) {
|
||||||
case BatteryOptimizeUtils.MODE_UNRESTRICTED:
|
case BatteryOptimizeUtils.MODE_UNRESTRICTED:
|
||||||
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_UNRESTRICTED;
|
|
||||||
break;
|
|
||||||
case BatteryOptimizeUtils.MODE_OPTIMIZED:
|
case BatteryOptimizeUtils.MODE_OPTIMIZED:
|
||||||
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED;
|
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_ALLOW_BACKGROUND;
|
||||||
break;
|
break;
|
||||||
case BatteryOptimizeUtils.MODE_RESTRICTED:
|
case BatteryOptimizeUtils.MODE_RESTRICTED:
|
||||||
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_RESTRICTED;
|
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_DISABLE_BACKGROUND;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (metricCategory == 0) {
|
if (metricCategory == 0) {
|
||||||
@@ -470,8 +462,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
}
|
}
|
||||||
int finalMetricCategory = metricCategory;
|
int finalMetricCategory = metricCategory;
|
||||||
mExecutor.execute(() -> {
|
mExecutor.execute(() -> {
|
||||||
String packageName =
|
String packageName = BatteryUtils
|
||||||
getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName());
|
.getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName());
|
||||||
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
||||||
.action(
|
.action(
|
||||||
/* attribution */ SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
/* attribution */ SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
||||||
@@ -482,33 +474,15 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onCreateForTriState(String packageName) {
|
private void onCreateBackgroundUsageState(String packageName) {
|
||||||
mUnrestrictedPreference = findPreference(KEY_PREF_UNRESTRICTED);
|
mAllowBackgroundUsagePreference = findPreference(KEY_ALLOW_BACKGROUND_USAGE);
|
||||||
mOptimizePreference = findPreference(KEY_PREF_OPTIMIZED);
|
if (mAllowBackgroundUsagePreference != null) {
|
||||||
mRestrictedPreference = findPreference(KEY_PREF_RESTRICTED);
|
mAllowBackgroundUsagePreference.setOnPreferenceClickListener(this);
|
||||||
mFooterPreference = findPreference(KEY_FOOTER_PREFERENCE);
|
mAllowBackgroundUsagePreference.setOnPreferenceChangeListener(this);
|
||||||
mUnrestrictedPreference.setOnClickListener(this);
|
|
||||||
mOptimizePreference.setOnClickListener(this);
|
|
||||||
mRestrictedPreference.setOnClickListener(this);
|
|
||||||
|
|
||||||
mBatteryOptimizeUtils = new BatteryOptimizeUtils(
|
|
||||||
getContext(), getArguments().getInt(EXTRA_UID), packageName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getSelectedPreference() {
|
|
||||||
if (mRestrictedPreference.isChecked()) {
|
|
||||||
return BatteryOptimizeUtils.MODE_RESTRICTED;
|
|
||||||
} else if (mUnrestrictedPreference.isChecked()) {
|
|
||||||
return BatteryOptimizeUtils.MODE_UNRESTRICTED;
|
|
||||||
} else if (mOptimizePreference.isChecked()) {
|
|
||||||
return BatteryOptimizeUtils.MODE_OPTIMIZED;
|
|
||||||
} else {
|
|
||||||
return BatteryOptimizeUtils.MODE_UNKNOWN;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static String getLoggingPackageName(Context context, String originalPackingName) {
|
mBatteryOptimizeUtils =
|
||||||
return BatteryUtils.isAppInstalledFromGooglePlayStore(context, originalPackingName)
|
new BatteryOptimizeUtils(
|
||||||
? originalPackingName : PACKAGE_NAME_NONE;
|
getContext(), getArguments().getInt(EXTRA_UID), packageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2021 The Android Open Source Project
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,50 +17,45 @@
|
|||||||
package com.android.settings.fuelgauge;
|
package com.android.settings.fuelgauge;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
|
import com.android.settingslib.PrimarySwitchPreference;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
import com.android.settingslib.widget.MainSwitchPreference;
|
||||||
|
|
||||||
public class RestrictedPreferenceController extends AbstractPreferenceController
|
/** Controller to update the app background usage state */
|
||||||
|
public class AllowBackgroundPreferenceController extends AbstractPreferenceController
|
||||||
implements PreferenceControllerMixin {
|
implements PreferenceControllerMixin {
|
||||||
|
|
||||||
private static final String TAG = "RESTRICTED_PREF";
|
private static final String TAG = "AllowBackgroundPreferenceController";
|
||||||
|
|
||||||
|
@VisibleForTesting static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage";
|
||||||
|
|
||||||
@VisibleForTesting String KEY_RESTRICTED_PREF = "restricted_pref";
|
|
||||||
@VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils;
|
@VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
public RestrictedPreferenceController(Context context, int uid, String packageName) {
|
public AllowBackgroundPreferenceController(Context context, int uid, String packageName) {
|
||||||
super(context);
|
super(context);
|
||||||
mBatteryOptimizeUtils = new BatteryOptimizeUtils(context, uid, packageName);
|
mBatteryOptimizeUtils = new BatteryOptimizeUtils(context, uid, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setChecked(Preference preference, boolean checked) {
|
||||||
|
if (preference instanceof PrimarySwitchPreference) {
|
||||||
|
((PrimarySwitchPreference) preference).setChecked(checked);
|
||||||
|
} else if (preference instanceof MainSwitchPreference) {
|
||||||
|
((MainSwitchPreference) preference).setChecked(checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
|
preference.setEnabled(mBatteryOptimizeUtils.isOptimizeModeMutable());
|
||||||
|
|
||||||
if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) {
|
final boolean isAllowBackground = mBatteryOptimizeUtils.getAppOptimizationMode()
|
||||||
Log.d(TAG, "disable preference for " + mBatteryOptimizeUtils.getPackageName());
|
!= BatteryOptimizeUtils.MODE_RESTRICTED;
|
||||||
preference.setEnabled(false);
|
setChecked(preference, isAllowBackground);
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
preference.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mBatteryOptimizeUtils.getAppOptimizationMode()
|
|
||||||
== BatteryOptimizeUtils.MODE_RESTRICTED) {
|
|
||||||
Log.d(TAG, "is restricted states");
|
|
||||||
((SelectorWithWidgetPreference) preference).setChecked(true);
|
|
||||||
} else {
|
|
||||||
((SelectorWithWidgetPreference) preference).setChecked(false);
|
|
||||||
if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) {
|
|
||||||
Log.d(TAG, "is system or default app, disable pref");
|
|
||||||
preference.setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -70,7 +65,7 @@ public class RestrictedPreferenceController extends AbstractPreferenceController
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPreferenceKey() {
|
public String getPreferenceKey() {
|
||||||
return KEY_RESTRICTED_PREF;
|
return KEY_ALLOW_BACKGROUND_USAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@@ -146,6 +146,22 @@ public class BatteryOptimizeUtils {
|
|||||||
return isSystemOrDefaultApp(mContext, mPowerAllowListBackend, mPackageName, mUid);
|
return isSystemOrDefaultApp(mContext, mPowerAllowListBackend, mPackageName, mUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return {@code true} if the optimization mode of this package can be changed
|
||||||
|
*/
|
||||||
|
public boolean isOptimizeModeMutable() {
|
||||||
|
return !isDisabledForOptimizeModeOnly() && !isSystemOrDefaultApp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return {@code true} if the optimization mode is mutable and current state is not restricted
|
||||||
|
*/
|
||||||
|
public boolean isSelectorPreferenceEnabled() {
|
||||||
|
// Enable the preference if apps are not set into restricted mode, otherwise disable it
|
||||||
|
return isOptimizeModeMutable()
|
||||||
|
&& getAppOptimizationMode() != BatteryOptimizeUtils.MODE_RESTRICTED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of installed applications.
|
* Gets the list of installed applications.
|
||||||
*/
|
*/
|
||||||
|
@@ -88,6 +88,7 @@ public class BatteryUtils {
|
|||||||
public static final String BYPASS_DOCK_DEFENDER_ACTION = "battery.dock.defender.bypass";
|
public static final String BYPASS_DOCK_DEFENDER_ACTION = "battery.dock.defender.bypass";
|
||||||
|
|
||||||
private static final String GOOGLE_PLAY_STORE_PACKAGE = "com.android.vending";
|
private static final String GOOGLE_PLAY_STORE_PACKAGE = "com.android.vending";
|
||||||
|
private static final String PACKAGE_NAME_NONE = "none";
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({StatusType.SCREEN_USAGE,
|
@IntDef({StatusType.SCREEN_USAGE,
|
||||||
@@ -140,6 +141,12 @@ public class BatteryUtils {
|
|||||||
FeatureFactory.getFeatureFactory().getPowerUsageFeatureProvider();
|
FeatureFactory.getFeatureFactory().getPowerUsageFeatureProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** For test to reset single instance. */
|
||||||
|
@VisibleForTesting
|
||||||
|
public void reset() {
|
||||||
|
sInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
public long getProcessTimeMs(@StatusType int type, @Nullable BatteryStats.Uid uid,
|
public long getProcessTimeMs(@StatusType int type, @Nullable BatteryStats.Uid uid,
|
||||||
int which) {
|
int which) {
|
||||||
if (uid == null) {
|
if (uid == null) {
|
||||||
@@ -616,6 +623,12 @@ public class BatteryUtils {
|
|||||||
&& GOOGLE_PLAY_STORE_PACKAGE.equals(installSourceInfo.getInitiatingPackageName());
|
&& GOOGLE_PLAY_STORE_PACKAGE.equals(installSourceInfo.getInitiatingPackageName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the logging package name. */
|
||||||
|
public static String getLoggingPackageName(Context context, String originalPackingName) {
|
||||||
|
return BatteryUtils.isAppInstalledFromGooglePlayStore(context, originalPackingName)
|
||||||
|
? originalPackingName : PACKAGE_NAME_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/** Gets the latest sticky battery intent from the Android system. */
|
/** Gets the latest sticky battery intent from the Android system. */
|
||||||
public static Intent getBatteryIntent(Context context) {
|
public static Intent getBatteryIntent(Context context) {
|
||||||
return com.android.settingslib.fuelgauge.BatteryUtils.getBatteryIntent(context);
|
return com.android.settingslib.fuelgauge.BatteryUtils.getBatteryIntent(context);
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
package com.android.settings.fuelgauge;
|
package com.android.settings.fuelgauge;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@@ -31,8 +30,10 @@ public class OptimizedPreferenceController extends AbstractPreferenceController
|
|||||||
|
|
||||||
private static final String TAG = "OPTIMIZED_PREF";
|
private static final String TAG = "OPTIMIZED_PREF";
|
||||||
|
|
||||||
@VisibleForTesting String KEY_OPTIMIZED_PREF = "optimized_pref";
|
@VisibleForTesting
|
||||||
@VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils;
|
static final String KEY_OPTIMIZED_PREF = "optimized_preference";
|
||||||
|
@VisibleForTesting
|
||||||
|
BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
public OptimizedPreferenceController(Context context, int uid, String packageName) {
|
public OptimizedPreferenceController(Context context, int uid, String packageName) {
|
||||||
super(context);
|
super(context);
|
||||||
@@ -46,24 +47,12 @@ public class OptimizedPreferenceController extends AbstractPreferenceController
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) {
|
preference.setEnabled(mBatteryOptimizeUtils.isSelectorPreferenceEnabled());
|
||||||
Log.d(TAG, "disable preference for " + mBatteryOptimizeUtils.getPackageName());
|
|
||||||
preference.setEnabled(true);
|
|
||||||
((SelectorWithWidgetPreference) preference).setChecked(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mBatteryOptimizeUtils.getAppOptimizationMode()
|
final boolean isOptimized = mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()
|
||||||
== BatteryOptimizeUtils.MODE_OPTIMIZED) {
|
|| mBatteryOptimizeUtils.getAppOptimizationMode()
|
||||||
Log.d(TAG, "is optimized states");
|
== BatteryOptimizeUtils.MODE_OPTIMIZED;
|
||||||
((SelectorWithWidgetPreference) preference).setChecked(true);
|
((SelectorWithWidgetPreference) preference).setChecked(isOptimized);
|
||||||
} else {
|
|
||||||
((SelectorWithWidgetPreference) preference).setChecked(false);
|
|
||||||
if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) {
|
|
||||||
Log.d(TAG, "is system or default app, disable pref");
|
|
||||||
preference.setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -0,0 +1,351 @@
|
|||||||
|
/*
|
||||||
|
* 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.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.backup.BackupManager;
|
||||||
|
import android.app.settings.SettingsEnums;
|
||||||
|
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.Switch;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.core.SubSettingLauncher;
|
||||||
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
|
import com.android.settingslib.HelpUtils;
|
||||||
|
import com.android.settingslib.applications.AppUtils;
|
||||||
|
import com.android.settingslib.applications.ApplicationsState;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.widget.FooterPreference;
|
||||||
|
import com.android.settingslib.widget.LayoutPreference;
|
||||||
|
import com.android.settingslib.widget.MainSwitchPreference;
|
||||||
|
import com.android.settingslib.widget.OnMainSwitchChangeListener;
|
||||||
|
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
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,
|
||||||
|
OnMainSwitchChangeListener {
|
||||||
|
private static final String TAG = "PowerBackgroundUsageDetail";
|
||||||
|
|
||||||
|
public static final String EXTRA_UID = "extra_uid";
|
||||||
|
public static final String EXTRA_PACKAGE_NAME = "extra_package_name";
|
||||||
|
public static final String EXTRA_LABEL = "extra_label";
|
||||||
|
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 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
|
||||||
|
BackupManager mBackupManager;
|
||||||
|
@VisibleForTesting
|
||||||
|
StringBuilder mLogStringBuilder;
|
||||||
|
@VisibleForTesting
|
||||||
|
@BatteryOptimizeUtils.OptimizationMode
|
||||||
|
int mOptimizationMode = BatteryOptimizeUtils.MODE_UNKNOWN;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Activity activity) {
|
||||||
|
super.onAttach(activity);
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
initHeader();
|
||||||
|
mOptimizationMode = mBatteryOptimizeUtils.getAppOptimizationMode();
|
||||||
|
initFooter();
|
||||||
|
mExecutor.execute(() -> {
|
||||||
|
String packageName = BatteryUtils
|
||||||
|
.getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName());
|
||||||
|
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
||||||
|
.action(
|
||||||
|
getContext(),
|
||||||
|
SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
||||||
|
packageName);
|
||||||
|
});
|
||||||
|
mLogStringBuilder = new StringBuilder("onResume mode = ").append(mOptimizationMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
notifyBackupManager();
|
||||||
|
final int currentOptimizeMode = mBatteryOptimizeUtils.getAppOptimizationMode();
|
||||||
|
mLogStringBuilder.append(", onPause mode = ").append(currentOptimizeMode);
|
||||||
|
logMetricCategory(currentOptimizeMode);
|
||||||
|
|
||||||
|
mExecutor.execute(() -> {
|
||||||
|
BatteryOptimizeLogUtils.writeLog(
|
||||||
|
getContext().getApplicationContext(),
|
||||||
|
Action.LEAVE,
|
||||||
|
BatteryOptimizeLogUtils.getPackageNameWithUserId(
|
||||||
|
mBatteryOptimizeUtils.getPackageName(), UserHandle.myUserId()),
|
||||||
|
mLogStringBuilder.toString());
|
||||||
|
});
|
||||||
|
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 onSwitchChanged(Switch switchView, boolean isChecked) {
|
||||||
|
mMainSwitchPreference.setChecked(isChecked);
|
||||||
|
updateSelectorPreference(isChecked);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetricsCategory() {
|
||||||
|
return SettingsEnums.FUELGAUGE_POWER_USAGE_MANAGE_BACKGROUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||||
|
final List<AbstractPreferenceController> 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));
|
||||||
|
|
||||||
|
return controllers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getPreferenceScreenResId() {
|
||||||
|
return R.xml.power_background_usage_detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getLogTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void updateSelectorPreference(boolean isEnabled) {
|
||||||
|
mOptimizePreference.setEnabled(isEnabled);
|
||||||
|
mUnrestrictedPreference.setEnabled(isEnabled);
|
||||||
|
onRadioButtonClicked(isEnabled ? mOptimizePreference : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void notifyBackupManager() {
|
||||||
|
if (mOptimizationMode != mBatteryOptimizeUtils.getAppOptimizationMode()) {
|
||||||
|
final BackupManager backupManager = mBackupManager != null
|
||||||
|
? mBackupManager : new BackupManager(getContext());
|
||||||
|
backupManager.dataChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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())
|
||||||
|
.setArguments(args)
|
||||||
|
.setSourceMetricsCategory(SettingsEnums.FUELGAUGE_POWER_USAGE_MANAGE_BACKGROUND)
|
||||||
|
.launch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void initHeader() {
|
||||||
|
final View appSnippet = mHeaderPreference.findViewById(R.id.entity_header);
|
||||||
|
final Activity context = getActivity();
|
||||||
|
final Bundle bundle = getArguments();
|
||||||
|
EntityHeaderController controller = EntityHeaderController
|
||||||
|
.newInstance(context, this, appSnippet)
|
||||||
|
.setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
|
||||||
|
EntityHeaderController.ActionType.ACTION_NONE);
|
||||||
|
|
||||||
|
if (mAppEntry == null) {
|
||||||
|
controller.setLabel(bundle.getString(EXTRA_LABEL));
|
||||||
|
|
||||||
|
final int iconId = bundle.getInt(EXTRA_ICON_ID, 0);
|
||||||
|
if (iconId == 0) {
|
||||||
|
controller.setIcon(context.getPackageManager().getDefaultActivityIcon());
|
||||||
|
} else {
|
||||||
|
controller.setIcon(context.getDrawable(bundle.getInt(EXTRA_ICON_ID)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mState.ensureIcon(mAppEntry);
|
||||||
|
controller.setLabel(mAppEntry);
|
||||||
|
controller.setIcon(mAppEntry);
|
||||||
|
controller.setIsInstantApp(AppUtils.isInstant(mAppEntry.info));
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.done(true /* rebindActions */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
mFooterPreference.setTitle(footerString);
|
||||||
|
final Intent helpIntent = HelpUtils.getHelpIntent(context, context.getString(
|
||||||
|
R.string.help_url_app_usage_settings), /*backupContext=*/ "");
|
||||||
|
if (helpIntent != null) {
|
||||||
|
mFooterPreference.setLearnMoreAction(v ->
|
||||||
|
startActivityForResult(helpIntent, /*requestCode=*/ 0));
|
||||||
|
mFooterPreference.setLearnMoreText(
|
||||||
|
context.getString(R.string.manager_battery_usage_link_a11y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
int metricCategory = 0;
|
||||||
|
switch (currentOptimizeMode) {
|
||||||
|
case BatteryOptimizeUtils.MODE_UNRESTRICTED:
|
||||||
|
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_UNRESTRICTED;
|
||||||
|
break;
|
||||||
|
case BatteryOptimizeUtils.MODE_OPTIMIZED:
|
||||||
|
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED;
|
||||||
|
break;
|
||||||
|
case BatteryOptimizeUtils.MODE_RESTRICTED:
|
||||||
|
metricCategory = SettingsEnums.ACTION_APP_BATTERY_USAGE_RESTRICTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (metricCategory == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int finalMetricCategory = metricCategory;
|
||||||
|
mExecutor.execute(() -> {
|
||||||
|
String packageName = BatteryUtils
|
||||||
|
.getLoggingPackageName(getContext(), mBatteryOptimizeUtils.getPackageName());
|
||||||
|
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
|
||||||
|
.action(
|
||||||
|
/* attribution */ SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
||||||
|
/* action */ finalMetricCategory,
|
||||||
|
/* pageId */ SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
||||||
|
packageName,
|
||||||
|
getArguments().getInt(EXTRA_POWER_USAGE_AMOUNT));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -17,7 +17,6 @@
|
|||||||
package com.android.settings.fuelgauge;
|
package com.android.settings.fuelgauge;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@@ -31,7 +30,9 @@ public class UnrestrictedPreferenceController extends AbstractPreferenceControll
|
|||||||
|
|
||||||
private static final String TAG = "UNRESTRICTED_PREF";
|
private static final String TAG = "UNRESTRICTED_PREF";
|
||||||
|
|
||||||
@VisibleForTesting String KEY_UNRESTRICTED_PREF = "unrestricted_pref";
|
@VisibleForTesting
|
||||||
|
static final String KEY_UNRESTRICTED_PREF = "unrestricted_preference";
|
||||||
|
|
||||||
@VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils;
|
@VisibleForTesting BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
public UnrestrictedPreferenceController(Context context, int uid, String packageName) {
|
public UnrestrictedPreferenceController(Context context, int uid, String packageName) {
|
||||||
@@ -41,26 +42,11 @@ public class UnrestrictedPreferenceController extends AbstractPreferenceControll
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
|
preference.setEnabled(mBatteryOptimizeUtils.isSelectorPreferenceEnabled());
|
||||||
|
|
||||||
if (mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()) {
|
final boolean isUnrestricted = mBatteryOptimizeUtils.getAppOptimizationMode()
|
||||||
Log.d(TAG, "disable preference for " + mBatteryOptimizeUtils.getPackageName());
|
== BatteryOptimizeUtils.MODE_UNRESTRICTED;
|
||||||
preference.setEnabled(false);
|
((SelectorWithWidgetPreference) preference).setChecked(isUnrestricted);
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
preference.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mBatteryOptimizeUtils.getAppOptimizationMode()
|
|
||||||
== BatteryOptimizeUtils.MODE_UNRESTRICTED) {
|
|
||||||
Log.d(TAG, "is unrestricted states");
|
|
||||||
((SelectorWithWidgetPreference) preference).setChecked(true);
|
|
||||||
} else {
|
|
||||||
((SelectorWithWidgetPreference) preference).setChecked(false);
|
|
||||||
if (mBatteryOptimizeUtils.isSystemOrDefaultApp()) {
|
|
||||||
Log.d(TAG, "is system or default app, disable pref");
|
|
||||||
preference.setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
package com.android.settings.fuelgauge;
|
package com.android.settings.fuelgauge;
|
||||||
|
|
||||||
import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS;
|
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 com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -53,13 +54,12 @@ import com.android.settings.testutils.FakeFeatureFactory;
|
|||||||
import com.android.settings.testutils.shadow.ShadowActivityManager;
|
import com.android.settings.testutils.shadow.ShadowActivityManager;
|
||||||
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
||||||
import com.android.settings.widget.EntityHeaderController;
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
|
import com.android.settingslib.PrimarySwitchPreference;
|
||||||
import com.android.settingslib.applications.AppUtils;
|
import com.android.settingslib.applications.AppUtils;
|
||||||
import com.android.settingslib.applications.ApplicationsState;
|
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.instrumentation.MetricsFeatureProvider;
|
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settingslib.widget.FooterPreference;
|
|
||||||
import com.android.settingslib.widget.LayoutPreference;
|
import com.android.settingslib.widget.LayoutPreference;
|
||||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -95,9 +95,7 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
private static final long FOREGROUND_SERVICE_TIME_MS = 444;
|
private static final long FOREGROUND_SERVICE_TIME_MS = 444;
|
||||||
private static final long FOREGROUND_TIME_MS =
|
private static final long FOREGROUND_TIME_MS =
|
||||||
FOREGROUND_ACTIVITY_TIME_MS + FOREGROUND_SERVICE_TIME_MS;
|
FOREGROUND_ACTIVITY_TIME_MS + FOREGROUND_SERVICE_TIME_MS;
|
||||||
private static final String KEY_PREF_UNRESTRICTED = "unrestricted_pref";
|
private static final String KEY_ALLOW_BACKGROUND_USAGE = "allow_background_usage";
|
||||||
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;
|
||||||
@@ -127,10 +125,7 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
private BackupManager mBackupManager;
|
private BackupManager mBackupManager;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private FooterPreference mFooterPreference;
|
private PrimarySwitchPreference mAllowBackgroundUsagePreference;
|
||||||
private SelectorWithWidgetPreference mRestrictedPreference;
|
|
||||||
private SelectorWithWidgetPreference mOptimizePreference;
|
|
||||||
private SelectorWithWidgetPreference mUnrestrictedPreference;
|
|
||||||
private AdvancedPowerUsageDetail mFragment;
|
private AdvancedPowerUsageDetail mFragment;
|
||||||
private SettingsActivity mTestActivity;
|
private SettingsActivity mTestActivity;
|
||||||
private FakeFeatureFactory mFeatureFactory;
|
private FakeFeatureFactory mFeatureFactory;
|
||||||
@@ -198,14 +193,9 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
nullable(UserHandle.class));
|
nullable(UserHandle.class));
|
||||||
doAnswer(callable).when(mActivity).startActivity(captor.capture());
|
doAnswer(callable).when(mActivity).startActivity(captor.capture());
|
||||||
|
|
||||||
mFooterPreference = new FooterPreference(mContext);
|
mAllowBackgroundUsagePreference = new PrimarySwitchPreference(mContext);
|
||||||
mRestrictedPreference = new SelectorWithWidgetPreference(mContext);
|
mAllowBackgroundUsagePreference.setKey(KEY_ALLOW_BACKGROUND_USAGE);
|
||||||
mOptimizePreference = new SelectorWithWidgetPreference(mContext);
|
mFragment.mAllowBackgroundUsagePreference = mAllowBackgroundUsagePreference;
|
||||||
mUnrestrictedPreference = new SelectorWithWidgetPreference(mContext);
|
|
||||||
mFragment.mFooterPreference = mFooterPreference;
|
|
||||||
mFragment.mRestrictedPreference = mRestrictedPreference;
|
|
||||||
mFragment.mOptimizePreference = mOptimizePreference;
|
|
||||||
mFragment.mUnrestrictedPreference = mUnrestrictedPreference;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@@ -307,70 +297,60 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void initPreferenceForTriState_isValidPackageName_hasCorrectString() {
|
public void initFooter_isValidPackageName_hasCorrectString() {
|
||||||
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
|
||||||
|
|
||||||
mFragment.initPreferenceForTriState(mContext);
|
mFragment.initFooter();
|
||||||
|
|
||||||
assertThat(mFooterPreference.getTitle().toString())
|
assertThat(mAllowBackgroundUsagePreference.getSummary().toString())
|
||||||
.isEqualTo("This app requires optimized battery usage.");
|
.isEqualTo("This app requires optimized battery usage.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void initPreferenceForTriState_isSystemOrDefaultApp_hasCorrectString() {
|
public void initFooter_isSystemOrDefaultApp_hasCorrectString() {
|
||||||
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
||||||
|
|
||||||
mFragment.initPreferenceForTriState(mContext);
|
mFragment.initFooter();
|
||||||
|
|
||||||
assertThat(mFooterPreference.getTitle()
|
assertThat(mAllowBackgroundUsagePreference.getSummary().toString())
|
||||||
.toString()).isEqualTo("This app requires unrestricted battery usage.");
|
.isEqualTo("This app requires unrestricted battery usage.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void initPreferenceForTriState_hasCorrectString() {
|
public void initFooter_hasCorrectString() {
|
||||||
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false);
|
||||||
|
|
||||||
mFragment.initPreferenceForTriState(mContext);
|
mFragment.initFooter();
|
||||||
|
|
||||||
assertThat(mFooterPreference.getTitle().toString())
|
assertThat(mAllowBackgroundUsagePreference.getSummary().toString())
|
||||||
.isEqualTo("Changing how an app uses your battery can affect its performance.");
|
.isEqualTo("Enable for real-time updates, disable to save battery");
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onRadioButtonClicked_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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onPause_optimizationModeChanged_logPreference()
|
public void onPause_optimizationModeChanged_logPreference()
|
||||||
throws PackageManager.NameNotFoundException, InterruptedException {
|
throws PackageManager.NameNotFoundException, InterruptedException {
|
||||||
final String packageName = "testPackageName";
|
final String packageName = "testPackageName";
|
||||||
final int mode = BatteryOptimizeUtils.MODE_RESTRICTED;
|
final int restrictedMode = BatteryOptimizeUtils.MODE_RESTRICTED;
|
||||||
mFragment.mOptimizationMode = mode;
|
final int optimizedMode = BatteryOptimizeUtils.MODE_OPTIMIZED;
|
||||||
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode);
|
mFragment.mOptimizationMode = restrictedMode;
|
||||||
|
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(restrictedMode);
|
||||||
when(mBatteryOptimizeUtils.getPackageName()).thenReturn(packageName);
|
when(mBatteryOptimizeUtils.getPackageName()).thenReturn(packageName);
|
||||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||||
when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo);
|
when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo);
|
||||||
when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending");
|
when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending");
|
||||||
mOptimizePreference.setKey(KEY_PREF_OPTIMIZED);
|
|
||||||
|
|
||||||
mFragment.onRadioButtonClicked(mOptimizePreference);
|
mFragment.onPreferenceChange(mAllowBackgroundUsagePreference, true);
|
||||||
|
verify(mBatteryOptimizeUtils).setAppUsageState(optimizedMode, Action.APPLY);
|
||||||
|
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(optimizedMode);
|
||||||
mFragment.onPause();
|
mFragment.onPause();
|
||||||
|
|
||||||
TimeUnit.SECONDS.sleep(1);
|
TimeUnit.SECONDS.sleep(1);
|
||||||
verify(mMetricsFeatureProvider)
|
verify(mMetricsFeatureProvider)
|
||||||
.action(
|
.action(
|
||||||
SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
||||||
SettingsEnums.ACTION_APP_BATTERY_USAGE_OPTIMIZED,
|
SettingsEnums.ACTION_APP_BATTERY_USAGE_ALLOW_BACKGROUND,
|
||||||
SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
SettingsEnums.OPEN_APP_BATTERY_USAGE,
|
||||||
packageName,
|
packageName,
|
||||||
/* consumed battery */ 0);
|
/* consumed battery */ 0);
|
||||||
@@ -379,15 +359,20 @@ public class AdvancedPowerUsageDetailTest {
|
|||||||
@Test
|
@Test
|
||||||
public void onPause_optimizationModeIsNotChanged_notInvokeLogging()
|
public void onPause_optimizationModeIsNotChanged_notInvokeLogging()
|
||||||
throws PackageManager.NameNotFoundException, InterruptedException {
|
throws PackageManager.NameNotFoundException, InterruptedException {
|
||||||
final int mode = BatteryOptimizeUtils.MODE_OPTIMIZED;
|
final int restrictedMode = BatteryOptimizeUtils.MODE_RESTRICTED;
|
||||||
mFragment.mOptimizationMode = mode;
|
final int optimizedMode = BatteryOptimizeUtils.MODE_OPTIMIZED;
|
||||||
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode);
|
mFragment.mOptimizationMode = restrictedMode;
|
||||||
|
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(restrictedMode);
|
||||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||||
when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo);
|
when(mPackageManager.getInstallSourceInfo(anyString())).thenReturn(mInstallSourceInfo);
|
||||||
when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending");
|
when(mInstallSourceInfo.getInitiatingPackageName()).thenReturn("com.android.vending");
|
||||||
mOptimizePreference.setKey(KEY_PREF_OPTIMIZED);
|
|
||||||
|
|
||||||
mFragment.onRadioButtonClicked(mOptimizePreference);
|
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);
|
||||||
mFragment.onPause();
|
mFragment.onPause();
|
||||||
|
|
||||||
TimeUnit.SECONDS.sleep(1);
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
@@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
@@ -121,6 +121,7 @@ public final class BatteryBackupHelperTest {
|
|||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
mStringWriter = new StringWriter();
|
mStringWriter = new StringWriter();
|
||||||
mPrintWriter = new PrintWriter(mStringWriter);
|
mPrintWriter = new PrintWriter(mStringWriter);
|
||||||
|
BatteryUtils.getInstance(mContext).reset();
|
||||||
doReturn(mContext).when(mContext).getApplicationContext();
|
doReturn(mContext).when(mContext).getApplicationContext();
|
||||||
doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
|
doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
|
||||||
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
|
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
|
||||||
|
@@ -31,10 +31,8 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
|
||||||
|
|
||||||
import com.android.settings.TestUtils;
|
import com.android.settings.TestUtils;
|
||||||
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry;
|
|
||||||
import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleRadioButtonsController;
|
import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleRadioButtonsController;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -75,6 +73,7 @@ public final class BatterySettingsMigrateCheckerTest {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
|
BatteryUtils.getInstance(mContext).reset();
|
||||||
doReturn(mContext).when(mContext).getApplicationContext();
|
doReturn(mContext).when(mContext).getApplicationContext();
|
||||||
doReturn(mPackageManager).when(mContext).getPackageManager();
|
doReturn(mPackageManager).when(mContext).getPackageManager();
|
||||||
doReturn(UID).when(mPackageManager)
|
doReturn(UID).when(mPackageManager)
|
||||||
|
@@ -18,8 +18,13 @@ package com.android.settings.fuelgauge;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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 static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -37,34 +42,41 @@ public class OptimizedPreferenceControllerTest {
|
|||||||
|
|
||||||
private OptimizedPreferenceController mController;
|
private OptimizedPreferenceController mController;
|
||||||
private SelectorWithWidgetPreference mPreference;
|
private SelectorWithWidgetPreference mPreference;
|
||||||
|
private BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
@Mock BatteryOptimizeUtils mockBatteryOptimizeUtils;
|
@Mock PackageManager mMockPackageManager;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
mController = new OptimizedPreferenceController(
|
Context context = spy(RuntimeEnvironment.application);
|
||||||
RuntimeEnvironment.application, UID, PACKAGE_NAME);
|
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);
|
mPreference = new SelectorWithWidgetPreference(RuntimeEnvironment.application);
|
||||||
mController.mBatteryOptimizeUtils = mockBatteryOptimizeUtils;
|
mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(context, UID, PACKAGE_NAME));
|
||||||
|
mController.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_invalidPackage_prefEnabled() {
|
public void testUpdateState_invalidPackage_prefEnabled() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
assertThat(mPreference.isEnabled()).isTrue();
|
assertThat(mPreference.isEnabled()).isFalse();
|
||||||
assertThat(mPreference.isChecked()).isTrue();
|
assertThat(mPreference.isChecked()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_isSystemOrDefaultAppAndOptimizeStates_prefChecked() {
|
public void testUpdateState_isSystemOrDefaultAppAndOptimizeStates_prefChecked() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
||||||
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
||||||
BatteryOptimizeUtils.MODE_OPTIMIZED);
|
BatteryOptimizeUtils.MODE_OPTIMIZED);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
@@ -74,8 +86,8 @@ public class OptimizedPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() {
|
public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
@@ -85,8 +97,8 @@ public class OptimizedPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_isOptimizedStates_prefChecked() {
|
public void testUpdateState_isOptimizedStates_prefChecked() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
||||||
BatteryOptimizeUtils.MODE_OPTIMIZED);
|
BatteryOptimizeUtils.MODE_OPTIMIZED);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
@@ -96,7 +108,7 @@ public class OptimizedPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_prefUnchecked() {
|
public void testUpdateState_prefUnchecked() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
@@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
* 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.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.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.nullable;
|
||||||
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
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.backup.BackupManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.widget.Switch;
|
||||||
|
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.loader.app.LoaderManager;
|
||||||
|
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
|
import com.android.settings.fuelgauge.batteryusage.BatteryEntry;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowActivityManager;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
||||||
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
|
import com.android.settingslib.applications.AppUtils;
|
||||||
|
import com.android.settingslib.applications.ApplicationsState;
|
||||||
|
import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
|
||||||
|
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;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Answers;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@Config(shadows = {
|
||||||
|
ShadowEntityHeaderController.class,
|
||||||
|
ShadowActivityManager.class,
|
||||||
|
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||||
|
})
|
||||||
|
public class PowerBackgroundUsageDetailTest {
|
||||||
|
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 Context mContext;
|
||||||
|
private PowerBackgroundUsageDetail mFragment;
|
||||||
|
private FooterPreference mFooterPreference;
|
||||||
|
private MainSwitchPreference mMainSwitchPreference;
|
||||||
|
private SelectorWithWidgetPreference mOptimizePreference;
|
||||||
|
private SelectorWithWidgetPreference mUnrestrictedPreference;
|
||||||
|
private SettingsActivity mTestActivity;
|
||||||
|
|
||||||
|
@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;
|
||||||
|
@Mock
|
||||||
|
private ApplicationsState.AppEntry mAppEntry;
|
||||||
|
@Mock
|
||||||
|
private BatteryEntry mBatteryEntry;
|
||||||
|
@Mock
|
||||||
|
private BackupManager mBackupManager;
|
||||||
|
@Mock
|
||||||
|
private PackageManager mPackageManager;
|
||||||
|
@Mock
|
||||||
|
private AppOpsManager mAppOpsManager;
|
||||||
|
@Mock
|
||||||
|
private Switch mMockSwitch;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
|
when(mContext.getPackageName()).thenReturn("foo");
|
||||||
|
|
||||||
|
mFragment = spy(new PowerBackgroundUsageDetail());
|
||||||
|
doReturn(mContext).when(mFragment).getContext();
|
||||||
|
doReturn(mActivity).when(mFragment).getActivity();
|
||||||
|
doReturn(SUMMARY).when(mFragment).getString(anyInt());
|
||||||
|
doReturn(APP_LABEL).when(mBundle).getString(nullable(String.class));
|
||||||
|
when(mFragment.getArguments()).thenReturn(mBundle);
|
||||||
|
doReturn(mLoaderManager).when(mFragment).getLoaderManager();
|
||||||
|
|
||||||
|
ShadowEntityHeaderController.setUseMock(mEntityHeaderController);
|
||||||
|
doReturn(mEntityHeaderController).when(mEntityHeaderController)
|
||||||
|
.setButtonActions(anyInt(), anyInt());
|
||||||
|
doReturn(mEntityHeaderController).when(mEntityHeaderController)
|
||||||
|
.setIcon(nullable(Drawable.class));
|
||||||
|
doReturn(mEntityHeaderController).when(mEntityHeaderController).setIcon(nullable(
|
||||||
|
ApplicationsState.AppEntry.class));
|
||||||
|
doReturn(mEntityHeaderController).when(mEntityHeaderController)
|
||||||
|
.setLabel(nullable(String.class));
|
||||||
|
doReturn(mEntityHeaderController).when(mEntityHeaderController)
|
||||||
|
.setLabel(nullable(String.class));
|
||||||
|
doReturn(mEntityHeaderController).when(mEntityHeaderController)
|
||||||
|
.setLabel(nullable(ApplicationsState.AppEntry.class));
|
||||||
|
doReturn(mEntityHeaderController).when(mEntityHeaderController)
|
||||||
|
.setSummary(nullable(String.class));
|
||||||
|
|
||||||
|
when(mBatteryEntry.getUid()).thenReturn(UID);
|
||||||
|
when(mBatteryEntry.getLabel()).thenReturn(APP_LABEL);
|
||||||
|
mBatteryEntry.mIconId = ICON_ID;
|
||||||
|
|
||||||
|
mFragment.mHeaderPreference = mHeaderPreference;
|
||||||
|
mFragment.mState = mState;
|
||||||
|
mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
|
||||||
|
mFragment.mBackupManager = mBackupManager;
|
||||||
|
mAppEntry.info = mock(ApplicationInfo.class);
|
||||||
|
|
||||||
|
mTestActivity = spy(new SettingsActivity());
|
||||||
|
doReturn(mPackageManager).when(mTestActivity).getPackageManager();
|
||||||
|
doReturn(mPackageManager).when(mActivity).getPackageManager();
|
||||||
|
doReturn(mAppOpsManager).when(mTestActivity).getSystemService(Context.APP_OPS_SERVICE);
|
||||||
|
|
||||||
|
final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
|
||||||
|
|
||||||
|
Answer<Void> callable = invocation -> {
|
||||||
|
mBundle = captor.getValue().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||||
|
System.out.println("mBundle = " + mBundle);
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
doAnswer(callable).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();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void initHeader_NoAppEntry_BuildByBundle() {
|
||||||
|
mFragment.mAppEntry = null;
|
||||||
|
mFragment.initHeader();
|
||||||
|
|
||||||
|
verify(mEntityHeaderController).setIcon(nullable(Drawable.class));
|
||||||
|
verify(mEntityHeaderController).setLabel(APP_LABEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void initHeader_HasAppEntry_BuildByAppEntry() {
|
||||||
|
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
|
||||||
|
new InstantAppDataProvider() {
|
||||||
|
@Override
|
||||||
|
public boolean isInstantApp(ApplicationInfo info) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mFragment.mAppEntry = mAppEntry;
|
||||||
|
mFragment.initHeader();
|
||||||
|
|
||||||
|
verify(mEntityHeaderController).setIcon(mAppEntry);
|
||||||
|
verify(mEntityHeaderController).setLabel(mAppEntry);
|
||||||
|
verify(mEntityHeaderController).setIsInstantApp(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void initHeader_HasAppEntry_InstantApp() {
|
||||||
|
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
|
||||||
|
new InstantAppDataProvider() {
|
||||||
|
@Override
|
||||||
|
public boolean isInstantApp(ApplicationInfo info) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mFragment.mAppEntry = mAppEntry;
|
||||||
|
mFragment.initHeader();
|
||||||
|
|
||||||
|
verify(mEntityHeaderController).setIcon(mAppEntry);
|
||||||
|
verify(mEntityHeaderController).setLabel(mAppEntry);
|
||||||
|
verify(mEntityHeaderController).setIsInstantApp(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void initFooter_hasCorrectString() {
|
||||||
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false);
|
||||||
|
|
||||||
|
mFragment.initFooter();
|
||||||
|
|
||||||
|
assertThat(mFooterPreference.getTitle().toString())
|
||||||
|
.isEqualTo("Changing how an app uses your battery can affect its performance.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onSwitchChanged_fromUnrestrictedModeSetDisabled_becomeRestrictedMode() {
|
||||||
|
final int restrictedMode = BatteryOptimizeUtils.MODE_RESTRICTED;
|
||||||
|
final int optimizedMode = BatteryOptimizeUtils.MODE_OPTIMIZED;
|
||||||
|
mFragment.mOptimizationMode = optimizedMode;
|
||||||
|
|
||||||
|
mFragment.onSwitchChanged(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.onSwitchChanged(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);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,126 +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.when;
|
|
||||||
|
|
||||||
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 RestrictedPreferenceControllerTest {
|
|
||||||
private static final int UID = 12345;
|
|
||||||
private static final String PACKAGE_NAME = "com.android.app";
|
|
||||||
|
|
||||||
private RestrictedPreferenceController mController;
|
|
||||||
private SelectorWithWidgetPreference mPreference;
|
|
||||||
|
|
||||||
@Mock BatteryOptimizeUtils mockBatteryOptimizeUtils;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
|
|
||||||
mController = new RestrictedPreferenceController(
|
|
||||||
RuntimeEnvironment.application, UID, PACKAGE_NAME);
|
|
||||||
mPreference = new SelectorWithWidgetPreference(RuntimeEnvironment.application);
|
|
||||||
mController.mBatteryOptimizeUtils = mockBatteryOptimizeUtils;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateState_isValidPackage_prefEnabled() {
|
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isEnabled()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateState_invalidPackage_prefDisabled() {
|
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isEnabled()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateState_isSystemOrDefaultAppAndRestrictedStates_prefChecked() {
|
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
|
||||||
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
|
||||||
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
|
||||||
BatteryOptimizeUtils.MODE_RESTRICTED);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isChecked()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() {
|
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
|
||||||
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isChecked()).isFalse();
|
|
||||||
assertThat(mPreference.isEnabled()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateState_isRestrictedStates_prefChecked() {
|
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
|
||||||
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
|
||||||
BatteryOptimizeUtils.MODE_RESTRICTED);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isChecked()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpdateState_prefUnchecked() {
|
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isChecked()).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHandlePreferenceTreeClick_samePrefKey_verifyAction() {
|
|
||||||
mPreference.setKey(mController.KEY_RESTRICTED_PREF);
|
|
||||||
mController.handlePreferenceTreeClick(mPreference);
|
|
||||||
|
|
||||||
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHandlePreferenceTreeClick_incorrectPrefKey_noAction() {
|
|
||||||
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -18,8 +18,13 @@ package com.android.settings.fuelgauge;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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 static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
import com.android.settingslib.widget.SelectorWithWidgetPreference;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -37,42 +42,53 @@ public class UnrestrictedPreferenceControllerTest {
|
|||||||
|
|
||||||
private UnrestrictedPreferenceController mController;
|
private UnrestrictedPreferenceController mController;
|
||||||
private SelectorWithWidgetPreference mPreference;
|
private SelectorWithWidgetPreference mPreference;
|
||||||
|
private BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
@Mock BatteryOptimizeUtils mockBatteryOptimizeUtils;
|
@Mock PackageManager mMockPackageManager;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
mController = new UnrestrictedPreferenceController(
|
Context context = spy(RuntimeEnvironment.application);
|
||||||
RuntimeEnvironment.application, UID, PACKAGE_NAME);
|
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);
|
mPreference = new SelectorWithWidgetPreference(RuntimeEnvironment.application);
|
||||||
mController.mBatteryOptimizeUtils = mockBatteryOptimizeUtils;
|
mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(context, UID, PACKAGE_NAME));
|
||||||
|
mController.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_isValidPackage_prefEnabled() {
|
public void testUpdateState_isValidPackage_prefEnabled() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mBatteryOptimizeUtils.isOptimizeModeMutable()).isTrue();
|
||||||
assertThat(mPreference.isEnabled()).isTrue();
|
assertThat(mPreference.isEnabled()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_invalidPackage_prefDisabled() {
|
public void testUpdateState_invalidPackage_prefDisabled() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(true);
|
||||||
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(false);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mBatteryOptimizeUtils.isOptimizeModeMutable()).isFalse();
|
||||||
assertThat(mPreference.isEnabled()).isFalse();
|
assertThat(mPreference.isEnabled()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_isSystemOrDefaultAppAndUnrestrictedStates_prefChecked() {
|
public void testUpdateState_isSystemOrDefaultAppAndUnrestrictedStates_prefChecked() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
||||||
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
||||||
BatteryOptimizeUtils.MODE_UNRESTRICTED);
|
BatteryOptimizeUtils.MODE_UNRESTRICTED);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
@@ -82,32 +98,38 @@ public class UnrestrictedPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() {
|
public void testUpdateState_isSystemOrDefaultApp_prefUnchecked() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
||||||
when(mockBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
when(mBatteryOptimizeUtils.isSystemOrDefaultApp()).thenReturn(true);
|
||||||
|
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
||||||
|
BatteryOptimizeUtils.MODE_OPTIMIZED);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
assertThat(mPreference.isChecked()).isFalse();
|
|
||||||
assertThat(mPreference.isEnabled()).isFalse();
|
assertThat(mPreference.isEnabled()).isFalse();
|
||||||
|
assertThat(mPreference.isChecked()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_isUnrestrictedStates_prefChecked() {
|
public void testUpdateState_isUnrestrictedStates_prefChecked() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isOptimizeModeMutable()).thenReturn(true);
|
||||||
when(mockBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
||||||
BatteryOptimizeUtils.MODE_UNRESTRICTED);
|
BatteryOptimizeUtils.MODE_UNRESTRICTED);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isEnabled()).isTrue();
|
||||||
assertThat(mPreference.isChecked()).isTrue();
|
assertThat(mPreference.isChecked()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateState_prefUnchecked() {
|
public void testUpdateState_prefUnchecked() {
|
||||||
when(mockBatteryOptimizeUtils.isDisabledForOptimizeModeOnly()).thenReturn(false);
|
when(mBatteryOptimizeUtils.isOptimizeModeMutable()).thenReturn(true);
|
||||||
|
when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(
|
||||||
|
BatteryOptimizeUtils.MODE_OPTIMIZED);
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
mController.updateState(mPreference);
|
||||||
|
|
||||||
|
assertThat(mPreference.isEnabled()).isTrue();
|
||||||
assertThat(mPreference.isChecked()).isFalse();
|
assertThat(mPreference.isChecked()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -82,6 +82,7 @@ public final class BatteryDiffEntryTest {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
ShadowUserHandle.reset();
|
ShadowUserHandle.reset();
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
|
BatteryUtils.getInstance(mContext).reset();
|
||||||
doReturn(mContext).when(mContext).getApplicationContext();
|
doReturn(mContext).when(mContext).getApplicationContext();
|
||||||
doReturn(mMockUserManager).when(mContext).getSystemService(UserManager.class);
|
doReturn(mMockUserManager).when(mContext).getSystemService(UserManager.class);
|
||||||
doReturn(mMockPackageManager).when(mContext).getPackageManager();
|
doReturn(mMockPackageManager).when(mContext).getPackageManager();
|
||||||
@@ -461,9 +462,6 @@ public final class BatteryDiffEntryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsUninstalledEntry_uninstalledApp_returnTrue() throws Exception {
|
public void testIsUninstalledEntry_uninstalledApp_returnTrue() throws Exception {
|
||||||
doReturn(BatteryUtils.UID_NULL)
|
|
||||||
.when(mMockPackageManager)
|
|
||||||
.getPackageUid(PACKAGE_NAME, PackageManager.GET_META_DATA);
|
|
||||||
final ContentValues values =
|
final ContentValues values =
|
||||||
getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
getContentValuesWithType(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
|
||||||
values.put(BatteryHistEntry.KEY_UID, UNINSTALLED_UID);
|
values.put(BatteryHistEntry.KEY_UID, UNINSTALLED_UID);
|
||||||
|
Reference in New Issue
Block a user