Merge "Limit the optimization mode restore mechanism for specific conditions" into udc-dev am: b2de62c076 am: 87a35ffae5

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/23241740

Change-Id: I304e73c7cae7c5669694296002916a5601c8b4a5
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2023-05-16 12:25:51 +00:00
committed by Automerger Merge Worker
4 changed files with 104 additions and 24 deletions

View File

@@ -31,6 +31,7 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.Log; import android.util.Log;
@@ -51,20 +52,23 @@ import java.util.List;
public final class BatteryBackupHelper implements BackupHelper { public final class BatteryBackupHelper implements BackupHelper {
/** An inditifier for {@link BackupHelper}. */ /** An inditifier for {@link BackupHelper}. */
public static final String TAG = "BatteryBackupHelper"; public static final String TAG = "BatteryBackupHelper";
// Definition for the device build information.
public static final String KEY_BUILD_BRAND = "device_build_brand";
public static final String KEY_BUILD_PRODUCT = "device_build_product";
public static final String KEY_BUILD_MANUFACTURER = "device_build_manufacture";
public static final String KEY_BUILD_FINGERPRINT = "device_build_fingerprint";
// Customized fields for device extra information.
public static final String KEY_BUILD_METADATA_1 = "device_build_metadata_1";
public static final String KEY_BUILD_METADATA_2 = "device_build_metadata_2";
private static final String DEVICE_IDLE_SERVICE = "deviceidle"; private static final String DEVICE_IDLE_SERVICE = "deviceidle";
private static final String BATTERY_OPTIMIZE_BACKUP_FILE_NAME = private static final String BATTERY_OPTIMIZE_BACKUP_FILE_NAME =
"battery_optimize_backup_historical_logs"; "battery_optimize_backup_historical_logs";
private static final int DEVICE_BUILD_INFO_SIZE = 6;
static final String DELIMITER = ","; static final String DELIMITER = ",";
static final String DELIMITER_MODE = ":"; static final String DELIMITER_MODE = ":";
static final String KEY_OPTIMIZATION_LIST = "optimization_mode_list"; static final String KEY_OPTIMIZATION_LIST = "optimization_mode_list";
static final String KEY_BUILD_BRAND = "device_build_brand";
static final String KEY_BUILD_PRODUCT = "device_build_product";
static final String KEY_BUILD_MANUFACTURER = "device_build_manufacture";
static final String KEY_BUILD_FINGERPRINT = "device_build_fingerprint";
// Customized fields for device extra information.
static final String KEY_BUILD_METADATA_1 = "device_build_metadata_1";
static final String KEY_BUILD_METADATA_2 = "device_build_metadata_2";
@VisibleForTesting @VisibleForTesting
ArraySet<ApplicationInfo> mTestApplicationInfoList = null; ArraySet<ApplicationInfo> mTestApplicationInfoList = null;
@@ -78,7 +82,13 @@ public final class BatteryBackupHelper implements BackupHelper {
@VisibleForTesting @VisibleForTesting
BatteryOptimizeUtils mBatteryOptimizeUtils; BatteryOptimizeUtils mBatteryOptimizeUtils;
private byte[] mOptimizationModeBytes;
private boolean mVerifyMigrateConfiguration = false;
private final Context mContext; private final Context mContext;
// Device information map from the restoreEntity() method.
private final ArrayMap<String, String> mDeviceBuildInfoMap =
new ArrayMap<>(DEVICE_BUILD_INFO_SIZE);
public BatteryBackupHelper(Context context) { public BatteryBackupHelper(Context context) {
mContext = context.getApplicationContext(); mContext = context.getApplicationContext();
@@ -101,7 +111,7 @@ public final class BatteryBackupHelper implements BackupHelper {
writeBackupData(data, KEY_BUILD_MANUFACTURER, Build.MANUFACTURER); writeBackupData(data, KEY_BUILD_MANUFACTURER, Build.MANUFACTURER);
writeBackupData(data, KEY_BUILD_FINGERPRINT, Build.FINGERPRINT); writeBackupData(data, KEY_BUILD_FINGERPRINT, Build.FINGERPRINT);
// Add customized device build metadata fields. // Add customized device build metadata fields.
PowerUsageFeatureProvider provider = FeatureFactory.getFactory(mContext) final PowerUsageFeatureProvider provider = FeatureFactory.getFactory(mContext)
.getPowerUsageFeatureProvider(mContext); .getPowerUsageFeatureProvider(mContext);
writeBackupData(data, KEY_BUILD_METADATA_1, provider.getBuildMetadata1(mContext)); writeBackupData(data, KEY_BUILD_METADATA_1, provider.getBuildMetadata1(mContext));
writeBackupData(data, KEY_BUILD_METADATA_2, provider.getBuildMetadata2(mContext)); writeBackupData(data, KEY_BUILD_METADATA_2, provider.getBuildMetadata2(mContext));
@@ -111,26 +121,31 @@ public final class BatteryBackupHelper implements BackupHelper {
@Override @Override
public void restoreEntity(BackupDataInputStream data) { public void restoreEntity(BackupDataInputStream data) {
BatterySettingsMigrateChecker.verifySaverConfiguration(mContext); // Ensure we only verify the migrate configuration one time.
if (!mVerifyMigrateConfiguration) {
mVerifyMigrateConfiguration = true;
BatterySettingsMigrateChecker.verifySaverConfiguration(mContext);
}
if (!isOwner() || data == null || data.size() == 0) { if (!isOwner() || data == null || data.size() == 0) {
Log.w(TAG, "ignore restoreEntity() for non-owner or empty data"); Log.w(TAG, "ignore restoreEntity() for non-owner or empty data");
return; return;
} }
final String dataKey = data.getKey();
if (KEY_OPTIMIZATION_LIST.equals(data.getKey())) { switch (dataKey) {
final int dataSize = data.size(); case KEY_BUILD_BRAND:
final byte[] dataBytes = new byte[dataSize]; case KEY_BUILD_PRODUCT:
try { case KEY_BUILD_MANUFACTURER:
data.read(dataBytes, 0 /*offset*/, dataSize); case KEY_BUILD_FINGERPRINT:
} catch (IOException e) { case KEY_BUILD_METADATA_1:
Log.e(TAG, "failed to load BackupDataInputStream", e); case KEY_BUILD_METADATA_2:
return; restoreBackupData(dataKey, data);
} break;
final int restoreCount = restoreOptimizationMode(dataBytes); case KEY_OPTIMIZATION_LIST:
if (restoreCount > 0) { // Hold the optimization mode data until all conditions are matched.
BatterySettingsMigrateChecker.verifyOptimizationModes(mContext); mOptimizationModeBytes = getBackupData(dataKey, data);
} break;
} }
performRestoreIfNeeded();
} }
@Override @Override
@@ -241,6 +256,23 @@ public final class BatteryBackupHelper implements BackupHelper {
return restoreCount; return restoreCount;
} }
private void performRestoreIfNeeded() {
if (mOptimizationModeBytes == null || mOptimizationModeBytes.length == 0) {
return;
}
final PowerUsageFeatureProvider provider = FeatureFactory.getFactory(mContext)
.getPowerUsageFeatureProvider(mContext);
if (!provider.isValidToRestoreOptimizationMode(mDeviceBuildInfoMap)) {
return;
}
// Start to restore the app optimization mode data.
final int restoreCount = restoreOptimizationMode(mOptimizationModeBytes);
if (restoreCount > 0) {
BatterySettingsMigrateChecker.verifyOptimizationModes(mContext);
}
mOptimizationModeBytes = null; // clear data
}
/** Dump the app optimization mode backup history data. */ /** Dump the app optimization mode backup history data. */
public static void dumpHistoricalData(Context context, PrintWriter writer) { public static void dumpHistoricalData(Context context, PrintWriter writer) {
BatteryHistoricalLogUtil.printBatteryOptimizeHistoricalLog( BatteryHistoricalLogUtil.printBatteryOptimizeHistoricalLog(
@@ -320,6 +352,28 @@ public final class BatteryBackupHelper implements BackupHelper {
return BatteryOptimizeUtils.getInstalledApplications(mContext, getIPackageManager()); return BatteryOptimizeUtils.getInstalledApplications(mContext, getIPackageManager());
} }
private void restoreBackupData(String dataKey, BackupDataInputStream data) {
final byte[] dataBytes = getBackupData(dataKey, data);
if (dataBytes == null || dataBytes.length == 0) {
return;
}
final String dataContent = new String(dataBytes, StandardCharsets.UTF_8);
mDeviceBuildInfoMap.put(dataKey, dataContent);
Log.d(TAG, String.format("restore:%s:%s", dataKey, dataContent));
}
private static byte[] getBackupData(String dataKey, BackupDataInputStream data) {
final int dataSize = data.size();
final byte[] dataBytes = new byte[dataSize];
try {
data.read(dataBytes, 0 /*offset*/, dataSize);
} catch (IOException e) {
Log.e(TAG, "failed to getBackupData() " + dataKey, e);
return null;
}
return dataBytes;
}
private static void writeBackupData( private static void writeBackupData(
BackupDataOutput data, String dataKey, String dataContent) { BackupDataOutput data, String dataKey, String dataContent) {
if (dataContent == null || dataContent.isEmpty()) { if (dataContent == null || dataContent.isEmpty()) {
@@ -332,6 +386,6 @@ public final class BatteryBackupHelper implements BackupHelper {
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "writeBackupData() is failed for " + dataKey, e); Log.e(TAG, "writeBackupData() is failed for " + dataKey, e);
} }
Log.d(TAG, String.format("%s:%s", dataKey, dataContent)); Log.d(TAG, String.format("backup:%s:%s", dataKey, dataContent));
} }
} }

View File

@@ -18,6 +18,7 @@ package com.android.settings.fuelgauge;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.util.ArrayMap;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import com.android.settingslib.fuelgauge.Estimate; import com.android.settingslib.fuelgauge.Estimate;
@@ -176,4 +177,9 @@ public interface PowerUsageFeatureProvider {
* Returns the customized device build information for data backup * Returns the customized device build information for data backup
*/ */
String getBuildMetadata2(Context context); String getBuildMetadata2(Context context);
/**
* Whether the app optimization mode is valid to restore
*/
boolean isValidToRestoreOptimizationMode(ArrayMap<String, String> deviceInfoMap);
} }

View File

@@ -22,6 +22,7 @@ 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.Process; import android.os.Process;
import android.util.ArrayMap;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.SparseIntArray; import android.util.SparseIntArray;
@@ -198,4 +199,9 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider
public String getBuildMetadata2(Context context) { public String getBuildMetadata2(Context context) {
return null; return null;
} }
@Override
public boolean isValidToRestoreOptimizationMode(ArrayMap<String, String> deviceInfoMap) {
return false;
}
} }

View File

@@ -283,6 +283,20 @@ public final class BatteryBackupHelperTest {
assertThat(TestUtils.getScheduledLevel(mContext)).isNotEqualTo(invalidScheduledLevel); assertThat(TestUtils.getScheduledLevel(mContext)).isNotEqualTo(invalidScheduledLevel);
} }
@Test
public void restoreEntity_verifyConfigurationOneTimeOnly() {
final int invalidScheduledLevel = 5;
TestUtils.setScheduledLevel(mContext, invalidScheduledLevel);
mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
TestUtils.setScheduledLevel(mContext, invalidScheduledLevel);
// Invoke the restoreEntity() method 2nd time.
mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
assertThat(TestUtils.getScheduledLevel(mContext))
.isEqualTo(invalidScheduledLevel);
}
@Test @Test
public void restoreOptimizationMode_nullBytesData_skipRestore() throws Exception { public void restoreOptimizationMode_nullBytesData_skipRestore() throws Exception {
mBatteryBackupHelper.restoreOptimizationMode(new byte[0]); mBatteryBackupHelper.restoreOptimizationMode(new byte[0]);