Loading protos/fuelgauge_log.proto +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ message BatteryOptimizeHistoricalLogEntry { RESET = 3; RESTORE = 4; BACKUP = 5; FORCE_RESET = 6; } optional string package_name = 1; Loading res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -526,6 +526,10 @@ <item>content://com.android.settings.slices/intent/media_output_indicator</item> </string-array> <!-- List containing the apps cannot be changed the battery optimize modes --> <string-array name="config_disable_optimization_mode_apps" translatable="false"> </string-array> <!-- Uri to query non-public Slice Uris. --> <string name="config_non_public_slice_query_uri" translatable="false"></string> Loading src/com/android/settings/fuelgauge/BatteryBackupHelper.java +30 −15 Original line number Diff line number Diff line Loading @@ -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]; Loading @@ -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); } } } Loading Loading @@ -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++) { Loading Loading @@ -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. */ Loading @@ -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( Loading @@ -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)); Loading Loading @@ -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; } } src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java +8 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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, Loading src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java +39 −2 Original line number Diff line number Diff line Loading @@ -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); } } Loading @@ -40,9 +51,35 @@ public final class BatterySettingsMigrateChecker extends BroadcastReceiver { static void verifyConfiguration(Context context) { context = context.getApplicationContext(); verifySaverConfiguration(context); verifyOptimizationModes(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); } }); } private static void verifySaverConfiguration(Context context) { 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); Loading Loading
protos/fuelgauge_log.proto +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ message BatteryOptimizeHistoricalLogEntry { RESET = 3; RESTORE = 4; BACKUP = 5; FORCE_RESET = 6; } optional string package_name = 1; Loading
res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -526,6 +526,10 @@ <item>content://com.android.settings.slices/intent/media_output_indicator</item> </string-array> <!-- List containing the apps cannot be changed the battery optimize modes --> <string-array name="config_disable_optimization_mode_apps" translatable="false"> </string-array> <!-- Uri to query non-public Slice Uris. --> <string name="config_non_public_slice_query_uri" translatable="false"></string> Loading
src/com/android/settings/fuelgauge/BatteryBackupHelper.java +30 −15 Original line number Diff line number Diff line Loading @@ -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]; Loading @@ -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); } } } Loading Loading @@ -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++) { Loading Loading @@ -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. */ Loading @@ -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( Loading @@ -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)); Loading Loading @@ -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; } }
src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java +8 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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, Loading
src/com/android/settings/fuelgauge/BatterySettingsMigrateChecker.java +39 −2 Original line number Diff line number Diff line Loading @@ -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); } } Loading @@ -40,9 +51,35 @@ public final class BatterySettingsMigrateChecker extends BroadcastReceiver { static void verifyConfiguration(Context context) { context = context.getApplicationContext(); verifySaverConfiguration(context); verifyOptimizationModes(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); } }); } private static void verifySaverConfiguration(Context context) { 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); Loading