diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 94fe572360b53..6272822ac3087 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -306,4 +306,10 @@ public abstract class PackageManagerInternal { */ public abstract boolean setEnabledOverlayPackages(int userId, String targetPackageName, List overlayPackageNames); + + /** + * Resolves an intent, allowing instant apps to be resolved. + */ + public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType, + int flags, int userId); } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 1e33bb9a33625..6f79bc2711983 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1196,13 +1196,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) { - try { - return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType, + synchronized (mService) { + return mService.getPackageManagerInternalLocked().resolveIntent(intent, resolvedType, PackageManager.MATCH_INSTANT | PackageManager.MATCH_DEFAULT_ONLY | flags | ActivityManagerService.STOCK_PM_FLAGS, userId); - } catch (RemoteException e) { } - return null; } ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index fe2fb66822f15..33bd3508b9989 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4012,8 +4012,17 @@ public class PackageManagerService extends IPackageManager.Stub { /** * Update given flags when being used to request {@link ResolveInfo}. + *

Instant apps are resolved specially, depending upon context. Minimally, + * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT} + * flag set. However, this flag is only honoured in three circumstances: + *

*/ - int updateFlagsForResolve(int flags, int userId, Object cookie) { + int updateFlagsForResolve(int flags, int userId, Intent intent, boolean includeInstantApp) { // Safe mode means we shouldn't match any third-party components if (mSafeMode) { flags |= PackageManager.MATCH_SYSTEM_ONLY; @@ -4025,15 +4034,24 @@ public class PackageManagerService extends IPackageManager.Stub { flags |= PackageManager.MATCH_INSTANT; } else { // Otherwise, prevent leaking ephemeral components + final boolean isSpecialProcess = + callingUid == Process.SYSTEM_UID + || callingUid == Process.SHELL_UID + || callingUid == 0; + final boolean allowMatchInstant = + (includeInstantApp + && Intent.ACTION_VIEW.equals(intent.getAction()) + && intent.hasCategory(Intent.CATEGORY_BROWSABLE) + && hasWebURI(intent)) + || isSpecialProcess + || mContext.checkCallingOrSelfPermission( + android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED; flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY; - if (callingUid != Process.SYSTEM_UID - && callingUid != Process.SHELL_UID - && callingUid != 0) { - // Unless called from the system process + if (!allowMatchInstant) { flags &= ~PackageManager.MATCH_INSTANT; } } - return updateFlagsForComponent(flags, userId, cookie); + return updateFlagsForComponent(flags, userId, intent /*cookie*/); } @Override @@ -5558,17 +5576,23 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public ResolveInfo resolveIntent(Intent intent, String resolvedType, int flags, int userId) { + return resolveIntentInternal( + intent, resolvedType, flags, userId, false /*includeInstantApp*/); + } + + private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType, + int flags, int userId, boolean includeInstantApp) { try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent"); if (!sUserManager.exists(userId)) return null; - flags = updateFlagsForResolve(flags, userId, intent); + flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp); enforceCrossUserPermission(Binder.getCallingUid(), userId, false /*requireFullPermission*/, false /*checkShell*/, "resolve intent"); Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); final List query = queryIntentActivitiesInternal(intent, resolvedType, - flags, userId); + flags, userId, includeInstantApp); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); final ResolveInfo bestChoice = @@ -5590,7 +5614,7 @@ public class PackageManagerService extends IPackageManager.Stub { } intent = updateIntentForResolve(intent); final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver()); - final int flags = updateFlagsForResolve(0, userId, intent); + final int flags = updateFlagsForResolve(0, userId, intent, false); final List query = queryIntentActivitiesInternal(intent, resolvedType, flags, userId); synchronized (mPackages) { @@ -5749,6 +5773,13 @@ public class PackageManagerService extends IPackageManager.Stub { if (ri != null) { return ri; } + // If we have an ephemeral app, use it + for (int i = 0; i < N; i++) { + ri = query.get(i); + if (ri.activityInfo.applicationInfo.isInstantApp()) { + return ri; + } + } ri = new ResolveInfo(mResolveInfo); ri.activityInfo = new ActivityInfo(ri.activityInfo); ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); @@ -5867,7 +5898,7 @@ public class PackageManagerService extends IPackageManager.Stub { List query, int priority, boolean always, boolean removeMatches, boolean debug, int userId) { if (!sUserManager.exists(userId)) return null; - flags = updateFlagsForResolve(flags, userId, intent); + flags = updateFlagsForResolve(flags, userId, intent, false); intent = updateIntentForResolve(intent); // writer synchronized (mPackages) { @@ -6035,7 +6066,7 @@ public class PackageManagerService extends IPackageManager.Stub { // cross-profile app linking works only towards the parent. final UserInfo parent = getProfileParent(sourceUserId); synchronized(mPackages) { - int flags = updateFlagsForResolve(0, parent.id, intent); + int flags = updateFlagsForResolve(0, parent.id, intent, false); CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( intent, resolvedType, flags, sourceUserId, parent.id); return xpDomainInfo != null; @@ -6094,9 +6125,14 @@ public class PackageManagerService extends IPackageManager.Stub { private @NonNull List queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId) { + return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false); + } + + private @NonNull List queryIntentActivitiesInternal(Intent intent, + String resolvedType, int flags, int userId, boolean includeInstantApp) { if (!sUserManager.exists(userId)) return Collections.emptyList(); final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid()); - flags = updateFlagsForResolve(flags, userId, intent); + flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp); enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission */, false /* checkShell */, "query intent activities"); @@ -6723,7 +6759,7 @@ public class PackageManagerService extends IPackageManager.Stub { Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); - flags = updateFlagsForResolve(flags, userId, intent); + flags = updateFlagsForResolve(flags, userId, intent, false); enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission */, false /* checkShell */, "query intent activity options"); @@ -6903,7 +6939,7 @@ public class PackageManagerService extends IPackageManager.Stub { private @NonNull List queryIntentReceiversInternal(Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); - flags = updateFlagsForResolve(flags, userId, intent); + flags = updateFlagsForResolve(flags, userId, intent, false); ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { @@ -6940,7 +6976,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return null; - flags = updateFlagsForResolve(flags, userId, intent); + flags = updateFlagsForResolve(flags, userId, intent, false); List query = queryIntentServicesInternal(intent, resolvedType, flags, userId); if (query != null) { if (query.size() >= 1) { @@ -6962,7 +6998,7 @@ public class PackageManagerService extends IPackageManager.Stub { private @NonNull List queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); - flags = updateFlagsForResolve(flags, userId, intent); + flags = updateFlagsForResolve(flags, userId, intent, false); ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { @@ -7006,7 +7042,7 @@ public class PackageManagerService extends IPackageManager.Stub { private @NonNull List queryIntentContentProvidersInternal( Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); - flags = updateFlagsForResolve(flags, userId, intent); + flags = updateFlagsForResolve(flags, userId, intent, false); ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { @@ -23003,13 +23039,18 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); return targetPackages; } - @Override public boolean setEnabledOverlayPackages(int userId, String targetPackageName, List overlayPackageNames) { // TODO: implement when we integrate OMS properly return false; } + + public ResolveInfo resolveIntent(Intent intent, String resolvedType, + int flags, int userId) { + return resolveIntentInternal( + intent, resolvedType, flags, userId, true /*includeInstantApp*/); + } } @Override diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index a8a5ff056521c..a057e9b566c27 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -3370,7 +3370,7 @@ final class Settings { private void applyDefaultPreferredActivityLPw(PackageManagerService service, Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp, IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) { - flags = service.updateFlagsForResolve(flags, userId, intent); + flags = service.updateFlagsForResolve(flags, userId, intent, false); List ri = service.mActivities.queryIntent(intent, intent.getType(), flags, 0); if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent