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