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

Commit 4a5e370b authored by Chandan Nath's avatar Chandan Nath
Browse files

[Multi-user] adb fullbackup: support userId

Bug: 121198030

Test: 1) atest RunBackupFrameworksServicesRoboTests
2) atest $(find \
frameworks/base/services/tests/servicestests/src/com/android/server/backup \
-name '*Test.java')
3) atest CtsBackupTestCases CtsBackupHostTestCases GtsBackupTestCases GtsBackupHostTestCases
4) tested "adb backup -all -obb -apk". confirmed that log contains "obb dir: /storage/emu.." etc. restore of wallpaper worked.

Change-Id: Ic8ff71c5dd949aecc7561a3bac5033e822fcf305
parent 9879a637
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import static com.android.server.backup.UserBackupManagerService.BACKUP_METADATA
import static com.android.server.backup.UserBackupManagerService.BACKUP_WIDGET_METADATA_TOKEN;

import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.backup.FullBackup;
import android.app.backup.FullBackupDataOutput;
import android.content.pm.PackageInfo;
@@ -15,7 +16,6 @@ import android.content.pm.Signature;
import android.content.pm.SigningInfo;
import android.os.Build;
import android.os.Environment;
import android.os.UserHandle;
import android.util.Log;
import android.util.StringBuilderPrinter;

@@ -254,12 +254,11 @@ public class AppMetadataBackupWriter {
     * for 'adb backup'.
     */
    // TODO(b/113807190): Investigate and potentially remove.
    public void backupObb(PackageInfo packageInfo) {
    public void backupObb(@UserIdInt int userId, PackageInfo packageInfo) {
        // TODO: migrate this to SharedStorageBackup, since AID_SYSTEM doesn't have access to
        // external storage.
        // TODO: http://b/22388012
        Environment.UserEnvironment userEnv =
                new Environment.UserEnvironment(UserHandle.USER_SYSTEM);
                new Environment.UserEnvironment(userId);
        File obbDir = userEnv.buildExternalStorageAppObbDirs(packageInfo.packageName)[0];
        if (obbDir != null) {
            if (MORE_DEBUG) {
+7 −7
Original line number Diff line number Diff line
@@ -54,12 +54,12 @@ import java.io.OutputStream;
 */
public class FullBackupEngine {
    private UserBackupManagerService backupManagerService;
    OutputStream mOutput;
    FullBackupPreflight mPreflightHook;
    BackupRestoreTask mTimeoutMonitor;
    IBackupAgent mAgent;
    boolean mIncludeApks;
    PackageInfo mPkg;
    private OutputStream mOutput;
    private FullBackupPreflight mPreflightHook;
    private BackupRestoreTask mTimeoutMonitor;
    private IBackupAgent mAgent;
    private boolean mIncludeApks;
    private PackageInfo mPkg;
    private final long mQuota;
    private final int mOpToken;
    private final int mTransportFlags;
@@ -130,7 +130,7 @@ public class FullBackupEngine {
                // TODO(b/113807190): Look into removing, only used for 'adb backup'.
                if (writeApk) {
                    appMetadataBackupWriter.backupApk(mPackage);
                    appMetadataBackupWriter.backupObb(mPackage);
                    appMetadataBackupWriter.backupObb(mUserId, mPackage);
                }

                if (DEBUG) {
+47 −41
Original line number Diff line number Diff line
@@ -66,24 +66,22 @@ import javax.crypto.spec.SecretKeySpec;
 */
public class PerformAdbBackupTask extends FullBackupTask implements BackupRestoreTask {

    private UserBackupManagerService backupManagerService;
    FullBackupEngine mBackupEngine;
    final AtomicBoolean mLatch;

    ParcelFileDescriptor mOutputFile;
    DeflaterOutputStream mDeflater;
    boolean mIncludeApks;
    boolean mIncludeObbs;
    boolean mIncludeShared;
    boolean mDoWidgets;
    boolean mAllApps;
    boolean mIncludeSystem;
    boolean mCompress;
    boolean mKeyValue;
    ArrayList<String> mPackages;
    PackageInfo mCurrentTarget;
    String mCurrentPassword;
    String mEncryptPassword;
    private final UserBackupManagerService mUserBackupManagerService;
    private final AtomicBoolean mLatch;

    private final ParcelFileDescriptor mOutputFile;
    private final boolean mIncludeApks;
    private final boolean mIncludeObbs;
    private final boolean mIncludeShared;
    private final boolean mDoWidgets;
    private final boolean mAllApps;
    private final boolean mIncludeSystem;
    private final boolean mCompress;
    private final boolean mKeyValue;
    private final ArrayList<String> mPackages;
    private PackageInfo mCurrentTarget;
    private final String mCurrentPassword;
    private final String mEncryptPassword;
    private final int mCurrentOpToken;

    public PerformAdbBackupTask(UserBackupManagerService backupManagerService,
@@ -92,7 +90,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
            String curPassword, String encryptPassword, boolean doAllApps, boolean doSystem,
            boolean doCompress, boolean doKeyValue, String[] packages, AtomicBoolean latch) {
        super(observer);
        this.backupManagerService = backupManagerService;
        mUserBackupManagerService = backupManagerService;
        mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
        mLatch = latch;

@@ -104,7 +102,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
        mAllApps = doAllApps;
        mIncludeSystem = doSystem;
        mPackages = (packages == null)
                ? new ArrayList<String>()
                ? new ArrayList<>()
                : new ArrayList<>(Arrays.asList(packages));
        mCurrentPassword = curPassword;
        // when backing up, if there is a current backup password, we require that
@@ -123,11 +121,11 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
        mKeyValue = doKeyValue;
    }

    void addPackagesToSet(TreeMap<String, PackageInfo> set, List<String> pkgNames) {
    private void addPackagesToSet(TreeMap<String, PackageInfo> set, List<String> pkgNames) {
        for (String pkgName : pkgNames) {
            if (!set.containsKey(pkgName)) {
                try {
                    PackageInfo info = backupManagerService.getPackageManager().getPackageInfo(
                    PackageInfo info = mUserBackupManagerService.getPackageManager().getPackageInfo(
                            pkgName,
                            PackageManager.GET_SIGNING_CERTIFICATES);
                    set.put(pkgName, info);
@@ -141,7 +139,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
    private OutputStream emitAesBackupHeader(StringBuilder headerbuf,
            OutputStream ofstream) throws Exception {
        // User key will be used to encrypt the master key.
        byte[] newUserSalt = backupManagerService
        byte[] newUserSalt = mUserBackupManagerService
                .randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);
        SecretKey userKey = PasswordUtils
                .buildPasswordKey(PBKDF_CURRENT, mEncryptPassword,
@@ -150,8 +148,8 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor

        // the master key is random for each backup
        byte[] masterPw = new byte[256 / 8];
        backupManagerService.getRng().nextBytes(masterPw);
        byte[] checksumSalt = backupManagerService
        mUserBackupManagerService.getRng().nextBytes(masterPw);
        byte[] checksumSalt = mUserBackupManagerService
                .randomBytes(PasswordUtils.PBKDF2_SALT_SIZE);

        // primary encryption of the datastream with the random key
@@ -232,11 +230,11 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor

        TreeMap<String, PackageInfo> packagesToBackup = new TreeMap<>();
        FullBackupObbConnection obbConnection = new FullBackupObbConnection(
                backupManagerService);
                mUserBackupManagerService);
        obbConnection.establish();  // we'll want this later

        sendStartBackup();
        PackageManager pm = backupManagerService.getPackageManager();
        PackageManager pm = mUserBackupManagerService.getPackageManager();

        // doAllApps supersedes the package set if any
        if (mAllApps) {
@@ -245,7 +243,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
            for (int i = 0; i < allPackages.size(); i++) {
                PackageInfo pkg = allPackages.get(i);
                // Exclude system apps if we've been asked to do so
                if (mIncludeSystem == true
                if (mIncludeSystem
                        || ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)) {
                    packagesToBackup.put(pkg.packageName, pkg);
                }
@@ -316,7 +314,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
            boolean encrypting = (mEncryptPassword != null && mEncryptPassword.length() > 0);

            // Only allow encrypted backups of encrypted devices
            if (backupManagerService.deviceIsEncrypted() && !encrypting) {
            if (mUserBackupManagerService.deviceIsEncrypted() && !encrypting) {
                Slog.e(TAG, "Unencrypted backup of encrypted device; aborting");
                return;
            }
@@ -325,7 +323,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor

            // Verify that the given password matches the currently-active
            // backup password, if any
            if (!backupManagerService.backupPasswordMatches(mCurrentPassword)) {
            if (!mUserBackupManagerService.backupPasswordMatches(mCurrentPassword)) {
                if (DEBUG) {
                    Slog.w(TAG, "Backup password mismatch; aborting");
                }
@@ -390,7 +388,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
            // Shared storage if requested
            if (mIncludeShared) {
                try {
                    pkg = backupManagerService.getPackageManager().getPackageInfo(
                    pkg = mUserBackupManagerService.getPackageManager().getPackageInfo(
                            SHARED_BACKUP_AGENT_PACKAGE, 0);
                    backupQueue.add(pkg);
                } catch (NameNotFoundException e) {
@@ -410,9 +408,17 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
                        pkg.packageName.equals(
                                SHARED_BACKUP_AGENT_PACKAGE);

                mBackupEngine = new FullBackupEngine(backupManagerService, out,
                        null, pkg, mIncludeApks, this, Long.MAX_VALUE,
                        mCurrentOpToken, /*transportFlags=*/ 0);
                FullBackupEngine mBackupEngine =
                        new FullBackupEngine(
                                mUserBackupManagerService,
                                out,
                                null,
                                pkg,
                                mIncludeApks,
                                this,
                                Long.MAX_VALUE,
                                mCurrentOpToken,
                                /*transportFlags=*/ 0);
                sendOnBackupPackage(isSharedStorage ? "Shared storage" : pkg.packageName);

                // Don't need to check preflight result as there is no preflight hook.
@@ -437,10 +443,10 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
                    }
                    KeyValueAdbBackupEngine kvBackupEngine =
                            new KeyValueAdbBackupEngine(out, keyValuePackage,
                                    backupManagerService,
                                    backupManagerService.getPackageManager(),
                                    backupManagerService.getBaseStateDir(),
                                    backupManagerService.getDataDir());
                                    mUserBackupManagerService,
                                    mUserBackupManagerService.getPackageManager(),
                                    mUserBackupManagerService.getBaseStateDir(),
                                    mUserBackupManagerService.getDataDir());
                    sendOnBackupPackage(keyValuePackage.packageName);
                    kvBackupEngine.backupOnePackage();
                }
@@ -471,7 +477,7 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
            if (DEBUG) {
                Slog.d(TAG, "Full backup pass complete.");
            }
            backupManagerService.getWakelock().release();
            mUserBackupManagerService.getWakelock().release();
        }
    }

@@ -493,8 +499,8 @@ public class PerformAdbBackupTask extends FullBackupTask implements BackupRestor
            Slog.w(TAG, "adb backup cancel of " + target);
        }
        if (target != null) {
            backupManagerService.tearDownAgentAndKill(mCurrentTarget.applicationInfo);
            mUserBackupManagerService.tearDownAgentAndKill(mCurrentTarget.applicationInfo);
        }
        backupManagerService.removeOperation(mCurrentOpToken);
        mUserBackupManagerService.removeOperation(mCurrentOpToken);
    }
}
+5 −2
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ import static org.robolectric.Shadows.shadowOf;
import static org.testng.Assert.expectThrows;

import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.Application;
import android.app.backup.BackupDataInput;
import android.app.backup.FullBackupDataOutput;
@@ -62,6 +63,7 @@ public class AppMetadataBackupWriterTest {
    private static final String TEST_PACKAGE_INSTALLER = "com.test.package.installer";
    private static final Long TEST_PACKAGE_VERSION_CODE = 100L;

    private @UserIdInt int mUserId;
    private PackageManager mPackageManager;
    private ShadowApplicationPackageManager mShadowPackageManager;
    private File mFilesDir;
@@ -72,6 +74,7 @@ public class AppMetadataBackupWriterTest {
    public void setUp() throws Exception {
        Application application = RuntimeEnvironment.application;

        mUserId = UserHandle.USER_SYSTEM;
        mPackageManager = application.getPackageManager();
        mShadowPackageManager = (ShadowApplicationPackageManager) shadowOf(mPackageManager);

@@ -352,7 +355,7 @@ public class AppMetadataBackupWriterTest {
        byte[] obbBytes = "obb".getBytes();
        File obbFile = createObbFileAndWrite(obbDir, obbBytes);

        mBackupWriter.backupObb(packageInfo);
        mBackupWriter.backupObb(mUserId, packageInfo);

        byte[] writtenBytes = getWrittenBytes(mBackupDataOutputFile, /* includeTarHeader */ false);
        assertThat(writtenBytes).isEqualTo(obbBytes);
@@ -366,7 +369,7 @@ public class AppMetadataBackupWriterTest {
        File obbDir = createObbDirForPackage(packageInfo.packageName);
        // No obb file created.

        mBackupWriter.backupObb(packageInfo);
        mBackupWriter.backupObb(mUserId, packageInfo);

        assertThat(mBackupDataOutputFile.length()).isEqualTo(0);
    }