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 Original line Diff line number Diff line
@@ -302,7 +302,7 @@ public class BackupHandler extends Handler {
                    sets = transport.getAvailableRestoreSets();
                    sets = transport.getAvailableRestoreSets();
                    // cache the result in the active session
                    // cache the result in the active session
                    synchronized (params.session) {
                    synchronized (params.session) {
                        params.session.mRestoreSets = sets;
                        params.session.setRestoreSets(sets);
                    }
                    }
                    if (sets == null) {
                    if (sets == null) {
                        EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
                        EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
+5 −4
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.server.backup.params;
package com.android.server.backup.params;


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


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


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


    public ActiveRestoreSession(BackupManagerService backupManagerService,
    public ActiveRestoreSession(
            String packageName, String transportName) {
            BackupManagerService backupManagerService,
            @Nullable String packageName,
            String transportName) {
        mBackupManagerService = backupManagerService;
        mBackupManagerService = backupManagerService;
        mPackageName = packageName;
        mPackageName = packageName;
        mTransportManager = backupManagerService.getTransportManager();
        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.
     * Returns 0 if operation sent or -1 otherwise.
     */
     */
+14 −7
Original line number Original line 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_OPERATION_TIMEOUT;
import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;


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


    private final int mEphemeralOpToken;
    private final int mEphemeralOpToken;


    // Invariant: mWakelock is already held, and this task is responsible for
    // This task can assume that the wakelock is properly held for it and doesn't have to worry
    // releasing it at the end of the restore operation.
    // about releasing it.
    public PerformUnifiedRestoreTask(BackupManagerService backupManagerService,
    public PerformUnifiedRestoreTask(
            TransportClient transportClient, IRestoreObserver observer,
            BackupManagerService backupManagerService,
            IBackupManagerMonitor monitor, long restoreSetToken, PackageInfo targetPackage,
            TransportClient transportClient,
            int pmToken, boolean isFullSystemRestore, String[] filterSet,
            IRestoreObserver observer,
            IBackupManagerMonitor monitor,
            long restoreSetToken,
            @Nullable PackageInfo targetPackage,
            int pmToken,
            boolean isFullSystemRestore,
            @Nullable String[] filterSet,
            OnTaskFinishedListener listener) {
            OnTaskFinishedListener listener) {
        this.backupManagerService = backupManagerService;
        this.backupManagerService = backupManagerService;
        mTransportManager = backupManagerService.getTransportManager();
        mTransportManager = backupManagerService.getTransportManager();
@@ -336,7 +343,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
     *
     *
     *   [ state change => FINAL ]
     *   [ state change => FINAL ]
     *
     *
     * 7. t.finishRestore(), release wakelock, etc.
     * 7. t.finishRestore(), call listeners, etc.
     *
     *
     *
     *
     */
     */
+256 −3
Original line number Original line 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.AdditionalMatchers.aryEq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import static org.robolectric.Shadows.shadowOf;
@@ -39,6 +41,7 @@ import android.app.backup.IRestoreSession;
import android.app.backup.RestoreSet;
import android.app.backup.RestoreSet;
import android.os.Looper;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.Presubmit;


import com.android.server.EventLogTags;
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.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.shadows.ShadowEventLog;
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.Before;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
@@ -62,8 +67,14 @@ import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowLooper;


import java.util.ArrayDeque;

@RunWith(FrameworkRobolectricTestRunner.class)
@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"})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
@Presubmit
public class ActiveRestoreSessionTest {
public class ActiveRestoreSessionTest {
@@ -78,6 +89,8 @@ public class ActiveRestoreSessionTest {
    private ShadowApplication mShadowApplication;
    private ShadowApplication mShadowApplication;
    private PowerManager.WakeLock mWakeLock;
    private PowerManager.WakeLock mWakeLock;
    private TransportData mTransport;
    private TransportData mTransport;
    private long mToken1;
    private long mToken2;
    private RestoreSet mRestoreSet1;
    private RestoreSet mRestoreSet1;
    private RestoreSet mRestoreSet2;
    private RestoreSet mRestoreSet2;


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


        mTransport = backupTransport();
        mTransport = backupTransport();


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


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

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


    @Test
    @Test
@@ -193,12 +214,244 @@ public class ActiveRestoreSessionTest {
        assertThat(mWakeLock.isHeld()).isFalse();
        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(
    private IRestoreSession createActiveRestoreSession(
            String packageName, TransportData transport) {
            String packageName, TransportData transport) {
        return new ActiveRestoreSession(
        return new ActiveRestoreSession(
                mBackupManagerService, packageName, transport.transportName);
                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 {
    private TransportMock setUpTransport(TransportData transport) throws Exception {
        return TransportTestUtils.setUpTransport(mTransportManager, transport);
        return TransportTestUtils.setUpTransport(mTransportManager, transport);
    }
    }
Loading