Add device build information in the backup stage

Insert the device build information in the battery optimization mode
backup stage, such that we can use it to decide whether we should
restore the data in the targeted device or not

Bug: 192523697
Test: make test RunSettingsRoboTests
ROBOTEST_FILTER=com.android.settings.fuelgauge.*

Change-Id: I3ab76e013ea9aca4d336a62e0c7cb6882c5b5085
This commit is contained in:
ykhung
2023-05-16 08:36:00 +08:00
parent 2c125d29a3
commit cad41681d6
4 changed files with 82 additions and 12 deletions

View File

@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager; import android.content.pm.IPackageManager;
import android.os.Build;
import android.os.IDeviceIdleController; import android.os.IDeviceIdleController;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
@@ -36,6 +37,7 @@ import android.util.Log;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action; import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend; import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
import java.io.IOException; import java.io.IOException;
@@ -56,6 +58,13 @@ public final class BatteryBackupHelper implements BackupHelper {
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;
@@ -83,9 +92,21 @@ public final class BatteryBackupHelper implements BackupHelper {
return; return;
} }
final List<String> allowlistedApps = getFullPowerList(); final List<String> allowlistedApps = getFullPowerList();
if (allowlistedApps != null) { if (allowlistedApps == null) {
backupOptimizationMode(data, allowlistedApps); return;
} }
writeBackupData(data, KEY_BUILD_BRAND, Build.BRAND);
writeBackupData(data, KEY_BUILD_PRODUCT, Build.PRODUCT);
writeBackupData(data, KEY_BUILD_MANUFACTURER, Build.MANUFACTURER);
writeBackupData(data, KEY_BUILD_FINGERPRINT, Build.FINGERPRINT);
// Add customized device build metadata fields.
PowerUsageFeatureProvider provider = FeatureFactory.getFactory(mContext)
.getPowerUsageFeatureProvider(mContext);
writeBackupData(data, KEY_BUILD_METADATA_1, provider.getBuildMetadata1(mContext));
writeBackupData(data, KEY_BUILD_METADATA_2, provider.getBuildMetadata2(mContext));
backupOptimizationMode(data, allowlistedApps);
} }
@Override @Override
@@ -301,6 +322,9 @@ public final class BatteryBackupHelper implements BackupHelper {
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()) {
return;
}
final byte[] dataContentBytes = dataContent.getBytes(); final byte[] dataContentBytes = dataContent.getBytes();
try { try {
data.writeEntityHeader(dataKey, dataContentBytes.length); data.writeEntityHeader(dataKey, dataContentBytes.length);
@@ -308,5 +332,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));
} }
} }

View File

@@ -166,4 +166,14 @@ public interface PowerUsageFeatureProvider {
* Returns {@link Set} for ignoring task root class names for screen on time * Returns {@link Set} for ignoring task root class names for screen on time
*/ */
Set<String> getIgnoreScreenOnTimeTaskRootSet(); Set<String> getIgnoreScreenOnTimeTaskRootSet();
/**
* Returns the customized device build information for data backup
*/
String getBuildMetadata1(Context context);
/**
* Returns the customized device build information for data backup
*/
String getBuildMetadata2(Context context);
} }

View File

@@ -188,4 +188,14 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider
public Set<String> getIgnoreScreenOnTimeTaskRootSet() { public Set<String> getIgnoreScreenOnTimeTaskRootSet() {
return new ArraySet<>(); return new ArraySet<>();
} }
@Override
public String getBuildMetadata1(Context context) {
return null;
}
@Override
public String getBuildMetadata2(Context context) {
return null;
}
} }

View File

@@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
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.inOrder;
@@ -45,6 +46,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.UserHandle; import android.os.UserHandle;
@@ -53,6 +55,7 @@ import android.util.ArraySet;
import com.android.settings.TestUtils; import com.android.settings.TestUtils;
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action; import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.fuelgauge.PowerAllowlistBackend; import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
import org.junit.After; import org.junit.After;
@@ -89,6 +92,7 @@ public final class BatteryBackupHelperTest {
private PrintWriter mPrintWriter; private PrintWriter mPrintWriter;
private StringWriter mStringWriter; private StringWriter mStringWriter;
private BatteryBackupHelper mBatteryBackupHelper; private BatteryBackupHelper mBatteryBackupHelper;
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
@Mock @Mock
private PackageManager mPackageManager; private PackageManager mPackageManager;
@@ -112,6 +116,8 @@ public final class BatteryBackupHelperTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mPowerUsageFeatureProvider =
FakeFeatureFactory.setupForTest().powerUsageFeatureProvider;
mContext = spy(RuntimeEnvironment.application); mContext = spy(RuntimeEnvironment.application);
mStringWriter = new StringWriter(); mStringWriter = new StringWriter();
mPrintWriter = new PrintWriter(mStringWriter); mPrintWriter = new PrintWriter(mStringWriter);
@@ -136,19 +142,11 @@ public final class BatteryBackupHelperTest {
} }
@Test @Test
public void performBackup_nullPowerList_notBackupPowerList() throws Exception { public void performBackup_emptyPowerList_backupPowerList() throws Exception {
doReturn(null).when(mDeviceController).getFullPowerWhitelist();
mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
verify(mBackupDataOutput, never()).writeEntityHeader(anyString(), anyInt());
}
@Test
public void performBackup_emptyPowerList_notBackupPowerList() throws Exception {
doReturn(new String[0]).when(mDeviceController).getFullPowerWhitelist(); doReturn(new String[0]).when(mDeviceController).getFullPowerWhitelist();
mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null); mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
verify(mBackupDataOutput, never()).writeEntityHeader(anyString(), anyInt()); verify(mBackupDataOutput, atLeastOnce()).writeEntityHeader(anyString(), anyInt());
} }
@Test @Test
@@ -330,6 +328,26 @@ public final class BatteryBackupHelperTest {
.setAppUsageState(MODE_RESTRICTED, Action.RESTORE); .setAppUsageState(MODE_RESTRICTED, Action.RESTORE);
} }
@Test
public void performBackup_backupDeviceBuildInformation() throws Exception {
final String[] fullPowerList = {"com.android.package"};
doReturn(fullPowerList).when(mDeviceController).getFullPowerWhitelist();
doReturn(null).when(mPowerUsageFeatureProvider).getBuildMetadata1(mContext);
final String deviceMetadata = "device.metadata.test_device";
doReturn(deviceMetadata).when(mPowerUsageFeatureProvider).getBuildMetadata2(mContext);
mBatteryBackupHelper.performBackup(null, mBackupDataOutput, null);
final InOrder inOrder = inOrder(mBackupDataOutput);
verifyBackupData(inOrder, BatteryBackupHelper.KEY_BUILD_BRAND, Build.BRAND);
verifyBackupData(inOrder, BatteryBackupHelper.KEY_BUILD_PRODUCT, Build.PRODUCT);
verifyBackupData(inOrder, BatteryBackupHelper.KEY_BUILD_MANUFACTURER, Build.MANUFACTURER);
verifyBackupData(inOrder, BatteryBackupHelper.KEY_BUILD_FINGERPRINT, Build.FINGERPRINT);
inOrder.verify(mBackupDataOutput, never()).writeEntityHeader(
eq(BatteryBackupHelper.KEY_BUILD_METADATA_1), anyInt());
verifyBackupData(inOrder, BatteryBackupHelper.KEY_BUILD_METADATA_2, deviceMetadata);
}
private void mockUid(int uid, String packageName) throws Exception { private void mockUid(int uid, String packageName) throws Exception {
doReturn(uid).when(mPackageManager) doReturn(uid).when(mPackageManager)
.getPackageUid(packageName, PackageManager.GET_META_DATA); .getPackageUid(packageName, PackageManager.GET_META_DATA);
@@ -401,6 +419,13 @@ public final class BatteryBackupHelperTest {
new ArraySet<>(Arrays.asList(applicationInfo1, applicationInfo2, applicationInfo3)); new ArraySet<>(Arrays.asList(applicationInfo1, applicationInfo2, applicationInfo3));
} }
private void verifyBackupData(
InOrder inOrder, String dataKey, String dataContent) throws Exception {
final byte[] expectedBytes = dataContent.getBytes();
inOrder.verify(mBackupDataOutput).writeEntityHeader(dataKey, expectedBytes.length);
inOrder.verify(mBackupDataOutput).writeEntityData(expectedBytes, expectedBytes.length);
}
@Implements(UserHandle.class) @Implements(UserHandle.class)
public static class ShadowUserHandle { public static class ShadowUserHandle {
// Sets the default as thte OWNER role. // Sets the default as thte OWNER role.