More progress on triaging PackageManager callers.

Catch a bunch of simple cases where the PackageManager flags are
obvious.  Add the ability to use the MATCH_SYSTEM_ONLY flag on
PackageInfo and ApplicationInfo queries.

Re-examine recent tasks after a user is unlocked, since some of the
activities may now be available and runnable.

Bug: 26471205, 26253870
Change-Id: I989d9f8409070e5cae13202b47e2c7de85bf4a5b
diff --git a/services/core/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java
index 4569dae..b5ea641 100644
--- a/services/core/java/com/android/server/AssetAtlasService.java
+++ b/services/core/java/com/android/server/AssetAtlasService.java
@@ -176,7 +176,8 @@
     private static String queryVersionName(Context context) {
         try {
             String packageName = context.getPackageName();
-            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
+            PackageInfo info = context.getPackageManager().getPackageInfo(packageName,
+                    PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
             return info.versionName;
         } catch (PackageManager.NameNotFoundException e) {
             Log.w(LOG_TAG, "Could not get package info", e);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 3c91423..c1a082b 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -269,7 +269,7 @@
         int sysUiUid = -1;
         try {
             sysUiUid = mContext.getPackageManager().getPackageUidAsUser("com.android.systemui",
-                    UserHandle.USER_SYSTEM);
+                    PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
         } catch (PackageManager.NameNotFoundException e) {
             // Some platforms, such as wearables do not have a system ui.
             Log.w(TAG, "Unable to resolve SystemUI's UID.", e);
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 8d707d6..bd95892 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -1052,12 +1052,11 @@
             for (int i=0; i<allowPowerExceptIdle.size(); i++) {
                 String pkg = allowPowerExceptIdle.valueAt(i);
                 try {
-                    ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
-                    if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
-                        int appid = UserHandle.getAppId(ai.uid);
-                        mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
-                        mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
-                    }
+                    ApplicationInfo ai = pm.getApplicationInfo(pkg,
+                            PackageManager.MATCH_SYSTEM_ONLY);
+                    int appid = UserHandle.getAppId(ai.uid);
+                    mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
+                    mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
                 } catch (PackageManager.NameNotFoundException e) {
                 }
             }
@@ -1065,16 +1064,15 @@
             for (int i=0; i<allowPower.size(); i++) {
                 String pkg = allowPower.valueAt(i);
                 try {
-                    ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
-                    if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
-                        int appid = UserHandle.getAppId(ai.uid);
-                        // These apps are on both the whitelist-except-idle as well
-                        // as the full whitelist, so they apply in all cases.
-                        mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
-                        mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
-                        mPowerSaveWhitelistApps.put(ai.packageName, appid);
-                        mPowerSaveWhitelistSystemAppIds.put(appid, true);
-                    }
+                    ApplicationInfo ai = pm.getApplicationInfo(pkg,
+                            PackageManager.MATCH_SYSTEM_ONLY);
+                    int appid = UserHandle.getAppId(ai.uid);
+                    // These apps are on both the whitelist-except-idle as well
+                    // as the full whitelist, so they apply in all cases.
+                    mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
+                    mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
+                    mPowerSaveWhitelistApps.put(ai.packageName, appid);
+                    mPowerSaveWhitelistSystemAppIds.put(appid, true);
                 } catch (PackageManager.NameNotFoundException e) {
                 }
             }
@@ -1182,9 +1180,7 @@
         synchronized (this) {
             try {
                 ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
-                        PackageManager.GET_UNINSTALLED_PACKAGES
-                                | PackageManager.GET_DISABLED_COMPONENTS
-                                | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
+                        PackageManager.MATCH_UNINSTALLED_PACKAGES);
                 if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
                     reportPowerSaveWhitelistChangedLocked();
                     updateWhitelistAppIdsLocked();
@@ -2010,9 +2006,7 @@
                     if (name != null) {
                         try {
                             ApplicationInfo ai = pm.getApplicationInfo(name,
-                                    PackageManager.GET_UNINSTALLED_PACKAGES
-                                            | PackageManager.GET_DISABLED_COMPONENTS
-                                            | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
+                                    PackageManager.MATCH_UNINSTALLED_PACKAGES);
                             mPowerSaveWhitelistUserApps.put(ai.packageName,
                                     UserHandle.getAppId(ai.uid));
                         } catch (PackageManager.NameNotFoundException e) {
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index 1249c8c..a291cc7 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -94,7 +94,8 @@
         PackageManager pm = mContext.getPackageManager();
         int allowedUid = -1;
         try {
-            allowedUid = pm.getPackageUidAsUser(allowedPackage, userHandle);
+            allowedUid = pm.getPackageUidAsUser(allowedPackage,
+                    PackageManager.MATCH_SYSTEM_ONLY, userHandle);
         } catch (PackageManager.NameNotFoundException e) {
             // not expected
             Slog.e(TAG, "not able to find package " + allowedPackage, e);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 9dda321..d12eadb 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1211,10 +1211,11 @@
         }
         if (r == null) {
             try {
-                ResolveInfo rInfo =
-                    AppGlobals.getPackageManager().resolveService(
-                                service, resolvedType,
-                                ActivityManagerService.STOCK_PM_FLAGS, userId);
+                // TODO: come back and remove this assumption to triage all services
+                ResolveInfo rInfo = AppGlobals.getPackageManager().resolveService(service,
+                        resolvedType, ActivityManagerService.STOCK_PM_FLAGS
+                                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
+                        userId);
                 ServiceInfo sInfo =
                     rInfo != null ? rInfo.serviceInfo : null;
                 if (sInfo == null) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f6f9f9d..b523700 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -255,6 +255,8 @@
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
 import static android.provider.Settings.Global.DEBUG_APP;
@@ -1952,6 +1954,7 @@
             }
             case SYSTEM_USER_UNLOCK_MSG: {
                 mSystemServiceManager.unlockUser(msg.arg1);
+                mRecentTasks.cleanupLocked(msg.arg1);
                 break;
             }
             case SYSTEM_USER_CURRENT_MSG: {
@@ -2290,7 +2293,7 @@
             ServiceManager.addService("processinfo", new ProcessInfoService(this));
 
             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
-                    "android", STOCK_PM_FLAGS);
+                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
 
             synchronized (this) {
@@ -3444,7 +3447,8 @@
                 try {
                     checkTime(startTime, "startProcess: getting gids from package manager");
                     final IPackageManager pm = AppGlobals.getPackageManager();
-                    permGids = pm.getPackageGids(app.info.packageName, app.userId);
+                    permGids = pm.getPackageGidsEtc(app.info.packageName,
+                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
                     MountServiceInternal mountServiceInternal = LocalServices.getService(
                             MountServiceInternal.class);
                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
@@ -9854,7 +9858,7 @@
             ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
                     .queryContentProviders(app.processName, app.uid,
                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
-                                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
+                                    | MATCH_DEBUG_TRIAGED_MISSING);
             providers = slice != null ? slice.getList() : null;
         } catch (RemoteException ex) {
         }
@@ -17079,7 +17083,7 @@
     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
             int callingUid, int[] users) {
         // TODO: come back and remove this assumption to triage all broadcasts
-        int pmFlags = STOCK_PM_FLAGS | PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
 
         List<ResolveInfo> receivers = null;
         try {
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index c63eaac..52d23cf 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -130,9 +130,11 @@
                     ActivityInfo ai = tmpAvailActCache.get(task.realActivity);
                     if (ai == null) {
                         try {
+                            // At this first cut, we're only interested in
+                            // activities that are fully runnable based on
+                            // current system state.
                             ai = pm.getActivityInfo(task.realActivity,
-                                    PackageManager.GET_UNINSTALLED_PACKAGES
-                                            | PackageManager.GET_DISABLED_COMPONENTS, user);
+                                    PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user);
                         } catch (RemoteException e) {
                             // Will never happen.
                             continue;
@@ -150,8 +152,7 @@
                         if (app == null) {
                             try {
                                 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
-                                        PackageManager.GET_UNINSTALLED_PACKAGES
-                                                | PackageManager.GET_DISABLED_COMPONENTS, user);
+                                        PackageManager.MATCH_UNINSTALLED_PACKAGES, user);
                             } catch (RemoteException e) {
                                 // Will never happen.
                                 continue;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 5aaa930..4325efd 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -2333,7 +2333,8 @@
         @Override
         public void onAppIdleStateChanged(String packageName, int userId, boolean idle) {
             try {
-                int uid = mContext.getPackageManager().getPackageUidAsUser(packageName, userId);
+                final int uid = mContext.getPackageManager().getPackageUidAsUser(packageName,
+                        PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
                 synchronized (mRulesLock) {
                     updateRuleForAppIdleLocked(uid);
                 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9e0f3ce..00e45a5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2848,12 +2848,12 @@
         // reader
         synchronized (mPackages) {
             final PackageParser.Package p = mPackages.get(packageName);
-            if (p != null) {
+            if (p != null && p.isMatch(flags)) {
                 return UserHandle.getUid(userId, p.applicationInfo.uid);
             }
             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
                 final PackageSetting ps = mSettings.mPackages.get(packageName);
-                if (ps != null) {
+                if (ps != null && ps.isMatch(flags)) {
                     return UserHandle.getUid(userId, ps.appId);
                 }
             }
@@ -2877,13 +2877,13 @@
         // reader
         synchronized (mPackages) {
             final PackageParser.Package p = mPackages.get(packageName);
-            if (p != null) {
+            if (p != null && p.isMatch(flags)) {
                 PackageSetting ps = (PackageSetting) p.mExtras;
                 return ps.getPermissionsState().computeGids(userId);
             }
             if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
                 final PackageSetting ps = mSettings.mPackages.get(packageName);
-                if (ps != null) {
+                if (ps != null && ps.isMatch(flags)) {
                     return ps.getPermissionsState().computeGids(userId);
                 }
             }
@@ -3149,8 +3149,8 @@
      */
     private int updateFlagsForPackage(int flags, int userId, Object cookie) {
         boolean triaged = true;
-        if ((flags & PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
-                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS) != 0) {
+        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
+                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
             // Caller is asking for component details, so they'd better be
             // asking for specific encryption matching behavior, or be triaged
             if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE
@@ -3160,12 +3160,13 @@
             }
         }
         if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
+                | PackageManager.MATCH_SYSTEM_ONLY
                 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
             triaged = false;
         }
         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
-            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie,
-                    new Throwable());
+            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
+                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
         }
         return updateFlagsForEncryption(flags, userId);
     }
@@ -3181,6 +3182,12 @@
      * Update given flags when being used to request {@link ComponentInfo}.
      */
     private int updateFlagsForComponent(int flags, int userId, Object cookie) {
+        if (cookie instanceof Intent) {
+            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
+                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+            }
+        }
+
         boolean triaged = true;
         // Caller is asking for component details, so they'd better be
         // asking for specific encryption matching behavior, or be triaged
@@ -3190,8 +3197,8 @@
             triaged = false;
         }
         if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
-            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie,
-                    new Throwable());
+            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
+                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
         }
         return updateFlagsForEncryption(flags, userId);
     }
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index e7c0ef7..f106b62 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -17,6 +17,7 @@
 package com.android.server.pm;
 
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
 
 import java.io.File;
@@ -78,4 +79,11 @@
     public boolean isSharedUser() {
         return sharedUser != null;
     }
+
+    public boolean isMatch(int flags) {
+        if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
+            return isSystem();
+        }
+        return true;
+    }
 }