Merge "Move query methods"
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 823d995..20e1454e 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -649,14 +649,13 @@
public abstract boolean isDataRestoreSafe(@NonNull Signature restoringFromSig,
@NonNull String packageName);
-
/**
- * Returns true if the the signing information for {@code clientUid} is sufficient to gain
- * access gated by {@code capability}. This can happen if the two UIDs have the same signing
- * information, if the signing information {@code clientUid} indicates that it has the signing
- * certificate for {@code serverUid} in its signing history (if it was previously signed by it),
- * or if the signing certificate for {@code clientUid} is in ths signing history for {@code
- * serverUid} and with the {@code capability} specified.
+ * Returns {@code true} if the the signing information for {@code clientUid} is sufficient
+ * to gain access gated by {@code capability}. This can happen if the two UIDs have the
+ * same signing information, if the signing information {@code clientUid} indicates that
+ * it has the signing certificate for {@code serverUid} in its signing history (if it was
+ * previously signed by it), or if the signing certificate for {@code clientUid} is in the
+ * signing history for {@code serverUid} and with the {@code capability} specified.
*/
public abstract boolean hasSignatureCapability(int serverUid, int clientUid,
@PackageParser.SigningDetails.CertCapabilities int capability);
@@ -697,4 +696,10 @@
*/
public abstract void freeStorage(String volumeUuid, long bytes, int storageFlags)
throws IOException;
+
+ /** Returns {@code true} if the specified component is enabled and matches the given flags. */
+ public abstract boolean isEnabledAndMatches(@NonNull ComponentInfo info, int flags, int userId);
+
+ /** Returns {@code true} if the given user requires extra badging for icons. */
+ public abstract boolean userNeedsBadging(int userId);
}
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java
new file mode 100644
index 0000000..2b2db62
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ComponentResolver.java
@@ -0,0 +1,1847 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+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 static com.android.server.pm.PackageManagerService.fixProcessName;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.AuxiliaryResolveInfo;
+import android.content.pm.InstantAppResolveInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.ActivityIntentInfo;
+import android.content.pm.PackageParser.ServiceIntentInfo;
+import android.content.pm.PackageUserState;
+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.Log;
+import android.util.LogPrinter;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.IntentResolver;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/** Resolves all Android component types [activities, services, providers and receivers]. */
+public class ComponentResolver {
+ private static final String TAG = "PackageManager";
+ private static final boolean DEBUG_FILTERS = false;
+ private static final boolean DEBUG_SHOW_INFO = false;
+
+ /**
+ * The set of all protected actions [i.e. those actions for which a high priority
+ * intent filter is disallowed].
+ */
+ private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
+ static {
+ PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
+ PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
+ PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
+ PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
+ }
+
+ 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);
+ if (v1 != v2) {
+ return (v1 > v2) ? -1 : 1;
+ }
+ v1 = r1.preferredOrder;
+ v2 = r2.preferredOrder;
+ if (v1 != v2) {
+ return (v1 > v2) ? -1 : 1;
+ }
+ if (r1.isDefault != r2.isDefault) {
+ return r1.isDefault ? -1 : 1;
+ }
+ v1 = r1.match;
+ v2 = r2.match;
+ //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
+ if (v1 != v2) {
+ return (v1 > v2) ? -1 : 1;
+ }
+ if (r1.system != r2.system) {
+ return r1.system ? -1 : 1;
+ }
+ if (r1.activityInfo != null) {
+ return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
+ }
+ if (r1.serviceInfo != null) {
+ return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
+ }
+ if (r1.providerInfo != null) {
+ return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
+ }
+ return 0;
+ };
+
+ private static UserManagerService sUserManager;
+ private static PackageManagerInternal sPackageManagerInternal;
+
+ private final Object mLock = new Object();
+
+ /** All available activities, for your resolving pleasure. */
+ @GuardedBy("mLock")
+ private final ActivityIntentResolver mActivities = new ActivityIntentResolver();
+
+ /** All available providers, for your resolving pleasure. */
+ @GuardedBy("mLock")
+ private final ProviderIntentResolver mProviders = new ProviderIntentResolver();
+
+ /** All available receivers, for your resolving pleasure. */
+ @GuardedBy("mLock")
+ private final ActivityIntentResolver mReceivers = new ActivityIntentResolver();
+
+ /** All available services, for your resolving pleasure. */
+ @GuardedBy("mLock")
+ private final ServiceIntentResolver mServices = new ServiceIntentResolver();
+
+ /** Mapping from provider authority [first directory in content URI codePath) to provider. */
+ @GuardedBy("mLock")
+ private final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = new ArrayMap<>();
+
+ /** Whether or not processing protected filters should be deferred. */
+ private boolean mDeferProtectedFilters = true;
+
+ /**
+ * Tracks high priority intent filters for protected actions. During boot, certain
+ * filter actions are protected and should never be allowed to have a high priority
+ * intent filter for them. However, there is one, and only one exception -- the
+ * setup wizard. It must be able to define a high priority intent filter for these
+ * actions to ensure there are no escapes from the wizard. We need to delay processing
+ * of these during boot as we need to inspect at all of the intent filters on the
+ * /system partition in order to know which component is the setup wizard. This can
+ * only ever be non-empty if {@link #mDeferProtectedFilters} is {@code true}.
+ */
+ private List<PackageParser.ActivityIntentInfo> mProtectedFilters;
+
+ ComponentResolver(UserManagerService userManager,
+ PackageManagerInternal packageManagerInternal) {
+ sPackageManagerInternal = packageManagerInternal;
+ sUserManager = userManager;
+ }
+
+ /** Returns the given activity */
+ PackageParser.Activity getActivity(ComponentName component) {
+ synchronized (mLock) {
+ return mActivities.mActivities.get(component);
+ }
+ }
+
+ /** Returns the given provider */
+ PackageParser.Provider getProvider(ComponentName component) {
+ synchronized (mLock) {
+ return mProviders.mProviders.get(component);
+ }
+ }
+
+ /** Returns the given receiver */
+ PackageParser.Activity getReceiver(ComponentName component) {
+ synchronized (mLock) {
+ return mReceivers.mActivities.get(component);
+ }
+ }
+
+ /** Returns the given service */
+ PackageParser.Service getService(ComponentName component) {
+ synchronized (mLock) {
+ return mServices.mServices.get(component);
+ }
+ }
+
+ List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags, int userId) {
+ synchronized (mLock) {
+ return mActivities.queryIntent(intent, resolvedType, flags, userId);
+ }
+ }
+
+ List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags,
+ List<PackageParser.Activity> activities, int userId) {
+ synchronized (mLock) {
+ return mActivities.queryIntentForPackage(
+ intent, resolvedType, flags, activities, userId);
+ }
+ }
+
+ List<ResolveInfo> queryProviders(Intent intent, String resolvedType, int flags, int userId) {
+ synchronized (mLock) {
+ return mProviders.queryIntent(intent, resolvedType, flags, userId);
+ }
+ }
+
+ List<ResolveInfo> queryProviders(Intent intent, String resolvedType, int flags,
+ List<PackageParser.Provider> providers, int userId) {
+ synchronized (mLock) {
+ return mProviders.queryIntentForPackage(intent, resolvedType, flags, providers, userId);
+ }
+ }
+
+ List<ProviderInfo> queryProviders(String processName, String metaDataKey, int uid, int flags,
+ int userId) {
+ if (!sUserManager.exists(userId)) {
+ return null;
+ }
+ List<ProviderInfo> providerList = null;
+ synchronized (mLock) {
+ for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) {
+ final PackageParser.Provider p = mProviders.mProviders.valueAt(i);
+ final PackageSetting ps = (PackageSetting) p.owner.mExtras;
+ if (ps == null) {
+ continue;
+ }
+ if (p.info.authority == null) {
+ continue;
+ }
+ if (processName != null && (!p.info.processName.equals(processName)
+ || !UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) {
+ continue;
+ }
+ // See PM.queryContentProviders()'s javadoc for why we have the metaData parameter.
+ if (metaDataKey != null
+ && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
+ continue;
+ }
+ final ProviderInfo info = PackageParser.generateProviderInfo(
+ p, flags, ps.readUserState(userId), userId);
+ if (info == null) {
+ continue;
+ }
+ if (providerList == null) {
+ providerList = new ArrayList<>(i + 1);
+ }
+ providerList.add(info);
+ }
+ }
+ return providerList;
+ }
+
+ ProviderInfo queryProvider(String authority, int flags, int userId) {
+ synchronized (mLock) {
+ final PackageParser.Provider p = mProvidersByAuthority.get(authority);
+ if (p == null) {
+ return null;
+ }
+ final PackageSetting ps = (PackageSetting) p.owner.mExtras;
+ if (ps == null) {
+ return null;
+ }
+ return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), userId);
+ }
+ }
+
+ void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo, boolean safeMode,
+ int userId) {
+ synchronized (mLock) {
+ for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) {
+ final PackageParser.Provider p = mProvidersByAuthority.valueAt(i);
+ final PackageSetting ps = (PackageSetting) p.owner.mExtras;
+ if (ps == null) {
+ continue;
+ }
+ if (!p.syncable) {
+ continue;
+ }
+ if (safeMode
+ && (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ continue;
+ }
+ final ProviderInfo info =
+ PackageParser.generateProviderInfo(p, 0, ps.readUserState(userId), userId);
+ if (info == null) {
+ continue;
+ }
+ outNames.add(mProvidersByAuthority.keyAt(i));
+ outInfo.add(info);
+ }
+ }
+ }
+
+ List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags, int userId) {
+ synchronized (mLock) {
+ return mReceivers.queryIntent(intent, resolvedType, flags, userId);
+ }
+ }
+
+ List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags,
+ List<PackageParser.Activity> receivers, int userId) {
+ synchronized (mLock) {
+ return mReceivers.queryIntentForPackage(intent, resolvedType, flags, receivers, userId);
+ }
+ }
+
+ List<ResolveInfo> queryServices(Intent intent, String resolvedType, int flags, int userId) {
+ synchronized (mLock) {
+ return mServices.queryIntent(intent, resolvedType, flags, userId);
+ }
+ }
+
+ List<ResolveInfo> queryServices(Intent intent, String resolvedType, int flags,
+ List<PackageParser.Service> 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(PackageParser.Package pkg) throws PackageManagerException {
+ synchronized (mLock) {
+ assertProvidersNotDefinedLocked(pkg);
+ }
+ }
+
+ /** Add all components defined in the given package to the internal structures. */
+ void addAllComponents(PackageParser.Package pkg, boolean chatty) {
+ final ArrayList<PackageParser.ActivityIntentInfo> newIntents = new ArrayList<>();
+ synchronized (mLock) {
+ addActivitiesLocked(pkg, newIntents, chatty);
+ addReceiversLocked(pkg, chatty);
+ addProvidersLocked(pkg, chatty);
+ addServicesLocked(pkg, chatty);
+ }
+ final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName(
+ PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM);
+ for (int i = newIntents.size() - 1; i >= 0; --i) {
+ final PackageParser.ActivityIntentInfo intentInfo = newIntents.get(i);
+ final PackageParser.Package disabledPkg = sPackageManagerInternal
+ .getDisabledPackage(intentInfo.activity.info.packageName);
+ final List<PackageParser.Activity> systemActivities =
+ disabledPkg != null ? disabledPkg.activities : null;
+ adjustPriority(systemActivities, intentInfo, setupWizardPackage);
+ }
+ }
+
+ /** Removes all components defined in the given package from the internal structures. */
+ void removeAllComponents(PackageParser.Package pkg, boolean chatty) {
+ synchronized (mLock) {
+ removeAllComponentsLocked(pkg, chatty);
+ }
+ }
+
+ /**
+ * 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() {
+ if (!mDeferProtectedFilters) {
+ return;
+ }
+ mDeferProtectedFilters = false;
+
+ if (mProtectedFilters == null || mProtectedFilters.size() == 0) {
+ return;
+ }
+ final List<ActivityIntentInfo> protectedFilters = mProtectedFilters;
+ mProtectedFilters = null;
+
+ final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName(
+ PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM);
+ if (DEBUG_FILTERS && setupWizardPackage == null) {
+ Slog.i(TAG, "No setup wizard;"
+ + " All protected intents capped to priority 0");
+ }
+ for (int i = protectedFilters.size() - 1; i >= 0; --i) {
+ final ActivityIntentInfo filter = protectedFilters.get(i);
+ if (filter.activity.info.packageName.equals(setupWizardPackage)) {
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Found setup wizard;"
+ + " allow priority " + filter.getPriority() + ";"
+ + " package: " + filter.activity.info.packageName
+ + " activity: " + filter.activity.className
+ + " priority: " + filter.getPriority());
+ }
+ // skip setup wizard; allow it to keep the high priority filter
+ continue;
+ }
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Protected action; cap priority to 0;"
+ + " package: " + filter.activity.info.packageName
+ + " activity: " + filter.activity.className
+ + " origPrio: " + filter.getPriority());
+ }
+ filter.setPriority(0);
+ }
+ }
+
+ void dumpActivityResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
+ if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
+ : "Activity Resolver Table:", " ", packageName,
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
+ dumpState.setTitlePrinted(true);
+ }
+ }
+
+ void dumpProviderResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
+ if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
+ : "Provider Resolver Table:", " ", packageName,
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
+ dumpState.setTitlePrinted(true);
+ }
+ }
+
+ void dumpReceiverResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
+ if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
+ : "Receiver Resolver Table:", " ", packageName,
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
+ dumpState.setTitlePrinted(true);
+ }
+ }
+
+ void dumpServiceResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
+ if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
+ : "Service Resolver Table:", " ", packageName,
+ dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
+ dumpState.setTitlePrinted(true);
+ }
+ }
+
+ void dumpContentProviders(PrintWriter pw, DumpState dumpState, String packageName) {
+ boolean printedSomething = false;
+ for (PackageParser.Provider p : mProviders.mProviders.values()) {
+ if (packageName != null && !packageName.equals(p.info.packageName)) {
+ continue;
+ }
+ if (!printedSomething) {
+ if (dumpState.onTitlePrinted()) {
+ pw.println();
+ }
+ pw.println("Registered ContentProviders:");
+ printedSomething = true;
+ }
+ pw.print(" "); p.printComponentShortName(pw); pw.println(":");
+ pw.print(" "); pw.println(p.toString());
+ }
+ printedSomething = false;
+ for (Map.Entry<String, PackageParser.Provider> entry :
+ mProvidersByAuthority.entrySet()) {
+ PackageParser.Provider p = entry.getValue();
+ if (packageName != null && !packageName.equals(p.info.packageName)) {
+ continue;
+ }
+ if (!printedSomething) {
+ if (dumpState.onTitlePrinted()) {
+ pw.println();
+ }
+ pw.println("ContentProvider Authorities:");
+ printedSomething = true;
+ }
+ pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
+ pw.print(" "); pw.println(p.toString());
+ if (p.info != null && p.info.applicationInfo != null) {
+ final String appInfo = p.info.applicationInfo.toString();
+ pw.print(" applicationInfo="); pw.println(appInfo);
+ }
+ }
+ }
+
+ void dumpServicePermissions(PrintWriter pw, DumpState dumpState, String packageName) {
+ if (dumpState.onTitlePrinted()) pw.println();
+ pw.println("Service permissions:");
+
+ final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
+ while (filterIterator.hasNext()) {
+ final ServiceIntentInfo info = filterIterator.next();
+ final ServiceInfo serviceInfo = info.service.info;
+ final String permission = serviceInfo.permission;
+ if (permission != null) {
+ pw.print(" ");
+ pw.print(serviceInfo.getComponentName().flattenToShortString());
+ pw.print(": ");
+ pw.println(permission);
+ }
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void addActivitiesLocked(PackageParser.Package pkg,
+ List<PackageParser.ActivityIntentInfo> newIntents, boolean chatty) {
+ final int activitiesSize = pkg.activities.size();
+ StringBuilder r = null;
+ for (int i = 0; i < activitiesSize; i++) {
+ PackageParser.Activity a = pkg.activities.get(i);
+ a.info.processName =
+ fixProcessName(pkg.applicationInfo.processName, a.info.processName);
+ mActivities.addActivity(a, "activity", newIntents);
+ if (DEBUG_PACKAGE_SCANNING && chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(a.info.name);
+ }
+ }
+ if (DEBUG_PACKAGE_SCANNING && chatty) {
+ Log.d(TAG, " Activities: " + (r == null ? "<NONE>" : r));
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void addProvidersLocked(PackageParser.Package pkg, boolean chatty) {
+ final int providersSize = pkg.providers.size();
+ StringBuilder r = null;
+ for (int i = 0; i < providersSize; i++) {
+ PackageParser.Provider p = pkg.providers.get(i);
+ p.info.processName = fixProcessName(pkg.applicationInfo.processName,
+ p.info.processName);
+ mProviders.addProvider(p);
+ p.syncable = p.info.isSyncable;
+ if (p.info.authority != null) {
+ String[] names = p.info.authority.split(";");
+ p.info.authority = null;
+ for (int j = 0; j < names.length; j++) {
+ if (j == 1 && p.syncable) {
+ // We only want the first authority for a provider to possibly be
+ // syncable, so if we already added this provider using a different
+ // authority clear the syncable flag. We copy the provider before
+ // changing it because the mProviders object contains a reference
+ // to a provider that we don't want to change.
+ // Only do this for the second authority since the resulting provider
+ // object can be the same for all future authorities for this provider.
+ p = new PackageParser.Provider(p);
+ p.syncable = false;
+ }
+ if (!mProvidersByAuthority.containsKey(names[j])) {
+ mProvidersByAuthority.put(names[j], p);
+ if (p.info.authority == null) {
+ p.info.authority = names[j];
+ } else {
+ p.info.authority = p.info.authority + ";" + names[j];
+ }
+ if (DEBUG_PACKAGE_SCANNING && chatty) {
+ Log.d(TAG, "Registered content provider: " + names[j]
+ + ", className = " + p.info.name
+ + ", isSyncable = " + p.info.isSyncable);
+ }
+ } else {
+ final PackageParser.Provider other =
+ mProvidersByAuthority.get(names[j]);
+ final ComponentName component =
+ (other != null && other.getComponentName() != null)
+ ? other.getComponentName() : null;
+ final String packageName =
+ component != null ? component.getPackageName() : "?";
+ Slog.w(TAG, "Skipping provider name " + names[j]
+ + " (in package " + pkg.applicationInfo.packageName + ")"
+ + ": name already used by " + packageName);
+ }
+ }
+ }
+ if (DEBUG_PACKAGE_SCANNING && chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(p.info.name);
+ }
+ }
+ if (DEBUG_PACKAGE_SCANNING && chatty) {
+ Log.d(TAG, " Providers: " + (r == null ? "<NONE>" : r));
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void addReceiversLocked(PackageParser.Package pkg, boolean chatty) {
+ final int receiversSize = pkg.receivers.size();
+ StringBuilder r = null;
+ for (int i = 0; i < receiversSize; i++) {
+ PackageParser.Activity a = pkg.receivers.get(i);
+ a.info.processName = fixProcessName(pkg.applicationInfo.processName,
+ a.info.processName);
+ mReceivers.addActivity(a, "receiver", null);
+ if (DEBUG_PACKAGE_SCANNING && chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(a.info.name);
+ }
+ }
+ if (DEBUG_PACKAGE_SCANNING && chatty) {
+ Log.d(TAG, " Receivers: " + (r == null ? "<NONE>" : r));
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void addServicesLocked(PackageParser.Package pkg, boolean chatty) {
+ final int servicesSize = pkg.services.size();
+ StringBuilder r = null;
+ for (int i = 0; i < servicesSize; i++) {
+ PackageParser.Service s = pkg.services.get(i);
+ s.info.processName = fixProcessName(pkg.applicationInfo.processName,
+ s.info.processName);
+ mServices.addService(s);
+ if (DEBUG_PACKAGE_SCANNING && chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(s.info.name);
+ }
+ }
+ if (DEBUG_PACKAGE_SCANNING && chatty) {
+ Log.d(TAG, " Services: " + (r == null ? "<NONE>" : r));
+ }
+ }
+
+
+ /**
+ * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
+ * MODIFIED. Do not pass in a list that should not be changed.
+ */
+ private static <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
+ IterGenerator<T> generator, Iterator<T> searchIterator) {
+ // loop through the set of actions; every one must be found in the intent filter
+ while (searchIterator.hasNext()) {
+ // we must have at least one filter in the list to consider a match
+ if (intentList.size() == 0) {
+ break;
+ }
+
+ final T searchAction = searchIterator.next();
+
+ // loop through the set of intent filters
+ final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
+ while (intentIter.hasNext()) {
+ final ActivityIntentInfo intentInfo = intentIter.next();
+ boolean selectionFound = false;
+
+ // loop through the intent filter's selection criteria; at least one
+ // of them must match the searched criteria
+ final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
+ while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
+ final T intentSelection = intentSelectionIter.next();
+ if (intentSelection != null && intentSelection.equals(searchAction)) {
+ selectionFound = true;
+ break;
+ }
+ }
+
+ // the selection criteria wasn't found in this filter's set; this filter
+ // is not a potential match
+ if (!selectionFound) {
+ intentIter.remove();
+ }
+ }
+ }
+ }
+
+ private static boolean isProtectedAction(ActivityIntentInfo filter) {
+ final Iterator<String> actionsIter = filter.actionsIterator();
+ while (actionsIter != null && actionsIter.hasNext()) {
+ final String filterAction = actionsIter.next();
+ if (PROTECTED_ACTIONS.contains(filterAction)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Finds a privileged activity that matches the specified activity names.
+ */
+ private static PackageParser.Activity findMatchingActivity(
+ List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
+ for (PackageParser.Activity sysActivity : activityList) {
+ if (sysActivity.info.name.equals(activityInfo.name)) {
+ return sysActivity;
+ }
+ if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
+ return sysActivity;
+ }
+ if (sysActivity.info.targetActivity != null) {
+ if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
+ return sysActivity;
+ }
+ if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
+ return sysActivity;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Adjusts the priority of the given intent filter according to policy.
+ * <p>
+ * <ul>
+ * <li>The priority for non privileged applications is capped to '0'</li>
+ * <li>The priority for protected actions on privileged applications is capped to '0'</li>
+ * <li>The priority for unbundled updates to privileged applications is capped to the
+ * priority defined on the system partition</li>
+ * </ul>
+ * <p>
+ * <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<PackageParser.Activity> systemActivities,
+ ActivityIntentInfo intent, String setupWizardPackage) {
+ // nothing to do; priority is fine as-is
+ if (intent.getPriority() <= 0) {
+ return;
+ }
+
+ final ActivityInfo activityInfo = intent.activity.info;
+ final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
+
+ final boolean privilegedApp =
+ ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
+ if (!privilegedApp) {
+ // non-privileged applications can never define a priority >0
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Non-privileged app; cap priority to 0;"
+ + " package: " + applicationInfo.packageName
+ + " activity: " + intent.activity.className
+ + " origPrio: " + intent.getPriority());
+ }
+ intent.setPriority(0);
+ return;
+ }
+
+ if (systemActivities == null) {
+ // the system package is not disabled; we're parsing the system partition
+ if (isProtectedAction(intent)) {
+ if (mDeferProtectedFilters) {
+ // We can't deal with these just yet. No component should ever obtain a
+ // >0 priority for a protected actions, with ONE exception -- the setup
+ // wizard. The setup wizard, however, cannot be known until we're able to
+ // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
+ // until all intent filters have been processed. Chicken, meet egg.
+ // Let the filter temporarily have a high priority and rectify the
+ // priorities after all system packages have been scanned.
+ if (mProtectedFilters == null) {
+ mProtectedFilters = new ArrayList<>();
+ }
+ mProtectedFilters.add(intent);
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Protected action; save for later;"
+ + " package: " + applicationInfo.packageName
+ + " activity: " + intent.activity.className
+ + " origPrio: " + intent.getPriority());
+ }
+ return;
+ } else {
+ if (DEBUG_FILTERS && setupWizardPackage == null) {
+ Slog.i(TAG, "No setup wizard;"
+ + " All protected intents capped to priority 0");
+ }
+ if (intent.activity.info.packageName.equals(setupWizardPackage)) {
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Found setup wizard;"
+ + " allow priority " + intent.getPriority() + ";"
+ + " package: " + intent.activity.info.packageName
+ + " activity: " + intent.activity.className
+ + " priority: " + intent.getPriority());
+ }
+ // setup wizard gets whatever it wants
+ return;
+ }
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Protected action; cap priority to 0;"
+ + " package: " + intent.activity.info.packageName
+ + " activity: " + intent.activity.className
+ + " origPrio: " + intent.getPriority());
+ }
+ intent.setPriority(0);
+ return;
+ }
+ }
+ // privileged apps on the system image get whatever priority they request
+ return;
+ }
+
+ // privileged app unbundled update ... try to find the same activity
+ final PackageParser.Activity foundActivity =
+ findMatchingActivity(systemActivities, activityInfo);
+ if (foundActivity == null) {
+ // this is a new activity; it cannot obtain >0 priority
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "New activity; cap priority to 0;"
+ + " package: " + applicationInfo.packageName
+ + " activity: " + intent.activity.className
+ + " origPrio: " + intent.getPriority());
+ }
+ intent.setPriority(0);
+ return;
+ }
+
+ // found activity, now check for filter equivalence
+
+ // a shallow copy is enough; we modify the list, not its contents
+ final List<ActivityIntentInfo> intentListCopy = new ArrayList<>(foundActivity.intents);
+ final List<ActivityIntentInfo> foundFilters = mActivities.findFilters(intent);
+
+ // find matching action subsets
+ final Iterator<String> actionsIterator = intent.actionsIterator();
+ if (actionsIterator != null) {
+ getIntentListSubset(intentListCopy, new ActionIterGenerator(), actionsIterator);
+ if (intentListCopy.size() == 0) {
+ // no more intents to match; we're not equivalent
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Mismatched action; cap priority to 0;"
+ + " package: " + applicationInfo.packageName
+ + " activity: " + intent.activity.className
+ + " origPrio: " + intent.getPriority());
+ }
+ intent.setPriority(0);
+ return;
+ }
+ }
+
+ // find matching category subsets
+ final Iterator<String> categoriesIterator = intent.categoriesIterator();
+ if (categoriesIterator != null) {
+ getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), categoriesIterator);
+ if (intentListCopy.size() == 0) {
+ // no more intents to match; we're not equivalent
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Mismatched category; cap priority to 0;"
+ + " package: " + applicationInfo.packageName
+ + " activity: " + intent.activity.className
+ + " origPrio: " + intent.getPriority());
+ }
+ intent.setPriority(0);
+ return;
+ }
+ }
+
+ // find matching schemes subsets
+ final Iterator<String> schemesIterator = intent.schemesIterator();
+ if (schemesIterator != null) {
+ getIntentListSubset(intentListCopy, new SchemesIterGenerator(), schemesIterator);
+ if (intentListCopy.size() == 0) {
+ // no more intents to match; we're not equivalent
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
+ + " package: " + applicationInfo.packageName
+ + " activity: " + intent.activity.className
+ + " origPrio: " + intent.getPriority());
+ }
+ intent.setPriority(0);
+ return;
+ }
+ }
+
+ // find matching authorities subsets
+ final Iterator<IntentFilter.AuthorityEntry> authoritiesIterator =
+ intent.authoritiesIterator();
+ if (authoritiesIterator != null) {
+ getIntentListSubset(intentListCopy, new AuthoritiesIterGenerator(),
+ authoritiesIterator);
+ if (intentListCopy.size() == 0) {
+ // no more intents to match; we're not equivalent
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Mismatched authority; cap priority to 0;"
+ + " package: " + applicationInfo.packageName
+ + " activity: " + intent.activity.className
+ + " origPrio: " + intent.getPriority());
+ }
+ intent.setPriority(0);
+ return;
+ }
+ }
+
+ // we found matching filter(s); app gets the max priority of all intents
+ int cappedPriority = 0;
+ for (int i = intentListCopy.size() - 1; i >= 0; --i) {
+ cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
+ }
+ if (intent.getPriority() > cappedPriority) {
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Found matching filter(s);"
+ + " cap priority to " + cappedPriority + ";"
+ + " package: " + applicationInfo.packageName
+ + " activity: " + intent.activity.className
+ + " origPrio: " + intent.getPriority());
+ }
+ intent.setPriority(cappedPriority);
+ return;
+ }
+ // all this for nothing; the requested priority was <= what was on the system
+ }
+
+ @GuardedBy("mLock")
+ private void removeAllComponentsLocked(PackageParser.Package pkg, boolean chatty) {
+ int componentSize;
+ StringBuilder r;
+ int i;
+
+ componentSize = pkg.activities.size();
+ r = null;
+ for (i = 0; i < componentSize; i++) {
+ PackageParser.Activity a = pkg.activities.get(i);
+ mActivities.removeActivity(a, "activity");
+ if (DEBUG_REMOVE && chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(a.info.name);
+ }
+ }
+ if (DEBUG_REMOVE && chatty) {
+ Log.d(TAG, " Activities: " + (r == null ? "<NONE>" : r));
+ }
+
+ componentSize = pkg.providers.size();
+ r = null;
+ for (i = 0; i < componentSize; i++) {
+ PackageParser.Provider p = pkg.providers.get(i);
+ mProviders.removeProvider(p);
+ if (p.info.authority == null) {
+ // Another content provider with this authority existed when this app was
+ // installed, so this authority is null. Ignore it as we don't have to
+ // unregister the provider.
+ continue;
+ }
+ String[] names = p.info.authority.split(";");
+ for (int j = 0; j < names.length; j++) {
+ if (mProvidersByAuthority.get(names[j]) == p) {
+ mProvidersByAuthority.remove(names[j]);
+ if (DEBUG_REMOVE && chatty) {
+ Log.d(TAG, "Unregistered content provider: " + names[j]
+ + ", className = " + p.info.name + ", isSyncable = "
+ + p.info.isSyncable);
+ }
+ }
+ }
+ if (DEBUG_REMOVE && chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(p.info.name);
+ }
+ }
+ if (DEBUG_REMOVE && chatty) {
+ Log.d(TAG, " Providers: " + (r == null ? "<NONE>" : r));
+ }
+
+ componentSize = pkg.receivers.size();
+ r = null;
+ for (i = 0; i < componentSize; i++) {
+ PackageParser.Activity a = pkg.receivers.get(i);
+ mReceivers.removeActivity(a, "receiver");
+ if (DEBUG_REMOVE && chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(a.info.name);
+ }
+ }
+ if (DEBUG_REMOVE && chatty) {
+ Log.d(TAG, " Receivers: " + (r == null ? "<NONE>" : r));
+ }
+
+ componentSize = pkg.services.size();
+ r = null;
+ for (i = 0; i < componentSize; i++) {
+ PackageParser.Service s = pkg.services.get(i);
+ mServices.removeService(s);
+ if (DEBUG_REMOVE && chatty) {
+ if (r == null) {
+ r = new StringBuilder(256);
+ } else {
+ r.append(' ');
+ }
+ r.append(s.info.name);
+ }
+ }
+ if (DEBUG_REMOVE && chatty) {
+ Log.d(TAG, " Services: " + (r == null ? "<NONE>" : r));
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void assertProvidersNotDefinedLocked(PackageParser.Package pkg)
+ throws PackageManagerException {
+ final int providersSize = pkg.providers.size();
+ int i;
+ for (i = 0; i < providersSize; i++) {
+ PackageParser.Provider p = pkg.providers.get(i);
+ if (p.info.authority != null) {
+ final String[] names = p.info.authority.split(";");
+ for (int j = 0; j < names.length; j++) {
+ if (mProvidersByAuthority.containsKey(names[j])) {
+ final PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
+ final String otherPackageName =
+ (other != null && other.getComponentName() != null)
+ ? other.getComponentName().getPackageName() : "?";
+ throw new PackageManagerException(
+ INSTALL_FAILED_CONFLICTING_PROVIDER,
+ "Can't install because provider name " + names[j]
+ + " (in package " + pkg.applicationInfo.packageName
+ + ") is already used by " + otherPackageName);
+ }
+ }
+ }
+ }
+ }
+
+ private static final class ActivityIntentResolver
+ extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
+ @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);
+ }
+
+ List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int 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> queryIntentForPackage(Intent intent, String resolvedType,
+ int flags, List<PackageParser.Activity> packageActivities, int userId) {
+ if (!sUserManager.exists(userId)) {
+ return null;
+ }
+ if (packageActivities == null) {
+ return null;
+ }
+ mFlags = flags;
+ final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
+ final int activitiesSize = packageActivities.size();
+ ArrayList<PackageParser.ActivityIntentInfo[]> listCut = new ArrayList<>(activitiesSize);
+
+ ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
+ for (int i = 0; i < activitiesSize; ++i) {
+ intentFilters = packageActivities.get(i).intents;
+ if (intentFilters != null && intentFilters.size() > 0) {
+ PackageParser.ActivityIntentInfo[] array =
+ new PackageParser.ActivityIntentInfo[intentFilters.size()];
+ intentFilters.toArray(array);
+ listCut.add(array);
+ }
+ }
+ return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
+ }
+
+ private void addActivity(PackageParser.Activity a, String type,
+ List<PackageParser.ActivityIntentInfo> newIntents) {
+ mActivities.put(a.getComponentName(), a);
+ if (DEBUG_SHOW_INFO) {
+ final CharSequence label = a.info.nonLocalizedLabel != null
+ ? a.info.nonLocalizedLabel
+ : a.info.name;
+ Log.v(TAG, " " + type + " " + label + ":");
+ }
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " Class=" + a.info.name);
+ }
+ final int intentsSize = a.intents.size();
+ for (int j = 0; j < intentsSize; j++) {
+ PackageParser.ActivityIntentInfo intent = a.intents.get(j);
+ if (newIntents != null && "activity".equals(type)) {
+ newIntents.add(intent);
+ }
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " IntentFilter:");
+ intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
+ }
+ if (!intent.debugCheck()) {
+ Log.w(TAG, "==> For Activity " + a.info.name);
+ }
+ addFilter(intent);
+ }
+ }
+
+ private void removeActivity(PackageParser.Activity a, String type) {
+ mActivities.remove(a.getComponentName());
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " " + type + " "
+ + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
+ : a.info.name) + ":");
+ Log.v(TAG, " Class=" + a.info.name);
+ }
+ final int intentsSize = a.intents.size();
+ for (int j = 0; j < intentsSize; j++) {
+ PackageParser.ActivityIntentInfo intent = a.intents.get(j);
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " IntentFilter:");
+ intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
+ }
+ removeFilter(intent);
+ }
+ }
+
+ @Override
+ protected boolean allowFilterResult(
+ PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
+ ActivityInfo filterAi = filter.activity.info;
+ for (int i = dest.size() - 1; i >= 0; --i) {
+ ActivityInfo destAi = dest.get(i).activityInfo;
+ if (destAi.name == filterAi.name && destAi.packageName == filterAi.packageName) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ protected ActivityIntentInfo[] newArray(int size) {
+ return new ActivityIntentInfo[size];
+ }
+
+ @Override
+ protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
+ if (!sUserManager.exists(userId)) return true;
+ PackageParser.Package p = filter.activity.owner;
+ if (p != null) {
+ PackageSetting ps = (PackageSetting) p.mExtras;
+ if (ps != null) {
+ // 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.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
+ && ps.getStopped(userId);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean isPackageForFilter(String packageName,
+ PackageParser.ActivityIntentInfo info) {
+ return packageName.equals(info.activity.owner.packageName);
+ }
+
+ @Override
+ protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
+ int match, int userId) {
+ if (!sUserManager.exists(userId)) return null;
+ if (!sPackageManagerInternal.isEnabledAndMatches(info.activity.info, mFlags, userId)) {
+ return null;
+ }
+ final PackageParser.Activity activity = info.activity;
+ PackageSetting ps = (PackageSetting) activity.owner.mExtras;
+ if (ps == null) {
+ return null;
+ }
+ final PackageUserState userState = ps.readUserState(userId);
+ ActivityInfo ai =
+ PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
+ if (ai == null) {
+ return null;
+ }
+ final boolean matchExplicitlyVisibleOnly =
+ (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
+ final boolean matchVisibleToInstantApp =
+ (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+ final boolean componentVisible =
+ matchVisibleToInstantApp
+ && info.isVisibleToInstantApp()
+ && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
+ final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
+ // throw out filters that aren't visible to ephemeral apps
+ if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
+ return null;
+ }
+ // throw out instant app filters if we're not explicitly requesting them
+ if (!matchInstantApp && userState.instantApp) {
+ return null;
+ }
+ // throw out instant app filters if updates are available; will trigger
+ // instant app resolution
+ if (userState.instantApp && ps.isUpdateAvailable()) {
+ return null;
+ }
+ final ResolveInfo res = new ResolveInfo();
+ res.activityInfo = ai;
+ if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
+ res.filter = info;
+ }
+ res.handleAllWebDataURI = info.handleAllWebDataURI();
+ res.priority = info.getPriority();
+ res.preferredOrder = activity.owner.mPreferredOrder;
+ //System.out.println("Result: " + res.activityInfo.className +
+ // " = " + res.priority);
+ res.match = match;
+ res.isDefault = info.hasDefault;
+ res.labelRes = info.labelRes;
+ res.nonLocalizedLabel = info.nonLocalizedLabel;
+ if (sPackageManagerInternal.userNeedsBadging(userId)) {
+ res.noResourceId = true;
+ } else {
+ res.icon = info.icon;
+ }
+ res.iconResourceId = info.icon;
+ res.system = res.activityInfo.applicationInfo.isSystemApp();
+ res.isInstantAppAvailable = userState.instantApp;
+ return res;
+ }
+
+ @Override
+ protected void sortResults(List<ResolveInfo> results) {
+ results.sort(RESOLVE_PRIORITY_SORTER);
+ }
+
+ @Override
+ protected void dumpFilter(PrintWriter out, String prefix,
+ PackageParser.ActivityIntentInfo filter) {
+ out.print(prefix);
+ out.print(Integer.toHexString(System.identityHashCode(filter.activity)));
+ out.print(' ');
+ filter.activity.printComponentShortName(out);
+ out.print(" filter ");
+ out.println(Integer.toHexString(System.identityHashCode(filter)));
+ }
+
+ @Override
+ protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
+ return filter.activity;
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ PackageParser.Activity activity = (PackageParser.Activity) label;
+ out.print(prefix);
+ out.print(Integer.toHexString(System.identityHashCode(activity)));
+ out.print(' ');
+ activity.printComponentShortName(out);
+ if (count > 1) {
+ out.print(" ("); out.print(count); out.print(" filters)");
+ }
+ out.println();
+ }
+
+ // Keys are String (activity class name), values are Activity.
+ private final ArrayMap<ComponentName, PackageParser.Activity> mActivities =
+ new ArrayMap<>();
+ private int mFlags;
+ }
+
+ private static final class ProviderIntentResolver
+ extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
+ @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);
+ }
+
+ List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int 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> queryIntentForPackage(Intent intent, String resolvedType,
+ int flags, List<PackageParser.Provider> packageProviders, int userId) {
+ if (!sUserManager.exists(userId)) {
+ return null;
+ }
+ if (packageProviders == null) {
+ return null;
+ }
+ mFlags = flags;
+ final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
+ final int providersSize = packageProviders.size();
+ ArrayList<PackageParser.ProviderIntentInfo[]> listCut = new ArrayList<>(providersSize);
+
+ ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
+ for (int i = 0; i < providersSize; ++i) {
+ intentFilters = packageProviders.get(i).intents;
+ if (intentFilters != null && intentFilters.size() > 0) {
+ PackageParser.ProviderIntentInfo[] array =
+ new PackageParser.ProviderIntentInfo[intentFilters.size()];
+ intentFilters.toArray(array);
+ listCut.add(array);
+ }
+ }
+ return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
+ }
+
+ void addProvider(PackageParser.Provider p) {
+ if (mProviders.containsKey(p.getComponentName())) {
+ Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
+ return;
+ }
+
+ mProviders.put(p.getComponentName(), p);
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " "
+ + (p.info.nonLocalizedLabel != null
+ ? p.info.nonLocalizedLabel
+ : p.info.name)
+ + ":");
+ Log.v(TAG, " Class=" + p.info.name);
+ }
+ final int intentsSize = p.intents.size();
+ int j;
+ for (j = 0; j < intentsSize; j++) {
+ PackageParser.ProviderIntentInfo intent = p.intents.get(j);
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " IntentFilter:");
+ intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
+ }
+ if (!intent.debugCheck()) {
+ Log.w(TAG, "==> For Provider " + p.info.name);
+ }
+ addFilter(intent);
+ }
+ }
+
+ void removeProvider(PackageParser.Provider p) {
+ mProviders.remove(p.getComponentName());
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " " + (p.info.nonLocalizedLabel != null
+ ? p.info.nonLocalizedLabel
+ : p.info.name) + ":");
+ Log.v(TAG, " Class=" + p.info.name);
+ }
+ final int intentsSize = p.intents.size();
+ int j;
+ for (j = 0; j < intentsSize; j++) {
+ PackageParser.ProviderIntentInfo intent = p.intents.get(j);
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " IntentFilter:");
+ intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
+ }
+ removeFilter(intent);
+ }
+ }
+
+ @Override
+ protected boolean allowFilterResult(
+ PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
+ ProviderInfo filterPi = filter.provider.info;
+ for (int i = dest.size() - 1; i >= 0; i--) {
+ ProviderInfo destPi = dest.get(i).providerInfo;
+ if (destPi.name == filterPi.name
+ && destPi.packageName == filterPi.packageName) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ protected PackageParser.ProviderIntentInfo[] newArray(int size) {
+ return new PackageParser.ProviderIntentInfo[size];
+ }
+
+ @Override
+ protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
+ if (!sUserManager.exists(userId)) {
+ return true;
+ }
+ PackageParser.Package p = filter.provider.owner;
+ if (p != null) {
+ PackageSetting ps = (PackageSetting) p.mExtras;
+ if (ps != null) {
+ // 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.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
+ && ps.getStopped(userId);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean isPackageForFilter(String packageName,
+ PackageParser.ProviderIntentInfo info) {
+ return packageName.equals(info.provider.owner.packageName);
+ }
+
+ @Override
+ protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
+ int match, int userId) {
+ if (!sUserManager.exists(userId)) {
+ return null;
+ }
+ final PackageParser.ProviderIntentInfo info = filter;
+ if (!sPackageManagerInternal.isEnabledAndMatches(info.provider.info, mFlags, userId)) {
+ return null;
+ }
+ final PackageParser.Provider provider = info.provider;
+ PackageSetting ps = (PackageSetting) provider.owner.mExtras;
+ if (ps == null) {
+ return null;
+ }
+ final PackageUserState userState = ps.readUserState(userId);
+ final boolean matchVisibleToInstantApp = (mFlags
+ & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+ final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
+ // throw out filters that aren't visible to instant applications
+ if (matchVisibleToInstantApp
+ && !(info.isVisibleToInstantApp() || userState.instantApp)) {
+ return null;
+ }
+ // throw out instant application filters if we're not explicitly requesting them
+ if (!isInstantApp && userState.instantApp) {
+ return null;
+ }
+ // throw out instant application filters if updates are available; will trigger
+ // instant application resolution
+ if (userState.instantApp && ps.isUpdateAvailable()) {
+ return null;
+ }
+ ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
+ userState, userId);
+ if (pi == null) {
+ return null;
+ }
+ final ResolveInfo res = new ResolveInfo();
+ res.providerInfo = pi;
+ if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
+ res.filter = filter;
+ }
+ res.priority = info.getPriority();
+ res.preferredOrder = provider.owner.mPreferredOrder;
+ res.match = match;
+ res.isDefault = info.hasDefault;
+ res.labelRes = info.labelRes;
+ res.nonLocalizedLabel = info.nonLocalizedLabel;
+ res.icon = info.icon;
+ res.system = res.providerInfo.applicationInfo.isSystemApp();
+ return res;
+ }
+
+ @Override
+ protected void sortResults(List<ResolveInfo> results) {
+ results.sort(RESOLVE_PRIORITY_SORTER);
+ }
+
+ @Override
+ protected void dumpFilter(PrintWriter out, String prefix,
+ PackageParser.ProviderIntentInfo filter) {
+ out.print(prefix);
+ out.print(Integer.toHexString(System.identityHashCode(filter.provider)));
+ out.print(' ');
+ filter.provider.printComponentShortName(out);
+ out.print(" filter ");
+ out.println(Integer.toHexString(System.identityHashCode(filter)));
+ }
+
+ @Override
+ protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
+ return filter.provider;
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ final PackageParser.Provider provider = (PackageParser.Provider) label;
+ out.print(prefix);
+ out.print(Integer.toHexString(System.identityHashCode(provider)));
+ out.print(' ');
+ provider.printComponentShortName(out);
+ if (count > 1) {
+ out.print(" (");
+ out.print(count);
+ out.print(" filters)");
+ }
+ out.println();
+ }
+
+ private final ArrayMap<ComponentName, PackageParser.Provider> mProviders = new ArrayMap<>();
+ private int mFlags;
+ }
+
+ private static final class ServiceIntentResolver
+ extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
+ @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);
+ }
+
+ List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int 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> queryIntentForPackage(Intent intent, String resolvedType,
+ int flags, List<PackageParser.Service> packageServices, int userId) {
+ if (!sUserManager.exists(userId)) return null;
+ if (packageServices == null) {
+ return null;
+ }
+ mFlags = flags;
+ final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
+ final int servicesSize = packageServices.size();
+ ArrayList<PackageParser.ServiceIntentInfo[]> listCut = new ArrayList<>(servicesSize);
+
+ ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
+ for (int i = 0; i < servicesSize; ++i) {
+ intentFilters = packageServices.get(i).intents;
+ if (intentFilters != null && intentFilters.size() > 0) {
+ PackageParser.ServiceIntentInfo[] array =
+ new PackageParser.ServiceIntentInfo[intentFilters.size()];
+ intentFilters.toArray(array);
+ listCut.add(array);
+ }
+ }
+ return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
+ }
+
+ void addService(PackageParser.Service s) {
+ mServices.put(s.getComponentName(), s);
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " "
+ + (s.info.nonLocalizedLabel != null
+ ? s.info.nonLocalizedLabel : s.info.name) + ":");
+ Log.v(TAG, " Class=" + s.info.name);
+ }
+ final int intentsSize = s.intents.size();
+ int j;
+ for (j = 0; j < intentsSize; j++) {
+ PackageParser.ServiceIntentInfo intent = s.intents.get(j);
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " IntentFilter:");
+ intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
+ }
+ if (!intent.debugCheck()) {
+ Log.w(TAG, "==> For Service " + s.info.name);
+ }
+ addFilter(intent);
+ }
+ }
+
+ void removeService(PackageParser.Service s) {
+ mServices.remove(s.getComponentName());
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
+ ? s.info.nonLocalizedLabel : s.info.name) + ":");
+ Log.v(TAG, " Class=" + s.info.name);
+ }
+ final int intentsSize = s.intents.size();
+ int j;
+ for (j = 0; j < intentsSize; j++) {
+ PackageParser.ServiceIntentInfo intent = s.intents.get(j);
+ if (DEBUG_SHOW_INFO) {
+ Log.v(TAG, " IntentFilter:");
+ intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
+ }
+ removeFilter(intent);
+ }
+ }
+
+ @Override
+ protected boolean allowFilterResult(
+ PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
+ ServiceInfo filterSi = filter.service.info;
+ for (int i = dest.size() - 1; i >= 0; --i) {
+ ServiceInfo destAi = dest.get(i).serviceInfo;
+ if (destAi.name == filterSi.name
+ && destAi.packageName == filterSi.packageName) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ protected PackageParser.ServiceIntentInfo[] newArray(int size) {
+ return new PackageParser.ServiceIntentInfo[size];
+ }
+
+ @Override
+ protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
+ if (!sUserManager.exists(userId)) return true;
+ PackageParser.Package p = filter.service.owner;
+ if (p != null) {
+ PackageSetting ps = (PackageSetting) p.mExtras;
+ if (ps != null) {
+ // 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.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
+ && ps.getStopped(userId);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean isPackageForFilter(String packageName,
+ PackageParser.ServiceIntentInfo info) {
+ return packageName.equals(info.service.owner.packageName);
+ }
+
+ @Override
+ protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
+ int match, int userId) {
+ if (!sUserManager.exists(userId)) return null;
+ final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo) filter;
+ if (!sPackageManagerInternal.isEnabledAndMatches(info.service.info, mFlags, userId)) {
+ return null;
+ }
+ final PackageParser.Service service = info.service;
+ PackageSetting ps = (PackageSetting) service.owner.mExtras;
+ if (ps == null) {
+ return null;
+ }
+ final PackageUserState userState = ps.readUserState(userId);
+ ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
+ userState, userId);
+ 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;
+ // throw out filters that aren't visible to ephemeral apps
+ if (matchVisibleToInstantApp
+ && !(info.isVisibleToInstantApp() || userState.instantApp)) {
+ return null;
+ }
+ // throw out ephemeral filters if we're not explicitly requesting them
+ if (!isInstantApp && userState.instantApp) {
+ return null;
+ }
+ // throw out instant app filters if updates are available; will trigger
+ // instant app resolution
+ if (userState.instantApp && ps.isUpdateAvailable()) {
+ return null;
+ }
+ final ResolveInfo res = new ResolveInfo();
+ res.serviceInfo = si;
+ if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
+ res.filter = filter;
+ }
+ res.priority = info.getPriority();
+ res.preferredOrder = service.owner.mPreferredOrder;
+ res.match = match;
+ res.isDefault = info.hasDefault;
+ res.labelRes = info.labelRes;
+ res.nonLocalizedLabel = info.nonLocalizedLabel;
+ res.icon = info.icon;
+ res.system = res.serviceInfo.applicationInfo.isSystemApp();
+ return res;
+ }
+
+ @Override
+ protected void sortResults(List<ResolveInfo> results) {
+ results.sort(RESOLVE_PRIORITY_SORTER);
+ }
+
+ @Override
+ protected void dumpFilter(PrintWriter out, String prefix,
+ PackageParser.ServiceIntentInfo filter) {
+ out.print(prefix);
+ out.print(Integer.toHexString(System.identityHashCode(filter.service)));
+ out.print(' ');
+ filter.service.printComponentShortName(out);
+ out.print(" filter ");
+ out.print(Integer.toHexString(System.identityHashCode(filter)));
+ if (filter.service.info.permission != null) {
+ out.print(" permission "); out.println(filter.service.info.permission);
+ } else {
+ out.println();
+ }
+ }
+
+ @Override
+ protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
+ return filter.service;
+ }
+
+ protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
+ final PackageParser.Service service = (PackageParser.Service) label;
+ out.print(prefix);
+ out.print(Integer.toHexString(System.identityHashCode(service)));
+ out.print(' ');
+ service.printComponentShortName(out);
+ if (count > 1) {
+ out.print(" ("); out.print(count); out.print(" filters)");
+ }
+ out.println();
+ }
+
+ // Keys are String (activity class name), values are Activity.
+ private final ArrayMap<ComponentName, PackageParser.Service> mServices = new ArrayMap<>();
+ private int mFlags;
+ }
+
+ static final class InstantAppIntentResolver
+ extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
+ AuxiliaryResolveInfo.AuxiliaryFilter> {
+ /**
+ * The result that has the highest defined order. Ordering applies on a
+ * per-package basis. Mapping is from package name to Pair of order and
+ * EphemeralResolveInfo.
+ * <p>
+ * NOTE: This is implemented as a field variable for convenience and efficiency.
+ * By having a field variable, we're able to track filter ordering as soon as
+ * a non-zero order is defined. Otherwise, multiple loops across the result set
+ * would be needed to apply ordering. If the intent resolver becomes re-entrant,
+ * this needs to be contained entirely within {@link #filterResults}.
+ */
+ final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult =
+ new ArrayMap<>();
+
+ @Override
+ protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
+ return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
+ }
+
+ @Override
+ protected boolean isPackageForFilter(String packageName,
+ AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
+ return true;
+ }
+
+ @Override
+ protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
+ AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
+ if (!sUserManager.exists(userId)) {
+ return null;
+ }
+ final String packageName = responseObj.resolveInfo.getPackageName();
+ final Integer order = responseObj.getOrder();
+ final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
+ mOrderResult.get(packageName);
+ // ordering is enabled and this item's order isn't high enough
+ if (lastOrderResult != null && lastOrderResult.first >= order) {
+ return null;
+ }
+ final InstantAppResolveInfo res = responseObj.resolveInfo;
+ if (order > 0) {
+ // non-zero order, enable ordering
+ mOrderResult.put(packageName, new Pair<>(order, res));
+ }
+ return responseObj;
+ }
+
+ @Override
+ protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
+ // only do work if ordering is enabled [most of the time it won't be]
+ if (mOrderResult.size() == 0) {
+ return;
+ }
+ int resultSize = results.size();
+ for (int i = 0; i < resultSize; i++) {
+ final InstantAppResolveInfo info = results.get(i).resolveInfo;
+ final String packageName = info.getPackageName();
+ final Pair<Integer, InstantAppResolveInfo> savedInfo =
+ mOrderResult.get(packageName);
+ if (savedInfo == null) {
+ // package doesn't having ordering
+ continue;
+ }
+ if (savedInfo.second == info) {
+ // circled back to the highest ordered item; remove from order list
+ mOrderResult.remove(packageName);
+ if (mOrderResult.size() == 0) {
+ // no more ordered items
+ break;
+ }
+ continue;
+ }
+ // item has a worse order, remove it from the result list
+ results.remove(i);
+ resultSize--;
+ i--;
+ }
+ }
+ }
+
+ /** Generic to create an {@link Iterator} for a data type */
+ static class IterGenerator<E> {
+ public Iterator<E> generate(ActivityIntentInfo info) {
+ return null;
+ }
+ }
+
+ /** Create an {@link Iterator} for intent actions */
+ static class ActionIterGenerator extends IterGenerator<String> {
+ @Override
+ public Iterator<String> generate(ActivityIntentInfo info) {
+ return info.actionsIterator();
+ }
+ }
+
+ /** Create an {@link Iterator} for intent categories */
+ static class CategoriesIterGenerator extends IterGenerator<String> {
+ @Override
+ public Iterator<String> generate(ActivityIntentInfo info) {
+ return info.categoriesIterator();
+ }
+ }
+
+ /** Create an {@link Iterator} for intent schemes */
+ static class SchemesIterGenerator extends IterGenerator<String> {
+ @Override
+ public Iterator<String> generate(ActivityIntentInfo info) {
+ return info.schemesIterator();
+ }
+ }
+
+ /** Create an {@link Iterator} for intent authorities */
+ static class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
+ @Override
+ public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
+ return info.authoritiesIterator();
+ }
+ }
+
+}
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index 19cefb8..9bd3924 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -36,9 +36,9 @@
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
-import android.content.pm.InstantAppRequest;
import android.content.pm.AuxiliaryResolveInfo;
import android.content.pm.InstantAppIntentFilter;
+import android.content.pm.InstantAppRequest;
import android.content.pm.InstantAppResolveInfo;
import android.content.pm.InstantAppResolveInfo.InstantAppDigest;
import android.metrics.LogMaker;
@@ -458,8 +458,8 @@
}
return Collections.emptyList();
}
- final PackageManagerService.InstantAppIntentResolver instantAppResolver =
- new PackageManagerService.InstantAppIntentResolver();
+ final ComponentResolver.InstantAppIntentResolver instantAppResolver =
+ new ComponentResolver.InstantAppIntentResolver();
for (int j = instantAppFilters.size() - 1; j >= 0; --j) {
final InstantAppIntentFilter instantAppFilter = instantAppFilters.get(j);
final List<IntentFilter> splitFilters = instantAppFilter.getFilters();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index fba4be2..fc2813b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -44,7 +44,6 @@
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
-import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
@@ -95,6 +94,7 @@
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
+import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
@@ -158,7 +158,6 @@
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstantAppInfo;
import android.content.pm.InstantAppRequest;
-import android.content.pm.InstantAppResolveInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.KeySet;
@@ -177,7 +176,6 @@
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.PackageParser.ParseFlags;
-import android.content.pm.PackageParser.ServiceIntentInfo;
import android.content.pm.PackageParser.SigningDetails;
import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
import android.content.pm.PackageStats;
@@ -295,7 +293,6 @@
import com.android.server.DeviceIdleController;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
-import com.android.server.IntentResolver;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
import com.android.server.ServiceThread;
@@ -416,12 +413,10 @@
public static final boolean DEBUG_INSTALL = false;
public static final boolean DEBUG_REMOVE = false;
private static final boolean DEBUG_BROADCASTS = false;
- private static final boolean DEBUG_SHOW_INFO = false;
private static final boolean DEBUG_PACKAGE_INFO = false;
private static final boolean DEBUG_INTENT_MATCHING = false;
public static final boolean DEBUG_PACKAGE_SCANNING = false;
private static final boolean DEBUG_VERIFY = false;
- private static final boolean DEBUG_FILTERS = false;
public static final boolean DEBUG_PERMISSIONS = false;
private static final boolean DEBUG_SHARED_LIBRARIES = false;
public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
@@ -588,18 +583,6 @@
sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
}
- /**
- * The set of all protected actions [i.e. those actions for which a high priority
- * intent filter is disallowed].
- */
- private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
- static {
- PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
- PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
- PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
- PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
- }
-
// Compilation reasons.
public static final int REASON_UNKNOWN = -1;
public static final int REASON_FIRST_BOOT = 0;
@@ -701,20 +684,6 @@
* are package location.
*/
final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
- /**
- * Tracks high priority intent filters for protected actions. During boot, certain
- * filter actions are protected and should never be allowed to have a high priority
- * intent filter for them. However, there is one, and only one exception -- the
- * setup wizard. It must be able to define a high priority intent filter for these
- * actions to ensure there are no escapes from the wizard. We need to delay processing
- * of these during boot as we need to look at all of the system packages in order
- * to know which component is the setup wizard.
- */
- private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
- /**
- * Whether or not processing protected filters should be deferred.
- */
- private boolean mDeferProtectedFilters = true;
/**
* Tracks existing system packages prior to receiving an OTA. Keys are package name.
@@ -912,24 +881,6 @@
final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
new ArrayMap<>();
- // All available activities, for your resolving pleasure.
- final ActivityIntentResolver mActivities =
- new ActivityIntentResolver();
-
- // All available receivers, for your resolving pleasure.
- final ActivityIntentResolver mReceivers =
- new ActivityIntentResolver();
-
- // All available services, for your resolving pleasure.
- final ServiceIntentResolver mServices = new ServiceIntentResolver();
-
- // All available providers, for your resolving pleasure.
- final ProviderIntentResolver mProviders = new ProviderIntentResolver();
-
- // Mapping from provider base names (first directory in content URI codePath)
- // to the provider information.
- final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = new ArrayMap<>();
-
// Mapping from instrumentation class names to info about them.
final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
new ArrayMap<>();
@@ -960,7 +911,7 @@
private final OnPermissionChangeListeners mOnPermissionChangeListeners;
// Cache of users who need badging.
- SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
+ private final SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
/** Token for keys in mPendingVerification. */
private int mPendingVerificationToken = 0;
@@ -1000,6 +951,7 @@
final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
private final PermissionManagerInternal mPermissionManager;
+ private final ComponentResolver mComponentResolver;
// List of packages names to keep cached, even if they are uninstalled for all users
private List<String> mKeepUninstalledPackages;
@@ -2415,6 +2367,8 @@
PackageManagerInternal.class, new PackageManagerInternalImpl());
sUserManager = new UserManagerService(context, this,
new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
+ mComponentResolver = new ComponentResolver(sUserManager,
+ LocalServices.getService(PackageManagerInternal.class));
mPermissionManager = PermissionManagerService.create(context,
new DefaultPermissionGrantedCallback() {
@Override
@@ -2425,7 +2379,8 @@
}
}, mPackages /*externalLock*/);
mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
- mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
+ mSettings = new Settings(Environment.getDataDirectory(),
+ mPermissionManager.getPermissionSettings(), mPackages);
}
}
mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
@@ -3057,38 +3012,10 @@
// Resolve protected action filters. Only the setup wizard is allowed to
// have a high priority filter for these actions.
mSetupWizardPackage = getSetupWizardPackageName();
- if (mProtectedFilters.size() > 0) {
- if (DEBUG_FILTERS && mSetupWizardPackage == null) {
- Slog.i(TAG, "No setup wizard;"
- + " All protected intents capped to priority 0");
- }
- for (ActivityIntentInfo filter : mProtectedFilters) {
- if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Found setup wizard;"
- + " allow priority " + filter.getPriority() + ";"
- + " package: " + filter.activity.info.packageName
- + " activity: " + filter.activity.className
- + " priority: " + filter.getPriority());
- }
- // skip setup wizard; allow it to keep the high priority filter
- continue;
- }
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Protected action; cap priority to 0;"
- + " package: " + filter.activity.info.packageName
- + " activity: " + filter.activity.className
- + " origPrio: " + filter.getPriority());
- }
- filter.setPriority(0);
- }
- }
+ mComponentResolver.fixProtectedFilterPriorities();
mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
- mDeferProtectedFilters = false;
- mProtectedFilters.clear();
-
// Now that we know all of the shared libraries, update all clients to have
// the correct library paths.
updateAllSharedLibrariesLPw(null);
@@ -3146,7 +3073,7 @@
// all defined users.
if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
for (UserInfo user : sUserManager.getUsers(true)) {
- mSettings.applyDefaultPreferredAppsLPw(this, user.id);
+ mSettings.applyDefaultPreferredAppsLPw(user.id);
applyFactoryDefaultBrowserLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
@@ -4242,7 +4169,7 @@
private boolean isComponentVisibleToInstantApp(
@Nullable ComponentName component, @ComponentType int type) {
if (type == TYPE_ACTIVITY) {
- final PackageParser.Activity activity = mActivities.mActivities.get(component);
+ final PackageParser.Activity activity = mComponentResolver.getActivity(component);
if (activity == null) {
return false;
}
@@ -4252,7 +4179,7 @@
(activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
return visibleToInstantApp && explicitlyVisibleToInstantApp;
} else if (type == TYPE_RECEIVER) {
- final PackageParser.Activity activity = mReceivers.mActivities.get(component);
+ final PackageParser.Activity activity = mComponentResolver.getReceiver(component);
if (activity == null) {
return false;
}
@@ -4262,12 +4189,12 @@
(activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
return visibleToInstantApp && !explicitlyVisibleToInstantApp;
} else if (type == TYPE_SERVICE) {
- final PackageParser.Service service = mServices.mServices.get(component);
+ final PackageParser.Service service = mComponentResolver.getService(component);
return service != null
? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
: false;
} else if (type == TYPE_PROVIDER) {
- final PackageParser.Provider provider = mProviders.mProviders.get(component);
+ final PackageParser.Provider provider = mComponentResolver.getProvider(component);
return provider != null
? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
: false;
@@ -5015,7 +4942,7 @@
}
synchronized (mPackages) {
- PackageParser.Activity a = mActivities.mActivities.get(component);
+ PackageParser.Activity a = mComponentResolver.getActivity(component);
if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
@@ -5061,7 +4988,7 @@
}
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- PackageParser.Activity a = mActivities.mActivities.get(component);
+ PackageParser.Activity a = mComponentResolver.getActivity(component);
if (a == null) {
return false;
}
@@ -5090,7 +5017,7 @@
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get receiver info");
synchronized (mPackages) {
- PackageParser.Activity a = mReceivers.mActivities.get(component);
+ PackageParser.Activity a = mComponentResolver.getReceiver(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getReceiverInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
@@ -5228,7 +5155,7 @@
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get service info");
synchronized (mPackages) {
- PackageParser.Service s = mServices.mServices.get(component);
+ PackageParser.Service s = mComponentResolver.getService(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getServiceInfo " + component + ": " + s);
if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
@@ -5252,7 +5179,7 @@
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get provider info");
synchronized (mPackages) {
- PackageParser.Provider p = mProviders.mProviders.get(component);
+ PackageParser.Provider p = mComponentResolver.getProvider(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getProviderInfo " + component + ": " + p);
if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
@@ -6806,7 +6733,7 @@
}
// Check for results in the current profile.
- result = filterIfNotSystemUser(mActivities.queryIntent(
+ result = filterIfNotSystemUser(mComponentResolver.queryActivities(
intent, resolvedType, flags, userId), userId);
addInstant = isInstantAppResolutionAllowed(intent, result, userId,
false /*skipPackageCheck*/);
@@ -6863,10 +6790,8 @@
final PackageParser.Package pkg = mPackages.get(pkgName);
result = null;
if (pkg != null) {
- result = filterIfNotSystemUser(
- mActivities.queryIntentForPackage(
- intent, resolvedType, flags, pkg.activities, userId),
- userId);
+ result = filterIfNotSystemUser(mComponentResolver.queryActivities(
+ intent, resolvedType, flags, pkg.activities, userId), userId);
}
if (result == null || result.size() == 0) {
// the caller wants to resolve for a particular package; however, there
@@ -6884,7 +6809,7 @@
result, intent, resolvedType, flags, userId, resolveForStart);
}
if (sortResult) {
- Collections.sort(result, mResolvePrioritySorter);
+ Collections.sort(result, RESOLVE_PRIORITY_SORTER);
}
return applyPostResolutionFilter(
result, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
@@ -6898,7 +6823,9 @@
ResolveInfo localInstantApp = null;
boolean blockResolution = false;
if (!alreadyResolvedLocally) {
- final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
+ final List<ResolveInfo> instantApps = mComponentResolver.queryActivities(
+ intent,
+ resolvedType,
flags
| PackageManager.GET_RESOLVED_FILTER
| PackageManager.MATCH_INSTANT
@@ -7004,7 +6931,7 @@
sourceUserId)) {
return null;
}
- List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
+ List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
resolvedType, flags, parentUserId);
if (resultTargetUser == null || resultTargetUser.isEmpty()) {
@@ -7444,7 +7371,7 @@
private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
String resolvedType, int flags, int sourceUserId) {
int targetUserId = filter.getTargetUserId();
- List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
+ List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
resolvedType, flags, targetUserId);
if (resultTargetUser != null && isUserEnabled(targetUserId)) {
// If all the matches in the target profile are suspended, return null.
@@ -7752,14 +7679,14 @@
String pkgName = intent.getPackage();
if (pkgName == null) {
final List<ResolveInfo> result =
- mReceivers.queryIntent(intent, resolvedType, flags, userId);
+ mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
return applyPostResolutionFilter(
result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
intent);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
- final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
+ final List<ResolveInfo> result = mComponentResolver.queryReceivers(
intent, resolvedType, flags, pkg.receivers, userId);
return applyPostResolutionFilter(
result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
@@ -7856,13 +7783,13 @@
String pkgName = intent.getPackage();
if (pkgName == null) {
return applyPostServiceResolutionFilter(
- mServices.queryIntent(intent, resolvedType, flags, userId),
+ mComponentResolver.queryServices(intent, resolvedType, flags, userId),
instantAppPkgName);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return applyPostServiceResolutionFilter(
- mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
+ mComponentResolver.queryServices(intent, resolvedType, flags, pkg.services,
userId),
instantAppPkgName);
}
@@ -7974,14 +7901,14 @@
String pkgName = intent.getPackage();
if (pkgName == null) {
return applyPostContentProviderResolutionFilter(
- mProviders.queryIntent(intent, resolvedType, flags, userId),
+ mComponentResolver.queryProviders(intent, resolvedType, flags, userId),
instantAppPkgName);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
return applyPostContentProviderResolutionFilter(
- mProviders.queryIntentForPackage(
- intent, resolvedType, flags, pkg.providers, userId),
+ mComponentResolver.queryProviders(intent, resolvedType, flags,
+ pkg.providers, userId),
instantAppPkgName);
}
return Collections.emptyList();
@@ -8394,26 +8321,22 @@
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForComponent(flags, userId, name);
final int callingUid = Binder.getCallingUid();
- synchronized (mPackages) {
- final PackageParser.Provider provider = mProvidersByAuthority.get(name);
- PackageSetting ps = provider != null
- ? mSettings.mPackages.get(provider.owner.packageName)
- : null;
- if (ps != null) {
- // provider not enabled
- if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
- return null;
- }
- final ComponentName component =
- new ComponentName(provider.info.packageName, provider.info.name);
- if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
- return null;
- }
- return PackageParser.generateProviderInfo(
- provider, flags, ps.readUserState(userId), userId);
- }
+ final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
+ if (providerInfo == null) {
return null;
}
+ if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
+ return null;
+ }
+ synchronized (mPackages) {
+ final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
+ final ComponentName component =
+ new ComponentName(providerInfo.packageName, providerInfo.name);
+ if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
+ return null;
+ }
+ return providerInfo;
+ }
}
/**
@@ -8424,28 +8347,8 @@
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return;
}
- // reader
- synchronized (mPackages) {
- final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
- .entrySet().iterator();
- final int userId = UserHandle.getCallingUserId();
- while (i.hasNext()) {
- Map.Entry<String, PackageParser.Provider> entry = i.next();
- PackageParser.Provider p = entry.getValue();
- PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
-
- if (ps != null && p.syncable
- && (!mSafeMode || (p.info.applicationInfo.flags
- &ApplicationInfo.FLAG_SYSTEM) != 0)) {
- ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
- ps.readUserState(userId), userId);
- if (info != null) {
- outNames.add(entry.getKey());
- outInfo.add(info);
- }
- }
- }
- }
+ mComponentResolver.querySyncProviders(
+ outNames, outInfo, mSafeMode, UserHandle.getCallingUserId());
}
@Override
@@ -8457,43 +8360,30 @@
if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForComponent(flags, userId, processName);
ArrayList<ProviderInfo> finalList = null;
- // reader
+ final List<ProviderInfo> matchList =
+ mComponentResolver.queryProviders(processName, metaDataKey, uid, flags, userId);
+ final int listSize = (matchList == null ? 0 : matchList.size());
synchronized (mPackages) {
- final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
- while (i.hasNext()) {
- final PackageParser.Provider p = i.next();
- PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
- if (ps != null && p.info.authority != null
- && (processName == null
- || (p.info.processName.equals(processName)
- && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
- && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
-
- // See PM.queryContentProviders()'s javadoc for why we have the metaData
- // parameter.
- if (metaDataKey != null
- && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
- continue;
- }
- final ComponentName component =
- new ComponentName(p.info.packageName, p.info.name);
- if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
- continue;
- }
- if (finalList == null) {
- finalList = new ArrayList<>(3);
- }
- ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
- ps.readUserState(userId), userId);
- if (info != null) {
- finalList.add(info);
- }
+ for (int i = 0; i < listSize; i++) {
+ final ProviderInfo providerInfo = matchList.get(i);
+ if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
+ continue;
}
+ final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
+ final ComponentName component =
+ new ComponentName(providerInfo.packageName, providerInfo.name);
+ if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
+ continue;
+ }
+ if (finalList == null) {
+ finalList = new ArrayList<>(listSize - i);
+ }
+ finalList.add(providerInfo);
}
}
if (finalList != null) {
- finalList.sort(mProviderInitOrderSorter);
+ finalList.sort(sProviderInitOrderSorter);
return new ParceledListSlice<>(finalList);
}
@@ -9063,8 +8953,7 @@
+ pkg.staticSharedLibVersion);
}
- private static String fixProcessName(String defProcessName,
- String processName) {
+ static String fixProcessName(String defProcessName, String processName) {
if (processName == null) {
return defProcessName;
}
@@ -11358,27 +11247,7 @@
// package isn't already installed, since we don't want to break
// things that are installed.
if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
- final int N = pkg.providers.size();
- int i;
- for (i=0; i<N; i++) {
- PackageParser.Provider p = pkg.providers.get(i);
- if (p.info.authority != null) {
- String names[] = p.info.authority.split(";");
- for (int j = 0; j < names.length; j++) {
- if (mProvidersByAuthority.containsKey(names[j])) {
- PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
- final String otherPackageName =
- ((other != null && other.getComponentName() != null) ?
- other.getComponentName().getPackageName() : "?");
- throw new PackageManagerException(
- INSTALL_FAILED_CONFLICTING_PROVIDER,
- "Can't install because provider name " + names[j]
- + " (in package " + pkg.applicationInfo.packageName
- + ") is already used by " + otherPackageName);
- }
- }
- }
- }
+ mComponentResolver.assertProvidersNotDefined(pkg);
}
// Verify that packages sharing a user with a privileged app are marked as privileged.
@@ -11676,125 +11545,7 @@
KeySetManagerService ksms = mSettings.mKeySetManagerService;
ksms.addScannedPackageLPw(pkg);
- int N = pkg.providers.size();
- StringBuilder r = null;
- int i;
- for (i=0; i<N; i++) {
- PackageParser.Provider p = pkg.providers.get(i);
- p.info.processName = fixProcessName(pkg.applicationInfo.processName,
- p.info.processName);
- mProviders.addProvider(p);
- p.syncable = p.info.isSyncable;
- if (p.info.authority != null) {
- String names[] = p.info.authority.split(";");
- p.info.authority = null;
- for (int j = 0; j < names.length; j++) {
- if (j == 1 && p.syncable) {
- // We only want the first authority for a provider to possibly be
- // syncable, so if we already added this provider using a different
- // authority clear the syncable flag. We copy the provider before
- // changing it because the mProviders object contains a reference
- // to a provider that we don't want to change.
- // Only do this for the second authority since the resulting provider
- // object can be the same for all future authorities for this provider.
- p = new PackageParser.Provider(p);
- p.syncable = false;
- }
- if (!mProvidersByAuthority.containsKey(names[j])) {
- mProvidersByAuthority.put(names[j], p);
- if (p.info.authority == null) {
- p.info.authority = names[j];
- } else {
- p.info.authority = p.info.authority + ";" + names[j];
- }
- if (DEBUG_PACKAGE_SCANNING) {
- if (chatty)
- Log.d(TAG, "Registered content provider: " + names[j]
- + ", className = " + p.info.name + ", isSyncable = "
- + p.info.isSyncable);
- }
- } else {
- PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
- Slog.w(TAG, "Skipping provider name " + names[j] +
- " (in package " + pkg.applicationInfo.packageName +
- "): name already used by "
- + ((other != null && other.getComponentName() != null)
- ? other.getComponentName().getPackageName() : "?"));
- }
- }
- }
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(p.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r);
- }
-
- N = pkg.services.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Service s = pkg.services.get(i);
- s.info.processName = fixProcessName(pkg.applicationInfo.processName,
- s.info.processName);
- mServices.addService(s);
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(s.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r);
- }
-
- N = pkg.receivers.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Activity a = pkg.receivers.get(i);
- a.info.processName = fixProcessName(pkg.applicationInfo.processName,
- a.info.processName);
- mReceivers.addActivity(a, "receiver");
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(a.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r);
- }
-
- N = pkg.activities.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Activity a = pkg.activities.get(i);
- a.info.processName = fixProcessName(pkg.applicationInfo.processName,
- a.info.processName);
- mActivities.addActivity(a, "activity");
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(a.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r);
- }
+ mComponentResolver.addAllComponents(pkg, chatty);
// Don't allow ephemeral applications to define new permissions groups.
if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
@@ -11812,9 +11563,10 @@
mPermissionManager.addAllPermissions(pkg, chatty);
}
- N = pkg.instrumentation.size();
- r = null;
- for (i=0; i<N; i++) {
+ int collectionSize = pkg.instrumentation.size();
+ StringBuilder r = null;
+ int i;
+ for (i = 0; i < collectionSize; i++) {
PackageParser.Instrumentation a = pkg.instrumentation.get(i);
a.info.packageName = pkg.applicationInfo.packageName;
a.info.sourceDir = pkg.applicationInfo.sourceDir;
@@ -11845,9 +11597,9 @@
}
if (pkg.protectedBroadcasts != null) {
- N = pkg.protectedBroadcasts.size();
+ collectionSize = pkg.protectedBroadcasts.size();
synchronized (mProtectedBroadcasts) {
- for (i = 0; i < N; i++) {
+ for (i = 0; i < collectionSize; i++) {
mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
}
}
@@ -12466,105 +12218,15 @@
}
void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
- int N = pkg.providers.size();
- StringBuilder r = null;
- int i;
- for (i=0; i<N; i++) {
- PackageParser.Provider p = pkg.providers.get(i);
- mProviders.removeProvider(p);
- if (p.info.authority == null) {
-
- /* There was another ContentProvider with this authority when
- * this app was installed so this authority is null,
- * Ignore it as we don't have to unregister the provider.
- */
- continue;
- }
- String names[] = p.info.authority.split(";");
- for (int j = 0; j < names.length; j++) {
- if (mProvidersByAuthority.get(names[j]) == p) {
- mProvidersByAuthority.remove(names[j]);
- if (DEBUG_REMOVE) {
- if (chatty)
- Log.d(TAG, "Unregistered content provider: " + names[j]
- + ", className = " + p.info.name + ", isSyncable = "
- + p.info.isSyncable);
- }
- }
- }
- if (DEBUG_REMOVE && chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(p.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r);
- }
-
- N = pkg.services.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Service s = pkg.services.get(i);
- mServices.removeService(s);
- if (chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(s.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r);
- }
-
- N = pkg.receivers.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Activity a = pkg.receivers.get(i);
- mReceivers.removeActivity(a, "receiver");
- if (DEBUG_REMOVE && chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(a.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r);
- }
-
- N = pkg.activities.size();
- r = null;
- for (i=0; i<N; i++) {
- PackageParser.Activity a = pkg.activities.get(i);
- mActivities.removeActivity(a, "activity");
- if (DEBUG_REMOVE && chatty) {
- if (r == null) {
- r = new StringBuilder(256);
- } else {
- r.append(' ');
- }
- r.append(a.info.name);
- }
- }
- if (r != null) {
- if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
- }
+ mComponentResolver.removeAllComponents(pkg, chatty);
final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
mPermissionManager.removeAllPermissions(pkg, allPackageNames, mPermissionCallback, chatty);
- N = pkg.instrumentation.size();
- r = null;
- for (i=0; i<N; i++) {
+ final int instrumentationSize = pkg.instrumentation.size();
+ StringBuilder r = null;
+ int i;
+ for (i = 0; i < instrumentationSize; i++) {
PackageParser.Instrumentation a = pkg.instrumentation.get(i);
mInstrumentation.remove(a.getComponentName());
if (DEBUG_REMOVE && chatty) {
@@ -12584,7 +12246,8 @@
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
// Only system apps can hold shared libraries.
if (pkg.libraryNames != null) {
- for (i = 0; i < pkg.libraryNames.size(); i++) {
+ final int libraryNamesSize = pkg.libraryNames.size();
+ for (i = 0; i < libraryNamesSize; i++) {
String name = pkg.libraryNames.get(i);
if (removeSharedLibraryLPw(name, 0)) {
if (DEBUG_REMOVE && chatty) {
@@ -12621,1135 +12284,6 @@
}
}
-
- final class ActivityIntentResolver
- extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
- 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(Intent intent, String resolvedType, int flags,
- int userId) {
- if (!sUserManager.exists(userId)) return null;
- mFlags = flags;
- return super.queryIntent(intent, resolvedType,
- (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- userId);
- }
-
- public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
- int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
- if (!sUserManager.exists(userId)) return null;
- if (packageActivities == null) {
- return null;
- }
- mFlags = flags;
- final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
- final int N = packageActivities.size();
- ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
- new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
-
- ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
- for (int i = 0; i < N; ++i) {
- intentFilters = packageActivities.get(i).intents;
- if (intentFilters != null && intentFilters.size() > 0) {
- PackageParser.ActivityIntentInfo[] array =
- new PackageParser.ActivityIntentInfo[intentFilters.size()];
- intentFilters.toArray(array);
- listCut.add(array);
- }
- }
- return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
- }
-
- /**
- * Finds a privileged activity that matches the specified activity names.
- */
- private PackageParser.Activity findMatchingActivity(
- List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
- for (PackageParser.Activity sysActivity : activityList) {
- if (sysActivity.info.name.equals(activityInfo.name)) {
- return sysActivity;
- }
- if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
- return sysActivity;
- }
- if (sysActivity.info.targetActivity != null) {
- if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
- return sysActivity;
- }
- if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
- return sysActivity;
- }
- }
- }
- return null;
- }
-
- public class IterGenerator<E> {
- public Iterator<E> generate(ActivityIntentInfo info) {
- return null;
- }
- }
-
- public class ActionIterGenerator extends IterGenerator<String> {
- @Override
- public Iterator<String> generate(ActivityIntentInfo info) {
- return info.actionsIterator();
- }
- }
-
- public class CategoriesIterGenerator extends IterGenerator<String> {
- @Override
- public Iterator<String> generate(ActivityIntentInfo info) {
- return info.categoriesIterator();
- }
- }
-
- public class SchemesIterGenerator extends IterGenerator<String> {
- @Override
- public Iterator<String> generate(ActivityIntentInfo info) {
- return info.schemesIterator();
- }
- }
-
- public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
- @Override
- public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
- return info.authoritiesIterator();
- }
- }
-
- /**
- * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
- * MODIFIED. Do not pass in a list that should not be changed.
- */
- private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
- IterGenerator<T> generator, Iterator<T> searchIterator) {
- // loop through the set of actions; every one must be found in the intent filter
- while (searchIterator.hasNext()) {
- // we must have at least one filter in the list to consider a match
- if (intentList.size() == 0) {
- break;
- }
-
- final T searchAction = searchIterator.next();
-
- // loop through the set of intent filters
- final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
- while (intentIter.hasNext()) {
- final ActivityIntentInfo intentInfo = intentIter.next();
- boolean selectionFound = false;
-
- // loop through the intent filter's selection criteria; at least one
- // of them must match the searched criteria
- final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
- while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
- final T intentSelection = intentSelectionIter.next();
- if (intentSelection != null && intentSelection.equals(searchAction)) {
- selectionFound = true;
- break;
- }
- }
-
- // the selection criteria wasn't found in this filter's set; this filter
- // is not a potential match
- if (!selectionFound) {
- intentIter.remove();
- }
- }
- }
- }
-
- private boolean isProtectedAction(ActivityIntentInfo filter) {
- final Iterator<String> actionsIter = filter.actionsIterator();
- while (actionsIter != null && actionsIter.hasNext()) {
- final String filterAction = actionsIter.next();
- if (PROTECTED_ACTIONS.contains(filterAction)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Adjusts the priority of the given intent filter according to policy.
- * <p>
- * <ul>
- * <li>The priority for non privileged applications is capped to '0'</li>
- * <li>The priority for protected actions on privileged applications is capped to '0'</li>
- * <li>The priority for unbundled updates to privileged applications is capped to the
- * priority defined on the system partition</li>
- * </ul>
- * <p>
- * <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<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
- // nothing to do; priority is fine as-is
- if (intent.getPriority() <= 0) {
- return;
- }
-
- final ActivityInfo activityInfo = intent.activity.info;
- final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
-
- final boolean privilegedApp =
- ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
- if (!privilegedApp) {
- // non-privileged applications can never define a priority >0
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Non-privileged app; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
- + " origPrio: " + intent.getPriority());
- }
- intent.setPriority(0);
- return;
- }
-
- if (systemActivities == null) {
- // the system package is not disabled; we're parsing the system partition
- if (isProtectedAction(intent)) {
- if (mDeferProtectedFilters) {
- // We can't deal with these just yet. No component should ever obtain a
- // >0 priority for a protected actions, with ONE exception -- the setup
- // wizard. The setup wizard, however, cannot be known until we're able to
- // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
- // until all intent filters have been processed. Chicken, meet egg.
- // Let the filter temporarily have a high priority and rectify the
- // priorities after all system packages have been scanned.
- mProtectedFilters.add(intent);
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Protected action; save for later;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
- + " origPrio: " + intent.getPriority());
- }
- return;
- } else {
- if (DEBUG_FILTERS && mSetupWizardPackage == null) {
- Slog.i(TAG, "No setup wizard;"
- + " All protected intents capped to priority 0");
- }
- if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Found setup wizard;"
- + " allow priority " + intent.getPriority() + ";"
- + " package: " + intent.activity.info.packageName
- + " activity: " + intent.activity.className
- + " priority: " + intent.getPriority());
- }
- // setup wizard gets whatever it wants
- return;
- }
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Protected action; cap priority to 0;"
- + " package: " + intent.activity.info.packageName
- + " activity: " + intent.activity.className
- + " origPrio: " + intent.getPriority());
- }
- intent.setPriority(0);
- return;
- }
- }
- // privileged apps on the system image get whatever priority they request
- return;
- }
-
- // privileged app unbundled update ... try to find the same activity
- final PackageParser.Activity foundActivity =
- findMatchingActivity(systemActivities, activityInfo);
- if (foundActivity == null) {
- // this is a new activity; it cannot obtain >0 priority
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "New activity; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
- + " origPrio: " + intent.getPriority());
- }
- intent.setPriority(0);
- return;
- }
-
- // found activity, now check for filter equivalence
-
- // a shallow copy is enough; we modify the list, not its contents
- final List<ActivityIntentInfo> intentListCopy =
- new ArrayList<>(foundActivity.intents);
- final List<ActivityIntentInfo> foundFilters = findFilters(intent);
-
- // find matching action subsets
- final Iterator<String> actionsIterator = intent.actionsIterator();
- if (actionsIterator != null) {
- getIntentListSubset(
- intentListCopy, new ActionIterGenerator(), actionsIterator);
- if (intentListCopy.size() == 0) {
- // no more intents to match; we're not equivalent
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Mismatched action; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
- + " origPrio: " + intent.getPriority());
- }
- intent.setPriority(0);
- return;
- }
- }
-
- // find matching category subsets
- final Iterator<String> categoriesIterator = intent.categoriesIterator();
- if (categoriesIterator != null) {
- getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
- categoriesIterator);
- if (intentListCopy.size() == 0) {
- // no more intents to match; we're not equivalent
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Mismatched category; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
- + " origPrio: " + intent.getPriority());
- }
- intent.setPriority(0);
- return;
- }
- }
-
- // find matching schemes subsets
- final Iterator<String> schemesIterator = intent.schemesIterator();
- if (schemesIterator != null) {
- getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
- schemesIterator);
- if (intentListCopy.size() == 0) {
- // no more intents to match; we're not equivalent
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
- + " origPrio: " + intent.getPriority());
- }
- intent.setPriority(0);
- return;
- }
- }
-
- // find matching authorities subsets
- final Iterator<IntentFilter.AuthorityEntry>
- authoritiesIterator = intent.authoritiesIterator();
- if (authoritiesIterator != null) {
- getIntentListSubset(intentListCopy,
- new AuthoritiesIterGenerator(),
- authoritiesIterator);
- if (intentListCopy.size() == 0) {
- // no more intents to match; we're not equivalent
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Mismatched authority; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
- + " origPrio: " + intent.getPriority());
- }
- intent.setPriority(0);
- return;
- }
- }
-
- // we found matching filter(s); app gets the max priority of all intents
- int cappedPriority = 0;
- for (int i = intentListCopy.size() - 1; i >= 0; --i) {
- cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
- }
- if (intent.getPriority() > cappedPriority) {
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Found matching filter(s);"
- + " cap priority to " + cappedPriority + ";"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
- + " origPrio: " + intent.getPriority());
- }
- intent.setPriority(cappedPriority);
- return;
- }
- // all this for nothing; the requested priority was <= what was on the system
- }
-
- public final void addActivity(PackageParser.Activity a, String type) {
- mActivities.put(a.getComponentName(), a);
- if (DEBUG_SHOW_INFO)
- Log.v(
- TAG, " " + type + " " +
- (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
- if (DEBUG_SHOW_INFO)
- Log.v(TAG, " Class=" + a.info.name);
- final int NI = a.intents.size();
- for (int j=0; j<NI; j++) {
- PackageParser.ActivityIntentInfo intent = a.intents.get(j);
- if ("activity".equals(type)) {
- final PackageSetting ps =
- mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
- final List<PackageParser.Activity> systemActivities =
- ps != null && ps.pkg != null ? ps.pkg.activities : null;
- adjustPriority(systemActivities, intent);
- }
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " IntentFilter:");
- intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
- }
- if (!intent.debugCheck()) {
- Log.w(TAG, "==> For Activity " + a.info.name);
- }
- addFilter(intent);
- }
- }
-
- public final void removeActivity(PackageParser.Activity a, String type) {
- mActivities.remove(a.getComponentName());
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " " + type + " "
- + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
- : a.info.name) + ":");
- Log.v(TAG, " Class=" + a.info.name);
- }
- final int NI = a.intents.size();
- for (int j=0; j<NI; j++) {
- PackageParser.ActivityIntentInfo intent = a.intents.get(j);
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " IntentFilter:");
- intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
- }
- removeFilter(intent);
- }
- }
-
- @Override
- protected boolean allowFilterResult(
- PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
- ActivityInfo filterAi = filter.activity.info;
- for (int i=dest.size()-1; i>=0; i--) {
- ActivityInfo destAi = dest.get(i).activityInfo;
- if (destAi.name == filterAi.name
- && destAi.packageName == filterAi.packageName) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- protected ActivityIntentInfo[] newArray(int size) {
- return new ActivityIntentInfo[size];
- }
-
- @Override
- protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
- if (!sUserManager.exists(userId)) return true;
- PackageParser.Package p = filter.activity.owner;
- if (p != null) {
- PackageSetting ps = (PackageSetting)p.mExtras;
- if (ps != null) {
- // 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.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
- && ps.getStopped(userId);
- }
- }
- return false;
- }
-
- @Override
- protected boolean isPackageForFilter(String packageName,
- PackageParser.ActivityIntentInfo info) {
- return packageName.equals(info.activity.owner.packageName);
- }
-
- @Override
- protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
- int match, int userId) {
- if (!sUserManager.exists(userId)) return null;
- if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
- return null;
- }
- final PackageParser.Activity activity = info.activity;
- PackageSetting ps = (PackageSetting) activity.owner.mExtras;
- if (ps == null) {
- return null;
- }
- final PackageUserState userState = ps.readUserState(userId);
- ActivityInfo ai =
- PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
- if (ai == null) {
- return null;
- }
- final boolean matchExplicitlyVisibleOnly =
- (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
- final boolean matchVisibleToInstantApp =
- (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
- final boolean componentVisible =
- matchVisibleToInstantApp
- && info.isVisibleToInstantApp()
- && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
- final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
- // throw out filters that aren't visible to ephemeral apps
- if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
- return null;
- }
- // throw out instant app filters if we're not explicitly requesting them
- if (!matchInstantApp && userState.instantApp) {
- return null;
- }
- // throw out instant app filters if updates are available; will trigger
- // instant app resolution
- if (userState.instantApp && ps.isUpdateAvailable()) {
- return null;
- }
- final ResolveInfo res = new ResolveInfo();
- res.activityInfo = ai;
- if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
- res.filter = info;
- }
- res.handleAllWebDataURI = info.handleAllWebDataURI();
- res.priority = info.getPriority();
- res.preferredOrder = activity.owner.mPreferredOrder;
- //System.out.println("Result: " + res.activityInfo.className +
- // " = " + res.priority);
- res.match = match;
- res.isDefault = info.hasDefault;
- res.labelRes = info.labelRes;
- res.nonLocalizedLabel = info.nonLocalizedLabel;
- if (userNeedsBadging(userId)) {
- res.noResourceId = true;
- } else {
- res.icon = info.icon;
- }
- res.iconResourceId = info.icon;
- res.system = res.activityInfo.applicationInfo.isSystemApp();
- res.isInstantAppAvailable = userState.instantApp;
- return res;
- }
-
- @Override
- protected void sortResults(List<ResolveInfo> results) {
- results.sort(mResolvePrioritySorter);
- }
-
- @Override
- protected void dumpFilter(PrintWriter out, String prefix,
- PackageParser.ActivityIntentInfo filter) {
- out.print(prefix); out.print(
- Integer.toHexString(System.identityHashCode(filter.activity)));
- out.print(' ');
- filter.activity.printComponentShortName(out);
- out.print(" filter ");
- out.println(Integer.toHexString(System.identityHashCode(filter)));
- }
-
- @Override
- protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
- return filter.activity;
- }
-
- protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
- PackageParser.Activity activity = (PackageParser.Activity)label;
- out.print(prefix); out.print(
- Integer.toHexString(System.identityHashCode(activity)));
- out.print(' ');
- activity.printComponentShortName(out);
- if (count > 1) {
- out.print(" ("); out.print(count); out.print(" filters)");
- }
- out.println();
- }
-
- // Keys are String (activity class name), values are Activity.
- private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
- = new ArrayMap<>();
- private int mFlags;
- }
-
- private final class ServiceIntentResolver
- extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
- 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(Intent intent, String resolvedType, int flags,
- int userId) {
- if (!sUserManager.exists(userId)) return null;
- mFlags = flags;
- return super.queryIntent(intent, resolvedType,
- (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- userId);
- }
-
- public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
- int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
- if (!sUserManager.exists(userId)) return null;
- if (packageServices == null) {
- return null;
- }
- mFlags = flags;
- final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
- final int N = packageServices.size();
- ArrayList<PackageParser.ServiceIntentInfo[]> listCut = new ArrayList<>(N);
-
- ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
- for (int i = 0; i < N; ++i) {
- intentFilters = packageServices.get(i).intents;
- if (intentFilters != null && intentFilters.size() > 0) {
- PackageParser.ServiceIntentInfo[] array =
- new PackageParser.ServiceIntentInfo[intentFilters.size()];
- intentFilters.toArray(array);
- listCut.add(array);
- }
- }
- return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
- }
-
- public final void addService(PackageParser.Service s) {
- mServices.put(s.getComponentName(), s);
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " "
- + (s.info.nonLocalizedLabel != null
- ? s.info.nonLocalizedLabel : s.info.name) + ":");
- Log.v(TAG, " Class=" + s.info.name);
- }
- final int NI = s.intents.size();
- int j;
- for (j=0; j<NI; j++) {
- PackageParser.ServiceIntentInfo intent = s.intents.get(j);
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " IntentFilter:");
- intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
- }
- if (!intent.debugCheck()) {
- Log.w(TAG, "==> For Service " + s.info.name);
- }
- addFilter(intent);
- }
- }
-
- public final void removeService(PackageParser.Service s) {
- mServices.remove(s.getComponentName());
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
- ? s.info.nonLocalizedLabel : s.info.name) + ":");
- Log.v(TAG, " Class=" + s.info.name);
- }
- final int NI = s.intents.size();
- int j;
- for (j=0; j<NI; j++) {
- PackageParser.ServiceIntentInfo intent = s.intents.get(j);
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " IntentFilter:");
- intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
- }
- removeFilter(intent);
- }
- }
-
- @Override
- protected boolean allowFilterResult(
- PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
- ServiceInfo filterSi = filter.service.info;
- for (int i=dest.size()-1; i>=0; i--) {
- ServiceInfo destAi = dest.get(i).serviceInfo;
- if (destAi.name == filterSi.name
- && destAi.packageName == filterSi.packageName) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- protected PackageParser.ServiceIntentInfo[] newArray(int size) {
- return new PackageParser.ServiceIntentInfo[size];
- }
-
- @Override
- protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
- if (!sUserManager.exists(userId)) return true;
- PackageParser.Package p = filter.service.owner;
- if (p != null) {
- PackageSetting ps = (PackageSetting)p.mExtras;
- if (ps != null) {
- // 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.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
- && ps.getStopped(userId);
- }
- }
- return false;
- }
-
- @Override
- protected boolean isPackageForFilter(String packageName,
- PackageParser.ServiceIntentInfo info) {
- return packageName.equals(info.service.owner.packageName);
- }
-
- @Override
- protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
- int match, int userId) {
- if (!sUserManager.exists(userId)) return null;
- final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
- if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
- return null;
- }
- final PackageParser.Service service = info.service;
- PackageSetting ps = (PackageSetting) service.owner.mExtras;
- if (ps == null) {
- return null;
- }
- final PackageUserState userState = ps.readUserState(userId);
- ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
- userState, userId);
- 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;
- // throw out filters that aren't visible to ephemeral apps
- if (matchVisibleToInstantApp
- && !(info.isVisibleToInstantApp() || userState.instantApp)) {
- return null;
- }
- // throw out ephemeral filters if we're not explicitly requesting them
- if (!isInstantApp && userState.instantApp) {
- return null;
- }
- // throw out instant app filters if updates are available; will trigger
- // instant app resolution
- if (userState.instantApp && ps.isUpdateAvailable()) {
- return null;
- }
- final ResolveInfo res = new ResolveInfo();
- res.serviceInfo = si;
- if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
- res.filter = filter;
- }
- res.priority = info.getPriority();
- res.preferredOrder = service.owner.mPreferredOrder;
- res.match = match;
- res.isDefault = info.hasDefault;
- res.labelRes = info.labelRes;
- res.nonLocalizedLabel = info.nonLocalizedLabel;
- res.icon = info.icon;
- res.system = res.serviceInfo.applicationInfo.isSystemApp();
- return res;
- }
-
- @Override
- protected void sortResults(List<ResolveInfo> results) {
- results.sort(mResolvePrioritySorter);
- }
-
- @Override
- protected void dumpFilter(PrintWriter out, String prefix,
- PackageParser.ServiceIntentInfo filter) {
- out.print(prefix); out.print(
- Integer.toHexString(System.identityHashCode(filter.service)));
- out.print(' ');
- filter.service.printComponentShortName(out);
- out.print(" filter ");
- out.print(Integer.toHexString(System.identityHashCode(filter)));
- if (filter.service.info.permission != null) {
- out.print(" permission "); out.println(filter.service.info.permission);
- } else {
- out.println();
- }
- }
-
- @Override
- protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
- return filter.service;
- }
-
- protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
- PackageParser.Service service = (PackageParser.Service)label;
- out.print(prefix); out.print(
- Integer.toHexString(System.identityHashCode(service)));
- out.print(' ');
- service.printComponentShortName(out);
- if (count > 1) {
- out.print(" ("); out.print(count); out.print(" filters)");
- }
- out.println();
- }
-
-// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
-// final Iterator<ResolveInfo> i = resolveInfoList.iterator();
-// final List<ResolveInfo> retList = Lists.newArrayList();
-// while (i.hasNext()) {
-// final ResolveInfo resolveInfo = (ResolveInfo) i;
-// if (isEnabledLP(resolveInfo.serviceInfo)) {
-// retList.add(resolveInfo);
-// }
-// }
-// return retList;
-// }
-
- // Keys are String (activity class name), values are Activity.
- private final ArrayMap<ComponentName, PackageParser.Service> mServices = new ArrayMap<>();
- private int mFlags;
- }
-
- private final class ProviderIntentResolver
- extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
- 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(Intent intent, String resolvedType, int flags,
- int userId) {
- if (!sUserManager.exists(userId))
- return null;
- mFlags = flags;
- return super.queryIntent(intent, resolvedType,
- (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- userId);
- }
-
- public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
- int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
- if (!sUserManager.exists(userId))
- return null;
- if (packageProviders == null) {
- return null;
- }
- mFlags = flags;
- final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
- final int N = packageProviders.size();
- ArrayList<PackageParser.ProviderIntentInfo[]> listCut = new ArrayList<>(N);
-
- ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
- for (int i = 0; i < N; ++i) {
- intentFilters = packageProviders.get(i).intents;
- if (intentFilters != null && intentFilters.size() > 0) {
- PackageParser.ProviderIntentInfo[] array =
- new PackageParser.ProviderIntentInfo[intentFilters.size()];
- intentFilters.toArray(array);
- listCut.add(array);
- }
- }
- return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
- }
-
- public final void addProvider(PackageParser.Provider p) {
- if (mProviders.containsKey(p.getComponentName())) {
- Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
- return;
- }
-
- mProviders.put(p.getComponentName(), p);
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " "
- + (p.info.nonLocalizedLabel != null
- ? p.info.nonLocalizedLabel : p.info.name) + ":");
- Log.v(TAG, " Class=" + p.info.name);
- }
- final int NI = p.intents.size();
- int j;
- for (j = 0; j < NI; j++) {
- PackageParser.ProviderIntentInfo intent = p.intents.get(j);
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " IntentFilter:");
- intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
- }
- if (!intent.debugCheck()) {
- Log.w(TAG, "==> For Provider " + p.info.name);
- }
- addFilter(intent);
- }
- }
-
- public final void removeProvider(PackageParser.Provider p) {
- mProviders.remove(p.getComponentName());
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " " + (p.info.nonLocalizedLabel != null
- ? p.info.nonLocalizedLabel : p.info.name) + ":");
- Log.v(TAG, " Class=" + p.info.name);
- }
- final int NI = p.intents.size();
- int j;
- for (j = 0; j < NI; j++) {
- PackageParser.ProviderIntentInfo intent = p.intents.get(j);
- if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " IntentFilter:");
- intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
- }
- removeFilter(intent);
- }
- }
-
- @Override
- protected boolean allowFilterResult(
- PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
- ProviderInfo filterPi = filter.provider.info;
- for (int i = dest.size() - 1; i >= 0; i--) {
- ProviderInfo destPi = dest.get(i).providerInfo;
- if (destPi.name == filterPi.name
- && destPi.packageName == filterPi.packageName) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- protected PackageParser.ProviderIntentInfo[] newArray(int size) {
- return new PackageParser.ProviderIntentInfo[size];
- }
-
- @Override
- protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
- if (!sUserManager.exists(userId))
- return true;
- PackageParser.Package p = filter.provider.owner;
- if (p != null) {
- PackageSetting ps = (PackageSetting) p.mExtras;
- if (ps != null) {
- // 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.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
- && ps.getStopped(userId);
- }
- }
- return false;
- }
-
- @Override
- protected boolean isPackageForFilter(String packageName,
- PackageParser.ProviderIntentInfo info) {
- return packageName.equals(info.provider.owner.packageName);
- }
-
- @Override
- protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
- int match, int userId) {
- if (!sUserManager.exists(userId))
- return null;
- final PackageParser.ProviderIntentInfo info = filter;
- if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
- return null;
- }
- final PackageParser.Provider provider = info.provider;
- PackageSetting ps = (PackageSetting) provider.owner.mExtras;
- if (ps == null) {
- return null;
- }
- final PackageUserState userState = ps.readUserState(userId);
- final boolean matchVisibleToInstantApp =
- (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
- final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
- // throw out filters that aren't visible to instant applications
- if (matchVisibleToInstantApp
- && !(info.isVisibleToInstantApp() || userState.instantApp)) {
- return null;
- }
- // throw out instant application filters if we're not explicitly requesting them
- if (!isInstantApp && userState.instantApp) {
- return null;
- }
- // throw out instant application filters if updates are available; will trigger
- // instant application resolution
- if (userState.instantApp && ps.isUpdateAvailable()) {
- return null;
- }
- ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
- userState, userId);
- if (pi == null) {
- return null;
- }
- final ResolveInfo res = new ResolveInfo();
- res.providerInfo = pi;
- if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
- res.filter = filter;
- }
- res.priority = info.getPriority();
- res.preferredOrder = provider.owner.mPreferredOrder;
- res.match = match;
- res.isDefault = info.hasDefault;
- res.labelRes = info.labelRes;
- res.nonLocalizedLabel = info.nonLocalizedLabel;
- res.icon = info.icon;
- res.system = res.providerInfo.applicationInfo.isSystemApp();
- return res;
- }
-
- @Override
- protected void sortResults(List<ResolveInfo> results) {
- results.sort(mResolvePrioritySorter);
- }
-
- @Override
- protected void dumpFilter(PrintWriter out, String prefix,
- PackageParser.ProviderIntentInfo filter) {
- out.print(prefix);
- out.print(
- Integer.toHexString(System.identityHashCode(filter.provider)));
- out.print(' ');
- filter.provider.printComponentShortName(out);
- out.print(" filter ");
- out.println(Integer.toHexString(System.identityHashCode(filter)));
- }
-
- @Override
- protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
- return filter.provider;
- }
-
- protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
- PackageParser.Provider provider = (PackageParser.Provider)label;
- out.print(prefix); out.print(
- Integer.toHexString(System.identityHashCode(provider)));
- out.print(' ');
- provider.printComponentShortName(out);
- if (count > 1) {
- out.print(" ("); out.print(count); out.print(" filters)");
- }
- out.println();
- }
-
- private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
- = new ArrayMap<>();
- private int mFlags;
- }
-
- static final class InstantAppIntentResolver
- extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
- AuxiliaryResolveInfo.AuxiliaryFilter> {
- /**
- * The result that has the highest defined order. Ordering applies on a
- * per-package basis. Mapping is from package name to Pair of order and
- * EphemeralResolveInfo.
- * <p>
- * NOTE: This is implemented as a field variable for convenience and efficiency.
- * By having a field variable, we're able to track filter ordering as soon as
- * a non-zero order is defined. Otherwise, multiple loops across the result set
- * would be needed to apply ordering. If the intent resolver becomes re-entrant,
- * this needs to be contained entirely within {@link #filterResults}.
- */
- final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
-
- @Override
- protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
- return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
- }
-
- @Override
- protected boolean isPackageForFilter(String packageName,
- AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
- return true;
- }
-
- @Override
- protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
- AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
- if (!sUserManager.exists(userId)) {
- return null;
- }
- final String packageName = responseObj.resolveInfo.getPackageName();
- final Integer order = responseObj.getOrder();
- final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
- mOrderResult.get(packageName);
- // ordering is enabled and this item's order isn't high enough
- if (lastOrderResult != null && lastOrderResult.first >= order) {
- return null;
- }
- final InstantAppResolveInfo res = responseObj.resolveInfo;
- if (order > 0) {
- // non-zero order, enable ordering
- mOrderResult.put(packageName, new Pair<>(order, res));
- }
- return responseObj;
- }
-
- @Override
- protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
- // only do work if ordering is enabled [most of the time it won't be]
- if (mOrderResult.size() == 0) {
- return;
- }
- int resultSize = results.size();
- for (int i = 0; i < resultSize; i++) {
- final InstantAppResolveInfo info = results.get(i).resolveInfo;
- final String packageName = info.getPackageName();
- final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
- if (savedInfo == null) {
- // package doesn't having ordering
- continue;
- }
- if (savedInfo.second == info) {
- // circled back to the highest ordered item; remove from order list
- mOrderResult.remove(packageName);
- if (mOrderResult.size() == 0) {
- // no more ordered items
- break;
- }
- continue;
- }
- // item has a worse order, remove it from the result list
- results.remove(i);
- resultSize--;
- i--;
- }
- }
- }
-
- private static final Comparator<ResolveInfo> mResolvePrioritySorter = (r1, r2) -> {
- int v1 = r1.priority;
- int v2 = r2.priority;
- //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
- if (v1 != v2) {
- return (v1 > v2) ? -1 : 1;
- }
- v1 = r1.preferredOrder;
- v2 = r2.preferredOrder;
- if (v1 != v2) {
- return (v1 > v2) ? -1 : 1;
- }
- if (r1.isDefault != r2.isDefault) {
- return r1.isDefault ? -1 : 1;
- }
- v1 = r1.match;
- v2 = r2.match;
- //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
- if (v1 != v2) {
- return (v1 > v2) ? -1 : 1;
- }
- if (r1.system != r2.system) {
- return r1.system ? -1 : 1;
- }
- if (r1.activityInfo != null) {
- return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
- }
- if (r1.serviceInfo != null) {
- return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
- }
- if (r1.providerInfo != null) {
- return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
- }
- return 0;
- };
-
- private static final Comparator<ProviderInfo> mProviderInitOrderSorter = (p1, p2) -> {
- final int v1 = p1.initOrder;
- final int v2 = p2.initOrder;
- return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
- };
-
@Override
public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
@@ -13789,6 +12323,12 @@
}
}
+ private static final Comparator<ProviderInfo> sProviderInitOrderSorter = (p1, p2) -> {
+ final int v1 = p1.initOrder;
+ final int v2 = p2.initOrder;
+ return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
+ };
+
@Override
public void notifyPackageRemoved(String packageName) {
final PackageListObserver[] observers;
@@ -20181,7 +18721,7 @@
try {
synchronized (mPackages) {
clearPackagePreferredActivitiesLPw(null, userId);
- mSettings.applyDefaultPreferredAppsLPw(this, userId);
+ mSettings.applyDefaultPreferredAppsLPw(userId);
// TODO: We have to reset the default SMS and Phone. This requires
// significant refactoring to keep all default apps in the package
// manager (cleaner but more work) or have the services provide
@@ -21422,7 +19962,7 @@
PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
removed.clear();
for (PreferredActivity pa : pir.filterSet()) {
- if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
+ if (!mComponentResolver.isActivityDefined(pa.mPref.mComponent)) {
removed.add(pa);
}
}
@@ -21565,6 +20105,7 @@
this, in, out, err, args, callback, resultReceiver);
}
+ @SuppressWarnings("resource")
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
@@ -21895,32 +20436,16 @@
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
- if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
- : "Activity Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
- dumpState.setTitlePrinted(true);
- }
+ mComponentResolver.dumpActivityResolvers(pw, dumpState, packageName);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
- if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
- : "Receiver Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
- dumpState.setTitlePrinted(true);
- }
+ mComponentResolver.dumpReceiverResolvers(pw, dumpState, packageName);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
- if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
- : "Service Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
- dumpState.setTitlePrinted(true);
- }
+ mComponentResolver.dumpServiceResolvers(pw, dumpState, packageName);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
- if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
- : "Provider Resolver Table:", " ", packageName,
- dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
- dumpState.setTitlePrinted(true);
- }
+ mComponentResolver.dumpProviderResolvers(pw, dumpState, packageName);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
@@ -22022,40 +20547,7 @@
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
- boolean printedSomething = false;
- for (PackageParser.Provider p : mProviders.mProviders.values()) {
- if (packageName != null && !packageName.equals(p.info.packageName)) {
- continue;
- }
- if (!printedSomething) {
- if (dumpState.onTitlePrinted())
- pw.println();
- pw.println("Registered ContentProviders:");
- printedSomething = true;
- }
- pw.print(" "); p.printComponentShortName(pw); pw.println(":");
- pw.print(" "); pw.println(p.toString());
- }
- printedSomething = false;
- for (Map.Entry<String, PackageParser.Provider> entry :
- mProvidersByAuthority.entrySet()) {
- PackageParser.Provider p = entry.getValue();
- if (packageName != null && !packageName.equals(p.info.packageName)) {
- continue;
- }
- if (!printedSomething) {
- if (dumpState.onTitlePrinted())
- pw.println();
- pw.println("ContentProvider Authorities:");
- printedSomething = true;
- }
- pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
- pw.print(" "); pw.println(p.toString());
- if (p.info != null && p.info.applicationInfo != null) {
- final String appInfo = p.info.applicationInfo.toString();
- pw.print(" applicationInfo="); pw.println(appInfo);
- }
- }
+ mComponentResolver.dumpContentProviders(pw, dumpState, packageName);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
@@ -22137,21 +20629,7 @@
if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
&& packageName == null) {
- if (dumpState.onTitlePrinted()) pw.println();
- pw.println("Service permissions:");
-
- final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
- while (filterIterator.hasNext()) {
- final ServiceIntentInfo info = filterIterator.next();
- final ServiceInfo serviceInfo = info.service.info;
- final String permission = serviceInfo.permission;
- if (permission != null) {
- pw.print(" ");
- pw.print(serviceInfo.getComponentName().flattenToShortString());
- pw.print(": ");
- pw.println(permission);
- }
- }
+ mComponentResolver.dumpServicePermissions(pw, dumpState, packageName);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
@@ -22282,6 +20760,7 @@
}
@GuardedBy("mPackages")
+ @SuppressWarnings("resource")
private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.println();
@@ -22310,6 +20789,7 @@
}
@GuardedBy("mPackages")
+ @SuppressWarnings("resource")
private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.println();
@@ -24337,6 +22817,20 @@
}
@Override
+ public boolean isEnabledAndMatches(ComponentInfo info, int flags, int userId) {
+ synchronized (mPackages) {
+ return mSettings.isEnabledAndMatchLPr(info, flags, userId);
+ }
+ }
+
+ @Override
+ public boolean userNeedsBadging(int userId) {
+ synchronized (mPackages) {
+ return PackageManagerService.this.userNeedsBadging(userId);
+ }
+ }
+
+ @Override
public void grantRuntimePermission(String packageName, String permName, int userId,
boolean overridePolicy) {
PackageManagerService.this.mPermissionManager.grantRuntimePermission(
@@ -24535,7 +23029,7 @@
public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
- return !PackageManagerService.this.filterAppAccessLPr(
+ return ps != null && !PackageManagerService.this.filterAppAccessLPr(
ps, callingUid, component, TYPE_UNKNOWN, userId);
}
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index ed56a32..8dd1a0f 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -44,6 +44,7 @@
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.PackageCleanItem;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
import android.content.pm.PackageUserState;
import android.content.pm.PermissionInfo;
@@ -88,6 +89,7 @@
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.XmlUtils;
+import com.android.server.LocalServices;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.permission.BasePermission;
import com.android.server.pm.permission.PermissionSettings;
@@ -422,11 +424,8 @@
/** Settings and other information about permissions */
final PermissionSettings mPermissions;
- Settings(PermissionSettings permissions, Object lock) {
- this(Environment.getDataDirectory(), permissions, lock);
- }
-
- Settings(File dataDir, PermissionSettings permission, Object lock) {
+ Settings(File dataDir, PermissionSettings permission,
+ Object lock) {
mLock = lock;
mPermissions = permission;
mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
@@ -3235,8 +3234,10 @@
return true;
}
- void applyDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
+ void applyDefaultPreferredAppsLPw(int userId) {
// First pull data from any pre-installed apps.
+ final PackageManagerInternal pmInternal =
+ LocalServices.getService(PackageManagerInternal.class);
for (PackageSetting ps : mPackages.values()) {
if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
&& ps.pkg.preferredActivityFilters != null) {
@@ -3244,8 +3245,8 @@
= ps.pkg.preferredActivityFilters;
for (int i=0; i<intents.size(); i++) {
PackageParser.ActivityIntentInfo aii = intents.get(i);
- applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
- ps.name, aii.activity.className), userId);
+ applyDefaultPreferredActivityLPw(pmInternal, aii, new ComponentName(
+ ps.name, aii.activity.className), userId);
}
}
}
@@ -3293,7 +3294,7 @@
+ " does not start with 'preferred-activities'");
continue;
}
- readDefaultPreferredActivitiesLPw(service, parser, userId);
+ readDefaultPreferredActivitiesLPw(parser, userId);
} catch (XmlPullParserException e) {
Slog.w(TAG, "Error reading apps file " + f, e);
} catch (IOException e) {
@@ -3309,8 +3310,8 @@
}
}
- private void applyDefaultPreferredActivityLPw(PackageManagerService service,
- IntentFilter tmpPa, ComponentName cn, int userId) {
+ private void applyDefaultPreferredActivityLPw(
+ PackageManagerInternal pmInternal, IntentFilter tmpPa, ComponentName cn, int userId) {
// The initial preferences only specify the target activity
// component and intent-filter, not the set of matches. So we
// now need to query for the matches to build the correct
@@ -3335,27 +3336,31 @@
boolean doNonData = true;
boolean hasSchemes = false;
- for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
+ final int dataSchemesCount = tmpPa.countDataSchemes();
+ for (int ischeme = 0; ischeme < dataSchemesCount; ischeme++) {
boolean doScheme = true;
- String scheme = tmpPa.getDataScheme(ischeme);
+ final String scheme = tmpPa.getDataScheme(ischeme);
if (scheme != null && !scheme.isEmpty()) {
hasSchemes = true;
}
- for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
+ final int dataSchemeSpecificPartsCount = tmpPa.countDataSchemeSpecificParts();
+ for (int issp = 0; issp < dataSchemeSpecificPartsCount; issp++) {
Uri.Builder builder = new Uri.Builder();
builder.scheme(scheme);
PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
builder.opaquePart(ssp.getPath());
Intent finalIntent = new Intent(intent);
finalIntent.setData(builder.build());
- applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+ applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
scheme, ssp, null, null, userId);
doScheme = false;
}
- for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
+ final int dataAuthoritiesCount = tmpPa.countDataAuthorities();
+ for (int iauth = 0; iauth < dataAuthoritiesCount; iauth++) {
boolean doAuth = true;
- IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
- for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
+ final IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
+ final int dataPathsCount = tmpPa.countDataPaths();
+ for (int ipath = 0; ipath < dataPathsCount; ipath++) {
Uri.Builder builder = new Uri.Builder();
builder.scheme(scheme);
if (auth.getHost() != null) {
@@ -3365,7 +3370,7 @@
builder.path(path.getPath());
Intent finalIntent = new Intent(intent);
finalIntent.setData(builder.build());
- applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+ applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
scheme, null, auth, path, userId);
doAuth = doScheme = false;
}
@@ -3377,7 +3382,7 @@
}
Intent finalIntent = new Intent(intent);
finalIntent.setData(builder.build());
- applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+ applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
scheme, null, auth, null, userId);
doScheme = false;
}
@@ -3387,7 +3392,7 @@
builder.scheme(scheme);
Intent finalIntent = new Intent(intent);
finalIntent.setData(builder.build());
- applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+ applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
scheme, null, null, null, userId);
}
doNonData = false;
@@ -3403,129 +3408,134 @@
Intent finalIntent = new Intent(intent);
builder.scheme(scheme);
finalIntent.setDataAndType(builder.build(), mimeType);
- applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+ applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
scheme, null, null, null, userId);
}
}
} else {
Intent finalIntent = new Intent(intent);
finalIntent.setType(mimeType);
- applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+ applyDefaultPreferredActivityLPw(pmInternal, finalIntent, flags, cn,
null, null, null, null, userId);
}
doNonData = false;
}
if (doNonData) {
- applyDefaultPreferredActivityLPw(service, intent, flags, cn,
+ applyDefaultPreferredActivityLPw(pmInternal, intent, flags, cn,
null, null, null, null, userId);
}
}
- private void applyDefaultPreferredActivityLPw(PackageManagerService service,
- Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
+ private void applyDefaultPreferredActivityLPw(PackageManagerInternal pmInternal, Intent intent,
+ int flags, ComponentName cn, String scheme, PatternMatcher ssp,
IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
- flags = service.updateFlagsForResolve(flags, userId, intent, Binder.getCallingUid(), false);
- List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
- intent.getType(), flags, 0);
- if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
- + " results: " + ri);
+ final List<ResolveInfo> ri =
+ pmInternal.queryIntentActivities(intent, flags, Binder.getCallingUid(), 0);
+ if (PackageManagerService.DEBUG_PREFERRED) {
+ Log.d(TAG, "Queried " + intent + " results: " + ri);
+ }
int systemMatch = 0;
int thirdPartyMatch = 0;
- if (ri != null && ri.size() > 1) {
- boolean haveAct = false;
- ComponentName haveNonSys = null;
- ComponentName[] set = new ComponentName[ri.size()];
- for (int i=0; i<ri.size(); i++) {
- ActivityInfo ai = ri.get(i).activityInfo;
- set[i] = new ComponentName(ai.packageName, ai.name);
- if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
- if (ri.get(i).match >= thirdPartyMatch) {
- // Keep track of the best match we find of all third
- // party apps, for use later to determine if we actually
- // want to set a preferred app for this intent.
- if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
- + ai.packageName + "/" + ai.name + ": non-system!");
- haveNonSys = set[i];
- break;
+ final int numMatches = (ri == null ? 0 : ri.size());
+ if (numMatches <= 1) {
+ Slog.w(TAG, "No potential matches found for " + intent
+ + " while setting preferred " + cn.flattenToShortString());
+ return;
+ }
+ boolean haveAct = false;
+ ComponentName haveNonSys = null;
+ ComponentName[] set = new ComponentName[ri.size()];
+ for (int i = 0; i < numMatches; i++) {
+ final ActivityInfo ai = ri.get(i).activityInfo;
+ set[i] = new ComponentName(ai.packageName, ai.name);
+ if ((ai.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ if (ri.get(i).match >= thirdPartyMatch) {
+ // Keep track of the best match we find of all third
+ // party apps, for use later to determine if we actually
+ // want to set a preferred app for this intent.
+ if (PackageManagerService.DEBUG_PREFERRED) {
+ Log.d(TAG, "Result " + ai.packageName + "/" + ai.name + ": non-system!");
}
- } else if (cn.getPackageName().equals(ai.packageName)
- && cn.getClassName().equals(ai.name)) {
- if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
- + ai.packageName + "/" + ai.name + ": default!");
- haveAct = true;
- systemMatch = ri.get(i).match;
- } else {
- if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
- + ai.packageName + "/" + ai.name + ": skipped");
+ haveNonSys = set[i];
+ break;
}
- }
- if (haveNonSys != null && thirdPartyMatch < systemMatch) {
- // If we have a matching third party app, but its match is not as
- // good as the built-in system app, then we don't want to actually
- // consider it a match because presumably the built-in app is still
- // the thing we want users to see by default.
- haveNonSys = null;
- }
- if (haveAct && haveNonSys == null) {
- IntentFilter filter = new IntentFilter();
- if (intent.getAction() != null) {
- filter.addAction(intent.getAction());
+ } else if (cn.getPackageName().equals(ai.packageName)
+ && cn.getClassName().equals(ai.name)) {
+ if (PackageManagerService.DEBUG_PREFERRED) {
+ Log.d(TAG, "Result " + ai.packageName + "/" + ai.name + ": default!");
}
- if (intent.getCategories() != null) {
- for (String cat : intent.getCategories()) {
- filter.addCategory(cat);
- }
- }
- if ((flags & MATCH_DEFAULT_ONLY) != 0) {
- filter.addCategory(Intent.CATEGORY_DEFAULT);
- }
- if (scheme != null) {
- filter.addDataScheme(scheme);
- }
- if (ssp != null) {
- filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
- }
- if (auth != null) {
- filter.addDataAuthority(auth);
- }
- if (path != null) {
- filter.addDataPath(path);
- }
- if (intent.getType() != null) {
- try {
- filter.addDataType(intent.getType());
- } catch (IntentFilter.MalformedMimeTypeException ex) {
- Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
- }
- }
- PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
- editPreferredActivitiesLPw(userId).addFilter(pa);
- } else if (haveNonSys == null) {
- StringBuilder sb = new StringBuilder();
- sb.append("No component ");
- sb.append(cn.flattenToShortString());
- sb.append(" found setting preferred ");
- sb.append(intent);
- sb.append("; possible matches are ");
- for (int i=0; i<set.length; i++) {
- if (i > 0) sb.append(", ");
- sb.append(set[i].flattenToShortString());
- }
- Slog.w(TAG, sb.toString());
+ haveAct = true;
+ systemMatch = ri.get(i).match;
} else {
- Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
- + haveNonSys.flattenToShortString());
+ if (PackageManagerService.DEBUG_PREFERRED) {
+ Log.d(TAG, "Result " + ai.packageName + "/" + ai.name + ": skipped");
+ }
}
+ }
+ if (haveNonSys != null && thirdPartyMatch < systemMatch) {
+ // If we have a matching third party app, but its match is not as
+ // good as the built-in system app, then we don't want to actually
+ // consider it a match because presumably the built-in app is still
+ // the thing we want users to see by default.
+ haveNonSys = null;
+ }
+ if (haveAct && haveNonSys == null) {
+ IntentFilter filter = new IntentFilter();
+ if (intent.getAction() != null) {
+ filter.addAction(intent.getAction());
+ }
+ if (intent.getCategories() != null) {
+ for (String cat : intent.getCategories()) {
+ filter.addCategory(cat);
+ }
+ }
+ if ((flags & MATCH_DEFAULT_ONLY) != 0) {
+ filter.addCategory(Intent.CATEGORY_DEFAULT);
+ }
+ if (scheme != null) {
+ filter.addDataScheme(scheme);
+ }
+ if (ssp != null) {
+ filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
+ }
+ if (auth != null) {
+ filter.addDataAuthority(auth);
+ }
+ if (path != null) {
+ filter.addDataPath(path);
+ }
+ if (intent.getType() != null) {
+ try {
+ filter.addDataType(intent.getType());
+ } catch (IntentFilter.MalformedMimeTypeException ex) {
+ Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
+ }
+ }
+ PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
+ editPreferredActivitiesLPw(userId).addFilter(pa);
+ } else if (haveNonSys == null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("No component ");
+ sb.append(cn.flattenToShortString());
+ sb.append(" found setting preferred ");
+ sb.append(intent);
+ sb.append("; possible matches are ");
+ for (int i = 0; i < set.length; i++) {
+ if (i > 0) sb.append(", ");
+ sb.append(set[i].flattenToShortString());
+ }
+ Slog.w(TAG, sb.toString());
} else {
- Slog.w(TAG, "No potential matches found for " + intent + " while setting preferred "
- + cn.flattenToShortString());
+ Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
+ + haveNonSys.flattenToShortString());
}
}
- private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
- XmlPullParser parser, int userId)
+ private void readDefaultPreferredActivitiesLPw(XmlPullParser parser, int userId)
throws XmlPullParserException, IOException {
+ final PackageManagerInternal pmInternal =
+ LocalServices.getService(PackageManagerInternal.class);
int outerDepth = parser.getDepth();
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -3538,8 +3548,8 @@
if (tagName.equals(TAG_ITEM)) {
PreferredActivity tmpPa = new PreferredActivity(parser);
if (tmpPa.mPref.getParseError() == null) {
- applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
- userId);
+ applyDefaultPreferredActivityLPw(
+ pmInternal, tmpPa, tmpPa.mPref.mComponent, userId);
} else {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Error in package manager settings: <preferred-activity> "
@@ -4154,7 +4164,7 @@
}
}
synchronized (mPackages) {
- applyDefaultPreferredAppsLPw(service, userHandle);
+ applyDefaultPreferredAppsLPw(userHandle);
}
}