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:
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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]);
|
||||||
|
Reference in New Issue
Block a user