Merge "Fix unintended preferred activity reset" into rvc-dev am: 69b18e57fc am: a08113255b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12220605

Change-Id: Ie6e90cdc7ec8cd2788bf3501b869cbe7d3e026c8
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b4ab57f..63c721a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -6432,9 +6432,14 @@
                     true /*allowDynamicSplits*/);
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
+            final boolean queryMayBeFiltered =
+                    UserHandle.getAppId(filterCallingUid) >= Process.FIRST_APPLICATION_UID
+                            && !resolveForStart;
+
             final ResolveInfo bestChoice =
                     chooseBestActivity(
-                            intent, resolvedType, flags, privateResolveFlags, query, userId);
+                            intent, resolvedType, flags, privateResolveFlags, query, userId,
+                            queryMayBeFiltered);
             final boolean nonBrowserOnly =
                     (privateResolveFlags & PackageManagerInternal.RESOLVE_NON_BROWSER_ONLY) != 0;
             if (nonBrowserOnly && bestChoice != null && bestChoice.handleAllWebDataURI) {
@@ -6598,7 +6603,8 @@
     }
 
     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
-            int flags, int privateResolveFlags, List<ResolveInfo> query, int userId) {
+            int flags, int privateResolveFlags, List<ResolveInfo> query, int userId,
+            boolean queryMayBeFiltered) {
         if (query != null) {
             final int N = query.size();
             if (N == 1) {
@@ -6623,7 +6629,7 @@
                 // If we have saved a preference for a preferred activity for
                 // this Intent, use that.
                 ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
-                        flags, query, r0.priority, true, false, debug, userId);
+                        flags, query, r0.priority, true, false, debug, userId, queryMayBeFiltered);
                 if (ri != null) {
                     return ri;
                 }
@@ -6805,11 +6811,19 @@
                 && intent.hasCategory(CATEGORY_DEFAULT);
     }
 
+    ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
+            List<ResolveInfo> query, int priority, boolean always,
+            boolean removeMatches, boolean debug, int userId) {
+        return findPreferredActivityNotLocked(
+                intent, resolvedType, flags, query, priority, always, removeMatches, debug, userId,
+                UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID);
+    }
+
     // TODO: handle preferred activities missing while user has amnesia
     /** <b>must not hold {@link #mLock}</b> */
     ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
             List<ResolveInfo> query, int priority, boolean always,
-            boolean removeMatches, boolean debug, int userId) {
+            boolean removeMatches, boolean debug, int userId, boolean queryMayBeFiltered) {
         if (Thread.holdsLock(mLock)) {
             Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                     + " is holding mLock", new Throwable());
@@ -6903,10 +6917,12 @@
                         }
                         final boolean excludeSetupWizardHomeActivity = isHomeIntent(intent)
                                 && !isDeviceProvisioned;
+                        final boolean allowSetMutation = !excludeSetupWizardHomeActivity
+                                && !queryMayBeFiltered;
                         if (ai == null) {
                             // Do not remove launcher's preferred activity during SetupWizard
                             // due to it may not install yet
-                            if (excludeSetupWizardHomeActivity) {
+                            if (!allowSetMutation) {
                                 continue;
                             }
 
@@ -6931,7 +6947,7 @@
                                 continue;
                             }
 
-                            if (removeMatches) {
+                            if (removeMatches && allowSetMutation) {
                                 pir.removeFilter(pa);
                                 changed = true;
                                 if (DEBUG_PREFERRED) {
@@ -6948,7 +6964,7 @@
 
                             if (always && !pa.mPref.sameSet(query, excludeSetupWizardHomeActivity)) {
                                 if (pa.mPref.isSuperset(query, excludeSetupWizardHomeActivity)) {
-                                    if (!excludeSetupWizardHomeActivity) {
+                                    if (allowSetMutation) {
                                         // some components of the set are no longer present in
                                         // the query, but the preferred activity can still be reused
                                         if (DEBUG_PREFERRED) {
@@ -6969,24 +6985,28 @@
                                         changed = true;
                                     } else {
                                         if (DEBUG_PREFERRED) {
-                                            Slog.i(TAG, "Do not remove preferred activity for launcher"
-                                                    + " during SetupWizard");
+                                            Slog.i(TAG, "Do not remove preferred activity");
                                         }
                                     }
                                 } else {
-                                    Slog.i(TAG,
-                                            "Result set changed, dropping preferred activity for "
-                                                    + intent + " type " + resolvedType);
-                                    if (DEBUG_PREFERRED) {
-                                        Slog.v(TAG, "Removing preferred activity since set changed "
-                                                + pa.mPref.mComponent);
+                                    if (allowSetMutation) {
+                                        Slog.i(TAG,
+                                                "Result set changed, dropping preferred activity "
+                                                        + "for " + intent + " type "
+                                                        + resolvedType);
+                                        if (DEBUG_PREFERRED) {
+                                            Slog.v(TAG,
+                                                    "Removing preferred activity since set changed "
+                                                            + pa.mPref.mComponent);
+                                        }
+                                        pir.removeFilter(pa);
+                                        // Re-add the filter as a "last chosen" entry (!always)
+                                        PreferredActivity lastChosen = new PreferredActivity(
+                                                pa, pa.mPref.mMatch, null, pa.mPref.mComponent,
+                                                false);
+                                        pir.addFilter(lastChosen);
+                                        changed = true;
                                     }
-                                    pir.removeFilter(pa);
-                                    // Re-add the filter as a "last chosen" entry (!always)
-                                    PreferredActivity lastChosen = new PreferredActivity(
-                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
-                                    pir.addFilter(lastChosen);
-                                    changed = true;
                                     return null;
                                 }
                             }