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

Commit 99c350da authored by Annie Meng's avatar Annie Meng
Browse files

[Multi-user] Convert key-value flow to use user id

Change paths that key-value backup/restore flow goes through to use
user id.

Bug: 121198605
Bug: 121198606
Test: 1) atest RunBackupFrameworksServicesRoboTests
2) atest $(find \
frameworks/base/services/tests/servicestests/src/com/android/server/backup \
-name '*Test.java')
3) adb shell bmgr backupnow [kv package]
Change-Id: Ie192391561f8e03f623c4d86914b3787ff2c0f88
parent 3596cfa9
Loading
Loading
Loading
Loading
+19 −16
Original line number Original line Diff line number Diff line
@@ -23,9 +23,9 @@ import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.content.pm.Signature;
import android.content.pm.SigningInfo;
import android.content.pm.SigningInfo;
import android.os.Build;
import android.os.Build;
@@ -49,9 +49,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.List;
import java.util.List;
import java.util.Set;

import java.util.Objects;
import java.util.Objects;
import java.util.Set;


/**
/**
 * We back up the signatures of each package so that during a system restore,
 * We back up the signatures of each package so that during a system restore,
@@ -95,6 +94,7 @@ public class PackageManagerBackupAgent extends BackupAgent {
    // is coming from pre-Android P device.
    // is coming from pre-Android P device.
    private static final int UNDEFINED_ANCESTRAL_RECORD_VERSION = -1;
    private static final int UNDEFINED_ANCESTRAL_RECORD_VERSION = -1;


    private int mUserId;
    private List<PackageInfo> mAllPackages;
    private List<PackageInfo> mAllPackages;
    private PackageManager mPackageManager;
    private PackageManager mPackageManager;
    // version & signature info of each app in a restore set
    // version & signature info of each app in a restore set
@@ -129,17 +129,18 @@ public class PackageManagerBackupAgent extends BackupAgent {


    // We're constructed with the set of applications that are participating
    // We're constructed with the set of applications that are participating
    // in backup.  This set changes as apps are installed & removed.
    // in backup.  This set changes as apps are installed & removed.
    public PackageManagerBackupAgent(PackageManager packageMgr, List<PackageInfo> packages) {
    public PackageManagerBackupAgent(
        init(packageMgr, packages);
            PackageManager packageMgr, List<PackageInfo> packages, int userId) {
        init(packageMgr, packages, userId);
    }
    }


    public PackageManagerBackupAgent(PackageManager packageMgr) {
    public PackageManagerBackupAgent(PackageManager packageMgr, int userId) {
        init(packageMgr, null);
        init(packageMgr, null, userId);


        evaluateStorablePackages();
        evaluateStorablePackages();
    }
    }


    private void init(PackageManager packageMgr, List<PackageInfo> packages) {
    private void init(PackageManager packageMgr, List<PackageInfo> packages, int userId) {
        mPackageManager = packageMgr;
        mPackageManager = packageMgr;
        mAllPackages = packages;
        mAllPackages = packages;
        mRestoredSignatures = null;
        mRestoredSignatures = null;
@@ -147,17 +148,19 @@ public class PackageManagerBackupAgent extends BackupAgent {


        mStoredSdkVersion = Build.VERSION.SDK_INT;
        mStoredSdkVersion = Build.VERSION.SDK_INT;
        mStoredIncrementalVersion = Build.VERSION.INCREMENTAL;
        mStoredIncrementalVersion = Build.VERSION.INCREMENTAL;
        mUserId = userId;
    }
    }


    // We will need to refresh our understanding of what is eligible for
    // We will need to refresh our understanding of what is eligible for
    // backup periodically; this entry point serves that purpose.
    // backup periodically; this entry point serves that purpose.
    public void evaluateStorablePackages() {
    public void evaluateStorablePackages() {
        mAllPackages = getStorableApplications(mPackageManager);
        mAllPackages = getStorableApplications(mPackageManager, mUserId);
    }
    }


    public static List<PackageInfo> getStorableApplications(PackageManager pm) {
    /** Gets all packages installed on user {@code userId} eligible for backup. */
        List<PackageInfo> pkgs;
    public static List<PackageInfo> getStorableApplications(PackageManager pm, int userId) {
        pkgs = pm.getInstalledPackages(PackageManager.GET_SIGNING_CERTIFICATES);
        List<PackageInfo> pkgs =
                pm.getInstalledPackagesAsUser(PackageManager.GET_SIGNING_CERTIFICATES, userId);
        int N = pkgs.size();
        int N = pkgs.size();
        for (int a = N-1; a >= 0; a--) {
        for (int a = N-1; a >= 0; a--) {
            PackageInfo pkg = pkgs.get(a);
            PackageInfo pkg = pkgs.get(a);
@@ -237,8 +240,8 @@ public class PackageManagerBackupAgent extends BackupAgent {
        ComponentName home = getPreferredHomeComponent();
        ComponentName home = getPreferredHomeComponent();
        if (home != null) {
        if (home != null) {
            try {
            try {
                homeInfo = mPackageManager.getPackageInfo(home.getPackageName(),
                homeInfo = mPackageManager.getPackageInfoAsUser(home.getPackageName(),
                        PackageManager.GET_SIGNING_CERTIFICATES);
                        PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
                homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName());
                homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName());
                homeVersion = homeInfo.getLongVersionCode();
                homeVersion = homeInfo.getLongVersionCode();
                SigningInfo signingInfo = homeInfo.signingInfo;
                SigningInfo signingInfo = homeInfo.signingInfo;
@@ -315,8 +318,8 @@ public class PackageManagerBackupAgent extends BackupAgent {
                } else {
                } else {
                    PackageInfo info = null;
                    PackageInfo info = null;
                    try {
                    try {
                        info = mPackageManager.getPackageInfo(packName,
                        info = mPackageManager.getPackageInfoAsUser(packName,
                                PackageManager.GET_SIGNING_CERTIFICATES);
                                PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
                    } catch (NameNotFoundException e) {
                    } catch (NameNotFoundException e) {
                        // Weird; we just found it, and now are told it doesn't exist.
                        // Weird; we just found it, and now are told it doesn't exist.
                        // Treat it as having been removed from the device.
                        // Treat it as having been removed from the device.
+22 −16
Original line number Original line Diff line number Diff line
@@ -496,11 +496,18 @@ public class UserBackupManagerService {
        mBaseStateDir = checkNotNull(baseStateDir, "baseStateDir cannot be null");
        mBaseStateDir = checkNotNull(baseStateDir, "baseStateDir cannot be null");
        mBaseStateDir.mkdirs();
        mBaseStateDir.mkdirs();
        if (!SELinux.restorecon(mBaseStateDir)) {
        if (!SELinux.restorecon(mBaseStateDir)) {
            Slog.e(TAG, "SELinux restorecon failed on " + mBaseStateDir);
            Slog.w(TAG, "SELinux restorecon failed on " + mBaseStateDir);
        }
        }


        mDataDir = checkNotNull(dataDir, "dataDir cannot be null");
        mDataDir = checkNotNull(dataDir, "dataDir cannot be null");

        // TODO(b/120424138): Remove when the system user moves out of the cache dir. The cache dir
        // is managed by init.rc so we don't have to create it below.
        if (userId != UserHandle.USER_SYSTEM) {
            mDataDir.mkdirs();
            if (!SELinux.restorecon(mDataDir)) {
                Slog.w(TAG, "SELinux restorecon failed on " + mDataDir);
            }
        }
        mBackupPasswordManager = new BackupPasswordManager(mContext, mBaseStateDir, mRng);
        mBackupPasswordManager = new BackupPasswordManager(mContext, mBaseStateDir, mRng);


        // Receivers for scheduled backups and transport initialization operations.
        // Receivers for scheduled backups and transport initialization operations.
@@ -797,7 +804,7 @@ public class UserBackupManagerService {
     * non-lifecycle agent instance, so we manually set up the context topology for it.
     * non-lifecycle agent instance, so we manually set up the context topology for it.
     */
     */
    public BackupAgent makeMetadataAgent() {
    public BackupAgent makeMetadataAgent() {
        PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager);
        PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager, mUserId);
        pmAgent.attach(mContext);
        pmAgent.attach(mContext);
        pmAgent.onCreate();
        pmAgent.onCreate();
        return pmAgent;
        return pmAgent;
@@ -808,7 +815,7 @@ public class UserBackupManagerService {
     */
     */
    public PackageManagerBackupAgent makeMetadataAgent(List<PackageInfo> packages) {
    public PackageManagerBackupAgent makeMetadataAgent(List<PackageInfo> packages) {
        PackageManagerBackupAgent pmAgent =
        PackageManagerBackupAgent pmAgent =
                new PackageManagerBackupAgent(mPackageManager, packages);
                new PackageManagerBackupAgent(mPackageManager, packages, mUserId);
        pmAgent.attach(mContext);
        pmAgent.attach(mContext);
        pmAgent.onCreate();
        pmAgent.onCreate();
        return pmAgent;
        return pmAgent;
@@ -879,7 +886,7 @@ public class UserBackupManagerService {
        boolean changed = false;
        boolean changed = false;
        ArrayList<FullBackupEntry> schedule = null;
        ArrayList<FullBackupEntry> schedule = null;
        List<PackageInfo> apps =
        List<PackageInfo> apps =
                PackageManagerBackupAgent.getStorableApplications(mPackageManager);
                PackageManagerBackupAgent.getStorableApplications(mPackageManager, mUserId);


        if (mFullBackupScheduleFile.exists()) {
        if (mFullBackupScheduleFile.exists()) {
            try (FileInputStream fstream = new FileInputStream(mFullBackupScheduleFile);
            try (FileInputStream fstream = new FileInputStream(mFullBackupScheduleFile);
@@ -1428,8 +1435,7 @@ public class UserBackupManagerService {
            mConnecting = true;
            mConnecting = true;
            mConnectedAgent = null;
            mConnectedAgent = null;
            try {
            try {
                if (mActivityManager.bindBackupAgent(app.packageName, mode,
                if (mActivityManager.bindBackupAgent(app.packageName, mode, mUserId)) {
                        UserHandle.USER_OWNER)) {
                    Slog.d(TAG, "awaiting agent for " + app);
                    Slog.d(TAG, "awaiting agent for " + app);


                    // success; wait for the agent to arrive
                    // success; wait for the agent to arrive
@@ -1488,7 +1494,7 @@ public class UserBackupManagerService {
    public void clearApplicationDataSynchronous(String packageName, boolean keepSystemState) {
    public void clearApplicationDataSynchronous(String packageName, boolean keepSystemState) {
        // Don't wipe packages marked allowClearUserData=false
        // Don't wipe packages marked allowClearUserData=false
        try {
        try {
            PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
            PackageInfo info = mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId);
            if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
            if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
                if (MORE_DEBUG) {
                if (MORE_DEBUG) {
                    Slog.i(TAG, "allowClearUserData=false so not wiping "
                    Slog.i(TAG, "allowClearUserData=false so not wiping "
@@ -1507,7 +1513,7 @@ public class UserBackupManagerService {
            mClearingData = true;
            mClearingData = true;
            try {
            try {
                mActivityManager.clearApplicationUserData(
                mActivityManager.clearApplicationUserData(
                        packageName, keepSystemState, observer, 0);
                        packageName, keepSystemState, observer, mUserId);
            } catch (RemoteException e) {
            } catch (RemoteException e) {
                // can't happen because the activity manager is in this process
                // can't happen because the activity manager is in this process
            }
            }
@@ -1616,8 +1622,8 @@ public class UserBackupManagerService {
                continue;
                continue;
            }
            }
            try {
            try {
                PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
                PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageName,
                        PackageManager.GET_SIGNING_CERTIFICATES);
                        PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
                if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo,
                if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo,
                        mPackageManager)) {
                        mPackageManager)) {
                    BackupObserverUtils.sendBackupOnPackageResult(observer, packageName,
                    BackupObserverUtils.sendBackupOnPackageResult(observer, packageName,
@@ -2339,8 +2345,8 @@ public class UserBackupManagerService {
        if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
        if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
        PackageInfo info;
        PackageInfo info;
        try {
        try {
            info = mPackageManager.getPackageInfo(packageName,
            info = mPackageManager.getPackageInfoAsUser(packageName,
                    PackageManager.GET_SIGNING_CERTIFICATES);
                    PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
        } catch (NameNotFoundException e) {
        } catch (NameNotFoundException e) {
            Slog.d(TAG, "No such package '" + packageName + "' - not clearing backup data");
            Slog.d(TAG, "No such package '" + packageName + "' - not clearing backup data");
            return;
            return;
@@ -3257,7 +3263,7 @@ public class UserBackupManagerService {
            if (packageName != null) {
            if (packageName != null) {
                PackageInfo app = null;
                PackageInfo app = null;
                try {
                try {
                    app = mPackageManager.getPackageInfo(packageName, 0);
                    app = mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId);
                } catch (NameNotFoundException nnf) {
                } catch (NameNotFoundException nnf) {
                    Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
                    Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
                    throw new IllegalArgumentException("Package " + packageName + " not found");
                    throw new IllegalArgumentException("Package " + packageName + " not found");
@@ -3361,7 +3367,7 @@ public class UserBackupManagerService {
                    mTransportManager.getCurrentTransportClient(callerLogString);
                    mTransportManager.getCurrentTransportClient(callerLogString);
            boolean eligible =
            boolean eligible =
                    AppBackupUtils.appIsRunningAndEligibleForBackupWithTransport(
                    AppBackupUtils.appIsRunningAndEligibleForBackupWithTransport(
                            transportClient, packageName, mPackageManager);
                            transportClient, packageName, mPackageManager, mUserId);
            if (transportClient != null) {
            if (transportClient != null) {
                mTransportManager.disposeOfTransportClient(transportClient, callerLogString);
                mTransportManager.disposeOfTransportClient(transportClient, callerLogString);
            }
            }
@@ -3385,7 +3391,7 @@ public class UserBackupManagerService {
            for (String packageName : packages) {
            for (String packageName : packages) {
                if (AppBackupUtils
                if (AppBackupUtils
                        .appIsRunningAndEligibleForBackupWithTransport(
                        .appIsRunningAndEligibleForBackupWithTransport(
                                transportClient, packageName, mPackageManager)) {
                                transportClient, packageName, mPackageManager, mUserId)) {
                    eligibleApps.add(packageName);
                    eligibleApps.add(packageName);
                }
                }
            }
            }
+5 −5
Original line number Original line Diff line number Diff line
@@ -45,7 +45,6 @@ import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.Process;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.SELinux;
import android.os.UserHandle;
import android.os.WorkSource;
import android.os.WorkSource;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
@@ -241,6 +240,7 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
    private final boolean mUserInitiated;
    private final boolean mUserInitiated;
    private final boolean mNonIncremental;
    private final boolean mNonIncremental;
    private final int mCurrentOpToken;
    private final int mCurrentOpToken;
    private final int mUserId;
    private final File mStateDirectory;
    private final File mStateDirectory;
    private final File mDataDirectory;
    private final File mDataDirectory;
    private final File mBlankStateFile;
    private final File mBlankStateFile;
@@ -320,6 +320,7 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
        mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
        mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
        mQueueLock = mBackupManagerService.getQueueLock();
        mQueueLock = mBackupManagerService.getQueueLock();
        mBlankStateFile = new File(mStateDirectory, BLANK_STATE_FILE_NAME);
        mBlankStateFile = new File(mStateDirectory, BLANK_STATE_FILE_NAME);
        mUserId = backupManagerService.getUserId();
    }
    }


    private void registerTask() {
    private void registerTask() {
@@ -480,8 +481,8 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
        final PackageInfo packageInfo;
        final PackageInfo packageInfo;
        try {
        try {
            packageInfo =
            packageInfo =
                    mPackageManager.getPackageInfo(
                    mPackageManager.getPackageInfoAsUser(
                            packageName, PackageManager.GET_SIGNING_CERTIFICATES);
                            packageName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
        } catch (PackageManager.NameNotFoundException e) {
        } catch (PackageManager.NameNotFoundException e) {
            mReporter.onAgentUnknown(packageName);
            mReporter.onAgentUnknown(packageName);
            throw AgentException.permanent(e);
            throw AgentException.permanent(e);
@@ -770,8 +771,7 @@ public class KeyValueBackupTask implements BackupRestoreTask, Runnable {


    private void writeWidgetPayloadIfAppropriate(FileDescriptor fd, String pkgName)
    private void writeWidgetPayloadIfAppropriate(FileDescriptor fd, String pkgName)
            throws IOException {
            throws IOException {
        // TODO: http://b/22388012
        byte[] widgetState = AppWidgetBackupBridge.getWidgetState(pkgName, mUserId);
        byte[] widgetState = AppWidgetBackupBridge.getWidgetState(pkgName, UserHandle.USER_SYSTEM);
        File widgetFile = new File(mStateDirectory, pkgName + "_widget");
        File widgetFile = new File(mStateDirectory, pkgName + "_widget");
        boolean priorStateExists = widgetFile.exists();
        boolean priorStateExists = widgetFile.exists();
        if (!priorStateExists && widgetState == null) {
        if (!priorStateExists && widgetState == null) {
+4 −1
Original line number Original line Diff line number Diff line
@@ -54,6 +54,7 @@ public class ActiveRestoreSession extends IRestoreSession.Stub {
    private final TransportManager mTransportManager;
    private final TransportManager mTransportManager;
    private final String mTransportName;
    private final String mTransportName;
    private final UserBackupManagerService mBackupManagerService;
    private final UserBackupManagerService mBackupManagerService;
    private final int mUserId;
    @Nullable private final String mPackageName;
    @Nullable private final String mPackageName;
    public RestoreSet[] mRestoreSets = null;
    public RestoreSet[] mRestoreSets = null;
    boolean mEnded = false;
    boolean mEnded = false;
@@ -67,6 +68,7 @@ public class ActiveRestoreSession extends IRestoreSession.Stub {
        mPackageName = packageName;
        mPackageName = packageName;
        mTransportManager = backupManagerService.getTransportManager();
        mTransportManager = backupManagerService.getTransportManager();
        mTransportName = transportName;
        mTransportName = transportName;
        mUserId = backupManagerService.getUserId();
    }
    }


    public void markTimedOut() {
    public void markTimedOut() {
@@ -304,7 +306,8 @@ public class ActiveRestoreSession extends IRestoreSession.Stub {


        final PackageInfo app;
        final PackageInfo app;
        try {
        try {
            app = mBackupManagerService.getPackageManager().getPackageInfo(packageName, 0);
            app = mBackupManagerService.getPackageManager().getPackageInfoAsUser(
                    packageName, 0, mUserId);
        } catch (NameNotFoundException nnf) {
        } catch (NameNotFoundException nnf) {
            Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
            Slog.w(TAG, "Asked to restore nonexistent pkg " + packageName);
            return -1;
            return -1;
+1 −1
Original line number Original line Diff line number Diff line
@@ -272,7 +272,7 @@ public class FullRestoreEngine extends RestoreEngine {
                                        instream, mBackupManagerService.getContext(),
                                        instream, mBackupManagerService.getContext(),
                                        mDeleteObserver, mManifestSignatures,
                                        mDeleteObserver, mManifestSignatures,
                                        mPackagePolicies, info, installerPackageName,
                                        mPackagePolicies, info, installerPackageName,
                                        bytesReadListener);
                                        bytesReadListener, mBackupManagerService.getUserId());
                                // good to go; promote to ACCEPT
                                // good to go; promote to ACCEPT
                                mPackagePolicies.put(pkg, isSuccessfullyInstalled
                                mPackagePolicies.put(pkg, isSuccessfullyInstalled
                                        ? RestorePolicy.ACCEPT
                                        ? RestorePolicy.ACCEPT
Loading