Loading services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java +11 −3 Original line number Diff line number Diff line Loading @@ -260,6 +260,10 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { @Nullable private ParcelFileDescriptor mSavedState; @Nullable private ParcelFileDescriptor mBackupData; @Nullable private ParcelFileDescriptor mNewState; // Indicates whether there was any data to be backed up, i.e. the queue was not empty // and at least one of the packages had data. Used to avoid updating current token for // empty backups. private boolean mHasDataToBackup; /** * This {@link ConditionVariable} is used to signal that the cancel operation has been Loading Loading @@ -332,6 +336,8 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { public void run() { Process.setThreadPriority(THREAD_PRIORITY); mHasDataToBackup = false; int status = BackupTransport.TRANSPORT_OK; try { startTask(); Loading Loading @@ -529,10 +535,10 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { String callerLogString = "KVBT.finishTask()"; // If we succeeded and this is the first time we've done a backup, we can record the current // backup dataset token. // If the backup data was not empty, we succeeded and this is the first time // we've done a backup, we can record the current backup dataset token. long currentToken = mBackupManagerService.getCurrentToken(); if ((status == BackupTransport.TRANSPORT_OK) && (currentToken == 0)) { if (mHasDataToBackup && (status == BackupTransport.TRANSPORT_OK) && (currentToken == 0)) { try { IBackupTransport transport = mTransportClient.connectOrThrow(callerLogString); mBackupManagerService.setCurrentToken(transport.getCurrentRestoreSet()); Loading Loading @@ -838,6 +844,8 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { return BackupTransport.TRANSPORT_OK; } mHasDataToBackup = true; int status; try (ParcelFileDescriptor backupData = ParcelFileDescriptor.open(backupDataFile, MODE_READ_ONLY)) { Loading services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java +40 −3 Original line number Diff line number Diff line Loading @@ -25,9 +25,12 @@ import static android.app.backup.BackupManager.SUCCESS; import static android.app.backup.ForwardingBackupAgent.forward; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createBackupWakeLock; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createInitializedBackupManagerService; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBackupManagerServiceBasics; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBinderCallerAndApplicationAsSystem; import static com.android.server.backup.testing.BackupManagerServiceTestUtils .createInitializedBackupManagerService; import static com.android.server.backup.testing.BackupManagerServiceTestUtils .setUpBackupManagerServiceBasics; import static com.android.server.backup.testing.BackupManagerServiceTestUtils .setUpBinderCallerAndApplicationAsSystem; import static com.android.server.backup.testing.PackageData.PM_PACKAGE; import static com.android.server.backup.testing.PackageData.fullBackupPackage; import static com.android.server.backup.testing.PackageData.keyValuePackage; Loading Loading @@ -327,6 +330,22 @@ public class KeyValueBackupTaskTest { .isEqualTo("packageState".getBytes()); } /** * Do not update backup token if the backup queue was empty */ @Test public void testRunTask_whenQueueEmptyOnFirstBackup_doesNotUpdateCurrentToken() throws Exception { TransportMock transportMock = setUpInitializedTransport(mTransport); KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true); mBackupManagerService.setCurrentToken(0L); when(transportMock.transport.getCurrentRestoreSet()).thenReturn(1234L); runTask(task); assertThat(mBackupManagerService.getCurrentToken()).isEqualTo(0L); } @Test public void testRunTask_whenOnePackageAndTransportUnavailable() throws Exception { TransportMock transportMock = setUpInitializedTransport(mTransport.unavailable()); Loading Loading @@ -2297,6 +2316,24 @@ public class KeyValueBackupTaskTest { expectThrows(IllegalArgumentException.class, () -> task.handleCancel(false)); } /** * Do not update backup token if no data was moved. */ @Test public void testRunTask_whenNoDataToBackupOnFirstBackup_doesNotUpdateCurrentToken() throws Exception { TransportMock transportMock = setUpInitializedTransport(mTransport); mBackupManagerService.setCurrentToken(0L); when(transportMock.transport.getCurrentRestoreSet()).thenReturn(1234L); // Set up agent with no data. setUpAgent(PACKAGE_1); KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true, PACKAGE_1); runTask(task); assertThat(mBackupManagerService.getCurrentToken()).isEqualTo(0L); } private void runTask(KeyValueBackupTask task) { // Pretend we are not on the main-thread to prevent RemoteCall from complaining mShadowMainLooper.setCurrentThread(false); Loading Loading
services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java +11 −3 Original line number Diff line number Diff line Loading @@ -260,6 +260,10 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { @Nullable private ParcelFileDescriptor mSavedState; @Nullable private ParcelFileDescriptor mBackupData; @Nullable private ParcelFileDescriptor mNewState; // Indicates whether there was any data to be backed up, i.e. the queue was not empty // and at least one of the packages had data. Used to avoid updating current token for // empty backups. private boolean mHasDataToBackup; /** * This {@link ConditionVariable} is used to signal that the cancel operation has been Loading Loading @@ -332,6 +336,8 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { public void run() { Process.setThreadPriority(THREAD_PRIORITY); mHasDataToBackup = false; int status = BackupTransport.TRANSPORT_OK; try { startTask(); Loading Loading @@ -529,10 +535,10 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { String callerLogString = "KVBT.finishTask()"; // If we succeeded and this is the first time we've done a backup, we can record the current // backup dataset token. // If the backup data was not empty, we succeeded and this is the first time // we've done a backup, we can record the current backup dataset token. long currentToken = mBackupManagerService.getCurrentToken(); if ((status == BackupTransport.TRANSPORT_OK) && (currentToken == 0)) { if (mHasDataToBackup && (status == BackupTransport.TRANSPORT_OK) && (currentToken == 0)) { try { IBackupTransport transport = mTransportClient.connectOrThrow(callerLogString); mBackupManagerService.setCurrentToken(transport.getCurrentRestoreSet()); Loading Loading @@ -838,6 +844,8 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable { return BackupTransport.TRANSPORT_OK; } mHasDataToBackup = true; int status; try (ParcelFileDescriptor backupData = ParcelFileDescriptor.open(backupDataFile, MODE_READ_ONLY)) { Loading
services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java +40 −3 Original line number Diff line number Diff line Loading @@ -25,9 +25,12 @@ import static android.app.backup.BackupManager.SUCCESS; import static android.app.backup.ForwardingBackupAgent.forward; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createBackupWakeLock; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createInitializedBackupManagerService; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBackupManagerServiceBasics; import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBinderCallerAndApplicationAsSystem; import static com.android.server.backup.testing.BackupManagerServiceTestUtils .createInitializedBackupManagerService; import static com.android.server.backup.testing.BackupManagerServiceTestUtils .setUpBackupManagerServiceBasics; import static com.android.server.backup.testing.BackupManagerServiceTestUtils .setUpBinderCallerAndApplicationAsSystem; import static com.android.server.backup.testing.PackageData.PM_PACKAGE; import static com.android.server.backup.testing.PackageData.fullBackupPackage; import static com.android.server.backup.testing.PackageData.keyValuePackage; Loading Loading @@ -327,6 +330,22 @@ public class KeyValueBackupTaskTest { .isEqualTo("packageState".getBytes()); } /** * Do not update backup token if the backup queue was empty */ @Test public void testRunTask_whenQueueEmptyOnFirstBackup_doesNotUpdateCurrentToken() throws Exception { TransportMock transportMock = setUpInitializedTransport(mTransport); KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true); mBackupManagerService.setCurrentToken(0L); when(transportMock.transport.getCurrentRestoreSet()).thenReturn(1234L); runTask(task); assertThat(mBackupManagerService.getCurrentToken()).isEqualTo(0L); } @Test public void testRunTask_whenOnePackageAndTransportUnavailable() throws Exception { TransportMock transportMock = setUpInitializedTransport(mTransport.unavailable()); Loading Loading @@ -2297,6 +2316,24 @@ public class KeyValueBackupTaskTest { expectThrows(IllegalArgumentException.class, () -> task.handleCancel(false)); } /** * Do not update backup token if no data was moved. */ @Test public void testRunTask_whenNoDataToBackupOnFirstBackup_doesNotUpdateCurrentToken() throws Exception { TransportMock transportMock = setUpInitializedTransport(mTransport); mBackupManagerService.setCurrentToken(0L); when(transportMock.transport.getCurrentRestoreSet()).thenReturn(1234L); // Set up agent with no data. setUpAgent(PACKAGE_1); KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true, PACKAGE_1); runTask(task); assertThat(mBackupManagerService.getCurrentToken()).isEqualTo(0L); } private void runTask(KeyValueBackupTask task) { // Pretend we are not on the main-thread to prevent RemoteCall from complaining mShadowMainLooper.setCurrentThread(false); Loading