Fix ComponentResolver Computer consistency
Migrates ComponentResolver and ResolveIntentHelper away from calling
PM directly in favor of using a consistent Computer snapshot. This
saves on snapshot rebuild and ensures data consistency within a single
method call.
Bug: 215403184
Change-Id: Id017db704493f38d94fd498f77d2264fe008ef45
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index e335a16..09ef03c 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -52,6 +52,7 @@
import com.android.server.pm.pkg.SharedUserApi;
import com.android.server.pm.pkg.component.ParsedMainComponent;
import com.android.server.pm.pkg.mutate.PackageStateMutator;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
import java.io.IOException;
import java.lang.annotation.Retention;
@@ -718,7 +719,8 @@
/**
* Returns a package object for the disabled system package name.
*/
- public abstract @Nullable PackageSetting getDisabledSystemPackage(@NonNull String packageName);
+ public abstract @Nullable PackageStateInternal getDisabledSystemPackage(
+ @NonNull String packageName);
/**
* Returns the package name for the disabled system package.
@@ -1334,4 +1336,12 @@
public abstract PackageStateMutator.Result commitPackageStateMutation(
@Nullable PackageStateMutator.InitialState state,
@NonNull Consumer<PackageStateMutator> consumer);
+
+ /**
+ * @return package data snapshot for use with other PackageManager infrastructure. This should
+ * only be used as a parameter passed to another PM related class. Do not call methods on this
+ * directly.
+ */
+ @NonNull
+ public abstract PackageDataSnapshot snapshot();
}
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index aae1cc0..c375c73 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -17,6 +17,8 @@
package com.android.server;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
@@ -32,6 +34,9 @@
import android.util.proto.ProtoOutputStream;
import com.android.internal.util.FastPrintWriter;
+import com.android.server.pm.Computer;
+import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -51,7 +56,7 @@
final private static boolean localLOGV = DEBUG || false;
final private static boolean localVerificationLOGV = DEBUG || false;
- public void addFilter(F f) {
+ public void addFilter(@Nullable PackageDataSnapshot snapshot, F f) {
IntentFilter intentFilter = getIntentFilter(f);
if (localLOGV) {
Slog.v(TAG, "Adding filter: " + f);
@@ -420,8 +425,9 @@
return Collections.unmodifiableSet(mFilters);
}
- public List<R> queryIntentFromList(Intent intent, String resolvedType, boolean defaultOnly,
- ArrayList<F[]> listCut, int userId) {
+ public List<R> queryIntentFromList(@NonNull Computer computer, Intent intent,
+ String resolvedType, boolean defaultOnly, ArrayList<F[]> listCut, int userId,
+ long customFlags) {
ArrayList<R> resultList = new ArrayList<R>();
final boolean debug = localLOGV ||
@@ -431,16 +437,21 @@
final String scheme = intent.getScheme();
int N = listCut.size();
for (int i = 0; i < N; ++i) {
- buildResolveList(intent, categories, debug, defaultOnly, resolvedType, scheme,
- listCut.get(i), resultList, userId);
+ buildResolveList(computer, intent, categories, debug, defaultOnly, resolvedType, scheme,
+ listCut.get(i), resultList, userId, customFlags);
}
filterResults(resultList);
sortResults(resultList);
return resultList;
}
- public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
- int userId) {
+ public List<R> queryIntent(@NonNull PackageDataSnapshot snapshot, Intent intent,
+ String resolvedType, boolean defaultOnly, @UserIdInt int userId) {
+ return queryIntent(snapshot, intent, resolvedType, defaultOnly, userId, 0);
+ }
+
+ protected final List<R> queryIntent(@NonNull PackageDataSnapshot snapshot, Intent intent,
+ String resolvedType, boolean defaultOnly, @UserIdInt int userId, long customFlags) {
String scheme = intent.getScheme();
ArrayList<R> finalList = new ArrayList<R>();
@@ -512,21 +523,22 @@
}
FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
+ Computer computer = (Computer) snapshot;
if (firstTypeCut != null) {
- buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
- scheme, firstTypeCut, finalList, userId);
+ buildResolveList(computer, intent, categories, debug, defaultOnly, resolvedType,
+ scheme, firstTypeCut, finalList, userId, customFlags);
}
if (secondTypeCut != null) {
- buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
- scheme, secondTypeCut, finalList, userId);
+ buildResolveList(computer, intent, categories, debug, defaultOnly, resolvedType,
+ scheme, secondTypeCut, finalList, userId, customFlags);
}
if (thirdTypeCut != null) {
- buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
- scheme, thirdTypeCut, finalList, userId);
+ buildResolveList(computer, intent, categories, debug, defaultOnly, resolvedType,
+ scheme, thirdTypeCut, finalList, userId, customFlags);
}
if (schemeCut != null) {
- buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
- scheme, schemeCut, finalList, userId);
+ buildResolveList(computer, intent, categories, debug, defaultOnly, resolvedType,
+ scheme, schemeCut, finalList, userId, customFlags);
}
filterResults(finalList);
sortResults(finalList);
@@ -554,7 +566,7 @@
* "stopped", that is whether it should not be included in the result
* if the intent requests to excluded stopped objects.
*/
- protected boolean isFilterStopped(F filter, int userId) {
+ protected boolean isFilterStopped(PackageStateInternal packageState, @UserIdInt int userId) {
return false;
}
@@ -584,7 +596,8 @@
protected abstract F[] newArray(int size);
@SuppressWarnings("unchecked")
- protected R newResult(F filter, int match, int userId) {
+ protected R newResult(@NonNull Computer computer, F filter, int match, int userId,
+ long customFlags) {
return (R)filter;
}
@@ -764,9 +777,10 @@
return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()]));
}
- private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
- boolean debug, boolean defaultOnly, String resolvedType, String scheme,
- F[] src, List<R> dest, int userId) {
+ private void buildResolveList(@NonNull Computer computer, Intent intent,
+ FastImmutableArraySet<String> categories, boolean debug, boolean defaultOnly,
+ String resolvedType, String scheme, F[] src, List<R> dest, int userId,
+ long customFlags) {
final String action = intent.getAction();
final Uri data = intent.getData();
final String packageName = intent.getPackage();
@@ -791,7 +805,8 @@
int match;
if (debug) Slog.v(TAG, "Matching against filter " + filter);
- if (excludingStopped && isFilterStopped(filter, userId)) {
+ if (excludingStopped && isFilterStopped(computer.getPackageStateInternal(packageName),
+ userId)) {
if (debug) {
Slog.v(TAG, " Filter's target is stopped; skipping");
}
@@ -833,7 +848,7 @@
Integer.toHexString(match) + " hasDefault="
+ intentFilter.hasCategory(Intent.CATEGORY_DEFAULT));
if (!defaultOnly || intentFilter.hasCategory(Intent.CATEGORY_DEFAULT)) {
- final R oneResult = newResult(filter, match, userId);
+ final R oneResult = newResult(computer, filter, match, userId, customFlags);
if (debug) Slog.v(TAG, " Created result: " + oneResult);
if (oneResult != null) {
dest.add(oneResult);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6c39a11..d21203f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -395,12 +395,14 @@
import com.android.server.graphics.fonts.FontManagerInternal;
import com.android.server.job.JobSchedulerInternal;
import com.android.server.os.NativeTombstoneManager;
+import com.android.server.pm.Computer;
import com.android.server.pm.Installer;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.pkg.SELinuxUtil;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
import com.android.server.uri.GrantUri;
import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal;
@@ -1105,10 +1107,11 @@
}
@Override
- protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
+ protected BroadcastFilter newResult(@NonNull Computer computer, BroadcastFilter filter,
+ int match, int userId, long customFlags) {
if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
|| userId == filter.owningUserId) {
- return super.newResult(filter, match, userId);
+ return super.newResult(computer, filter, match, userId, customFlags);
}
return null;
}
@@ -13039,7 +13042,7 @@
if (!bf.debugCheck()) {
Slog.w(TAG, "==> For Dynamic broadcast");
}
- mReceiverResolver.addFilter(bf);
+ mReceiverResolver.addFilter(getPackageManagerInternal().snapshot(), bf);
}
// Enqueue broadcasts for all existing stickies that match
@@ -13861,6 +13864,7 @@
intent, resolvedType, callingUid, users, broadcastAllowList);
}
if (intent.getComponent() == null) {
+ final PackageDataSnapshot snapshot = getPackageManagerInternal().snapshot();
if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
// Query one target user at a time, excluding shell-restricted users
for (int i = 0; i < users.length; i++) {
@@ -13869,7 +13873,7 @@
continue;
}
List<BroadcastFilter> registeredReceiversForUser =
- mReceiverResolver.queryIntent(intent,
+ mReceiverResolver.queryIntent(snapshot, intent,
resolvedType, false /*defaultOnly*/, users[i]);
if (registeredReceivers == null) {
registeredReceivers = registeredReceiversForUser;
@@ -13878,7 +13882,7 @@
}
}
} else {
- registeredReceivers = mReceiverResolver.queryIntent(intent,
+ registeredReceivers = mReceiverResolver.queryIntent(snapshot, intent,
resolvedType, false /*defaultOnly*/, userId);
}
}
diff --git a/services/core/java/com/android/server/firewall/IntentFirewall.java b/services/core/java/com/android/server/firewall/IntentFirewall.java
index 1139d28..bb8a744 100644
--- a/services/core/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/core/java/com/android/server/firewall/IntentFirewall.java
@@ -24,6 +24,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
@@ -38,6 +39,8 @@
import com.android.internal.util.XmlUtils;
import com.android.server.EventLogTags;
import com.android.server.IntentResolver;
+import com.android.server.LocalServices;
+import com.android.server.pm.Computer;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -75,6 +78,9 @@
private final RuleObserver mObserver;
+ @NonNull
+ private PackageManagerInternal mPackageManager;
+
private FirewallIntentResolver mActivityResolver = new FirewallIntentResolver();
private FirewallIntentResolver mBroadcastResolver = new FirewallIntentResolver();
private FirewallIntentResolver mServiceResolver = new FirewallIntentResolver();
@@ -123,6 +129,13 @@
mObserver.startWatching();
}
+ private PackageManagerInternal getPackageManager() {
+ if (mPackageManager == null) {
+ mPackageManager = LocalServices.getService(PackageManagerInternal.class);
+ }
+ return mPackageManager;
+ }
+
/**
* This is called from ActivityManager to check if a start activity intent should be allowed.
* It is assumed the caller is already holding the global ActivityManagerService lock.
@@ -154,7 +167,8 @@
// For the first pass, find all the rules that have at least one intent-filter or
// component-filter that matches this intent
List<Rule> candidateRules;
- candidateRules = resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, 0);
+ candidateRules = resolver.queryIntent(getPackageManager().snapshot(), intent, resolvedType,
+ false /*defaultOnly*/, 0);
if (candidateRules == null) {
candidateRules = new ArrayList<Rule>();
}
@@ -375,7 +389,7 @@
for (int ruleIndex=0; ruleIndex<rules.size(); ruleIndex++) {
Rule rule = rules.get(ruleIndex);
for (int i=0; i<rule.getIntentFilterCount(); i++) {
- resolver.addFilter(rule.getIntentFilter(i));
+ resolver.addFilter(null, rule.getIntentFilter(i));
}
for (int i=0; i<rule.getComponentFilterCount(); i++) {
resolver.addComponentFilter(rule.getComponentFilter(i), rule);
@@ -512,7 +526,8 @@
}
@Override
- protected Rule newResult(FirewallIntentFilter filter, int match, int userId) {
+ protected Rule newResult(@NonNull Computer computer, FirewallIntentFilter filter,
+ int match, int userId, long customFlags) {
return filter.rule;
}
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index 0d9ccd2..2a4882a 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -51,6 +51,8 @@
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.SharedUserApi;
+import com.android.server.pm.resolution.ComponentResolverApi;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
import com.android.server.utils.WatchedArrayMap;
import com.android.server.utils.WatchedLongSparseArray;
@@ -98,7 +100,7 @@
* {@link ComputerEngine} and {@link ComputerLocked}.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-public interface Computer {
+public interface Computer extends PackageDataSnapshot {
/**
* Every method must be annotated.
@@ -178,6 +180,18 @@
@Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
String resolvedType, int userId);
+
+ /**
+ * Filters out ephemeral activities.
+ * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
+ * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
+ *
+ * @param resolveInfos The pre-filtered list of resolved activities
+ * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
+ * is performed.
+ * @param intent
+ * @return A filtered list of resolved activities.
+ */
@Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
@@ -648,4 +662,16 @@
@Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
@NonNull
ArraySet<PackageStateInternal> getSharedUserPackages(int sharedUserAppId);
+
+ @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
+ @NonNull
+ ComponentResolverApi getComponentResolver();
+
+ @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
+ @Nullable
+ PackageStateInternal getDisabledSystemPackage(@NonNull String packageName);
+
+ @Computer.LiveImplementation(override = LiveImplementation.MANDATORY)
+ @Nullable
+ ResolveInfo getInstantAppInstallerInfo();
}
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index c437697..9e87898 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -49,7 +49,6 @@
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
-import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
import static com.android.server.pm.PackageManagerService.DEBUG_DOMAIN_VERIFICATION;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTANT;
@@ -59,6 +58,7 @@
import static com.android.server.pm.PackageManagerService.HIDE_EPHEMERAL_APIS;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
+import static com.android.server.pm.resolution.ComponentResolver.RESOLVE_PRIORITY_SORTER;
import android.Manifest;
import android.annotation.NonNull;
@@ -143,6 +143,7 @@
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
+import com.android.server.pm.resolution.ComponentResolverApi;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import com.android.server.pm.verify.domain.DomainVerificationUtils;
import com.android.server.uri.UriGrantsManagerInternal;
@@ -362,7 +363,7 @@
private final PermissionManagerServiceInternal mPermissionManager;
private final ApexManager mApexManager;
private final PackageManagerServiceInjector mInjector;
- private final ComponentResolver mComponentResolver;
+ private final ComponentResolverApi mComponentResolver;
private final InstantAppResolverConnection mInstantAppResolverConnection;
private final DefaultAppProvider mDefaultAppProvider;
private final DomainVerificationManagerInternal mDomainVerificationManager;
@@ -644,7 +645,7 @@
// reader
String pkgName = intent.getPackage();
if (pkgName == null) {
- final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
+ final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(this, intent,
resolvedType, flags, userId);
if (resolveInfos == null) {
return Collections.emptyList();
@@ -654,7 +655,7 @@
}
final AndroidPackage pkg = mPackages.get(pkgName);
if (pkg != null) {
- final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
+ final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(this, intent,
resolvedType, flags, pkg.getServices(),
userId);
if (resolveInfos == null) {
@@ -691,7 +692,7 @@
}
// Check for results in the current profile.
- result = filterIfNotSystemUser(mComponentResolver.queryActivities(
+ result = filterIfNotSystemUser(mComponentResolver.queryActivities(this,
intent, resolvedType, flags, userId), userId);
addInstant = isInstantAppResolutionAllowed(intent, result, userId,
false /*skipPackageCheck*/, flags);
@@ -753,7 +754,7 @@
result = null;
if (setting != null && setting.getAndroidPackage() != null && (resolveForStart
|| !shouldFilterApplication(setting, filterCallingUid, userId))) {
- result = filterIfNotSystemUser(mComponentResolver.queryActivities(
+ result = filterIfNotSystemUser(mComponentResolver.queryActivities(this,
intent, resolvedType, flags, setting.getAndroidPackage().getActivities(),
userId), userId);
}
@@ -1181,7 +1182,7 @@
sourceUserId)) {
return null;
}
- List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
+ List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(this, intent,
resolvedType, flags, parentUserId);
if (resultTargetUser == null || resultTargetUser.isEmpty()) {
@@ -1232,7 +1233,7 @@
Intent intent, String resolvedType, int userId) {
CrossProfileIntentResolver resolver = mSettings.getCrossProfileIntentResolver(userId);
if (resolver != null) {
- return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
+ return resolver.queryIntent(this, intent, resolvedType, false /*defaultOnly*/, userId);
}
return null;
}
@@ -1447,7 +1448,7 @@
ResolveInfo localInstantApp = null;
boolean blockResolution = false;
if (!alreadyResolvedLocally) {
- final List<ResolveInfo> instantApps = mComponentResolver.queryActivities(
+ final List<ResolveInfo> instantApps = mComponentResolver.queryActivities(this,
intent,
resolvedType,
flags
@@ -1493,8 +1494,8 @@
null /*callingFeatureId*/, isRequesterInstantApp, userId,
null /*verificationBundle*/, resolveForStart,
digest.getDigestPrefixSecure(), token);
- auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
- mInstantAppResolverConnection, requestObject);
+ auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(this,
+ mUserManager, mInstantAppResolverConnection, requestObject);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
} else {
// we have an instant application locally, but, we can't admit that since
@@ -1830,7 +1831,7 @@
return null;
}
- List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
+ List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(this, intent,
resolvedType, flags, targetUserId);
if (CollectionUtils.isEmpty(resultTargetUser)) {
return null;
@@ -2586,7 +2587,7 @@
mSettings.getPersistentPreferredActivities(userId);
//TODO(b/158003772): Remove double query
List<PersistentPreferredActivity> pprefs = ppir != null
- ? ppir.queryIntent(intent, resolvedType,
+ ? ppir.queryIntent(this, intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
userId)
: new ArrayList<>();
@@ -3244,7 +3245,7 @@
// Get the list of preferred activities that handle the intent
if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
List<PreferredActivity> prefs = pir != null
- ? pir.queryIntent(intent, resolvedType,
+ ? pir.queryIntent(this, intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
userId)
: null;
@@ -3376,7 +3377,7 @@
pa.mPref.mComponent,
pa.mPref.mAlways);
pir.removeFilter(pa);
- pir.addFilter(freshPa);
+ pir.addFilter(this, freshPa);
result.mChanged = true;
} else {
if (DEBUG_PREFERRED) {
@@ -3399,7 +3400,7 @@
PreferredActivity lastChosen = new PreferredActivity(
pa, pa.mPref.mMatch, null, pa.mPref.mComponent,
false);
- pir.addFilter(lastChosen);
+ pir.addFilter(this, lastChosen);
result.mChanged = true;
}
result.mPreferredResolveInfo = null;
@@ -3454,7 +3455,7 @@
Slog.v(TAG, "Looking for persistent preferred activities...");
}
List<PersistentPreferredActivity> pprefs = ppir != null
- ? ppir.queryIntent(intent, resolvedType,
+ ? ppir.queryIntent(this, intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
userId)
: null;
@@ -4661,7 +4662,8 @@
int callingUid) {
if (!mUserManager.exists(userId)) return null;
flags = updateFlagsForComponent(flags, userId);
- final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
+ final ProviderInfo providerInfo = mComponentResolver.queryProvider(this, name, flags,
+ userId);
boolean checkedGrants = false;
if (providerInfo != null) {
// Looking for cross-user grants before enforcing the typical cross-users permissions
@@ -4739,7 +4741,7 @@
final List<String> names = new ArrayList<>();
final List<ProviderInfo> infos = new ArrayList<>();
final int callingUserId = UserHandle.getCallingUserId();
- mComponentResolver.querySyncProviders(names, infos, safeMode, callingUserId);
+ mComponentResolver.querySyncProviders(this, names, infos, safeMode, callingUserId);
for (int i = infos.size() - 1; i >= 0; i--) {
final ProviderInfo providerInfo = infos.get(i);
final PackageStateInternal ps = mSettings.getPackage(providerInfo.packageName);
@@ -4771,8 +4773,8 @@
if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForComponent(flags, userId);
ArrayList<ProviderInfo> finalList = null;
- final List<ProviderInfo> matchList =
- mComponentResolver.queryProviders(processName, metaDataKey, uid, flags, userId);
+ final List<ProviderInfo> matchList = mComponentResolver.queryProviders(this, processName,
+ metaDataKey, uid, flags, userId);
final int listSize = (matchList == null ? 0 : matchList.size());
for (int i = 0; i < listSize; i++) {
final ProviderInfo providerInfo = matchList.get(i);
@@ -5674,4 +5676,22 @@
public ArraySet<PackageStateInternal> getSharedUserPackages(int sharedUserAppId) {
return mSettings.getSharedUserPackages(sharedUserAppId);
}
+
+ @NonNull
+ @Override
+ public ComponentResolverApi getComponentResolver() {
+ return mComponentResolver;
+ }
+
+ @Nullable
+ @Override
+ public PackageStateInternal getDisabledSystemPackage(@NonNull String packageName) {
+ return mSettings.getDisabledSystemPkg(packageName);
+ }
+
+ @Nullable
+ @Override
+ public ResolveInfo getInstantAppInstallerInfo() {
+ return mInstantAppInstallerInfo;
+ }
}
diff --git a/services/core/java/com/android/server/pm/ComputerLocked.java b/services/core/java/com/android/server/pm/ComputerLocked.java
index 583348b..5d89c7d 100644
--- a/services/core/java/com/android/server/pm/ComputerLocked.java
+++ b/services/core/java/com/android/server/pm/ComputerLocked.java
@@ -48,6 +48,7 @@
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.SharedUserApi;
+import com.android.server.pm.resolution.ComponentResolverApi;
import com.android.server.utils.WatchedArrayMap;
import com.android.server.utils.WatchedLongSparseArray;
@@ -868,4 +869,28 @@
return super.getSharedUserPackages(sharedUserAppId);
}
}
+
+ @NonNull
+ @Override
+ public ComponentResolverApi getComponentResolver() {
+ synchronized (mLock) {
+ return super.getComponentResolver();
+ }
+ }
+
+ @Nullable
+ @Override
+ public PackageStateInternal getDisabledSystemPackage(@NonNull String packageName) {
+ synchronized (mLock) {
+ return super.getDisabledSystemPackage(packageName);
+ }
+ }
+
+ @Nullable
+ @Override
+ public ResolveInfo getInstantAppInstallerInfo() {
+ synchronized (mLock) {
+ return super.getInstantAppInstallerInfo();
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/ComputerTracker.java b/services/core/java/com/android/server/pm/ComputerTracker.java
index 72e67da..216ad71 100644
--- a/services/core/java/com/android/server/pm/ComputerTracker.java
+++ b/services/core/java/com/android/server/pm/ComputerTracker.java
@@ -49,6 +49,7 @@
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.SharedUserApi;
+import com.android.server.pm.resolution.ComponentResolverApi;
import com.android.server.utils.WatchedArrayMap;
import com.android.server.utils.WatchedLongSparseArray;
@@ -1299,4 +1300,28 @@
return current.mComputer.getSharedUserPackages(sharedUserAppId);
}
}
+
+ @NonNull
+ @Override
+ public ComponentResolverApi getComponentResolver() {
+ try (ThreadComputer current = snapshot()) {
+ return current.mComputer.getComponentResolver();
+ }
+ }
+
+ @Nullable
+ @Override
+ public PackageStateInternal getDisabledSystemPackage(@NonNull String packageName) {
+ try (ThreadComputer current = snapshot()) {
+ return current.mComputer.getDisabledSystemPackage(packageName);
+ }
+ }
+
+ @Nullable
+ @Override
+ public ResolveInfo getInstantAppInstallerInfo() {
+ try (ThreadComputer current = snapshot()) {
+ return current.mComputer.getInstantAppInstallerInfo();
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/DumpHelper.java b/services/core/java/com/android/server/pm/DumpHelper.java
index d5a882b..2b46ed4 100644
--- a/services/core/java/com/android/server/pm/DumpHelper.java
+++ b/services/core/java/com/android/server/pm/DumpHelper.java
@@ -405,7 +405,8 @@
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
- mPm.mComponentResolver.dumpContentProviders(pw, dumpState, packageName);
+ mPm.mComponentResolver.dumpContentProviders(mPm.snapshotComputer(), pw, dumpState,
+ packageName);
}
if (!checkin
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 2ef092e..234a230 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -36,6 +36,7 @@
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
+import static android.content.pm.PackageManagerInternal.PACKAGE_SETUP_WIZARD;
import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile;
import static android.os.PowerExemptionManager.REASON_PACKAGE_REPLACED;
@@ -454,7 +455,8 @@
KeySetManagerService ksms = mPm.mSettings.getKeySetManagerService();
ksms.addScannedPackageLPw(pkg);
- mPm.mComponentResolver.addAllComponents(pkg, chatty);
+ mPm.mComponentResolver.addAllComponents(pkg, chatty, mPm.mSetupWizardPackage,
+ mPm.snapshotComputer());
mPm.mAppsFilter.addPackage(pkgSetting, isReplace);
mPm.addAllPackageProperties(pkg);
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index 79f8dc1..92d6a82 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -57,6 +57,7 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.server.pm.InstantAppResolverConnection.ConnectionException;
import com.android.server.pm.InstantAppResolverConnection.PhaseTwoCallback;
+import com.android.server.pm.resolution.ComponentResolver;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -134,8 +135,9 @@
}
}
- public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(
- InstantAppResolverConnection connection, InstantAppRequest requestObj) {
+ public static AuxiliaryResolveInfo doInstantAppResolutionPhaseOne(@NonNull Computer computer,
+ @NonNull UserManagerService userManager, InstantAppResolverConnection connection,
+ InstantAppRequest requestObj) {
final long startTime = System.currentTimeMillis();
final String token = requestObj.token;
if (DEBUG_INSTANT) {
@@ -149,7 +151,7 @@
final List<InstantAppResolveInfo> instantAppResolveInfoList =
connection.getInstantAppResolveInfoList(buildRequestInfo(requestObj));
if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
- resolveInfo = InstantAppResolver.filterInstantAppIntent(
+ resolveInfo = InstantAppResolver.filterInstantAppIntent(computer, userManager,
instantAppResolveInfoList, origIntent, requestObj.resolvedType,
requestObj.userId, origIntent.getPackage(), token,
requestObj.hostDigestPrefixSecure);
@@ -187,9 +189,10 @@
return resolveInfo;
}
- public static void doInstantAppResolutionPhaseTwo(Context context,
- InstantAppResolverConnection connection, InstantAppRequest requestObj,
- ActivityInfo instantAppInstaller, Handler callbackHandler) {
+ public static void doInstantAppResolutionPhaseTwo(Context context, @NonNull Computer computer,
+ @NonNull UserManagerService userManager, InstantAppResolverConnection connection,
+ InstantAppRequest requestObj, ActivityInfo instantAppInstaller,
+ Handler callbackHandler) {
final long startTime = System.currentTimeMillis();
final String token = requestObj.token;
if (DEBUG_INSTANT) {
@@ -205,7 +208,7 @@
final Intent failureIntent;
if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
final AuxiliaryResolveInfo instantAppIntentInfo =
- InstantAppResolver.filterInstantAppIntent(
+ InstantAppResolver.filterInstantAppIntent(computer, userManager,
instantAppResolveInfoList, origIntent, null /*resolvedType*/,
0 /*userId*/, origIntent.getPackage(),
token, requestObj.hostDigestPrefixSecure);
@@ -386,7 +389,8 @@
);
}
- private static AuxiliaryResolveInfo filterInstantAppIntent(
+ private static AuxiliaryResolveInfo filterInstantAppIntent(@NonNull Computer computer,
+ @NonNull UserManagerService userManager,
List<InstantAppResolveInfo> instantAppResolveInfoList, Intent origIntent,
String resolvedType, int userId, String packageName, String token,
int[] hostDigestPrefixSecure) {
@@ -421,7 +425,8 @@
}
// We matched a resolve info; resolve the filters to see if anything matches completely.
List<AuxiliaryResolveInfo.AuxiliaryFilter> matchFilters = computeResolveFilters(
- origIntent, resolvedType, userId, packageName, token, instantAppResolveInfo);
+ computer, userManager, origIntent, resolvedType, userId, packageName, token,
+ instantAppResolveInfo);
if (matchFilters != null) {
if (matchFilters.isEmpty()) {
requiresSecondPhase = true;
@@ -464,7 +469,8 @@
*
*/
private static List<AuxiliaryResolveInfo.AuxiliaryFilter> computeResolveFilters(
- Intent origIntent, String resolvedType, int userId, String packageName, String token,
+ @NonNull Computer computer, @NonNull UserManagerService userManager, Intent origIntent,
+ String resolvedType, int userId, String packageName, String token,
InstantAppResolveInfo instantAppInfo) {
if (instantAppInfo.shouldLetInstallerDecide()) {
return Collections.singletonList(
@@ -490,7 +496,7 @@
return Collections.emptyList();
}
final ComponentResolver.InstantAppIntentResolver instantAppResolver =
- new ComponentResolver.InstantAppIntentResolver();
+ new ComponentResolver.InstantAppIntentResolver(userManager);
for (int j = instantAppFilters.size() - 1; j >= 0; --j) {
final InstantAppIntentFilter instantAppFilter = instantAppFilters.get(j);
final List<IntentFilter> splitFilters = instantAppFilter.getFilters();
@@ -508,7 +514,7 @@
&& filter.hasCategory(Intent.CATEGORY_BROWSABLE)) {
continue;
}
- instantAppResolver.addFilter(
+ instantAppResolver.addFilter(computer,
new AuxiliaryResolveInfo.AuxiliaryFilter(
filter,
instantAppInfo,
@@ -518,8 +524,8 @@
}
}
List<AuxiliaryResolveInfo.AuxiliaryFilter> matchedResolveInfoList =
- instantAppResolver.queryIntent(
- origIntent, resolvedType, false /*defaultOnly*/, userId);
+ instantAppResolver.queryIntent(computer, origIntent, resolvedType,
+ false /*defaultOnly*/, userId);
if (!matchedResolveInfoList.isEmpty()) {
if (DEBUG_INSTANT) {
Log.d(TAG, "[" + token + "] Found match(es); " + matchedResolveInfoList);
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index ec71940..46e2aa3 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -313,6 +313,8 @@
}
case INSTANT_APP_RESOLUTION_PHASE_TWO: {
InstantAppResolver.doInstantAppResolutionPhaseTwo(mPm.mContext,
+ mPm.snapshotComputer(),
+ mPm.mUserManager,
mPm.mInstantAppResolverConnection,
(InstantAppRequest) msg.obj,
mPm.mInstantAppInstallerActivity,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 725e92a..0b7a6a7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -111,7 +111,6 @@
import android.content.pm.PackageManager.Property;
import android.content.pm.PackageManager.PropertyLocation;
import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageManagerInternal.PrivateResolveFlags;
import android.content.pm.PackagePartitions;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
@@ -242,6 +241,8 @@
import com.android.server.pm.pkg.mutate.PackageStateWrite;
import com.android.server.pm.pkg.mutate.PackageUserStateWrite;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
+import com.android.server.pm.resolution.ComponentResolver;
+import com.android.server.pm.resolution.ComponentResolverApi;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import com.android.server.pm.verify.domain.DomainVerificationService;
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy;
@@ -791,9 +792,6 @@
private final AtomicInteger mNextMoveId = new AtomicInteger();
final MovePackageHelper.MoveCallbacks mMoveCallbacks;
- // Cache of users who need badging.
- private final SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
-
/**
* Token for keys in mPendingVerification.
* Handler thread only!
@@ -912,6 +910,8 @@
final UserManagerService mUserManager;
+ final UserNeedsBadgingCache mUserNeedsBadging;
+
// Stores a list of users whose package restrictions file needs to be updated
final ArraySet<Integer> mDirtyUsers = new ArraySet<>();
@@ -992,7 +992,7 @@
public final ApplicationInfo androidApplication;
public final String appPredictionServicePackage;
public final AppsFilter appsFilter;
- public final ComponentResolver componentResolver;
+ public final ComponentResolverApi componentResolver;
public final PackageManagerService service;
public final WatchedArrayMap<String, Integer> frozenPackages;
public final SharedLibrariesRead sharedLibraries;
@@ -1081,17 +1081,10 @@
private final SnapshotStatistics mSnapshotStatistics;
/**
- * Return the live computer.
- */
- Computer liveComputer() {
- return mLiveComputer;
- }
-
- /**
* Return the cached computer. The method will rebuild the cached computer if necessary.
* The live computer will be returned if snapshots are disabled.
*/
- Computer snapshotComputer() {
+ public Computer snapshotComputer() {
if (Thread.holdsLock(mLock)) {
// If the current thread holds mLock then it may have modified state but not
// yet invalidated the snapshot. Always give the thread the live computer.
@@ -1171,8 +1164,8 @@
@Override
public void notifyPackagesReplacedReceived(String[] packages) {
- ArraySet<String> packagesToNotify =
- mComputer.getNotifyPackagesForReplacedReceived(packages);
+ Computer computer = snapshotComputer();
+ ArraySet<String> packagesToNotify = computer.getNotifyPackagesForReplacedReceived(packages);
for (int index = 0; index < packagesToNotify.size(); index++) {
notifyInstallObserver(packagesToNotify.valueAt(index));
}
@@ -1441,7 +1434,7 @@
context, lock, installer, installLock, new PackageAbiHelperImpl(),
backgroundHandler,
SYSTEM_PARTITIONS,
- (i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock),
+ (i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mUserNeedsBadging),
(i, pm) -> PermissionManagerService.create(context,
i.getSystemConfig().getAvailableFeatures()),
(i, pm) -> new UserManagerService(context, pm,
@@ -1619,6 +1612,7 @@
mPermissionManager = injector.getPermissionManagerServiceInternal();
mSettings = injector.getSettings();
mUserManager = injector.getUserManagerService();
+ mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager);
mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
mHandler = injector.getHandler();
mSharedLibraries = injector.getSharedLibrariesImpl();
@@ -1744,6 +1738,7 @@
mTestUtilityService = LocalServices.getService(TestUtilityService.class);
LocalServices.addService(PackageManagerInternal.class, mPmInternal);
mUserManager = injector.getUserManagerService();
+ mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager);
mComponentResolver = injector.getComponentResolver();
mPermissionManager = injector.getPermissionManagerServiceInternal();
mSettings = injector.getSettings();
@@ -1846,7 +1841,9 @@
mAppDataHelper);
mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper);
mPreferredActivityHelper = new PreferredActivityHelper(this);
- mResolveIntentHelper = new ResolveIntentHelper(this, mPreferredActivityHelper);
+ mResolveIntentHelper = new ResolveIntentHelper(mContext, mPreferredActivityHelper,
+ injector.getCompatibility(), mUserManager, mDomainVerificationManager,
+ mUserNeedsBadging, () -> mResolveInfo, () -> mInstantAppInstallerActivity);
mDexOptHelper = new DexOptHelper(this);
mSuspendPackageHelper = new SuspendPackageHelper(this, mInjector, mBroadcastHelper,
mProtectedPackages);
@@ -1862,6 +1859,7 @@
registerObservers(true);
}
+ Computer computer = mLiveComputer;
// CHECKSTYLE:OFF IndentationCheck
synchronized (mInstallLock) {
// writer
@@ -1975,12 +1973,12 @@
userIds, startTime);
// Resolve the storage manager.
- mStorageManagerPackage = getStorageManagerPackageName();
+ mStorageManagerPackage = getStorageManagerPackageName(computer);
// Resolve protected action filters. Only the setup wizard is allowed to
// have a high priority filter for these actions.
- mSetupWizardPackage = getSetupWizardPackageNameImpl();
- mComponentResolver.fixProtectedFilterPriorities();
+ mSetupWizardPackage = getSetupWizardPackageNameImpl(computer);
+ mComponentResolver.fixProtectedFilterPriorities(mPmInternal.getSetupWizardPackageName());
mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
@@ -2108,13 +2106,13 @@
SystemClock.uptimeMillis());
if (!mOnlyCore) {
- mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
- mRequiredInstallerPackage = getRequiredInstallerLPr();
- mRequiredUninstallerPackage = getRequiredUninstallerLPr();
+ mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(computer);
+ mRequiredInstallerPackage = getRequiredInstallerLPr(computer);
+ mRequiredUninstallerPackage = getRequiredUninstallerLPr(computer);
ComponentName intentFilterVerifierComponent =
- getIntentFilterVerifierComponentNameLPr();
+ getIntentFilterVerifierComponentNameLPr(computer);
ComponentName domainVerificationAgent =
- getDomainVerificationAgentComponentNameLPr();
+ getDomainVerificationAgentComponentNameLPr(computer);
DomainVerificationProxy domainVerificationProxy = DomainVerificationProxy.makeProxy(
intentFilterVerifierComponent, domainVerificationAgent, mContext,
@@ -2137,7 +2135,7 @@
// PermissionController hosts default permission granting and role management, so it's a
// critical part of the core system.
- mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
+ mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr(computer);
mSettings.setPermissionControllerVersion(
getPackageInfo(mRequiredPermissionControllerPackage, 0,
@@ -2170,7 +2168,8 @@
mInstantAppResolverConnection =
mInjector.getInstantAppResolverConnection(instantAppResolverComponent);
mInstantAppResolverSettingsComponent =
- getInstantAppResolverSettingsLPr(instantAppResolverComponent);
+ getInstantAppResolverSettingsLPr(computer,
+ instantAppResolverComponent);
} else {
mInstantAppResolverConnection = null;
mInstantAppResolverSettingsComponent = null;
@@ -2258,11 +2257,13 @@
"persist.pm.mock-upgrade", false /* default */);
}
- private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
+ @Nullable
+ private String getRequiredButNotReallyRequiredVerifierLPr(@NonNull Computer computer) {
final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
final List<ResolveInfo> matches =
- mResolveIntentHelper.queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
+ mResolveIntentHelper.queryIntentReceiversInternal(computer, intent,
+ PACKAGE_MIME_TYPE,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
UserHandle.USER_SYSTEM, Binder.getCallingUid());
if (matches.size() == 1) {
@@ -2300,12 +2301,13 @@
return servicesExtensionPackage;
}
- private @NonNull String getRequiredInstallerLPr() {
+ private @NonNull String getRequiredInstallerLPr(@NonNull Computer computer) {
final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE);
- final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
+ final List<ResolveInfo> matches = computer.queryIntentActivitiesInternal(intent,
+ PACKAGE_MIME_TYPE,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
UserHandle.USER_SYSTEM);
if (matches.size() == 1) {
@@ -2319,14 +2321,14 @@
}
}
- private @NonNull String getRequiredUninstallerLPr() {
+ private @NonNull String getRequiredUninstallerLPr(@NonNull Computer computer) {
final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
- final ResolveInfo resolveInfo = resolveIntent(intent, null,
- MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
- UserHandle.USER_SYSTEM);
+ final ResolveInfo resolveInfo = mResolveIntentHelper.resolveIntentInternal(computer, intent,
+ null, MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
+ 0 /*privateResolveFlags*/, UserHandle.USER_SYSTEM, false, Binder.getCallingUid());
if (resolveInfo == null ||
mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
throw new RuntimeException("There must be exactly one uninstaller; found "
@@ -2335,11 +2337,11 @@
return resolveInfo.getComponentInfo().packageName;
}
- private @NonNull String getRequiredPermissionControllerLPr() {
+ private @NonNull String getRequiredPermissionControllerLPr(@NonNull Computer computer) {
final Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSIONS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
- final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
+ final List<ResolveInfo> matches = computer.queryIntentActivitiesInternal(intent, null,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
UserHandle.USER_SYSTEM);
if (matches.size() == 1) {
@@ -2354,11 +2356,13 @@
}
}
- private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
+ @NonNull
+ private ComponentName getIntentFilterVerifierComponentNameLPr(@NonNull Computer computer) {
final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
final List<ResolveInfo> matches =
- mResolveIntentHelper.queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
+ mResolveIntentHelper.queryIntentReceiversInternal(computer, intent,
+ PACKAGE_MIME_TYPE,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
UserHandle.USER_SYSTEM, Binder.getCallingUid());
ResolveInfo best = null;
@@ -2384,10 +2388,10 @@
}
@Nullable
- private ComponentName getDomainVerificationAgentComponentNameLPr() {
+ private ComponentName getDomainVerificationAgentComponentNameLPr(@NonNull Computer computer) {
Intent intent = new Intent(Intent.ACTION_DOMAINS_NEED_VERIFICATION);
List<ResolveInfo> matches =
- mResolveIntentHelper.queryIntentReceiversInternal(intent, null,
+ mResolveIntentHelper.queryIntentReceiversInternal(computer, intent, null,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
UserHandle.USER_SYSTEM, Binder.getCallingUid());
ResolveInfo best = null;
@@ -2496,13 +2500,14 @@
| MATCH_DIRECT_BOOT_UNAWARE
| Intent.FLAG_IGNORE_EPHEMERAL
| (mIsEngBuild ? 0 : MATCH_SYSTEM_ONLY);
+ final Computer computer = snapshotComputer();
final Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
List<ResolveInfo> matches = null;
for (String action : orderedActions) {
intent.setAction(action);
- matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
+ matches = computer.queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
resolveFlags, UserHandle.USER_SYSTEM);
if (matches.isEmpty()) {
if (DEBUG_INSTANT) {
@@ -2532,14 +2537,14 @@
}
}
- private @Nullable ComponentName getInstantAppResolverSettingsLPr(
+ private @Nullable ComponentName getInstantAppResolverSettingsLPr(@NonNull Computer computer,
@NonNull ComponentName resolver) {
final Intent intent = new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
.addCategory(Intent.CATEGORY_DEFAULT)
.setPackage(resolver.getPackageName());
final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
- List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
- UserHandle.USER_SYSTEM);
+ List<ResolveInfo> matches = computer.queryIntentActivitiesInternal(intent, null,
+ resolveFlags, UserHandle.USER_SYSTEM);
if (matches.isEmpty()) {
return null;
}
@@ -2942,27 +2947,6 @@
}
/**
- * Update given flags when being used to request {@link PackageInfo}.
- */
- private long updateFlagsForPackage(long flags, int userId) {
- return mComputer.updateFlagsForPackage(flags, userId);
- }
-
- /**
- * Update given flags when being used to request {@link ApplicationInfo}.
- */
- private long updateFlagsForApplication(long flags, int userId) {
- return mComputer.updateFlagsForApplication(flags, userId);
- }
-
- /**
- * Update given flags when being used to request {@link ComponentInfo}.
- */
- private long updateFlagsForComponent(long flags, int userId) {
- return mComputer.updateFlagsForComponent(flags, userId);
- }
-
- /**
* Update given flags when being used to request {@link ResolveInfo}.
* <p>Instant apps are resolved specially, depending upon context. Minimally,
* {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
@@ -3314,8 +3298,8 @@
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
@PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- return mResolveIntentHelper.resolveIntentInternal(intent, resolvedType, flags,
- 0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid());
+ return mResolveIntentHelper.resolveIntentInternal(snapshotComputer(), intent, resolvedType,
+ flags, 0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid());
}
@Override
@@ -3414,8 +3398,8 @@
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
- return new ParceledListSlice<>(
- queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
+ return new ParceledListSlice<>(snapshotComputer().queryIntentActivitiesInternal(intent,
+ resolvedType, flags, userId));
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
@@ -3429,68 +3413,28 @@
return mComputer.getInstantAppPackageName(callingUid);
}
- @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
- String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- return mComputer.queryIntentActivitiesInternal(intent,
- resolvedType, flags, userId);
- }
-
- @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
- String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
- @PrivateResolveFlags long privateResolveFlags, int filterCallingUid, int userId,
- boolean resolveForStart, boolean allowDynamicSplits) {
- return mComputer.queryIntentActivitiesInternal(intent,
- resolvedType, flags, privateResolveFlags,
- filterCallingUid, userId, resolveForStart, allowDynamicSplits);
- }
-
- private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
- String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int sourceUserId,
- int parentUserId) {
- return mComputer.getCrossProfileDomainPreferredLpr(intent,
- resolvedType, flags, sourceUserId, parentUserId);
- }
-
- /**
- * Filters out ephemeral activities.
- * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
- * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
- *
- * @param resolveInfos The pre-filtered list of resolved activities
- * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
- * is performed.
- * @param intent
- * @return A filtered list of resolved activities.
- */
- List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
- String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
- boolean resolveForStart, int userId, Intent intent) {
- return mComputer.applyPostResolutionFilter(resolveInfos,
- ephemeralPkgName, allowDynamicSplits, filterCallingUid,
- resolveForStart, userId, intent);
- }
-
@Override
public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
Intent[] specifics, String[] specificTypes, Intent intent,
String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
return new ParceledListSlice<>(mResolveIntentHelper.queryIntentActivityOptionsInternal(
- caller, specifics, specificTypes, intent, resolvedType, flags, userId));
+ snapshotComputer(), caller, specifics, specificTypes, intent, resolvedType, flags,
+ userId));
}
@Override
public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal(intent,
- resolvedType, flags, userId, Binder.getCallingUid()));
+ return new ParceledListSlice<>(mResolveIntentHelper.queryIntentReceiversInternal(
+ snapshotComputer(), intent, resolvedType, flags, userId, Binder.getCallingUid()));
}
@Override
public ResolveInfo resolveService(Intent intent, String resolvedType,
@PackageManager.ResolveInfoFlagsBits long flags, int userId) {
final int callingUid = Binder.getCallingUid();
- return mResolveIntentHelper.resolveServiceInternal(intent, resolvedType, flags, userId,
- callingUid);
+ return mResolveIntentHelper.resolveServiceInternal(snapshotComputer(), intent, resolvedType,
+ flags, userId, callingUid);
}
@Override
@@ -3513,7 +3457,7 @@
public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
return new ParceledListSlice<>(mResolveIntentHelper.queryIntentContentProvidersInternal(
- intent, resolvedType, flags, userId));
+ snapshotComputer(), intent, resolvedType, flags, userId));
}
@Override
@@ -3907,15 +3851,9 @@
synchronized (mLock) {
mPackageUsage.writeNow(mSettings.getPackagesLocked());
- // This is the last chance to write out pending restriction settings
- if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
- mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
- synchronized (mDirtyUsers) {
- for (int userId : mDirtyUsers) {
- mSettings.writePackageRestrictionsLPr(userId);
- }
- mDirtyUsers.clear();
- }
+ if (mHandler.hasMessages(WRITE_SETTINGS)) {
+ mHandler.removeMessages(WRITE_SETTINGS);
+ writeSettings();
}
}
}
@@ -5409,7 +5347,7 @@
}
}
}
- resolver.addFilter(newFilter);
+ resolver.addFilter(snapshotComputer(), newFilter);
}
scheduleWritePackageRestrictions(sourceUserId);
}
@@ -5498,11 +5436,11 @@
mPreferredActivityHelper.setHomeActivity(comp, userId);
}
- private @Nullable String getSetupWizardPackageNameImpl() {
+ private @Nullable String getSetupWizardPackageNameImpl(@NonNull Computer computer) {
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
- final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
+ final List<ResolveInfo> matches = computer.queryIntentActivitiesInternal(intent, null,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
| MATCH_DISABLED_COMPONENTS,
UserHandle.myUserId());
@@ -5515,10 +5453,10 @@
}
}
- private @Nullable String getStorageManagerPackageName() {
+ private @Nullable String getStorageManagerPackageName(@NonNull Computer computer) {
final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
- final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
+ final List<ResolveInfo> matches = computer.queryIntentActivitiesInternal(intent, null,
MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
| MATCH_DISABLED_COMPONENTS,
UserHandle.myUserId());
@@ -6784,21 +6722,7 @@
}
boolean userNeedsBadging(int userId) {
- int index = mUserNeedsBadging.indexOfKey(userId);
- if (index < 0) {
- final UserInfo userInfo;
- final long token = Binder.clearCallingIdentity();
- try {
- userInfo = mUserManager.getUserInfo(userId);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- final boolean b;
- b = userInfo != null && userInfo.isManagedProfile();
- mUserNeedsBadging.put(userId, b);
- return b;
- }
- return mUserNeedsBadging.valueAt(index);
+ return mUserNeedsBadging.get(userId);
}
@Nullable
@@ -7034,16 +6958,14 @@
}
@Override
- public PackageSetting getDisabledSystemPackage(@NonNull String packageName) {
- synchronized (mLock) {
- return mSettings.getDisabledSystemPkgLPr(packageName);
- }
+ public PackageStateInternal getDisabledSystemPackage(@NonNull String packageName) {
+ return snapshotComputer().getDisabledSystemPackage(packageName);
}
@Override
public @Nullable
String getDisabledSystemPackageName(@NonNull String packageName) {
- PackageSetting disabledPkgSetting = getDisabledSystemPackage(
+ PackageStateInternal disabledPkgSetting = getDisabledSystemPackage(
packageName);
AndroidPackage disabledPkg = disabledPkgSetting == null
? null : disabledPkgSetting.getPkg();
@@ -7183,9 +7105,8 @@
public List<ResolveInfo> queryIntentActivities(
Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
int filterCallingUid, int userId) {
- return PackageManagerService.this
- .queryIntentActivitiesInternal(intent, resolvedType, flags, 0, filterCallingUid,
- userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
+ return snapshotComputer().queryIntentActivitiesInternal(intent, resolvedType, flags,
+ userId);
}
@Override
@@ -7193,7 +7114,7 @@
String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
int filterCallingUid, int userId) {
return PackageManagerService.this.mResolveIntentHelper.queryIntentReceiversInternal(
- intent, resolvedType, flags, userId, filterCallingUid);
+ snapshotComputer(), intent, resolvedType, flags, userId, filterCallingUid);
}
@Override
@@ -7436,7 +7357,7 @@
@PackageManager.ResolveInfoFlagsBits long flags,
@PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
boolean resolveForStart, int filterCallingUid) {
- return mResolveIntentHelper.resolveIntentInternal(
+ return mResolveIntentHelper.resolveIntentInternal(snapshotComputer(),
intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
filterCallingUid);
}
@@ -7444,8 +7365,8 @@
@Override
public ResolveInfo resolveService(Intent intent, String resolvedType,
@PackageManager.ResolveInfoFlagsBits long flags, int userId, int callingUid) {
- return mResolveIntentHelper.resolveServiceInternal(intent, resolvedType, flags, userId,
- callingUid);
+ return mResolveIntentHelper.resolveServiceInternal(snapshotComputer(), intent,
+ resolvedType, flags, userId, callingUid);
}
@Override
@@ -7900,6 +7821,12 @@
@NonNull Consumer<PackageStateMutator> consumer) {
return PackageManagerService.this.commitPackageStateMutation(state, consumer);
}
+
+ @NonNull
+ @Override
+ public Computer snapshot() {
+ return snapshotComputer();
+ }
}
private boolean setEnabledOverlayPackages(@UserIdInt int userId,
@@ -8346,16 +8273,6 @@
}
}
- private void applyMimeGroupChanges(String packageName, String mimeGroup) {
- if (mComponentResolver.updateMimeGroup(packageName, mimeGroup)) {
- Binder.withCleanCallingIdentity(() ->
- mPreferredActivityHelper.clearPackagePreferredActivities(packageName,
- UserHandle.USER_ALL));
- }
-
- mPmInternal.writeSettings(false);
- }
-
@Override
public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
enforceOwnerRights(packageName, Binder.getCallingUid());
@@ -8375,7 +8292,13 @@
commitPackageStateMutation(null, packageName, packageStateWrite -> {
packageStateWrite.setMimeGroup(mimeGroup, mimeTypesSet);
});
- applyMimeGroupChanges(packageName, mimeGroup);
+ if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) {
+ Binder.withCleanCallingIdentity(() ->
+ mPreferredActivityHelper.clearPackagePreferredActivities(packageName,
+ UserHandle.USER_ALL));
+ }
+
+ scheduleWriteSettings();
}
@Override
@@ -8607,8 +8530,8 @@
@Override
public IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage,
String featureId, int userId) throws RemoteException {
- return mResolveIntentHelper.getLaunchIntentSenderForPackage(packageName, callingPackage,
- featureId, userId);
+ return mResolveIntentHelper.getLaunchIntentSenderForPackage(snapshotComputer(),
+ packageName, callingPackage, featureId, userId);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
index 05bb01e..a02237f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
@@ -34,6 +34,7 @@
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.permission.LegacyPermissionManagerInternal;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.resolution.ComponentResolver;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import java.util.List;
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 2f56bfe..a9471cf 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -93,6 +93,7 @@
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.component.ParsedMainComponent;
+import com.android.server.pm.resolution.ComponentResolverApi;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import dalvik.system.VMRuntime;
@@ -1064,7 +1065,7 @@
// Static to give access to ComputeEngine
public static void applyEnforceIntentFilterMatching(
- PlatformCompat compat, ComponentResolver resolver,
+ PlatformCompat compat, ComponentResolverApi resolver,
List<ResolveInfo> resolveInfos, boolean isReceiver,
Intent intent, String resolvedType, int filterCallingUid) {
// Do not enforce filter matching when the caller is system or root.
diff --git a/services/core/java/com/android/server/pm/PreferredActivityHelper.java b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
index bb82e6a..8c49baf 100644
--- a/services/core/java/com/android/server/pm/PreferredActivityHelper.java
+++ b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
@@ -140,8 +140,8 @@
return false;
}
final Intent intent = mPm.getHomeIntent();
- final List<ResolveInfo> resolveInfos = mPm.queryIntentActivitiesInternal(intent, null,
- MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
+ final List<ResolveInfo> resolveInfos = mPm.snapshotComputer().queryIntentActivitiesInternal(
+ intent, null, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
intent, null, 0, resolveInfos, true, false, false, userId);
final String packageName = preferredResolveInfo != null
@@ -209,7 +209,8 @@
if (removeExisting && existing != null) {
Settings.removeFilters(pir, filter, existing);
}
- pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
+ pir.addFilter(mPm.snapshotComputer(),
+ new PreferredActivity(filter, match, set, activity, always));
mPm.scheduleWritePackageRestrictions(userId);
}
if (!(isHomeFilter(filter) && updateDefaultHomeNotLocked(userId))) {
@@ -394,6 +395,7 @@
}
synchronized (mPm.mLock) {
mPm.mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
+ mPm.snapshotComputer(),
new PersistentPreferredActivity(filter, activity, true));
mPm.scheduleWritePackageRestrictions(userId);
}
@@ -672,8 +674,8 @@
0, userId, callingUid, false /*includeInstantApps*/,
mPm.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
0));
- final List<ResolveInfo> query = mPm.queryIntentActivitiesInternal(intent, resolvedType,
- flags, userId);
+ final List<ResolveInfo> query = mPm.snapshotComputer().queryIntentActivitiesInternal(intent,
+ resolvedType, flags, userId);
synchronized (mPm.mLock) {
return mPm.findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
userId);
@@ -699,8 +701,8 @@
filter.dump(new PrintStreamPrinter(System.out), " ");
}
intent.setComponent(null);
- final List<ResolveInfo> query = mPm.queryIntentActivitiesInternal(intent, resolvedType,
- flags, userId);
+ final List<ResolveInfo> query = mPm.snapshotComputer().queryIntentActivitiesInternal(intent,
+ resolvedType, flags, userId);
// Find any earlier preferred or last chosen entries and nuke them
findPreferredActivityNotLocked(
intent, resolvedType, flags, query, false, true, false, userId);
@@ -715,8 +717,8 @@
}
final int userId = UserHandle.getCallingUserId();
if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
- final List<ResolveInfo> query = mPm.queryIntentActivitiesInternal(intent, resolvedType,
- flags, userId);
+ final List<ResolveInfo> query = mPm.snapshotComputer().queryIntentActivitiesInternal(intent,
+ resolvedType, flags, userId);
return findPreferredActivityNotLocked(
intent, resolvedType, flags, query, false, false, false, userId);
}
diff --git a/services/core/java/com/android/server/pm/ResolveIntentHelper.java b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
index 2aff90f..25356a4 100644
--- a/services/core/java/com/android/server/pm/ResolveIntentHelper.java
+++ b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
@@ -27,6 +27,8 @@
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentFilter;
@@ -50,23 +52,52 @@
import com.android.internal.app.ResolverActivity;
import com.android.internal.util.ArrayUtils;
+import com.android.server.compat.PlatformCompat;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.resolution.ComponentResolverApi;
+import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
+import java.util.function.Supplier;
final class ResolveIntentHelper {
- private final PackageManagerService mPm;
+ @NonNull
+ private final Context mContext;
+ @NonNull
+ private final PlatformCompat mPlatformCompat;
+ @NonNull
+ private final UserManagerService mUserManager;
+ @NonNull
private final PreferredActivityHelper mPreferredActivityHelper;
+ @NonNull
+ private final DomainVerificationManagerInternal mDomainVerificationManager;
+ @NonNull
+ private final UserNeedsBadgingCache mUserNeedsBadging;
+ @NonNull
+ private final Supplier<ResolveInfo> mResolveInfoSupplier;
+ @NonNull
+ private final Supplier<ActivityInfo> mInstantAppInstallerActivitySupplier;
- // TODO(b/198166813): remove PMS dependency
- ResolveIntentHelper(PackageManagerService pm, PreferredActivityHelper preferredActivityHelper) {
- mPm = pm;
+ ResolveIntentHelper(@NonNull Context context,
+ @NonNull PreferredActivityHelper preferredActivityHelper,
+ @NonNull PlatformCompat platformCompat, @NonNull UserManagerService userManager,
+ @NonNull DomainVerificationManagerInternal domainVerificationManager,
+ @NonNull UserNeedsBadgingCache userNeedsBadgingCache,
+ @NonNull Supplier<ResolveInfo> resolveInfoSupplier,
+ @NonNull Supplier<ActivityInfo> instantAppInstallerActivitySupplier) {
+ mContext = context;
mPreferredActivityHelper = preferredActivityHelper;
+ mPlatformCompat = platformCompat;
+ mUserManager = userManager;
+ mDomainVerificationManager = domainVerificationManager;
+ mUserNeedsBadging = userNeedsBadgingCache;
+ mResolveInfoSupplier = resolveInfoSupplier;
+ mInstantAppInstallerActivitySupplier = instantAppInstallerActivitySupplier;
}
/**
@@ -74,35 +105,33 @@
* However, if {@code resolveForStart} is {@code true}, all instant apps are visible
* since we need to allow the system to start any installed application.
*/
- public ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
+ public ResolveInfo resolveIntentInternal(Computer computer, Intent intent, String resolvedType,
@PackageManager.ResolveInfoFlagsBits long flags,
@PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
boolean resolveForStart, int filterCallingUid) {
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
- if (!mPm.mUserManager.exists(userId)) return null;
+ if (!mUserManager.exists(userId)) return null;
final int callingUid = Binder.getCallingUid();
- flags = mPm.updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
- mPm.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
+ flags = computer.updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
+ computer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
resolvedType, flags));
- mPm.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
+ computer.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
false /*checkShell*/, "resolve intent");
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
- final List<ResolveInfo> query = mPm.queryIntentActivitiesInternal(intent, resolvedType,
- flags, privateResolveFlags, filterCallingUid, userId, resolveForStart,
- true /*allowDynamicSplits*/);
+ final List<ResolveInfo> query = computer.queryIntentActivitiesInternal(intent,
+ resolvedType, flags, privateResolveFlags, filterCallingUid, userId,
+ resolveForStart, true /*allowDynamicSplits*/);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
final boolean queryMayBeFiltered =
UserHandle.getAppId(filterCallingUid) >= Process.FIRST_APPLICATION_UID
&& !resolveForStart;
- final ResolveInfo bestChoice =
- chooseBestActivity(
- intent, resolvedType, flags, privateResolveFlags, query, userId,
- queryMayBeFiltered);
+ final ResolveInfo bestChoice = chooseBestActivity(computer, intent, resolvedType, flags,
+ privateResolveFlags, query, userId, queryMayBeFiltered);
final boolean nonBrowserOnly =
(privateResolveFlags & PackageManagerInternal.RESOLVE_NON_BROWSER_ONLY) != 0;
if (nonBrowserOnly && bestChoice != null && bestChoice.handleAllWebDataURI) {
@@ -114,7 +143,7 @@
}
}
- private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
+ private ResolveInfo chooseBestActivity(Computer computer, Intent intent, String resolvedType,
@PackageManager.ResolveInfoFlagsBits long flags,
@PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
List<ResolveInfo> query, int userId, boolean queryMayBeFiltered) {
@@ -156,9 +185,10 @@
// If we have an ephemeral app, use it
if (ri.activityInfo.applicationInfo.isInstantApp()) {
final String packageName = ri.activityInfo.packageName;
- final PackageStateInternal ps = mPm.getPackageStateInternal(packageName);
+ final PackageStateInternal ps =
+ computer.getPackageStateInternal(packageName);
if (ps != null && PackageManagerServiceUtils.hasAnyDomainApproval(
- mPm.mDomainVerificationManager, ps, intent, flags, userId)) {
+ mDomainVerificationManager, ps, intent, flags, userId)) {
return ri;
}
}
@@ -167,7 +197,7 @@
& PackageManagerInternal.RESOLVE_NON_RESOLVER_ONLY) != 0) {
return null;
}
- ri = new ResolveInfo(mPm.getResolveInfo());
+ ri = new ResolveInfo(mResolveInfoSupplier.get());
// if all resolve options are browsers, mark the resolver's info as if it were
// also a browser.
ri.handleAllWebDataURI = browserCount == n;
@@ -184,7 +214,7 @@
if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
ri.resolvePackageName = intentPackage;
- if (mPm.userNeedsBadging(userId)) {
+ if (mUserNeedsBadging.get(userId)) {
ri.noResourceId = true;
} else {
ri.icon = appi.icon;
@@ -225,13 +255,14 @@
return true;
}
- public IntentSender getLaunchIntentSenderForPackage(String packageName, String callingPackage,
- String featureId, int userId) throws RemoteException {
+ public IntentSender getLaunchIntentSenderForPackage(@NonNull Computer computer,
+ String packageName, String callingPackage, String featureId, int userId)
+ throws RemoteException {
Objects.requireNonNull(packageName);
final int callingUid = Binder.getCallingUid();
- mPm.enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+ computer.enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
false /* checkShell */, "get launch intent sender for package");
- final int packageUid = mPm.getPackageUid(callingPackage, 0 /* flags */, userId);
+ final int packageUid = computer.getPackageUid(callingPackage, 0 /* flags */, userId);
if (!UserHandle.isSameApp(callingUid, packageUid)) {
throw new SecurityException("getLaunchIntentSenderForPackage() from calling uid: "
+ callingUid + " does not own package: " + callingPackage);
@@ -242,17 +273,17 @@
final Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
intentToResolve.addCategory(Intent.CATEGORY_INFO);
intentToResolve.setPackage(packageName);
- String resolvedType = intentToResolve.resolveTypeIfNeeded(
- mPm.mContext.getContentResolver());
- List<ResolveInfo> ris = mPm.queryIntentActivitiesInternal(intentToResolve, resolvedType,
+ final ContentResolver contentResolver = mContext.getContentResolver();
+ String resolvedType = intentToResolve.resolveTypeIfNeeded(contentResolver);
+ List<ResolveInfo> ris = computer.queryIntentActivitiesInternal(intentToResolve, resolvedType,
0 /* flags */, 0 /* privateResolveFlags */, callingUid, userId,
true /* resolveForStart */, false /* allowDynamicSplits */);
if (ris == null || ris.size() <= 0) {
intentToResolve.removeCategory(Intent.CATEGORY_INFO);
intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
intentToResolve.setPackage(packageName);
- resolvedType = intentToResolve.resolveTypeIfNeeded(mPm.mContext.getContentResolver());
- ris = mPm.queryIntentActivitiesInternal(intentToResolve, resolvedType,
+ resolvedType = intentToResolve.resolveTypeIfNeeded(contentResolver);
+ ris = computer.queryIntentActivitiesInternal(intentToResolve, resolvedType,
0 /* flags */, 0 /* privateResolveFlags */, callingUid, userId,
true /* resolveForStart */, false /* allowDynamicSplits */);
}
@@ -277,17 +308,17 @@
// In this method, we have to know the actual calling UID, but in some cases Binder's
// call identity is removed, so the UID has to be passed in explicitly.
- public @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
+ public @NonNull List<ResolveInfo> queryIntentReceiversInternal(Computer computer, Intent intent,
String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
int filterCallingUid) {
- if (!mPm.mUserManager.exists(userId)) return Collections.emptyList();
- mPm.enforceCrossUserPermission(filterCallingUid, userId, false /*requireFullPermission*/,
+ if (!mUserManager.exists(userId)) return Collections.emptyList();
+ computer.enforceCrossUserPermission(filterCallingUid, userId, false /*requireFullPermission*/,
false /*checkShell*/, "query intent receivers");
- final String instantAppPkgName = mPm.getInstantAppPackageName(filterCallingUid);
- flags = mPm.updateFlagsForResolve(
- flags, userId, filterCallingUid, false /*includeInstantApps*/,
- mPm.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
- flags));
+ final String instantAppPkgName = computer.getInstantAppPackageName(filterCallingUid);
+ flags = computer.updateFlagsForResolve(flags, userId, filterCallingUid,
+ false /*includeInstantApps*/,
+ computer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
+ resolvedType, flags));
Intent originalIntent = null;
ComponentName comp = intent.getComponent();
if (comp == null) {
@@ -297,9 +328,10 @@
comp = intent.getComponent();
}
}
+ final ComponentResolverApi componentResolver = computer.getComponentResolver();
List<ResolveInfo> list = Collections.emptyList();
if (comp != null) {
- final ActivityInfo ai = mPm.getReceiverInfo(comp, flags, userId);
+ final ActivityInfo ai = computer.getReceiverInfo(comp, flags, userId);
if (ai != null) {
// When specifying an explicit component, we prevent the activity from being
// used when either 1) the calling package is normal and the activity is within
@@ -335,28 +367,25 @@
list = new ArrayList<>(1);
list.add(ri);
PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
- mPm.mInjector.getCompatibility(), mPm.mComponentResolver,
- list, true, intent, resolvedType, filterCallingUid);
+ mPlatformCompat, componentResolver, list, true, intent,
+ resolvedType, filterCallingUid);
}
}
} else {
- // reader
- synchronized (mPm.mLock) {
- String pkgName = intent.getPackage();
- if (pkgName == null) {
- final List<ResolveInfo> result = mPm.mComponentResolver.queryReceivers(
- intent, resolvedType, flags, userId);
- if (result != null) {
- list = result;
- }
+ String pkgName = intent.getPackage();
+ if (pkgName == null) {
+ final List<ResolveInfo> result = componentResolver
+ .queryReceivers(computer, intent, resolvedType, flags, userId);
+ if (result != null) {
+ list = result;
}
- final AndroidPackage pkg = mPm.mPackages.get(pkgName);
- if (pkg != null) {
- final List<ResolveInfo> result = mPm.mComponentResolver.queryReceivers(
- intent, resolvedType, flags, pkg.getReceivers(), userId);
- if (result != null) {
- list = result;
- }
+ }
+ final AndroidPackage pkg = computer.getPackage(pkgName);
+ if (pkg != null) {
+ final List<ResolveInfo> result = componentResolver.queryReceivers(computer,
+ intent, resolvedType, flags, pkg.getReceivers(), userId);
+ if (result != null) {
+ list = result;
}
}
}
@@ -364,21 +393,22 @@
if (originalIntent != null) {
// We also have to ensure all components match the original intent
PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
- mPm.mInjector.getCompatibility(), mPm.mComponentResolver,
+ mPlatformCompat, componentResolver,
list, true, originalIntent, resolvedType, filterCallingUid);
}
- return mPm.applyPostResolutionFilter(
- list, instantAppPkgName, false, filterCallingUid, false, userId, intent);
+ return computer.applyPostResolutionFilter(list, instantAppPkgName, false, filterCallingUid,
+ false, userId, intent);
}
- public ResolveInfo resolveServiceInternal(Intent intent, String resolvedType,
- @PackageManager.ResolveInfoFlagsBits long flags, int userId, int callingUid) {
- if (!mPm.mUserManager.exists(userId)) return null;
- flags = mPm.updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
+ public ResolveInfo resolveServiceInternal(@NonNull Computer computer, Intent intent,
+ String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
+ int callingUid) {
+ if (!mUserManager.exists(userId)) return null;
+ flags = computer.updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
- List<ResolveInfo> query = mPm.queryIntentServicesInternal(
+ List<ResolveInfo> query = computer.queryIntentServicesInternal(
intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
if (query != null) {
if (query.size() >= 1) {
@@ -391,12 +421,12 @@
}
public @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
- Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
- int userId) {
- if (!mPm.mUserManager.exists(userId)) return Collections.emptyList();
+ @NonNull Computer computer, Intent intent, String resolvedType,
+ @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+ if (!mUserManager.exists(userId)) return Collections.emptyList();
final int callingUid = Binder.getCallingUid();
- final String instantAppPkgName = mPm.getInstantAppPackageName(callingUid);
- flags = mPm.updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
+ final String instantAppPkgName = computer.getInstantAppPackageName(callingUid);
+ flags = computer.updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
ComponentName comp = intent.getComponent();
if (comp == null) {
@@ -407,7 +437,7 @@
}
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<>(1);
- final ProviderInfo pi = mPm.getProviderInfo(comp, flags, userId);
+ final ProviderInfo pi = computer.getProviderInfo(comp, flags, userId);
if (pi != null) {
// When specifying an explicit component, we prevent the provider from being
// used when either 1) the provider is in an instant application and the
@@ -432,8 +462,8 @@
|| (matchVisibleToInstantAppOnly && isCallerInstantApp
&& isTargetHiddenFromInstantApp));
final boolean blockNormalResolution = !isTargetInstantApp && !isCallerInstantApp
- && mPm.shouldFilterApplication(
- mPm.getPackageStateInternal(pi.applicationInfo.packageName,
+ && computer.shouldFilterApplication(
+ computer.getPackageStateInternal(pi.applicationInfo.packageName,
Process.SYSTEM_UID), callingUid, userId);
if (!blockResolution && !blockNormalResolution) {
final ResolveInfo ri = new ResolveInfo();
@@ -444,46 +474,40 @@
return list;
}
- // reader
- synchronized (mPm.mLock) {
- String pkgName = intent.getPackage();
- if (pkgName == null) {
- final List<ResolveInfo> resolveInfos = mPm.mComponentResolver.queryProviders(intent,
- resolvedType, flags, userId);
- if (resolveInfos == null) {
- return Collections.emptyList();
- }
- return applyPostContentProviderResolutionFilter(
- resolveInfos, instantAppPkgName, userId, callingUid);
+ final ComponentResolverApi componentResolver = computer.getComponentResolver();
+ String pkgName = intent.getPackage();
+ if (pkgName == null) {
+ final List<ResolveInfo> resolveInfos = componentResolver.queryProviders(computer,
+ intent, resolvedType, flags, userId);
+ if (resolveInfos == null) {
+ return Collections.emptyList();
}
- final AndroidPackage pkg = mPm.mPackages.get(pkgName);
- if (pkg != null) {
- final List<ResolveInfo> resolveInfos = mPm.mComponentResolver.queryProviders(intent,
- resolvedType, flags,
- pkg.getProviders(), userId);
- if (resolveInfos == null) {
- return Collections.emptyList();
- }
- return applyPostContentProviderResolutionFilter(
- resolveInfos, instantAppPkgName, userId, callingUid);
- }
- return Collections.emptyList();
+ return applyPostContentProviderResolutionFilter(computer, resolveInfos,
+ instantAppPkgName, userId, callingUid);
}
+ final AndroidPackage pkg = computer.getPackage(pkgName);
+ if (pkg != null) {
+ final List<ResolveInfo> resolveInfos = componentResolver.queryProviders(computer,
+ intent, resolvedType, flags, pkg.getProviders(), userId);
+ if (resolveInfos == null) {
+ return Collections.emptyList();
+ }
+ return applyPostContentProviderResolutionFilter(computer, resolveInfos,
+ instantAppPkgName, userId, callingUid);
+ }
+ return Collections.emptyList();
}
- private List<ResolveInfo> applyPostContentProviderResolutionFilter(
+ private List<ResolveInfo> applyPostContentProviderResolutionFilter(@NonNull Computer computer,
List<ResolveInfo> resolveInfos, String instantAppPkgName,
@UserIdInt int userId, int callingUid) {
for (int i = resolveInfos.size() - 1; i >= 0; i--) {
final ResolveInfo info = resolveInfos.get(i);
if (instantAppPkgName == null) {
- SettingBase callingSetting =
- mPm.mSettings.getSettingLPr(UserHandle.getAppId(callingUid));
- PackageStateInternal resolvedSetting =
- mPm.getPackageStateInternal(info.providerInfo.packageName, 0);
- if (!mPm.mAppsFilter.shouldFilterApplication(
- callingUid, callingSetting, resolvedSetting, userId)) {
+ PackageStateInternal resolvedSetting = computer.getPackageStateInternal(
+ info.providerInfo.packageName, 0);
+ if (!computer.shouldFilterApplication(resolvedSetting, callingUid, userId)) {
continue;
}
}
@@ -494,7 +518,7 @@
if (info.providerInfo.splitName != null
&& !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
info.providerInfo.splitName)) {
- if (mPm.mInstantAppInstallerActivity == null) {
+ if (mInstantAppInstallerActivitySupplier.get() == null) {
if (DEBUG_INSTANT) {
Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
}
@@ -507,7 +531,7 @@
Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
}
final ResolveInfo installerInfo = new ResolveInfo(
- mPm.getInstantAppInstallerInfo());
+ computer.getInstantAppInstallerInfo());
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
null /*failureActivity*/,
info.providerInfo.packageName,
@@ -531,20 +555,21 @@
return resolveInfos;
}
- public @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
- Intent[] specifics, String[] specificTypes, Intent intent,
+ public @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(Computer computer,
+ ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent,
String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
- if (!mPm.mUserManager.exists(userId)) return Collections.emptyList();
+ if (!mUserManager.exists(userId)) return Collections.emptyList();
final int callingUid = Binder.getCallingUid();
- flags = mPm.updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
- mPm.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
- flags));
- mPm.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
+ flags = computer.updateFlagsForResolve(flags, userId, callingUid,
+ false /*includeInstantApps*/,
+ computer.isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId,
+ resolvedType, flags));
+ computer.enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
false /*checkShell*/, "query intent activity options");
final String resultsAction = intent.getAction();
- final List<ResolveInfo> results = mPm.queryIntentActivitiesInternal(intent, resolvedType,
- flags | PackageManager.GET_RESOLVED_FILTER, userId);
+ final List<ResolveInfo> results = computer.queryIntentActivitiesInternal(intent,
+ resolvedType, flags | PackageManager.GET_RESOLVED_FILTER, userId);
if (DEBUG_INTENT_MATCHING) {
Log.v(TAG, "Query " + intent + ": " + results);
@@ -584,21 +609,20 @@
ComponentName comp = sintent.getComponent();
if (comp == null) {
- ri = mPm.resolveIntent(
- sintent,
- specificTypes != null ? specificTypes[i] : null,
- flags, userId);
+ ri = resolveIntentInternal(computer, sintent,
+ specificTypes != null ? specificTypes[i] : null, flags,
+ 0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid());
if (ri == null) {
continue;
}
- if (ri == mPm.getResolveInfo()) {
+ if (ri == mResolveInfoSupplier.get()) {
// ACK! Must do something better with this.
}
ai = ri.activityInfo;
comp = new ComponentName(ai.applicationInfo.packageName,
ai.name);
} else {
- ai = mPm.getActivityInfo(comp, flags, userId);
+ ai = computer.getActivityInfo(comp, flags, userId);
if (ai == null) {
continue;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 4d7da1b..2ad35b7 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -120,6 +120,7 @@
import com.android.server.pm.pkg.component.ParsedPermission;
import com.android.server.pm.pkg.component.ParsedProcess;
import com.android.server.pm.pkg.parsing.PackageInfoWithoutStateUtils;
+import com.android.server.pm.resolution.ComponentResolver;
import com.android.server.pm.verify.domain.DomainVerificationLegacySettings;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import com.android.server.pm.verify.domain.DomainVerificationPersistence;
@@ -1551,7 +1552,7 @@
if (pa.mPref.getParseError() == null) {
final PreferredIntentResolver resolver = editPreferredActivitiesLPw(userId);
if (resolver.shouldAddPreferredActivity(pa)) {
- resolver.addFilter(pa);
+ resolver.addFilter(null, pa);
}
} else {
PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -1579,7 +1580,7 @@
String tagName = parser.getName();
if (tagName.equals(TAG_ITEM)) {
PersistentPreferredActivity ppa = new PersistentPreferredActivity(parser);
- editPersistentPreferredActivitiesLPw(userId).addFilter(ppa);
+ editPersistentPreferredActivitiesLPw(userId).addFilter(null, ppa);
} else {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Unknown element under <" + TAG_PERSISTENT_PREFERRED_ACTIVITIES + ">: "
@@ -1601,7 +1602,7 @@
final String tagName = parser.getName();
if (tagName.equals(TAG_ITEM)) {
CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser);
- editCrossProfileIntentResolverLPw(userId).addFilter(cpif);
+ editCrossProfileIntentResolverLPw(userId).addFilter(null, cpif);
} else {
String msg = "Unknown element under " + TAG_CROSS_PROFILE_INTENT_FILTERS + ": " +
tagName;
@@ -1868,8 +1869,7 @@
.build();
}
if (suspended && suspendParamsMap == null) {
- final SuspendParams suspendParams =
- SuspendParams.getInstanceOrNull(
+ final SuspendParams suspendParams = new SuspendParams(
oldSuspendDialogInfo,
suspendedAppExtras,
suspendedLauncherExtras);
@@ -3517,7 +3517,7 @@
removeFilters(pir, filter, existing);
}
PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
- pir.addFilter(pa);
+ pir.addFilter(null, pa);
} else if (haveNonSys == null) {
StringBuilder sb = new StringBuilder();
sb.append("No component ");
diff --git a/services/core/java/com/android/server/pm/SuspendPackageHelper.java b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
index 85d1367..bd1c9c7 100644
--- a/services/core/java/com/android/server/pm/SuspendPackageHelper.java
+++ b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
@@ -112,7 +112,7 @@
}
final SuspendParams newSuspendParams =
- SuspendParams.getInstanceOrNull(dialogInfo, appExtras, launcherExtras);
+ new SuspendParams(dialogInfo, appExtras, launcherExtras);
final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
final IntArray changedUids = new IntArray(packageNames.length);
@@ -148,13 +148,12 @@
final WatchedArrayMap<String, SuspendParams> suspendParamsMap =
packageState.getUserStateOrDefault(userId).getSuspendParams();
- final SuspendParams suspendParams = suspendParamsMap == null
- ? null : suspendParamsMap.get(packageName);
- boolean hasSuspension = suspendParams != null;
if (suspended) {
- if (hasSuspension) {
+ if (suspendParamsMap != null && suspendParamsMap.containsKey(packageName)) {
+ final SuspendParams suspendParams = suspendParamsMap.get(packageName);
// Skip if there's no changes
- if (Objects.equals(suspendParams.getDialogInfo(), dialogInfo)
+ if (suspendParams != null
+ && Objects.equals(suspendParams.getDialogInfo(), dialogInfo)
&& Objects.equals(suspendParams.getAppExtras(), appExtras)
&& Objects.equals(suspendParams.getLauncherExtras(),
launcherExtras)) {
diff --git a/services/core/java/com/android/server/pm/UserNeedsBadgingCache.java b/services/core/java/com/android/server/pm/UserNeedsBadgingCache.java
new file mode 100644
index 0000000..90c9228
--- /dev/null
+++ b/services/core/java/com/android/server/pm/UserNeedsBadgingCache.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.pm.UserInfo;
+import android.os.Binder;
+import android.util.SparseBooleanArray;
+
+import com.android.internal.annotations.GuardedBy;
+
+public class UserNeedsBadgingCache {
+
+ private final Object mLock = new Object();
+
+ // Cache of users who need badging.
+ @GuardedBy("mLock")
+ @NonNull
+ private final SparseBooleanArray mUserCache = new SparseBooleanArray();
+
+ @NonNull
+ private final UserManagerService mUserManager;
+
+ public UserNeedsBadgingCache(@NonNull UserManagerService userManager) {
+ mUserManager = userManager;
+ }
+
+ public void delete(@UserIdInt int userId) {
+ synchronized (mLock) {
+ mUserCache.delete(userId);
+ }
+ }
+
+ public boolean get(@UserIdInt int userId) {
+ synchronized (mLock) {
+ int index = mUserCache.indexOfKey(userId);
+ if (index >= 0) {
+ return mUserCache.valueAt(index);
+ }
+ }
+
+ final UserInfo userInfo;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ userInfo = mUserManager.getUserInfo(userId);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ final boolean b;
+ b = userInfo != null && userInfo.isManagedProfile();
+ synchronized (mLock) {
+ mUserCache.put(userId, b);
+ }
+ return b;
+ }
+}
diff --git a/services/core/java/com/android/server/pm/WatchedIntentResolver.java b/services/core/java/com/android/server/pm/WatchedIntentResolver.java
index 1c3d884..daa50ab 100644
--- a/services/core/java/com/android/server/pm/WatchedIntentResolver.java
+++ b/services/core/java/com/android/server/pm/WatchedIntentResolver.java
@@ -18,8 +18,10 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.IntentFilter;
import com.android.server.IntentResolver;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
import com.android.server.utils.Snappable;
import com.android.server.utils.Watchable;
import com.android.server.utils.WatchableImpl;
@@ -99,8 +101,8 @@
}
@Override
- public void addFilter(F f) {
- super.addFilter(f);
+ public void addFilter(@Nullable PackageDataSnapshot snapshot, F f) {
+ super.addFilter(snapshot, f);
f.registerObserver(mWatcher);
onChanged();
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index ed47bfb7..87494a6 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -3364,7 +3364,7 @@
// For updated system applications, a privileged/oem permission
// is granted only if it had been defined by the original application.
if (pkgSetting.getTransientState().isUpdatedSystemApp()) {
- final PackageSetting disabledPs = mPackageManagerInt
+ final PackageStateInternal disabledPs = mPackageManagerInt
.getDisabledSystemPackage(pkg.getPackageName());
final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.getPkg();
if (disabledPkg != null
@@ -3762,7 +3762,7 @@
return;
}
- PackageSetting disabledPs = mPackageManagerInt.getDisabledSystemPackage(
+ PackageStateInternal disabledPs = mPackageManagerInt.getDisabledSystemPackage(
pkg.getPackageName());
boolean isShadowingSystemPkg = disabledPs != null && disabledPs.getAppId() == pkg.getUid();
@@ -4104,7 +4104,7 @@
}
private boolean isPermissionDeclaredByDisabledSystemPkg(@NonNull Permission permission) {
- final PackageSetting disabledSourcePs = mPackageManagerInt.getDisabledSystemPackage(
+ final PackageStateInternal disabledSourcePs = mPackageManagerInt.getDisabledSystemPackage(
permission.getPackageName());
if (disabledSourcePs != null && disabledSourcePs.getPkg() != null) {
final String permissionName = permission.getName();
diff --git a/services/core/java/com/android/server/pm/pkg/SuspendParams.java b/services/core/java/com/android/server/pm/pkg/SuspendParams.java
index d24ce96..0926ba2 100644
--- a/services/core/java/com/android/server/pm/pkg/SuspendParams.java
+++ b/services/core/java/com/android/server/pm/pkg/SuspendParams.java
@@ -46,27 +46,13 @@
private final PersistableBundle appExtras;
private final PersistableBundle launcherExtras;
- private SuspendParams(SuspendDialogInfo dialogInfo, PersistableBundle appExtras,
+ public SuspendParams(SuspendDialogInfo dialogInfo, PersistableBundle appExtras,
PersistableBundle launcherExtras) {
this.dialogInfo = dialogInfo;
this.appExtras = appExtras;
this.launcherExtras = launcherExtras;
}
- /**
- * Returns a {@link SuspendParams} object with the given fields. Returns {@code null} if all
- * the fields are {@code null}.
- *
- * @return A {@link SuspendParams} object or {@code null}.
- */
- public static SuspendParams getInstanceOrNull(SuspendDialogInfo dialogInfo,
- PersistableBundle appExtras, PersistableBundle launcherExtras) {
- if (dialogInfo == null && appExtras == null && launcherExtras == null) {
- return null;
- }
- return new SuspendParams(dialogInfo, appExtras, launcherExtras);
- }
-
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
@@ -170,7 +156,7 @@
Slog.e(LOG_TAG, "Exception while trying to parse SuspendParams,"
+ " some fields may default", e);
}
- return getInstanceOrNull(readDialogInfo, readAppExtras, readLauncherExtras);
+ return new SuspendParams(readDialogInfo, readAppExtras, readLauncherExtras);
}
public SuspendDialogInfo getDialogInfo() {
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/resolution/ComponentResolver.java
similarity index 70%
rename from services/core/java/com/android/server/pm/ComponentResolver.java
rename to services/core/java/com/android/server/pm/resolution/ComponentResolver.java
index aa393d2..cf9370d 100644
--- a/services/core/java/com/android/server/pm/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/resolution/ComponentResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-package com.android.server.pm;
+package com.android.server.pm.resolution;
import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
-import static android.content.pm.PackageManagerInternal.PACKAGE_SETUP_WIZARD;
import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
@@ -32,11 +32,9 @@
import android.content.pm.AuxiliaryResolveInfo;
import android.content.pm.InstantAppResolveInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
@@ -46,14 +44,18 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.IntentResolver;
+import com.android.server.pm.Computer;
+import com.android.server.pm.DumpState;
+import com.android.server.pm.PackageManagerException;
+import com.android.server.pm.UserManagerService;
+import com.android.server.pm.UserNeedsBadgingCache;
import com.android.server.pm.parsing.PackageInfoUtils;
-import com.android.server.pm.parsing.PackageInfoUtils.CachedApplicationInfoGenerator;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.pkg.PackageStateUtils;
import com.android.server.pm.pkg.PackageUserStateInternal;
import com.android.server.pm.pkg.component.ComponentMutateUtils;
import com.android.server.pm.pkg.component.ParsedActivity;
@@ -63,12 +65,13 @@
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedProviderImpl;
import com.android.server.pm.pkg.component.ParsedService;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
import com.android.server.utils.Snappable;
import com.android.server.utils.SnapshotCache;
-import com.android.server.utils.WatchableImpl;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
@@ -79,9 +82,7 @@
import java.util.function.Function;
/** Resolves all Android component types [activities, services, providers and receivers]. */
-public class ComponentResolver
- extends WatchableImpl
- implements Snappable {
+public class ComponentResolver extends ComponentResolverLocked implements Snappable {
private static final boolean DEBUG = false;
private static final String TAG = "PackageManager";
private static final boolean DEBUG_FILTERS = false;
@@ -104,7 +105,7 @@
PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
}
- static final Comparator<ResolveInfo> RESOLVE_PRIORITY_SORTER = (r1, r2) -> {
+ public static final Comparator<ResolveInfo> RESOLVE_PRIORITY_SORTER = (r1, r2) -> {
int v1 = r1.priority;
int v2 = r2.priority;
//System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
@@ -140,62 +141,8 @@
return 0;
};
- private static UserManagerService sUserManager;
- private static PackageManagerInternal sPackageManagerInternal;
-
- /**
- * Locking within package manager is going to get worse before it gets better. Currently,
- * we need to share the {@link PackageManagerService} lock to prevent deadlocks. This occurs
- * because in order to safely query the resolvers, we need to obtain this lock. However,
- * during resolution, we call into the {@link PackageManagerService}. This is _not_ to
- * operate on data controlled by the service proper, but, to check the state of package
- * settings [contained in a {@link Settings} object]. However, the {@link Settings} object
- * happens to be protected by the main {@link PackageManagerService} lock.
- * <p>
- * There are a couple potential solutions.
- * <ol>
- * <li>Split all of our locks into reader/writer locks. This would allow multiple,
- * simultaneous read operations and means we don't have to be as cautious about lock
- * layering. Only when we want to perform a write operation will we ever be in a
- * position to deadlock the system.</li>
- * <li>Use the same lock across all classes within the {@code com.android.server.pm}
- * package. By unifying the lock object, we remove any potential lock layering issues
- * within the package manager. However, we already have a sense that this lock is
- * heavily contended and merely adding more dependencies on it will have further
- * impact.</li>
- * <li>Implement proper lock ordering within the package manager. By defining the
- * relative layer of the component [eg. {@link PackageManagerService} is at the top.
- * Somewhere in the middle would be {@link ComponentResolver}. At the very bottom
- * would be {@link Settings}.] The ordering would allow higher layers to hold their
- * lock while calling down. Lower layers must relinquish their lock before calling up.
- * Since {@link Settings} would live at the lowest layer, the {@link ComponentResolver}
- * would be able to hold its lock while checking the package setting state.</li>
- * </ol>
- */
- private final PackageManagerTracedLock mLock;
-
- /** All available activities, for your resolving pleasure. */
- @GuardedBy("mLock")
- private final ActivityIntentResolver mActivities;
-
- /** All available providers, for your resolving pleasure. */
- @GuardedBy("mLock")
- private final ProviderIntentResolver mProviders;
-
- /** All available receivers, for your resolving pleasure. */
- @GuardedBy("mLock")
- private final ReceiverIntentResolver mReceivers;
-
- /** All available services, for your resolving pleasure. */
- @GuardedBy("mLock")
- private final ServiceIntentResolver mServices;
-
- /** Mapping from provider authority [first directory in content URI codePath) to provider. */
- @GuardedBy("mLock")
- private final ArrayMap<String, ParsedProvider> mProvidersByAuthority;
-
/** Whether or not processing protected filters should be deferred. */
- private boolean mDeferProtectedFilters = true;
+ boolean mDeferProtectedFilters = true;
/**
* Tracks high priority intent filters for protected actions. During boot, certain
@@ -210,348 +157,62 @@
* This is a pair of component package name to actual filter, because we don't store the
* name inside the filter. It's technically independent of the component it's contained in.
*/
- private List<Pair<ParsedMainComponent, ParsedIntentInfo>> mProtectedFilters;
+ List<Pair<ParsedMainComponent, ParsedIntentInfo>> mProtectedFilters;
- ComponentResolver(UserManagerService userManager,
- PackageManagerInternal packageManagerInternal,
- PackageManagerTracedLock lock) {
- sPackageManagerInternal = packageManagerInternal;
- sUserManager = userManager;
- mLock = lock;
-
- mActivities = new ActivityIntentResolver();
- mProviders = new ProviderIntentResolver();
- mReceivers = new ReceiverIntentResolver();
- mServices = new ServiceIntentResolver();
+ public ComponentResolver(@NonNull UserManagerService userManager,
+ @NonNull UserNeedsBadgingCache userNeedsBadgingCache) {
+ super(userManager);
+ mActivities = new ActivityIntentResolver(userManager, userNeedsBadgingCache);
+ mProviders = new ProviderIntentResolver(userManager);
+ mReceivers = new ReceiverIntentResolver(userManager, userNeedsBadgingCache);
+ mServices = new ServiceIntentResolver(userManager);
mProvidersByAuthority = new ArrayMap<>();
mDeferProtectedFilters = true;
- mSnapshot = new SnapshotCache<ComponentResolver>(this, this) {
+ mSnapshot = new SnapshotCache<ComponentResolverApi>(this, this) {
@Override
- public ComponentResolver createSnapshot() {
- return new ComponentResolver(mSource);
+ public ComponentResolverApi createSnapshot() {
+ return new ComponentResolverSnapshot(ComponentResolver.this,
+ userNeedsBadgingCache);
}};
}
- // Copy constructor used in creating snapshots.
- private ComponentResolver(ComponentResolver orig) {
- // Do not set the static variables that are set in the default constructor. Do
- // create a new object for the lock. The snapshot is read-only, so a lock is not
- // strictly required. However, the current code is simpler if the lock exists,
- // but does not contend with any outside class.
- // TODO: make the snapshot lock-free
- mLock = new PackageManagerTracedLock();
-
- mActivities = new ActivityIntentResolver(orig.mActivities);
- mProviders = new ProviderIntentResolver(orig.mProviders);
- mReceivers = new ReceiverIntentResolver(orig.mReceivers);
- mServices = new ServiceIntentResolver(orig.mServices);
- mProvidersByAuthority = new ArrayMap<>(orig.mProvidersByAuthority);
- mDeferProtectedFilters = orig.mDeferProtectedFilters;
- mProtectedFilters = (mProtectedFilters == null)
- ? null
- : new ArrayList<>(orig.mProtectedFilters);
-
- mSnapshot = null;
- }
-
- final SnapshotCache<ComponentResolver> mSnapshot;
+ final SnapshotCache<ComponentResolverApi> mSnapshot;
/**
* Create a snapshot.
*/
- public ComponentResolver snapshot() {
+ public ComponentResolverApi snapshot() {
return mSnapshot.snapshot();
}
-
- /** Returns the given activity */
- @Nullable
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public ParsedActivity getActivity(@NonNull ComponentName component) {
- synchronized (mLock) {
- return mActivities.mActivities.get(component);
- }
- }
-
- /** Returns the given provider */
- @Nullable
- ParsedProvider getProvider(@NonNull ComponentName component) {
- synchronized (mLock) {
- return mProviders.mProviders.get(component);
- }
- }
-
- /** Returns the given receiver */
- @Nullable
- ParsedActivity getReceiver(@NonNull ComponentName component) {
- synchronized (mLock) {
- return mReceivers.mActivities.get(component);
- }
- }
-
- /** Returns the given service */
- @Nullable
- ParsedService getService(@NonNull ComponentName component) {
- synchronized (mLock) {
- return mServices.mServices.get(component);
- }
- }
-
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public boolean componentExists(@NonNull ComponentName componentName) {
- synchronized (mLock) {
- ParsedMainComponent component = mActivities.mActivities.get(componentName);
- if (component != null) {
- return true;
- }
- component = mReceivers.mActivities.get(componentName);
- if (component != null) {
- return true;
- }
- component = mServices.mServices.get(componentName);
- if (component != null) {
- return true;
- }
- return mProviders.mProviders.get(componentName) != null;
- }
- }
-
- @Nullable
- List<ResolveInfo> queryActivities(Intent intent, String resolvedType, long flags,
- int userId) {
- synchronized (mLock) {
- return mActivities.queryIntent(intent, resolvedType, flags, userId);
- }
- }
-
- @Nullable
- List<ResolveInfo> queryActivities(Intent intent, String resolvedType, long flags,
- List<ParsedActivity> activities, int userId) {
- synchronized (mLock) {
- return mActivities.queryIntentForPackage(
- intent, resolvedType, flags, activities, userId);
- }
- }
-
- @Nullable
- List<ResolveInfo> queryProviders(Intent intent, String resolvedType, long flags, int userId) {
- synchronized (mLock) {
- return mProviders.queryIntent(intent, resolvedType, flags, userId);
- }
- }
-
- @Nullable
- List<ResolveInfo> queryProviders(Intent intent, String resolvedType, long flags,
- List<ParsedProvider> providers, int userId) {
- synchronized (mLock) {
- return mProviders.queryIntentForPackage(intent, resolvedType, flags, providers, userId);
- }
- }
-
- @Nullable
- List<ProviderInfo> queryProviders(String processName, String metaDataKey, int uid, long flags,
- int userId) {
- if (!sUserManager.exists(userId)) {
- return null;
- }
- List<ProviderInfo> providerList = null;
- CachedApplicationInfoGenerator appInfoGenerator = null;
- synchronized (mLock) {
- for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) {
- final ParsedProvider p = mProviders.mProviders.valueAt(i);
- if (p.getAuthority() == null) {
- continue;
- }
-
- final PackageStateInternal ps =
- sPackageManagerInternal.getPackageStateInternal(p.getPackageName());
- if (ps == null) {
- continue;
- }
-
- AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName());
- if (pkg == null) {
- continue;
- }
-
- if (processName != null && (!p.getProcessName().equals(processName)
- || !UserHandle.isSameApp(pkg.getUid(), uid))) {
- continue;
- }
- // See PM.queryContentProviders()'s javadoc for why we have the metaData parameter.
- if (metaDataKey != null && !p.getMetaData().containsKey(metaDataKey)) {
- continue;
- }
- if (appInfoGenerator == null) {
- appInfoGenerator = new CachedApplicationInfoGenerator();
- }
- final PackageUserStateInternal state = ps.getUserStateOrDefault(userId);
- final ApplicationInfo appInfo =
- appInfoGenerator.generate(pkg, flags, state, userId, ps);
- if (appInfo == null) {
- continue;
- }
-
- final ProviderInfo info = PackageInfoUtils.generateProviderInfo(
- pkg, p, flags, state, appInfo, userId, ps);
- if (info == null) {
- continue;
- }
- if (providerList == null) {
- providerList = new ArrayList<>(i + 1);
- }
- providerList.add(info);
- }
- }
- return providerList;
- }
-
- @Nullable
- ProviderInfo queryProvider(String authority, long flags, int userId) {
- synchronized (mLock) {
- final ParsedProvider p = mProvidersByAuthority.get(authority);
- if (p == null) {
- return null;
- }
- final PackageStateInternal ps =
- sPackageManagerInternal.getPackageStateInternal(p.getPackageName());
- if (ps == null) {
- return null;
- }
- final AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName());
- if (pkg == null) {
- return null;
- }
- final PackageUserStateInternal state = ps.getUserStateOrDefault(userId);
- ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
- pkg, flags, state, userId, ps);
- if (appInfo == null) {
- return null;
- }
- return PackageInfoUtils.generateProviderInfo(pkg, p, flags, state, appInfo, userId, ps);
- }
- }
-
- void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo, boolean safeMode,
- int userId) {
- synchronized (mLock) {
- CachedApplicationInfoGenerator appInfoGenerator = null;
- for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) {
- final ParsedProvider p = mProvidersByAuthority.valueAt(i);
- if (!p.isSyncable()) {
- continue;
- }
-
- final PackageStateInternal ps =
- sPackageManagerInternal.getPackageStateInternal(p.getPackageName());
- if (ps == null) {
- continue;
- }
-
- final AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName());
- if (pkg == null) {
- continue;
- }
-
- if (safeMode && !pkg.isSystem()) {
- continue;
- }
- if (appInfoGenerator == null) {
- appInfoGenerator = new CachedApplicationInfoGenerator();
- }
- final PackageUserStateInternal state = ps.getUserStateOrDefault(userId);
- final ApplicationInfo appInfo =
- appInfoGenerator.generate(pkg, 0, state, userId, ps);
- if (appInfo == null) {
- continue;
- }
-
- final ProviderInfo info = PackageInfoUtils.generateProviderInfo(
- pkg, p, 0, state, appInfo, userId, ps);
- if (info == null) {
- continue;
- }
- outNames.add(mProvidersByAuthority.keyAt(i));
- outInfo.add(info);
- }
- }
- }
-
- @Nullable
- List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, long flags, int userId) {
- synchronized (mLock) {
- return mReceivers.queryIntent(intent, resolvedType, flags, userId);
- }
- }
-
- @Nullable
- List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, long flags,
- List<ParsedActivity> receivers, int userId) {
- synchronized (mLock) {
- return mReceivers.queryIntentForPackage(intent, resolvedType, flags, receivers, userId);
- }
- }
-
- @Nullable
- List<ResolveInfo> queryServices(Intent intent, String resolvedType, long flags, int userId) {
- synchronized (mLock) {
- return mServices.queryIntent(intent, resolvedType, flags, userId);
- }
- }
-
- @Nullable
- List<ResolveInfo> queryServices(Intent intent, String resolvedType, long flags,
- List<ParsedService> services, int userId) {
- synchronized (mLock) {
- return mServices.queryIntentForPackage(intent, resolvedType, flags, services, userId);
- }
- }
-
- /** Returns {@code true} if the given activity is defined by some package */
- boolean isActivityDefined(ComponentName component) {
- synchronized (mLock) {
- return mActivities.mActivities.get(component) != null;
- }
- }
-
- /** Asserts none of the providers defined in the given package haven't already been defined. */
- void assertProvidersNotDefined(AndroidPackage pkg) throws PackageManagerException {
- synchronized (mLock) {
- assertProvidersNotDefinedLocked(pkg);
- }
- }
-
/** Add all components defined in the given package to the internal structures. */
- void addAllComponents(AndroidPackage pkg, boolean chatty) {
+ public void addAllComponents(AndroidPackage pkg, boolean chatty,
+ @Nullable String setupWizardPackage, @NonNull Computer computer) {
final ArrayList<Pair<ParsedActivity, ParsedIntentInfo>> newIntents = new ArrayList<>();
synchronized (mLock) {
- addActivitiesLocked(pkg, newIntents, chatty);
- addReceiversLocked(pkg, chatty);
- addProvidersLocked(pkg, chatty);
- addServicesLocked(pkg, chatty);
+ addActivitiesLocked(computer, pkg, newIntents, chatty);
+ addReceiversLocked(computer, pkg, chatty);
+ addProvidersLocked(computer, pkg, chatty);
+ addServicesLocked(computer, pkg, chatty);
onChanged();
}
- // expect single setupwizard package
- final String setupWizardPackage = ArrayUtils.firstOrNull(
- sPackageManagerInternal.getKnownPackageNames(
- PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM));
for (int i = newIntents.size() - 1; i >= 0; --i) {
final Pair<ParsedActivity, ParsedIntentInfo> pair = newIntents.get(i);
- final PackageSetting disabledPkgSetting = (PackageSetting) sPackageManagerInternal
+ final PackageStateInternal disabledPkgSetting = computer
.getDisabledSystemPackage(pair.first.getPackageName());
final AndroidPackage disabledPkg =
disabledPkgSetting == null ? null : disabledPkgSetting.getPkg();
final List<ParsedActivity> systemActivities =
disabledPkg != null ? disabledPkg.getActivities() : null;
- adjustPriority(systemActivities, pair.first, pair.second, setupWizardPackage);
+ adjustPriority(computer, systemActivities, pair.first, pair.second, setupWizardPackage);
onChanged();
}
}
/** Removes all components defined in the given package from the internal structures. */
- void removeAllComponents(AndroidPackage pkg, boolean chatty) {
+ public void removeAllComponents(AndroidPackage pkg, boolean chatty) {
synchronized (mLock) {
removeAllComponentsLocked(pkg, chatty);
onChanged();
@@ -562,7 +223,7 @@
* Reprocess any protected filters that have been deferred. At this point, we've scanned
* all of the filters defined on the /system partition and know the special components.
*/
- void fixProtectedFilterPriorities() {
+ public void fixProtectedFilterPriorities(@Nullable String setupWizardPackage) {
synchronized (mLock) {
if (!mDeferProtectedFilters) {
return;
@@ -576,11 +237,6 @@
mProtectedFilters;
mProtectedFilters = null;
- // expect single setupwizard package
- final String setupWizardPackage = ArrayUtils.firstOrNull(
- sPackageManagerInternal.getKnownPackageNames(
- PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM));
-
if (DEBUG_FILTERS && setupWizardPackage == null) {
Slog.i(TAG, "No setup wizard;"
+ " All protected intents capped to priority 0");
@@ -615,7 +271,7 @@
}
}
- void dumpActivityResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
+ public void dumpActivityResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
synchronized (mLock) {
if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
: "Activity Resolver Table:", " ", packageName,
@@ -625,7 +281,7 @@
}
}
- void dumpProviderResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
+ public void dumpProviderResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
synchronized (mLock) {
if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
: "Provider Resolver Table:", " ", packageName,
@@ -635,7 +291,7 @@
}
}
- void dumpReceiverResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
+ public void dumpReceiverResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
synchronized (mLock) {
if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
: "Receiver Resolver Table:", " ", packageName,
@@ -645,7 +301,7 @@
}
}
- void dumpServiceResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
+ public void dumpServiceResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
synchronized (mLock) {
if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
: "Service Resolver Table:", " ", packageName,
@@ -655,7 +311,8 @@
}
}
- void dumpContentProviders(PrintWriter pw, DumpState dumpState, String packageName) {
+ public void dumpContentProviders(@NonNull Computer computer, PrintWriter pw,
+ DumpState dumpState, String packageName) {
synchronized (mLock) {
boolean printedSomething = false;
for (ParsedProvider p : mProviders.mProviders.values()) {
@@ -695,7 +352,7 @@
pw.print(" ");
pw.println(p.toString());
- AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName());
+ AndroidPackage pkg = computer.getPackage(p.getPackageName());
if (pkg != null) {
pw.print(" applicationInfo=");
@@ -705,7 +362,7 @@
}
}
- void dumpServicePermissions(PrintWriter pw, DumpState dumpState) {
+ public void dumpServicePermissions(PrintWriter pw, DumpState dumpState) {
synchronized (mLock) {
if (dumpState.onTitlePrinted()) pw.println();
pw.println("Service permissions:");
@@ -728,13 +385,13 @@
}
@GuardedBy("mLock")
- private void addActivitiesLocked(AndroidPackage pkg,
+ private void addActivitiesLocked(@NonNull Computer computer, AndroidPackage pkg,
List<Pair<ParsedActivity, ParsedIntentInfo>> newIntents, boolean chatty) {
final int activitiesSize = ArrayUtils.size(pkg.getActivities());
StringBuilder r = null;
for (int i = 0; i < activitiesSize; i++) {
ParsedActivity a = pkg.getActivities().get(i);
- mActivities.addActivity(a, "activity", newIntents);
+ mActivities.addActivity(computer, a, "activity", newIntents);
if (DEBUG_PACKAGE_SCANNING && chatty) {
if (r == null) {
r = new StringBuilder(256);
@@ -750,12 +407,12 @@
}
@GuardedBy("mLock")
- private void addProvidersLocked(AndroidPackage pkg, boolean chatty) {
+ private void addProvidersLocked(@NonNull Computer computer, AndroidPackage pkg, boolean chatty) {
final int providersSize = ArrayUtils.size(pkg.getProviders());
StringBuilder r = null;
for (int i = 0; i < providersSize; i++) {
ParsedProvider p = pkg.getProviders().get(i);
- mProviders.addProvider(p);
+ mProviders.addProvider(computer, p);
if (p.getAuthority() != null) {
String[] names = p.getAuthority().split(";");
@@ -814,12 +471,12 @@
}
@GuardedBy("mLock")
- private void addReceiversLocked(AndroidPackage pkg, boolean chatty) {
+ private void addReceiversLocked(@NonNull Computer computer, AndroidPackage pkg, boolean chatty) {
final int receiversSize = ArrayUtils.size(pkg.getReceivers());
StringBuilder r = null;
for (int i = 0; i < receiversSize; i++) {
ParsedActivity a = pkg.getReceivers().get(i);
- mReceivers.addActivity(a, "receiver", null);
+ mReceivers.addActivity(computer, a, "receiver", null);
if (DEBUG_PACKAGE_SCANNING && chatty) {
if (r == null) {
r = new StringBuilder(256);
@@ -835,12 +492,12 @@
}
@GuardedBy("mLock")
- private void addServicesLocked(AndroidPackage pkg, boolean chatty) {
+ private void addServicesLocked(@NonNull Computer computer, AndroidPackage pkg, boolean chatty) {
final int servicesSize = ArrayUtils.size(pkg.getServices());
StringBuilder r = null;
for (int i = 0; i < servicesSize; i++) {
ParsedService s = pkg.getServices().get(i);
- mServices.addService(s);
+ mServices.addService(computer, s);
if (DEBUG_PACKAGE_SCANNING && chatty) {
if (r == null) {
r = new StringBuilder(256);
@@ -945,8 +602,8 @@
* <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
* allowed to obtain any priority on any action.
*/
- private void adjustPriority(List<ParsedActivity> systemActivities, ParsedActivity activity,
- ParsedIntentInfo intentInfo, String setupWizardPackage) {
+ private void adjustPriority(@NonNull Computer computer, List<ParsedActivity> systemActivities,
+ ParsedActivity activity, ParsedIntentInfo intentInfo, String setupWizardPackage) {
// nothing to do; priority is fine as-is
IntentFilter intentFilter = intentInfo.getIntentFilter();
if (intentFilter.getPriority() <= 0) {
@@ -954,7 +611,7 @@
}
String packageName = activity.getPackageName();
- AndroidPackage pkg = sPackageManagerInternal.getPackage(packageName);
+ AndroidPackage pkg = computer.getPackage(packageName);
final boolean privilegedApp = pkg.isPrivileged();
String className = activity.getClassName();
@@ -1231,28 +888,30 @@
}
}
- @GuardedBy("mLock")
- private void assertProvidersNotDefinedLocked(AndroidPackage pkg)
+ /** Asserts none of the providers defined in the given package haven't already been defined. */
+ public void assertProvidersNotDefined(@NonNull AndroidPackage pkg)
throws PackageManagerException {
- final int providersSize = ArrayUtils.size(pkg.getProviders());
- int i;
- for (i = 0; i < providersSize; i++) {
- ParsedProvider p = pkg.getProviders().get(i);
- if (p.getAuthority() != null) {
- final String[] names = p.getAuthority().split(";");
- for (int j = 0; j < names.length; j++) {
- if (mProvidersByAuthority.containsKey(names[j])) {
- final ParsedProvider other = mProvidersByAuthority.get(names[j]);
- final String otherPackageName =
- (other != null && other.getComponentName() != null)
- ? other.getComponentName().getPackageName() : "?";
- // if we're installing over the same already-installed package, this is ok
- if (!otherPackageName.equals(pkg.getPackageName())) {
- throw new PackageManagerException(
- INSTALL_FAILED_CONFLICTING_PROVIDER,
- "Can't install because provider name " + names[j]
- + " (in package " + pkg.getPackageName()
- + ") is already used by " + otherPackageName);
+ synchronized (mLock) {
+ final int providersSize = ArrayUtils.size(pkg.getProviders());
+ int i;
+ for (i = 0; i < providersSize; i++) {
+ ParsedProvider p = pkg.getProviders().get(i);
+ if (p.getAuthority() != null) {
+ final String[] names = p.getAuthority().split(";");
+ for (int j = 0; j < names.length; j++) {
+ if (mProvidersByAuthority.containsKey(names[j])) {
+ final ParsedProvider other = mProvidersByAuthority.get(names[j]);
+ final String otherPackageName =
+ (other != null && other.getComponentName() != null)
+ ? other.getComponentName().getPackageName() : "?";
+ // if installing over the same already-installed package,this is ok
+ if (!otherPackageName.equals(pkg.getPackageName())) {
+ throw new PackageManagerException(
+ INSTALL_FAILED_CONFLICTING_PROVIDER,
+ "Can't install because provider name " + names[j]
+ + " (in package " + pkg.getPackageName()
+ + ") is already used by " + otherPackageName);
+ }
}
}
}
@@ -1266,22 +925,31 @@
private final ArrayMap<String, F[]> mMimeGroupToFilter = new ArrayMap<>();
private boolean mIsUpdatingMimeGroup = false;
+ @NonNull
+ protected final UserManagerService mUserManager;
+
// Default constructor
- MimeGroupsAwareIntentResolver() {
+ MimeGroupsAwareIntentResolver(@NonNull UserManagerService userManager) {
+ mUserManager = userManager;
}
// Copy constructor used in creating snapshots
- MimeGroupsAwareIntentResolver(MimeGroupsAwareIntentResolver<F, R> orig) {
+ MimeGroupsAwareIntentResolver(MimeGroupsAwareIntentResolver<F, R> orig,
+ @NonNull UserManagerService userManager) {
+ mUserManager = userManager;
copyFrom(orig);
copyInto(mMimeGroupToFilter, orig.mMimeGroupToFilter);
mIsUpdatingMimeGroup = orig.mIsUpdatingMimeGroup;
}
@Override
- public void addFilter(F f) {
+ public void addFilter(@Nullable PackageDataSnapshot snapshot, F f) {
IntentFilter intentFilter = getIntentFilter(f);
- applyMimeGroups(f);
- super.addFilter(f);
+ // We assume Computer is available for this class and all subclasses. Because this class
+ // uses subclass method override to handle logic, the Computer parameter must be in the
+ // base, leading to this odd nullability.
+ applyMimeGroups((Computer) snapshot, f);
+ super.addFilter(snapshot, f);
if (!mIsUpdatingMimeGroup) {
register_intent_filter(f, intentFilter.mimeGroupsIterator(), mMimeGroupToFilter,
@@ -1309,7 +977,8 @@
* @param mimeGroup MIME group to update
* @return true, if any intent filters were changed due to this update
*/
- public boolean updateMimeGroup(String packageName, String mimeGroup) {
+ public boolean updateMimeGroup(@NonNull Computer computer, String packageName,
+ String mimeGroup) {
F[] filters = mMimeGroupToFilter.get(mimeGroup);
int n = filters != null ? filters.length : 0;
@@ -1318,18 +987,18 @@
F filter;
for (int i = 0; i < n && (filter = filters[i]) != null; i++) {
if (isPackageForFilter(packageName, filter)) {
- hasChanges |= updateFilter(filter);
+ hasChanges |= updateFilter(computer, filter);
}
}
mIsUpdatingMimeGroup = false;
return hasChanges;
}
- private boolean updateFilter(F f) {
+ private boolean updateFilter(@NonNull Computer computer, F f) {
IntentFilter filter = getIntentFilter(f);
List<String> oldTypes = filter.dataTypes();
removeFilter(f);
- addFilter(f);
+ addFilter(computer, f);
List<String> newTypes = filter.dataTypes();
return !equalLists(oldTypes, newTypes);
}
@@ -1350,16 +1019,18 @@
return first.equals(second);
}
- private void applyMimeGroups(F f) {
+ private void applyMimeGroups(@NonNull Computer computer, F f) {
IntentFilter filter = getIntentFilter(f);
for (int i = filter.countMimeGroups() - 1; i >= 0; i--) {
- List<String> mimeTypes = sPackageManagerInternal.getMimeGroup(
- f.first.getPackageName(), filter.getMimeGroup(i));
+ final PackageStateInternal packageState = computer.getPackageStateInternal(
+ f.first.getPackageName());
- for (int typeIndex = mimeTypes.size() - 1; typeIndex >= 0; typeIndex--) {
- String mimeType = mimeTypes.get(typeIndex);
+ Collection<String> mimeTypes = packageState == null
+ ? Collections.emptyList() : packageState.getMimeGroups()
+ .get(filter.getMimeGroup(i));
+ for (String mimeType : mimeTypes) {
try {
filter.addDynamicDataType(mimeType);
} catch (IntentFilter.MalformedMimeTypeException e) {
@@ -1370,50 +1041,74 @@
}
}
}
+
+ @Override
+ protected boolean isFilterStopped(@Nullable PackageStateInternal packageState,
+ @UserIdInt int userId) {
+ if (!mUserManager.exists(userId)) {
+ return true;
+ }
+
+ if (packageState == null || packageState.getPkg() == null) {
+ return false;
+ }
+
+ // System apps are never considered stopped for purposes of
+ // filtering, because there may be no way for the user to
+ // actually re-launch them.
+ return !packageState.isSystem()
+ && packageState.getUserStateOrDefault(userId).isStopped();
+ }
}
- private static class ActivityIntentResolver
+ public static class ActivityIntentResolver
extends MimeGroupsAwareIntentResolver<Pair<ParsedActivity, ParsedIntentInfo>, ResolveInfo> {
+ @NonNull
+ private UserNeedsBadgingCache mUserNeedsBadging;
+
// Default constructor
- ActivityIntentResolver() {
+ ActivityIntentResolver(@NonNull UserManagerService userManager,
+ @NonNull UserNeedsBadgingCache userNeedsBadgingCache) {
+ super(userManager);
+ mUserNeedsBadging = userNeedsBadgingCache;
}
// Copy constructor used in creating snapshots
- ActivityIntentResolver(ActivityIntentResolver orig) {
- super(orig);
+ ActivityIntentResolver(@NonNull ActivityIntentResolver orig,
+ @NonNull UserManagerService userManager,
+ @NonNull UserNeedsBadgingCache userNeedsBadgingCache) {
+ super(orig, userManager);
mActivities.putAll(orig.mActivities);
- mFlags = orig.mFlags;
+ mUserNeedsBadging = userNeedsBadgingCache;
}
@Override
- public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
- boolean defaultOnly, int userId) {
- if (!sUserManager.exists(userId)) return null;
- mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
- return super.queryIntent(intent, resolvedType, defaultOnly, userId);
+ public List<ResolveInfo> queryIntent(@NonNull PackageDataSnapshot snapshot, Intent intent,
+ String resolvedType, boolean defaultOnly, @UserIdInt int userId) {
+ if (!mUserManager.exists(userId)) return null;
+ long flags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
+ return super.queryIntent(snapshot, intent, resolvedType, defaultOnly, userId, flags);
}
- List<ResolveInfo> queryIntent(Intent intent, String resolvedType, long flags,
- int userId) {
- if (!sUserManager.exists(userId)) {
+ List<ResolveInfo> queryIntent(@NonNull Computer computer, Intent intent,
+ String resolvedType, long flags, int userId) {
+ if (!mUserManager.exists(userId)) {
return null;
}
- mFlags = flags;
- return super.queryIntent(intent, resolvedType,
- (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- userId);
+ return super.queryIntent(computer, intent, resolvedType,
+ (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId, flags);
}
- List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
- long flags, List<ParsedActivity> packageActivities, int userId) {
- if (!sUserManager.exists(userId)) {
+ List<ResolveInfo> queryIntentForPackage(@NonNull Computer computer, Intent intent,
+ String resolvedType, long flags, List<ParsedActivity> packageActivities,
+ int userId) {
+ if (!mUserManager.exists(userId)) {
return null;
}
if (packageActivities == null) {
return Collections.emptyList();
}
- mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
final int activitiesSize = packageActivities.size();
ArrayList<Pair<ParsedActivity, ParsedIntentInfo>[]> listCut =
@@ -1431,10 +1126,11 @@
listCut.add(array);
}
}
- return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
+ return super.queryIntentFromList(computer, intent, resolvedType,
+ defaultOnly, listCut, userId, flags);
}
- protected void addActivity(ParsedActivity a, String type,
+ protected void addActivity(@NonNull Computer computer, ParsedActivity a, String type,
List<Pair<ParsedActivity, ParsedIntentInfo>> newIntents) {
mActivities.put(a.getComponentName(), a);
if (DEBUG_SHOW_INFO) {
@@ -1455,7 +1151,7 @@
if (!intentFilter.debugCheck()) {
Log.w(TAG, "==> For Activity " + a.getName());
}
- addFilter(Pair.create(a, intent));
+ addFilter(computer, Pair.create(a, intent));
}
}
@@ -1497,11 +1193,6 @@
}
@Override
- protected boolean isFilterStopped(Pair<ParsedActivity, ParsedIntentInfo> filter, int userId) {
- return ComponentResolver.isFilterStopped(filter, userId);
- }
-
- @Override
protected boolean isPackageForFilter(String packageName,
Pair<ParsedActivity, ParsedIntentInfo> info) {
return packageName.equals(info.first.getPackageName());
@@ -1517,43 +1208,35 @@
}
@Override
- protected ResolveInfo newResult(Pair<ParsedActivity, ParsedIntentInfo> pair,
- int match, int userId) {
+ protected ResolveInfo newResult(@NonNull Computer computer,
+ Pair<ParsedActivity, ParsedIntentInfo> pair, int match, int userId,
+ long customFlags) {
ParsedActivity activity = pair.first;
ParsedIntentInfo info = pair.second;
IntentFilter intentFilter = info.getIntentFilter();
- if (!sUserManager.exists(userId)) {
+ if (!mUserManager.exists(userId)) {
if (DEBUG) {
log("User doesn't exist", info, match, userId);
}
return null;
}
- AndroidPackage pkg = sPackageManagerInternal.getPackage(activity.getPackageName());
- if (pkg == null) {
- return null;
- }
-
- if (!sPackageManagerInternal.isEnabledAndMatches(activity, mFlags, userId)) {
+ final PackageStateInternal packageState =
+ computer.getPackageStateInternal(activity.getPackageName());
+ if (packageState == null || packageState.getPkg() == null
+ || !PackageStateUtils.isEnabledAndMatches(packageState, activity, customFlags,
+ userId)) {
if (DEBUG) {
- log("!PackageManagerInternal.isEnabledAndMatches; mFlags="
- + DebugUtils.flagsToString(PackageManager.class, "MATCH_", mFlags),
+ log("!PackageManagerInternal.isEnabledAndMatches; flags="
+ + DebugUtils.flagsToString(PackageManager.class, "MATCH_", customFlags),
info, match, userId);
}
return null;
}
- PackageStateInternal ps =
- sPackageManagerInternal.getPackageStateInternal(activity.getPackageName());
- if (ps == null) {
- if (DEBUG) {
- log("info.activity.owner.mExtras == null", info, match, userId);
- }
- return null;
- }
- final PackageUserStateInternal userState = ps.getUserStateOrDefault(userId);
- ActivityInfo ai = PackageInfoUtils.generateActivityInfo(pkg, activity, mFlags,
- userState, userId, ps);
+ final PackageUserStateInternal userState = packageState.getUserStateOrDefault(userId);
+ ActivityInfo ai = PackageInfoUtils.generateActivityInfo(packageState.getPkg(), activity,
+ customFlags, userState, userId, packageState);
if (ai == null) {
if (DEBUG) {
log("Failed to create ActivityInfo based on " + activity, info, match,
@@ -1562,15 +1245,15 @@
return null;
}
final boolean matchExplicitlyVisibleOnly =
- (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
+ (customFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
final boolean matchVisibleToInstantApp =
- (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+ (customFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
final boolean componentVisible =
matchVisibleToInstantApp
&& intentFilter.isVisibleToInstantApp()
&& (!matchExplicitlyVisibleOnly
|| intentFilter.isExplicitlyVisibleToInstantApp());
- final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
+ final boolean matchInstantApp = (customFlags & PackageManager.MATCH_INSTANT) != 0;
// throw out filters that aren't visible to ephemeral apps
if (matchVisibleToInstantApp && !(componentVisible || userState.isInstantApp())) {
if (DEBUG) {
@@ -1595,7 +1278,7 @@
}
// throw out instant app filters if updates are available; will trigger
// instant app resolution
- if (userState.isInstantApp() && ps.isUpdateAvailable()) {
+ if (userState.isInstantApp() && packageState.isUpdateAvailable()) {
if (DEBUG) {
log("Instant app update is available", info, match, userId);
}
@@ -1604,7 +1287,7 @@
final ResolveInfo res =
new ResolveInfo(intentFilter.hasCategory(Intent.CATEGORY_BROWSABLE));
res.activityInfo = ai;
- if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
+ if ((customFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
res.filter = intentFilter;
}
res.handleAllWebDataURI = intentFilter.handleAllWebDataURI();
@@ -1617,7 +1300,7 @@
res.isDefault = info.isHasDefault();
res.labelRes = info.getLabelRes();
res.nonLocalizedLabel = info.getNonLocalizedLabel();
- if (sPackageManagerInternal.userNeedsBadging(userId)) {
+ if (mUserNeedsBadging.get(userId)) {
res.noResourceId = true;
} else {
res.icon = info.getIcon();
@@ -1683,19 +1366,22 @@
// ActivityIntentResolver.
protected final ArrayMap<ComponentName, ParsedActivity> mActivities =
new ArrayMap<>();
- private long mFlags;
}
// Both receivers and activities share a class, but point to different get methods
- private static final class ReceiverIntentResolver extends ActivityIntentResolver {
+ public static final class ReceiverIntentResolver extends ActivityIntentResolver {
// Default constructor
- ReceiverIntentResolver() {
+ ReceiverIntentResolver(@NonNull UserManagerService userManager,
+ @NonNull UserNeedsBadgingCache userNeedsBadgingCache) {
+ super(userManager, userNeedsBadgingCache);
}
// Copy constructor used in creating snapshots
- ReceiverIntentResolver(ReceiverIntentResolver orig) {
- super(orig);
+ ReceiverIntentResolver(@NonNull ReceiverIntentResolver orig,
+ @NonNull UserManagerService userManager,
+ @NonNull UserNeedsBadgingCache userNeedsBadgingCache) {
+ super(orig, userManager, userNeedsBadgingCache);
}
@Override
@@ -1704,48 +1390,50 @@
}
}
- private static final class ProviderIntentResolver
+ public static final class ProviderIntentResolver
extends MimeGroupsAwareIntentResolver<Pair<ParsedProvider, ParsedIntentInfo>, ResolveInfo> {
// Default constructor
- ProviderIntentResolver() {
+ ProviderIntentResolver(@NonNull UserManagerService userManager) {
+ super(userManager);
}
// Copy constructor used in creating snapshots
- ProviderIntentResolver(ProviderIntentResolver orig) {
- super(orig);
+ ProviderIntentResolver(@NonNull ProviderIntentResolver orig,
+ @NonNull UserManagerService userManager) {
+ super(orig, userManager);
mProviders.putAll(orig.mProviders);
- mFlags = orig.mFlags;
}
@Override
- public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
- boolean defaultOnly, int userId) {
- mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
- return super.queryIntent(intent, resolvedType, defaultOnly, userId);
- }
-
- @Nullable
- List<ResolveInfo> queryIntent(Intent intent, String resolvedType, long flags,
- int userId) {
- if (!sUserManager.exists(userId)) {
+ public List<ResolveInfo> queryIntent(@NonNull PackageDataSnapshot snapshot, Intent intent,
+ String resolvedType, boolean defaultOnly, @UserIdInt int userId) {
+ if (!mUserManager.exists(userId)) {
return null;
}
- mFlags = flags;
- return super.queryIntent(intent, resolvedType,
- (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- userId);
+ long flags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
+ return super.queryIntent(snapshot, intent, resolvedType, defaultOnly, userId, flags);
}
@Nullable
- List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
- long flags, List<ParsedProvider> packageProviders, int userId) {
- if (!sUserManager.exists(userId)) {
+ List<ResolveInfo> queryIntent(@NonNull Computer computer, Intent intent,
+ String resolvedType, long flags, int userId) {
+ if (!mUserManager.exists(userId)) {
+ return null;
+ }
+ return super.queryIntent(computer, intent, resolvedType,
+ (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId, flags);
+ }
+
+ @Nullable
+ List<ResolveInfo> queryIntentForPackage(@NonNull Computer computer, Intent intent,
+ String resolvedType, long flags, List<ParsedProvider> packageProviders,
+ int userId) {
+ if (!mUserManager.exists(userId)) {
return null;
}
if (packageProviders == null) {
return Collections.emptyList();
}
- mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
final int providersSize = packageProviders.size();
ArrayList<Pair<ParsedProvider, ParsedIntentInfo>[]> listCut =
@@ -1763,10 +1451,11 @@
listCut.add(array);
}
}
- return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
+ return super.queryIntentFromList(computer, intent, resolvedType,
+ defaultOnly, listCut, userId, flags);
}
- void addProvider(ParsedProvider p) {
+ void addProvider(@NonNull Computer computer, ParsedProvider p) {
if (mProviders.containsKey(p.getComponentName())) {
Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
return;
@@ -1789,7 +1478,7 @@
if (!intentFilter.debugCheck()) {
Log.w(TAG, "==> For Provider " + p.getName());
}
- addFilter(Pair.create(p, intent));
+ addFilter(computer, Pair.create(p, intent));
}
}
@@ -1832,21 +1521,16 @@
}
@Override
- protected boolean isFilterStopped(Pair<ParsedProvider, ParsedIntentInfo> filter,
- int userId) {
- return ComponentResolver.isFilterStopped(filter, userId);
- }
-
- @Override
protected boolean isPackageForFilter(String packageName,
Pair<ParsedProvider, ParsedIntentInfo> info) {
return packageName.equals(info.first.getPackageName());
}
@Override
- protected ResolveInfo newResult(Pair<ParsedProvider, ParsedIntentInfo> pair,
- int match, int userId) {
- if (!sUserManager.exists(userId)) {
+ protected ResolveInfo newResult(@NonNull Computer computer,
+ Pair<ParsedProvider, ParsedIntentInfo> pair, int match, int userId,
+ long customFlags) {
+ if (!mUserManager.exists(userId)) {
return null;
}
@@ -1854,24 +1538,18 @@
ParsedIntentInfo intentInfo = pair.second;
IntentFilter filter = intentInfo.getIntentFilter();
- AndroidPackage pkg = sPackageManagerInternal.getPackage(provider.getPackageName());
- if (pkg == null) {
+ PackageStateInternal packageState =
+ computer.getPackageStateInternal(provider.getPackageName());
+ if (packageState == null || packageState.getPkg() == null
+ || !PackageStateUtils.isEnabledAndMatches(packageState, provider, customFlags,
+ userId)) {
return null;
}
- if (!sPackageManagerInternal.isEnabledAndMatches(provider, mFlags, userId)) {
- return null;
- }
-
- PackageStateInternal ps =
- sPackageManagerInternal.getPackageStateInternal(provider.getPackageName());
- if (ps == null) {
- return null;
- }
- final PackageUserStateInternal userState = ps.getUserStateOrDefault(userId);
- final boolean matchVisibleToInstantApp = (mFlags
+ final PackageUserStateInternal userState = packageState.getUserStateOrDefault(userId);
+ final boolean matchVisibleToInstantApp = (customFlags
& PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
- final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
+ final boolean isInstantApp = (customFlags & PackageManager.MATCH_INSTANT) != 0;
// throw out filters that aren't visible to instant applications
if (matchVisibleToInstantApp
&& !(filter.isVisibleToInstantApp() || userState.isInstantApp())) {
@@ -1883,22 +1561,22 @@
}
// throw out instant application filters if updates are available; will trigger
// instant application resolution
- if (userState.isInstantApp() && ps.isUpdateAvailable()) {
+ if (userState.isInstantApp() && packageState.isUpdateAvailable()) {
return null;
}
final ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
- pkg, mFlags, userState, userId, ps);
+ packageState.getPkg(), customFlags, userState, userId, packageState);
if (appInfo == null) {
return null;
}
- ProviderInfo pi = PackageInfoUtils.generateProviderInfo(pkg, provider, mFlags,
- userState, appInfo, userId, ps);
+ ProviderInfo pi = PackageInfoUtils.generateProviderInfo(packageState.getPkg(), provider,
+ customFlags, userState, appInfo, userId, packageState);
if (pi == null) {
return null;
}
final ResolveInfo res = new ResolveInfo();
res.providerInfo = pi;
- if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
+ if ((customFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
res.filter = filter;
}
res.priority = filter.getPriority();
@@ -1959,46 +1637,46 @@
return input.second.getIntentFilter();
}
- private final ArrayMap<ComponentName, ParsedProvider> mProviders = new ArrayMap<>();
- private long mFlags;
+ final ArrayMap<ComponentName, ParsedProvider> mProviders = new ArrayMap<>();
}
- private static final class ServiceIntentResolver
+ public static final class ServiceIntentResolver
extends MimeGroupsAwareIntentResolver<Pair<ParsedService, ParsedIntentInfo>, ResolveInfo> {
// Default constructor
- ServiceIntentResolver() {
+ ServiceIntentResolver(@NonNull UserManagerService userManager) {
+ super(userManager);
}
// Copy constructor used in creating snapshots
- ServiceIntentResolver(ServiceIntentResolver orig) {
- copyFrom(orig);
+ ServiceIntentResolver(@NonNull ServiceIntentResolver orig,
+ @NonNull UserManagerService userManager) {
+ super(orig, userManager);
mServices.putAll(orig.mServices);
- mFlags = orig.mFlags;
}
@Override
- public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
- boolean defaultOnly, int userId) {
- mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
- return super.queryIntent(intent, resolvedType, defaultOnly, userId);
+ public List<ResolveInfo> queryIntent(@NonNull PackageDataSnapshot snapshot, Intent intent,
+ String resolvedType, boolean defaultOnly, @UserIdInt int userId) {
+ if (!mUserManager.exists(userId)) {
+ return null;
+ }
+ long flags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
+ return super.queryIntent(snapshot, intent, resolvedType, defaultOnly, userId, flags);
}
- List<ResolveInfo> queryIntent(Intent intent, String resolvedType, long flags,
- int userId) {
- if (!sUserManager.exists(userId)) return null;
- mFlags = flags;
- return super.queryIntent(intent, resolvedType,
- (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- userId);
+ List<ResolveInfo> queryIntent(@NonNull Computer computer, Intent intent,
+ String resolvedType, long flags, int userId) {
+ if (!mUserManager.exists(userId)) return null;
+ return super.queryIntent(computer, intent, resolvedType,
+ (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId, flags);
}
- List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
- long flags, List<ParsedService> packageServices, int userId) {
- if (!sUserManager.exists(userId)) return null;
+ List<ResolveInfo> queryIntentForPackage(@NonNull Computer computer, Intent intent,
+ String resolvedType, long flags, List<ParsedService> packageServices, int userId) {
+ if (!mUserManager.exists(userId)) return null;
if (packageServices == null) {
return Collections.emptyList();
}
- mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
final int servicesSize = packageServices.size();
ArrayList<Pair<ParsedService, ParsedIntentInfo>[]> listCut =
@@ -2016,10 +1694,11 @@
listCut.add(array);
}
}
- return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
+ return super.queryIntentFromList(computer, intent, resolvedType,
+ defaultOnly, listCut, userId, flags);
}
- void addService(ParsedService s) {
+ void addService(@NonNull Computer computer, ParsedService s) {
mServices.put(s.getComponentName(), s);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " service:");
@@ -2037,7 +1716,7 @@
if (!intentFilter.debugCheck()) {
Log.w(TAG, "==> For Service " + s.getName());
}
- addFilter(Pair.create(s, intent));
+ addFilter(computer, Pair.create(s, intent));
}
}
@@ -2080,48 +1759,38 @@
}
@Override
- protected boolean isFilterStopped(Pair<ParsedService, ParsedIntentInfo> filter, int userId) {
- return ComponentResolver.isFilterStopped(filter, userId);
- }
-
- @Override
protected boolean isPackageForFilter(String packageName,
Pair<ParsedService, ParsedIntentInfo> info) {
return packageName.equals(info.first.getPackageName());
}
@Override
- protected ResolveInfo newResult(Pair<ParsedService, ParsedIntentInfo> pair, int match,
- int userId) {
- if (!sUserManager.exists(userId)) return null;
+ protected ResolveInfo newResult(@NonNull Computer computer,
+ Pair<ParsedService, ParsedIntentInfo> pair, int match, int userId,
+ long customFlags) {
+ if (!mUserManager.exists(userId)) return null;
ParsedService service = pair.first;
ParsedIntentInfo intentInfo = pair.second;
IntentFilter filter = intentInfo.getIntentFilter();
- AndroidPackage pkg = sPackageManagerInternal.getPackage(service.getPackageName());
- if (pkg == null) {
+ final PackageStateInternal packageState = computer.getPackageStateInternal(
+ service.getPackageName());
+ if (packageState == null || packageState.getPkg() == null
+ || !PackageStateUtils.isEnabledAndMatches(packageState, service, customFlags,
+ userId)) {
return null;
}
- if (!sPackageManagerInternal.isEnabledAndMatches(service, mFlags, userId)) {
- return null;
- }
-
- PackageStateInternal ps =
- sPackageManagerInternal.getPackageStateInternal(service.getPackageName());
- if (ps == null) {
- return null;
- }
- final PackageUserStateInternal userState = ps.getUserStateOrDefault(userId);
- ServiceInfo si = PackageInfoUtils.generateServiceInfo(pkg, service, mFlags,
- userState, userId, ps);
+ final PackageUserStateInternal userState = packageState.getUserStateOrDefault(userId);
+ ServiceInfo si = PackageInfoUtils.generateServiceInfo(packageState.getPkg(), service,
+ customFlags, userState, userId, packageState);
if (si == null) {
return null;
}
final boolean matchVisibleToInstantApp =
- (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
- final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
+ (customFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+ final boolean isInstantApp = (customFlags & PackageManager.MATCH_INSTANT) != 0;
// throw out filters that aren't visible to ephemeral apps
if (matchVisibleToInstantApp
&& !(filter.isVisibleToInstantApp() || userState.isInstantApp())) {
@@ -2133,12 +1802,12 @@
}
// throw out instant app filters if updates are available; will trigger
// instant app resolution
- if (userState.isInstantApp() && ps.isUpdateAvailable()) {
+ if (userState.isInstantApp() && packageState.isUpdateAvailable()) {
return null;
}
final ResolveInfo res = new ResolveInfo();
res.serviceInfo = si;
- if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
+ if ((customFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
res.filter = filter;
}
res.priority = filter.getPriority();
@@ -2203,11 +1872,10 @@
}
// Keys are String (activity class name), values are Activity.
- private final ArrayMap<ComponentName, ParsedService> mServices = new ArrayMap<>();
- private long mFlags;
+ final ArrayMap<ComponentName, ParsedService> mServices = new ArrayMap<>();
}
- static final class InstantAppIntentResolver
+ public static final class InstantAppIntentResolver
extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
AuxiliaryResolveInfo.AuxiliaryFilter> {
/**
@@ -2224,6 +1892,13 @@
final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult =
new ArrayMap<>();
+ @NonNull
+ private final UserManagerService mUserManager;
+
+ public InstantAppIntentResolver(@NonNull UserManagerService userManager) {
+ mUserManager = userManager;
+ }
+
@Override
protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
@@ -2236,9 +1911,10 @@
}
@Override
- protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
- AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
- if (!sUserManager.exists(userId)) {
+ protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(@NonNull Computer computer,
+ AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId,
+ long customFlags) {
+ if (!mUserManager.exists(userId)) {
return null;
}
final String packageName = responseObj.resolveInfo.getPackageName();
@@ -2296,40 +1972,17 @@
}
}
- private static boolean isFilterStopped(Pair<? extends ParsedComponent, ParsedIntentInfo> pair,
- int userId) {
- if (!sUserManager.exists(userId)) {
- return true;
- }
-
- AndroidPackage pkg = sPackageManagerInternal.getPackage(pair.first.getPackageName());
- if (pkg == null) {
- return false;
- }
-
- PackageStateInternal ps =
- sPackageManagerInternal.getPackageStateInternal(pair.first.getPackageName());
- if (ps == null) {
- return false;
- }
-
- // System apps are never considered stopped for purposes of
- // filtering, because there may be no way for the user to
- // actually re-launch them.
- return !ps.isSystem() && ps.getUserStateOrDefault(userId).isStopped();
- }
-
/**
* Removes MIME type from the group, by delegating to IntentResolvers
* @return true if any intent filters were changed due to this update
*/
- boolean updateMimeGroup(String packageName, String group) {
+ public boolean updateMimeGroup(@NonNull Computer computer, String packageName, String group) {
boolean hasChanges = false;
synchronized (mLock) {
- hasChanges |= mActivities.updateMimeGroup(packageName, group);
- hasChanges |= mProviders.updateMimeGroup(packageName, group);
- hasChanges |= mReceivers.updateMimeGroup(packageName, group);
- hasChanges |= mServices.updateMimeGroup(packageName, group);
+ hasChanges |= mActivities.updateMimeGroup(computer, packageName, group);
+ hasChanges |= mProviders.updateMimeGroup(computer, packageName, group);
+ hasChanges |= mReceivers.updateMimeGroup(computer, packageName, group);
+ hasChanges |= mServices.updateMimeGroup(computer, packageName, group);
if (hasChanges) {
onChanged();
}
diff --git a/services/core/java/com/android/server/pm/resolution/ComponentResolverApi.java b/services/core/java/com/android/server/pm/resolution/ComponentResolverApi.java
new file mode 100644
index 0000000..b6f2b2a0
--- /dev/null
+++ b/services/core/java/com/android/server/pm/resolution/ComponentResolverApi.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.resolution;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.pm.Computer;
+import com.android.server.pm.pkg.component.ParsedActivity;
+import com.android.server.pm.pkg.component.ParsedProvider;
+import com.android.server.pm.pkg.component.ParsedService;
+
+import java.util.List;
+
+public interface ComponentResolverApi {
+
+ boolean isActivityDefined(@NonNull ComponentName component);
+
+ @Nullable
+ ParsedActivity getActivity(@NonNull ComponentName component);
+
+ @Nullable
+ ParsedProvider getProvider(@NonNull ComponentName component);
+
+ @Nullable
+ ParsedActivity getReceiver(@NonNull ComponentName component);
+
+ @Nullable
+ ParsedService getService(@NonNull ComponentName component);
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ boolean componentExists(@NonNull ComponentName componentName);
+
+ @Nullable
+ List<ResolveInfo> queryActivities(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @UserIdInt int userId);
+
+ @Nullable
+ List<ResolveInfo> queryActivities(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> activities,
+ @UserIdInt int userId);
+
+ @Nullable
+ ProviderInfo queryProvider(@NonNull Computer computer, @NonNull String authority, long flags,
+ @UserIdInt int userId);
+
+ @Nullable
+ List<ResolveInfo> queryProviders(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @UserIdInt int userId);
+
+ @Nullable
+ List<ResolveInfo> queryProviders(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedProvider> providers,
+ @UserIdInt int userId);
+
+ @Nullable
+ List<ProviderInfo> queryProviders(@NonNull Computer computer, @Nullable String processName,
+ @Nullable String metaDataKey, int uid, long flags, @UserIdInt int userId);
+
+ @Nullable
+ List<ResolveInfo> queryReceivers(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @UserIdInt int userId);
+
+ @Nullable
+ List<ResolveInfo> queryReceivers(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> receivers,
+ @UserIdInt int userId);
+
+ @Nullable
+ List<ResolveInfo> queryServices(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @UserIdInt int userId);
+
+ @Nullable
+ List<ResolveInfo> queryServices(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedService> services,
+ @UserIdInt int userId);
+
+ void querySyncProviders(@NonNull Computer computer, @NonNull List<String> outNames,
+ @NonNull List<ProviderInfo> outInfo, boolean safeMode, @UserIdInt int userId);
+}
diff --git a/services/core/java/com/android/server/pm/resolution/ComponentResolverBase.java b/services/core/java/com/android/server/pm/resolution/ComponentResolverBase.java
new file mode 100644
index 0000000..6b50fc6
--- /dev/null
+++ b/services/core/java/com/android/server/pm/resolution/ComponentResolverBase.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.resolution;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+
+import com.android.server.pm.Computer;
+import com.android.server.pm.UserManagerService;
+import com.android.server.pm.parsing.PackageInfoUtils;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.PackageStateInternal;
+import com.android.server.pm.pkg.PackageUserStateInternal;
+import com.android.server.pm.pkg.component.ParsedActivity;
+import com.android.server.pm.pkg.component.ParsedMainComponent;
+import com.android.server.pm.pkg.component.ParsedProvider;
+import com.android.server.pm.pkg.component.ParsedService;
+import com.android.server.utils.WatchableImpl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class ComponentResolverBase extends WatchableImpl implements ComponentResolverApi {
+
+ @NonNull
+ protected ComponentResolver.ActivityIntentResolver mActivities;
+
+ @NonNull
+ protected ComponentResolver.ProviderIntentResolver mProviders;
+
+ @NonNull
+ protected ComponentResolver.ReceiverIntentResolver mReceivers;
+
+ @NonNull
+ protected ComponentResolver.ServiceIntentResolver mServices;
+
+ /** Mapping from provider authority [first directory in content URI codePath) to provider. */
+ @NonNull
+ protected ArrayMap<String, ParsedProvider> mProvidersByAuthority;
+
+ @NonNull
+ protected UserManagerService mUserManager;
+
+ protected ComponentResolverBase(@NonNull UserManagerService userManager) {
+ mUserManager = userManager;
+ }
+
+ @Override
+ public boolean componentExists(@NonNull ComponentName componentName) {
+ ParsedMainComponent component = mActivities.mActivities.get(componentName);
+ if (component != null) {
+ return true;
+ }
+ component = mReceivers.mActivities.get(componentName);
+ if (component != null) {
+ return true;
+ }
+ component = mServices.mServices.get(componentName);
+ if (component != null) {
+ return true;
+ }
+ return mProviders.mProviders.get(componentName) != null;
+ }
+
+ @Nullable
+ @Override
+ public ParsedActivity getActivity(@NonNull ComponentName component) {
+ return mActivities.mActivities.get(component);
+ }
+
+ @Nullable
+ @Override
+ public ParsedProvider getProvider(@NonNull ComponentName component) {
+ return mProviders.mProviders.get(component);
+ }
+
+ @Nullable
+ @Override
+ public ParsedActivity getReceiver(@NonNull ComponentName component) {
+ return mReceivers.mActivities.get(component);
+ }
+
+ @Nullable
+ @Override
+ public ParsedService getService(@NonNull ComponentName component) {
+ return mServices.mServices.get(component);
+ }
+
+ /**
+ * Returns {@code true} if the given activity is defined by some package
+ */
+ @Override
+ public boolean isActivityDefined(@NonNull ComponentName component) {
+ return mActivities.mActivities.get(component) != null;
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryActivities(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, int userId) {
+ return mActivities.queryIntent(computer, intent, resolvedType, flags, userId);
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryActivities(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> activities,
+ int userId) {
+ return mActivities.queryIntentForPackage(computer, intent, resolvedType, flags, activities,
+ userId);
+ }
+
+ @Nullable
+ @Override
+ public ProviderInfo queryProvider(@NonNull Computer computer, @NonNull String authority,
+ long flags, int userId) {
+ final ParsedProvider p = mProvidersByAuthority.get(authority);
+ if (p == null) {
+ return null;
+ }
+ PackageStateInternal packageState = computer.getPackageStateInternal(p.getPackageName());
+ if (packageState == null) {
+ return null;
+ }
+ final AndroidPackage pkg = packageState.getPkg();
+ if (pkg == null) {
+ return null;
+ }
+ final PackageUserStateInternal state = packageState.getUserStateOrDefault(userId);
+ ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
+ pkg, flags, state, userId, packageState);
+ if (appInfo == null) {
+ return null;
+ }
+ return PackageInfoUtils.generateProviderInfo(pkg, p, flags, state, appInfo, userId,
+ packageState);
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryProviders(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, int userId) {
+ return mProviders.queryIntent(computer, intent, resolvedType, flags, userId);
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryProviders(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedProvider> providers,
+ @UserIdInt int userId) {
+ return mProviders.queryIntentForPackage(computer, intent, resolvedType, flags, providers,
+ userId);
+ }
+
+ @Nullable
+ @Override
+ public List<ProviderInfo> queryProviders(@NonNull Computer computer,
+ @Nullable String processName, @Nullable String metaDataKey, int uid, long flags,
+ int userId) {
+ if (!mUserManager.exists(userId)) {
+ return null;
+ }
+ List<ProviderInfo> providerList = null;
+ PackageInfoUtils.CachedApplicationInfoGenerator appInfoGenerator = null;
+ for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) {
+ final ParsedProvider p = mProviders.mProviders.valueAt(i);
+ if (p.getAuthority() == null) {
+ continue;
+ }
+
+ final PackageStateInternal ps = computer.getPackageStateInternal(p.getPackageName());
+ if (ps == null) {
+ continue;
+ }
+
+ AndroidPackage pkg = ps.getPkg();
+ if (pkg == null) {
+ continue;
+ }
+
+ if (processName != null && (!p.getProcessName().equals(processName)
+ || !UserHandle.isSameApp(pkg.getUid(), uid))) {
+ continue;
+ }
+ // See PM.queryContentProviders()'s javadoc for why we have the metaData parameter.
+ if (metaDataKey != null && !p.getMetaData().containsKey(metaDataKey)) {
+ continue;
+ }
+ if (appInfoGenerator == null) {
+ appInfoGenerator = new PackageInfoUtils.CachedApplicationInfoGenerator();
+ }
+ final PackageUserStateInternal state = ps.getUserStateOrDefault(userId);
+ final ApplicationInfo appInfo =
+ appInfoGenerator.generate(pkg, flags, state, userId, ps);
+ if (appInfo == null) {
+ continue;
+ }
+
+ final ProviderInfo info = PackageInfoUtils.generateProviderInfo(
+ pkg, p, flags, state, appInfo, userId, ps);
+ if (info == null) {
+ continue;
+ }
+ if (providerList == null) {
+ providerList = new ArrayList<>(i + 1);
+ }
+ providerList.add(info);
+ }
+ return providerList;
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryReceivers(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, int userId) {
+ return mReceivers.queryIntent(computer, intent, resolvedType, flags, userId);
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryReceivers(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> receivers,
+ @UserIdInt int userId) {
+ return mReceivers.queryIntentForPackage(computer, intent, resolvedType, flags, receivers,
+ userId);
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryServices(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @UserIdInt int userId) {
+ return mServices.queryIntent(computer, intent, resolvedType, flags, userId);
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryServices(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedService> services,
+ @UserIdInt int userId) {
+ return mServices.queryIntentForPackage(computer, intent, resolvedType, flags, services,
+ userId);
+ }
+
+ @Override
+ public void querySyncProviders(@NonNull Computer computer, @NonNull List<String> outNames,
+ @NonNull List<ProviderInfo> outInfo, boolean safeMode, int userId) {
+ PackageInfoUtils.CachedApplicationInfoGenerator appInfoGenerator = null;
+ for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) {
+ final ParsedProvider p = mProvidersByAuthority.valueAt(i);
+ if (!p.isSyncable()) {
+ continue;
+ }
+
+ final PackageStateInternal ps = computer.getPackageStateInternal(p.getPackageName());
+ if (ps == null) {
+ continue;
+ }
+
+ final AndroidPackage pkg = ps.getPkg();
+ if (pkg == null) {
+ continue;
+ }
+
+ if (safeMode && !pkg.isSystem()) {
+ continue;
+ }
+ if (appInfoGenerator == null) {
+ appInfoGenerator = new PackageInfoUtils.CachedApplicationInfoGenerator();
+ }
+ final PackageUserStateInternal state = ps.getUserStateOrDefault(userId);
+ final ApplicationInfo appInfo =
+ appInfoGenerator.generate(pkg, 0, state, userId, ps);
+ if (appInfo == null) {
+ continue;
+ }
+
+ final ProviderInfo info = PackageInfoUtils.generateProviderInfo(
+ pkg, p, 0, state, appInfo, userId, ps);
+ if (info == null) {
+ continue;
+ }
+ outNames.add(mProvidersByAuthority.keyAt(i));
+ outInfo.add(info);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/resolution/ComponentResolverLocked.java b/services/core/java/com/android/server/pm/resolution/ComponentResolverLocked.java
new file mode 100644
index 0000000..ecc53eb
--- /dev/null
+++ b/services/core/java/com/android/server/pm/resolution/ComponentResolverLocked.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.resolution;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+
+import com.android.server.pm.Computer;
+import com.android.server.pm.PackageManagerTracedLock;
+import com.android.server.pm.UserManagerService;
+import com.android.server.pm.pkg.component.ParsedActivity;
+import com.android.server.pm.pkg.component.ParsedProvider;
+import com.android.server.pm.pkg.component.ParsedService;
+
+import java.util.List;
+
+public abstract class ComponentResolverLocked extends ComponentResolverBase {
+
+ protected final PackageManagerTracedLock mLock = new PackageManagerTracedLock();
+
+ protected ComponentResolverLocked(@NonNull UserManagerService userManager) {
+ super(userManager);
+ }
+
+ @Override
+ public boolean componentExists(@NonNull ComponentName componentName) {
+ synchronized (mLock) {
+ return super.componentExists(componentName);
+ }
+ }
+
+ @Nullable
+ @Override
+ public ParsedActivity getActivity(@NonNull ComponentName component) {
+ synchronized (mLock) {
+ return super.getActivity(component);
+ }
+ }
+
+ @Nullable
+ @Override
+ public ParsedProvider getProvider(@NonNull ComponentName component) {
+ synchronized (mLock) {
+ return super.getProvider(component);
+ }
+ }
+
+ @Nullable
+ @Override
+ public ParsedActivity getReceiver(@NonNull ComponentName component) {
+ synchronized (mLock) {
+ return super.getReceiver(component);
+ }
+ }
+
+ @Nullable
+ @Override
+ public ParsedService getService(@NonNull ComponentName component) {
+ synchronized (mLock) {
+ return super.getService(component);
+ }
+ }
+
+ @Override
+ public boolean isActivityDefined(@NonNull ComponentName component) {
+ synchronized (mLock) {
+ return super.isActivityDefined(component);
+ }
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryActivities(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryActivities(computer, intent, resolvedType, flags, userId);
+ }
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryActivities(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> activities,
+ @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryActivities(computer, intent, resolvedType, flags, activities, userId);
+ }
+ }
+
+ @Nullable
+ @Override
+ public ProviderInfo queryProvider(@NonNull Computer computer, @NonNull String authority,
+ long flags, @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryProvider(computer, authority, flags, userId);
+ }
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryProviders(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryProviders(computer, intent, resolvedType, flags, userId);
+ }
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryProviders(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedProvider> providers,
+ @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryProviders(computer, intent, resolvedType, flags, providers, userId);
+ }
+ }
+
+ @Nullable
+ @Override
+ public List<ProviderInfo> queryProviders(@NonNull Computer computer,
+ @Nullable String processName, @Nullable String metaDataKey, int uid, long flags,
+ @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryProviders(computer, processName, metaDataKey, uid, flags, userId);
+ }
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryReceivers(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryReceivers(computer, intent, resolvedType, flags, userId);
+ }
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryReceivers(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedActivity> receivers,
+ @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryReceivers(computer, intent, resolvedType, flags, receivers, userId);
+ }
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryServices(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryServices(computer, intent, resolvedType, flags, userId);
+ }
+ }
+
+ @Nullable
+ @Override
+ public List<ResolveInfo> queryServices(@NonNull Computer computer, @NonNull Intent intent,
+ @Nullable String resolvedType, long flags, @NonNull List<ParsedService> services,
+ @UserIdInt int userId) {
+ synchronized (mLock) {
+ return super.queryServices(computer, intent, resolvedType, flags, services, userId);
+ }
+ }
+
+ @Override
+ public void querySyncProviders(@NonNull Computer computer, @NonNull List<String> outNames,
+ @NonNull List<ProviderInfo> outInfo, boolean safeMode, @UserIdInt int userId) {
+ synchronized (mLock) {
+ super.querySyncProviders(computer, outNames, outInfo, safeMode, userId);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/pm/resolution/ComponentResolverSnapshot.java b/services/core/java/com/android/server/pm/resolution/ComponentResolverSnapshot.java
new file mode 100644
index 0000000..3a96fe6
--- /dev/null
+++ b/services/core/java/com/android/server/pm/resolution/ComponentResolverSnapshot.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.resolution;
+
+import android.annotation.NonNull;
+import android.util.ArrayMap;
+
+import com.android.server.pm.UserManagerService;
+import com.android.server.pm.UserNeedsBadgingCache;
+
+public class ComponentResolverSnapshot extends ComponentResolverBase {
+
+ public ComponentResolverSnapshot(@NonNull ComponentResolver orig,
+ @NonNull UserNeedsBadgingCache userNeedsBadgingCache) {
+ super(UserManagerService.getInstance());
+ mActivities = new ComponentResolver.ActivityIntentResolver(orig.mActivities, mUserManager,
+ userNeedsBadgingCache);
+ mProviders = new ComponentResolver.ProviderIntentResolver(orig.mProviders, mUserManager);
+ mReceivers = new ComponentResolver.ReceiverIntentResolver(orig.mReceivers, mUserManager,
+ userNeedsBadgingCache);
+ mServices = new ComponentResolver.ServiceIntentResolver(orig.mServices, mUserManager);
+ mProvidersByAuthority = new ArrayMap<>(orig.mProvidersByAuthority);
+ }
+}
diff --git a/services/core/java/com/android/server/pm/snapshot/PackageDataSnapshot.java b/services/core/java/com/android/server/pm/snapshot/PackageDataSnapshot.java
new file mode 100644
index 0000000..b091445
--- /dev/null
+++ b/services/core/java/com/android/server/pm/snapshot/PackageDataSnapshot.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.snapshot;
+
+public interface PackageDataSnapshot {
+}
diff --git a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
index c5709fc..43b2e1e 100644
--- a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
+++ b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt
@@ -29,6 +29,7 @@
import com.android.server.pm.parsing.pkg.AndroidPackage
import com.android.server.pm.parsing.pkg.PackageImpl
import com.android.server.pm.parsing.pkg.ParsedPackage
+import com.android.server.pm.resolution.ComponentResolver
import com.android.server.pm.test.override.PackageManagerComponentLabelIconOverrideTest.Companion.Params.AppType
import com.android.server.testutils.TestHandler
import com.android.server.testutils.mock
@@ -46,6 +47,8 @@
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.doReturn
import org.mockito.Mockito.intThat
import org.mockito.Mockito.never
import org.mockito.Mockito.same
@@ -337,8 +340,8 @@
val mockSettings = Settings(mockedPkgSettings)
val mockComponentResolver: ComponentResolver = mockThrowOnUnmocked {
params.componentName?.let {
- whenever(this.componentExists(same(it))) { mockActivity != null }
- whenever(this.getActivity(same(it))) { mockActivity }
+ doReturn(mockActivity != null).`when`(this).componentExists(same(it))
+ doReturn(mockActivity).`when`(this).getActivity(same(it))
}
whenever(this.snapshot()) { this@mockThrowOnUnmocked }
whenever(registerObserver(any())).thenCallRealMethod()
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 4ec1641..ca5bf20 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -68,6 +68,7 @@
import com.android.server.pm.permission.PermissionManagerServiceInternal
import com.android.server.pm.pkg.parsing.ParsingPackage
import com.android.server.pm.pkg.parsing.ParsingPackageUtils
+import com.android.server.pm.resolution.ComponentResolver
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
import com.android.server.supplementalprocess.SupplementalProcessManagerLocal
import com.android.server.testutils.TestHandler
@@ -632,7 +633,7 @@
}
private fun mockQueryActivities(action: String, vararg activities: ActivityInfo) {
- whenever(mocks.componentResolver.queryActivities(
+ whenever(mocks.componentResolver.queryActivities(any(),
argThat { intent: Intent? -> intent != null && (action == intent.action) },
nullable(), anyLong(), anyInt())) {
ArrayList(activities.asList().map { info: ActivityInfo? ->
@@ -642,7 +643,7 @@
}
private fun mockQueryServices(action: String, vararg services: ServiceInfo) {
- whenever(mocks.componentResolver.queryServices(
+ whenever(mocks.componentResolver.queryServices(any(),
argThat { intent: Intent? -> intent != null && (action == intent.action) },
nullable(), anyLong(), anyInt())) {
ArrayList(services.asList().map { info ->
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index 8873f42..6789af4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -225,7 +225,11 @@
assertThat(packageUserState1.isSuspended(), is(true));
assertThat(packageUserState1.getSuspendParams().size(), is(1));
assertThat(packageUserState1.getSuspendParams().keyAt(0), is("android"));
- assertThat(packageUserState1.getSuspendParams().valueAt(0), is(nullValue()));
+ assertThat(packageUserState1.getSuspendParams().valueAt(0).getAppExtras(), is(nullValue()));
+ assertThat(packageUserState1.getSuspendParams().valueAt(0).getDialogInfo(),
+ is(nullValue()));
+ assertThat(packageUserState1.getSuspendParams().valueAt(0).getLauncherExtras(),
+ is(nullValue()));
// Verify that the snapshot returns the same answers
ps1 = snapshot.mPackages.get(PACKAGE_NAME_1);
@@ -233,7 +237,11 @@
assertThat(packageUserState1.isSuspended(), is(true));
assertThat(packageUserState1.getSuspendParams().size(), is(1));
assertThat(packageUserState1.getSuspendParams().keyAt(0), is("android"));
- assertThat(packageUserState1.getSuspendParams().valueAt(0), is(nullValue()));
+ assertThat(packageUserState1.getSuspendParams().valueAt(0).getAppExtras(), is(nullValue()));
+ assertThat(packageUserState1.getSuspendParams().valueAt(0).getDialogInfo(),
+ is(nullValue()));
+ assertThat(packageUserState1.getSuspendParams().valueAt(0).getLauncherExtras(),
+ is(nullValue()));
PackageSetting ps2 = settingsUnderTest.mPackages.get(PACKAGE_NAME_2);
PackageUserStateInternal packageUserState2 = ps2.readUserState(0);
@@ -315,14 +323,14 @@
.build();
ps1.modifyUserState(0).putSuspendParams( "suspendingPackage1",
- SuspendParams.getInstanceOrNull(dialogInfo1, appExtras1, launcherExtras1));
+ new SuspendParams(dialogInfo1, appExtras1, launcherExtras1));
ps1.modifyUserState(0).putSuspendParams( "suspendingPackage2",
- SuspendParams.getInstanceOrNull(dialogInfo2, appExtras2, launcherExtras2));
+ new SuspendParams(dialogInfo2, appExtras2, launcherExtras2));
settingsUnderTest.mPackages.put(PACKAGE_NAME_1, ps1);
watcher.verifyChangeReported("put package 1");
ps2.modifyUserState(0).putSuspendParams( "suspendingPackage3",
- SuspendParams.getInstanceOrNull(null, appExtras1, null));
+ new SuspendParams(null, appExtras1, null));
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
watcher.verifyChangeReported("put package 2");
@@ -686,7 +694,7 @@
.setNeutralButtonAction(BUTTON_ACTION_MORE_DETAILS)
.build();
origPkgSetting01.modifyUserState(0).putSuspendParams("suspendingPackage1",
- SuspendParams.getInstanceOrNull(dialogInfo1, appExtras1, launcherExtras1));
+ new SuspendParams(dialogInfo1, appExtras1, launcherExtras1));
final PackageSetting testPkgSetting01 = new PackageSetting(
PACKAGE_NAME /*pkgName*/,
REAL_PACKAGE_NAME /*realPkgName*/,
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
index 4dc9612..9ad503c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
@@ -85,7 +85,7 @@
oldUserState = new PackageUserStateImpl();
oldUserState.putSuspendParams("suspendingPackage",
- SuspendParams.getInstanceOrNull(null, new PersistableBundle(), null));
+ new SuspendParams(null, new PersistableBundle(), null));
assertThat(testUserState.equals(oldUserState), is(false));
oldUserState = new PackageUserStateImpl();
@@ -185,7 +185,7 @@
private static SuspendParams createSuspendParams(SuspendDialogInfo dialogInfo,
PersistableBundle appExtras, PersistableBundle launcherExtras) {
- return SuspendParams.getInstanceOrNull(dialogInfo, appExtras, launcherExtras);
+ return new SuspendParams(dialogInfo, appExtras, launcherExtras);
}
private static PersistableBundle createPersistableBundle(String lKey, long lValue, String sKey,
diff --git a/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java b/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
index 95af1e1..6e03569 100644
--- a/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
@@ -145,7 +145,7 @@
IntentFilter i = new IntentFilter("TEST_ACTION");
PreferredActivity a1 = new PreferredActivity(i, 1, components, component, true);
- r.addFilter(a1);
+ r.addFilter(null, a1);
watcher.verifyChangeReported("addFilter");
i.setPriority(i.getPriority() + 1);
watcher.verifyNoChangeReported("indepenent intent");