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

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

Merge changes Ie9c8934d,Iea747394

* changes:
  Create "android" backup agent in the system process for all users
  [Multi-user] Pass userId on backup agent creation
parents fb069906 d582787a
Loading
Loading
Loading
Loading
+32 −11
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ import android.util.MergedConfiguration;
import android.util.Pair;
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.SuperNotCalledException;
import android.util.proto.ProtoOutputStream;
@@ -305,8 +306,14 @@ public final class ActivityThread extends ClientTransactionHandler {
    @UnsupportedAppUsage
    final ArrayList<Application> mAllApplications
            = new ArrayList<Application>();
    // set of instantiated backup agents, keyed by package name
    final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>();
    /**
     * Bookkeeping of instantiated backup agents indexed first by user id, then by package name.
     * Indexing by user id supports parallel backups across users on system packages as they run in
     * the same process with the same package name. Indexing by package name supports multiple
     * distinct applications running in the same process.
     */
    private final SparseArray<ArrayMap<String, BackupAgent>> mBackupAgentsByUser =
            new SparseArray<>();
    /** Reference to singleton {@link ActivityThread} */
    @UnsupportedAppUsage
    private static volatile ActivityThread sCurrentActivityThread;
@@ -659,10 +666,11 @@ public final class ActivityThread extends ClientTransactionHandler {
        ApplicationInfo appInfo;
        CompatibilityInfo compatInfo;
        int backupMode;
        int userId;
        public String toString() {
            return "CreateBackupAgentData{appInfo=" + appInfo
                    + " backupAgent=" + appInfo.backupAgentName
                    + " mode=" + backupMode + "}";
                    + " mode=" + backupMode + " userId=" + userId + "}";
        }
    }

@@ -877,20 +885,22 @@ public final class ActivityThread extends ClientTransactionHandler {
        }

        public final void scheduleCreateBackupAgent(ApplicationInfo app,
                CompatibilityInfo compatInfo, int backupMode) {
                CompatibilityInfo compatInfo, int backupMode, int userId) {
            CreateBackupAgentData d = new CreateBackupAgentData();
            d.appInfo = app;
            d.compatInfo = compatInfo;
            d.backupMode = backupMode;
            d.userId = userId;

            sendMessage(H.CREATE_BACKUP_AGENT, d);
        }

        public final void scheduleDestroyBackupAgent(ApplicationInfo app,
                CompatibilityInfo compatInfo) {
                CompatibilityInfo compatInfo, int userId) {
            CreateBackupAgentData d = new CreateBackupAgentData();
            d.appInfo = app;
            d.compatInfo = compatInfo;
            d.userId = userId;

            sendMessage(H.DESTROY_BACKUP_AGENT, d);
        }
@@ -3616,7 +3626,8 @@ public final class ActivityThread extends ClientTransactionHandler {

        try {
            IBinder binder = null;
            BackupAgent agent = mBackupAgents.get(packageName);
            ArrayMap<String, BackupAgent> backupAgents = getBackupAgentsForUser(data.userId);
            BackupAgent agent = backupAgents.get(packageName);
            if (agent != null) {
                // reusing the existing instance
                if (DEBUG_BACKUP) {
@@ -3635,9 +3646,9 @@ public final class ActivityThread extends ClientTransactionHandler {
                    context.setOuterContext(agent);
                    agent.attach(context);

                    agent.onCreate();
                    agent.onCreate(UserHandle.of(data.userId));
                    binder = agent.onBind();
                    mBackupAgents.put(packageName, agent);
                    backupAgents.put(packageName, agent);
                } catch (Exception e) {
                    // If this is during restore, fail silently; otherwise go
                    // ahead and let the user see the crash.
@@ -3653,7 +3664,7 @@ public final class ActivityThread extends ClientTransactionHandler {

            // tell the OS that we're live now
            try {
                ActivityManager.getService().backupAgentCreated(packageName, binder);
                ActivityManager.getService().backupAgentCreated(packageName, binder, data.userId);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
@@ -3669,7 +3680,8 @@ public final class ActivityThread extends ClientTransactionHandler {

        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
        String packageName = packageInfo.mPackageName;
        BackupAgent agent = mBackupAgents.get(packageName);
        ArrayMap<String, BackupAgent> backupAgents = getBackupAgentsForUser(data.userId);
        BackupAgent agent = backupAgents.get(packageName);
        if (agent != null) {
            try {
                agent.onDestroy();
@@ -3677,12 +3689,21 @@ public final class ActivityThread extends ClientTransactionHandler {
                Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
                e.printStackTrace();
            }
            mBackupAgents.remove(packageName);
            backupAgents.remove(packageName);
        } else {
            Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
        }
    }

    private ArrayMap<String, BackupAgent> getBackupAgentsForUser(int userId) {
        ArrayMap<String, BackupAgent> backupAgents = mBackupAgentsByUser.get(userId);
        if (backupAgents == null) {
            backupAgents = new ArrayMap<>();
            mBackupAgentsByUser.put(userId, backupAgents);
        }
        return backupAgents;
    }

    @UnsupportedAppUsage
    private void handleCreateService(CreateServiceData data) {
        // If we are getting ready to gc after going to the background, well
+2 −2
Original line number Diff line number Diff line
@@ -221,8 +221,8 @@ interface IActivityManager {
    boolean shutdown(int timeout);
    void stopAppSwitches();
    void resumeAppSwitches();
    boolean bindBackupAgent(in String packageName, int backupRestoreMode, int userId);
    void backupAgentCreated(in String packageName, in IBinder agent);
    boolean bindBackupAgent(in String packageName, int backupRestoreMode, int targetUserId);
    void backupAgentCreated(in String packageName, in IBinder agent, int userId);
    void unbindBackupAgent(in ApplicationInfo appInfo);
    int getUidForIntentSender(in IIntentSender sender);
    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
+2 −2
Original line number Diff line number Diff line
@@ -88,9 +88,9 @@ oneway interface IApplicationThread {
    void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType);
    void setSchedulingGroup(int group);
    void scheduleCreateBackupAgent(in ApplicationInfo app, in CompatibilityInfo compatInfo,
            int backupMode);
            int backupMode, int userId);
    void scheduleDestroyBackupAgent(in ApplicationInfo app,
            in CompatibilityInfo compatInfo);
            in CompatibilityInfo compatInfo, int userId);
    void scheduleOnNewActivityOptions(IBinder token, in Bundle options);
    void scheduleSuicide();
    void dispatchPackageBroadcast(int cmd, in String[] packages);
+2 −2
Original line number Diff line number Diff line
@@ -465,12 +465,12 @@ public class TransactionParcelTests {

        @Override
        public void scheduleCreateBackupAgent(ApplicationInfo applicationInfo,
                CompatibilityInfo compatibilityInfo, int i) throws RemoteException {
                CompatibilityInfo compatibilityInfo, int i, int userId) throws RemoteException {
        }

        @Override
        public void scheduleDestroyBackupAgent(ApplicationInfo applicationInfo,
                CompatibilityInfo compatibilityInfo) throws RemoteException {
                CompatibilityInfo compatibilityInfo, int userId) throws RemoteException {
        }

        @Override
+27 −16
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA
import static com.android.server.am.MemoryStatUtil.hasMemcg;
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
@@ -4848,7 +4849,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            try {
                thread.scheduleCreateBackupAgent(backupTarget.appInfo,
                        compatibilityInfoForPackage(backupTarget.appInfo),
                        backupTarget.backupMode);
                        backupTarget.backupMode, backupTarget.userId);
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
                badApp = true;
@@ -13695,18 +13696,26 @@ public class ActivityManagerService extends IActivityManager.Stub
    // Cause the target app to be launched if necessary and its backup agent
    // instantiated.  The backup agent will invoke backupAgentCreated() on the
    // activity manager to announce its creation.
    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
    public boolean bindBackupAgent(String packageName, int backupMode, int targetUserId) {
        if (DEBUG_BACKUP) {
            Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode="
                    + backupMode + " userId=" + userId + " callingUid = " + Binder.getCallingUid()
            Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode
                    + " targetUserId=" + targetUserId + " callingUid = " + Binder.getCallingUid()
                    + " uid = " + Process.myUid());
        }
        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
        // The instantiatedUserId is the user of the process the backup agent is started in. This is
        // different from the targetUserId which is the user whose data is to be backed up or
        // restored. This distinction is important for system-process packages that live in the
        // system user's process but backup/restore data for non-system users.
        // TODO (b/123688746): Handle all system-process packages with singleton check.
        final int instantiatedUserId =
                PLATFORM_PACKAGE_NAME.equals(packageName) ? UserHandle.USER_SYSTEM : targetUserId;
        IPackageManager pm = AppGlobals.getPackageManager();
        ApplicationInfo app = null;
        try {
            app = pm.getApplicationInfo(packageName, STOCK_PM_FLAGS, userId);
            app = pm.getApplicationInfo(packageName, STOCK_PM_FLAGS, instantiatedUserId);
        } catch (RemoteException e) {
            // can't happen; package manager is process-local
        }
@@ -13730,7 +13739,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                        + app.packageName + ": " + e);
            }
            BackupRecord r = new BackupRecord(app, backupMode);
            BackupRecord r = new BackupRecord(app, backupMode, targetUserId);
            ComponentName hostingName =
                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
                            ? new ComponentName(app.packageName, app.backupAgentName)
@@ -13752,10 +13761,10 @@ public class ActivityManagerService extends IActivityManager.Stub
                proc.inFullBackup = true;
            }
            r.app = proc;
            final BackupRecord backupTarget = mBackupTargets.get(userId);
            final BackupRecord backupTarget = mBackupTargets.get(targetUserId);
            oldBackupUid = backupTarget != null ? backupTarget.appInfo.uid : -1;
            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
            mBackupTargets.put(userId, r);
            mBackupTargets.put(targetUserId, r);
            // Try not to kill the process during backup
            updateOomAdjLocked(proc, true);
@@ -13766,7 +13775,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
                try {
                    proc.thread.scheduleCreateBackupAgent(app,
                            compatibilityInfoForPackage(app), backupMode);
                            compatibilityInfoForPackage(app), backupMode, targetUserId);
                } catch (RemoteException e) {
                    // Will time out on the backup manager side
                }
@@ -13806,16 +13815,18 @@ public class ActivityManagerService extends IActivityManager.Stub
    // A backup agent has just come up
    @Override
    public void backupAgentCreated(String agentPackageName, IBinder agent) {
        final int callingUserId = UserHandle.getCallingUserId();
    public void backupAgentCreated(String agentPackageName, IBinder agent, int userId) {
        // Resolve the target user id and enforce permissions.
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, /* allowAll */ false, ALLOW_FULL_ONLY, "backupAgentCreated", null);
        if (DEBUG_BACKUP) {
            Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName + " = " + agent
                    + " callingUserId = " + callingUserId + " callingUid = "
                    + Binder.getCallingUid() + " uid = " + Process.myUid());
                    + " callingUserId = " + UserHandle.getCallingUserId() + " userId = " + userId
                    + " callingUid = " + Binder.getCallingUid() + " uid = " + Process.myUid());
        }
        synchronized(this) {
            final BackupRecord backupTarget = mBackupTargets.get(callingUserId);
            final BackupRecord backupTarget = mBackupTargets.get(userId);
            String backupAppName = backupTarget == null ? null : backupTarget.appInfo.packageName;
            if (!agentPackageName.equals(backupAppName)) {
                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
@@ -13827,7 +13838,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        try {
            IBackupManager bm = IBackupManager.Stub.asInterface(
                    ServiceManager.getService(Context.BACKUP_SERVICE));
            bm.agentConnectedForUser(callingUserId, agentPackageName, agent);
            bm.agentConnectedForUser(userId, agentPackageName, agent);
        } catch (RemoteException e) {
            // can't happen; the backup manager service is local
        } catch (Exception e) {
@@ -13880,7 +13891,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                if (proc.thread != null) {
                    try {
                        proc.thread.scheduleDestroyBackupAgent(appInfo,
                                compatibilityInfoForPackage(appInfo));
                                compatibilityInfoForPackage(appInfo), userId);
                    } catch (Exception e) {
                        Slog.e(TAG, "Exception when unbinding backup agent:");
                        e.printStackTrace();
Loading