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

Commit a4a54e2a authored by Amith Yamasani's avatar Amith Yamasani
Browse files

Make sure persistent processes are not replicated for secondary users.

An intent is launched in a singleton process if the process is persistent
and the resolved activity/service/etc is not requested to run in a different
process.

Change-Id: I1463e73a76bc8bde4185f9cf4395edb47515841d
parent 455b7bb8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -3458,9 +3458,9 @@ public class PackageParser {
            ai.disableCompatibilityMode();
        }
        if (stopped) {
            p.applicationInfo.flags |= ApplicationInfo.FLAG_STOPPED;
            ai.flags |= ApplicationInfo.FLAG_STOPPED;
        } else {
            p.applicationInfo.flags &= ~ApplicationInfo.FLAG_STOPPED;
            ai.flags &= ~ApplicationInfo.FLAG_STOPPED;
        }
        if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
            ai.enabled = true;
+42 −13
Original line number Diff line number Diff line
@@ -1808,16 +1808,18 @@ public final class ActivityManagerService extends ActivityManagerNative
    final ProcessRecord getProcessRecordLocked(
            String processName, int uid) {
        // Temporary hack to make Settings run per user
        if (uid == Process.SYSTEM_UID && !processName.equals("com.android.settings")) {
        if (uid == Process.SYSTEM_UID) {
            // The system gets to run in any process.  If there are multiple
            // processes with the same uid, just pick the first (this
            // should never happen).
            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
                    processName);
            return procs != null ? procs.valueAt(0) : null;
            if (procs == null) return null;
            final int N = procs.size();
            for (int i = 0; i < N; i++) {
                if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
            }
        }
        // uid = applyUserId(uid);
        ProcessRecord proc = mProcessNames.get(processName, uid);
        return proc;
    }
@@ -6183,7 +6185,9 @@ public final class ActivityManagerService extends ActivityManagerNative
                if (cpi == null) {
                    return null;
                }
                if (isSingleton(cpi.processName, cpi.applicationInfo)) {
                    userId = 0;
                }
                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
                String msg;
@@ -10923,6 +10927,9 @@ public final class ActivityManagerService extends ActivityManagerNative
                    return null;
                }
                if (userId > 0) {
                    if (isSingleton(sInfo.processName, sInfo.applicationInfo)) {
                        userId = 0;
                    }
                    sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
                }
                ComponentName name = new ComponentName(
@@ -11741,6 +11748,21 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
    }
    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) {
        boolean result = false;
        if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
            result = false;
        } else if (componentProcessName == aInfo.packageName) {
            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
        } else if ("system".equals(componentProcessName)) {
            result = true;
        }
        if (DEBUG_MU) {
            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result);
        }
        return result;
    }
    public int bindService(IApplicationThread caller, IBinder token,
            Intent service, String resolvedType,
            IServiceConnection connection, int flags, int userId) {
@@ -11808,6 +11830,11 @@ public final class ActivityManagerService extends ActivityManagerNative
            if (res.record == null) {
                return -1;
            }
            if (isSingleton(res.record.processName, res.record.appInfo)) {
                userId = 0;
                res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
                        Binder.getCallingUid(), 0);
            }
            ServiceRecord s = res.record;
            final long origId = Binder.clearCallingIdentity();
@@ -12740,7 +12767,11 @@ public final class ActivityManagerService extends ActivityManagerNative
                if (ai != null) {
                    receivers = new ArrayList();
                    ResolveInfo ri = new ResolveInfo();
                    if (isSingleton(ai.processName, ai.applicationInfo)) {
                        ri.activityInfo = getActivityInfoForUser(ai, 0);
                    } else {
                        ri.activityInfo = getActivityInfoForUser(ai, userId);
                    }
                    receivers.add(ri);
                }
            } else {
@@ -14894,16 +14925,14 @@ public final class ActivityManagerService extends ActivityManagerNative
        if (info == null) return null;
        ApplicationInfo newInfo = new ApplicationInfo(info);
        newInfo.uid = applyUserId(info.uid, userId);
        if (newInfo.uid >= Process.FIRST_APPLICATION_UID) {
        newInfo.dataDir = USER_DATA_DIR + userId + "/"
                + info.packageName;
        }
        return newInfo;
    }
    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
        if (aInfo == null || aInfo.applicationInfo.uid < Process.FIRST_APPLICATION_UID
                || userId < 1) {
        if (aInfo == null
                || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
            return aInfo;
        }
+5 −1
Original line number Diff line number Diff line
@@ -2345,8 +2345,9 @@ final class ActivityStack {
        }

        if (err == ActivityManager.START_SUCCESS) {
            final int userId = aInfo != null ? UserId.getUserId(aInfo.applicationInfo.uid) : 0;
            Slog.i(TAG, "START {" + intent.toShortString(true, true, true, false)
                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
                    + " u=" + userId + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
        }

        ActivityRecord sourceRecord = null;
@@ -2943,6 +2944,9 @@ final class ActivityStack {
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
                profileFile, profileFd, userId);
        if (mService.isSingleton(aInfo.processName, aInfo.applicationInfo)) {
            userId = 0;
        }
        aInfo = mService.getActivityInfoForUser(aInfo, userId);

        synchronized (mService) {
+4 −2
Original line number Diff line number Diff line
@@ -719,8 +719,10 @@ public class BroadcastQueue {
                    info.activityInfo.applicationInfo.packageName,
                    info.activityInfo.name);
            if (r.callingUid != Process.SYSTEM_UID) {
                info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, UserId
                        .getUserId(r.callingUid));
                boolean isSingleton = mService.isSingleton(info.activityInfo.processName,
                        info.activityInfo.applicationInfo);
                int targetUserId = isSingleton ? 0 : UserId.getUserId(r.callingUid);
                info.activityInfo = mService.getActivityInfoForUser(info.activityInfo,targetUserId);
            }
            r.curReceiver = info.activityInfo;
            if (DEBUG_MU && r.callingUid > UserId.PER_USER_RANGE) {