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

Commit ca1b5b9f authored by Annie Meng's avatar Annie Meng Committed by Android (Google) Code Review
Browse files

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

parents dbad904b 99c350da
Loading
Loading
Loading
Loading
+19 −16
Original line number Diff line number Diff line
@@ -23,9 +23,9 @@ import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.content.pm.SigningInfo;
import android.os.Build;
@@ -49,9 +49,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

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

/**
 * 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.
    private static final int UNDEFINED_ANCESTRAL_RECORD_VERSION = -1;

    private int mUserId;
    private List<PackageInfo> mAllPackages;
    private PackageManager mPackageManager;
    // 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
    // in backup.  This set changes as apps are installed & removed.
    public PackageManagerBackupAgent(PackageManager packageMgr, List<PackageInfo> packages) {
        init(packageMgr, packages);
    public PackageManagerBackupAgent(
            PackageManager packageMgr, List<PackageInfo> packages, int userId) {
        init(packageMgr, packages, userId);
    }

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

        evaluateStorablePackages();
    }

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

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

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

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

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

        // 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.
     */
    public BackupAgent makeMetadataAgent() {
        PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager);
        PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager, mUserId);
        pmAgent.attach(mContext);
        pmAgent.onCreate();
        return pmAgent;
@@ -808,7 +815,7 @@ public class UserBackupManagerService {
     */
    public PackageManagerBackupAgent makeMetadataAgent(List<PackageInfo> packages) {
        PackageManagerBackupAgent pmAgent =
                new PackageManagerBackupAgent(mPackageManager, packages);
                new PackageManagerBackupAgent(mPackageManager, packages, mUserId);
        pmAgent.attach(mContext);
        pmAgent.onCreate();
        return pmAgent;
@@ -879,7 +886,7 @@ public class UserBackupManagerService {
        boolean changed = false;
        ArrayList<FullBackupEntry> schedule = null;
        List<PackageInfo> apps =
                PackageManagerBackupAgent.getStorableApplications(mPackageManager);
                PackageManagerBackupAgent.getStorableApplications(mPackageManager, mUserId);

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

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

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

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

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

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

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