diff options
| -rw-r--r-- | api/current.txt | 6 | ||||
| -rw-r--r-- | api/test-current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/app/ApplicationPackageManager.java | 265 | ||||
| -rw-r--r-- | core/java/android/content/Intent.java | 28 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 35 | ||||
| -rw-r--r-- | core/java/android/os/StrictMode.java | 45 | ||||
| -rw-r--r-- | core/java/android/os/strictmode/ImplicitDirectBootViolation.java | 37 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 40 |
8 files changed, 304 insertions, 153 deletions
diff --git a/api/current.txt b/api/current.txt index 41211f6c9bba..f30bc69ccddc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -10137,6 +10137,7 @@ package android.content { field public static final int FLAG_ACTIVITY_SINGLE_TOP = 536870912; // 0x20000000 field public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; // 0x4000 field public static final int FLAG_DEBUG_LOG_RESOLUTION = 8; // 0x8 + field public static final int FLAG_DIRECT_BOOT_AUTO = 256; // 0x100 field public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 16; // 0x10 field public static final int FLAG_FROM_BACKGROUND = 4; // 0x4 field public static final int FLAG_GRANT_PERSISTABLE_URI_PERMISSION = 64; // 0x40 @@ -11388,6 +11389,7 @@ package android.content.pm { field public static final int INSTALL_REASON_USER = 4; // 0x4 field public static final int MATCH_ALL = 131072; // 0x20000 field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000 + field public static final int MATCH_DIRECT_BOOT_AUTO = 268435456; // 0x10000000 field public static final int MATCH_DIRECT_BOOT_AWARE = 524288; // 0x80000 field public static final int MATCH_DIRECT_BOOT_UNAWARE = 262144; // 0x40000 field public static final int MATCH_DISABLED_COMPONENTS = 512; // 0x200 @@ -33207,6 +33209,7 @@ package android.os { method public android.os.StrictMode.VmPolicy.Builder detectCleartextNetwork(); method public android.os.StrictMode.VmPolicy.Builder detectContentUriWithoutPermission(); method public android.os.StrictMode.VmPolicy.Builder detectFileUriExposure(); + method public android.os.StrictMode.VmPolicy.Builder detectImplicitDirectBoot(); method public android.os.StrictMode.VmPolicy.Builder detectLeakedClosableObjects(); method public android.os.StrictMode.VmPolicy.Builder detectLeakedRegistrationObjects(); method public android.os.StrictMode.VmPolicy.Builder detectLeakedSqlLiteObjects(); @@ -33620,6 +33623,9 @@ package android.os.strictmode { public final class FileUriExposedViolation extends android.os.strictmode.Violation { } + public final class ImplicitDirectBootViolation extends android.os.strictmode.Violation { + } + public class InstanceCountViolation extends android.os.strictmode.Violation { method public long getNumberOfInstances(); } diff --git a/api/test-current.txt b/api/test-current.txt index 1e76d4a321ea..5d1f3e24aa45 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -695,6 +695,7 @@ package android.os { field public static final int DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION = 32768; // 0x8000 field public static final int DETECT_VM_CURSOR_LEAKS = 256; // 0x100 field public static final int DETECT_VM_FILE_URI_EXPOSURE = 8192; // 0x2000 + field public static final int DETECT_VM_IMPLICIT_DIRECT_BOOT = 536870912; // 0x20000000 field public static final int DETECT_VM_INSTANCE_LEAKS = 2048; // 0x800 field public static final int DETECT_VM_NON_SDK_API_USAGE = 1073741824; // 0x40000000 field public static final int DETECT_VM_REGISTRATION_LEAKS = 4096; // 0x1000 diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 0e4483312fd2..344610a5375f 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -73,6 +73,7 @@ import android.os.Message; 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 @@ public class ApplicationPackageManager extends PackageManager { @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 class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { /** @hide */ @Override public @NonNull List<SharedLibraryInfo> getSharedLibraries(int flags) { - return getSharedLibrariesAsUser(flags, mContext.getUserId()); + return getSharedLibrariesAsUser(flags, getUserId()); } /** @hide */ @@ -535,7 +550,7 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @SuppressWarnings("unchecked") @Override public List<PackageInfo> getInstalledPackages(int flags) { - return getInstalledPackagesAsUser(flags, mContext.getUserId()); + return getInstalledPackagesAsUser(flags, getUserId()); } /** @hide */ @@ -778,7 +793,7 @@ public class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @SuppressWarnings("unchecked") @Override public List<ApplicationInfo> getInstalledApplications(int flags) { - return getInstalledApplicationsAsUser(flags, mContext.getUserId()); + return getInstalledApplicationsAsUser(flags, getUserId()); } /** @hide */ @@ -817,7 +833,7 @@ public class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { + 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @Override public ResolveInfo resolveActivity(Intent intent, int flags) { - return resolveActivityAsUser(intent, flags, mContext.getUserId()); + return resolveActivityAsUser(intent, flags, getUserId()); } @Override @@ -938,7 +949,7 @@ public class ApplicationPackageManager extends PackageManager { return mPM.resolveIntent( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), - flags, + updateFlagsForComponent(flags, userId, intent), userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -948,7 +959,7 @@ public class ApplicationPackageManager extends PackageManager { @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 class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { } 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { return mPM.resolveService( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), - flags, + updateFlagsForComponent(flags, userId, intent), userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1048,17 +1066,18 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { try { return mPM.setPackagesSuspendedAsUser(packageNames, suspended, appExtras, launcherExtras, dialogMessage, mContext.getOpPackageName(), - mContext.getUserId()); + getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2169,7 +2257,7 @@ public class ApplicationPackageManager extends PackageManager { final PersistableBundle extras; try { extras = mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(), - mContext.getUserId()); + getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2189,7 +2277,7 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @Override public boolean isPackageSuspended() { - return isPackageSuspendedForUser(mContext.getOpPackageName(), mContext.getUserId()); + return isPackageSuspendedForUser(mContext.getOpPackageName(), getUserId()); } /** @hide */ @@ -2247,7 +2335,7 @@ public class ApplicationPackageManager extends PackageManager { 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 class ApplicationPackageManager extends PackageManager { 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 class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { 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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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 @@ public class ApplicationPackageManager extends PackageManager { @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(); } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 631c4b7d1912..78738e9c3b06 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -5372,19 +5372,23 @@ public class Intent implements Parcelable, Cloneable { public static final int FLAG_GRANT_PREFIX_URI_PERMISSION = 0x00000080; /** - * Internal flag used to indicate that a system component has done their - * homework and verified that they correctly handle packages and components - * that come and go over time. In particular: - * <ul> - * <li>Apps installed on external storage, which will appear to be - * uninstalled while the the device is ejected. - * <li>Apps with encryption unaware components, which will appear to not - * exist while the device is locked. - * </ul> - * - * @hide + * Flag used to automatically match intents based on their Direct Boot + * awareness and the current user state. + * <p> + * Since the default behavior is to automatically apply the current user + * state, this is effectively a sentinel value that doesn't change the + * output of any queries based on its presence or absence. + * <p> + * Instead, this value can be useful in conjunction with + * {@link android.os.StrictMode.VmPolicy.Builder#detectImplicitDirectBoot()} + * to detect when a caller is relying on implicit automatic matching, + * instead of confirming the explicit behavior they want. */ - public static final int FLAG_DEBUG_TRIAGED_MISSING = 0x00000100; + public static final int FLAG_DIRECT_BOOT_AUTO = 0x00000100; + + /** {@hide} */ + @Deprecated + public static final int FLAG_DEBUG_TRIAGED_MISSING = FLAG_DIRECT_BOOT_AUTO; /** * Internal flag used to indicate ephemeral applications should not be diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 63eced73d66a..721063a8f7d5 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -179,6 +179,7 @@ public abstract class PackageManager { MATCH_DEFAULT_ONLY, MATCH_DISABLED_COMPONENTS, MATCH_DISABLED_UNTIL_USED_COMPONENTS, + MATCH_DIRECT_BOOT_AUTO, MATCH_DIRECT_BOOT_AWARE, MATCH_DIRECT_BOOT_UNAWARE, MATCH_SYSTEM_ONLY, @@ -202,6 +203,7 @@ public abstract class PackageManager { MATCH_DISABLED_COMPONENTS, MATCH_DISABLED_UNTIL_USED_COMPONENTS, MATCH_DEFAULT_ONLY, + MATCH_DIRECT_BOOT_AUTO, MATCH_DIRECT_BOOT_AWARE, MATCH_DIRECT_BOOT_UNAWARE, MATCH_SYSTEM_ONLY, @@ -506,22 +508,29 @@ public abstract class PackageManager { public static final int GET_SIGNING_CERTIFICATES = 0x08000000; /** - * Internal flag used to indicate that a system component has done their - * homework and verified that they correctly handle packages and components - * that come and go over time. In particular: + * Querying flag: automatically match components based on their Direct Boot + * awareness and the current user state. + * <p> + * Since the default behavior is to automatically apply the current user + * state, this is effectively a sentinel value that doesn't change the + * output of any queries based on its presence or absence. + * <p> + * Instead, this value can be useful in conjunction with + * {@link android.os.StrictMode.VmPolicy.Builder#detectImplicitDirectBoot()} + * to detect when a caller is relying on implicit automatic matching, + * instead of confirming the explicit behavior they want, using a + * combination of these flags: * <ul> - * <li>Apps installed on external storage, which will appear to be - * uninstalled while the the device is ejected. - * <li>Apps with encryption unaware components, which will appear to not - * exist while the device is locked. + * <li>{@link #MATCH_DIRECT_BOOT_AWARE} + * <li>{@link #MATCH_DIRECT_BOOT_UNAWARE} + * <li>{@link #MATCH_DIRECT_BOOT_AUTO} * </ul> - * - * @see #MATCH_UNINSTALLED_PACKAGES - * @see #MATCH_DIRECT_BOOT_AWARE - * @see #MATCH_DIRECT_BOOT_UNAWARE - * @hide */ - public static final int MATCH_DEBUG_TRIAGED_MISSING = 0x10000000; + public static final int MATCH_DIRECT_BOOT_AUTO = 0x10000000; + + /** @hide */ + @Deprecated + public static final int MATCH_DEBUG_TRIAGED_MISSING = MATCH_DIRECT_BOOT_AUTO; /** * Internal flag used to indicate that a package is a hidden system app. diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index f22455047ae5..3ce7150b3507 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.net.TrafficStats; import android.net.Uri; import android.os.strictmode.CleartextNetworkViolation; @@ -36,6 +37,7 @@ import android.os.strictmode.DiskReadViolation; import android.os.strictmode.DiskWriteViolation; import android.os.strictmode.ExplicitGcViolation; import android.os.strictmode.FileUriExposedViolation; +import android.os.strictmode.ImplicitDirectBootViolation; import android.os.strictmode.InstanceCountViolation; import android.os.strictmode.IntentReceiverLeakedViolation; import android.os.strictmode.LeakedClosableViolation; @@ -272,6 +274,9 @@ public final class StrictMode { /** @hide */ @TestApi public static final int DETECT_VM_NON_SDK_API_USAGE = 0x40 << 24; // for VmPolicy + /** @hide */ + @TestApi public static final int DETECT_VM_IMPLICIT_DIRECT_BOOT = 0x20 << 24; // for VmPolicy + private static final int ALL_VM_DETECT_BITS = DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS @@ -282,7 +287,8 @@ public final class StrictMode { | DETECT_VM_CLEARTEXT_NETWORK | DETECT_VM_CONTENT_URI_WITHOUT_PERMISSION | DETECT_VM_UNTAGGED_SOCKET - | DETECT_VM_NON_SDK_API_USAGE; + | DETECT_VM_NON_SDK_API_USAGE + | DETECT_VM_IMPLICIT_DIRECT_BOOT; // Byte 3: Penalty @@ -891,6 +897,8 @@ public final class StrictMode { } // TODO: Decide whether to detect non SDK API usage beyond a certain API level. + // TODO: enable detectImplicitDirectBoot() once system is less noisy + return this; } @@ -999,6 +1007,29 @@ public final class StrictMode { } /** + * Detect any implicit reliance on Direct Boot automatic filtering + * of {@link PackageManager} values. Violations are only triggered + * when implicit calls are made while the user is locked. + * <p> + * Apps becoming Direct Boot aware need to carefully inspect each + * query site and explicitly decide which combination of flags they + * want to use: + * <ul> + * <li>{@link PackageManager#MATCH_DIRECT_BOOT_AWARE} + * <li>{@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE} + * <li>{@link PackageManager#MATCH_DIRECT_BOOT_AUTO} + * </ul> + */ + public Builder detectImplicitDirectBoot() { + return enable(DETECT_VM_IMPLICIT_DIRECT_BOOT); + } + + /** @hide */ + public Builder permitImplicitDirectBoot() { + return disable(DETECT_VM_IMPLICIT_DIRECT_BOOT); + } + + /** * Crashes the whole process on violation. This penalty runs at the end of all enabled * penalties so you'll still get your logging or other violations before the process * dies. @@ -1991,6 +2022,11 @@ public final class StrictMode { } /** @hide */ + public static boolean vmImplicitDirectBootEnabled() { + return (sVmPolicy.mask & DETECT_VM_IMPLICIT_DIRECT_BOOT) != 0; + } + + /** @hide */ public static void onSqliteObjectLeaked(String message, Throwable originStack) { onVmPolicyViolation(new SqliteObjectLeakedViolation(message, originStack)); } @@ -2062,6 +2098,11 @@ public final class StrictMode { onVmPolicyViolation(new UntaggedSocketViolation()); } + /** @hide */ + public static void onImplicitDirectBoot() { + onVmPolicyViolation(new ImplicitDirectBootViolation()); + } + // Map from VM violation fingerprint to uptime millis. private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<>(); @@ -2665,6 +2706,8 @@ public final class StrictMode { return DETECT_EXPLICIT_GC; } else if (mViolation instanceof NonSdkApiUsedViolation) { return DETECT_VM_NON_SDK_API_USAGE; + } else if (mViolation instanceof ImplicitDirectBootViolation) { + return DETECT_VM_IMPLICIT_DIRECT_BOOT; } throw new IllegalStateException("missing violation bit"); } diff --git a/core/java/android/os/strictmode/ImplicitDirectBootViolation.java b/core/java/android/os/strictmode/ImplicitDirectBootViolation.java new file mode 100644 index 000000000000..d7877cabfab1 --- /dev/null +++ b/core/java/android/os/strictmode/ImplicitDirectBootViolation.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.strictmode; + +import android.content.pm.PackageManager; + +/** + * Subclass of {@code Violation} that is used when a process implicitly relies + * on automatic Direct Boot filtering. + * + * @see PackageManager#MATCH_DIRECT_BOOT_AUTO + */ +public final class ImplicitDirectBootViolation extends Violation { + /** @hide */ + public static final String MESSAGE = + "Implicitly relying on automatic Direct Boot filtering; request explicit" + + " filtering with PackageManager.MATCH_DIRECT_BOOT flags"; + + /** @hide */ + public ImplicitDirectBootViolation() { + super(MESSAGE); + } +} diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 42b02737de61..c536e4dbea59 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -430,7 +430,6 @@ public class PackageManagerService extends IPackageManager.Stub private static final boolean DEBUG_ABI_SELECTION = false; private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE; - private static final boolean DEBUG_TRIAGED_MISSING = false; private static final boolean DEBUG_APP_DATA = false; /** REMOVE. According to Svet, this was only used to reset permissions during development. */ @@ -4750,22 +4749,6 @@ public class PackageManagerService extends IPackageManager.Stub */ private int updateFlagsForPackage(int flags, int userId, Object cookie) { final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM; - boolean triaged = true; - 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_DIRECT_BOOT_UNAWARE - | PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { - triaged = false; - } - } - if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES - | PackageManager.MATCH_SYSTEM_ONLY - | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { - triaged = false; - } if ((flags & PackageManager.MATCH_ANY_USER) != 0) { // require the permission to be held; the calling uid and given user id referring // to the same user is not sufficient @@ -4782,10 +4765,6 @@ public class PackageManagerService extends IPackageManager.Stub // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380 flags |= PackageManager.MATCH_ANY_USER; } - 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 - + " with flags 0x" + Integer.toHexString(flags), new Throwable()); - } return updateFlags(flags, userId); } @@ -4800,25 +4779,6 @@ public class PackageManagerService extends IPackageManager.Stub * 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 - if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE - | PackageManager.MATCH_DIRECT_BOOT_AWARE - | 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 - + " with flags 0x" + Integer.toHexString(flags), new Throwable()); - } - return updateFlags(flags, userId); } |