Merge "ASM - Bug fixes for clearTopIfNeeded" into udc-dev
diff --git a/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java b/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java
index 1f7af41..19d8129 100644
--- a/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java
+++ b/services/core/java/com/android/server/wm/ActivitySecurityModelFeatureFlags.java
@@ -43,7 +43,7 @@
     static final String DOC_LINK = "go/android-asm";
 
     /** Used to determine which version of the ASM logic was used in logs while we iterate */
-    static final int ASM_VERSION = 6;
+    static final int ASM_VERSION = 7;
 
     private static final String NAMESPACE = NAMESPACE_WINDOW_MANAGER;
     private static final String KEY_ASM_PREFIX = "ActivitySecurity__";
@@ -89,6 +89,9 @@
 
         if (flagEnabled) {
             String[] packageNames = sPm.getPackagesForUid(uid);
+            if (packageNames == null) {
+                return true;
+            }
             for (int i = 0; i < packageNames.length; i++) {
                 if (sExcludedPackageNames.contains(packageNames[i])) {
                     return false;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 89cd7db..211c230 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2269,13 +2269,14 @@
      */
     private void clearTopIfNeeded(@NonNull Task targetTask, int callingUid, int realCallingUid,
             int startingUid, int launchFlags) {
-        if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) != FLAG_ACTIVITY_NEW_TASK) {
-            // Launch is from the same task, so must be a top or privileged UID
+        if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) != FLAG_ACTIVITY_NEW_TASK
+                || mBalCode == BAL_ALLOW_ALLOWLISTED_UID) {
+            // Launch is from the same task, (a top or privileged UID), or is directly privileged.
             return;
         }
 
-        Predicate<ActivityRecord> isLaunchingOrLaunched = ar -> !ar.finishing
-                && (ar.isUid(startingUid) || ar.isUid(callingUid) || ar.isUid(realCallingUid));
+        Predicate<ActivityRecord> isLaunchingOrLaunched = ar ->
+                ar.isUid(startingUid) || ar.isUid(callingUid) || ar.isUid(realCallingUid);
 
         // Return early if we know for sure we won't need to clear any activities by just checking
         // the top activity.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index a0a2557..eaf5583 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1666,7 +1666,7 @@
             String callerActivityClassName) {
         // We may have already checked that the callingUid has additional clearTask privileges, and
         // cleared the calling identify. If so, we infer we do not need further restrictions here.
-        if (callingUid == SYSTEM_UID) {
+        if (callingUid == SYSTEM_UID || !task.isVisible() || task.inMultiWindowMode()) {
             return;
         }
 
@@ -1772,13 +1772,19 @@
             return new Pair<>(true, true);
         }
 
+        // Always allow actual top activity to clear task
+        ActivityRecord topActivity = task.getTopMostActivity();
+        if (topActivity != null && topActivity.isUid(uid)) {
+            return new Pair<>(true, true);
+        }
+
         // Consider the source activity, whether or not it is finishing. Do not consider any other
         // finishing activity.
         Predicate<ActivityRecord> topOfStackPredicate = (ar) -> ar.equals(sourceRecord)
                 || (!ar.finishing && !ar.isAlwaysOnTop());
 
         // Check top of stack (or the first task fragment for embedding).
-        ActivityRecord topActivity = task.getActivity(topOfStackPredicate);
+        topActivity = task.getActivity(topOfStackPredicate);
         if (topActivity == null) {
             return new Pair<>(false, false);
         }