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