|
147 | 147 | import java.io.StringWriter; |
148 | 148 | import java.lang.ref.WeakReference; |
149 | 149 | import java.util.ArrayList; |
| 150 | +import java.util.Arrays; |
150 | 151 | import java.util.Collections; |
151 | 152 | import java.util.Comparator; |
152 | 153 | import java.util.HashMap; |
@@ -447,6 +448,11 @@ abstract class ForegroundToken implements IBinder.DeathRecipient { |
447 | 448 | */ |
448 | 449 | final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); |
449 | 450 |
|
| 451 | + /** |
| 452 | + * Constant array of the users that are currently started. |
| 453 | + */ |
| 454 | + int[] mStartedUserArray = new int[] { 0 }; |
| 455 | + |
450 | 456 | /** |
451 | 457 | * Registered observers of the user switching mechanics. |
452 | 458 | */ |
@@ -832,7 +838,8 @@ static class ProcessChangeItem { |
832 | 838 | static ActivityManagerService mSelf; |
833 | 839 | static ActivityThread mSystemThread; |
834 | 840 |
|
835 | | - private int mCurrentUserId; |
| 841 | + private int mCurrentUserId = 0; |
| 842 | + private int[] mCurrentUserArray = new int[] { 0 }; |
836 | 843 | private UserManagerService mUserManager; |
837 | 844 |
|
838 | 845 | private final class AppDeathRecipient implements IBinder.DeathRecipient { |
@@ -1568,6 +1575,7 @@ private ActivityManagerService() { |
1568 | 1575 | // User 0 is the first and only user that runs at boot. |
1569 | 1576 | mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); |
1570 | 1577 | mUserLru.add(Integer.valueOf(0)); |
| 1578 | + updateStartedUserArrayLocked(); |
1571 | 1579 |
|
1572 | 1580 | GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", |
1573 | 1581 | ConfigurationInfo.GL_ES_VERSION_UNDEFINED); |
@@ -3750,6 +3758,7 @@ private void forceStopPackageLocked(final String packageName, int uid) { |
3750 | 3758 | intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); |
3751 | 3759 | } |
3752 | 3760 | intent.putExtra(Intent.EXTRA_UID, uid); |
| 3761 | + intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); |
3753 | 3762 | broadcastIntentLocked(null, null, intent, |
3754 | 3763 | null, null, 0, null, null, null, |
3755 | 3764 | false, false, |
@@ -9311,6 +9320,9 @@ boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, |
9311 | 9320 | pw.print(mUserLru.get(i)); |
9312 | 9321 | } |
9313 | 9322 | pw.println("]"); |
| 9323 | + if (dumpAll) { |
| 9324 | + pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); |
| 9325 | + } |
9314 | 9326 | pw.println(" mHomeProcess: " + mHomeProcess); |
9315 | 9327 | pw.println(" mPreviousProcess: " + mPreviousProcess); |
9316 | 9328 | if (dumpAll) { |
@@ -11498,7 +11510,7 @@ private final int broadcastIntentLocked(ProcessRecord callerApp, |
11498 | 11510 | userId = handleIncomingUserLocked(callingPid, callingUid, userId, |
11499 | 11511 | true, false, "broadcast", callerPackage); |
11500 | 11512 |
|
11501 | | - // Make sure that the user who is receiving this broadcast is started |
| 11513 | + // Make sure that the user who is receiving this broadcast is started. |
11502 | 11514 | // If not, we will just skip it. |
11503 | 11515 | if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { |
11504 | 11516 | if (callingUid != Process.SYSTEM_UID || (intent.getFlags() |
@@ -11693,13 +11705,10 @@ private final int broadcastIntentLocked(ProcessRecord callerApp, |
11693 | 11705 | int[] users; |
11694 | 11706 | if (userId == UserHandle.USER_ALL) { |
11695 | 11707 | // Caller wants broadcast to go to all started users. |
11696 | | - users = new int[mStartedUsers.size()]; |
11697 | | - for (int i=0; i<mStartedUsers.size(); i++) { |
11698 | | - users[i] = mStartedUsers.keyAt(i); |
11699 | | - } |
| 11708 | + users = mStartedUserArray; |
11700 | 11709 | } else { |
11701 | 11710 | // Caller wants broadcast to go to one specific user. |
11702 | | - users = new int[] {userId}; |
| 11711 | + users = mCurrentUserArray; |
11703 | 11712 | } |
11704 | 11713 |
|
11705 | 11714 | // Figure out who all will receive this broadcast. |
@@ -13975,9 +13984,11 @@ public boolean switchUser(int userId) { |
13975 | 13984 | // we need to start it now. |
13976 | 13985 | if (mStartedUsers.get(userId) == null) { |
13977 | 13986 | mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); |
| 13987 | + updateStartedUserArrayLocked(); |
13978 | 13988 | } |
13979 | 13989 |
|
13980 | 13990 | mCurrentUserId = userId; |
| 13991 | + mCurrentUserArray = new int[] { userId }; |
13981 | 13992 | final Integer userIdInt = Integer.valueOf(userId); |
13982 | 13993 | mUserLru.remove(userIdInt); |
13983 | 13994 | mUserLru.add(userIdInt); |
@@ -14256,6 +14267,7 @@ void finishUserStop(UserStartedState uss) { |
14256 | 14267 | // User can no longer run. |
14257 | 14268 | mStartedUsers.remove(userId); |
14258 | 14269 | mUserLru.remove(Integer.valueOf(userId)); |
| 14270 | + updateStartedUserArrayLocked(); |
14259 | 14271 |
|
14260 | 14272 | // Clean up all state and processes associated with the user. |
14261 | 14273 | // Kill all the processes for the user. |
@@ -14311,6 +14323,29 @@ boolean isUserRunningLocked(int userId) { |
14311 | 14323 | return state != null && state.mState != UserStartedState.STATE_STOPPING; |
14312 | 14324 | } |
14313 | 14325 |
|
| 14326 | + @Override |
| 14327 | + public int[] getRunningUserIds() { |
| 14328 | + if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) |
| 14329 | + != PackageManager.PERMISSION_GRANTED) { |
| 14330 | + String msg = "Permission Denial: isUserRunning() from pid=" |
| 14331 | + + Binder.getCallingPid() |
| 14332 | + + ", uid=" + Binder.getCallingUid() |
| 14333 | + + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; |
| 14334 | + Slog.w(TAG, msg); |
| 14335 | + throw new SecurityException(msg); |
| 14336 | + } |
| 14337 | + synchronized (this) { |
| 14338 | + return mStartedUserArray; |
| 14339 | + } |
| 14340 | + } |
| 14341 | + |
| 14342 | + private void updateStartedUserArrayLocked() { |
| 14343 | + mStartedUserArray = new int[mStartedUsers.size()]; |
| 14344 | + for (int i=0; i<mStartedUsers.size(); i++) { |
| 14345 | + mStartedUserArray[i] = mStartedUsers.keyAt(i); |
| 14346 | + } |
| 14347 | + } |
| 14348 | + |
14314 | 14349 | @Override |
14315 | 14350 | public void registerUserSwitchObserver(IUserSwitchObserver observer) { |
14316 | 14351 | if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) |
|
0 commit comments