Add allowlist mechanism for battery optimization mode
Add a mechanism to add package name into the allowlist to avoid users change the battery optimization modes for specific apps in the list https://screenshot.googleplex.com/8hrHCcTh5bNYXqp Bug: 281566984 Test: make test RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.fuelgauge.* Change-Id: I8efa6a55646d761f5bee3667a59b38ab68c74bc1
This commit is contained in:
@@ -91,11 +91,12 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
|
||||
@Override
|
||||
public void restoreEntity(BackupDataInputStream data) {
|
||||
BatterySettingsMigrateChecker.verifyConfiguration(mContext);
|
||||
BatterySettingsMigrateChecker.verifySaverConfiguration(mContext);
|
||||
if (!isOwner() || data == null || data.size() == 0) {
|
||||
Log.w(TAG, "ignore restoreEntity() for non-owner or empty data");
|
||||
return;
|
||||
}
|
||||
|
||||
if (KEY_OPTIMIZATION_LIST.equals(data.getKey())) {
|
||||
final int dataSize = data.size();
|
||||
final byte[] dataBytes = new byte[dataSize];
|
||||
@@ -105,7 +106,10 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
Log.e(TAG, "failed to load BackupDataInputStream", e);
|
||||
return;
|
||||
}
|
||||
restoreOptimizationMode(dataBytes);
|
||||
final int restoreCount = restoreOptimizationMode(dataBytes);
|
||||
if (restoreCount > 0) {
|
||||
BatterySettingsMigrateChecker.verifyOptimizationModes(mContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,17 +179,17 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void restoreOptimizationMode(byte[] dataBytes) {
|
||||
int restoreOptimizationMode(byte[] dataBytes) {
|
||||
final long timestamp = System.currentTimeMillis();
|
||||
final String dataContent = new String(dataBytes, StandardCharsets.UTF_8);
|
||||
if (dataContent == null || dataContent.isEmpty()) {
|
||||
Log.w(TAG, "no data found in the restoreOptimizationMode()");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
final String[] appConfigurations = dataContent.split(BatteryBackupHelper.DELIMITER);
|
||||
if (appConfigurations == null || appConfigurations.length == 0) {
|
||||
Log.w(TAG, "no data found from the split() processing");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
int restoreCount = 0;
|
||||
for (int index = 0; index < appConfigurations.length; index++) {
|
||||
@@ -217,6 +221,7 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
}
|
||||
Log.d(TAG, String.format("restoreOptimizationMode() count=%d in %d/ms",
|
||||
restoreCount, (System.currentTimeMillis() - timestamp)));
|
||||
return restoreCount;
|
||||
}
|
||||
|
||||
/** Dump the app optimization mode backup history data. */
|
||||
@@ -225,6 +230,23 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
getSharedPreferences(context), writer);
|
||||
}
|
||||
|
||||
static boolean isOwner() {
|
||||
return UserHandle.myUserId() == UserHandle.USER_SYSTEM;
|
||||
}
|
||||
|
||||
static BatteryOptimizeUtils newBatteryOptimizeUtils(
|
||||
Context context, String packageName, BatteryOptimizeUtils testOptimizeUtils) {
|
||||
final int uid = BatteryUtils.getInstance(context).getPackageUid(packageName);
|
||||
if (uid == BatteryUtils.UID_NULL) {
|
||||
return null;
|
||||
}
|
||||
final BatteryOptimizeUtils batteryOptimizeUtils =
|
||||
testOptimizeUtils != null
|
||||
? testOptimizeUtils /*testing only*/
|
||||
: new BatteryOptimizeUtils(context, uid, packageName);
|
||||
return batteryOptimizeUtils;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static SharedPreferences getSharedPreferences(Context context) {
|
||||
return context.getSharedPreferences(
|
||||
@@ -233,14 +255,11 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
|
||||
private void restoreOptimizationMode(
|
||||
String packageName, @BatteryOptimizeUtils.OptimizationMode int mode) {
|
||||
final int uid = BatteryUtils.getInstance(mContext).getPackageUid(packageName);
|
||||
if (uid == BatteryUtils.UID_NULL) {
|
||||
final BatteryOptimizeUtils batteryOptimizeUtils =
|
||||
newBatteryOptimizeUtils(mContext, packageName, mBatteryOptimizeUtils);
|
||||
if (batteryOptimizeUtils == null) {
|
||||
return;
|
||||
}
|
||||
final BatteryOptimizeUtils batteryOptimizeUtils =
|
||||
mBatteryOptimizeUtils != null
|
||||
? mBatteryOptimizeUtils /*testing only*/
|
||||
: new BatteryOptimizeUtils(mContext, uid, packageName);
|
||||
batteryOptimizeUtils.setAppUsageState(
|
||||
mode, BatteryOptimizeHistoricalLogEntry.Action.RESTORE);
|
||||
Log.d(TAG, String.format("restore:%s mode=%d", packageName, mode));
|
||||
@@ -294,8 +313,4 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
Log.e(TAG, "writeBackupData() is failed for " + dataKey, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOwner() {
|
||||
return UserHandle.myUserId() == UserHandle.USER_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
@@ -31,11 +31,14 @@ import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
|
||||
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/** A utility class for application usage operation. */
|
||||
public class BatteryOptimizeUtils {
|
||||
@@ -214,6 +217,11 @@ public class BatteryOptimizeUtils {
|
||||
|| powerAllowlistBackend.isDefaultActiveApp(packageName, uid);
|
||||
}
|
||||
|
||||
static List<String> getAllowList(Context context) {
|
||||
return Arrays.asList(context.getResources().getStringArray(
|
||||
R.array.config_disable_optimization_mode_apps));
|
||||
}
|
||||
|
||||
private static void setAppUsageStateInternal(
|
||||
Context context, @OptimizationMode int mode, int uid, String packageName,
|
||||
BatteryUtils batteryUtils, PowerAllowlistBackend powerAllowlistBackend,
|
||||
|
@@ -23,16 +23,27 @@ import android.content.Intent;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry;
|
||||
import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleRadioButtonsController;
|
||||
import com.android.settingslib.fuelgauge.BatterySaverUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Execute battery settings migration tasks in the device booting stage. */
|
||||
public final class BatterySettingsMigrateChecker extends BroadcastReceiver {
|
||||
private static final String TAG = "BatterySettingsMigrateChecker";
|
||||
|
||||
@VisibleForTesting
|
||||
static BatteryOptimizeUtils sBatteryOptimizeUtils = null;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent != null && Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
|
||||
if (intent != null
|
||||
&& Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())
|
||||
&& BatteryBackupHelper.isOwner()) {
|
||||
verifyConfiguration(context);
|
||||
}
|
||||
}
|
||||
@@ -40,9 +51,35 @@ public final class BatterySettingsMigrateChecker extends BroadcastReceiver {
|
||||
static void verifyConfiguration(Context context) {
|
||||
context = context.getApplicationContext();
|
||||
verifySaverConfiguration(context);
|
||||
verifyOptimizationModes(context);
|
||||
}
|
||||
|
||||
private static void verifySaverConfiguration(Context context) {
|
||||
/** Avoid users set important apps into the unexpected battery optimize modes */
|
||||
static void verifyOptimizationModes(Context context) {
|
||||
Log.d(TAG, "invoke verifyOptimizationModes()");
|
||||
verifyOptimizationModes(context, BatteryOptimizeUtils.getAllowList(context));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static void verifyOptimizationModes(Context context, List<String> allowList) {
|
||||
allowList.forEach(packageName -> {
|
||||
final BatteryOptimizeUtils batteryOptimizeUtils =
|
||||
BatteryBackupHelper.newBatteryOptimizeUtils(context, packageName,
|
||||
/* testOptimizeUtils */ sBatteryOptimizeUtils);
|
||||
if (batteryOptimizeUtils == null) {
|
||||
return;
|
||||
}
|
||||
if (batteryOptimizeUtils.getAppOptimizationMode() !=
|
||||
BatteryOptimizeUtils.MODE_OPTIMIZED) {
|
||||
Log.w(TAG, "Reset optimization mode for: " + packageName);
|
||||
batteryOptimizeUtils.setAppUsageState(BatteryOptimizeUtils.MODE_OPTIMIZED,
|
||||
BatteryOptimizeHistoricalLogEntry.Action.FORCE_RESET);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void verifySaverConfiguration(Context context) {
|
||||
Log.d(TAG, "invoke verifySaverConfiguration()");
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final int threshold = Settings.Global.getInt(resolver,
|
||||
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
|
||||
|
Reference in New Issue
Block a user