Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c709366f authored by Bernardo Rufino's avatar Bernardo Rufino Committed by Android (Google) Code Review
Browse files

Merge "More tests for ActiveRestoreSession"

parents 8a771ee9 12b6bafc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -302,7 +302,7 @@ public class BackupHandler extends Handler {
                    sets = transport.getAvailableRestoreSets();
                    // cache the result in the active session
                    synchronized (params.session) {
                        params.session.mRestoreSets = sets;
                        params.session.setRestoreSets(sets);
                    }
                    if (sets == null) {
                        EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+5 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.backup.params;

import android.annotation.Nullable;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IRestoreObserver;
import android.content.pm.PackageInfo;
@@ -28,10 +29,10 @@ public class RestoreParams {
    public final IRestoreObserver observer;
    public final IBackupManagerMonitor monitor;
    public final long token;
    public final PackageInfo packageInfo;
    @Nullable public final PackageInfo packageInfo;
    public final int pmToken; // in post-install restore, the PM's token for this transaction
    public final boolean isSystemRestore;
    public final String[] filterSet;
    @Nullable public final String[] filterSet;
    public final OnTaskFinishedListener listener;

    /**
@@ -129,10 +130,10 @@ public class RestoreParams {
            IRestoreObserver observer,
            IBackupManagerMonitor monitor,
            long token,
            PackageInfo packageInfo,
            @Nullable PackageInfo packageInfo,
            int pmToken,
            boolean isSystemRestore,
            String[] filterSet,
            @Nullable String[] filterSet,
            OnTaskFinishedListener listener) {
        this.transportClient = transportClient;
        this.observer = observer;
+10 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSI
import static com.android.server.backup.internal.BackupHandler.MSG_RUN_GET_RESTORE_SETS;
import static com.android.server.backup.internal.BackupHandler.MSG_RUN_RESTORE;

import android.annotation.Nullable;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IRestoreObserver;
import android.app.backup.IRestoreSession;
@@ -53,13 +54,15 @@ public class ActiveRestoreSession extends IRestoreSession.Stub {
    private final TransportManager mTransportManager;
    private final String mTransportName;
    private final BackupManagerService mBackupManagerService;
    private final String mPackageName;
    @Nullable private final String mPackageName;
    public RestoreSet[] mRestoreSets = null;
    boolean mEnded = false;
    boolean mTimedOut = false;

    public ActiveRestoreSession(BackupManagerService backupManagerService,
            String packageName, String transportName) {
    public ActiveRestoreSession(
            BackupManagerService backupManagerService,
            @Nullable String packageName,
            String transportName) {
        mBackupManagerService = backupManagerService;
        mPackageName = packageName;
        mTransportManager = backupManagerService.getTransportManager();
@@ -360,6 +363,10 @@ public class ActiveRestoreSession extends IRestoreSession.Stub {
        }
    }

    public void setRestoreSets(RestoreSet[] restoreSets) {
        mRestoreSets = restoreSets;
    }

    /**
     * Returns 0 if operation sent or -1 otherwise.
     */
+14 −7
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTOR
import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;

import android.annotation.Nullable;
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
import android.app.backup.BackupDataInput;
@@ -158,12 +159,18 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {

    private final int mEphemeralOpToken;

    // Invariant: mWakelock is already held, and this task is responsible for
    // releasing it at the end of the restore operation.
    public PerformUnifiedRestoreTask(BackupManagerService backupManagerService,
            TransportClient transportClient, IRestoreObserver observer,
            IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
            int pmToken, boolean isFullSystemRestore, String[] filterSet,
    // This task can assume that the wakelock is properly held for it and doesn't have to worry
    // about releasing it.
    public PerformUnifiedRestoreTask(
            BackupManagerService backupManagerService,
            TransportClient transportClient,
            IRestoreObserver observer,
            IBackupManagerMonitor monitor,
            long restoreSetToken,
            @Nullable PackageInfo targetPackage,
            int pmToken,
            boolean isFullSystemRestore,
            @Nullable String[] filterSet,
            OnTaskFinishedListener listener) {
        this.backupManagerService = backupManagerService;
        mTransportManager = backupManagerService.getTransportManager();
@@ -336,7 +343,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
     *
     *   [ state change => FINAL ]
     *
     * 7. t.finishRestore(), release wakelock, etc.
     * 7. t.finishRestore(), call listeners, etc.
     *
     *
     */
+256 −3
Original line number Diff line number Diff line
@@ -25,8 +25,10 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
@@ -39,6 +41,7 @@ import android.app.backup.IRestoreSession;
import android.app.backup.RestoreSet;
import android.os.Looper;
import android.os.PowerManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;

import com.android.server.EventLogTags;
@@ -51,7 +54,9 @@ import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.shadows.ShadowEventLog;
import com.android.server.testing.shadows.ShadowPerformUnifiedRestoreTask;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -62,8 +67,14 @@ import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowLooper;

import java.util.ArrayDeque;

@RunWith(FrameworkRobolectricTestRunner.class)
@Config(manifest = Config.NONE, sdk = 26, shadows = ShadowEventLog.class)
@Config(
    manifest = Config.NONE,
    sdk = 26,
    shadows = {ShadowEventLog.class, ShadowPerformUnifiedRestoreTask.class}
)
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class ActiveRestoreSessionTest {
@@ -78,6 +89,8 @@ public class ActiveRestoreSessionTest {
    private ShadowApplication mShadowApplication;
    private PowerManager.WakeLock mWakeLock;
    private TransportData mTransport;
    private long mToken1;
    private long mToken2;
    private RestoreSet mRestoreSet1;
    private RestoreSet mRestoreSet2;

@@ -87,8 +100,10 @@ public class ActiveRestoreSessionTest {

        mTransport = backupTransport();

        mRestoreSet1 = new RestoreSet("name1", "device1", 1L);
        mRestoreSet2 = new RestoreSet("name2", "device2", 2L);
        mToken1 = 1L;
        mRestoreSet1 = new RestoreSet("name1", "device1", mToken1);
        mToken2 = 2L;
        mRestoreSet2 = new RestoreSet("name2", "device2", mToken2);

        Application application = RuntimeEnvironment.application;
        mShadowApplication = shadowOf(application);
@@ -106,6 +121,12 @@ public class ActiveRestoreSessionTest {
                application.getPackageManager(),
                backupHandler,
                mWakeLock);
        when(mBackupManagerService.getPendingRestores()).thenReturn(new ArrayDeque<>());
    }

    @After
    public void tearDown() throws Exception {
        ShadowPerformUnifiedRestoreTask.reset();
    }

    @Test
@@ -193,12 +214,244 @@ public class ActiveRestoreSessionTest {
        assertThat(mWakeLock.isHeld()).isFalse();
    }

    @Test
    public void testRestoreAll() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        doCallRealMethod().when(mBackupManagerService).setRestoreInProgress(anyBoolean());
        when(mBackupManagerService.isRestoreInProgress()).thenCallRealMethod();
        TransportMock transportMock = setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);

        int result = restoreSession.restoreAll(mToken1, mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(0);
        verify(mTransportManager)
                .disposeOfTransportClient(eq(transportMock.transportClient), any());
        assertThat(mWakeLock.isHeld()).isFalse();
        assertThat(mBackupManagerService.isRestoreInProgress()).isFalse();
        // Verify it created the task properly
        ShadowPerformUnifiedRestoreTask shadowTask =
                ShadowPerformUnifiedRestoreTask.getLastCreated();
        assertThat(shadowTask.isFullSystemRestore()).isTrue();
        assertThat(shadowTask.getFilterSet()).isNull();
        assertThat(shadowTask.getPackage()).isNull();
    }

    @Test
    public void testRestoreAll_whenNoRestoreSets() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);

        int result = restoreSession.restoreAll(mToken1, mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(-1);
        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated()).isNull();
    }

    @Test
    public void testRestoreAll_whenSinglePackageSession() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(PACKAGE_1, mTransport, mRestoreSet1);

        int result = restoreSession.restoreAll(mToken1, mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(-1);
        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated()).isNull();
    }

    @Test
    public void testRestoreAll_whenSessionEnded() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
        restoreSession.endRestoreSession();
        mShadowBackupLooper.runToEndOfTasks();

        expectThrows(
                IllegalStateException.class,
                () -> restoreSession.restoreAll(mToken1, mObserver, mMonitor));
    }

    @Test
    public void testRestoreAll_whenTransportNotRegistered() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport.unregistered());
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);

        int result = restoreSession.restoreAll(mToken1, mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(-1);
        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated()).isNull();
    }

    @Test
    public void testRestoreAll_whenRestoreInProgress_addsToPendingRestores() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        when(mBackupManagerService.isRestoreInProgress()).thenReturn(true);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);

        int result = restoreSession.restoreAll(mToken1, mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(0);
        assertThat(mBackupManagerService.getPendingRestores()).hasSize(1);
    }

    @Test
    public void testRestoreSome_for2Packages() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        TransportMock transportMock = setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);

        int result =
                restoreSession.restoreSome(
                        mToken1, mObserver, mMonitor, new String[] {PACKAGE_1, PACKAGE_2});

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(0);
        verify(mTransportManager)
                .disposeOfTransportClient(eq(transportMock.transportClient), any());
        assertThat(mWakeLock.isHeld()).isFalse();
        assertThat(mBackupManagerService.isRestoreInProgress()).isFalse();
        ShadowPerformUnifiedRestoreTask shadowTask =
                ShadowPerformUnifiedRestoreTask.getLastCreated();
        assertThat(shadowTask.getFilterSet()).asList().containsExactly(PACKAGE_1, PACKAGE_2);
        assertThat(shadowTask.getPackage()).isNull();
    }

    @Test
    public void testRestoreSome_for2Packages_createsSystemRestoreTask() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);

        restoreSession.restoreSome(
                mToken1, mObserver, mMonitor, new String[] {PACKAGE_1, PACKAGE_2});

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated().isFullSystemRestore()).isTrue();
    }

    @Test
    public void testRestoreSome_for1Package() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);

        restoreSession.restoreSome(mToken1, mObserver, mMonitor, new String[] {PACKAGE_1});

        mShadowBackupLooper.runToEndOfTasks();
        ShadowPerformUnifiedRestoreTask shadowTask =
                ShadowPerformUnifiedRestoreTask.getLastCreated();
        assertThat(shadowTask.getFilterSet()).asList().containsExactly(PACKAGE_1);
        assertThat(shadowTask.getPackage()).isNull();
    }

    @Test
    public void testRestoreSome_for1Package_createsNonSystemRestoreTask() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);

        restoreSession.restoreSome(mToken1, mObserver, mMonitor, new String[] {PACKAGE_1});

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated().isFullSystemRestore())
                .isFalse();
    }

    @Test
    public void testRestoreSome_whenNoRestoreSets() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);

        int result =
                restoreSession.restoreSome(mToken1, mObserver, mMonitor, new String[] {PACKAGE_1});

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(-1);
        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated()).isNull();
    }

    @Test
    public void testRestoreSome_whenSinglePackageSession() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(PACKAGE_1, mTransport, mRestoreSet1);

        int result =
                restoreSession.restoreSome(mToken1, mObserver, mMonitor, new String[] {PACKAGE_2});

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(-1);
        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated()).isNull();
    }

    @Test
    public void testRestoreSome_whenSessionEnded() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);
        restoreSession.endRestoreSession();
        mShadowBackupLooper.runToEndOfTasks();

        expectThrows(
                IllegalStateException.class,
                () ->
                        restoreSession.restoreSome(
                                mToken1, mObserver, mMonitor, new String[] {PACKAGE_1}));
    }

    @Test
    public void testRestoreSome_whenTransportNotRegistered() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport.unregistered());
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);

        int result =
                restoreSession.restoreSome(mToken1, mObserver, mMonitor, new String[] {PACKAGE_1});

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(-1);
        assertThat(ShadowPerformUnifiedRestoreTask.getLastCreated()).isNull();
    }

    private IRestoreSession createActiveRestoreSession(
            String packageName, TransportData transport) {
        return new ActiveRestoreSession(
                mBackupManagerService, packageName, transport.transportName);
    }

    private IRestoreSession createActiveRestoreSessionWithRestoreSets(
            String packageName, TransportData transport, RestoreSet... restoreSets)
            throws RemoteException {
        ActiveRestoreSession restoreSession =
                new ActiveRestoreSession(
                        mBackupManagerService, packageName, transport.transportName);
        restoreSession.setRestoreSets(restoreSets);
        return restoreSession;
    }

    private TransportMock setUpTransport(TransportData transport) throws Exception {
        return TransportTestUtils.setUpTransport(mTransportManager, transport);
    }
Loading