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