StrictMode to catch implicit Direct Boot matching.

When an app starts becoming Direct Boot aware, it can be difficult
to track down all the places they're implicitly relying on
PackageManager filtering behavior.

For example, if the current Launcher isn't Direct Boot aware, we
hide it until the user is unlocked, which could confuse other Direct
Boot aware apps into thinking it had been uninstalled, which could
cause data loss.

This change helps apps track down places where they're implicitly
relying on the automatic filtering; they should instead carefully
choose a combination of MATCH_DIRECT_BOOT flags to decide on the
explicit matching behavior they want.

To implement this, we partially migrate the updateFlags() methods
out into ApplicationPackageManager, since the checking needs to
happen on the client side to correctly report StrictMode
violations.  We don't currently mutate the flags, but we retain
the naming to keep that door open in the future.

Test: manual
Bug: 110413274
Change-Id: Iff6feba19da81ea1b4eeb3af821c3bdfbd9bf17c
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0e44833..344610a 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -73,6 +73,7 @@
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.StrictMode;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -149,15 +150,16 @@
     @Override
     public PackageInfo getPackageInfo(String packageName, int flags)
             throws NameNotFoundException {
-        return getPackageInfoAsUser(packageName, flags, mContext.getUserId());
+        return getPackageInfoAsUser(packageName, flags, getUserId());
     }
 
     @Override
     public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            PackageInfo pi = mPM.getPackageInfoVersioned(versionedPackage, flags,
-                    mContext.getUserId());
+            PackageInfo pi = mPM.getPackageInfoVersioned(versionedPackage,
+                    updateFlagsForPackage(flags, userId), userId);
             if (pi != null) {
                 return pi;
             }
@@ -171,7 +173,8 @@
     public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
             throws NameNotFoundException {
         try {
-            PackageInfo pi = mPM.getPackageInfo(packageName, flags, userId);
+            PackageInfo pi = mPM.getPackageInfo(packageName,
+                    updateFlagsForPackage(flags, userId), userId);
             if (pi != null) {
                 return pi;
             }
@@ -262,8 +265,10 @@
     @Override
     public int[] getPackageGids(String packageName, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            int[] gids = mPM.getPackageGids(packageName, flags, mContext.getUserId());
+            int[] gids = mPM.getPackageGids(packageName,
+                    updateFlagsForPackage(flags, userId), userId);
             if (gids != null) {
                 return gids;
             }
@@ -276,7 +281,7 @@
 
     @Override
     public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
-        return getPackageUidAsUser(packageName, flags, mContext.getUserId());
+        return getPackageUidAsUser(packageName, flags, getUserId());
     }
 
     @Override
@@ -288,7 +293,8 @@
     public int getPackageUidAsUser(String packageName, int flags, int userId)
             throws NameNotFoundException {
         try {
-            int uid = mPM.getPackageUid(packageName, flags, userId);
+            int uid = mPM.getPackageUid(packageName,
+                    updateFlagsForPackage(flags, userId), userId);
             if (uid >= 0) {
                 return uid;
             }
@@ -374,14 +380,15 @@
     @Override
     public ApplicationInfo getApplicationInfo(String packageName, int flags)
             throws NameNotFoundException {
-        return getApplicationInfoAsUser(packageName, flags, mContext.getUserId());
+        return getApplicationInfoAsUser(packageName, flags, getUserId());
     }
 
     @Override
     public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
             throws NameNotFoundException {
         try {
-            ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, userId);
+            ApplicationInfo ai = mPM.getApplicationInfo(packageName,
+                    updateFlagsForApplication(flags, userId), userId);
             if (ai != null) {
                 // This is a temporary hack. Callers must use
                 // createPackageContext(packageName).getApplicationInfo() to
@@ -423,8 +430,10 @@
     @Override
     public ActivityInfo getActivityInfo(ComponentName className, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId());
+            ActivityInfo ai = mPM.getActivityInfo(className,
+                    updateFlagsForComponent(flags, userId, null), userId);
             if (ai != null) {
                 return ai;
             }
@@ -438,8 +447,10 @@
     @Override
     public ActivityInfo getReceiverInfo(ComponentName className, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            ActivityInfo ai = mPM.getReceiverInfo(className, flags, mContext.getUserId());
+            ActivityInfo ai = mPM.getReceiverInfo(className,
+                    updateFlagsForComponent(flags, userId, null), userId);
             if (ai != null) {
                 return ai;
             }
@@ -453,8 +464,10 @@
     @Override
     public ServiceInfo getServiceInfo(ComponentName className, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            ServiceInfo si = mPM.getServiceInfo(className, flags, mContext.getUserId());
+            ServiceInfo si = mPM.getServiceInfo(className,
+                    updateFlagsForComponent(flags, userId, null), userId);
             if (si != null) {
                 return si;
             }
@@ -468,8 +481,10 @@
     @Override
     public ProviderInfo getProviderInfo(ComponentName className, int flags)
             throws NameNotFoundException {
+        final int userId = getUserId();
         try {
-            ProviderInfo pi = mPM.getProviderInfo(className, flags, mContext.getUserId());
+            ProviderInfo pi = mPM.getProviderInfo(className,
+                    updateFlagsForComponent(flags, userId, null), userId);
             if (pi != null) {
                 return pi;
             }
@@ -492,7 +507,7 @@
     /** @hide */
     @Override
     public @NonNull List<SharedLibraryInfo> getSharedLibraries(int flags) {
-        return getSharedLibrariesAsUser(flags, mContext.getUserId());
+        return getSharedLibrariesAsUser(flags, getUserId());
     }
 
     /** @hide */
@@ -535,7 +550,7 @@
     @Override
     public ChangedPackages getChangedPackages(int sequenceNumber) {
         try {
-            return mPM.getChangedPackages(sequenceNumber, mContext.getUserId());
+            return mPM.getChangedPackages(sequenceNumber, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -578,7 +593,7 @@
     @Override
     public int checkPermission(String permName, String pkgName) {
         try {
-            return mPM.checkPermission(permName, pkgName, mContext.getUserId());
+            return mPM.checkPermission(permName, pkgName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -587,7 +602,7 @@
     @Override
     public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
         try {
-            return mPM.isPermissionRevokedByPolicy(permName, pkgName, mContext.getUserId());
+            return mPM.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -681,7 +696,7 @@
     public boolean shouldShowRequestPermissionRationale(String permission) {
         try {
             return mPM.shouldShowRequestPermissionRationale(permission,
-                    mContext.getPackageName(), mContext.getUserId());
+                    mContext.getPackageName(), getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -769,7 +784,7 @@
     @SuppressWarnings("unchecked")
     @Override
     public List<PackageInfo> getInstalledPackages(int flags) {
-        return getInstalledPackagesAsUser(flags, mContext.getUserId());
+        return getInstalledPackagesAsUser(flags, getUserId());
     }
 
     /** @hide */
@@ -778,7 +793,7 @@
     public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
         try {
             ParceledListSlice<PackageInfo> parceledList =
-                    mPM.getInstalledPackages(flags, userId);
+                    mPM.getInstalledPackages(updateFlagsForPackage(flags, userId), userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -792,10 +807,11 @@
     @Override
     public List<PackageInfo> getPackagesHoldingPermissions(
             String[] permissions, int flags) {
-        final int userId = mContext.getUserId();
+        final int userId = getUserId();
         try {
             ParceledListSlice<PackageInfo> parceledList =
-                    mPM.getPackagesHoldingPermissions(permissions, flags, userId);
+                    mPM.getPackagesHoldingPermissions(permissions,
+                            updateFlagsForPackage(flags, userId), userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -808,7 +824,7 @@
     @SuppressWarnings("unchecked")
     @Override
     public List<ApplicationInfo> getInstalledApplications(int flags) {
-        return getInstalledApplicationsAsUser(flags, mContext.getUserId());
+        return getInstalledApplicationsAsUser(flags, getUserId());
     }
 
     /** @hide */
@@ -817,7 +833,7 @@
     public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
         try {
             ParceledListSlice<ApplicationInfo> parceledList =
-                    mPM.getInstalledApplications(flags, userId);
+                    mPM.getInstalledApplications(updateFlagsForApplication(flags, userId), userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -832,8 +848,7 @@
     @Override
     public List<InstantAppInfo> getInstantApps() {
         try {
-            ParceledListSlice<InstantAppInfo> slice =
-                    mPM.getInstantApps(mContext.getUserId());
+            ParceledListSlice<InstantAppInfo> slice = mPM.getInstantApps(getUserId());
             if (slice != null) {
                 return slice.getList();
             }
@@ -847,8 +862,7 @@
     @Override
     public Drawable getInstantAppIcon(String packageName) {
         try {
-            Bitmap bitmap = mPM.getInstantAppIcon(
-                    packageName, mContext.getUserId());
+            Bitmap bitmap = mPM.getInstantAppIcon(packageName, getUserId());
             if (bitmap != null) {
                 return new BitmapDrawable(null, bitmap);
             }
@@ -866,7 +880,7 @@
     @Override
     public boolean isInstantApp(String packageName) {
         try {
-            return mPM.isInstantApp(packageName, mContext.getUserId());
+            return mPM.isInstantApp(packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -886,8 +900,7 @@
     @Override
     public @NonNull byte[] getInstantAppCookie() {
         try {
-            final byte[] cookie = mPM.getInstantAppCookie(
-                    mContext.getPackageName(), mContext.getUserId());
+            final byte[] cookie = mPM.getInstantAppCookie(mContext.getPackageName(), getUserId());
             if (cookie != null) {
                 return cookie;
             } else {
@@ -910,8 +923,7 @@
                     + getInstantAppCookieMaxBytes());
         }
         try {
-            mPM.setInstantAppCookie(mContext.getPackageName(),
-                    cookie, mContext.getUserId());
+            mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -920,8 +932,7 @@
     @Override
     public boolean setInstantAppCookie(@NonNull byte[] cookie) {
         try {
-            return mPM.setInstantAppCookie(mContext.getPackageName(),
-                    cookie, mContext.getUserId());
+            return mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -929,7 +940,7 @@
 
     @Override
     public ResolveInfo resolveActivity(Intent intent, int flags) {
-        return resolveActivityAsUser(intent, flags, mContext.getUserId());
+        return resolveActivityAsUser(intent, flags, getUserId());
     }
 
     @Override
@@ -938,7 +949,7 @@
             return mPM.resolveIntent(
                 intent,
                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                flags,
+                updateFlagsForComponent(flags, userId, intent),
                 userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -948,7 +959,7 @@
     @Override
     public List<ResolveInfo> queryIntentActivities(Intent intent,
                                                    int flags) {
-        return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId());
+        return queryIntentActivitiesAsUser(intent, flags, getUserId());
     }
 
     /** @hide Same as above but for a specific user */
@@ -957,10 +968,11 @@
     public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
             int flags, int userId) {
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentActivities(intent,
-                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                            flags, userId);
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivities(
+                    intent,
+                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -972,9 +984,9 @@
 
     @Override
     @SuppressWarnings("unchecked")
-    public List<ResolveInfo> queryIntentActivityOptions(
-        ComponentName caller, Intent[] specifics, Intent intent,
-        int flags) {
+    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics,
+            Intent intent, int flags) {
+        final int userId = getUserId();
         final ContentResolver resolver = mContext.getContentResolver();
 
         String[] specificTypes = null;
@@ -995,9 +1007,14 @@
         }
 
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentActivityOptions(caller, specifics, specificTypes, intent,
-                    intent.resolveTypeIfNeeded(resolver), flags, mContext.getUserId());
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivityOptions(
+                    caller,
+                    specifics,
+                    specificTypes,
+                    intent,
+                    intent.resolveTypeIfNeeded(resolver),
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -1014,10 +1031,11 @@
     @SuppressWarnings("unchecked")
     public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentReceivers(intent,
-                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                            flags,  userId);
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentReceivers(
+                    intent,
+                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -1029,7 +1047,7 @@
 
     @Override
     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
-        return queryBroadcastReceiversAsUser(intent, flags, mContext.getUserId());
+        return queryBroadcastReceiversAsUser(intent, flags, getUserId());
     }
 
     @Override
@@ -1039,7 +1057,7 @@
             return mPM.resolveService(
                 intent,
                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                flags,
+                updateFlagsForComponent(flags, userId, intent),
                 userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1048,17 +1066,18 @@
 
     @Override
     public ResolveInfo resolveService(Intent intent, int flags) {
-        return resolveServiceAsUser(intent, flags, mContext.getUserId());
+        return resolveServiceAsUser(intent, flags, getUserId());
     }
 
     @Override
     @SuppressWarnings("unchecked")
     public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentServices(intent,
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentServices(
+                    intent,
                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                    flags, userId);
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -1070,7 +1089,7 @@
 
     @Override
     public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
-        return queryIntentServicesAsUser(intent, flags, mContext.getUserId());
+        return queryIntentServicesAsUser(intent, flags, getUserId());
     }
 
     @Override
@@ -1078,10 +1097,11 @@
     public List<ResolveInfo> queryIntentContentProvidersAsUser(
             Intent intent, int flags, int userId) {
         try {
-            ParceledListSlice<ResolveInfo> parceledList =
-                    mPM.queryIntentContentProviders(intent,
-                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                            flags, userId);
+            ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentContentProviders(
+                    intent,
+                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                    updateFlagsForComponent(flags, userId, intent),
+                    userId);
             if (parceledList == null) {
                 return Collections.emptyList();
             }
@@ -1093,19 +1113,20 @@
 
     @Override
     public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
-        return queryIntentContentProvidersAsUser(intent, flags, mContext.getUserId());
+        return queryIntentContentProvidersAsUser(intent, flags, getUserId());
     }
 
     @Override
     public ProviderInfo resolveContentProvider(String name, int flags) {
-        return resolveContentProviderAsUser(name, flags, mContext.getUserId());
+        return resolveContentProviderAsUser(name, flags, getUserId());
     }
 
     /** @hide **/
     @Override
     public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
         try {
-            return mPM.resolveContentProvider(name, flags, userId);
+            return mPM.resolveContentProvider(name,
+                    updateFlagsForComponent(flags, userId, null), userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1122,8 +1143,8 @@
     public List<ProviderInfo> queryContentProviders(String processName,
             int uid, int flags, String metaDataKey) {
         try {
-            ParceledListSlice<ProviderInfo> slice =
-                    mPM.queryContentProviders(processName, uid, flags, metaDataKey);
+            ParceledListSlice<ProviderInfo> slice = mPM.queryContentProviders(processName, uid,
+                    updateFlagsForComponent(flags, UserHandle.getUserId(uid), null), metaDataKey);
             return slice != null ? slice.getList() : Collections.<ProviderInfo>emptyList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1517,6 +1538,73 @@
         mPM = pm;
     }
 
+    /**
+     * Update given flags when being used to request {@link PackageInfo}.
+     */
+    private int updateFlagsForPackage(int flags, int userId) {
+        if ((flags & (GET_ACTIVITIES | GET_RECEIVERS | GET_SERVICES | GET_PROVIDERS)) != 0) {
+            // Caller is asking for component details, so they'd better be
+            // asking for specific Direct Boot matching behavior
+            if ((flags & (MATCH_DIRECT_BOOT_UNAWARE
+                    | MATCH_DIRECT_BOOT_AWARE
+                    | MATCH_DIRECT_BOOT_AUTO)) == 0) {
+                onImplicitDirectBoot(userId);
+            }
+        }
+        return flags;
+    }
+
+    /**
+     * Update given flags when being used to request {@link ApplicationInfo}.
+     */
+    private int updateFlagsForApplication(int flags, int userId) {
+        return updateFlagsForPackage(flags, userId);
+    }
+
+    /**
+     * Update given flags when being used to request {@link ComponentInfo}.
+     */
+    private int updateFlagsForComponent(int flags, int userId, Intent intent) {
+        if (intent != null) {
+            if ((intent.getFlags() & Intent.FLAG_DIRECT_BOOT_AUTO) != 0) {
+                flags |= MATCH_DIRECT_BOOT_AUTO;
+            }
+        }
+
+        // Caller is asking for component details, so they'd better be
+        // asking for specific Direct Boot matching behavior
+        if ((flags & (MATCH_DIRECT_BOOT_UNAWARE
+                | MATCH_DIRECT_BOOT_AWARE
+                | MATCH_DIRECT_BOOT_AUTO)) == 0) {
+            onImplicitDirectBoot(userId);
+        }
+        return flags;
+    }
+
+    private void onImplicitDirectBoot(int userId) {
+        // Only report if someone is relying on implicit behavior while the user
+        // is locked; code running when unlocked is going to see both aware and
+        // unaware components.
+        if (StrictMode.vmImplicitDirectBootEnabled()) {
+            // We can cache the unlocked state for the userId we're running as,
+            // since any relocking of that user will always result in our
+            // process being killed to release any CE FDs we're holding onto.
+            if (userId == UserHandle.myUserId()) {
+                if (mUserUnlocked) {
+                    return;
+                } else if (mContext.getSystemService(UserManager.class)
+                        .isUserUnlockingOrUnlocked(userId)) {
+                    mUserUnlocked = true;
+                } else {
+                    StrictMode.onImplicitDirectBoot();
+                }
+            } else if (!mContext.getSystemService(UserManager.class)
+                    .isUserUnlockingOrUnlocked(userId)) {
+                StrictMode.onImplicitDirectBoot();
+            }
+        }
+    }
+
     @Nullable
     private Drawable getCachedIcon(@NonNull ResourceName name) {
         synchronized (sSync) {
@@ -1730,7 +1818,7 @@
     @Override
     public int installExistingPackage(String packageName, int installReason)
             throws NameNotFoundException {
-        return installExistingPackageAsUser(packageName, installReason, mContext.getUserId());
+        return installExistingPackageAsUser(packageName, installReason, getUserId());
     }
 
     @Override
@@ -2089,7 +2177,7 @@
 
     @Override
     public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
-        deletePackageAsUser(packageName, observer, flags, mContext.getUserId());
+        deletePackageAsUser(packageName, observer, flags, getUserId());
     }
 
     @Override
@@ -2107,7 +2195,7 @@
     public void clearApplicationUserData(String packageName,
                                          IPackageDataObserver observer) {
         try {
-            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
+            mPM.clearApplicationUserData(packageName, observer, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2158,7 +2246,7 @@
         try {
             return mPM.setPackagesSuspendedAsUser(packageNames, suspended, appExtras,
                     launcherExtras, dialogMessage, mContext.getOpPackageName(),
-                    mContext.getUserId());
+                    getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2169,7 +2257,7 @@
         final PersistableBundle extras;
         try {
             extras = mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(),
-                    mContext.getUserId());
+                    getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2189,7 +2277,7 @@
     @Override
     public boolean isPackageSuspended(String packageName) throws NameNotFoundException {
         try {
-            return isPackageSuspendedForUser(packageName, mContext.getUserId());
+            return isPackageSuspendedForUser(packageName, getUserId());
         } catch (IllegalArgumentException ie) {
             throw new NameNotFoundException(packageName);
         }
@@ -2197,7 +2285,7 @@
 
     @Override
     public boolean isPackageSuspended() {
-        return isPackageSuspendedForUser(mContext.getOpPackageName(), mContext.getUserId());
+        return isPackageSuspendedForUser(mContext.getOpPackageName(), getUserId());
     }
 
     /** @hide */
@@ -2247,7 +2335,7 @@
     public void addPreferredActivity(IntentFilter filter,
                                      int match, ComponentName[] set, ComponentName activity) {
         try {
-            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
+            mPM.addPreferredActivity(filter, match, set, activity, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2267,7 +2355,7 @@
     public void replacePreferredActivity(IntentFilter filter,
                                          int match, ComponentName[] set, ComponentName activity) {
         try {
-            mPM.replacePreferredActivity(filter, match, set, activity, mContext.getUserId());
+            mPM.replacePreferredActivity(filter, match, set, activity, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2316,7 +2404,7 @@
     public void setComponentEnabledSetting(ComponentName componentName,
                                            int newState, int flags) {
         try {
-            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
+            mPM.setComponentEnabledSetting(componentName, newState, flags, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2325,7 +2413,7 @@
     @Override
     public int getComponentEnabledSetting(ComponentName componentName) {
         try {
-            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
+            return mPM.getComponentEnabledSetting(componentName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2336,7 +2424,7 @@
                                              int newState, int flags) {
         try {
             mPM.setApplicationEnabledSetting(packageName, newState, flags,
-                    mContext.getUserId(), mContext.getOpPackageName());
+                    getUserId(), mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2345,7 +2433,7 @@
     @Override
     public int getApplicationEnabledSetting(String packageName) {
         try {
-            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
+            return mPM.getApplicationEnabledSetting(packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2457,7 +2545,7 @@
             if (mInstaller == null) {
                 try {
                     mInstaller = new PackageInstaller(mPM.getPackageInstaller(),
-                            mContext.getPackageName(), mContext.getUserId());
+                            mContext.getPackageName(), getUserId());
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
                 }
@@ -2469,7 +2557,7 @@
     @Override
     public boolean isPackageAvailable(String packageName) {
         try {
-            return mPM.isPackageAvailable(packageName, mContext.getUserId());
+            return mPM.isPackageAvailable(packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2509,7 +2597,7 @@
         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
             return dr;
         }
-        return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
+        return getUserBadgedIcon(dr, new UserHandle(getUserId()));
     }
 
     /**
@@ -2657,6 +2745,9 @@
     private final ContextImpl mContext;
     private final IPackageManager mPM;
 
+    /** Assume locked until we hear otherwise */
+    private volatile boolean mUserUnlocked = false;
+
     private static final Object sSync = new Object();
     private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
             = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
@@ -2701,7 +2792,7 @@
     @Override
     public boolean canRequestPackageInstalls() {
         try {
-            return mPM.canRequestPackageInstalls(mContext.getPackageName(), mContext.getUserId());
+            return mPM.canRequestPackageInstalls(mContext.getPackageName(), getUserId());
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -2811,7 +2902,7 @@
     @Override
     public CharSequence getHarmfulAppWarning(String packageName) {
         try {
-            return mPM.getHarmfulAppWarning(packageName, mContext.getUserId());
+            return mPM.getHarmfulAppWarning(packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -2820,7 +2911,7 @@
     @Override
     public void setHarmfulAppWarning(String packageName, CharSequence warning) {
         try {
-            mPM.setHarmfulAppWarning(packageName, warning, mContext.getUserId());
+            mPM.setHarmfulAppWarning(packageName, warning, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }