• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.pm;
18 
19 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
20 import static android.content.pm.PackageManagerInternal.PACKAGE_SETUP_WIZARD;
21 
22 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
23 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
24 import static com.android.server.pm.PackageManagerService.fixProcessName;
25 
26 import android.content.ComponentName;
27 import android.content.Intent;
28 import android.content.IntentFilter;
29 import android.content.pm.ActivityInfo;
30 import android.content.pm.ApplicationInfo;
31 import android.content.pm.AuxiliaryResolveInfo;
32 import android.content.pm.InstantAppResolveInfo;
33 import android.content.pm.PackageManager;
34 import android.content.pm.PackageManagerInternal;
35 import android.content.pm.PackageParser;
36 import android.content.pm.PackageParser.ActivityIntentInfo;
37 import android.content.pm.PackageParser.ServiceIntentInfo;
38 import android.content.pm.PackageUserState;
39 import android.content.pm.ProviderInfo;
40 import android.content.pm.ResolveInfo;
41 import android.content.pm.ServiceInfo;
42 import android.os.UserHandle;
43 import android.util.ArrayMap;
44 import android.util.ArraySet;
45 import android.util.DebugUtils;
46 import android.util.Log;
47 import android.util.LogPrinter;
48 import android.util.Pair;
49 import android.util.Slog;
50 
51 import com.android.internal.annotations.GuardedBy;
52 import com.android.server.IntentResolver;
53 
54 import java.io.PrintWriter;
55 import java.util.ArrayList;
56 import java.util.Comparator;
57 import java.util.Iterator;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.Set;
61 
62 /** Resolves all Android component types [activities, services, providers and receivers]. */
63 public class ComponentResolver {
64     private static final boolean DEBUG = false;
65     private static final String TAG = "PackageManager";
66     private static final boolean DEBUG_FILTERS = false;
67     private static final boolean DEBUG_SHOW_INFO = false;
68 
69     /**
70      * The set of all protected actions [i.e. those actions for which a high priority
71      * intent filter is disallowed].
72      */
73     private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
74     static {
75         PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
76         PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
77         PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
78         PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
79     }
80 
81     static final Comparator<ResolveInfo> RESOLVE_PRIORITY_SORTER = (r1, r2) -> {
82         int v1 = r1.priority;
83         int v2 = r2.priority;
84         //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
85         if (v1 != v2) {
86             return (v1 > v2) ? -1 : 1;
87         }
88         v1 = r1.preferredOrder;
89         v2 = r2.preferredOrder;
90         if (v1 != v2) {
91             return (v1 > v2) ? -1 : 1;
92         }
93         if (r1.isDefault != r2.isDefault) {
94             return r1.isDefault ? -1 : 1;
95         }
96         v1 = r1.match;
97         v2 = r2.match;
98         //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
99         if (v1 != v2) {
100             return (v1 > v2) ? -1 : 1;
101         }
102         if (r1.system != r2.system) {
103             return r1.system ? -1 : 1;
104         }
105         if (r1.activityInfo != null) {
106             return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
107         }
108         if (r1.serviceInfo != null) {
109             return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
110         }
111         if (r1.providerInfo != null) {
112             return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
113         }
114         return 0;
115     };
116 
117     private static UserManagerService sUserManager;
118     private static PackageManagerInternal sPackageManagerInternal;
119 
120     /**
121      * Locking within package manager is going to get worse before it gets better. Currently,
122      * we need to share the {@link PackageManagerService} lock to prevent deadlocks. This occurs
123      * because in order to safely query the resolvers, we need to obtain this lock. However,
124      * during resolution, we call into the {@link PackageManagerService}. This is _not_ to
125      * operate on data controlled by the service proper, but, to check the state of package
126      * settings [contained in a {@link Settings} object]. However, the {@link Settings} object
127      * happens to be protected by the main {@link PackageManagerService} lock.
128      * <p>
129      * There are a couple potential solutions.
130      * <ol>
131      * <li>Split all of our locks into reader/writer locks. This would allow multiple,
132      * simultaneous read operations and means we don't have to be as cautious about lock
133      * layering. Only when we want to perform a write operation will we ever be in a
134      * position to deadlock the system.</li>
135      * <li>Use the same lock across all classes within the {@code com.android.server.pm}
136      * package. By unifying the lock object, we remove any potential lock layering issues
137      * within the package manager. However, we already have a sense that this lock is
138      * heavily contended and merely adding more dependencies on it will have further
139      * impact.</li>
140      * <li>Implement proper lock ordering within the package manager. By defining the
141      * relative layer of the component [eg. {@link PackageManagerService} is at the top.
142      * Somewhere in the middle would be {@link ComponentResolver}. At the very bottom
143      * would be {@link Settings}.] The ordering would allow higher layers to hold their
144      * lock while calling down. Lower layers must relinquish their lock before calling up.
145      * Since {@link Settings} would live at the lowest layer, the {@link ComponentResolver}
146      * would be able to hold its lock while checking the package setting state.</li>
147      * </ol>
148      */
149     private final Object mLock;
150 
151     /** All available activities, for your resolving pleasure. */
152     @GuardedBy("mLock")
153     private final ActivityIntentResolver mActivities = new ActivityIntentResolver();
154 
155     /** All available providers, for your resolving pleasure. */
156     @GuardedBy("mLock")
157     private final ProviderIntentResolver mProviders = new ProviderIntentResolver();
158 
159     /** All available receivers, for your resolving pleasure. */
160     @GuardedBy("mLock")
161     private final ActivityIntentResolver mReceivers = new ActivityIntentResolver();
162 
163     /** All available services, for your resolving pleasure. */
164     @GuardedBy("mLock")
165     private final ServiceIntentResolver mServices = new ServiceIntentResolver();
166 
167     /** Mapping from provider authority [first directory in content URI codePath) to provider. */
168     @GuardedBy("mLock")
169     private final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = new ArrayMap<>();
170 
171     /** Whether or not processing protected filters should be deferred. */
172     private boolean mDeferProtectedFilters = true;
173 
174     /**
175      * Tracks high priority intent filters for protected actions. During boot, certain
176      * filter actions are protected and should never be allowed to have a high priority
177      * intent filter for them. However, there is one, and only one exception -- the
178      * setup wizard. It must be able to define a high priority intent filter for these
179      * actions to ensure there are no escapes from the wizard. We need to delay processing
180      * of these during boot as we need to inspect at all of the intent filters on the
181      * /system partition in order to know which component is the setup wizard. This can
182      * only ever be non-empty if {@link #mDeferProtectedFilters} is {@code true}.
183      */
184     private List<PackageParser.ActivityIntentInfo> mProtectedFilters;
185 
ComponentResolver(UserManagerService userManager, PackageManagerInternal packageManagerInternal, Object lock)186     ComponentResolver(UserManagerService userManager,
187             PackageManagerInternal packageManagerInternal,
188             Object lock) {
189         sPackageManagerInternal = packageManagerInternal;
190         sUserManager = userManager;
191         mLock = lock;
192     }
193 
194     /** Returns the given activity */
getActivity(ComponentName component)195     PackageParser.Activity getActivity(ComponentName component) {
196         synchronized (mLock) {
197             return mActivities.mActivities.get(component);
198         }
199     }
200 
201     /** Returns the given provider */
getProvider(ComponentName component)202     PackageParser.Provider getProvider(ComponentName component) {
203         synchronized (mLock) {
204             return mProviders.mProviders.get(component);
205         }
206     }
207 
208     /** Returns the given receiver */
getReceiver(ComponentName component)209     PackageParser.Activity getReceiver(ComponentName component) {
210         synchronized (mLock) {
211             return mReceivers.mActivities.get(component);
212         }
213     }
214 
215     /** Returns the given service */
getService(ComponentName component)216     PackageParser.Service getService(ComponentName component) {
217         synchronized (mLock) {
218             return mServices.mServices.get(component);
219         }
220     }
221 
queryActivities(Intent intent, String resolvedType, int flags, int userId)222     List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags, int userId) {
223         synchronized (mLock) {
224             return mActivities.queryIntent(intent, resolvedType, flags, userId);
225         }
226     }
227 
queryActivities(Intent intent, String resolvedType, int flags, List<PackageParser.Activity> activities, int userId)228     List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags,
229             List<PackageParser.Activity> activities, int userId) {
230         synchronized (mLock) {
231             return mActivities.queryIntentForPackage(
232                     intent, resolvedType, flags, activities, userId);
233         }
234     }
235 
queryProviders(Intent intent, String resolvedType, int flags, int userId)236     List<ResolveInfo> queryProviders(Intent intent, String resolvedType, int flags, int userId) {
237         synchronized (mLock) {
238             return mProviders.queryIntent(intent, resolvedType, flags, userId);
239         }
240     }
241 
queryProviders(Intent intent, String resolvedType, int flags, List<PackageParser.Provider> providers, int userId)242     List<ResolveInfo> queryProviders(Intent intent, String resolvedType, int flags,
243             List<PackageParser.Provider> providers, int userId) {
244         synchronized (mLock) {
245             return mProviders.queryIntentForPackage(intent, resolvedType, flags, providers, userId);
246         }
247     }
248 
queryProviders(String processName, String metaDataKey, int uid, int flags, int userId)249     List<ProviderInfo> queryProviders(String processName, String metaDataKey, int uid, int flags,
250             int userId) {
251         if (!sUserManager.exists(userId)) {
252             return null;
253         }
254         List<ProviderInfo> providerList = null;
255         synchronized (mLock) {
256             for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) {
257                 final PackageParser.Provider p = mProviders.mProviders.valueAt(i);
258                 final PackageSetting ps = (PackageSetting) p.owner.mExtras;
259                 if (ps == null) {
260                     continue;
261                 }
262                 if (p.info.authority == null) {
263                     continue;
264                 }
265                 if (processName != null && (!p.info.processName.equals(processName)
266                         || !UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) {
267                     continue;
268                 }
269                 // See PM.queryContentProviders()'s javadoc for why we have the metaData parameter.
270                 if (metaDataKey != null
271                         && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
272                     continue;
273                 }
274                 final ProviderInfo info = PackageParser.generateProviderInfo(
275                         p, flags, ps.readUserState(userId), userId);
276                 if (info == null) {
277                     continue;
278                 }
279                 if (providerList == null) {
280                     providerList = new ArrayList<>(i + 1);
281                 }
282                 providerList.add(info);
283             }
284         }
285         return providerList;
286     }
287 
queryProvider(String authority, int flags, int userId)288     ProviderInfo queryProvider(String authority, int flags, int userId) {
289         synchronized (mLock) {
290             final PackageParser.Provider p = mProvidersByAuthority.get(authority);
291             if (p == null) {
292                 return null;
293             }
294             final PackageSetting ps = (PackageSetting) p.owner.mExtras;
295             if (ps == null) {
296                 return null;
297             }
298             return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), userId);
299         }
300     }
301 
querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo, boolean safeMode, int userId)302     void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo, boolean safeMode,
303             int userId) {
304         synchronized (mLock) {
305             for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) {
306                 final PackageParser.Provider p = mProvidersByAuthority.valueAt(i);
307                 final PackageSetting ps = (PackageSetting) p.owner.mExtras;
308                 if (ps == null) {
309                     continue;
310                 }
311                 if (!p.syncable) {
312                     continue;
313                 }
314                 if (safeMode
315                         && (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
316                     continue;
317                 }
318                 final ProviderInfo info =
319                         PackageParser.generateProviderInfo(p, 0, ps.readUserState(userId), userId);
320                 if (info == null) {
321                     continue;
322                 }
323                 outNames.add(mProvidersByAuthority.keyAt(i));
324                 outInfo.add(info);
325             }
326         }
327     }
328 
queryReceivers(Intent intent, String resolvedType, int flags, int userId)329     List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags, int userId) {
330         synchronized (mLock) {
331             return mReceivers.queryIntent(intent, resolvedType, flags, userId);
332         }
333     }
334 
queryReceivers(Intent intent, String resolvedType, int flags, List<PackageParser.Activity> receivers, int userId)335     List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags,
336             List<PackageParser.Activity> receivers, int userId) {
337         synchronized (mLock) {
338             return mReceivers.queryIntentForPackage(intent, resolvedType, flags, receivers, userId);
339         }
340     }
341 
queryServices(Intent intent, String resolvedType, int flags, int userId)342     List<ResolveInfo> queryServices(Intent intent, String resolvedType, int flags, int userId) {
343         synchronized (mLock) {
344             return mServices.queryIntent(intent, resolvedType, flags, userId);
345         }
346     }
347 
queryServices(Intent intent, String resolvedType, int flags, List<PackageParser.Service> services, int userId)348     List<ResolveInfo> queryServices(Intent intent, String resolvedType, int flags,
349             List<PackageParser.Service> services, int userId) {
350         synchronized (mLock) {
351             return mServices.queryIntentForPackage(intent, resolvedType, flags, services, userId);
352         }
353     }
354 
355     /** Returns {@code true} if the given activity is defined by some package */
isActivityDefined(ComponentName component)356     boolean isActivityDefined(ComponentName component) {
357         synchronized (mLock) {
358             return mActivities.mActivities.get(component) != null;
359         }
360     }
361 
362     /** Asserts none of the providers defined in the given package haven't already been defined. */
assertProvidersNotDefined(PackageParser.Package pkg)363     void assertProvidersNotDefined(PackageParser.Package pkg) throws PackageManagerException {
364         synchronized (mLock) {
365             assertProvidersNotDefinedLocked(pkg);
366         }
367     }
368 
369     /** Add all components defined in the given package to the internal structures. */
addAllComponents(PackageParser.Package pkg, boolean chatty)370     void addAllComponents(PackageParser.Package pkg, boolean chatty) {
371         final ArrayList<PackageParser.ActivityIntentInfo> newIntents = new ArrayList<>();
372         synchronized (mLock) {
373             addActivitiesLocked(pkg, newIntents, chatty);
374             addReceiversLocked(pkg, chatty);
375             addProvidersLocked(pkg, chatty);
376             addServicesLocked(pkg, chatty);
377         }
378         final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName(
379                 PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM);
380         for (int i = newIntents.size() - 1; i >= 0; --i) {
381             final PackageParser.ActivityIntentInfo intentInfo = newIntents.get(i);
382             final PackageParser.Package disabledPkg = sPackageManagerInternal
383                     .getDisabledSystemPackage(intentInfo.activity.info.packageName);
384             final List<PackageParser.Activity> systemActivities =
385                     disabledPkg != null ? disabledPkg.activities : null;
386             adjustPriority(systemActivities, intentInfo, setupWizardPackage);
387         }
388     }
389 
390     /** Removes all components defined in the given package from the internal structures. */
removeAllComponents(PackageParser.Package pkg, boolean chatty)391     void removeAllComponents(PackageParser.Package pkg, boolean chatty) {
392         synchronized (mLock) {
393             removeAllComponentsLocked(pkg, chatty);
394         }
395     }
396 
397     /**
398      * Reprocess any protected filters that have been deferred. At this point, we've scanned
399      * all of the filters defined on the /system partition and know the special components.
400      */
fixProtectedFilterPriorities()401     void fixProtectedFilterPriorities() {
402         if (!mDeferProtectedFilters) {
403             return;
404         }
405         mDeferProtectedFilters = false;
406 
407         if (mProtectedFilters == null || mProtectedFilters.size() == 0) {
408             return;
409         }
410         final List<ActivityIntentInfo> protectedFilters = mProtectedFilters;
411         mProtectedFilters = null;
412 
413         final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName(
414                 PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM);
415         if (DEBUG_FILTERS && setupWizardPackage == null) {
416             Slog.i(TAG, "No setup wizard;"
417                     + " All protected intents capped to priority 0");
418         }
419         for (int i = protectedFilters.size() - 1; i >= 0; --i) {
420             final ActivityIntentInfo filter = protectedFilters.get(i);
421             if (filter.activity.info.packageName.equals(setupWizardPackage)) {
422                 if (DEBUG_FILTERS) {
423                     Slog.i(TAG, "Found setup wizard;"
424                             + " allow priority " + filter.getPriority() + ";"
425                             + " package: " + filter.activity.info.packageName
426                             + " activity: " + filter.activity.className
427                             + " priority: " + filter.getPriority());
428                 }
429                 // skip setup wizard; allow it to keep the high priority filter
430                 continue;
431             }
432             if (DEBUG_FILTERS) {
433                 Slog.i(TAG, "Protected action; cap priority to 0;"
434                         + " package: " + filter.activity.info.packageName
435                         + " activity: " + filter.activity.className
436                         + " origPrio: " + filter.getPriority());
437             }
438             filter.setPriority(0);
439         }
440     }
441 
dumpActivityResolvers(PrintWriter pw, DumpState dumpState, String packageName)442     void dumpActivityResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
443         if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
444                 : "Activity Resolver Table:", "  ", packageName,
445                 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
446             dumpState.setTitlePrinted(true);
447         }
448     }
449 
dumpProviderResolvers(PrintWriter pw, DumpState dumpState, String packageName)450     void dumpProviderResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
451         if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
452                 : "Provider Resolver Table:", "  ", packageName,
453                 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
454             dumpState.setTitlePrinted(true);
455         }
456     }
457 
dumpReceiverResolvers(PrintWriter pw, DumpState dumpState, String packageName)458     void dumpReceiverResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
459         if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
460                 : "Receiver Resolver Table:", "  ", packageName,
461                 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
462             dumpState.setTitlePrinted(true);
463         }
464     }
465 
dumpServiceResolvers(PrintWriter pw, DumpState dumpState, String packageName)466     void dumpServiceResolvers(PrintWriter pw, DumpState dumpState, String packageName) {
467         if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
468                 : "Service Resolver Table:", "  ", packageName,
469                 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
470             dumpState.setTitlePrinted(true);
471         }
472     }
473 
dumpContentProviders(PrintWriter pw, DumpState dumpState, String packageName)474     void dumpContentProviders(PrintWriter pw, DumpState dumpState, String packageName) {
475         boolean printedSomething = false;
476         for (PackageParser.Provider p : mProviders.mProviders.values()) {
477             if (packageName != null && !packageName.equals(p.info.packageName)) {
478                 continue;
479             }
480             if (!printedSomething) {
481                 if (dumpState.onTitlePrinted()) {
482                     pw.println();
483                 }
484                 pw.println("Registered ContentProviders:");
485                 printedSomething = true;
486             }
487             pw.print("  "); p.printComponentShortName(pw); pw.println(":");
488             pw.print("    "); pw.println(p.toString());
489         }
490         printedSomething = false;
491         for (Map.Entry<String, PackageParser.Provider> entry :
492                 mProvidersByAuthority.entrySet()) {
493             PackageParser.Provider p = entry.getValue();
494             if (packageName != null && !packageName.equals(p.info.packageName)) {
495                 continue;
496             }
497             if (!printedSomething) {
498                 if (dumpState.onTitlePrinted()) {
499                     pw.println();
500                 }
501                 pw.println("ContentProvider Authorities:");
502                 printedSomething = true;
503             }
504             pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
505             pw.print("    "); pw.println(p.toString());
506             if (p.info != null && p.info.applicationInfo != null) {
507                 final String appInfo = p.info.applicationInfo.toString();
508                 pw.print("      applicationInfo="); pw.println(appInfo);
509             }
510         }
511     }
512 
dumpServicePermissions(PrintWriter pw, DumpState dumpState, String packageName)513     void dumpServicePermissions(PrintWriter pw, DumpState dumpState, String packageName) {
514         if (dumpState.onTitlePrinted()) pw.println();
515         pw.println("Service permissions:");
516 
517         final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
518         while (filterIterator.hasNext()) {
519             final ServiceIntentInfo info = filterIterator.next();
520             final ServiceInfo serviceInfo = info.service.info;
521             final String permission = serviceInfo.permission;
522             if (permission != null) {
523                 pw.print("    ");
524                 pw.print(serviceInfo.getComponentName().flattenToShortString());
525                 pw.print(": ");
526                 pw.println(permission);
527             }
528         }
529     }
530 
531     @GuardedBy("mLock")
addActivitiesLocked(PackageParser.Package pkg, List<PackageParser.ActivityIntentInfo> newIntents, boolean chatty)532     private void addActivitiesLocked(PackageParser.Package pkg,
533             List<PackageParser.ActivityIntentInfo> newIntents, boolean chatty) {
534         final int activitiesSize = pkg.activities.size();
535         StringBuilder r = null;
536         for (int i = 0; i < activitiesSize; i++) {
537             PackageParser.Activity a = pkg.activities.get(i);
538             a.info.processName =
539                     fixProcessName(pkg.applicationInfo.processName, a.info.processName);
540             mActivities.addActivity(a, "activity", newIntents);
541             if (DEBUG_PACKAGE_SCANNING && chatty) {
542                 if (r == null) {
543                     r = new StringBuilder(256);
544                 } else {
545                     r.append(' ');
546                 }
547                 r.append(a.info.name);
548             }
549         }
550         if (DEBUG_PACKAGE_SCANNING && chatty) {
551             Log.d(TAG, "  Activities: " + (r == null ? "<NONE>" : r));
552         }
553     }
554 
555     @GuardedBy("mLock")
addProvidersLocked(PackageParser.Package pkg, boolean chatty)556     private void addProvidersLocked(PackageParser.Package pkg, boolean chatty) {
557         final int providersSize = pkg.providers.size();
558         StringBuilder r = null;
559         for (int i = 0; i < providersSize; i++) {
560             PackageParser.Provider p = pkg.providers.get(i);
561             p.info.processName = fixProcessName(pkg.applicationInfo.processName,
562                     p.info.processName);
563             mProviders.addProvider(p);
564             p.syncable = p.info.isSyncable;
565             if (p.info.authority != null) {
566                 String[] names = p.info.authority.split(";");
567                 p.info.authority = null;
568                 for (int j = 0; j < names.length; j++) {
569                     if (j == 1 && p.syncable) {
570                         // We only want the first authority for a provider to possibly be
571                         // syncable, so if we already added this provider using a different
572                         // authority clear the syncable flag. We copy the provider before
573                         // changing it because the mProviders object contains a reference
574                         // to a provider that we don't want to change.
575                         // Only do this for the second authority since the resulting provider
576                         // object can be the same for all future authorities for this provider.
577                         p = new PackageParser.Provider(p);
578                         p.syncable = false;
579                     }
580                     if (!mProvidersByAuthority.containsKey(names[j])) {
581                         mProvidersByAuthority.put(names[j], p);
582                         if (p.info.authority == null) {
583                             p.info.authority = names[j];
584                         } else {
585                             p.info.authority = p.info.authority + ";" + names[j];
586                         }
587                         if (DEBUG_PACKAGE_SCANNING && chatty) {
588                             Log.d(TAG, "Registered content provider: " + names[j]
589                                     + ", className = " + p.info.name
590                                     + ", isSyncable = " + p.info.isSyncable);
591                         }
592                     } else {
593                         final PackageParser.Provider other =
594                                 mProvidersByAuthority.get(names[j]);
595                         final ComponentName component =
596                                 (other != null && other.getComponentName() != null)
597                                         ? other.getComponentName() : null;
598                         final String packageName =
599                                 component != null ? component.getPackageName() : "?";
600                         Slog.w(TAG, "Skipping provider name " + names[j]
601                                 + " (in package " + pkg.applicationInfo.packageName + ")"
602                                 + ": name already used by " + packageName);
603                     }
604                 }
605             }
606             if (DEBUG_PACKAGE_SCANNING && chatty) {
607                 if (r == null) {
608                     r = new StringBuilder(256);
609                 } else {
610                     r.append(' ');
611                 }
612                 r.append(p.info.name);
613             }
614         }
615         if (DEBUG_PACKAGE_SCANNING && chatty) {
616             Log.d(TAG, "  Providers: " + (r == null ? "<NONE>" : r));
617         }
618     }
619 
620     @GuardedBy("mLock")
addReceiversLocked(PackageParser.Package pkg, boolean chatty)621     private void addReceiversLocked(PackageParser.Package pkg, boolean chatty) {
622         final int receiversSize = pkg.receivers.size();
623         StringBuilder r = null;
624         for (int i = 0; i < receiversSize; i++) {
625             PackageParser.Activity a = pkg.receivers.get(i);
626             a.info.processName = fixProcessName(pkg.applicationInfo.processName,
627                     a.info.processName);
628             mReceivers.addActivity(a, "receiver", null);
629             if (DEBUG_PACKAGE_SCANNING && chatty) {
630                 if (r == null) {
631                     r = new StringBuilder(256);
632                 } else {
633                     r.append(' ');
634                 }
635                 r.append(a.info.name);
636             }
637         }
638         if (DEBUG_PACKAGE_SCANNING && chatty) {
639             Log.d(TAG, "  Receivers: " + (r == null ? "<NONE>" : r));
640         }
641     }
642 
643     @GuardedBy("mLock")
addServicesLocked(PackageParser.Package pkg, boolean chatty)644     private void addServicesLocked(PackageParser.Package pkg, boolean chatty) {
645         final int servicesSize = pkg.services.size();
646         StringBuilder r = null;
647         for (int i = 0; i < servicesSize; i++) {
648             PackageParser.Service s = pkg.services.get(i);
649             s.info.processName = fixProcessName(pkg.applicationInfo.processName,
650                     s.info.processName);
651             mServices.addService(s);
652             if (DEBUG_PACKAGE_SCANNING && chatty) {
653                 if (r == null) {
654                     r = new StringBuilder(256);
655                 } else {
656                     r.append(' ');
657                 }
658                 r.append(s.info.name);
659             }
660         }
661         if (DEBUG_PACKAGE_SCANNING && chatty) {
662             Log.d(TAG, "  Services: " + (r == null ? "<NONE>" : r));
663         }
664     }
665 
666 
667     /**
668      * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
669      * MODIFIED. Do not pass in a list that should not be changed.
670      */
getIntentListSubset(List<ActivityIntentInfo> intentList, IterGenerator<T> generator, Iterator<T> searchIterator)671     private static <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
672             IterGenerator<T> generator, Iterator<T> searchIterator) {
673         // loop through the set of actions; every one must be found in the intent filter
674         while (searchIterator.hasNext()) {
675             // we must have at least one filter in the list to consider a match
676             if (intentList.size() == 0) {
677                 break;
678             }
679 
680             final T searchAction = searchIterator.next();
681 
682             // loop through the set of intent filters
683             final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
684             while (intentIter.hasNext()) {
685                 final ActivityIntentInfo intentInfo = intentIter.next();
686                 boolean selectionFound = false;
687 
688                 // loop through the intent filter's selection criteria; at least one
689                 // of them must match the searched criteria
690                 final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
691                 while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
692                     final T intentSelection = intentSelectionIter.next();
693                     if (intentSelection != null && intentSelection.equals(searchAction)) {
694                         selectionFound = true;
695                         break;
696                     }
697                 }
698 
699                 // the selection criteria wasn't found in this filter's set; this filter
700                 // is not a potential match
701                 if (!selectionFound) {
702                     intentIter.remove();
703                 }
704             }
705         }
706     }
707 
isProtectedAction(ActivityIntentInfo filter)708     private static boolean isProtectedAction(ActivityIntentInfo filter) {
709         final Iterator<String> actionsIter = filter.actionsIterator();
710         while (actionsIter != null && actionsIter.hasNext()) {
711             final String filterAction = actionsIter.next();
712             if (PROTECTED_ACTIONS.contains(filterAction)) {
713                 return true;
714             }
715         }
716         return false;
717     }
718 
719     /**
720      * Finds a privileged activity that matches the specified activity names.
721      */
findMatchingActivity( List<PackageParser.Activity> activityList, ActivityInfo activityInfo)722     private static PackageParser.Activity findMatchingActivity(
723             List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
724         for (PackageParser.Activity sysActivity : activityList) {
725             if (sysActivity.info.name.equals(activityInfo.name)) {
726                 return sysActivity;
727             }
728             if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
729                 return sysActivity;
730             }
731             if (sysActivity.info.targetActivity != null) {
732                 if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
733                     return sysActivity;
734                 }
735                 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
736                     return sysActivity;
737                 }
738             }
739         }
740         return null;
741     }
742 
743     /**
744      * Adjusts the priority of the given intent filter according to policy.
745      * <p>
746      * <ul>
747      * <li>The priority for non privileged applications is capped to '0'</li>
748      * <li>The priority for protected actions on privileged applications is capped to '0'</li>
749      * <li>The priority for unbundled updates to privileged applications is capped to the
750      *      priority defined on the system partition</li>
751      * </ul>
752      * <p>
753      * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
754      * allowed to obtain any priority on any action.
755      */
adjustPriority(List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent, String setupWizardPackage)756     private void adjustPriority(List<PackageParser.Activity> systemActivities,
757             ActivityIntentInfo intent, String setupWizardPackage) {
758         // nothing to do; priority is fine as-is
759         if (intent.getPriority() <= 0) {
760             return;
761         }
762 
763         final ActivityInfo activityInfo = intent.activity.info;
764         final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
765 
766         final boolean privilegedApp =
767                 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
768         if (!privilegedApp) {
769             // non-privileged applications can never define a priority >0
770             if (DEBUG_FILTERS) {
771                 Slog.i(TAG, "Non-privileged app; cap priority to 0;"
772                         + " package: " + applicationInfo.packageName
773                         + " activity: " + intent.activity.className
774                         + " origPrio: " + intent.getPriority());
775             }
776             intent.setPriority(0);
777             return;
778         }
779 
780         if (systemActivities == null) {
781             // the system package is not disabled; we're parsing the system partition
782             if (isProtectedAction(intent)) {
783                 if (mDeferProtectedFilters) {
784                     // We can't deal with these just yet. No component should ever obtain a
785                     // >0 priority for a protected actions, with ONE exception -- the setup
786                     // wizard. The setup wizard, however, cannot be known until we're able to
787                     // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
788                     // until all intent filters have been processed. Chicken, meet egg.
789                     // Let the filter temporarily have a high priority and rectify the
790                     // priorities after all system packages have been scanned.
791                     if (mProtectedFilters == null) {
792                         mProtectedFilters = new ArrayList<>();
793                     }
794                     mProtectedFilters.add(intent);
795                     if (DEBUG_FILTERS) {
796                         Slog.i(TAG, "Protected action; save for later;"
797                                 + " package: " + applicationInfo.packageName
798                                 + " activity: " + intent.activity.className
799                                 + " origPrio: " + intent.getPriority());
800                     }
801                     return;
802                 } else {
803                     if (DEBUG_FILTERS && setupWizardPackage == null) {
804                         Slog.i(TAG, "No setup wizard;"
805                                 + " All protected intents capped to priority 0");
806                     }
807                     if (intent.activity.info.packageName.equals(setupWizardPackage)) {
808                         if (DEBUG_FILTERS) {
809                             Slog.i(TAG, "Found setup wizard;"
810                                     + " allow priority " + intent.getPriority() + ";"
811                                     + " package: " + intent.activity.info.packageName
812                                     + " activity: " + intent.activity.className
813                                     + " priority: " + intent.getPriority());
814                         }
815                         // setup wizard gets whatever it wants
816                         return;
817                     }
818                     if (DEBUG_FILTERS) {
819                         Slog.i(TAG, "Protected action; cap priority to 0;"
820                                 + " package: " + intent.activity.info.packageName
821                                 + " activity: " + intent.activity.className
822                                 + " origPrio: " + intent.getPriority());
823                     }
824                     intent.setPriority(0);
825                     return;
826                 }
827             }
828             // privileged apps on the system image get whatever priority they request
829             return;
830         }
831 
832         // privileged app unbundled update ... try to find the same activity
833         final PackageParser.Activity foundActivity =
834                 findMatchingActivity(systemActivities, activityInfo);
835         if (foundActivity == null) {
836             // this is a new activity; it cannot obtain >0 priority
837             if (DEBUG_FILTERS) {
838                 Slog.i(TAG, "New activity; cap priority to 0;"
839                         + " package: " + applicationInfo.packageName
840                         + " activity: " + intent.activity.className
841                         + " origPrio: " + intent.getPriority());
842             }
843             intent.setPriority(0);
844             return;
845         }
846 
847         // found activity, now check for filter equivalence
848 
849         // a shallow copy is enough; we modify the list, not its contents
850         final List<ActivityIntentInfo> intentListCopy = new ArrayList<>(foundActivity.intents);
851         final List<ActivityIntentInfo> foundFilters = mActivities.findFilters(intent);
852 
853         // find matching action subsets
854         final Iterator<String> actionsIterator = intent.actionsIterator();
855         if (actionsIterator != null) {
856             getIntentListSubset(intentListCopy, new ActionIterGenerator(), actionsIterator);
857             if (intentListCopy.size() == 0) {
858                 // no more intents to match; we're not equivalent
859                 if (DEBUG_FILTERS) {
860                     Slog.i(TAG, "Mismatched action; cap priority to 0;"
861                             + " package: " + applicationInfo.packageName
862                             + " activity: " + intent.activity.className
863                             + " origPrio: " + intent.getPriority());
864                 }
865                 intent.setPriority(0);
866                 return;
867             }
868         }
869 
870         // find matching category subsets
871         final Iterator<String> categoriesIterator = intent.categoriesIterator();
872         if (categoriesIterator != null) {
873             getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), categoriesIterator);
874             if (intentListCopy.size() == 0) {
875                 // no more intents to match; we're not equivalent
876                 if (DEBUG_FILTERS) {
877                     Slog.i(TAG, "Mismatched category; cap priority to 0;"
878                             + " package: " + applicationInfo.packageName
879                             + " activity: " + intent.activity.className
880                             + " origPrio: " + intent.getPriority());
881                 }
882                 intent.setPriority(0);
883                 return;
884             }
885         }
886 
887         // find matching schemes subsets
888         final Iterator<String> schemesIterator = intent.schemesIterator();
889         if (schemesIterator != null) {
890             getIntentListSubset(intentListCopy, new SchemesIterGenerator(), schemesIterator);
891             if (intentListCopy.size() == 0) {
892                 // no more intents to match; we're not equivalent
893                 if (DEBUG_FILTERS) {
894                     Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
895                             + " package: " + applicationInfo.packageName
896                             + " activity: " + intent.activity.className
897                             + " origPrio: " + intent.getPriority());
898                 }
899                 intent.setPriority(0);
900                 return;
901             }
902         }
903 
904         // find matching authorities subsets
905         final Iterator<IntentFilter.AuthorityEntry> authoritiesIterator =
906                 intent.authoritiesIterator();
907         if (authoritiesIterator != null) {
908             getIntentListSubset(intentListCopy, new AuthoritiesIterGenerator(),
909                     authoritiesIterator);
910             if (intentListCopy.size() == 0) {
911                 // no more intents to match; we're not equivalent
912                 if (DEBUG_FILTERS) {
913                     Slog.i(TAG, "Mismatched authority; cap priority to 0;"
914                             + " package: " + applicationInfo.packageName
915                             + " activity: " + intent.activity.className
916                             + " origPrio: " + intent.getPriority());
917                 }
918                 intent.setPriority(0);
919                 return;
920             }
921         }
922 
923         // we found matching filter(s); app gets the max priority of all intents
924         int cappedPriority = 0;
925         for (int i = intentListCopy.size() - 1; i >= 0; --i) {
926             cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
927         }
928         if (intent.getPriority() > cappedPriority) {
929             if (DEBUG_FILTERS) {
930                 Slog.i(TAG, "Found matching filter(s);"
931                         + " cap priority to " + cappedPriority + ";"
932                         + " package: " + applicationInfo.packageName
933                         + " activity: " + intent.activity.className
934                         + " origPrio: " + intent.getPriority());
935             }
936             intent.setPriority(cappedPriority);
937             return;
938         }
939         // all this for nothing; the requested priority was <= what was on the system
940     }
941 
942     @GuardedBy("mLock")
removeAllComponentsLocked(PackageParser.Package pkg, boolean chatty)943     private void removeAllComponentsLocked(PackageParser.Package pkg, boolean chatty) {
944         int componentSize;
945         StringBuilder r;
946         int i;
947 
948         componentSize = pkg.activities.size();
949         r = null;
950         for (i = 0; i < componentSize; i++) {
951             PackageParser.Activity a = pkg.activities.get(i);
952             mActivities.removeActivity(a, "activity");
953             if (DEBUG_REMOVE && chatty) {
954                 if (r == null) {
955                     r = new StringBuilder(256);
956                 } else {
957                     r.append(' ');
958                 }
959                 r.append(a.info.name);
960             }
961         }
962         if (DEBUG_REMOVE && chatty) {
963             Log.d(TAG, "  Activities: " + (r == null ? "<NONE>" : r));
964         }
965 
966         componentSize = pkg.providers.size();
967         r = null;
968         for (i = 0; i < componentSize; i++) {
969             PackageParser.Provider p = pkg.providers.get(i);
970             mProviders.removeProvider(p);
971             if (p.info.authority == null) {
972                 // Another content provider with this authority existed when this app was
973                 // installed, so this authority is null. Ignore it as we don't have to
974                 // unregister the provider.
975                 continue;
976             }
977             String[] names = p.info.authority.split(";");
978             for (int j = 0; j < names.length; j++) {
979                 if (mProvidersByAuthority.get(names[j]) == p) {
980                     mProvidersByAuthority.remove(names[j]);
981                     if (DEBUG_REMOVE && chatty) {
982                         Log.d(TAG, "Unregistered content provider: " + names[j]
983                                 + ", className = " + p.info.name + ", isSyncable = "
984                                 + p.info.isSyncable);
985                     }
986                 }
987             }
988             if (DEBUG_REMOVE && chatty) {
989                 if (r == null) {
990                     r = new StringBuilder(256);
991                 } else {
992                     r.append(' ');
993                 }
994                 r.append(p.info.name);
995             }
996         }
997         if (DEBUG_REMOVE && chatty) {
998             Log.d(TAG, "  Providers: " + (r == null ? "<NONE>" : r));
999         }
1000 
1001         componentSize = pkg.receivers.size();
1002         r = null;
1003         for (i = 0; i < componentSize; i++) {
1004             PackageParser.Activity a = pkg.receivers.get(i);
1005             mReceivers.removeActivity(a, "receiver");
1006             if (DEBUG_REMOVE && chatty) {
1007                 if (r == null) {
1008                     r = new StringBuilder(256);
1009                 } else {
1010                     r.append(' ');
1011                 }
1012                 r.append(a.info.name);
1013             }
1014         }
1015         if (DEBUG_REMOVE && chatty) {
1016             Log.d(TAG, "  Receivers: " + (r == null ? "<NONE>" : r));
1017         }
1018 
1019         componentSize = pkg.services.size();
1020         r = null;
1021         for (i = 0; i < componentSize; i++) {
1022             PackageParser.Service s = pkg.services.get(i);
1023             mServices.removeService(s);
1024             if (DEBUG_REMOVE && chatty) {
1025                 if (r == null) {
1026                     r = new StringBuilder(256);
1027                 } else {
1028                     r.append(' ');
1029                 }
1030                 r.append(s.info.name);
1031             }
1032         }
1033         if (DEBUG_REMOVE && chatty) {
1034             Log.d(TAG, "  Services: " + (r == null ? "<NONE>" : r));
1035         }
1036     }
1037 
1038     @GuardedBy("mLock")
assertProvidersNotDefinedLocked(PackageParser.Package pkg)1039     private void assertProvidersNotDefinedLocked(PackageParser.Package pkg)
1040             throws PackageManagerException {
1041         final int providersSize = pkg.providers.size();
1042         int i;
1043         for (i = 0; i < providersSize; i++) {
1044             PackageParser.Provider p = pkg.providers.get(i);
1045             if (p.info.authority != null) {
1046                 final String[] names = p.info.authority.split(";");
1047                 for (int j = 0; j < names.length; j++) {
1048                     if (mProvidersByAuthority.containsKey(names[j])) {
1049                         final PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
1050                         final String otherPackageName =
1051                                 (other != null && other.getComponentName() != null)
1052                                         ? other.getComponentName().getPackageName() : "?";
1053                         // if we're installing over the same already-installed package, this is ok
1054                         if (!otherPackageName.equals(pkg.packageName)) {
1055                             throw new PackageManagerException(
1056                                     INSTALL_FAILED_CONFLICTING_PROVIDER,
1057                                     "Can't install because provider name " + names[j]
1058                                             + " (in package " + pkg.applicationInfo.packageName
1059                                             + ") is already used by " + otherPackageName);
1060                         }
1061                     }
1062                 }
1063             }
1064         }
1065     }
1066 
1067     private static final class ActivityIntentResolver
1068             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
1069         @Override
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)1070         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
1071                 boolean defaultOnly, int userId) {
1072             if (!sUserManager.exists(userId)) return null;
1073             mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
1074             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
1075         }
1076 
queryIntent(Intent intent, String resolvedType, int flags, int userId)1077         List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
1078                 int userId) {
1079             if (!sUserManager.exists(userId)) {
1080                 return null;
1081             }
1082             mFlags = flags;
1083             return super.queryIntent(intent, resolvedType,
1084                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
1085                     userId);
1086         }
1087 
queryIntentForPackage(Intent intent, String resolvedType, int flags, List<PackageParser.Activity> packageActivities, int userId)1088         List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
1089                 int flags, List<PackageParser.Activity> packageActivities, int userId) {
1090             if (!sUserManager.exists(userId)) {
1091                 return null;
1092             }
1093             if (packageActivities == null) {
1094                 return null;
1095             }
1096             mFlags = flags;
1097             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
1098             final int activitiesSize = packageActivities.size();
1099             ArrayList<PackageParser.ActivityIntentInfo[]> listCut = new ArrayList<>(activitiesSize);
1100 
1101             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
1102             for (int i = 0; i < activitiesSize; ++i) {
1103                 intentFilters = packageActivities.get(i).intents;
1104                 if (intentFilters != null && intentFilters.size() > 0) {
1105                     PackageParser.ActivityIntentInfo[] array =
1106                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
1107                     intentFilters.toArray(array);
1108                     listCut.add(array);
1109                 }
1110             }
1111             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
1112         }
1113 
addActivity(PackageParser.Activity a, String type, List<PackageParser.ActivityIntentInfo> newIntents)1114         private void addActivity(PackageParser.Activity a, String type,
1115                 List<PackageParser.ActivityIntentInfo> newIntents) {
1116             mActivities.put(a.getComponentName(), a);
1117             if (DEBUG_SHOW_INFO) {
1118                 final CharSequence label = a.info.nonLocalizedLabel != null
1119                         ? a.info.nonLocalizedLabel
1120                         : a.info.name;
1121                 Log.v(TAG, "  " + type + " " + label + ":");
1122             }
1123             if (DEBUG_SHOW_INFO) {
1124                 Log.v(TAG, "    Class=" + a.info.name);
1125             }
1126             final int intentsSize = a.intents.size();
1127             for (int j = 0; j < intentsSize; j++) {
1128                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
1129                 if (newIntents != null && "activity".equals(type)) {
1130                     newIntents.add(intent);
1131                 }
1132                 if (DEBUG_SHOW_INFO) {
1133                     Log.v(TAG, "    IntentFilter:");
1134                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
1135                 }
1136                 if (!intent.debugCheck()) {
1137                     Log.w(TAG, "==> For Activity " + a.info.name);
1138                 }
1139                 addFilter(intent);
1140             }
1141         }
1142 
removeActivity(PackageParser.Activity a, String type)1143         private void removeActivity(PackageParser.Activity a, String type) {
1144             mActivities.remove(a.getComponentName());
1145             if (DEBUG_SHOW_INFO) {
1146                 Log.v(TAG, "  " + type + " "
1147                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
1148                                 : a.info.name) + ":");
1149                 Log.v(TAG, "    Class=" + a.info.name);
1150             }
1151             final int intentsSize = a.intents.size();
1152             for (int j = 0; j < intentsSize; j++) {
1153                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
1154                 if (DEBUG_SHOW_INFO) {
1155                     Log.v(TAG, "    IntentFilter:");
1156                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
1157                 }
1158                 removeFilter(intent);
1159             }
1160         }
1161 
1162         @Override
allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)1163         protected boolean allowFilterResult(
1164                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
1165             ActivityInfo filterAi = filter.activity.info;
1166             for (int i = dest.size() - 1; i >= 0; --i) {
1167                 ActivityInfo destAi = dest.get(i).activityInfo;
1168                 if (destAi.name == filterAi.name && destAi.packageName == filterAi.packageName) {
1169                     return false;
1170                 }
1171             }
1172             return true;
1173         }
1174 
1175         @Override
newArray(int size)1176         protected ActivityIntentInfo[] newArray(int size) {
1177             return new ActivityIntentInfo[size];
1178         }
1179 
1180         @Override
isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId)1181         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
1182             if (!sUserManager.exists(userId)) return true;
1183             PackageParser.Package p = filter.activity.owner;
1184             if (p != null) {
1185                 PackageSetting ps = (PackageSetting) p.mExtras;
1186                 if (ps != null) {
1187                     // System apps are never considered stopped for purposes of
1188                     // filtering, because there may be no way for the user to
1189                     // actually re-launch them.
1190                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
1191                             && ps.getStopped(userId);
1192                 }
1193             }
1194             return false;
1195         }
1196 
1197         @Override
isPackageForFilter(String packageName, PackageParser.ActivityIntentInfo info)1198         protected boolean isPackageForFilter(String packageName,
1199                 PackageParser.ActivityIntentInfo info) {
1200             return packageName.equals(info.activity.owner.packageName);
1201         }
1202 
log(String reason, ActivityIntentInfo info, int match, int userId)1203         private void log(String reason, ActivityIntentInfo info, int match,
1204                 int userId) {
1205             Slog.w(TAG, reason
1206                     + "; match: "
1207                     + DebugUtils.flagsToString(IntentFilter.class, "MATCH_", match)
1208                     + "; userId: " + userId
1209                     + "; intent info: " + info);
1210         }
1211 
1212         @Override
newResult(PackageParser.ActivityIntentInfo info, int match, int userId)1213         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
1214                 int match, int userId) {
1215             if (!sUserManager.exists(userId)) {
1216                 if (DEBUG) {
1217                     log("User doesn't exist", info, match, userId);
1218                 }
1219                 return null;
1220             }
1221             if (!sPackageManagerInternal.isEnabledAndMatches(info.activity.info, mFlags, userId)) {
1222                 if (DEBUG) {
1223                     log("!PackageManagerInternal.isEnabledAndMatches; mFlags="
1224                             + DebugUtils.flagsToString(PackageManager.class, "MATCH_", mFlags),
1225                             info, match, userId);
1226                 }
1227                 return null;
1228             }
1229             final PackageParser.Activity activity = info.activity;
1230             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
1231             if (ps == null) {
1232                 if (DEBUG) {
1233                     log("info.activity.owner.mExtras == null", info, match, userId);
1234                 }
1235                 return null;
1236             }
1237             final PackageUserState userState = ps.readUserState(userId);
1238             ActivityInfo ai =
1239                     PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
1240             if (ai == null) {
1241                 if (DEBUG) {
1242                     log("Failed to create ActivityInfo based on " + info.activity, info, match,
1243                             userId);
1244                 }
1245                 return null;
1246             }
1247             final boolean matchExplicitlyVisibleOnly =
1248                     (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
1249             final boolean matchVisibleToInstantApp =
1250                     (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
1251             final boolean componentVisible =
1252                     matchVisibleToInstantApp
1253                     && info.isVisibleToInstantApp()
1254                     && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
1255             final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
1256             // throw out filters that aren't visible to ephemeral apps
1257             if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
1258                 if (DEBUG) {
1259                     log("Filter(s) not visible to ephemeral apps"
1260                             + "; matchVisibleToInstantApp=" + matchVisibleToInstantApp
1261                             + "; matchInstantApp=" + matchInstantApp
1262                             + "; info.isVisibleToInstantApp()=" + info.isVisibleToInstantApp()
1263                             + "; matchExplicitlyVisibleOnly=" + matchExplicitlyVisibleOnly
1264                             + "; info.isExplicitlyVisibleToInstantApp()="
1265                                     + info.isExplicitlyVisibleToInstantApp(),
1266                             info, match, userId);
1267                 }
1268                 return null;
1269             }
1270             // throw out instant app filters if we're not explicitly requesting them
1271             if (!matchInstantApp && userState.instantApp) {
1272                 if (DEBUG) {
1273                     log("Instant app filter is not explicitly requested", info, match, userId);
1274                 }
1275                 return null;
1276             }
1277             // throw out instant app filters if updates are available; will trigger
1278             // instant app resolution
1279             if (userState.instantApp && ps.isUpdateAvailable()) {
1280                 if (DEBUG) {
1281                     log("Instant app update is available", info, match, userId);
1282                 }
1283                 return null;
1284             }
1285             final ResolveInfo res = new ResolveInfo();
1286             res.activityInfo = ai;
1287             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
1288                 res.filter = info;
1289             }
1290             res.handleAllWebDataURI = info.handleAllWebDataURI();
1291             res.priority = info.getPriority();
1292             res.preferredOrder = activity.owner.mPreferredOrder;
1293             //System.out.println("Result: " + res.activityInfo.className +
1294             //                   " = " + res.priority);
1295             res.match = match;
1296             res.isDefault = info.hasDefault;
1297             res.labelRes = info.labelRes;
1298             res.nonLocalizedLabel = info.nonLocalizedLabel;
1299             if (sPackageManagerInternal.userNeedsBadging(userId)) {
1300                 res.noResourceId = true;
1301             } else {
1302                 res.icon = info.icon;
1303             }
1304             res.iconResourceId = info.icon;
1305             res.system = res.activityInfo.applicationInfo.isSystemApp();
1306             res.isInstantAppAvailable = userState.instantApp;
1307             return res;
1308         }
1309 
1310         @Override
sortResults(List<ResolveInfo> results)1311         protected void sortResults(List<ResolveInfo> results) {
1312             results.sort(RESOLVE_PRIORITY_SORTER);
1313         }
1314 
1315         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)1316         protected void dumpFilter(PrintWriter out, String prefix,
1317                 PackageParser.ActivityIntentInfo filter) {
1318             out.print(prefix);
1319             out.print(Integer.toHexString(System.identityHashCode(filter.activity)));
1320             out.print(' ');
1321             filter.activity.printComponentShortName(out);
1322             out.print(" filter ");
1323             out.println(Integer.toHexString(System.identityHashCode(filter)));
1324         }
1325 
1326         @Override
filterToLabel(PackageParser.ActivityIntentInfo filter)1327         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
1328             return filter.activity;
1329         }
1330 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)1331         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
1332             PackageParser.Activity activity = (PackageParser.Activity) label;
1333             out.print(prefix);
1334             out.print(Integer.toHexString(System.identityHashCode(activity)));
1335             out.print(' ');
1336             activity.printComponentShortName(out);
1337             if (count > 1) {
1338                 out.print(" ("); out.print(count); out.print(" filters)");
1339             }
1340             out.println();
1341         }
1342 
1343         // Keys are String (activity class name), values are Activity.
1344         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities =
1345                 new ArrayMap<>();
1346         private int mFlags;
1347     }
1348 
1349     private static final class ProviderIntentResolver
1350             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
1351         @Override
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)1352         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
1353                 boolean defaultOnly, int userId) {
1354             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
1355             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
1356         }
1357 
queryIntent(Intent intent, String resolvedType, int flags, int userId)1358         List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
1359                 int userId) {
1360             if (!sUserManager.exists(userId)) {
1361                 return null;
1362             }
1363             mFlags = flags;
1364             return super.queryIntent(intent, resolvedType,
1365                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
1366                     userId);
1367         }
1368 
queryIntentForPackage(Intent intent, String resolvedType, int flags, List<PackageParser.Provider> packageProviders, int userId)1369         List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
1370                 int flags, List<PackageParser.Provider> packageProviders, int userId) {
1371             if (!sUserManager.exists(userId)) {
1372                 return null;
1373             }
1374             if (packageProviders == null) {
1375                 return null;
1376             }
1377             mFlags = flags;
1378             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
1379             final int providersSize = packageProviders.size();
1380             ArrayList<PackageParser.ProviderIntentInfo[]> listCut = new ArrayList<>(providersSize);
1381 
1382             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
1383             for (int i = 0; i < providersSize; ++i) {
1384                 intentFilters = packageProviders.get(i).intents;
1385                 if (intentFilters != null && intentFilters.size() > 0) {
1386                     PackageParser.ProviderIntentInfo[] array =
1387                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
1388                     intentFilters.toArray(array);
1389                     listCut.add(array);
1390                 }
1391             }
1392             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
1393         }
1394 
addProvider(PackageParser.Provider p)1395         void addProvider(PackageParser.Provider p) {
1396             if (mProviders.containsKey(p.getComponentName())) {
1397                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
1398                 return;
1399             }
1400 
1401             mProviders.put(p.getComponentName(), p);
1402             if (DEBUG_SHOW_INFO) {
1403                 Log.v(TAG, "  "
1404                         + (p.info.nonLocalizedLabel != null
1405                                 ? p.info.nonLocalizedLabel
1406                                 : p.info.name)
1407                         + ":");
1408                 Log.v(TAG, "    Class=" + p.info.name);
1409             }
1410             final int intentsSize = p.intents.size();
1411             int j;
1412             for (j = 0; j < intentsSize; j++) {
1413                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
1414                 if (DEBUG_SHOW_INFO) {
1415                     Log.v(TAG, "    IntentFilter:");
1416                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
1417                 }
1418                 if (!intent.debugCheck()) {
1419                     Log.w(TAG, "==> For Provider " + p.info.name);
1420                 }
1421                 addFilter(intent);
1422             }
1423         }
1424 
removeProvider(PackageParser.Provider p)1425         void removeProvider(PackageParser.Provider p) {
1426             mProviders.remove(p.getComponentName());
1427             if (DEBUG_SHOW_INFO) {
1428                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
1429                         ? p.info.nonLocalizedLabel
1430                         : p.info.name) + ":");
1431                 Log.v(TAG, "    Class=" + p.info.name);
1432             }
1433             final int intentsSize = p.intents.size();
1434             int j;
1435             for (j = 0; j < intentsSize; j++) {
1436                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
1437                 if (DEBUG_SHOW_INFO) {
1438                     Log.v(TAG, "    IntentFilter:");
1439                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
1440                 }
1441                 removeFilter(intent);
1442             }
1443         }
1444 
1445         @Override
allowFilterResult( PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest)1446         protected boolean allowFilterResult(
1447                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
1448             ProviderInfo filterPi = filter.provider.info;
1449             for (int i = dest.size() - 1; i >= 0; i--) {
1450                 ProviderInfo destPi = dest.get(i).providerInfo;
1451                 if (destPi.name == filterPi.name
1452                         && destPi.packageName == filterPi.packageName) {
1453                     return false;
1454                 }
1455             }
1456             return true;
1457         }
1458 
1459         @Override
newArray(int size)1460         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
1461             return new PackageParser.ProviderIntentInfo[size];
1462         }
1463 
1464         @Override
isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId)1465         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
1466             if (!sUserManager.exists(userId)) {
1467                 return true;
1468             }
1469             PackageParser.Package p = filter.provider.owner;
1470             if (p != null) {
1471                 PackageSetting ps = (PackageSetting) p.mExtras;
1472                 if (ps != null) {
1473                     // System apps are never considered stopped for purposes of
1474                     // filtering, because there may be no way for the user to
1475                     // actually re-launch them.
1476                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
1477                             && ps.getStopped(userId);
1478                 }
1479             }
1480             return false;
1481         }
1482 
1483         @Override
isPackageForFilter(String packageName, PackageParser.ProviderIntentInfo info)1484         protected boolean isPackageForFilter(String packageName,
1485                 PackageParser.ProviderIntentInfo info) {
1486             return packageName.equals(info.provider.owner.packageName);
1487         }
1488 
1489         @Override
newResult(PackageParser.ProviderIntentInfo filter, int match, int userId)1490         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
1491                 int match, int userId) {
1492             if (!sUserManager.exists(userId)) {
1493                 return null;
1494             }
1495             final PackageParser.ProviderIntentInfo info = filter;
1496             if (!sPackageManagerInternal.isEnabledAndMatches(info.provider.info, mFlags, userId)) {
1497                 return null;
1498             }
1499             final PackageParser.Provider provider = info.provider;
1500             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
1501             if (ps == null) {
1502                 return null;
1503             }
1504             final PackageUserState userState = ps.readUserState(userId);
1505             final boolean matchVisibleToInstantApp = (mFlags
1506                     & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
1507             final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
1508             // throw out filters that aren't visible to instant applications
1509             if (matchVisibleToInstantApp
1510                     && !(info.isVisibleToInstantApp() || userState.instantApp)) {
1511                 return null;
1512             }
1513             // throw out instant application filters if we're not explicitly requesting them
1514             if (!isInstantApp && userState.instantApp) {
1515                 return null;
1516             }
1517             // throw out instant application filters if updates are available; will trigger
1518             // instant application resolution
1519             if (userState.instantApp && ps.isUpdateAvailable()) {
1520                 return null;
1521             }
1522             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
1523                     userState, userId);
1524             if (pi == null) {
1525                 return null;
1526             }
1527             final ResolveInfo res = new ResolveInfo();
1528             res.providerInfo = pi;
1529             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
1530                 res.filter = filter;
1531             }
1532             res.priority = info.getPriority();
1533             res.preferredOrder = provider.owner.mPreferredOrder;
1534             res.match = match;
1535             res.isDefault = info.hasDefault;
1536             res.labelRes = info.labelRes;
1537             res.nonLocalizedLabel = info.nonLocalizedLabel;
1538             res.icon = info.icon;
1539             res.system = res.providerInfo.applicationInfo.isSystemApp();
1540             return res;
1541         }
1542 
1543         @Override
sortResults(List<ResolveInfo> results)1544         protected void sortResults(List<ResolveInfo> results) {
1545             results.sort(RESOLVE_PRIORITY_SORTER);
1546         }
1547 
1548         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ProviderIntentInfo filter)1549         protected void dumpFilter(PrintWriter out, String prefix,
1550                 PackageParser.ProviderIntentInfo filter) {
1551             out.print(prefix);
1552             out.print(Integer.toHexString(System.identityHashCode(filter.provider)));
1553             out.print(' ');
1554             filter.provider.printComponentShortName(out);
1555             out.print(" filter ");
1556             out.println(Integer.toHexString(System.identityHashCode(filter)));
1557         }
1558 
1559         @Override
filterToLabel(PackageParser.ProviderIntentInfo filter)1560         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
1561             return filter.provider;
1562         }
1563 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)1564         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
1565             final PackageParser.Provider provider = (PackageParser.Provider) label;
1566             out.print(prefix);
1567             out.print(Integer.toHexString(System.identityHashCode(provider)));
1568             out.print(' ');
1569             provider.printComponentShortName(out);
1570             if (count > 1) {
1571                 out.print(" (");
1572                 out.print(count);
1573                 out.print(" filters)");
1574             }
1575             out.println();
1576         }
1577 
1578         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders = new ArrayMap<>();
1579         private int mFlags;
1580     }
1581 
1582     private static final class ServiceIntentResolver
1583             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
1584         @Override
queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)1585         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
1586                 boolean defaultOnly, int userId) {
1587             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
1588             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
1589         }
1590 
queryIntent(Intent intent, String resolvedType, int flags, int userId)1591         List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
1592                 int userId) {
1593             if (!sUserManager.exists(userId)) return null;
1594             mFlags = flags;
1595             return super.queryIntent(intent, resolvedType,
1596                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
1597                     userId);
1598         }
1599 
queryIntentForPackage(Intent intent, String resolvedType, int flags, List<PackageParser.Service> packageServices, int userId)1600         List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
1601                 int flags, List<PackageParser.Service> packageServices, int userId) {
1602             if (!sUserManager.exists(userId)) return null;
1603             if (packageServices == null) {
1604                 return null;
1605             }
1606             mFlags = flags;
1607             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
1608             final int servicesSize = packageServices.size();
1609             ArrayList<PackageParser.ServiceIntentInfo[]> listCut = new ArrayList<>(servicesSize);
1610 
1611             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
1612             for (int i = 0; i < servicesSize; ++i) {
1613                 intentFilters = packageServices.get(i).intents;
1614                 if (intentFilters != null && intentFilters.size() > 0) {
1615                     PackageParser.ServiceIntentInfo[] array =
1616                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
1617                     intentFilters.toArray(array);
1618                     listCut.add(array);
1619                 }
1620             }
1621             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
1622         }
1623 
addService(PackageParser.Service s)1624         void addService(PackageParser.Service s) {
1625             mServices.put(s.getComponentName(), s);
1626             if (DEBUG_SHOW_INFO) {
1627                 Log.v(TAG, "  "
1628                         + (s.info.nonLocalizedLabel != null
1629                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
1630                 Log.v(TAG, "    Class=" + s.info.name);
1631             }
1632             final int intentsSize = s.intents.size();
1633             int j;
1634             for (j = 0; j < intentsSize; j++) {
1635                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
1636                 if (DEBUG_SHOW_INFO) {
1637                     Log.v(TAG, "    IntentFilter:");
1638                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
1639                 }
1640                 if (!intent.debugCheck()) {
1641                     Log.w(TAG, "==> For Service " + s.info.name);
1642                 }
1643                 addFilter(intent);
1644             }
1645         }
1646 
removeService(PackageParser.Service s)1647         void removeService(PackageParser.Service s) {
1648             mServices.remove(s.getComponentName());
1649             if (DEBUG_SHOW_INFO) {
1650                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
1651                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
1652                 Log.v(TAG, "    Class=" + s.info.name);
1653             }
1654             final int intentsSize = s.intents.size();
1655             int j;
1656             for (j = 0; j < intentsSize; j++) {
1657                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
1658                 if (DEBUG_SHOW_INFO) {
1659                     Log.v(TAG, "    IntentFilter:");
1660                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
1661                 }
1662                 removeFilter(intent);
1663             }
1664         }
1665 
1666         @Override
allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)1667         protected boolean allowFilterResult(
1668                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
1669             ServiceInfo filterSi = filter.service.info;
1670             for (int i = dest.size() - 1; i >= 0; --i) {
1671                 ServiceInfo destAi = dest.get(i).serviceInfo;
1672                 if (destAi.name == filterSi.name
1673                         && destAi.packageName == filterSi.packageName) {
1674                     return false;
1675                 }
1676             }
1677             return true;
1678         }
1679 
1680         @Override
newArray(int size)1681         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
1682             return new PackageParser.ServiceIntentInfo[size];
1683         }
1684 
1685         @Override
isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId)1686         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
1687             if (!sUserManager.exists(userId)) return true;
1688             PackageParser.Package p = filter.service.owner;
1689             if (p != null) {
1690                 PackageSetting ps = (PackageSetting) p.mExtras;
1691                 if (ps != null) {
1692                     // System apps are never considered stopped for purposes of
1693                     // filtering, because there may be no way for the user to
1694                     // actually re-launch them.
1695                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
1696                             && ps.getStopped(userId);
1697                 }
1698             }
1699             return false;
1700         }
1701 
1702         @Override
isPackageForFilter(String packageName, PackageParser.ServiceIntentInfo info)1703         protected boolean isPackageForFilter(String packageName,
1704                 PackageParser.ServiceIntentInfo info) {
1705             return packageName.equals(info.service.owner.packageName);
1706         }
1707 
1708         @Override
newResult(PackageParser.ServiceIntentInfo filter, int match, int userId)1709         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
1710                 int match, int userId) {
1711             if (!sUserManager.exists(userId)) return null;
1712             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo) filter;
1713             if (!sPackageManagerInternal.isEnabledAndMatches(info.service.info, mFlags, userId)) {
1714                 return null;
1715             }
1716             final PackageParser.Service service = info.service;
1717             PackageSetting ps = (PackageSetting) service.owner.mExtras;
1718             if (ps == null) {
1719                 return null;
1720             }
1721             final PackageUserState userState = ps.readUserState(userId);
1722             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
1723                     userState, userId);
1724             if (si == null) {
1725                 return null;
1726             }
1727             final boolean matchVisibleToInstantApp =
1728                     (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
1729             final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
1730             // throw out filters that aren't visible to ephemeral apps
1731             if (matchVisibleToInstantApp
1732                     && !(info.isVisibleToInstantApp() || userState.instantApp)) {
1733                 return null;
1734             }
1735             // throw out ephemeral filters if we're not explicitly requesting them
1736             if (!isInstantApp && userState.instantApp) {
1737                 return null;
1738             }
1739             // throw out instant app filters if updates are available; will trigger
1740             // instant app resolution
1741             if (userState.instantApp && ps.isUpdateAvailable()) {
1742                 return null;
1743             }
1744             final ResolveInfo res = new ResolveInfo();
1745             res.serviceInfo = si;
1746             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
1747                 res.filter = filter;
1748             }
1749             res.priority = info.getPriority();
1750             res.preferredOrder = service.owner.mPreferredOrder;
1751             res.match = match;
1752             res.isDefault = info.hasDefault;
1753             res.labelRes = info.labelRes;
1754             res.nonLocalizedLabel = info.nonLocalizedLabel;
1755             res.icon = info.icon;
1756             res.system = res.serviceInfo.applicationInfo.isSystemApp();
1757             return res;
1758         }
1759 
1760         @Override
sortResults(List<ResolveInfo> results)1761         protected void sortResults(List<ResolveInfo> results) {
1762             results.sort(RESOLVE_PRIORITY_SORTER);
1763         }
1764 
1765         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)1766         protected void dumpFilter(PrintWriter out, String prefix,
1767                 PackageParser.ServiceIntentInfo filter) {
1768             out.print(prefix);
1769             out.print(Integer.toHexString(System.identityHashCode(filter.service)));
1770             out.print(' ');
1771             filter.service.printComponentShortName(out);
1772             out.print(" filter ");
1773             out.print(Integer.toHexString(System.identityHashCode(filter)));
1774             if (filter.service.info.permission != null) {
1775                 out.print(" permission "); out.println(filter.service.info.permission);
1776             } else {
1777                 out.println();
1778             }
1779         }
1780 
1781         @Override
filterToLabel(PackageParser.ServiceIntentInfo filter)1782         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
1783             return filter.service;
1784         }
1785 
dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)1786         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
1787             final PackageParser.Service service = (PackageParser.Service) label;
1788             out.print(prefix);
1789             out.print(Integer.toHexString(System.identityHashCode(service)));
1790             out.print(' ');
1791             service.printComponentShortName(out);
1792             if (count > 1) {
1793                 out.print(" ("); out.print(count); out.print(" filters)");
1794             }
1795             out.println();
1796         }
1797 
1798         // Keys are String (activity class name), values are Activity.
1799         private final ArrayMap<ComponentName, PackageParser.Service> mServices = new ArrayMap<>();
1800         private int mFlags;
1801     }
1802 
1803     static final class InstantAppIntentResolver
1804             extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
1805             AuxiliaryResolveInfo.AuxiliaryFilter> {
1806         /**
1807          * The result that has the highest defined order. Ordering applies on a
1808          * per-package basis. Mapping is from package name to Pair of order and
1809          * EphemeralResolveInfo.
1810          * <p>
1811          * NOTE: This is implemented as a field variable for convenience and efficiency.
1812          * By having a field variable, we're able to track filter ordering as soon as
1813          * a non-zero order is defined. Otherwise, multiple loops across the result set
1814          * would be needed to apply ordering. If the intent resolver becomes re-entrant,
1815          * this needs to be contained entirely within {@link #filterResults}.
1816          */
1817         final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult =
1818                 new ArrayMap<>();
1819 
1820         @Override
newArray(int size)1821         protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
1822             return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
1823         }
1824 
1825         @Override
isPackageForFilter(String packageName, AuxiliaryResolveInfo.AuxiliaryFilter responseObj)1826         protected boolean isPackageForFilter(String packageName,
1827                 AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
1828             return true;
1829         }
1830 
1831         @Override
newResult( AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId)1832         protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
1833                 AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
1834             if (!sUserManager.exists(userId)) {
1835                 return null;
1836             }
1837             final String packageName = responseObj.resolveInfo.getPackageName();
1838             final Integer order = responseObj.getOrder();
1839             final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
1840                     mOrderResult.get(packageName);
1841             // ordering is enabled and this item's order isn't high enough
1842             if (lastOrderResult != null && lastOrderResult.first >= order) {
1843                 return null;
1844             }
1845             final InstantAppResolveInfo res = responseObj.resolveInfo;
1846             if (order > 0) {
1847                 // non-zero order, enable ordering
1848                 mOrderResult.put(packageName, new Pair<>(order, res));
1849             }
1850             return responseObj;
1851         }
1852 
1853         @Override
filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results)1854         protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
1855             // only do work if ordering is enabled [most of the time it won't be]
1856             if (mOrderResult.size() == 0) {
1857                 return;
1858             }
1859             int resultSize = results.size();
1860             for (int i = 0; i < resultSize; i++) {
1861                 final InstantAppResolveInfo info = results.get(i).resolveInfo;
1862                 final String packageName = info.getPackageName();
1863                 final Pair<Integer, InstantAppResolveInfo> savedInfo =
1864                         mOrderResult.get(packageName);
1865                 if (savedInfo == null) {
1866                     // package doesn't having ordering
1867                     continue;
1868                 }
1869                 if (savedInfo.second == info) {
1870                     // circled back to the highest ordered item; remove from order list
1871                     mOrderResult.remove(packageName);
1872                     if (mOrderResult.size() == 0) {
1873                         // no more ordered items
1874                         break;
1875                     }
1876                     continue;
1877                 }
1878                 // item has a worse order, remove it from the result list
1879                 results.remove(i);
1880                 resultSize--;
1881                 i--;
1882             }
1883         }
1884     }
1885 
1886     /** Generic to create an {@link Iterator} for a data type */
1887     static class IterGenerator<E> {
generate(ActivityIntentInfo info)1888         public Iterator<E> generate(ActivityIntentInfo info) {
1889             return null;
1890         }
1891     }
1892 
1893     /** Create an {@link Iterator} for intent actions */
1894     static class ActionIterGenerator extends IterGenerator<String> {
1895         @Override
generate(ActivityIntentInfo info)1896         public Iterator<String> generate(ActivityIntentInfo info) {
1897             return info.actionsIterator();
1898         }
1899     }
1900 
1901     /** Create an {@link Iterator} for intent categories */
1902     static class CategoriesIterGenerator extends IterGenerator<String> {
1903         @Override
generate(ActivityIntentInfo info)1904         public Iterator<String> generate(ActivityIntentInfo info) {
1905             return info.categoriesIterator();
1906         }
1907     }
1908 
1909     /** Create an {@link Iterator} for intent schemes */
1910     static class SchemesIterGenerator extends IterGenerator<String> {
1911         @Override
generate(ActivityIntentInfo info)1912         public Iterator<String> generate(ActivityIntentInfo info) {
1913             return info.schemesIterator();
1914         }
1915     }
1916 
1917     /** Create an {@link Iterator} for intent authorities */
1918     static class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
1919         @Override
generate(ActivityIntentInfo info)1920         public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
1921             return info.authoritiesIterator();
1922         }
1923     }
1924 
1925 }
1926