import android.content.ComponentName;
import android.content.Intent;
+import android.content.pm.PackageManager.ApplicationInfoFlags;
+import android.content.pm.PackageManager.ComponentInfoFlags;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageManager.PackageInfoFlags;
+import android.content.pm.PackageManager.ResolveInfoFlags;
import android.os.Bundle;
import android.util.SparseArray;
public abstract boolean isPermissionsReviewRequired(String packageName, int userId);
/**
- * Gets all of the information we know about a particular package.
- *
- * @param packageName The package name to find.
- * @param userId The user under which to check.
- *
- * @return An {@link ApplicationInfo} containing information about the
- * package, or {@code null} if no application exists with that
- * package name.
+ * Retrieve all of the information we know about a particular package/application.
+ * @param filterCallingUid The results will be filtered in the context of this UID instead
+ * of the calling UID.
+ * @see PackageManager#getPackageInfo(String, int)
+ */
+ public abstract PackageInfo getPackageInfo(String packageName,
+ @PackageInfoFlags int flags, int filterCallingUid, int userId);
+
+ /**
+ * Retrieve all of the information we know about a particular package/application.
+ * @param filterCallingUid The results will be filtered in the context of this UID instead
+ * of the calling UID.
+ * @see PackageManager#getApplicationInfo(String, int)
+ */
+ public abstract ApplicationInfo getApplicationInfo(String packageName,
+ @ApplicationInfoFlags int flags, int filterCallingUid, int userId);
+
+ /**
+ * Retrieve all of the information we know about a particular activity class.
+ * @param filterCallingUid The results will be filtered in the context of this UID instead
+ * of the calling UID.
+ * @see PackageManager#getActivityInfo(ComponentName, int)
+ */
+ public abstract ActivityInfo getActivityInfo(ComponentName component,
+ @ComponentInfoFlags int flags, int filterCallingUid, int userId);
+
+ /**
+ * Retrieve all activities that can be performed for the given intent.
+ * @param filterCallingUid The results will be filtered in the context of this UID instead
+ * of the calling UID.
+ * @see PackageManager#queryIntentActivities(Intent, int)
*/
- public abstract ApplicationInfo getApplicationInfo(String packageName, int userId);
+ public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
+ @ResolveInfoFlags int flags, int filterCallingUid, int userId);
/**
* Interface to {@link com.android.server.pm.PackageManagerService#getHomeActivitiesAsUser}.
import android.content.pm.LauncherApps.ShortcutQuery;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
private static final boolean DEBUG = false;
private static final String TAG = "LauncherAppsService";
private final Context mContext;
- private final PackageManager mPm;
private final UserManager mUm;
private final ActivityManagerInternal mActivityManagerInternal;
private final ShortcutServiceInternal mShortcutServiceInternal;
public LauncherAppsImpl(Context context) {
mContext = context;
- mPm = mContext.getPackageManager();
mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mActivityManagerInternal = Preconditions.checkNotNull(
LocalServices.getService(ActivityManagerInternal.class));
void verifyCallingPackage(String callingPackage) {
int packageUid = -1;
try {
- packageUid = mPm.getPackageUidAsUser(callingPackage,
+ packageUid = AppGlobals.getPackageManager().getPackageUid(callingPackage,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_UNINSTALLED_PACKAGES,
UserHandle.getUserId(getCallingUid()));
- } catch (NameNotFoundException e) {
+ } catch (RemoteException ignore) {
+ }
+ if (packageUid < 0) {
Log.e(TAG, "Package not found: " + callingPackage);
}
- if (packageUid != Binder.getCallingUid()) {
+ if (packageUid != injectBinderCallingUid()) {
throw new SecurityException("Calling package name mismatch");
}
}
return null;
}
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- return pm.getActivityInfo(component,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ return pmInt.getActivityInfo(component,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
} finally {
Binder.restoreCallingIdentity(ident);
}
return null;
}
+ final int callingUid = injectBinderCallingUid();
long ident = injectClearCallingIdentity();
try {
- List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(intent,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
return new ParceledListSlice<>(apps);
} finally {
injectRestoreCallingIdentity(ident);
return false;
}
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- PackageInfo info = pm.getPackageInfo(packageName,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ PackageInfo info = pmInt.getPackageInfo(packageName,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
return info != null && info.applicationInfo.enabled;
} finally {
Binder.restoreCallingIdentity(ident);
return null;
}
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- ApplicationInfo info = pm.getApplicationInfo(packageName, flags,
- user.getIdentifier());
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ ApplicationInfo info = pmInt.getApplicationInfo(packageName, flags,
+ callingUid, user.getIdentifier());
return info;
} finally {
Binder.restoreCallingIdentity(ident);
return false;
}
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- ActivityInfo info = pm.getActivityInfo(component,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ ActivityInfo info = pmInt.getActivityInfo(component,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
return info != null;
} finally {
Binder.restoreCallingIdentity(ident);
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
launchIntent.setPackage(component.getPackageName());
+ final int callingUid = injectBinderCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- ActivityInfo info = pm.getActivityInfo(component,
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
+ ActivityInfo info = pmInt.getActivityInfo(component,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
if (!info.exported) {
throw new SecurityException("Cannot launch non-exported components "
+ component);
// Check that the component actually has Intent.CATEGORY_LAUCNCHER
// as calling startActivityAsUser ignores the category and just
// resolves based on the component if present.
- List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent,
+ List<ResolveInfo> apps = pmInt.queryIntentActivities(launchIntent,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- user.getIdentifier());
+ callingUid, user.getIdentifier());
final int size = apps.size();
for (int i = 0; i < size; ++i) {
ActivityInfo activityInfo = apps.get(i).activityInfo;
@Override
public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
- flags, userId);
+ flags, Binder.getCallingUid(), userId);
}
@Override
public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
int flags, int userId) {
return getPackageInfoInternal(versionedPackage.getPackageName(),
- versionedPackage.getVersionCode(), flags, userId);
+ versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
}
+ /**
+ * Important: The provided filterCallingUid is used exclusively to filter out packages
+ * that can be seen based on user state. It's typically the original caller uid prior
+ * to clearing. Because it can only be provided by trusted code, it's value can be
+ * trusted and will be used as-is; unlike userId which will be validated by this method.
+ */
private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
- int flags, int userId) {
+ int flags, int filterCallingUid, int userId) {
if (!sUserManager.exists(userId)) return null;
- final int callingUid = Binder.getCallingUid();
flags = updateFlagsForPackage(flags, userId, packageName);
- enforceCrossUserPermission(callingUid, userId,
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */, "get package info");
// reader
if (matchFactoryOnly) {
final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
if (ps != null) {
- if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (filterAppAccessLPr(ps, callingUid, userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
return generatePackageInfo(ps, flags, userId);
Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
if (p != null) {
final PackageSetting ps = (PackageSetting) p.mExtras;
- if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
+ if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) return null;
- if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (filterAppAccessLPr(ps, callingUid, userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
return generatePackageInfo(ps, flags, userId);
}
private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
- int uid, int userId) {
+ int filterCallingUid, int userId) {
if (!sUserManager.exists(userId)) return null;
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
- if (filterSharedLibPackageLPr(ps, uid, userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (filterAppAccessLPr(ps, uid, userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
if (ps.pkg == null) {
@Override
public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
+ return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
+ }
+
+ /**
+ * Important: The provided filterCallingUid is used exclusively to filter out applications
+ * that can be seen based on user state. It's typically the original caller uid prior
+ * to clearing. Because it can only be provided by trusted code, it's value can be
+ * trusted and will be used as-is; unlike userId which will be validated by this method.
+ */
+ private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
+ int filterCallingUid, int userId) {
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForApplication(flags, userId, packageName);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
if (p != null) {
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) return null;
- if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
- if (filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
return null;
}
// Note: isEnabledLP() does not apply here - always return info
if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
// Already generates the external package name
return generateApplicationInfoFromSettingsLPw(packageName,
- Binder.getCallingUid(), flags, userId);
+ flags, filterCallingUid, userId);
}
}
return null;
@Override
public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
+ return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
+ }
+
+ /**
+ * Important: The provided filterCallingUid is used exclusively to filter out activities
+ * that can be seen based on user state. It's typically the original caller uid prior
+ * to clearing. Because it can only be provided by trusted code, it's value can be
+ * trusted and will be used as-is; unlike userId which will be validated by this method.
+ */
+ private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
+ int filterCallingUid, int userId) {
if (!sUserManager.exists(userId)) return null;
- final int callingUid = Binder.getCallingUid();
flags = updateFlagsForComponent(flags, userId, component);
- enforceCrossUserPermission(callingUid, userId,
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */, "get activity info");
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
- if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, userId)) {
+ if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
return null;
}
return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
- flags, userId, resolveForStart);
+ flags, callingUid, userId, resolveForStart);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
final ResolveInfo bestChoice =
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId) {
- return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
+ return queryIntentActivitiesInternal(
+ intent, resolvedType, flags, Binder.getCallingUid(), userId, false);
}
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
- String resolvedType, int flags, int userId, boolean resolveForStart) {
+ String resolvedType, int flags, int filterCallingUid, int userId,
+ boolean resolveForStart) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
- final int callingUid = Binder.getCallingUid();
- final String instantAppPkgName = getInstantAppPackageName(callingUid);
- enforceCrossUserPermission(callingUid, userId,
+ final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */,
"query intent activities");
final String pkgName = intent.getPackage();
}
}
- flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart,
+ flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
comp != null || pkgName != null /*onlyExposedExplicitly*/);
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
}
@Override
- public ApplicationInfo getApplicationInfo(String packageName, int userId) {
- return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
+ public PackageInfo getPackageInfo(
+ String packageName, int flags, int filterCallingUid, int userId) {
+ return PackageManagerService.this
+ .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
+ flags, filterCallingUid, userId);
+ }
+
+ @Override
+ public ApplicationInfo getApplicationInfo(
+ String packageName, int flags, int filterCallingUid, int userId) {
+ return PackageManagerService.this
+ .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
+ }
+
+ @Override
+ public ActivityInfo getActivityInfo(
+ ComponentName component, int flags, int filterCallingUid, int userId) {
+ return PackageManagerService.this
+ .getActivityInfoInternal(component, flags, filterCallingUid, userId);
+ }
+
+ @Override
+ public List<ResolveInfo> queryIntentActivities(
+ Intent intent, int flags, int filterCallingUid, int userId) {
+ final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
+ return PackageManagerService.this
+ .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
+ userId, false /*resolveForStart*/);
}
@Override