Merge "Validate Computer functions" into sc-dev

This commit is contained in:
Lee Shombert
2021-06-22 00:11:11 +00:00
committed by Android (Google) Code Review
2 changed files with 391 additions and 114 deletions

View File

@@ -436,8 +436,10 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.DigestException; import java.security.DigestException;
import java.security.DigestInputStream; import java.security.DigestInputStream;
@@ -1918,14 +1920,65 @@ public class PackageManagerService extends IPackageManager.Stub
} }
/** /**
* A computer provides the functional interface to the snapshot. * A {@link Computer} provides a set of functions that can operate on live data or snapshot
* data. At this time, the {@link Computer} is implemented by the
* {@link ComputerEngine}, which is in turn extended by {@link ComputerLocked}.
*
* New functions must be added carefully.
* <ol>
* <li> New functions must be true functions with respect to data collected in a
* {@link Snapshot}. Such data may never be modified from inside a {@link Computer}
* function.
* </li>
*
* <li> A new function must be implemented in {@link ComputerEngine}.
* </li>
*
* <li> A new function must be overridden in {@link ComputerLocked} if the function
* cannot safely access live data without holding the PackageManagerService lock. The
* form of the {@link ComputerLocked} function must be a single call to the
* {@link ComputerEngine} implementation, wrapped in a <code>synchronized</code>
* block. Functions in {@link ComputerLocked} should never include any other code.
* </li>
*
* Care must be taken when deciding if a function should be overridden in
* {@link ComputerLocked}. The complex lock relationships of PackageManagerService
* and other managers (like PermissionManager) mean deadlock is possible. On the
* other hand, not overriding in {@link ComputerLocked} may leave a function walking
* unstable data.
*
* To coax developers to consider such issues carefully, all methods in
* {@link Computer} must be annotated with <code>@LiveImplementation(override =
* MANDATORY)</code> or <code>LiveImplementation(locked = NOT_ALLOWED)</code>. A unit
* test verifies the annotation and that the annotation corresponds to the code in
* {@link ComputerEngine} and {@link ComputerLocked}.
*/ */
private interface Computer { @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
protected interface Computer {
/**
* Every method must be annotated.
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface LiveImplementation {
// A Computer method must be annotated with one of the following values:
// MANDATORY - the method must be overridden in ComputerEngineLive. The
// format of the override is a call to the super method, wrapped in a
// synchronization block.
// NOT_ALLOWED - the method may not appear in the live computer. It must
// be final in the ComputerEngine.
int MANDATORY = 1;
int NOT_ALLOWED = 2;
int override() default MANDATORY;
String rationale() default "";
}
/** /**
* Administrative statistics: record that the snapshot has been used. Every call * Administrative statistics: record that the snapshot has been used. Every call
* to use() increments the usage counter. * to use() increments the usage counter.
*/ */
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
default void use() { default void use() {
} }
@@ -1933,95 +1986,154 @@ public class PackageManagerService extends IPackageManager.Stub
* Fetch the snapshot usage counter. * Fetch the snapshot usage counter.
* @return The number of times this snapshot was used. * @return The number of times this snapshot was used.
*/ */
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
default int getUsed() { default int getUsed() {
return 0; return 0;
} }
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
@NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType, @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid,
int userId, boolean resolveForStart, boolean allowDynamicSplits); int userId, boolean resolveForStart, boolean allowDynamicSplits);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
@NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType, @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
int flags, int userId); int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
@NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, String resolvedType, @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, String resolvedType,
int flags, int userId, int callingUid, boolean includeInstantApps); int flags, int userId, int callingUid, boolean includeInstantApps);
@LiveImplementation(override = LiveImplementation.MANDATORY)
@NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent, @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent,
String resolvedType, int flags, int filterCallingUid, int userId, String resolvedType, int flags, int filterCallingUid, int userId,
boolean resolveForStart, boolean allowDynamicSplits, String pkgName, boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
String instantAppPkgName); String instantAppPkgName);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ActivityInfo getActivityInfo(ComponentName component, int flags, int userId); ActivityInfo getActivityInfo(ComponentName component, int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ActivityInfo getActivityInfoInternal(ComponentName component, int flags, ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
int filterCallingUid, int userId); int filterCallingUid, int userId);
@LiveImplementation(override = LiveImplementation.MANDATORY)
AndroidPackage getPackage(String packageName); AndroidPackage getPackage(String packageName);
@LiveImplementation(override = LiveImplementation.MANDATORY)
AndroidPackage getPackage(int uid); AndroidPackage getPackage(int uid);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
int filterCallingUid, int userId); int filterCallingUid, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ApplicationInfo getApplicationInfo(String packageName, int flags, int userId); ApplicationInfo getApplicationInfo(String packageName, int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ApplicationInfo getApplicationInfoInternal(String packageName, int flags, ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
int filterCallingUid, int userId); int filterCallingUid, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ComponentName getDefaultHomeActivity(int userId); ComponentName getDefaultHomeActivity(int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId); ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType, CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, String resolvedType,
int flags, int sourceUserId, int parentUserId); int flags, int sourceUserId, int parentUserId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
Intent getHomeIntent(); Intent getHomeIntent();
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
String resolvedType, int userId); String resolvedType, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos, List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
boolean resolveForStart, int userId, Intent intent); boolean resolveForStart, int userId, Intent intent);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId); PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
PackageInfo getPackageInfo(String packageName, int flags, int userId); PackageInfo getPackageInfo(String packageName, int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
PackageInfo getPackageInfoInternal(String packageName, long versionCode, int flags, PackageInfo getPackageInfoInternal(String packageName, long versionCode, int flags,
int filterCallingUid, int userId); int filterCallingUid, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
PackageSetting getPackageSetting(String packageName); PackageSetting getPackageSetting(String packageName);
@LiveImplementation(override = LiveImplementation.MANDATORY)
PackageSetting getPackageSettingInternal(String packageName, int callingUid); PackageSetting getPackageSettingInternal(String packageName, int callingUid);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId); ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
int sourceUserId, int targetUserId); int sourceUserId, int targetUserId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
ServiceInfo getServiceInfo(ComponentName component, int flags, int userId); ServiceInfo getServiceInfo(ComponentName component, int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version); SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version);
@LiveImplementation(override = LiveImplementation.MANDATORY)
String getInstantAppPackageName(int callingUid); String getInstantAppPackageName(int callingUid);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
String resolveExternalPackageNameLPr(AndroidPackage pkg); String resolveExternalPackageNameLPr(AndroidPackage pkg);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
String resolveInternalPackageNameLPr(String packageName, long versionCode); String resolveInternalPackageNameLPr(String packageName, long versionCode);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
String[] getPackagesForUid(int uid); String[] getPackagesForUid(int uid);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
UserInfo getProfileParent(int userId); UserInfo getProfileParent(int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean canViewInstantApps(int callingUid, int userId); boolean canViewInstantApps(int callingUid, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId, boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
int flags); int flags);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isCallerSameApp(String packageName, int uid); boolean isCallerSameApp(String packageName, int uid);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isComponentVisibleToInstantApp(@Nullable ComponentName component); boolean isComponentVisibleToInstantApp(@Nullable ComponentName component);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isComponentVisibleToInstantApp(@Nullable ComponentName component, boolean isComponentVisibleToInstantApp(@Nullable ComponentName component,
@ComponentType int type); @ComponentType int type);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId,
String resolvedType, int flags); String resolvedType, int flags);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isInstantApp(String packageName, int userId); boolean isInstantApp(String packageName, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid); boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId); boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid, boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
@Nullable ComponentName component, @ComponentType int componentType, int userId); @Nullable ComponentName component, @ComponentType int componentType, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid, boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
int userId); int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid, boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid,
int userId); int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int checkUidPermission(String permName, int uid); int checkUidPermission(String permName, int uid);
@LiveImplementation(override = LiveImplementation.MANDATORY)
int getPackageUidInternal(String packageName, int flags, int userId, int callingUid); int getPackageUidInternal(String packageName, int flags, int userId, int callingUid);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForApplication(int flags, int userId); int updateFlagsForApplication(int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForComponent(int flags, int userId); int updateFlagsForComponent(int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForPackage(int flags, int userId); int updateFlagsForPackage(int flags, int userId);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
boolean isImplicitImageCaptureIntentAndNotSetByDpc); boolean isImplicitImageCaptureIntentAndNotSetByDpc);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps, int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps,
boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc); boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, String message); boolean requireFullPermission, boolean checkShell, String message);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
void enforceCrossUserPermission(int callingUid, @UserIdInt int userId, void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, String message); boolean requireFullPermission, boolean checkShell, String message);
@LiveImplementation(override = LiveImplementation.NOT_ALLOWED)
void enforceCrossUserPermission(int callingUid, @UserIdInt int userId, void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, boolean requireFullPermission, boolean checkShell,
boolean requirePermissionWhenSameUser, String message); boolean requirePermissionWhenSameUser, String message);
@LiveImplementation(override = LiveImplementation.MANDATORY)
SigningDetails getSigningDetails(@NonNull String packageName); SigningDetails getSigningDetails(@NonNull String packageName);
@LiveImplementation(override = LiveImplementation.MANDATORY)
SigningDetails getSigningDetails(int uid); SigningDetails getSigningDetails(int uid);
@LiveImplementation(override = LiveImplementation.MANDATORY)
boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId); boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId);
@LiveImplementation(override = LiveImplementation.MANDATORY)
boolean filterAppAccess(String packageName, int callingUid, int userId); boolean filterAppAccess(String packageName, int callingUid, int userId);
@LiveImplementation(override = LiveImplementation.MANDATORY)
void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState); void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState);
} }
@@ -2030,7 +2142,8 @@ public class PackageManagerService extends IPackageManager.Stub
* is entirely self-contained - it has no implicit access to * is entirely self-contained - it has no implicit access to
* PackageManagerService. * PackageManagerService.
*/ */
private static class ComputerEngine implements Computer { @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
protected static class ComputerEngine implements Computer {
// The administrative use counter. // The administrative use counter.
private int mUsed = 0; private int mUsed = 0;
@@ -2076,7 +2189,7 @@ public class PackageManagerService extends IPackageManager.Stub
// PackageManagerService attributes that are primitives are referenced through the // PackageManagerService attributes that are primitives are referenced through the
// pms object directly. Primitives are the only attributes so referenced. // pms object directly. Primitives are the only attributes so referenced.
protected final PackageManagerService mService; protected final PackageManagerService mService;
protected boolean safeMode() { private boolean safeMode() {
return mService.mSafeMode; return mService.mSafeMode;
} }
protected ComponentName resolveComponentName() { protected ComponentName resolveComponentName() {
@@ -2130,18 +2243,18 @@ public class PackageManagerService extends IPackageManager.Stub
/** /**
* Record that the snapshot was used. * Record that the snapshot was used.
*/ */
public void use() { public final void use() {
mUsed++; mUsed++;
} }
/** /**
* Return the usage counter. * Return the usage counter.
*/ */
public int getUsed() { public final int getUsed() {
return mUsed; return mUsed;
} }
public @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
int filterCallingUid, int userId, boolean resolveForStart, int filterCallingUid, int userId, boolean resolveForStart,
boolean allowDynamicSplits) { boolean allowDynamicSplits) {
@@ -2240,14 +2353,14 @@ public class PackageManagerService extends IPackageManager.Stub
resolveForStart, userId, intent); resolveForStart, userId, intent);
} }
public @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId) { String resolvedType, int flags, int userId) {
return queryIntentActivitiesInternal( return queryIntentActivitiesInternal(
intent, resolvedType, flags, 0 /*privateResolveFlags*/, Binder.getCallingUid(), intent, resolvedType, flags, 0 /*privateResolveFlags*/, Binder.getCallingUid(),
userId, false /*resolveForStart*/, true /*allowDynamicSplits*/); userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
} }
public @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, public final @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
String resolvedType, int flags, int userId, int callingUid, String resolvedType, int flags, int userId, int callingUid,
boolean includeInstantApps) { boolean includeInstantApps) {
if (!mUserManager.exists(userId)) return Collections.emptyList(); if (!mUserManager.exists(userId)) return Collections.emptyList();
@@ -2471,7 +2584,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null; return null;
} }
public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { public final ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId); return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
} }
@@ -2481,7 +2594,7 @@ public class PackageManagerService extends IPackageManager.Stub
* to clearing. Because it can only be provided by trusted code, its value can be * to clearing. Because it can only be provided by trusted code, its value can be
* trusted and will be used as-is; unlike userId which will be validated by this method. * trusted and will be used as-is; unlike userId which will be validated by this method.
*/ */
public ActivityInfo getActivityInfoInternal(ComponentName component, int flags, public final ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
int filterCallingUid, int userId) { int filterCallingUid, int userId) {
if (!mUserManager.exists(userId)) return null; if (!mUserManager.exists(userId)) return null;
flags = updateFlagsForComponent(flags, userId); flags = updateFlagsForComponent(flags, userId);
@@ -2535,8 +2648,8 @@ public class PackageManagerService extends IPackageManager.Stub
return pkg; return pkg;
} }
public ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, public final ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName,
int filterCallingUid, int userId) { int flags, int filterCallingUid, int userId) {
if (!mUserManager.exists(userId)) return null; if (!mUserManager.exists(userId)) return null;
PackageSetting ps = mSettings.getPackageLPr(packageName); PackageSetting ps = mSettings.getPackageLPr(packageName);
if (ps != null) { if (ps != null) {
@@ -2563,7 +2676,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null; return null;
} }
public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { public final ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId); return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
} }
@@ -2573,7 +2686,7 @@ public class PackageManagerService extends IPackageManager.Stub
* to clearing. Because it can only be provided by trusted code, its value can be * to clearing. Because it can only be provided by trusted code, its value can be
* trusted and will be used as-is; unlike userId which will be validated by this method. * trusted and will be used as-is; unlike userId which will be validated by this method.
*/ */
public ApplicationInfo getApplicationInfoInternal(String packageName, int flags, public final ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
int filterCallingUid, int userId) { int filterCallingUid, int userId) {
if (!mUserManager.exists(userId)) return null; if (!mUserManager.exists(userId)) return null;
flags = updateFlagsForApplication(flags, userId); flags = updateFlagsForApplication(flags, userId);
@@ -2765,7 +2878,7 @@ public class PackageManagerService extends IPackageManager.Stub
* Report the 'Home' activity which is currently set as "always use this one". If non is set * Report the 'Home' activity which is currently set as "always use this one". If non is set
* then reports the most likely home activity or null if there are more than one. * then reports the most likely home activity or null if there are more than one.
*/ */
public ComponentName getDefaultHomeActivity(int userId) { public final ComponentName getDefaultHomeActivity(int userId) {
List<ResolveInfo> allHomeCandidates = new ArrayList<>(); List<ResolveInfo> allHomeCandidates = new ArrayList<>();
ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId); ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
if (cn != null) { if (cn != null) {
@@ -2793,7 +2906,7 @@ public class PackageManagerService extends IPackageManager.Stub
return lastComponent; return lastComponent;
} }
public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, public final ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
int userId) { int userId) {
Intent intent = getHomeIntent(); Intent intent = getHomeIntent();
List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null, List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
@@ -2822,7 +2935,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null; return null;
} }
public CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, public final CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
String resolvedType, int flags, int sourceUserId, int parentUserId) { String resolvedType, int flags, int sourceUserId, int parentUserId) {
if (!mUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, if (!mUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
sourceUserId)) { sourceUserId)) {
@@ -2868,15 +2981,15 @@ public class PackageManagerService extends IPackageManager.Stub
return result; return result;
} }
public Intent getHomeIntent() { public final Intent getHomeIntent() {
Intent intent = new Intent(Intent.ACTION_MAIN); Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME); intent.addCategory(Intent.CATEGORY_HOME);
intent.addCategory(Intent.CATEGORY_DEFAULT); intent.addCategory(Intent.CATEGORY_DEFAULT);
return intent; return intent;
} }
public List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, public final List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(
String resolvedType, int userId) { Intent intent, String resolvedType, int userId) {
CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolver(userId); CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolver(userId);
if (resolver != null) { if (resolver != null) {
return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId); return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
@@ -2895,7 +3008,8 @@ public class PackageManagerService extends IPackageManager.Stub
* @param intent * @param intent
* @return A filtered list of resolved activities. * @return A filtered list of resolved activities.
*/ */
public List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos, public final List<ResolveInfo> applyPostResolutionFilter(
@NonNull List<ResolveInfo> resolveInfos,
String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
boolean resolveForStart, int userId, Intent intent) { boolean resolveForStart, int userId, Intent intent) {
final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId); final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
@@ -3041,7 +3155,7 @@ public class PackageManagerService extends IPackageManager.Stub
return resolveInfos; return resolveInfos;
} }
public List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
int userId) { int userId) {
final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
@@ -3188,7 +3302,7 @@ public class PackageManagerService extends IPackageManager.Stub
return result; return result;
} }
public PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { public final PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
if (!mUserManager.exists(userId)) return null; if (!mUserManager.exists(userId)) return null;
if (ps == null) { if (ps == null) {
return null; return null;
@@ -3258,7 +3372,7 @@ public class PackageManagerService extends IPackageManager.Stub
} }
} }
public PackageInfo getPackageInfo(String packageName, int flags, int userId) { public final PackageInfo getPackageInfo(String packageName, int flags, int userId) {
return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST, return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
flags, Binder.getCallingUid(), userId); flags, Binder.getCallingUid(), userId);
} }
@@ -3269,7 +3383,7 @@ public class PackageManagerService extends IPackageManager.Stub
* to clearing. Because it can only be provided by trusted code, its value can be * to clearing. Because it can only be provided by trusted code, its value can be
* trusted and will be used as-is; unlike userId which will be validated by this method. * trusted and will be used as-is; unlike userId which will be validated by this method.
*/ */
public PackageInfo getPackageInfoInternal(String packageName, long versionCode, public final PackageInfo getPackageInfoInternal(String packageName, long versionCode,
int flags, int filterCallingUid, int userId) { int flags, int filterCallingUid, int userId) {
if (!mUserManager.exists(userId)) return null; if (!mUserManager.exists(userId)) return null;
flags = updateFlagsForPackage(flags, userId); flags = updateFlagsForPackage(flags, userId);
@@ -3340,7 +3454,7 @@ public class PackageManagerService extends IPackageManager.Stub
} }
@Nullable @Nullable
public PackageSetting getPackageSetting(String packageName) { public final PackageSetting getPackageSetting(String packageName) {
return getPackageSettingInternal(packageName, Binder.getCallingUid()); return getPackageSettingInternal(packageName, Binder.getCallingUid());
} }
@@ -3350,7 +3464,7 @@ public class PackageManagerService extends IPackageManager.Stub
return mSettings.getPackageLPr(packageName); return mSettings.getPackageLPr(packageName);
} }
public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { public final ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) { if (getInstantAppPackageName(callingUid) != null) {
return ParceledListSlice.emptyList(); return ParceledListSlice.emptyList();
@@ -3489,7 +3603,7 @@ public class PackageManagerService extends IPackageManager.Stub
return new CrossProfileDomainInfo(forwardingInfo, highestApprovalLevel); return new CrossProfileDomainInfo(forwardingInfo, highestApprovalLevel);
} }
public ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, public final ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
int sourceUserId, int targetUserId) { int sourceUserId, int targetUserId) {
ResolveInfo forwardingResolveInfo = new ResolveInfo(); ResolveInfo forwardingResolveInfo = new ResolveInfo();
final long ident = Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity();
@@ -3601,7 +3715,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null; return null;
} }
public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { public final ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
if (!mUserManager.exists(userId)) return null; if (!mUserManager.exists(userId)) return null;
final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid();
flags = updateFlagsForComponent(flags, userId); flags = updateFlagsForComponent(flags, userId);
@@ -3635,7 +3749,7 @@ public class PackageManagerService extends IPackageManager.Stub
} }
@Nullable @Nullable
public SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) { public final SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
return getSharedLibraryInfo(name, version, mSharedLibraries, null); return getSharedLibraryInfo(name, version, mSharedLibraries, null);
} }
@@ -3671,7 +3785,7 @@ public class PackageManagerService extends IPackageManager.Stub
return ownerUid; return ownerUid;
} }
public String resolveExternalPackageNameLPr(AndroidPackage pkg) { public final String resolveExternalPackageNameLPr(AndroidPackage pkg) {
if (pkg.getStaticSharedLibName() != null) { if (pkg.getStaticSharedLibName() != null) {
return pkg.getManifestPackageName(); return pkg.getManifestPackageName();
} }
@@ -3745,7 +3859,7 @@ public class PackageManagerService extends IPackageManager.Stub
return packageName; return packageName;
} }
public String resolveInternalPackageNameLPr(String packageName, long versionCode) { public final String resolveInternalPackageNameLPr(String packageName, long versionCode) {
final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid();
return resolveInternalPackageNameInternalLocked(packageName, versionCode, return resolveInternalPackageNameInternalLocked(packageName, versionCode,
callingUid); callingUid);
@@ -3766,7 +3880,7 @@ public class PackageManagerService extends IPackageManager.Stub
* calls to invalidateGetPackagesForUidCache() to locate the points at * calls to invalidateGetPackagesForUidCache() to locate the points at
* which the cache is invalidated. * which the cache is invalidated.
*/ */
public String[] getPackagesForUid(int uid) { public final String[] getPackagesForUid(int uid) {
return getPackagesForUidInternal(uid, Binder.getCallingUid()); return getPackagesForUidInternal(uid, Binder.getCallingUid());
} }
@@ -3807,7 +3921,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null; return null;
} }
public UserInfo getProfileParent(int userId) { public final UserInfo getProfileParent(int userId) {
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
try { try {
return mUserManager.getProfileParent(userId); return mUserManager.getProfileParent(userId);
@@ -3837,7 +3951,7 @@ public class PackageManagerService extends IPackageManager.Stub
* <li>The calling application is the default app prediction service.</li> * <li>The calling application is the default app prediction service.</li>
* </ol> * </ol>
*/ */
public boolean canViewInstantApps(int callingUid, int userId) { public final boolean canViewInstantApps(int callingUid, int userId) {
if (callingUid < Process.FIRST_APPLICATION_UID) { if (callingUid < Process.FIRST_APPLICATION_UID) {
return true; return true;
} }
@@ -3861,8 +3975,8 @@ public class PackageManagerService extends IPackageManager.Stub
return false; return false;
} }
public boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId, public final boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid,
int flags) { int userId, int flags) {
// Callers can access only the libs they depend on, otherwise they need to explicitly // Callers can access only the libs they depend on, otherwise they need to explicitly
// ask for the shared libraries given the caller is allowed to access all static libs. // ask for the shared libraries given the caller is allowed to access all static libs.
if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) { if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
@@ -3945,13 +4059,13 @@ public class PackageManagerService extends IPackageManager.Stub
== PackageManager.PERMISSION_GRANTED; == PackageManager.PERMISSION_GRANTED;
} }
public boolean isCallerSameApp(String packageName, int uid) { public final boolean isCallerSameApp(String packageName, int uid) {
AndroidPackage pkg = mPackages.get(packageName); AndroidPackage pkg = mPackages.get(packageName);
return pkg != null return pkg != null
&& UserHandle.getAppId(uid) == pkg.getUid(); && UserHandle.getAppId(uid) == pkg.getUid();
} }
public boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) { public final boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) { if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
return true; return true;
} }
@@ -3964,7 +4078,7 @@ public class PackageManagerService extends IPackageManager.Stub
return false; return false;
} }
public boolean isComponentVisibleToInstantApp( public final boolean isComponentVisibleToInstantApp(
@Nullable ComponentName component, @ComponentType int type) { @Nullable ComponentName component, @ComponentType int type) {
if (type == TYPE_ACTIVITY) { if (type == TYPE_ACTIVITY) {
final ParsedActivity activity = mComponentResolver.getActivity(component); final ParsedActivity activity = mComponentResolver.getActivity(component);
@@ -4012,13 +4126,13 @@ public class PackageManagerService extends IPackageManager.Stub
* @return {@code true} if the intent is a camera intent and the persistent preferred * @return {@code true} if the intent is a camera intent and the persistent preferred
* activity was not set by the DPC. * activity was not set by the DPC.
*/ */
public boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent, int userId, public final boolean isImplicitImageCaptureIntentAndNotSetByDpcLocked(Intent intent,
String resolvedType, int flags) { int userId, String resolvedType, int flags) {
return intent.isImplicitImageCaptureIntent() && !isPersistentPreferredActivitySetByDpm( return intent.isImplicitImageCaptureIntent() && !isPersistentPreferredActivitySetByDpm(
intent, userId, resolvedType, flags); intent, userId, resolvedType, flags);
} }
public boolean isInstantApp(String packageName, int userId) { public final boolean isInstantApp(String packageName, int userId) {
final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */, enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
false /* checkShell */, "isInstantApp"); false /* checkShell */, "isInstantApp");
@@ -4026,7 +4140,7 @@ public class PackageManagerService extends IPackageManager.Stub
return isInstantAppInternal(packageName, userId, callingUid); return isInstantAppInternal(packageName, userId, callingUid);
} }
public boolean isInstantAppInternal(String packageName, @UserIdInt int userId, public final boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
int callingUid) { int callingUid) {
if (HIDE_EPHEMERAL_APIS) { if (HIDE_EPHEMERAL_APIS) {
return false; return false;
@@ -4160,7 +4274,8 @@ public class PackageManagerService extends IPackageManager.Stub
} }
} }
public boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) { public final boolean isSameProfileGroup(@UserIdInt int callerUserId,
@UserIdInt int userId) {
final long identity = Binder.clearCallingIdentity(); final long identity = Binder.clearCallingIdentity();
try { try {
return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId); return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
@@ -4187,7 +4302,8 @@ public class PackageManagerService extends IPackageManager.Stub
* *
* @see #canViewInstantApps(int, int) * @see #canViewInstantApps(int, int)
*/ */
public boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid, public final boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps,
int callingUid,
@Nullable ComponentName component, @ComponentType int componentType, int userId) { @Nullable ComponentName component, @ComponentType int componentType, int userId) {
// if we're in an isolated process, get the real calling UID // if we're in an isolated process, get the real calling UID
if (Process.isIsolated(callingUid)) { if (Process.isIsolated(callingUid)) {
@@ -4247,7 +4363,7 @@ public class PackageManagerService extends IPackageManager.Stub
/** /**
* @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int) * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
*/ */
public boolean shouldFilterApplicationLocked( public final boolean shouldFilterApplicationLocked(
@Nullable PackageSetting ps, int callingUid, int userId) { @Nullable PackageSetting ps, int callingUid, int userId) {
return shouldFilterApplicationLocked(ps, callingUid, null, TYPE_UNKNOWN, userId); return shouldFilterApplicationLocked(ps, callingUid, null, TYPE_UNKNOWN, userId);
} }
@@ -4255,8 +4371,8 @@ public class PackageManagerService extends IPackageManager.Stub
/** /**
* @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int) * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
*/ */
public boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus, int callingUid, public final boolean shouldFilterApplicationLocked(@NonNull SharedUserSetting sus,
int userId) { int callingUid, int userId) {
boolean filterApp = true; boolean filterApp = true;
for (int index = sus.packages.size() - 1; index >= 0 && filterApp; index--) { for (int index = sus.packages.size() - 1; index >= 0 && filterApp; index--) {
filterApp &= shouldFilterApplicationLocked(sus.packages.valueAt(index), filterApp &= shouldFilterApplicationLocked(sus.packages.valueAt(index),
@@ -4280,7 +4396,7 @@ public class PackageManagerService extends IPackageManager.Stub
} }
// NOTE: Can't remove without a major refactor. Keep around for now. // NOTE: Can't remove without a major refactor. Keep around for now.
public int checkUidPermission(String permName, int uid) { public final int checkUidPermission(String permName, int uid) {
return mPermissionManager.checkUidPermission(uid, permName); return mPermissionManager.checkUidPermission(uid, permName);
} }
@@ -4330,21 +4446,21 @@ public class PackageManagerService extends IPackageManager.Stub
/** /**
* Update given flags when being used to request {@link ApplicationInfo}. * Update given flags when being used to request {@link ApplicationInfo}.
*/ */
public int updateFlagsForApplication(int flags, int userId) { public final int updateFlagsForApplication(int flags, int userId) {
return updateFlagsForPackage(flags, userId); return updateFlagsForPackage(flags, userId);
} }
/** /**
* Update given flags when being used to request {@link ComponentInfo}. * Update given flags when being used to request {@link ComponentInfo}.
*/ */
public int updateFlagsForComponent(int flags, int userId) { public final int updateFlagsForComponent(int flags, int userId) {
return updateFlags(flags, userId); return updateFlags(flags, userId);
} }
/** /**
* Update given flags when being used to request {@link PackageInfo}. * Update given flags when being used to request {@link PackageInfo}.
*/ */
public int updateFlagsForPackage(int flags, int userId) { public final int updateFlagsForPackage(int flags, int userId) {
final boolean isCallerSystemUser = UserHandle.getCallingUserId() final boolean isCallerSystemUser = UserHandle.getCallingUserId()
== UserHandle.USER_SYSTEM; == UserHandle.USER_SYSTEM;
if ((flags & PackageManager.MATCH_ANY_USER) != 0) { if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
@@ -4380,14 +4496,14 @@ public class PackageManagerService extends IPackageManager.Stub
* action and a {@code android.intent.category.BROWSABLE} category</li> * action and a {@code android.intent.category.BROWSABLE} category</li>
* </ul> * </ul>
*/ */
public int updateFlagsForResolve(int flags, int userId, int callingUid, public final int updateFlagsForResolve(int flags, int userId, int callingUid,
boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) { boolean wantInstantApps, boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
return updateFlagsForResolve(flags, userId, callingUid, return updateFlagsForResolve(flags, userId, callingUid,
wantInstantApps, false /*onlyExposedExplicitly*/, wantInstantApps, false /*onlyExposedExplicitly*/,
isImplicitImageCaptureIntentAndNotSetByDpc); isImplicitImageCaptureIntentAndNotSetByDpc);
} }
public int updateFlagsForResolve(int flags, int userId, int callingUid, public final int updateFlagsForResolve(int flags, int userId, int callingUid,
boolean wantInstantApps, boolean onlyExposedExplicitly, boolean wantInstantApps, boolean onlyExposedExplicitly,
boolean isImplicitImageCaptureIntentAndNotSetByDpc) { boolean isImplicitImageCaptureIntentAndNotSetByDpc) {
// Safe mode means we shouldn't match any third-party components // Safe mode means we shouldn't match any third-party components
@@ -4429,7 +4545,7 @@ public class PackageManagerService extends IPackageManager.Stub
* @param checkShell whether to prevent shell from access if there's a debugging restriction * @param checkShell whether to prevent shell from access if there's a debugging restriction
* @param message the message to log on security exception * @param message the message to log on security exception
*/ */
public void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId, public final void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, String message) { boolean requireFullPermission, boolean checkShell, String message) {
if (userId < 0) { if (userId < 0) {
throw new IllegalArgumentException("Invalid userId " + userId); throw new IllegalArgumentException("Invalid userId " + userId);
@@ -4467,7 +4583,7 @@ public class PackageManagerService extends IPackageManager.Stub
* @param checkShell whether to prevent shell from access if there's a debugging restriction * @param checkShell whether to prevent shell from access if there's a debugging restriction
* @param message the message to log on security exception * @param message the message to log on security exception
*/ */
public void enforceCrossUserPermission(int callingUid, @UserIdInt int userId, public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, String message) { boolean requireFullPermission, boolean checkShell, String message) {
enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, false, enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, false,
message); message);
@@ -4484,7 +4600,7 @@ public class PackageManagerService extends IPackageManager.Stub
* reference the same user. * reference the same user.
* @param message the message to log on security exception * @param message the message to log on security exception
*/ */
public void enforceCrossUserPermission(int callingUid, @UserIdInt int userId, public final void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
boolean requireFullPermission, boolean checkShell, boolean requireFullPermission, boolean checkShell,
boolean requirePermissionWhenSameUser, String message) { boolean requirePermissionWhenSameUser, String message) {
if (userId < 0) { if (userId < 0) {
@@ -4736,31 +4852,14 @@ public class PackageManagerService extends IPackageManager.Stub
} }
/** /**
* The live computer differs from the ComputerEngine in the methods that fetch data * This subclass is the external interface to the live computer. Some internal helper
* from PackageManagerService. * methods are overridden to fetch live data instead of snapshot data. For each
**/ * Computer interface that is overridden in this class, the override takes the PM lock
private static class ComputerEngineLive extends ComputerEngine { * and then delegates to the live computer engine. This is required because there are
ComputerEngineLive(Snapshot args) { * no locks taken in the engine itself.
super(args);
}
protected ComponentName resolveComponentName() {
return mService.mResolveComponentName;
}
protected ActivityInfo instantAppInstallerActivity() {
return mService.mInstantAppInstallerActivity;
}
protected ApplicationInfo androidApplication() {
return mService.mAndroidApplication;
}
}
/**
* This subclass is the external interface to the live computer. For each
* interface, it takes the PM lock and then delegates to the live
* computer engine. This is required because there are no locks taken in
* the engine itself.
*/ */
private static class ComputerLocked extends ComputerEngineLive { @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
protected static class ComputerLocked extends ComputerEngine {
private final Object mLock; private final Object mLock;
ComputerLocked(Snapshot args) { ComputerLocked(Snapshot args) {
@@ -4768,18 +4867,17 @@ public class PackageManagerService extends IPackageManager.Stub
mLock = mService.mLock; mLock = mService.mLock;
} }
/** protected final ComponentName resolveComponentName() {
* Explicilty snapshot {@link Settings#mPackages} for cases where the caller must not lock return mService.mResolveComponentName;
* in order to get package data. It is expected that the caller locks itself to be able }
* to block on changes to the package data and bring itself up to date once the change protected final ActivityInfo instantAppInstallerActivity() {
* propagates to it. Use with heavy caution. return mService.mInstantAppInstallerActivity;
* @return }
*/ protected final ApplicationInfo androidApplication() {
private Map<String, PackageSetting> snapshotPackageSettings() { return mService.mAndroidApplication;
return mSettings.snapshot().mPackages;
} }
public @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent, public final @NonNull List<ResolveInfo> queryIntentServicesInternalBody(Intent intent,
String resolvedType, int flags, int userId, int callingUid, String resolvedType, int flags, int userId, int callingUid,
String instantAppPkgName) { String instantAppPkgName) {
synchronized (mLock) { synchronized (mLock) {
@@ -4787,8 +4885,8 @@ public class PackageManagerService extends IPackageManager.Stub
callingUid, instantAppPkgName); callingUid, instantAppPkgName);
} }
} }
public @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent, public final @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(
String resolvedType, int flags, int filterCallingUid, int userId, Intent intent, String resolvedType, int flags, int filterCallingUid, int userId,
boolean resolveForStart, boolean allowDynamicSplits, String pkgName, boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
String instantAppPkgName) { String instantAppPkgName) {
synchronized (mLock) { synchronized (mLock) {
@@ -4797,31 +4895,31 @@ public class PackageManagerService extends IPackageManager.Stub
instantAppPkgName); instantAppPkgName);
} }
} }
public ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags, public final ActivityInfo getActivityInfoInternalBody(ComponentName component, int flags,
int filterCallingUid, int userId) { int filterCallingUid, int userId) {
synchronized (mLock) { synchronized (mLock) {
return super.getActivityInfoInternalBody(component, flags, filterCallingUid, return super.getActivityInfoInternalBody(component, flags, filterCallingUid,
userId); userId);
} }
} }
public AndroidPackage getPackage(String packageName) { public final AndroidPackage getPackage(String packageName) {
synchronized (mLock) { synchronized (mLock) {
return super.getPackage(packageName); return super.getPackage(packageName);
} }
} }
public AndroidPackage getPackage(int uid) { public final AndroidPackage getPackage(int uid) {
synchronized (mLock) { synchronized (mLock) {
return super.getPackage(uid); return super.getPackage(uid);
} }
} }
public ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags, public final ApplicationInfo getApplicationInfoInternalBody(String packageName, int flags,
int filterCallingUid, int userId) { int filterCallingUid, int userId) {
synchronized (mLock) { synchronized (mLock) {
return super.getApplicationInfoInternalBody(packageName, flags, filterCallingUid, return super.getApplicationInfoInternalBody(packageName, flags, filterCallingUid,
userId); userId);
} }
} }
public ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody( public final ArrayList<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPrBody(
Intent intent, int matchFlags, List<ResolveInfo> candidates, Intent intent, int matchFlags, List<ResolveInfo> candidates,
CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug) { CrossProfileDomainInfo xpDomainInfo, int userId, boolean debug) {
synchronized (mLock) { synchronized (mLock) {
@@ -4829,49 +4927,49 @@ public class PackageManagerService extends IPackageManager.Stub
matchFlags, candidates, xpDomainInfo, userId, debug); matchFlags, candidates, xpDomainInfo, userId, debug);
} }
} }
public PackageInfo getPackageInfoInternalBody(String packageName, long versionCode, public final PackageInfo getPackageInfoInternalBody(String packageName, long versionCode,
int flags, int filterCallingUid, int userId) { int flags, int filterCallingUid, int userId) {
synchronized (mLock) { synchronized (mLock) {
return super.getPackageInfoInternalBody(packageName, versionCode, flags, return super.getPackageInfoInternalBody(packageName, versionCode, flags,
filterCallingUid, userId); filterCallingUid, userId);
} }
} }
public PackageSetting getPackageSettingInternal(String packageName, int callingUid) { public final PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
synchronized (mLock) { synchronized (mLock) {
return super.getPackageSettingInternal(packageName, callingUid); return super.getPackageSettingInternal(packageName, callingUid);
} }
} }
public ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId, public final ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
int callingUid) { int callingUid) {
synchronized (mLock) { synchronized (mLock) {
return super.getInstalledPackagesBody(flags, userId, callingUid); return super.getInstalledPackagesBody(flags, userId, callingUid);
} }
} }
public ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId, public final ServiceInfo getServiceInfoBody(ComponentName component, int flags, int userId,
int callingUid) { int callingUid) {
synchronized (mLock) { synchronized (mLock) {
return super.getServiceInfoBody(component, flags, userId, callingUid); return super.getServiceInfoBody(component, flags, userId, callingUid);
} }
} }
public String getInstantAppPackageName(int callingUid) { public final String getInstantAppPackageName(int callingUid) {
synchronized (mLock) { synchronized (mLock) {
return super.getInstantAppPackageName(callingUid); return super.getInstantAppPackageName(callingUid);
} }
} }
public String[] getPackagesForUidInternalBody(int callingUid, int userId, int appId, public final String[] getPackagesForUidInternalBody(int callingUid, int userId, int appId,
boolean isCallerInstantApp) { boolean isCallerInstantApp) {
synchronized (mLock) { synchronized (mLock) {
return super.getPackagesForUidInternalBody(callingUid, userId, appId, return super.getPackagesForUidInternalBody(callingUid, userId, appId,
isCallerInstantApp); isCallerInstantApp);
} }
} }
public boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId, public final boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId,
int callingUid) { int callingUid) {
synchronized (mLock) { synchronized (mLock) {
return super.isInstantAppInternalBody(packageName, userId, callingUid); return super.isInstantAppInternalBody(packageName, userId, callingUid);
} }
} }
public boolean isInstantAppResolutionAllowedBody(Intent intent, public final boolean isInstantAppResolutionAllowedBody(Intent intent,
List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck, List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck,
int flags) { int flags) {
synchronized (mLock) { synchronized (mLock) {
@@ -4879,33 +4977,33 @@ public class PackageManagerService extends IPackageManager.Stub
skipPackageCheck, flags); skipPackageCheck, flags);
} }
} }
public int getPackageUidInternal(String packageName, int flags, int userId, public final int getPackageUidInternal(String packageName, int flags, int userId,
int callingUid) { int callingUid) {
synchronized (mLock) { synchronized (mLock) {
return super.getPackageUidInternal(packageName, flags, userId, callingUid); return super.getPackageUidInternal(packageName, flags, userId, callingUid);
} }
} }
public SigningDetails getSigningDetails(@NonNull String packageName) { public final SigningDetails getSigningDetails(@NonNull String packageName) {
synchronized (mLock) { synchronized (mLock) {
return super.getSigningDetails(packageName); return super.getSigningDetails(packageName);
} }
} }
public SigningDetails getSigningDetails(int uid) { public final SigningDetails getSigningDetails(int uid) {
synchronized (mLock) { synchronized (mLock) {
return super.getSigningDetails(uid); return super.getSigningDetails(uid);
} }
} }
public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) { public final boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
synchronized (mLock) { synchronized (mLock) {
return super.filterAppAccess(pkg, callingUid, userId); return super.filterAppAccess(pkg, callingUid, userId);
} }
} }
public boolean filterAppAccess(String packageName, int callingUid, int userId) { public final boolean filterAppAccess(String packageName, int callingUid, int userId) {
synchronized (mLock) { synchronized (mLock) {
return super.filterAppAccess(packageName, callingUid, userId); return super.filterAppAccess(packageName, callingUid, userId);
} }
} }
public void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) { public final void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) {
synchronized (mLock) { synchronized (mLock) {
super.dump(type, fd, pw, dumpState); super.dump(type, fd, pw, dumpState);
} }

View File

@@ -18,7 +18,11 @@ package com.android.server.pm;
import static com.google.common.truth.Truth.assertWithMessage; import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.fail;
import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isFinal;
import static java.lang.reflect.Modifier.isPrivate;
import static java.lang.reflect.Modifier.isProtected;
import static java.lang.reflect.Modifier.isPublic; import static java.lang.reflect.Modifier.isPublic;
import static java.lang.reflect.Modifier.isStatic; import static java.lang.reflect.Modifier.isStatic;
@@ -44,9 +48,12 @@ import org.junit.runner.RunWith;
import java.io.File; import java.io.File;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -393,6 +400,178 @@ public class PackageManagerServiceTest {
Assert.assertEquals(3600000003L, multiPackage[1].timeouts.maxPendingTimeUs); Assert.assertEquals(3600000003L, multiPackage[1].timeouts.maxPendingTimeUs);
} }
// Report an error from the Computer structure validation test.
private void flag(String name, String msg) {
fail(name + " " + msg);
}
// Return a string that identifies a Method. This is not very efficient but it is not
// called very often.
private String displayName(Method m) {
String r = m.getName();
String p = Arrays.toString(m.getGenericParameterTypes())
.replaceAll("([a-zA-Z0-9]+\\.)+", "")
.replace("class ", "")
.replaceAll("^\\[", "(")
.replaceAll("\\]$", ")");
return r + p;
}
// Match a method to an array of Methods. Matching is on method signature: name and
// parameter types. If a method in the declared array matches, return it. Otherwise
// return null.
private Method matchMethod(Method m, Method[] declared) {
String n = m.getName();
Type[] t = m.getGenericParameterTypes();
for (int i = 0; i < declared.length; i++) {
Method l = declared[i];
if (l != null && l.getName().equals(n)
&& Arrays.equals(l.getGenericParameterTypes(), t)) {
Method result = l;
// Set the method to null since it has been visited already.
declared[i] = null;
return result;
}
}
return null;
}
// Return the boolean locked value. A null return means the annotation was not
// found. This method will fail if the annotation is found but is not one of the
// known constants.
private Boolean getOverride(Method m) {
final String name = "Computer." + displayName(m);
final PackageManagerService.Computer.LiveImplementation annotation =
m.getAnnotation(PackageManagerService.Computer.LiveImplementation.class);
if (annotation == null) {
return null;
}
final int override = annotation.override();
if (override == PackageManagerService.Computer.LiveImplementation.MANDATORY) {
return true;
} else if (override == PackageManagerService.Computer.LiveImplementation.NOT_ALLOWED) {
return false;
} else {
flag(name, "invalid Live value: " + override);
return null;
}
}
@Test
public void testComputerStructure() {
// Verify that Copmuter methods are properly annotated and that ComputerLocked is
// properly populated per annotations.
// Call PackageManagerService.validateComputer();
Class base = PackageManagerService.Computer.class;
HashMap<Method, Boolean> methodType = new HashMap<>();
// Verify that all Computer methods are annotated and that the annotation
// parameter locked() is valid.
for (Method m : base.getDeclaredMethods()) {
final String name = "Computer." + displayName(m);
Boolean override = getOverride(m);
if (override == null) {
flag(name, "missing required Live annotation");
}
methodType.put(m, override);
}
Class coreClass = PackageManagerService.ComputerEngine.class;
final Method[] coreMethods = coreClass.getDeclaredMethods();
// Examine every method in the core. If it inherits from a base method it must be
// "public final" if the base is NOT_ALLOWED or "public" if the base is MANDATORY.
// If the core method does not inherit from the base then it must be either
// private or protected.
for (Method m : base.getDeclaredMethods()) {
String name = "Computer." + displayName(m);
final boolean locked = methodType.get(m);
final Method core = matchMethod(m, coreMethods);
if (core == null) {
flag(name, "not overridden in ComputerEngine");
continue;
}
name = "ComputerEngine." + displayName(m);
final int modifiers = core.getModifiers();
if (!locked) {
if (!isPublic(modifiers)) {
flag(name, "is not public");
}
if (!isFinal(modifiers)) {
flag(name, "is not final");
}
}
}
// Any methods left in the coreMethods array must be private or protected.
// Protected methods must be overridden (and final) in the live list.
Method[] coreHelpers = new Method[coreMethods.length];
int coreIndex = 0;
for (Method m : coreMethods) {
if (m != null) {
final String name = "ComputerEngine." + displayName(m);
final int modifiers = m.getModifiers();
if (isPrivate(modifiers)) {
// Okay
} else if (isProtected(modifiers)) {
coreHelpers[coreIndex++] = m;
} else {
flag(name, "is neither private nor protected");
}
}
}
Class liveClass = PackageManagerService.ComputerLocked.class;
final Method[] liveMethods = liveClass.getDeclaredMethods();
// Examine every method in the live list. Every method must be final and must
// inherit either from base or core. If the method inherits from a base method
// then the base must be MANDATORY.
for (Method m : base.getDeclaredMethods()) {
String name = "Computer." + displayName(m);
final boolean locked = methodType.get(m);
final Method live = matchMethod(m, liveMethods);
if (live == null) {
if (locked) {
flag(name, "not overridden in ComputerLocked");
}
continue;
}
if (!locked) {
flag(name, "improperly overridden in ComputerLocked");
continue;
}
name = "ComputerLocked." + displayName(m);
final int modifiers = live.getModifiers();
if (!locked) {
if (!isPublic(modifiers)) {
flag(name, "is not public");
}
if (!isFinal(modifiers)) {
flag(name, "is not final");
}
}
}
for (Method m : coreHelpers) {
if (m == null) {
continue;
}
String name = "ComputerLocked." + displayName(m);
final Method live = matchMethod(m, liveMethods);
if (live == null) {
flag(name, "is not overridden in ComputerLocked");
continue;
}
}
for (Method m : liveMethods) {
if (m != null) {
String name = "ComputerLocked." + displayName(m);
flag(name, "illegal local method");
}
}
}
private static PerPackageReadTimeouts[] getPerPackageReadTimeouts(String knownDigestersList) { private static PerPackageReadTimeouts[] getPerPackageReadTimeouts(String knownDigestersList) {
final String defaultTimeouts = "3600000001:3600000002:3600000003"; final String defaultTimeouts = "3600000001:3600000002:3600000003";
List<PerPackageReadTimeouts> result = PerPackageReadTimeouts.parseDigestersList( List<PerPackageReadTimeouts> result = PerPackageReadTimeouts.parseDigestersList(