diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index b6ebbdf02867a..185fcb97fa5f4 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -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; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index e37adc7ab2c38..77bec41b71939 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -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 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( @@ -11740,7 +11747,22 @@ 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(); - ri.activityInfo = getActivityInfoForUser(ai, userId); + 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; - } + 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; } diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 6596e1fd28fad..2c53186bbd8d9 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -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) { diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java index 1b83e0b869c40..47b8c0aa98479 100644 --- a/services/java/com/android/server/am/BroadcastQueue.java +++ b/services/java/com/android/server/am/BroadcastQueue.java @@ -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) {