Merge "StrictMode to catch implicit Direct Boot matching."
diff --git a/api/current.txt b/api/current.txt
index 41211f6..f30bc69 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10137,6 +10137,7 @@
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 @@
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 @@
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 @@
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 1e76d4a..5d1f3e2 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -695,6 +695,7 @@
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 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();
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 631c4b7..78738e9 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5372,19 +5372,23 @@
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 63eced7..721063a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -179,6 +179,7 @@
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 @@
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 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 f224550..3ce7150 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -27,6 +27,7 @@
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.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 @@
/** @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 @@
| 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 @@
}
// 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 @@
}
/**
+ * 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 @@
}
/** @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 @@
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 @@
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 0000000..d7877ca
--- /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 42b0273..c536e4d 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 @@
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 @@
*/
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 @@
// 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 @@
* 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);
}