[B&R] restore the backup data for app optimization mode back am: adec23a106
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/15681503 Change-Id: I4977c0f78803d943426a7b2d64b0304bbc2c0b8a
This commit is contained in:
@@ -27,6 +27,7 @@ import android.content.pm.IPackageManager;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ParceledListSlice;
|
import android.content.pm.ParceledListSlice;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.IDeviceIdleController;
|
import android.os.IDeviceIdleController;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
@@ -40,6 +41,7 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
|
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -49,7 +51,7 @@ 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";
|
||||||
private static final String DEVICE_IDLE_SERVICE = "deviceidle";
|
private static final String DEVICE_IDLE_SERVICE = "deviceidle";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = Build.TYPE.equals("userdebug");
|
||||||
|
|
||||||
// Only the owner can see all apps.
|
// Only the owner can see all apps.
|
||||||
private static final int RETRIEVE_FLAG_ADMIN =
|
private static final int RETRIEVE_FLAG_ADMIN =
|
||||||
@@ -60,8 +62,8 @@ public final class BatteryBackupHelper implements BackupHelper {
|
|||||||
PackageManager.MATCH_DISABLED_COMPONENTS |
|
PackageManager.MATCH_DISABLED_COMPONENTS |
|
||||||
PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
|
PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
|
||||||
|
|
||||||
static final CharSequence DELIMITER = ",";
|
static final String DELIMITER = ",";
|
||||||
static final CharSequence DELIMITER_MODE = "|";
|
static final String DELIMITER_MODE = ":";
|
||||||
static final String KEY_FULL_POWER_LIST = "full_power_list";
|
static final String KEY_FULL_POWER_LIST = "full_power_list";
|
||||||
static final String KEY_OPTIMIZATION_LIST = "optimization_mode_list";
|
static final String KEY_OPTIMIZATION_LIST = "optimization_mode_list";
|
||||||
|
|
||||||
@@ -71,6 +73,8 @@ public final class BatteryBackupHelper implements BackupHelper {
|
|||||||
IDeviceIdleController mIDeviceIdleController;
|
IDeviceIdleController mIDeviceIdleController;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
IPackageManager mIPackageManager;
|
IPackageManager mIPackageManager;
|
||||||
|
@VisibleForTesting
|
||||||
|
BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
@@ -81,8 +85,8 @@ public final class BatteryBackupHelper implements BackupHelper {
|
|||||||
@Override
|
@Override
|
||||||
public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
|
public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
|
||||||
ParcelFileDescriptor newState) {
|
ParcelFileDescriptor newState) {
|
||||||
if (!isOwner()) {
|
if (!isOwner() || data == null) {
|
||||||
Log.w(TAG, "ignore performBackup() for non-owner");
|
Log.w(TAG, "ignore performBackup() for non-owner or empty data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final List<String> allowlistedApps = backupFullPowerList(data);
|
final List<String> allowlistedApps = backupFullPowerList(data);
|
||||||
@@ -93,7 +97,21 @@ public final class BatteryBackupHelper implements BackupHelper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void restoreEntity(BackupDataInputStream data) {
|
public void restoreEntity(BackupDataInputStream data) {
|
||||||
Log.d(TAG, "restoreEntity()");
|
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];
|
||||||
|
try {
|
||||||
|
data.read(dataBytes, 0 /*offset*/, dataSize);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "failed to load BackupDataInputStream", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
restoreOptimizationMode(dataBytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -115,7 +133,6 @@ public final class BatteryBackupHelper implements BackupHelper {
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
debugLog("allowlistedApps:" + Arrays.toString(allowlistedApps));
|
|
||||||
final String allowedApps = String.join(DELIMITER, allowlistedApps);
|
final String allowedApps = String.join(DELIMITER, allowlistedApps);
|
||||||
writeBackupData(data, KEY_FULL_POWER_LIST, allowedApps);
|
writeBackupData(data, KEY_FULL_POWER_LIST, allowedApps);
|
||||||
Log.d(TAG, String.format("backup getFullPowerList() size=%d in %d/ms",
|
Log.d(TAG, String.format("backup getFullPowerList() size=%d in %d/ms",
|
||||||
@@ -159,6 +176,64 @@ public final class BatteryBackupHelper implements BackupHelper {
|
|||||||
applications.size(), backupCount, (System.currentTimeMillis() - timestamp)));
|
applications.size(), backupCount, (System.currentTimeMillis() - timestamp)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
void 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;
|
||||||
|
}
|
||||||
|
final String[] appConfigurations = dataContent.split(BatteryBackupHelper.DELIMITER);
|
||||||
|
if (appConfigurations == null || appConfigurations.length == 0) {
|
||||||
|
Log.w(TAG, "no data found from the split() processing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int restoreCount = 0;
|
||||||
|
for (int index = 0; index < appConfigurations.length; index++) {
|
||||||
|
final String[] results = appConfigurations[index]
|
||||||
|
.split(BatteryBackupHelper.DELIMITER_MODE);
|
||||||
|
// Example format: com.android.systemui:2 we should have length=2
|
||||||
|
if (results == null || results.length != 2) {
|
||||||
|
Log.w(TAG, "invalid raw data found:" + appConfigurations[index]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final String packageName = results[0];
|
||||||
|
// Ignores system/default apps.
|
||||||
|
if (isSystemOrDefaultApp(packageName)) {
|
||||||
|
Log.w(TAG, "ignore from isSystemOrDefaultApp():" + packageName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
@BatteryOptimizeUtils.OptimizationMode
|
||||||
|
int optimizationMode = BatteryOptimizeUtils.MODE_UNKNOWN;
|
||||||
|
try {
|
||||||
|
optimizationMode = Integer.parseInt(results[1]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.e(TAG, "failed to parse the optimization mode: "
|
||||||
|
+ appConfigurations[index], e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
restoreOptimizationMode(packageName, optimizationMode);
|
||||||
|
restoreCount++;
|
||||||
|
}
|
||||||
|
Log.d(TAG, String.format("restoreOptimizationMode() count=%d in %d/ms",
|
||||||
|
restoreCount, (System.currentTimeMillis() - timestamp)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreOptimizationMode(
|
||||||
|
String packageName, @BatteryOptimizeUtils.OptimizationMode int mode) {
|
||||||
|
final int uid = BatteryUtils.getInstance(mContext).getPackageUid(packageName);
|
||||||
|
if (uid == BatteryUtils.UID_NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final BatteryOptimizeUtils batteryOptimizeUtils =
|
||||||
|
mBatteryOptimizeUtils != null
|
||||||
|
? mBatteryOptimizeUtils /*testing only*/
|
||||||
|
: new BatteryOptimizeUtils(mContext, uid, packageName);
|
||||||
|
batteryOptimizeUtils.setAppOptimizationMode(mode);
|
||||||
|
Log.d(TAG, String.format("restore:%s mode=%d", packageName, mode));
|
||||||
|
}
|
||||||
|
|
||||||
// Provides an opportunity to inject mock IDeviceIdleController for testing.
|
// Provides an opportunity to inject mock IDeviceIdleController for testing.
|
||||||
private IDeviceIdleController getIDeviceIdleController() {
|
private IDeviceIdleController getIDeviceIdleController() {
|
||||||
if (mIDeviceIdleController != null) {
|
if (mIDeviceIdleController != null) {
|
||||||
|
@@ -16,18 +16,27 @@
|
|||||||
|
|
||||||
package com.android.settings.fuelgauge;
|
package com.android.settings.fuelgauge;
|
||||||
|
|
||||||
|
import static com.android.settings.fuelgauge.BatteryBackupHelper.DELIMITER;
|
||||||
|
import static com.android.settings.fuelgauge.BatteryBackupHelper.DELIMITER_MODE;
|
||||||
|
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_RESTRICTED;
|
||||||
|
import static com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNRESTRICTED;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
|
import static org.mockito.Mockito.inOrder;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.AppOpsManager;
|
import android.app.AppOpsManager;
|
||||||
|
import android.app.backup.BackupDataInputStream;
|
||||||
import android.app.backup.BackupDataOutput;
|
import android.app.backup.BackupDataOutput;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
@@ -49,6 +58,8 @@ import org.junit.After;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.InOrder;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
@@ -68,9 +79,13 @@ public final class BatteryBackupHelperTest {
|
|||||||
private Context mContext;
|
private Context mContext;
|
||||||
private BatteryBackupHelper mBatteryBackupHelper;
|
private BatteryBackupHelper mBatteryBackupHelper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PackageManager mPackageManager;
|
||||||
@Mock
|
@Mock
|
||||||
private BackupDataOutput mBackupDataOutput;
|
private BackupDataOutput mBackupDataOutput;
|
||||||
@Mock
|
@Mock
|
||||||
|
private BackupDataInputStream mBackupDataInputStream;
|
||||||
|
@Mock
|
||||||
private IDeviceIdleController mDeviceController;
|
private IDeviceIdleController mDeviceController;
|
||||||
@Mock
|
@Mock
|
||||||
private IPackageManager mIPackageManager;
|
private IPackageManager mIPackageManager;
|
||||||
@@ -80,18 +95,25 @@ public final class BatteryBackupHelperTest {
|
|||||||
private UserManager mUserManager;
|
private UserManager mUserManager;
|
||||||
@Mock
|
@Mock
|
||||||
private PowerAllowlistBackend mPowerAllowlistBackend;
|
private PowerAllowlistBackend mPowerAllowlistBackend;
|
||||||
|
@Mock
|
||||||
|
private BatteryOptimizeUtils mBatteryOptimizeUtils;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
doReturn(mContext).when(mContext).getApplicationContext();
|
doReturn(mContext).when(mContext).getApplicationContext();
|
||||||
doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
|
doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
|
||||||
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
|
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
|
||||||
|
doReturn(mPackageManager).when(mContext).getPackageManager();
|
||||||
mBatteryBackupHelper = new BatteryBackupHelper(mContext);
|
mBatteryBackupHelper = new BatteryBackupHelper(mContext);
|
||||||
mBatteryBackupHelper.mIDeviceIdleController = mDeviceController;
|
mBatteryBackupHelper.mIDeviceIdleController = mDeviceController;
|
||||||
mBatteryBackupHelper.mIPackageManager = mIPackageManager;
|
mBatteryBackupHelper.mIPackageManager = mIPackageManager;
|
||||||
mBatteryBackupHelper.mPowerAllowlistBackend = mPowerAllowlistBackend;
|
mBatteryBackupHelper.mPowerAllowlistBackend = mPowerAllowlistBackend;
|
||||||
|
mBatteryBackupHelper.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
|
||||||
|
mockUid(1001 /*fake uid*/, PACKAGE_NAME1);
|
||||||
|
mockUid(1002 /*fake uid*/, PACKAGE_NAME2);
|
||||||
|
mockUid(BatteryUtils.UID_NULL, PACKAGE_NAME3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@@ -144,8 +166,7 @@ public final class BatteryBackupHelperTest {
|
|||||||
|
|
||||||
mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
|
mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
|
||||||
|
|
||||||
final String expectedResult = fullPowerList[0]
|
final String expectedResult = fullPowerList[0] + DELIMITER + fullPowerList[1];
|
||||||
+ BatteryBackupHelper.DELIMITER + fullPowerList[1];
|
|
||||||
final byte[] expectedBytes = expectedResult.getBytes();
|
final byte[] expectedBytes = expectedResult.getBytes();
|
||||||
verify(mBackupDataOutput).writeEntityHeader(
|
verify(mBackupDataOutput).writeEntityHeader(
|
||||||
BatteryBackupHelper.KEY_FULL_POWER_LIST, expectedBytes.length);
|
BatteryBackupHelper.KEY_FULL_POWER_LIST, expectedBytes.length);
|
||||||
@@ -186,7 +207,7 @@ public final class BatteryBackupHelperTest {
|
|||||||
mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
|
mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
|
||||||
|
|
||||||
// 2 for UNRESTRICTED mode and 1 for RESTRICTED mode.
|
// 2 for UNRESTRICTED mode and 1 for RESTRICTED mode.
|
||||||
final String expectedResult = PACKAGE_NAME1 + "|2," + PACKAGE_NAME2 + "|1,";
|
final String expectedResult = PACKAGE_NAME1 + ":2," + PACKAGE_NAME2 + ":1,";
|
||||||
verifyBackupData(expectedResult);
|
verifyBackupData(expectedResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +223,7 @@ public final class BatteryBackupHelperTest {
|
|||||||
mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
|
mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
|
||||||
|
|
||||||
// "com.android.testing.2" for RESTRICTED mode.
|
// "com.android.testing.2" for RESTRICTED mode.
|
||||||
final String expectedResult = PACKAGE_NAME2 + "|1,";
|
final String expectedResult = PACKAGE_NAME2 + ":1,";
|
||||||
verifyBackupData(expectedResult);
|
verifyBackupData(expectedResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,10 +239,103 @@ public final class BatteryBackupHelperTest {
|
|||||||
mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
|
mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
|
||||||
|
|
||||||
// "com.android.testing.2" for RESTRICTED mode.
|
// "com.android.testing.2" for RESTRICTED mode.
|
||||||
final String expectedResult = PACKAGE_NAME2 + "|1,";
|
final String expectedResult = PACKAGE_NAME2 + ":1,";
|
||||||
verifyBackupData(expectedResult);
|
verifyBackupData(expectedResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restoreEntity_nonOwner_notReadBackupData() throws Exception {
|
||||||
|
ShadowUserHandle.setUid(1);
|
||||||
|
mockBackupData(30 /*dataSize*/, BatteryBackupHelper.KEY_OPTIMIZATION_LIST);
|
||||||
|
|
||||||
|
mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
|
||||||
|
|
||||||
|
verifyZeroInteractions(mBackupDataInputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restoreEntity_zeroDataSize_notReadBackupData() throws Exception {
|
||||||
|
final int zeroDataSize = 0;
|
||||||
|
mockBackupData(zeroDataSize, BatteryBackupHelper.KEY_OPTIMIZATION_LIST);
|
||||||
|
|
||||||
|
mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
|
||||||
|
|
||||||
|
verify(mBackupDataInputStream, never()).read(any(), anyInt(), anyInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restoreEntity_incorrectDataKey_notReadBackupData() throws Exception {
|
||||||
|
final String incorrectDataKey = BatteryBackupHelper.KEY_FULL_POWER_LIST;
|
||||||
|
mockBackupData(30 /*dataSize*/, incorrectDataKey);
|
||||||
|
|
||||||
|
mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
|
||||||
|
|
||||||
|
verify(mBackupDataInputStream, never()).read(any(), anyInt(), anyInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restoreEntity_readExpectedDataFromBackupData() throws Exception {
|
||||||
|
final int dataSize = 30;
|
||||||
|
mockBackupData(dataSize, BatteryBackupHelper.KEY_OPTIMIZATION_LIST);
|
||||||
|
|
||||||
|
mBatteryBackupHelper.restoreEntity(mBackupDataInputStream);
|
||||||
|
|
||||||
|
final ArgumentCaptor<byte[]> captor = ArgumentCaptor.forClass(byte[].class);
|
||||||
|
verify(mBackupDataInputStream).read(captor.capture(), eq(0), eq(dataSize));
|
||||||
|
assertThat(captor.getValue().length).isEqualTo(dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restoreOptimizationMode_nullBytesData_skipRestore() throws Exception {
|
||||||
|
mBatteryBackupHelper.restoreOptimizationMode(new byte[0]);
|
||||||
|
verifyZeroInteractions(mBatteryOptimizeUtils);
|
||||||
|
|
||||||
|
mBatteryBackupHelper.restoreOptimizationMode("invalid data format".getBytes());
|
||||||
|
verifyZeroInteractions(mBatteryOptimizeUtils);
|
||||||
|
|
||||||
|
mBatteryBackupHelper.restoreOptimizationMode(DELIMITER.getBytes());
|
||||||
|
verifyZeroInteractions(mBatteryOptimizeUtils);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restoreOptimizationMode_invalidModeFormat_skipRestore() throws Exception {
|
||||||
|
final String invalidNumberFormat = "google";
|
||||||
|
final String packageModes =
|
||||||
|
PACKAGE_NAME1 + DELIMITER_MODE + MODE_RESTRICTED + DELIMITER +
|
||||||
|
PACKAGE_NAME2 + DELIMITER_MODE + invalidNumberFormat;
|
||||||
|
|
||||||
|
mBatteryBackupHelper.restoreOptimizationMode(packageModes.getBytes());
|
||||||
|
|
||||||
|
final InOrder inOrder = inOrder(mBatteryOptimizeUtils);
|
||||||
|
inOrder.verify(mBatteryOptimizeUtils).setAppOptimizationMode(MODE_RESTRICTED);
|
||||||
|
inOrder.verify(mBatteryOptimizeUtils, never()).setAppOptimizationMode(anyInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restoreOptimizationMode_restoreExpectedModes() throws Exception {
|
||||||
|
final String packageModes =
|
||||||
|
PACKAGE_NAME1 + DELIMITER_MODE + MODE_RESTRICTED + DELIMITER +
|
||||||
|
PACKAGE_NAME2 + DELIMITER_MODE + MODE_UNRESTRICTED + DELIMITER +
|
||||||
|
PACKAGE_NAME3 + DELIMITER_MODE + MODE_RESTRICTED + DELIMITER;
|
||||||
|
|
||||||
|
mBatteryBackupHelper.restoreOptimizationMode(packageModes.getBytes());
|
||||||
|
|
||||||
|
final InOrder inOrder = inOrder(mBatteryOptimizeUtils);
|
||||||
|
inOrder.verify(mBatteryOptimizeUtils).setAppOptimizationMode(MODE_RESTRICTED);
|
||||||
|
inOrder.verify(mBatteryOptimizeUtils).setAppOptimizationMode(MODE_UNRESTRICTED);
|
||||||
|
inOrder.verify(mBatteryOptimizeUtils, never()).setAppOptimizationMode(MODE_RESTRICTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mockUid(int uid, String packageName) throws Exception {
|
||||||
|
doReturn(uid).when(mPackageManager)
|
||||||
|
.getPackageUid(packageName, PackageManager.GET_META_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mockBackupData(int dataSize, String dataKey) {
|
||||||
|
doReturn(dataSize).when(mBackupDataInputStream).size();
|
||||||
|
doReturn(dataKey).when(mBackupDataInputStream).getKey();
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyBackupData(String expectedResult) throws Exception {
|
private void verifyBackupData(String expectedResult) throws Exception {
|
||||||
final byte[] expectedBytes = expectedResult.getBytes();
|
final byte[] expectedBytes = expectedResult.getBytes();
|
||||||
verify(mBackupDataOutput).writeEntityHeader(
|
verify(mBackupDataOutput).writeEntityHeader(
|
||||||
|
Reference in New Issue
Block a user