Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2150660d authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add allowlist mechanism for battery optimization mode" into udc-dev am: 2b91f1a4

parents a8830ef2 2b91f1a4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ message BatteryOptimizeHistoricalLogEntry {
    RESET = 3;
    RESTORE = 4;
    BACKUP = 5;
    FORCE_RESET = 6;
  }

  optional string package_name = 1;
+4 −0
Original line number Diff line number Diff line
@@ -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>

+30 −15
Original line number Diff line number Diff line
@@ -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;
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -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,
+39 −2
Original line number Diff line number Diff line
@@ -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);
    }

    /** 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