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