PerformBackupTask getting 2 IBackupObserver.backupFinished()
Remove IBackupObserver.backupFinished() before
executeNextState(BackupState.FINAL), add test cases to verify it and
format PerformBackupTaskTest.java
Bug: 77272662
Test: make RunFrameworksServicesRoboTests
Change-Id: Ia464d0326437fb8680ab88619829c483e2c1164d
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
index 90baea0..1f2d898 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -269,7 +269,6 @@
if (mOriginalQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
Slog.w(TAG, "Backup begun with an empty queue - nothing to do.");
backupManagerService.addBackupTrace("queue empty at begin");
- BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.SUCCESS);
executeNextState(BackupState.FINAL);
return;
}
@@ -349,8 +348,6 @@
// restage everything and try again later.
backupManagerService.resetBackupState(mStateDir); // Just to make sure.
// In case of any other error, it's backup transport error.
- BackupObserverUtils.sendBackupFinished(mObserver,
- BackupManager.ERROR_TRANSPORT_ABORTED);
executeNextState(BackupState.FINAL);
}
}
@@ -384,21 +381,11 @@
// if things went wrong at this point, we need to
// restage everything and try again later.
backupManagerService.resetBackupState(mStateDir); // Just to make sure.
- BackupObserverUtils.sendBackupFinished(mObserver,
- invokeAgentToObserverError(mStatus));
executeNextState(BackupState.FINAL);
}
}
}
- private int invokeAgentToObserverError(int error) {
- if (error == BackupTransport.AGENT_ERROR) {
- return BackupManager.ERROR_AGENT_FAILURE;
- } else {
- return BackupManager.ERROR_TRANSPORT_ABORTED;
- }
- }
-
// Transport has been initialized and the PM metadata submitted successfully
// if that was warranted. Now we process the single next thing in the queue.
private void invokeNextAgent() {
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index 5e90b3f..de2e5c6 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -17,16 +17,16 @@
package com.android.server.backup;
import static com.android.server.backup.testing.BackupManagerServiceTestUtils.createBackupWakeLock;
-import static com.android.server.backup.testing.BackupManagerServiceTestUtils
- .setUpBackupManagerServiceBasics;
-import static com.android.server.backup.testing.BackupManagerServiceTestUtils
- .startBackupThreadAndGetLooper;
+import static com.android.server.backup.testing.BackupManagerServiceTestUtils.setUpBackupManagerServiceBasics;
+import static com.android.server.backup.testing.BackupManagerServiceTestUtils.startBackupThreadAndGetLooper;
import static com.android.server.backup.testing.TestUtils.uncheck;
import static com.android.server.backup.testing.TransportData.backupTransport;
-
import static com.google.common.truth.Truth.assertThat;
-
+import static java.util.Collections.emptyList;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toList;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.argThat;
@@ -41,10 +41,6 @@
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
-import static java.util.Collections.emptyList;
-import static java.util.stream.Collectors.toCollection;
-import static java.util.stream.Collectors.toList;
-
import android.app.Application;
import android.app.IBackupAgent;
import android.app.backup.BackupAgent;
@@ -58,6 +54,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.os.DeadObjectException;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -66,7 +63,6 @@
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.util.Pair;
-
import com.android.internal.backup.IBackupTransport;
import com.android.server.backup.internal.BackupHandler;
import com.android.server.backup.internal.BackupRequest;
@@ -81,9 +77,14 @@
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.shadows.ShadowBackupDataInput;
import com.android.server.testing.shadows.ShadowBackupDataOutput;
-
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
@@ -97,20 +98,15 @@
import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.shadows.ShadowQueuedWork;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Stream;
-
@RunWith(FrameworkRobolectricTestRunner.class)
@Config(
- manifest = Config.NONE,
- sdk = 26,
- shadows = {ShadowBackupDataInput.class, ShadowBackupDataOutput.class, ShadowQueuedWork.class}
-)
+ manifest = Config.NONE,
+ sdk = 26,
+ shadows = {
+ ShadowBackupDataInput.class,
+ ShadowBackupDataOutput.class,
+ ShadowQueuedWork.class
+ })
@SystemLoaderPackages({"com.android.server.backup", "android.app.backup"})
@SystemLoaderClasses({IBackupTransport.class, IBackupAgent.class, PackageInfo.class})
@Presubmit
@@ -382,8 +378,7 @@
runTask(task);
verify(mListener).onFinished(any());
- // TODO: Should it be 2 times? (PBT.beginBackup() and PBT.finalizeBackup())
- verify(mObserver, times(2)).backupFinished(eq(BackupManager.ERROR_TRANSPORT_ABORTED));
+ verify(mObserver).backupFinished(eq(BackupManager.ERROR_TRANSPORT_ABORTED));
}
@Test
@@ -538,6 +533,57 @@
verify(mObserver).backupFinished(BackupManager.SUCCESS);
}
+ @Test
+ public void testRunTask_whenQueueEmpty() throws Exception {
+ TransportMock transportMock = setUpTransport(mTransport);
+ PerformBackupTask task =
+ createPerformBackupTask(
+ transportMock.transportClient, mTransport.transportDirName, true);
+
+ runTask(task);
+
+ verify(mObserver).backupFinished(eq(BackupManager.SUCCESS));
+ }
+
+ @Test
+ public void testRunTask_whenIncrementalAndTransportUnavailableDuringPmBackup()
+ throws Exception {
+ TransportMock transportMock = setUpTransport(mTransport);
+ IBackupTransport transportBinder = transportMock.transport;
+ setUpAgent(PACKAGE_1);
+ when(transportBinder.getBackupQuota(
+ eq(BackupManagerService.PACKAGE_MANAGER_SENTINEL), anyBoolean()))
+ .thenThrow(DeadObjectException.class);
+ PerformBackupTask task =
+ createPerformBackupTask(
+ transportMock.transportClient,
+ mTransport.transportDirName,
+ false,
+ PACKAGE_1);
+
+ runTask(task);
+
+ verify(mListener).onFinished(any());
+ verify(mObserver).backupFinished(eq(BackupManager.ERROR_TRANSPORT_ABORTED));
+ }
+
+ @Test
+ public void testRunTask_whenIncrementalAndAgentFails() throws Exception {
+ TransportMock transportMock = setUpTransport(mTransport);
+ createFakePmAgent();
+ PerformBackupTask task =
+ createPerformBackupTask(
+ transportMock.transportClient,
+ mTransport.transportDirName,
+ false,
+ PACKAGE_1);
+
+ runTask(task);
+
+ verify(mListener).onFinished(any());
+ verify(mObserver).backupFinished(eq(BackupManager.ERROR_TRANSPORT_ABORTED));
+ }
+
private void runTask(PerformBackupTask task) {
Message message = mBackupHandler.obtainMessage(BackupHandler.MSG_BACKUP_RESTORE_STEP, task);
mBackupHandler.sendMessage(message);
@@ -637,6 +683,19 @@
return pmAgent;
}
+ /**
+ * Returns an implementation of PackageManagerBackupAgent that throws RuntimeException in {@link
+ * BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)}
+ */
+ private PackageManagerBackupAgent createFakePmAgent() {
+ PackageManagerBackupAgent fakePmAgent =
+ new FakePackageManagerBackupAgent(mApplication.getPackageManager());
+ fakePmAgent.attach(mApplication);
+ fakePmAgent.onCreate();
+ when(mBackupManagerService.makeMetadataAgent()).thenReturn(fakePmAgent);
+ return fakePmAgent;
+ }
+
/** Matches {@link PackageInfo} whose package name is {@code packageName}. */
private static ArgumentMatcher<PackageInfo> packageInfo(String packageName) {
// We have to test for packageInfo nulity because of Mockito's own stubbing with argThat().
@@ -713,4 +772,18 @@
mBackupHandler.sendMessage(message);
}
}
+
+ private static class FakePackageManagerBackupAgent extends PackageManagerBackupAgent {
+ public FakePackageManagerBackupAgent(PackageManager packageMgr) {
+ super(packageMgr);
+ }
+
+ @Override
+ public void onBackup(
+ ParcelFileDescriptor oldState,
+ BackupDataOutput data,
+ ParcelFileDescriptor newState) {
+ throw new RuntimeException();
+ }
+ }
}