Fix issue #16366571: UIDs for work and normal Chrome processes are the same

Use uid as main key for determining which app tasks a caller has
access to.

Change-Id: Ibbe3f0f64197671d279c3fc519edfc720d442938
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b86621f..2667bcd 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -985,7 +985,7 @@
         ArrayList<AppTask> tasks = new ArrayList<AppTask>();
         List<IAppTask> appTasks;
         try {
-            appTasks = ActivityManagerNative.getDefault().getAppTasks();
+            appTasks = ActivityManagerNative.getDefault().getAppTasks(mContext.getPackageName());
         } catch (RemoteException e) {
             // System dead, we will be dead too soon!
             return null;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 3dafa4b..97e793f 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -554,7 +554,8 @@
 
         case GET_APP_TASKS_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            List<IAppTask> list = getAppTasks();
+            String callingPackage = data.readString();
+            List<IAppTask> list = getAppTasks(callingPackage);
             reply.writeNoException();
             int N = list != null ? list.size() : -1;
             reply.writeInt(N);
@@ -2880,10 +2881,11 @@
         reply.recycle();
         return res;
     }
-    public List<IAppTask> getAppTasks() throws RemoteException {
+    public List<IAppTask> getAppTasks(String callingPackage) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(callingPackage);
         mRemote.transact(GET_APP_TASKS_TRANSACTION, data, reply, 0);
         reply.readException();
         ArrayList<IAppTask> list = null;
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 70514d8..fcfe5aa 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -119,7 +119,7 @@
     public void activityDestroyed(IBinder token) throws RemoteException;
     public String getCallingPackage(IBinder token) throws RemoteException;
     public ComponentName getCallingActivity(IBinder token) throws RemoteException;
-    public List<IAppTask> getAppTasks() throws RemoteException;
+    public List<IAppTask> getAppTasks(String callingPackage) throws RemoteException;
     public int addAppTask(IBinder activityToken, Intent intent,
             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException;
     public Point getAppTaskThumbnailSize() throws RemoteException;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e8b1d03..192c566 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7509,18 +7509,10 @@
     // =========================================================
 
     @Override
-    public List<IAppTask> getAppTasks() {
-        final PackageManager pm = mContext.getPackageManager();
+    public List<IAppTask> getAppTasks(String callingPackage) {
         int callingUid = Binder.getCallingUid();
         long ident = Binder.clearCallingIdentity();
 
-        // Compose the list of packages for this id to test against
-        HashSet<String> packages = new HashSet<String>();
-        String[] uidPackages = pm.getPackagesForUid(callingUid);
-        for (int i = 0; i < uidPackages.length; i++) {
-            packages.add(uidPackages[i]);
-        }
-
         synchronized(this) {
             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
             try {
@@ -7529,13 +7521,21 @@
                 final int N = mRecentTasks.size();
                 for (int i = 0; i < N; i++) {
                     TaskRecord tr = mRecentTasks.get(i);
-                    // Skip tasks that do not match the package name
-                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
-                        ActivityManager.RecentTaskInfo taskInfo =
-                                createRecentTaskInfoFromTaskRecord(tr);
-                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
-                        list.add(taskImpl);
+                    // Skip tasks that do not match the caller.  We don't need to verify
+                    // callingPackage, because we are also limiting to callingUid and know
+                    // that will limit to the correct security sandbox.
+                    if (tr.effectiveUid != callingUid) {
+                        continue;
                     }
+                    Intent intent = tr.getBaseIntent();
+                    if (intent == null ||
+                            !callingPackage.equals(intent.getComponent().getPackageName())) {
+                        continue;
+                    }
+                    ActivityManager.RecentTaskInfo taskInfo =
+                            createRecentTaskInfoFromTaskRecord(tr);
+                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
+                    list.add(taskImpl);
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -7699,7 +7699,7 @@
                     if (!allowed) {
                         // If the caller doesn't have the GET_TASKS permission, then only
                         // allow them to see a small subset of tasks -- their own and home.
-                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
+                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
                             continue;
                         }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 5ad84d4..e6edff8e 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3763,7 +3763,7 @@
             if (activities.isEmpty()) {
                 continue;
             }
-            if (!allowed && !task.isHomeTask() && task.creatorUid != callingUid) {
+            if (!allowed && !task.isHomeTask() && task.effectiveUid != callingUid) {
                 continue;
             }
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 2a8c6fb..845a5b0 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -26,11 +26,16 @@
 import android.app.ActivityManager;
 import android.app.ActivityManager.TaskThumbnail;
 import android.app.ActivityOptions;
+import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.Slog;
@@ -57,6 +62,7 @@
     private static final String ATTR_AUTOREMOVERECENTS = "auto_remove_recents";
     private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
     private static final String ATTR_USERID = "user_id";
+    private static final String ATTR_EFFECTIVE_UID = "effective_uid";
     private static final String ATTR_TASKTYPE = "task_type";
     private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
     private static final String ATTR_LASTACTIVETIME = "last_active_time";
@@ -83,6 +89,7 @@
     final IVoiceInteractor voiceInteractor;         // Associated interactor to provide to app
     Intent intent;          // The original intent that started the task.
     Intent affinityIntent;  // Intent of affinity-moved activity that started this task.
+    int effectiveUid;       // The current effective uid of the identity of this task.
     ComponentName origActivity; // The non-alias activity component of the intent.
     ComponentName realActivity; // The actual activity component that started the task.
     long firstActiveTime;   // First time this task was active.
@@ -198,7 +205,7 @@
     TaskRecord(ActivityManagerService service, int _taskId, Intent _intent, Intent _affinityIntent,
             String _affinity, ComponentName _realActivity, ComponentName _origActivity,
             boolean _rootWasReset, boolean _autoRemoveRecents, boolean _askedCompatMode,
-            int _taskType, int _userId,
+            int _taskType, int _userId, int _effectiveUid,
             String _lastDescription, ArrayList<ActivityRecord> activities, long _firstActiveTime,
             long _lastActiveTime, long lastTimeMoved, boolean neverRelinquishIdentity,
             ActivityManager.TaskDescription _lastTaskDescription, int taskAffiliation,
@@ -222,6 +229,7 @@
         taskType = _taskType;
         mTaskToReturnTo = HOME_ACTIVITY_TYPE;
         userId = _userId;
+        effectiveUid = _effectiveUid;
         firstActiveTime = _firstActiveTime;
         lastActiveTime = _lastActiveTime;
         lastDescription = _lastDescription;
@@ -265,6 +273,7 @@
         }
 
         affinity = info.taskAffinity;
+        effectiveUid = info.applicationInfo.uid;
         stringName = null;
 
         if (info.targetActivity == null) {
@@ -311,7 +320,6 @@
         }
 
         userId = UserHandle.getUserId(info.applicationInfo.uid);
-        creatorUid = info.applicationInfo.uid;
         if ((info.flags & ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS) != 0) {
             // If the activity itself has requested auto-remove, then just always do it.
             autoRemoveRecents = true;
@@ -814,6 +822,7 @@
         out.attribute(null, ATTR_AUTOREMOVERECENTS, String.valueOf(autoRemoveRecents));
         out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
         out.attribute(null, ATTR_USERID, String.valueOf(userId));
+        out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
         out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
         out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
         out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
@@ -872,6 +881,7 @@
         boolean askedCompatMode = false;
         int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
         int userId = 0;
+        int effectiveUid = -1;
         String lastDescription = null;
         long firstActiveTime = -1;
         long lastActiveTime = -1;
@@ -908,6 +918,8 @@
                 askedCompatMode = Boolean.valueOf(attrValue);
             } else if (ATTR_USERID.equals(attrName)) {
                 userId = Integer.valueOf(attrValue);
+            } else if (ATTR_EFFECTIVE_UID.equals(attrName)) {
+                effectiveUid = Integer.valueOf(attrValue);
             } else if (ATTR_TASKTYPE.equals(attrName)) {
                 taskType = Integer.valueOf(attrValue);
             } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) {
@@ -970,10 +982,30 @@
                     createLastTaskDescriptionIconFilename(taskId, lastActiveTime)));
         }
 
+        if (effectiveUid <= 0) {
+            Intent checkIntent = intent != null ? intent : affinityIntent;
+            effectiveUid = 0;
+            if (checkIntent != null) {
+                IPackageManager pm = AppGlobals.getPackageManager();
+                try {
+                    ApplicationInfo ai = pm.getApplicationInfo(
+                            checkIntent.getComponent().getPackageName(),
+                            PackageManager.GET_UNINSTALLED_PACKAGES
+                                    | PackageManager.GET_DISABLED_COMPONENTS, userId);
+                    if (ai != null) {
+                        effectiveUid = ai.uid;
+                    }
+                } catch (RemoteException e) {
+                }
+            }
+            Slog.w(TAG, "Updating task #" + taskId + " for " + checkIntent
+                    + ": effectiveUid=" + effectiveUid);
+        }
+
         final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
                 affinityIntent, affinity, realActivity, origActivity, rootHasReset,
-                autoRemoveRecents, askedCompatMode, taskType, userId, lastDescription, activities,
-                firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
+                autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
+                activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
                 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
                 callingUid, callingPackage);
 
@@ -987,8 +1019,8 @@
 
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("userId="); pw.print(userId);
-                pw.print(" creatorUid="); pw.print(creatorUid);
-                pw.print(" mCallingUid="); pw.print(mCallingUid);
+                pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
+                pw.print(" mCallingUid="); UserHandle.formatUid(pw, mCallingUid);
                 pw.print(" mCallingPackage="); pw.println(mCallingPackage);
         if (affinity != null) {
             pw.print(prefix); pw.print("affinity="); pw.println(affinity);