Merge "Allow companion apps to start background activities from PendingIntents (even if they aren't foreground)"
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index a7404bc..a3e7d36 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -164,6 +164,20 @@
     }
 
     @Override
+    public void onUnlockUser(int userHandle) {
+        Set<Association> associations = readAllAssociations(userHandle);
+        Set<String> companionAppPackages = new HashSet<>();
+        for (Association association : associations) {
+            companionAppPackages.add(association.companionAppPackage);
+        }
+        ActivityTaskManagerInternal atmInternal = LocalServices.getService(
+                ActivityTaskManagerInternal.class);
+        if (atmInternal != null) {
+            atmInternal.setCompanionAppPackages(userHandle, companionAppPackages);
+        }
+    }
+
+    @Override
     public void binderDied() {
         Handler.getMain().post(this::cleanup);
     }
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index cd15587..3b358e8 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -981,6 +981,11 @@
             if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
                 return false;
             }
+            // don't abort if the realCallingUid is an associated companion app
+            if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
+                    realCallingUid)) {
+                return false;
+            }
         }
         // If we don't have callerApp at this point, no caller was provided to startActivity().
         // That's the case for PendingIntent-based starts, since the creator's process might not be
@@ -1026,7 +1031,7 @@
         }
         // don't abort if the callingPackage has companion device
         final int callingUserId = UserHandle.getUserId(callingUid);
-        if (mService.isAssociatedCompanionApp(callingUserId, callingPackage)) {
+        if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
             return false;
         }
         // don't abort if the callingPackage is temporarily whitelisted
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 4a687fe..b64abdb 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -443,8 +443,8 @@
     // VoiceInteractionManagerService
     ComponentName mActiveVoiceInteractionServiceComponent;
 
-    // A map userId and all its companion app packages
-    private final Map<Integer, Set<String>> mCompanionAppPackageMap = new ArrayMap<>();
+    // A map userId and all its companion app uids
+    private final Map<Integer, Set<Integer>> mCompanionAppUidsMap = new ArrayMap<>();
 
     VrController mVrController;
     KeyguardController mKeyguardController;
@@ -5907,12 +5907,12 @@
         }
     }
 
-    boolean isAssociatedCompanionApp(int userId, String packageName) {
-        final Set<String> allPackages = mCompanionAppPackageMap.get(userId);
-        if (allPackages == null) {
+    boolean isAssociatedCompanionApp(int userId, int uid) {
+        final Set<Integer> allUids = mCompanionAppUidsMap.get(userId);
+        if (allUids == null) {
             return false;
         }
-        return allPackages.contains(packageName);
+        return allUids.contains(uid);
     }
 
     final class H extends Handler {
@@ -7291,13 +7291,16 @@
 
         @Override
         public void setCompanionAppPackages(int userId, Set<String> companionAppPackages) {
-            // Deep copy all content to make sure we do not rely on the source
-            final Set<String> result = new HashSet<>();
+            // Translate package names into UIDs
+            final Set<Integer> result = new HashSet<>();
             for (String pkg : companionAppPackages) {
-                result.add(pkg);
+                final int uid = getPackageManagerInternalLocked().getPackageUid(pkg, 0, userId);
+                if (uid >= 0) {
+                    result.add(uid);
+                }
             }
             synchronized (mGlobalLock) {
-                mCompanionAppPackageMap.put(userId, result);
+                mCompanionAppUidsMap.put(userId, result);
             }
         }
     }