Show the current user in power menu

Shows a little indicator next to the current user in the power menu
when multi-user is enabled.

Fixed a bug where Settings was sometimes being launched in the wrong
process when there are 2 instances running.

Change-Id: Iaf2a00f6d1871fd2a88d8982439e445423bb2896
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index c402329..5917cbf 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -25,6 +25,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageDataObserver;
+import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.net.Uri;
@@ -1494,7 +1495,15 @@
             reply.writeInt(result ? 1 : 0);
             return true;
         }
-        
+
+        case GET_CURRENT_USER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            UserInfo userInfo = getCurrentUser();
+            reply.writeNoException();
+            userInfo.writeToParcel(reply, 0);
+            return true;
+        }
+
         case REMOVE_SUB_TASK_TRANSACTION:
         {
             data.enforceInterface(IActivityManager.descriptor);
@@ -3530,7 +3539,19 @@
         data.recycle();
         return result;
     }
-    
+
+    public UserInfo getCurrentUser() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(SWITCH_USER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        UserInfo userInfo = UserInfo.CREATOR.createFromParcel(reply);
+        reply.recycle();
+        data.recycle();
+        return userInfo;
+    }
+
     public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 1d994d8..2b1eb43 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -28,6 +28,7 @@
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.ProviderInfo;
+import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.net.Uri;
@@ -318,10 +319,11 @@
     public boolean getPackageAskScreenCompat(String packageName) throws RemoteException;
     public void setPackageAskScreenCompat(String packageName, boolean ask)
             throws RemoteException;
-    
+
     // Multi-user APIs
     public boolean switchUser(int userid) throws RemoteException;
-    
+    public UserInfo getCurrentUser() throws RemoteException;
+
     public boolean removeSubTask(int taskId, int subTaskIndex) throws RemoteException;
 
     public boolean removeTask(int taskId, int flags) throws RemoteException;
@@ -575,4 +577,5 @@
     int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141;
     int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
     int KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+143;
+    int GET_CURRENT_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+144;
 }
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 4ebabd3..aeb518c 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -200,10 +200,19 @@
 
         List<UserInfo> users = mContext.getPackageManager().getUsers();
         if (users.size() > 1) {
+            UserInfo currentUser;
+            try {
+                currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+            } catch (RemoteException re) {
+                currentUser = null;
+            }
             for (final UserInfo user : users) {
+                boolean isCurrentUser = currentUser == null
+                        ? user.id == 0 : (currentUser.id == user.id);
                 SinglePressAction switchToUser = new SinglePressAction(
                         com.android.internal.R.drawable.ic_menu_cc,
-                        user.name != null ? user.name : "Primary") {
+                        (user.name != null ? user.name : "Primary")
+                        + (isCurrentUser ? " \u2714" : "")) {
                     public void onPress() {
                         try {
                             ActivityManagerNative.getDefault().switchUser(user.id);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 78f17bc..143f77d 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1795,12 +1795,15 @@
     final ProcessRecord getProcessRecordLocked(
             String processName, int uid) {
         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;
+            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
+            if (procs == null) return null;
+            int N = procs.size();
+            for (int i = 0; i < N; i++) {
+                if (UserId.isSameUser(procs.keyAt(i), uid)) {
+                    return procs.valueAt(i);
+                }
+            }
+            return null;
         }
         // uid = applyUserId(uid);
         ProcessRecord proc = mProcessNames.get(processName, uid);
@@ -14645,6 +14648,16 @@
         return true;
     }
 
+    @Override
+    public UserInfo getCurrentUser() throws RemoteException {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != 0 && callingUid != Process.myUid()) {
+            Slog.e(TAG, "Trying to get user from unauthorized app");
+            return null;
+        }
+        return AppGlobals.getPackageManager().getUser(mCurrentUserId);
+    }
+
     private void onUserRemoved(Intent intent) {
         int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
         if (extraUserId < 1) return;