/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.server.backup.restore;

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.TestUtils.assertEventLogged;
import static com.android.server.backup.testing.TestUtils.assertEventNotLogged;
import static com.android.server.backup.testing.TransportData.backupTransport;

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;
import static org.testng.Assert.expectThrows;

import android.app.Application;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IRestoreObserver;
import android.app.backup.IRestoreSession;
import android.app.backup.RestoreSet;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;

import com.android.server.EventLogTags;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.TransportManager;
import com.android.server.backup.UserBackupManagerService;
import com.android.server.backup.internal.BackupHandler;
import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportTestUtils;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.testing.shadows.ShadowApplicationPackageManager;
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;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowBinder;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowPackageManager;

import java.util.ArrayDeque;

@RunWith(RobolectricTestRunner.class)
@Config(
        shadows = {
            ShadowApplicationPackageManager.class,
            ShadowBinder.class,
            ShadowEventLog.class,
            ShadowPerformUnifiedRestoreTask.class
        })
@Presubmit
public class ActiveRestoreSessionTest {
    private static final String PACKAGE_1 = "com.example.package1";
    private static final String PACKAGE_2 = "com.example.package2";
    private static final long TOKEN_1 = 1L;
    private static final long TOKEN_2 = 2L;

    @Mock private UserBackupManagerService mBackupManagerService;
    @Mock private TransportManager mTransportManager;
    @Mock private IRestoreObserver mObserver;
    @Mock private IBackupManagerMonitor mMonitor;
    private ShadowLooper mShadowBackupLooper;
    private ShadowApplication mShadowApplication;
    private PowerManager.WakeLock mWakeLock;
    private TransportData mTransport;
    private RestoreSet mRestoreSet1;
    private RestoreSet mRestoreSet2;
    private ShadowPackageManager mShadowPackageManager;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        mTransport = backupTransport();

        mRestoreSet1 = new RestoreSet("name1", "device1", TOKEN_1);
        mRestoreSet2 = new RestoreSet("name2", "device2", TOKEN_2);

        Application application = RuntimeEnvironment.application;
        mShadowApplication = shadowOf(application);

        mShadowPackageManager = shadowOf(application.getPackageManager());

        Looper backupLooper = startBackupThreadAndGetLooper();
        mShadowBackupLooper = shadowOf(backupLooper);

        Handler mainHandler = new Handler(Looper.getMainLooper());
        BackupAgentTimeoutParameters agentTimeoutParameters =
                new BackupAgentTimeoutParameters(mainHandler, application.getContentResolver());
        agentTimeoutParameters.start();

        // We need to mock BMS timeout parameters before initializing the BackupHandler since
        // the constructor of BackupHandler relies on it.
        when(mBackupManagerService.getAgentTimeoutParameters()).thenReturn(agentTimeoutParameters);
        BackupHandler backupHandler = new BackupHandler(mBackupManagerService, backupLooper);

        mWakeLock = createBackupWakeLock(application);

        // TODO: Migrate to use spy(createInitializedBackupManagerService())
        setUpBackupManagerServiceBasics(
                mBackupManagerService,
                application,
                mTransportManager,
                application.getPackageManager(),
                backupHandler,
                mWakeLock,
                agentTimeoutParameters);
        when(mBackupManagerService.getPendingRestores()).thenReturn(new ArrayDeque<>());
    }

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

    @Test
    public void testGetAvailableRestoreSets_withoutPermission() throws Exception {
        mShadowApplication.denyPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);

        expectThrows(
                SecurityException.class,
                () -> restoreSession.getAvailableRestoreSets(mObserver, mMonitor));
    }

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

        expectThrows(
                RuntimeException.class,
                () -> restoreSession.getAvailableRestoreSets(null, mMonitor));
    }

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

        int result = restoreSession.getAvailableRestoreSets(mObserver, mMonitor);

        assertThat(result).isEqualTo(-1);
    }

    @Test
    public void testGetAvailableRestoreSets() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        TransportMock transportMock = setUpTransport(mTransport);
        when(transportMock.transport.getAvailableRestoreSets())
                .thenReturn(new RestoreSet[] {mRestoreSet1, mRestoreSet2});
        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);

        int result = restoreSession.getAvailableRestoreSets(mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(0);
        verify(mObserver)
                .restoreSetsAvailable(aryEq(new RestoreSet[] {mRestoreSet1, mRestoreSet2}));
        verify(mTransportManager)
                .disposeOfTransportClient(eq(transportMock.transportClient), any());
        assertThat(mWakeLock.isHeld()).isFalse();
    }

    @Test
    public void testGetAvailableRestoreSets_forEmptyRestoreSets() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        TransportMock transportMock = setUpTransport(mTransport);
        when(transportMock.transport.getAvailableRestoreSets()).thenReturn(new RestoreSet[0]);
        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);

        int result = restoreSession.getAvailableRestoreSets(mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(0);
        verify(mObserver).restoreSetsAvailable(aryEq(new RestoreSet[0]));
        assertEventNotLogged(EventLogTags.RESTORE_TRANSPORT_FAILURE);
    }

    @Test
    public void testGetAvailableRestoreSets_forNullRestoreSets() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        TransportMock transportMock = setUpTransport(mTransport);
        when(transportMock.transport.getAvailableRestoreSets()).thenReturn(null);
        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);

        int result = restoreSession.getAvailableRestoreSets(mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(0);
        verify(mObserver).restoreSetsAvailable(isNull());
        assertEventLogged(EventLogTags.RESTORE_TRANSPORT_FAILURE);
        verify(mTransportManager)
                .disposeOfTransportClient(eq(transportMock.transportClient), any());
        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(TOKEN_1, 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(TOKEN_1, mObserver, mMonitor);

        assertThat(result).isEqualTo(-1);
    }

    @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(TOKEN_1, mObserver, mMonitor);

        assertThat(result).isEqualTo(-1);
    }

    @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(TOKEN_1, 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(TOKEN_1, mObserver, mMonitor);

        assertThat(result).isEqualTo(-1);
    }

    @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(TOKEN_1, mObserver, mMonitor);

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

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

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

        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 testRestorePackages_for2Packages_createsSystemRestoreTask() throws Exception {
        mShadowApplication.grantPermissions(android.Manifest.permission.BACKUP);
        setUpTransport(mTransport);
        IRestoreSession restoreSession =
                createActiveRestoreSessionWithRestoreSets(null, mTransport, mRestoreSet1);

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

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

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

        restoreSession.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_1}, mMonitor);

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

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

        restoreSession.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_1}, mMonitor);

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

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

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

        assertThat(result).isEqualTo(-1);
    }

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

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

        assertThat(result).isEqualTo(-1);
    }

    @Test
    public void testRestorePackages_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.restorePackages(TOKEN_1, mObserver, new String[] {PACKAGE_1},
                                mMonitor));
    }

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

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

        assertThat(result).isEqualTo(-1);
    }

    @Test
    public void testRestorePackage_whenCallerIsPackage() throws Exception {
        // No need for BACKUP permission in this case
        mShadowApplication.denyPermissions(android.Manifest.permission.BACKUP);
        ShadowBinder.setCallingUid(1);
        setUpPackage(PACKAGE_1, /* uid */ 1);
        when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1);
        TransportMock transportMock = setUpTransport(mTransport);
        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);

        int result = restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor);

        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.isFullSystemRestore()).isFalse();
        assertThat(shadowTask.getFilterSet()).isNull();
        assertThat(shadowTask.getPackage().packageName).isEqualTo(PACKAGE_1);
    }

    @Test
    public void testRestorePackage_whenPackageNullWhenCreated() throws Exception {
        ShadowBinder.setCallingUid(1);
        setUpPackage(PACKAGE_1, /* uid */ 1);
        when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1);
        setUpTransport(mTransport);
        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);

        int result = restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(0);
    }

    @Test
    public void testRestorePackage_whenCallerIsNotPackageAndPermissionGranted() throws Exception {
        final int pid = 1211;
        final int uid = 1;
        mShadowApplication.grantPermissions(pid, uid, android.Manifest.permission.BACKUP);
        ShadowBinder.setCallingPid(pid);
        ShadowBinder.setCallingUid(uid);
        setUpPackage(PACKAGE_1, /* uid */ 2);
        when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1);
        setUpTransport(mTransport);
        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);

        int result = restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(0);
    }

    @Test
    public void testRestorePackage_whenCallerIsNotPackageAndPermissionDenied() throws Exception {
        final int pid = 1211;
        final int uid = 1;
        mShadowApplication.denyPermissions(pid, uid, android.Manifest.permission.BACKUP);
        ShadowBinder.setCallingPid(pid);
        ShadowBinder.setCallingUid(uid);
        setUpPackage(PACKAGE_1, /* uid */ 2);
        when(mBackupManagerService.getAvailableRestoreToken(PACKAGE_1)).thenReturn(TOKEN_1);
        setUpTransport(mTransport);
        IRestoreSession restoreSession = createActiveRestoreSession(PACKAGE_1, mTransport);

        expectThrows(
                SecurityException.class,
                () -> restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor));
    }

    @Test
    public void testRestorePackage_whenPackageNotFound() throws Exception {
        final int pid = 1211;
        final int uid = 1;
        mShadowApplication.grantPermissions(pid, uid, android.Manifest.permission.BACKUP);
        ShadowBinder.setCallingPid(pid);
        ShadowBinder.setCallingUid(uid);
        setUpPackage(PACKAGE_1, /* uid */ 1);
        setUpTransport(mTransport);
        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);

        int result = restoreSession.restorePackage(PACKAGE_2, mObserver, mMonitor);

        assertThat(result).isEqualTo(-1);
    }

    @Test
    public void testRestorePackage_whenSessionEnded() throws Exception {
        ShadowBinder.setCallingUid(1);
        setUpPackage(PACKAGE_1, /* uid */ 1);
        setUpTransport(mTransport);
        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);
        restoreSession.endRestoreSession();
        mShadowBackupLooper.runToEndOfTasks();

        expectThrows(
                IllegalStateException.class,
                () -> restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor));
    }

    @Test
    public void testRestorePackage_whenTransportNotRegistered() throws Exception {
        ShadowBinder.setCallingUid(1);
        setUpPackage(PACKAGE_1, /* uid */ 1);
        setUpTransport(mTransport.unregistered());
        IRestoreSession restoreSession = createActiveRestoreSession(null, mTransport);

        int result = restoreSession.restorePackage(PACKAGE_1, mObserver, mMonitor);

        assertThat(result).isEqualTo(-1);
    }

    // TODO: Create a builder for PackageInfo/ApplicationInfo and unify usage with
    //       TransportManagerTest
    private void setUpPackage(String packageName, int uid) {
        PackageInfo packageInfo = new PackageInfo();
        packageInfo.packageName = packageName;
        packageInfo.applicationInfo = new ApplicationInfo();
        packageInfo.applicationInfo.uid = uid;
        mShadowPackageManager.installPackage(packageInfo);
        ShadowApplicationPackageManager.addInstalledPackage(packageName, packageInfo);
    }

    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);
    }
}
