Restrict readability of uid state changes so that uid states of other users uids are not exposed to those that do not have permission.

Test: manual test
Bug: 217934898
Change-Id: I3f52d4ca32c22c54fa9b1663954a43b44d9000a0
Merged-In: I3f52d4ca32c22c54fa9b1663954a43b44d9000a0
(cherry picked from commit c69aa1be70009c10e76196f71023f229cc667b7a)
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 6897c01..9a1b8a9 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -171,10 +171,11 @@
     <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="audioserver" />
     <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="audioserver" />
     <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="audioserver" />
-    <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="audioserver" />
+    <assign-permission name="android.permission.INTERACT_ACROSS_USERS_FULL" uid="audioserver" />
     <assign-permission name="android.permission.OBSERVE_SENSOR_PRIVACY" uid="audioserver" />
 
     <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="cameraserver" />
+    <assign-permission name="android.permission.INTERACT_ACROSS_USERS_FULL" uid="cameraserver" />
     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="cameraserver" />
     <assign-permission name="android.permission.WAKE_LOCK" uid="cameraserver" />
     <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="cameraserver" />
diff --git a/services/core/java/com/android/server/am/UidObserverController.java b/services/core/java/com/android/server/am/UidObserverController.java
index e8c1b54..51cb987 100644
--- a/services/core/java/com/android/server/am/UidObserverController.java
+++ b/services/core/java/com/android/server/am/UidObserverController.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.am;
 
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
@@ -25,6 +26,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerProto;
 import android.app.IUidObserver;
+import android.content.pm.PackageManager;
 import android.os.Handler;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -81,7 +83,9 @@
             @NonNull String callingPackage, int callingUid) {
         synchronized (mLock) {
             mUidObservers.register(observer, new UidObserverRegistration(callingUid,
-                    callingPackage, which, cutpoint));
+                    callingPackage, which, cutpoint,
+                    ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, callingUid)
+                    == PackageManager.PERMISSION_GRANTED));
         }
     }
 
@@ -252,6 +256,11 @@
                 final ChangeRecord item = mActiveUidChanges[j];
                 final long start = SystemClock.uptimeMillis();
                 final int change = item.change;
+                // Does the user have permission? Don't send a non user UID change otherwise
+                if (UserHandle.getUserId(item.uid) != UserHandle.getUserId(reg.mUid)
+                        && !reg.mCanInteractAcrossUsers) {
+                    continue;
+                }
                 if (change == UidRecord.CHANGE_PROCSTATE
                         && (reg.mWhich & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
                     // No-op common case: no significant change, the observer is not
@@ -437,6 +446,7 @@
         private final String mPkg;
         private final int mWhich;
         private final int mCutpoint;
+        private final boolean mCanInteractAcrossUsers;
 
         /**
          * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
@@ -467,11 +477,13 @@
                 ActivityManagerProto.UID_OBSERVER_FLAG_PROC_OOM_ADJ,
         };
 
-        UidObserverRegistration(int uid, @NonNull String pkg, int which, int cutpoint) {
+        UidObserverRegistration(int uid, @NonNull String pkg, int which, int cutpoint,
+                boolean canInteractAcrossUsers) {
             this.mUid = uid;
             this.mPkg = pkg;
             this.mWhich = which;
             this.mCutpoint = cutpoint;
+            this.mCanInteractAcrossUsers = canInteractAcrossUsers;
             mLastProcStates = cutpoint >= ActivityManager.MIN_PROCESS_STATE
                     ? new SparseIntArray() : null;
         }