1 /* 2 * Copyright (C) 2010 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 android.app; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.compat.annotation.UnsupportedAppUsage; 22 import android.content.BroadcastReceiver; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.IIntentReceiver; 26 import android.content.Intent; 27 import android.content.ServiceConnection; 28 import android.content.pm.ApplicationInfo; 29 import android.content.pm.IPackageManager; 30 import android.content.pm.PackageManager; 31 import android.content.pm.PackageManager.NameNotFoundException; 32 import android.content.pm.SharedLibraryInfo; 33 import android.content.pm.dex.ArtManager; 34 import android.content.pm.split.SplitDependencyLoader; 35 import android.content.res.AssetManager; 36 import android.content.res.CompatibilityInfo; 37 import android.content.res.Resources; 38 import android.os.Build; 39 import android.os.Bundle; 40 import android.os.FileUtils; 41 import android.os.GraphicsEnvironment; 42 import android.os.Handler; 43 import android.os.IBinder; 44 import android.os.Process; 45 import android.os.RemoteException; 46 import android.os.StrictMode; 47 import android.os.SystemProperties; 48 import android.os.Trace; 49 import android.os.UserHandle; 50 import android.provider.Settings; 51 import android.security.net.config.NetworkSecurityConfigProvider; 52 import android.sysprop.VndkProperties; 53 import android.text.TextUtils; 54 import android.util.AndroidRuntimeException; 55 import android.util.ArrayMap; 56 import android.util.Log; 57 import android.util.Slog; 58 import android.util.SparseArray; 59 import android.view.DisplayAdjustments; 60 61 import com.android.internal.annotations.GuardedBy; 62 import com.android.internal.util.ArrayUtils; 63 64 import dalvik.system.BaseDexClassLoader; 65 import dalvik.system.VMRuntime; 66 67 import java.io.File; 68 import java.io.IOException; 69 import java.io.InputStream; 70 import java.lang.ref.WeakReference; 71 import java.lang.reflect.InvocationTargetException; 72 import java.lang.reflect.Method; 73 import java.net.URL; 74 import java.nio.file.Paths; 75 import java.util.ArrayList; 76 import java.util.Arrays; 77 import java.util.Collections; 78 import java.util.Enumeration; 79 import java.util.LinkedHashSet; 80 import java.util.List; 81 import java.util.Objects; 82 import java.util.Set; 83 import java.util.concurrent.Executor; 84 85 final class IntentReceiverLeaked extends AndroidRuntimeException { 86 @UnsupportedAppUsage IntentReceiverLeaked(String msg)87 public IntentReceiverLeaked(String msg) { 88 super(msg); 89 } 90 } 91 92 final class ServiceConnectionLeaked extends AndroidRuntimeException { 93 @UnsupportedAppUsage ServiceConnectionLeaked(String msg)94 public ServiceConnectionLeaked(String msg) { 95 super(msg); 96 } 97 } 98 99 /** 100 * Local state maintained about a currently loaded .apk. 101 * @hide 102 */ 103 public final class LoadedApk { 104 static final String TAG = "LoadedApk"; 105 static final boolean DEBUG = false; 106 107 @UnsupportedAppUsage 108 private final ActivityThread mActivityThread; 109 @UnsupportedAppUsage 110 final String mPackageName; 111 @UnsupportedAppUsage 112 private ApplicationInfo mApplicationInfo; 113 @UnsupportedAppUsage 114 private String mAppDir; 115 @UnsupportedAppUsage 116 private String mResDir; 117 private String[] mLegacyOverlayDirs; 118 private String[] mOverlayPaths; 119 @UnsupportedAppUsage 120 private String mDataDir; 121 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 122 private String mLibDir; 123 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 124 private File mDataDirFile; 125 private File mDeviceProtectedDataDirFile; 126 private File mCredentialProtectedDataDirFile; 127 @UnsupportedAppUsage 128 private final ClassLoader mBaseClassLoader; 129 private ClassLoader mDefaultClassLoader; 130 private final boolean mSecurityViolation; 131 private final boolean mIncludeCode; 132 private final boolean mRegisterPackage; 133 @UnsupportedAppUsage 134 private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments(); 135 /** WARNING: This may change. Don't hold external references to it. */ 136 @UnsupportedAppUsage 137 Resources mResources; 138 @UnsupportedAppUsage 139 private ClassLoader mClassLoader; 140 @UnsupportedAppUsage 141 private Application mApplication; 142 143 private String[] mSplitNames; 144 private String[] mSplitAppDirs; 145 @UnsupportedAppUsage 146 private String[] mSplitResDirs; 147 private String[] mSplitClassLoaderNames; 148 149 @UnsupportedAppUsage 150 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers 151 = new ArrayMap<>(); 152 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers 153 = new ArrayMap<>(); 154 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 155 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices 156 = new ArrayMap<>(); 157 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices 158 = new ArrayMap<>(); 159 private AppComponentFactory mAppComponentFactory; 160 private final Object mLock = new Object(); 161 getApplication()162 Application getApplication() { 163 return mApplication; 164 } 165 166 /** 167 * Create information about a new .apk 168 * 169 * NOTE: This constructor is called with ActivityThread's lock held, 170 * so MUST NOT call back out to the activity manager. 171 */ LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, boolean includeCode, boolean registerPackage)172 public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo, 173 CompatibilityInfo compatInfo, ClassLoader baseLoader, 174 boolean securityViolation, boolean includeCode, boolean registerPackage) { 175 176 mActivityThread = activityThread; 177 setApplicationInfo(aInfo); 178 mPackageName = aInfo.packageName; 179 mBaseClassLoader = baseLoader; 180 mSecurityViolation = securityViolation; 181 mIncludeCode = includeCode; 182 mRegisterPackage = registerPackage; 183 mDisplayAdjustments.setCompatibilityInfo(compatInfo); 184 mAppComponentFactory = createAppFactory(mApplicationInfo, mBaseClassLoader); 185 } 186 adjustNativeLibraryPaths(ApplicationInfo info)187 private static ApplicationInfo adjustNativeLibraryPaths(ApplicationInfo info) { 188 // If we're dealing with a multi-arch application that has both 189 // 32 and 64 bit shared libraries, we might need to choose the secondary 190 // depending on what the current runtime's instruction set is. 191 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) { 192 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet(); 193 194 // Get the instruction set that the libraries of secondary Abi is supported. 195 // In presence of a native bridge this might be different than the one secondary Abi used. 196 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi); 197 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa); 198 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa; 199 200 // If the runtimeIsa is the same as the primary isa, then we do nothing. 201 // Everything will be set up correctly because info.nativeLibraryDir will 202 // correspond to the right ISA. 203 if (runtimeIsa.equals(secondaryIsa)) { 204 final ApplicationInfo modified = new ApplicationInfo(info); 205 modified.nativeLibraryDir = modified.secondaryNativeLibraryDir; 206 modified.primaryCpuAbi = modified.secondaryCpuAbi; 207 return modified; 208 } 209 } 210 211 return info; 212 } 213 214 /** 215 * Create information about the system package. 216 * Must call {@link #installSystemApplicationInfo} later. 217 */ LoadedApk(ActivityThread activityThread)218 LoadedApk(ActivityThread activityThread) { 219 mActivityThread = activityThread; 220 mApplicationInfo = new ApplicationInfo(); 221 mApplicationInfo.packageName = "android"; 222 mPackageName = "android"; 223 mAppDir = null; 224 mResDir = null; 225 mSplitAppDirs = null; 226 mSplitResDirs = null; 227 mSplitClassLoaderNames = null; 228 mLegacyOverlayDirs = null; 229 mOverlayPaths = null; 230 mDataDir = null; 231 mDataDirFile = null; 232 mDeviceProtectedDataDirFile = null; 233 mCredentialProtectedDataDirFile = null; 234 mLibDir = null; 235 mBaseClassLoader = null; 236 mSecurityViolation = false; 237 mIncludeCode = true; 238 mRegisterPackage = false; 239 mResources = Resources.getSystem(); 240 mDefaultClassLoader = ClassLoader.getSystemClassLoader(); 241 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader); 242 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader, 243 new ApplicationInfo(mApplicationInfo)); 244 } 245 246 /** 247 * Sets application info about the system package. 248 */ installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader)249 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { 250 assert info.packageName.equals("android"); 251 mApplicationInfo = info; 252 mDefaultClassLoader = classLoader; 253 mAppComponentFactory = createAppFactory(info, mDefaultClassLoader); 254 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader, 255 new ApplicationInfo(mApplicationInfo)); 256 } 257 createAppFactory(ApplicationInfo appInfo, ClassLoader cl)258 private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl) { 259 if (mIncludeCode && appInfo.appComponentFactory != null && cl != null) { 260 try { 261 return (AppComponentFactory) 262 cl.loadClass(appInfo.appComponentFactory).newInstance(); 263 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { 264 Slog.e(TAG, "Unable to instantiate appComponentFactory", e); 265 } 266 } 267 return AppComponentFactory.DEFAULT; 268 } 269 getAppFactory()270 public AppComponentFactory getAppFactory() { 271 return mAppComponentFactory; 272 } 273 274 @UnsupportedAppUsage getPackageName()275 public String getPackageName() { 276 return mPackageName; 277 } 278 279 @UnsupportedAppUsage getApplicationInfo()280 public ApplicationInfo getApplicationInfo() { 281 return mApplicationInfo; 282 } 283 getTargetSdkVersion()284 public int getTargetSdkVersion() { 285 return mApplicationInfo.targetSdkVersion; 286 } 287 isSecurityViolation()288 public boolean isSecurityViolation() { 289 return mSecurityViolation; 290 } 291 292 @UnsupportedAppUsage(trackingBug = 172409979) getCompatibilityInfo()293 public CompatibilityInfo getCompatibilityInfo() { 294 return mDisplayAdjustments.getCompatibilityInfo(); 295 } 296 setCompatibilityInfo(CompatibilityInfo compatInfo)297 public void setCompatibilityInfo(CompatibilityInfo compatInfo) { 298 mDisplayAdjustments.setCompatibilityInfo(compatInfo); 299 } 300 301 /** 302 * Gets the array of shared libraries that are listed as 303 * used by the given package. 304 * 305 * @param packageName the name of the package (note: not its 306 * file name) 307 * @return null-ok; the array of shared libraries, each one 308 * a fully-qualified path 309 */ getLibrariesFor(String packageName)310 private static String[] getLibrariesFor(String packageName) { 311 ApplicationInfo ai = null; 312 try { 313 ai = ActivityThread.getPackageManager().getApplicationInfo(packageName, 314 PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId()); 315 } catch (RemoteException e) { 316 throw e.rethrowFromSystemServer(); 317 } 318 319 if (ai == null) { 320 return null; 321 } 322 323 return ai.sharedLibraryFiles; 324 } 325 326 /** 327 * Update the ApplicationInfo for an app. If oldPaths is null, all the paths are considered 328 * new. 329 * @param aInfo The new ApplicationInfo to use for this LoadedApk 330 * @param oldPaths The code paths for the old ApplicationInfo object. null means no paths can 331 * be reused. 332 */ updateApplicationInfo(@onNull ApplicationInfo aInfo, @Nullable List<String> oldPaths)333 public void updateApplicationInfo(@NonNull ApplicationInfo aInfo, 334 @Nullable List<String> oldPaths) { 335 setApplicationInfo(aInfo); 336 337 final List<String> newPaths = new ArrayList<>(); 338 makePaths(mActivityThread, aInfo, newPaths); 339 final List<String> addedPaths = new ArrayList<>(newPaths.size()); 340 341 if (oldPaths != null) { 342 for (String path : newPaths) { 343 final String apkName = path.substring(path.lastIndexOf(File.separator)); 344 boolean match = false; 345 for (String oldPath : oldPaths) { 346 final String oldApkName = oldPath.substring(oldPath.lastIndexOf(File.separator)); 347 if (apkName.equals(oldApkName)) { 348 match = true; 349 break; 350 } 351 } 352 if (!match) { 353 addedPaths.add(path); 354 } 355 } 356 } else { 357 addedPaths.addAll(newPaths); 358 } 359 synchronized (mLock) { 360 createOrUpdateClassLoaderLocked(addedPaths); 361 if (mResources != null) { 362 final String[] splitPaths; 363 try { 364 splitPaths = getSplitPaths(null); 365 } catch (NameNotFoundException e) { 366 // This should NEVER fail. 367 throw new AssertionError("null split not found"); 368 } 369 370 mResources = ResourcesManager.getInstance().getResources(null, mResDir, 371 splitPaths, mLegacyOverlayDirs, mOverlayPaths, 372 mApplicationInfo.sharedLibraryFiles, null, null, getCompatibilityInfo(), 373 getClassLoader(), mApplication == null ? null 374 : mApplication.getResources().getLoaders()); 375 } 376 } 377 mAppComponentFactory = createAppFactory(aInfo, mDefaultClassLoader); 378 } 379 setApplicationInfo(ApplicationInfo aInfo)380 private void setApplicationInfo(ApplicationInfo aInfo) { 381 final int myUid = Process.myUid(); 382 aInfo = adjustNativeLibraryPaths(aInfo); 383 mApplicationInfo = aInfo; 384 mAppDir = aInfo.sourceDir; 385 mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir; 386 mLegacyOverlayDirs = aInfo.resourceDirs; 387 mOverlayPaths = aInfo.overlayPaths; 388 mDataDir = aInfo.dataDir; 389 mLibDir = aInfo.nativeLibraryDir; 390 mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir); 391 mDeviceProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceProtectedDataDir); 392 mCredentialProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialProtectedDataDir); 393 394 mSplitNames = aInfo.splitNames; 395 mSplitAppDirs = aInfo.splitSourceDirs; 396 mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs; 397 mSplitClassLoaderNames = aInfo.splitClassLoaderNames; 398 399 if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) { 400 mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies); 401 } 402 } 403 makePaths(ActivityThread activityThread, ApplicationInfo aInfo, List<String> outZipPaths)404 public static void makePaths(ActivityThread activityThread, 405 ApplicationInfo aInfo, 406 List<String> outZipPaths) { 407 makePaths(activityThread, false, aInfo, outZipPaths, null); 408 } 409 appendSharedLibrariesLibPathsIfNeeded( List<SharedLibraryInfo> sharedLibraries, ApplicationInfo aInfo, Set<String> outSeenPaths, List<String> outLibPaths)410 private static void appendSharedLibrariesLibPathsIfNeeded( 411 List<SharedLibraryInfo> sharedLibraries, ApplicationInfo aInfo, 412 Set<String> outSeenPaths, 413 List<String> outLibPaths) { 414 if (sharedLibraries == null) { 415 return; 416 } 417 for (SharedLibraryInfo lib : sharedLibraries) { 418 if (lib.isNative()) { 419 // Native shared lib doesn't contribute to the native lib search path. Its name is 420 // sent to libnativeloader and then the native shared lib is exported from the 421 // default linker namespace. 422 continue; 423 } 424 List<String> paths = lib.getAllCodePaths(); 425 outSeenPaths.addAll(paths); 426 for (String path : paths) { 427 appendApkLibPathIfNeeded(path, aInfo, outLibPaths); 428 } 429 appendSharedLibrariesLibPathsIfNeeded( 430 lib.getDependencies(), aInfo, outSeenPaths, outLibPaths); 431 } 432 } 433 makePaths(ActivityThread activityThread, boolean isBundledApp, ApplicationInfo aInfo, List<String> outZipPaths, List<String> outLibPaths)434 public static void makePaths(ActivityThread activityThread, 435 boolean isBundledApp, 436 ApplicationInfo aInfo, 437 List<String> outZipPaths, 438 List<String> outLibPaths) { 439 final String appDir = aInfo.sourceDir; 440 final String libDir = aInfo.nativeLibraryDir; 441 442 outZipPaths.clear(); 443 outZipPaths.add(appDir); 444 445 // Do not load all available splits if the app requested isolated split loading. 446 if (aInfo.splitSourceDirs != null && !aInfo.requestsIsolatedSplitLoading()) { 447 Collections.addAll(outZipPaths, aInfo.splitSourceDirs); 448 } 449 450 if (outLibPaths != null) { 451 outLibPaths.clear(); 452 } 453 454 /* 455 * The following is a bit of a hack to inject 456 * instrumentation into the system: If the app 457 * being started matches one of the instrumentation names, 458 * then we combine both the "instrumentation" and 459 * "instrumented" app into the path, along with the 460 * concatenation of both apps' shared library lists. 461 */ 462 463 String[] instrumentationLibs = null; 464 // activityThread will be null when called from the WebView zygote; just assume 465 // no instrumentation applies in this case. 466 if (activityThread != null) { 467 String instrumentationPackageName = activityThread.mInstrumentationPackageName; 468 String instrumentationAppDir = activityThread.mInstrumentationAppDir; 469 String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs; 470 String instrumentationLibDir = activityThread.mInstrumentationLibDir; 471 472 String instrumentedAppDir = activityThread.mInstrumentedAppDir; 473 String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs; 474 String instrumentedLibDir = activityThread.mInstrumentedLibDir; 475 476 if (appDir.equals(instrumentationAppDir) 477 || appDir.equals(instrumentedAppDir)) { 478 outZipPaths.clear(); 479 outZipPaths.add(instrumentationAppDir); 480 if (!instrumentationAppDir.equals(instrumentedAppDir)) { 481 outZipPaths.add(instrumentedAppDir); 482 } 483 484 // Only add splits if the app did not request isolated split loading. 485 if (!aInfo.requestsIsolatedSplitLoading()) { 486 if (instrumentationSplitAppDirs != null) { 487 Collections.addAll(outZipPaths, instrumentationSplitAppDirs); 488 } 489 490 if (!instrumentationAppDir.equals(instrumentedAppDir)) { 491 if (instrumentedSplitAppDirs != null) { 492 Collections.addAll(outZipPaths, instrumentedSplitAppDirs); 493 } 494 } 495 } 496 497 if (outLibPaths != null) { 498 outLibPaths.add(instrumentationLibDir); 499 if (!instrumentationLibDir.equals(instrumentedLibDir)) { 500 outLibPaths.add(instrumentedLibDir); 501 } 502 } 503 504 if (!instrumentedAppDir.equals(instrumentationAppDir)) { 505 instrumentationLibs = getLibrariesFor(instrumentationPackageName); 506 } 507 } 508 } 509 510 if (outLibPaths != null) { 511 if (outLibPaths.isEmpty()) { 512 outLibPaths.add(libDir); 513 } 514 515 // Add path to libraries in apk for current abi. Do this now because more entries 516 // will be added to zipPaths that shouldn't be part of the library path. 517 if (aInfo.primaryCpuAbi != null) { 518 // Add fake libs into the library search path if we target prior to N. 519 if (aInfo.targetSdkVersion < Build.VERSION_CODES.N) { 520 outLibPaths.add("/system/fake-libs" + 521 (VMRuntime.is64BitAbi(aInfo.primaryCpuAbi) ? "64" : "")); 522 } 523 for (String apk : outZipPaths) { 524 outLibPaths.add(apk + "!/lib/" + aInfo.primaryCpuAbi); 525 } 526 } 527 528 if (isBundledApp) { 529 // Add path to system libraries to libPaths; 530 // Access to system libs should be limited 531 // to bundled applications; this is why updated 532 // system apps are not included. 533 outLibPaths.add(System.getProperty("java.library.path")); 534 } 535 } 536 537 // Add the shared libraries native paths. The dex files in shared libraries will 538 // be resolved through shared library loaders, which are setup later. 539 Set<String> outSeenPaths = new LinkedHashSet<>(); 540 appendSharedLibrariesLibPathsIfNeeded( 541 aInfo.sharedLibraryInfos, aInfo, outSeenPaths, outLibPaths); 542 543 // ApplicationInfo.sharedLibraryFiles is a public API, so anyone can change it. 544 // We prepend shared libraries that the package manager hasn't seen, maintaining their 545 // original order where possible. 546 if (aInfo.sharedLibraryFiles != null) { 547 int index = 0; 548 for (String lib : aInfo.sharedLibraryFiles) { 549 // sharedLibraryFiles might contain native shared libraries that are not APK paths. 550 if (!lib.endsWith(".apk")) { 551 continue; 552 } 553 if (!outSeenPaths.contains(lib) && !outZipPaths.contains(lib)) { 554 outZipPaths.add(index, lib); 555 index++; 556 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths); 557 } 558 } 559 } 560 561 if (instrumentationLibs != null) { 562 for (String lib : instrumentationLibs) { 563 if (!outZipPaths.contains(lib)) { 564 outZipPaths.add(0, lib); 565 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths); 566 } 567 } 568 } 569 } 570 571 /** 572 * This method appends a path to the appropriate native library folder of a 573 * library if this library is hosted in an APK. This allows support for native 574 * shared libraries. The library API is determined based on the application 575 * ABI. 576 * 577 * @param path Path to the library. 578 * @param applicationInfo The application depending on the library. 579 * @param outLibPaths List to which to add the native lib path if needed. 580 */ appendApkLibPathIfNeeded(@onNull String path, @NonNull ApplicationInfo applicationInfo, @Nullable List<String> outLibPaths)581 private static void appendApkLibPathIfNeeded(@NonNull String path, 582 @NonNull ApplicationInfo applicationInfo, @Nullable List<String> outLibPaths) { 583 // Looking at the suffix is a little hacky but a safe and simple solution. 584 // We will be revisiting code in the next release and clean this up. 585 if (outLibPaths != null && applicationInfo.primaryCpuAbi != null && path.endsWith(".apk")) { 586 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O) { 587 outLibPaths.add(path + "!/lib/" + applicationInfo.primaryCpuAbi); 588 } 589 } 590 } 591 592 /* 593 * All indices received by the super class should be shifted by 1 when accessing mSplitNames, 594 * etc. The super class assumes the base APK is index 0, while the PackageManager APIs don't 595 * include the base APK in the list of splits. 596 */ 597 private class SplitDependencyLoaderImpl extends SplitDependencyLoader<NameNotFoundException> { 598 @GuardedBy("mLock") 599 private final String[][] mCachedResourcePaths; 600 @GuardedBy("mLock") 601 private final ClassLoader[] mCachedClassLoaders; 602 SplitDependencyLoaderImpl(@onNull SparseArray<int[]> dependencies)603 SplitDependencyLoaderImpl(@NonNull SparseArray<int[]> dependencies) { 604 super(dependencies); 605 mCachedResourcePaths = new String[mSplitNames.length + 1][]; 606 mCachedClassLoaders = new ClassLoader[mSplitNames.length + 1]; 607 } 608 609 @Override isSplitCached(int splitIdx)610 protected boolean isSplitCached(int splitIdx) { 611 synchronized (mLock) { 612 return mCachedClassLoaders[splitIdx] != null; 613 } 614 } 615 616 @Override constructSplit(int splitIdx, @NonNull int[] configSplitIndices, int parentSplitIdx)617 protected void constructSplit(int splitIdx, @NonNull int[] configSplitIndices, 618 int parentSplitIdx) throws NameNotFoundException { 619 synchronized (mLock) { 620 final ArrayList<String> splitPaths = new ArrayList<>(); 621 if (splitIdx == 0) { 622 createOrUpdateClassLoaderLocked(null); 623 mCachedClassLoaders[0] = mClassLoader; 624 625 // Never add the base resources here, they always get added no matter what. 626 for (int configSplitIdx : configSplitIndices) { 627 splitPaths.add(mSplitResDirs[configSplitIdx - 1]); 628 } 629 mCachedResourcePaths[0] = splitPaths.toArray(new String[splitPaths.size()]); 630 return; 631 } 632 633 // Since we handled the special base case above, parentSplitIdx is always valid. 634 final ClassLoader parent = mCachedClassLoaders[parentSplitIdx]; 635 mCachedClassLoaders[splitIdx] = ApplicationLoaders.getDefault().getClassLoader( 636 mSplitAppDirs[splitIdx - 1], getTargetSdkVersion(), false, null, 637 null, parent, mSplitClassLoaderNames[splitIdx - 1]); 638 639 Collections.addAll(splitPaths, mCachedResourcePaths[parentSplitIdx]); 640 splitPaths.add(mSplitResDirs[splitIdx - 1]); 641 for (int configSplitIdx : configSplitIndices) { 642 splitPaths.add(mSplitResDirs[configSplitIdx - 1]); 643 } 644 mCachedResourcePaths[splitIdx] = splitPaths.toArray(new String[splitPaths.size()]); 645 } 646 } 647 ensureSplitLoaded(String splitName)648 private int ensureSplitLoaded(String splitName) throws NameNotFoundException { 649 int idx = 0; 650 if (splitName != null) { 651 idx = Arrays.binarySearch(mSplitNames, splitName); 652 if (idx < 0) { 653 throw new PackageManager.NameNotFoundException( 654 "Split name '" + splitName + "' is not installed"); 655 } 656 idx += 1; 657 } 658 loadDependenciesForSplit(idx); 659 return idx; 660 } 661 getClassLoaderForSplit(String splitName)662 ClassLoader getClassLoaderForSplit(String splitName) throws NameNotFoundException { 663 final int idx = ensureSplitLoaded(splitName); 664 synchronized (mLock) { 665 return mCachedClassLoaders[idx]; 666 } 667 } 668 getSplitPathsForSplit(String splitName)669 String[] getSplitPathsForSplit(String splitName) throws NameNotFoundException { 670 final int idx = ensureSplitLoaded(splitName); 671 synchronized (mLock) { 672 return mCachedResourcePaths[idx]; 673 } 674 } 675 } 676 677 private SplitDependencyLoaderImpl mSplitLoader; 678 getSplitClassLoader(String splitName)679 ClassLoader getSplitClassLoader(String splitName) throws NameNotFoundException { 680 if (mSplitLoader == null) { 681 return mClassLoader; 682 } 683 return mSplitLoader.getClassLoaderForSplit(splitName); 684 } 685 getSplitPaths(String splitName)686 String[] getSplitPaths(String splitName) throws NameNotFoundException { 687 if (mSplitLoader == null) { 688 return mSplitResDirs; 689 } 690 return mSplitLoader.getSplitPathsForSplit(splitName); 691 } 692 693 /** 694 * Create a class loader for the {@code sharedLibrary}. Shared libraries are canonicalized, 695 * so if we already created a class loader with that shared library, we return it. 696 * 697 * Implementation notes: the canonicalization of shared libraries is something dex2oat 698 * also does. 699 */ createSharedLibraryLoader(SharedLibraryInfo sharedLibrary, boolean isBundledApp, String librarySearchPath, String libraryPermittedPath)700 ClassLoader createSharedLibraryLoader(SharedLibraryInfo sharedLibrary, 701 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) { 702 List<String> paths = sharedLibrary.getAllCodePaths(); 703 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders( 704 sharedLibrary.getDependencies(), isBundledApp, librarySearchPath, 705 libraryPermittedPath); 706 final String jars = (paths.size() == 1) ? paths.get(0) : 707 TextUtils.join(File.pathSeparator, paths); 708 709 // Shared libraries get a null parent: this has the side effect of having canonicalized 710 // shared libraries using ApplicationLoaders cache, which is the behavior we want. 711 return ApplicationLoaders.getDefault().getSharedLibraryClassLoaderWithSharedLibraries(jars, 712 mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath, 713 libraryPermittedPath, /* parent */ null, 714 /* classLoaderName */ null, sharedLibraries); 715 } 716 createSharedLibrariesLoaders(List<SharedLibraryInfo> sharedLibraries, boolean isBundledApp, String librarySearchPath, String libraryPermittedPath)717 private List<ClassLoader> createSharedLibrariesLoaders(List<SharedLibraryInfo> sharedLibraries, 718 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) { 719 if (sharedLibraries == null) { 720 return null; 721 } 722 List<ClassLoader> loaders = new ArrayList<>(); 723 for (SharedLibraryInfo info : sharedLibraries) { 724 if (info.isNative()) { 725 // Native shared lib doesn't contribute to the native lib search path. Its name is 726 // sent to libnativeloader and then the native shared lib is exported from the 727 // default linker namespace. 728 continue; 729 } 730 loaders.add(createSharedLibraryLoader( 731 info, isBundledApp, librarySearchPath, libraryPermittedPath)); 732 } 733 return loaders; 734 } 735 allowThreadDiskReads()736 private StrictMode.ThreadPolicy allowThreadDiskReads() { 737 if (mActivityThread == null) { 738 // When LoadedApk is used without an ActivityThread (usually in a 739 // zygote context), don't call into StrictMode, as it initializes 740 // the binder subsystem, which we don't want. 741 return null; 742 } 743 744 return StrictMode.allowThreadDiskReads(); 745 } 746 setThreadPolicy(StrictMode.ThreadPolicy policy)747 private void setThreadPolicy(StrictMode.ThreadPolicy policy) { 748 if (mActivityThread != null && policy != null) { 749 StrictMode.setThreadPolicy(policy); 750 } 751 } 752 allowVmViolations()753 private StrictMode.VmPolicy allowVmViolations() { 754 if (mActivityThread == null) { 755 // When LoadedApk is used without an ActivityThread (usually in a 756 // zygote context), don't call into StrictMode, as it initializes 757 // the binder subsystem, which we don't want. 758 return null; 759 } 760 761 return StrictMode.allowVmViolations(); 762 } 763 setVmPolicy(StrictMode.VmPolicy policy)764 private void setVmPolicy(StrictMode.VmPolicy policy) { 765 if (mActivityThread != null && policy != null) { 766 StrictMode.setVmPolicy(policy); 767 } 768 } 769 770 @GuardedBy("mLock") createOrUpdateClassLoaderLocked(List<String> addedPaths)771 private void createOrUpdateClassLoaderLocked(List<String> addedPaths) { 772 if (mPackageName.equals("android")) { 773 // Note: This branch is taken for system server and we don't need to setup 774 // jit profiling support. 775 if (mClassLoader != null) { 776 // nothing to update 777 return; 778 } 779 780 if (mBaseClassLoader != null) { 781 mDefaultClassLoader = mBaseClassLoader; 782 } else { 783 mDefaultClassLoader = ClassLoader.getSystemClassLoader(); 784 } 785 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader); 786 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader, 787 new ApplicationInfo(mApplicationInfo)); 788 return; 789 } 790 791 // Avoid the binder call when the package is the current application package. 792 // The activity manager will perform ensure that dexopt is performed before 793 // spinning up the process. Similarly, don't call into binder when we don't 794 // have an ActivityThread object. 795 if (mActivityThread != null 796 && !Objects.equals(mPackageName, ActivityThread.currentPackageName()) 797 && mIncludeCode) { 798 try { 799 ActivityThread.getPackageManager().notifyPackageUse(mPackageName, 800 PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE); 801 } catch (RemoteException re) { 802 throw re.rethrowFromSystemServer(); 803 } 804 } 805 806 if (mRegisterPackage) { 807 try { 808 ActivityManager.getService().addPackageDependency(mPackageName); 809 } catch (RemoteException e) { 810 throw e.rethrowFromSystemServer(); 811 } 812 } 813 814 // Lists for the elements of zip/code and native libraries. 815 // 816 // Both lists are usually not empty. We expect on average one APK for the zip component, 817 // but shared libraries and splits are not uncommon. We expect at least three elements 818 // for native libraries (app-based, system, vendor). As such, give both some breathing 819 // space and initialize to a small value (instead of incurring growth code). 820 final List<String> zipPaths = new ArrayList<>(10); 821 final List<String> libPaths = new ArrayList<>(10); 822 823 boolean isBundledApp = mApplicationInfo.isSystemApp() 824 && !mApplicationInfo.isUpdatedSystemApp(); 825 826 // Vendor apks are treated as bundled only when /vendor/lib is in the default search 827 // paths. If not, they are treated as unbundled; access to system libs is limited. 828 // Having /vendor/lib in the default search paths means that all system processes 829 // are allowed to use any vendor library, which in turn means that system is dependent 830 // on vendor partition. In the contrary, not having /vendor/lib in the default search 831 // paths mean that the two partitions are separated and thus we can treat vendor apks 832 // as unbundled. 833 final String defaultSearchPaths = System.getProperty("java.library.path"); 834 final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib"); 835 if (mApplicationInfo.getCodePath() != null 836 && mApplicationInfo.isVendor() && treatVendorApkAsUnbundled) { 837 isBundledApp = false; 838 } 839 840 // Similar to vendor apks, we should add /product/lib for apks from product partition 841 // when product apps are marked as unbundled. We cannot use the same way from vendor 842 // to check if lib path exists because there is possibility that /product/lib would not 843 // exist from legacy device while product apks are bundled. To make this clear, we use 844 // "ro.product.vndk.version" property. If the property is defined, we regard all product 845 // apks as unbundled. 846 if (mApplicationInfo.getCodePath() != null 847 && mApplicationInfo.isProduct() 848 && VndkProperties.product_vndk_version().isPresent()) { 849 isBundledApp = false; 850 } 851 852 makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths); 853 854 // Including an inaccessible dir in libraryPermittedPath would cause SELinux denials 855 // when the loader attempts to canonicalise the path. so we don't. 856 String libraryPermittedPath = canAccessDataDir() ? mDataDir : ""; 857 858 if (isBundledApp) { 859 // For bundled apps, add the base directory of the app (e.g., 860 // /system/app/Foo/) to the permitted paths so that it can load libraries 861 // embedded in module apks under the directory. For now, GmsCore is relying 862 // on this, but this isn't specific to the app. Also note that, we don't 863 // need to do this for unbundled apps as entire /data is already set to 864 // the permitted paths for them. 865 libraryPermittedPath += File.pathSeparator 866 + Paths.get(getAppDir()).getParent().toString(); 867 868 // This is necessary to grant bundled apps access to 869 // libraries located in subdirectories of /system/lib 870 libraryPermittedPath += File.pathSeparator + defaultSearchPaths; 871 } 872 873 final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths); 874 875 if (mActivityThread != null) { 876 final String gpuDebugApp = mActivityThread.getStringCoreSetting( 877 Settings.Global.GPU_DEBUG_APP, ""); 878 if (!gpuDebugApp.isEmpty() && mPackageName.equals(gpuDebugApp)) { 879 880 // The current application is used to debug, attempt to get the debug layers. 881 try { 882 // Get the ApplicationInfo from PackageManager so that metadata fields present. 883 final ApplicationInfo ai = ActivityThread.getPackageManager() 884 .getApplicationInfo(mPackageName, PackageManager.GET_META_DATA, 885 UserHandle.myUserId()); 886 final String debugLayerPath = GraphicsEnvironment.getInstance() 887 .getDebugLayerPathsFromSettings(mActivityThread.getCoreSettings(), 888 ActivityThread.getPackageManager(), mPackageName, ai); 889 if (debugLayerPath != null) { 890 libraryPermittedPath += File.pathSeparator + debugLayerPath; 891 } 892 } catch (RemoteException e) { 893 // Unlikely to fail for applications, but in case of failure, something is wrong 894 // inside the system server, hence just skip. 895 Slog.e(ActivityThread.TAG, 896 "RemoteException when fetching debug layer paths for: " + mPackageName); 897 } 898 } 899 } 900 901 // If we're not asked to include code, we construct a classloader that has 902 // no code path included. We still need to set up the library search paths 903 // and permitted path because NativeActivity relies on it (it attempts to 904 // call System.loadLibrary() on a classloader from a LoadedApk with 905 // mIncludeCode == false). 906 if (!mIncludeCode) { 907 if (mDefaultClassLoader == null) { 908 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads(); 909 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader( 910 "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp, 911 librarySearchPath, libraryPermittedPath, mBaseClassLoader, 912 null /* classLoaderName */); 913 setThreadPolicy(oldPolicy); 914 mAppComponentFactory = AppComponentFactory.DEFAULT; 915 } 916 917 if (mClassLoader == null) { 918 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader, 919 new ApplicationInfo(mApplicationInfo)); 920 } 921 922 return; 923 } 924 925 /* 926 * With all the combination done (if necessary, actually create the java class 927 * loader and set up JIT profiling support if necessary. 928 * 929 * In many cases this is a single APK, so try to avoid the StringBuilder in TextUtils. 930 */ 931 final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) : 932 TextUtils.join(File.pathSeparator, zipPaths); 933 934 if (DEBUG) Slog.v(ActivityThread.TAG, "Class path: " + zip + 935 ", JNI path: " + librarySearchPath); 936 937 boolean registerAppInfoToArt = false; 938 if (mDefaultClassLoader == null) { 939 // Setup the dex reporter to notify package manager 940 // of any relevant dex loads. The idle maintenance job will use the information 941 // reported to optimize the loaded dex files. 942 // Note that we only need one global reporter per app. 943 // Make sure we do this before creating the main app classloader for the first time 944 // so that we can capture the complete application startup. 945 // 946 // We should not do this in a zygote context (where mActivityThread will be null), 947 // thus we'll guard against it. 948 // Also, the system server reporter (SystemServerDexLoadReporter) is already registered 949 // when system server starts, so we don't need to do it here again. 950 if (mActivityThread != null && !ActivityThread.isSystem()) { 951 BaseDexClassLoader.setReporter(DexLoadReporter.getInstance()); 952 } 953 954 // Temporarily disable logging of disk reads on the Looper thread 955 // as this is early and necessary. 956 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads(); 957 958 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders( 959 mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath, 960 libraryPermittedPath); 961 962 List<String> nativeSharedLibraries = new ArrayList<>(); 963 if (mApplicationInfo.sharedLibraryInfos != null) { 964 for (SharedLibraryInfo info : mApplicationInfo.sharedLibraryInfos) { 965 if (info.isNative()) { 966 nativeSharedLibraries.add(info.getName()); 967 } 968 } 969 } 970 971 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries( 972 zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath, 973 libraryPermittedPath, mBaseClassLoader, 974 mApplicationInfo.classLoaderName, sharedLibraries, nativeSharedLibraries); 975 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader); 976 977 setThreadPolicy(oldPolicy); 978 // Setup the class loader paths for profiling. 979 registerAppInfoToArt = true; 980 } 981 982 if (!libPaths.isEmpty()) { 983 // Temporarily disable logging of disk reads on the Looper thread as this is necessary 984 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads(); 985 try { 986 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, libPaths); 987 } finally { 988 setThreadPolicy(oldPolicy); 989 } 990 } 991 992 if (addedPaths != null && addedPaths.size() > 0) { 993 final String add = TextUtils.join(File.pathSeparator, addedPaths); 994 ApplicationLoaders.getDefault().addPath(mDefaultClassLoader, add); 995 // Setup the new code paths for profiling. 996 registerAppInfoToArt = true; 997 } 998 999 // Setup jit profile support. 1000 // 1001 // It is ok to call this multiple times if the application gets updated with new splits. 1002 // The runtime only keeps track of unique code paths and can handle re-registration of 1003 // the same code path. There's no need to pass `addedPaths` since any new code paths 1004 // are already in `mApplicationInfo`. 1005 // 1006 // It is NOT ok to call this function from the system_server (for any of the packages it 1007 // loads code from) so we explicitly disallow it there. 1008 // 1009 // It is not ok to call this in a zygote context where mActivityThread is null. 1010 if (registerAppInfoToArt && !ActivityThread.isSystem() && mActivityThread != null) { 1011 registerAppInfoToArt(); 1012 } 1013 1014 // Call AppComponentFactory to select/create the main class loader of this app. 1015 // Since this may call code in the app, mDefaultClassLoader must be fully set up 1016 // before invoking the factory. 1017 // Invoke with a copy of ApplicationInfo to protect against the app changing it. 1018 if (mClassLoader == null) { 1019 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader, 1020 new ApplicationInfo(mApplicationInfo)); 1021 } 1022 } 1023 1024 /** 1025 * Return whether we can access the package's private data directory in order to be able to 1026 * load code from it. 1027 */ canAccessDataDir()1028 private boolean canAccessDataDir() { 1029 // In a zygote context where mActivityThread is null we can't access the app data dir. 1030 if (mActivityThread == null) { 1031 return false; 1032 } 1033 1034 // A package can access its own data directory (the common case, so short-circuit it). 1035 if (Objects.equals(mPackageName, ActivityThread.currentPackageName())) { 1036 return true; 1037 } 1038 1039 // Temporarily disable logging of disk reads on the Looper thread as this is necessary - 1040 // and the loader will access the directory anyway if we don't check it. 1041 StrictMode.ThreadPolicy oldThreadPolicy = allowThreadDiskReads(); 1042 1043 // Also disable logging of access to /data/user before CE storage is unlocked. The check 1044 // below will return false (because the directory name we pass will not match the 1045 // encrypted one), but that's correct. 1046 StrictMode.VmPolicy oldVmPolicy = allowVmViolations(); 1047 1048 try { 1049 // We are constructing a classloader for a different package. It is likely, 1050 // but not certain, that we can't acccess its app data dir - so check. 1051 return new File(mDataDir).canExecute(); 1052 } finally { 1053 setThreadPolicy(oldThreadPolicy); 1054 setVmPolicy(oldVmPolicy); 1055 } 1056 } 1057 1058 @UnsupportedAppUsage getClassLoader()1059 public ClassLoader getClassLoader() { 1060 synchronized (mLock) { 1061 if (mClassLoader == null) { 1062 createOrUpdateClassLoaderLocked(null /*addedPaths*/); 1063 } 1064 return mClassLoader; 1065 } 1066 } 1067 registerAppInfoToArt()1068 private void registerAppInfoToArt() { 1069 // Only set up profile support if the loaded apk has the same uid as the 1070 // current process. 1071 // Currently, we do not support profiling across different apps. 1072 // (e.g. application's uid might be different when the code is 1073 // loaded by another app via createApplicationContext) 1074 if (mApplicationInfo.uid != Process.myUid()) { 1075 return; 1076 } 1077 1078 final List<String> codePaths = new ArrayList<>(); 1079 if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) { 1080 codePaths.add(mApplicationInfo.sourceDir); 1081 } 1082 if (mApplicationInfo.splitSourceDirs != null) { 1083 Collections.addAll(codePaths, mApplicationInfo.splitSourceDirs); 1084 } 1085 1086 if (codePaths.isEmpty()) { 1087 // If there are no code paths there's no need to setup a profile file and register with 1088 // the runtime, 1089 return; 1090 } 1091 1092 for (int i = codePaths.size() - 1; i >= 0; i--) { 1093 String splitName = i == 0 ? null : mApplicationInfo.splitNames[i - 1]; 1094 String curProfileFile = ArtManager.getCurrentProfilePath( 1095 mPackageName, UserHandle.myUserId(), splitName); 1096 String refProfileFile = ArtManager.getReferenceProfilePath( 1097 mPackageName, UserHandle.myUserId(), splitName); 1098 int codePathType = codePaths.get(i).equals(mApplicationInfo.sourceDir) 1099 ? VMRuntime.CODE_PATH_TYPE_PRIMARY_APK 1100 : VMRuntime.CODE_PATH_TYPE_SPLIT_APK; 1101 VMRuntime.registerAppInfo( 1102 mPackageName, 1103 curProfileFile, 1104 refProfileFile, 1105 new String[] {codePaths.get(i)}, 1106 codePathType); 1107 } 1108 1109 // Register the app data directory with the reporter. It will 1110 // help deciding whether or not a dex file is the primary apk or a 1111 // secondary dex. 1112 DexLoadReporter.getInstance().registerAppDataDir(mPackageName, mDataDir); 1113 } 1114 1115 /** 1116 * Setup value for Thread.getContextClassLoader(). If the 1117 * package will not run in in a VM with other packages, we set 1118 * the Java context ClassLoader to the 1119 * PackageInfo.getClassLoader value. However, if this VM can 1120 * contain multiple packages, we intead set the Java context 1121 * ClassLoader to a proxy that will warn about the use of Java 1122 * context ClassLoaders and then fall through to use the 1123 * system ClassLoader. 1124 * 1125 * <p> Note that this is similar to but not the same as the 1126 * android.content.Context.getClassLoader(). While both 1127 * context class loaders are typically set to the 1128 * PathClassLoader used to load the package archive in the 1129 * single application per VM case, a single Android process 1130 * may contain several Contexts executing on one thread with 1131 * their own logical ClassLoaders while the Java context 1132 * ClassLoader is a thread local. This is why in the case when 1133 * we have multiple packages per VM we do not set the Java 1134 * context ClassLoader to an arbitrary but instead warn the 1135 * user to set their own if we detect that they are using a 1136 * Java library that expects it to be set. 1137 */ initializeJavaContextClassLoader()1138 private void initializeJavaContextClassLoader() { 1139 IPackageManager pm = ActivityThread.getPackageManager(); 1140 android.content.pm.PackageInfo pi = 1141 PackageManager.getPackageInfoAsUserCached( 1142 mPackageName, 1143 PackageManager.MATCH_DEBUG_TRIAGED_MISSING, 1144 UserHandle.myUserId()); 1145 if (pi == null) { 1146 throw new IllegalStateException("Unable to get package info for " 1147 + mPackageName + "; is package not installed?"); 1148 } 1149 /* 1150 * Two possible indications that this package could be 1151 * sharing its virtual machine with other packages: 1152 * 1153 * 1.) the sharedUserId attribute is set in the manifest, 1154 * indicating a request to share a VM with other 1155 * packages with the same sharedUserId. 1156 * 1157 * 2.) the application element of the manifest has an 1158 * attribute specifying a non-default process name, 1159 * indicating the desire to run in another packages VM. 1160 */ 1161 boolean sharedUserIdSet = (pi.sharedUserId != null); 1162 boolean processNameNotDefault = 1163 (pi.applicationInfo != null && 1164 !mPackageName.equals(pi.applicationInfo.processName)); 1165 boolean sharable = (sharedUserIdSet || processNameNotDefault); 1166 ClassLoader contextClassLoader = 1167 (sharable) 1168 ? new WarningContextClassLoader() 1169 : mClassLoader; 1170 Thread.currentThread().setContextClassLoader(contextClassLoader); 1171 } 1172 1173 private static class WarningContextClassLoader extends ClassLoader { 1174 1175 private static boolean warned = false; 1176 warn(String methodName)1177 private void warn(String methodName) { 1178 if (warned) { 1179 return; 1180 } 1181 warned = true; 1182 Thread.currentThread().setContextClassLoader(getParent()); 1183 Slog.w(ActivityThread.TAG, "ClassLoader." + methodName + ": " + 1184 "The class loader returned by " + 1185 "Thread.getContextClassLoader() may fail for processes " + 1186 "that host multiple applications. You should explicitly " + 1187 "specify a context class loader. For example: " + 1188 "Thread.setContextClassLoader(getClass().getClassLoader());"); 1189 } 1190 getResource(String resName)1191 @Override public URL getResource(String resName) { 1192 warn("getResource"); 1193 return getParent().getResource(resName); 1194 } 1195 getResources(String resName)1196 @Override public Enumeration<URL> getResources(String resName) throws IOException { 1197 warn("getResources"); 1198 return getParent().getResources(resName); 1199 } 1200 getResourceAsStream(String resName)1201 @Override public InputStream getResourceAsStream(String resName) { 1202 warn("getResourceAsStream"); 1203 return getParent().getResourceAsStream(resName); 1204 } 1205 loadClass(String className)1206 @Override public Class<?> loadClass(String className) throws ClassNotFoundException { 1207 warn("loadClass"); 1208 return getParent().loadClass(className); 1209 } 1210 setClassAssertionStatus(String cname, boolean enable)1211 @Override public void setClassAssertionStatus(String cname, boolean enable) { 1212 warn("setClassAssertionStatus"); 1213 getParent().setClassAssertionStatus(cname, enable); 1214 } 1215 setPackageAssertionStatus(String pname, boolean enable)1216 @Override public void setPackageAssertionStatus(String pname, boolean enable) { 1217 warn("setPackageAssertionStatus"); 1218 getParent().setPackageAssertionStatus(pname, enable); 1219 } 1220 setDefaultAssertionStatus(boolean enable)1221 @Override public void setDefaultAssertionStatus(boolean enable) { 1222 warn("setDefaultAssertionStatus"); 1223 getParent().setDefaultAssertionStatus(enable); 1224 } 1225 clearAssertionStatus()1226 @Override public void clearAssertionStatus() { 1227 warn("clearAssertionStatus"); 1228 getParent().clearAssertionStatus(); 1229 } 1230 } 1231 1232 @UnsupportedAppUsage getAppDir()1233 public String getAppDir() { 1234 return mAppDir; 1235 } 1236 getLibDir()1237 public String getLibDir() { 1238 return mLibDir; 1239 } 1240 1241 @UnsupportedAppUsage getResDir()1242 public String getResDir() { 1243 return mResDir; 1244 } 1245 getSplitAppDirs()1246 public String[] getSplitAppDirs() { 1247 return mSplitAppDirs; 1248 } 1249 1250 @UnsupportedAppUsage getSplitResDirs()1251 public String[] getSplitResDirs() { 1252 return mSplitResDirs; 1253 } 1254 1255 /** 1256 * Corresponds to {@link ApplicationInfo#resourceDirs}. 1257 */ 1258 @UnsupportedAppUsage getOverlayDirs()1259 public String[] getOverlayDirs() { 1260 return mLegacyOverlayDirs; 1261 } 1262 1263 /** 1264 * Corresponds to {@link ApplicationInfo#overlayPaths}. 1265 */ getOverlayPaths()1266 public String[] getOverlayPaths() { 1267 return mOverlayPaths; 1268 } 1269 getDataDir()1270 public String getDataDir() { 1271 return mDataDir; 1272 } 1273 1274 @UnsupportedAppUsage getDataDirFile()1275 public File getDataDirFile() { 1276 return mDataDirFile; 1277 } 1278 getDeviceProtectedDataDirFile()1279 public File getDeviceProtectedDataDirFile() { 1280 return mDeviceProtectedDataDirFile; 1281 } 1282 getCredentialProtectedDataDirFile()1283 public File getCredentialProtectedDataDirFile() { 1284 return mCredentialProtectedDataDirFile; 1285 } 1286 1287 @UnsupportedAppUsage getAssets()1288 public AssetManager getAssets() { 1289 return getResources().getAssets(); 1290 } 1291 1292 @UnsupportedAppUsage getResources()1293 public Resources getResources() { 1294 if (mResources == null) { 1295 final String[] splitPaths; 1296 try { 1297 splitPaths = getSplitPaths(null); 1298 } catch (NameNotFoundException e) { 1299 // This should never fail. 1300 throw new AssertionError("null split not found"); 1301 } 1302 1303 if (Process.myUid() == mApplicationInfo.uid) { 1304 ResourcesManager.getInstance().initializeApplicationPaths(mResDir, splitPaths); 1305 } 1306 1307 mResources = ResourcesManager.getInstance().getResources(null, mResDir, 1308 splitPaths, mLegacyOverlayDirs, mOverlayPaths, 1309 mApplicationInfo.sharedLibraryFiles, null, null, getCompatibilityInfo(), 1310 getClassLoader(), null); 1311 } 1312 return mResources; 1313 } 1314 1315 @UnsupportedAppUsage makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation)1316 public Application makeApplication(boolean forceDefaultAppClass, 1317 Instrumentation instrumentation) { 1318 if (mApplication != null) { 1319 return mApplication; 1320 } 1321 1322 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication"); 1323 1324 Application app = null; 1325 1326 String appClass = mApplicationInfo.className; 1327 if (forceDefaultAppClass || (appClass == null)) { 1328 appClass = "android.app.Application"; 1329 } 1330 1331 try { 1332 final java.lang.ClassLoader cl = getClassLoader(); 1333 if (!mPackageName.equals("android")) { 1334 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, 1335 "initializeJavaContextClassLoader"); 1336 initializeJavaContextClassLoader(); 1337 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1338 } 1339 1340 // Rewrite the R 'constants' for all library apks. 1341 SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers( 1342 false, false); 1343 for (int i = 0, n = packageIdentifiers.size(); i < n; i++) { 1344 final int id = packageIdentifiers.keyAt(i); 1345 if (id == 0x01 || id == 0x7f) { 1346 continue; 1347 } 1348 1349 rewriteRValues(cl, packageIdentifiers.valueAt(i), id); 1350 } 1351 1352 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); 1353 // The network security config needs to be aware of multiple 1354 // applications in the same process to handle discrepancies 1355 NetworkSecurityConfigProvider.handleNewApplication(appContext); 1356 app = mActivityThread.mInstrumentation.newApplication( 1357 cl, appClass, appContext); 1358 appContext.setOuterContext(app); 1359 } catch (Exception e) { 1360 if (!mActivityThread.mInstrumentation.onException(app, e)) { 1361 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1362 throw new RuntimeException( 1363 "Unable to instantiate application " + appClass 1364 + " package " + mPackageName + ": " + e.toString(), e); 1365 } 1366 } 1367 mActivityThread.mAllApplications.add(app); 1368 mApplication = app; 1369 1370 if (instrumentation != null) { 1371 try { 1372 instrumentation.callApplicationOnCreate(app); 1373 } catch (Exception e) { 1374 if (!instrumentation.onException(app, e)) { 1375 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1376 throw new RuntimeException( 1377 "Unable to create application " + app.getClass().getName() 1378 + ": " + e.toString(), e); 1379 } 1380 } 1381 } 1382 1383 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1384 1385 return app; 1386 } 1387 1388 @UnsupportedAppUsage rewriteRValues(ClassLoader cl, String packageName, int id)1389 private void rewriteRValues(ClassLoader cl, String packageName, int id) { 1390 final Class<?> rClazz; 1391 try { 1392 rClazz = cl.loadClass(packageName + ".R"); 1393 } catch (ClassNotFoundException e) { 1394 // This is not necessarily an error, as some packages do not ship with resources 1395 // (or they do not need rewriting). 1396 Log.i(TAG, "No resource references to update in package " + packageName); 1397 return; 1398 } 1399 1400 final Method callback; 1401 try { 1402 callback = rClazz.getMethod("onResourcesLoaded", int.class); 1403 } catch (NoSuchMethodException e) { 1404 // No rewriting to be done. 1405 return; 1406 } 1407 1408 Throwable cause; 1409 try { 1410 callback.invoke(null, id); 1411 return; 1412 } catch (IllegalAccessException e) { 1413 cause = e; 1414 } catch (InvocationTargetException e) { 1415 cause = e.getCause(); 1416 } 1417 1418 throw new RuntimeException("Failed to rewrite resource references for " + packageName, 1419 cause); 1420 } 1421 removeContextRegistrations(Context context, String who, String what)1422 public void removeContextRegistrations(Context context, 1423 String who, String what) { 1424 final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled(); 1425 synchronized (mReceivers) { 1426 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap = 1427 mReceivers.remove(context); 1428 if (rmap != null) { 1429 for (int i = 0; i < rmap.size(); i++) { 1430 LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i); 1431 IntentReceiverLeaked leak = new IntentReceiverLeaked( 1432 what + " " + who + " has leaked IntentReceiver " 1433 + rd.getIntentReceiver() + " that was " + 1434 "originally registered here. Are you missing a " + 1435 "call to unregisterReceiver()?"); 1436 leak.setStackTrace(rd.getLocation().getStackTrace()); 1437 Slog.e(ActivityThread.TAG, leak.getMessage(), leak); 1438 if (reportRegistrationLeaks) { 1439 StrictMode.onIntentReceiverLeaked(leak); 1440 } 1441 try { 1442 ActivityManager.getService().unregisterReceiver( 1443 rd.getIIntentReceiver()); 1444 } catch (RemoteException e) { 1445 throw e.rethrowFromSystemServer(); 1446 } 1447 } 1448 } 1449 mUnregisteredReceivers.remove(context); 1450 } 1451 1452 synchronized (mServices) { 1453 //Slog.i(TAG, "Receiver registrations: " + mReceivers); 1454 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap = 1455 mServices.remove(context); 1456 if (smap != null) { 1457 for (int i = 0; i < smap.size(); i++) { 1458 LoadedApk.ServiceDispatcher sd = smap.valueAt(i); 1459 ServiceConnectionLeaked leak = new ServiceConnectionLeaked( 1460 what + " " + who + " has leaked ServiceConnection " 1461 + sd.getServiceConnection() + " that was originally bound here"); 1462 leak.setStackTrace(sd.getLocation().getStackTrace()); 1463 Slog.e(ActivityThread.TAG, leak.getMessage(), leak); 1464 if (reportRegistrationLeaks) { 1465 StrictMode.onServiceConnectionLeaked(leak); 1466 } 1467 try { 1468 ActivityManager.getService().unbindService( 1469 sd.getIServiceConnection()); 1470 } catch (RemoteException e) { 1471 throw e.rethrowFromSystemServer(); 1472 } 1473 sd.doForget(); 1474 } 1475 } 1476 mUnboundServices.remove(context); 1477 //Slog.i(TAG, "Service registrations: " + mServices); 1478 } 1479 } 1480 getReceiverDispatcher(BroadcastReceiver r, Context context, Handler handler, Instrumentation instrumentation, boolean registered)1481 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r, 1482 Context context, Handler handler, 1483 Instrumentation instrumentation, boolean registered) { 1484 synchronized (mReceivers) { 1485 LoadedApk.ReceiverDispatcher rd = null; 1486 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null; 1487 if (registered) { 1488 map = mReceivers.get(context); 1489 if (map != null) { 1490 rd = map.get(r); 1491 } 1492 } 1493 if (rd == null) { 1494 rd = new ReceiverDispatcher(r, context, handler, 1495 instrumentation, registered); 1496 if (registered) { 1497 if (map == null) { 1498 map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); 1499 mReceivers.put(context, map); 1500 } 1501 map.put(r, rd); 1502 } 1503 } else { 1504 rd.validate(context, handler); 1505 } 1506 rd.mForgotten = false; 1507 return rd.getIIntentReceiver(); 1508 } 1509 } 1510 forgetReceiverDispatcher(Context context, BroadcastReceiver r)1511 public IIntentReceiver forgetReceiverDispatcher(Context context, 1512 BroadcastReceiver r) { 1513 synchronized (mReceivers) { 1514 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context); 1515 LoadedApk.ReceiverDispatcher rd = null; 1516 if (map != null) { 1517 rd = map.get(r); 1518 if (rd != null) { 1519 map.remove(r); 1520 if (map.size() == 0) { 1521 mReceivers.remove(context); 1522 } 1523 if (r.getDebugUnregister()) { 1524 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder 1525 = mUnregisteredReceivers.get(context); 1526 if (holder == null) { 1527 holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>(); 1528 mUnregisteredReceivers.put(context, holder); 1529 } 1530 RuntimeException ex = new IllegalArgumentException( 1531 "Originally unregistered here:"); 1532 ex.fillInStackTrace(); 1533 rd.setUnregisterLocation(ex); 1534 holder.put(r, rd); 1535 } 1536 rd.mForgotten = true; 1537 return rd.getIIntentReceiver(); 1538 } 1539 } 1540 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder 1541 = mUnregisteredReceivers.get(context); 1542 if (holder != null) { 1543 rd = holder.get(r); 1544 if (rd != null) { 1545 RuntimeException ex = rd.getUnregisterLocation(); 1546 throw new IllegalArgumentException( 1547 "Unregistering Receiver " + r 1548 + " that was already unregistered", ex); 1549 } 1550 } 1551 if (context == null) { 1552 throw new IllegalStateException("Unbinding Receiver " + r 1553 + " from Context that is no longer in use: " + context); 1554 } else { 1555 throw new IllegalArgumentException("Receiver not registered: " + r); 1556 } 1557 1558 } 1559 } 1560 1561 static final class ReceiverDispatcher { 1562 1563 final static class InnerReceiver extends IIntentReceiver.Stub { 1564 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher; 1565 final LoadedApk.ReceiverDispatcher mStrongRef; 1566 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong)1567 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) { 1568 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd); 1569 mStrongRef = strong ? rd : null; 1570 } 1571 1572 @Override performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser)1573 public void performReceive(Intent intent, int resultCode, String data, 1574 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 1575 final LoadedApk.ReceiverDispatcher rd; 1576 if (intent == null) { 1577 Log.wtf(TAG, "Null intent received"); 1578 rd = null; 1579 } else { 1580 rd = mDispatcher.get(); 1581 } 1582 if (ActivityThread.DEBUG_BROADCAST) { 1583 int seq = intent.getIntExtra("seq", -1); 1584 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction() 1585 + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null)); 1586 } 1587 if (rd != null) { 1588 rd.performReceive(intent, resultCode, data, extras, 1589 ordered, sticky, sendingUser); 1590 } else { 1591 // The activity manager dispatched a broadcast to a registered 1592 // receiver in this process, but before it could be delivered the 1593 // receiver was unregistered. Acknowledge the broadcast on its 1594 // behalf so that the system's broadcast sequence can continue. 1595 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 1596 "Finishing broadcast to unregistered receiver"); 1597 IActivityManager mgr = ActivityManager.getService(); 1598 try { 1599 if (extras != null) { 1600 extras.setAllowFds(false); 1601 } 1602 mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags()); 1603 } catch (RemoteException e) { 1604 throw e.rethrowFromSystemServer(); 1605 } 1606 } 1607 } 1608 } 1609 1610 final IIntentReceiver.Stub mIIntentReceiver; 1611 @UnsupportedAppUsage 1612 final BroadcastReceiver mReceiver; 1613 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 1614 final Context mContext; 1615 final Handler mActivityThread; 1616 final Instrumentation mInstrumentation; 1617 final boolean mRegistered; 1618 final IntentReceiverLeaked mLocation; 1619 RuntimeException mUnregisterLocation; 1620 boolean mForgotten; 1621 1622 final class Args extends BroadcastReceiver.PendingResult { 1623 private Intent mCurIntent; 1624 private final boolean mOrdered; 1625 private boolean mDispatched; 1626 private boolean mRunCalled; 1627 Args(Intent intent, int resultCode, String resultData, Bundle resultExtras, boolean ordered, boolean sticky, int sendingUser)1628 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras, 1629 boolean ordered, boolean sticky, int sendingUser) { 1630 super(resultCode, resultData, resultExtras, 1631 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered, 1632 sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags()); 1633 mCurIntent = intent; 1634 mOrdered = ordered; 1635 } 1636 getRunnable()1637 public final Runnable getRunnable() { 1638 return () -> { 1639 final BroadcastReceiver receiver = mReceiver; 1640 final boolean ordered = mOrdered; 1641 1642 if (ActivityThread.DEBUG_BROADCAST) { 1643 int seq = mCurIntent.getIntExtra("seq", -1); 1644 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction() 1645 + " seq=" + seq + " to " + mReceiver); 1646 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered 1647 + " mOrderedHint=" + ordered); 1648 } 1649 1650 final IActivityManager mgr = ActivityManager.getService(); 1651 final Intent intent = mCurIntent; 1652 if (intent == null) { 1653 Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched 1654 + (mRunCalled ? ", run() has already been called" : "")); 1655 } 1656 1657 mCurIntent = null; 1658 mDispatched = true; 1659 mRunCalled = true; 1660 if (receiver == null || intent == null || mForgotten) { 1661 if (mRegistered && ordered) { 1662 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 1663 "Finishing null broadcast to " + mReceiver); 1664 sendFinished(mgr); 1665 } 1666 return; 1667 } 1668 1669 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg"); 1670 try { 1671 ClassLoader cl = mReceiver.getClass().getClassLoader(); 1672 intent.setExtrasClassLoader(cl); 1673 // TODO: determine at registration time if caller is 1674 // protecting themselves with signature permission 1675 intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent), 1676 mContext.getAttributionSource()); 1677 setExtrasClassLoader(cl); 1678 receiver.setPendingResult(this); 1679 receiver.onReceive(mContext, intent); 1680 } catch (Exception e) { 1681 if (mRegistered && ordered) { 1682 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 1683 "Finishing failed broadcast to " + mReceiver); 1684 sendFinished(mgr); 1685 } 1686 if (mInstrumentation == null || 1687 !mInstrumentation.onException(mReceiver, e)) { 1688 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1689 throw new RuntimeException( 1690 "Error receiving broadcast " + intent 1691 + " in " + mReceiver, e); 1692 } 1693 } 1694 1695 if (receiver.getPendingResult() != null) { 1696 finish(); 1697 } 1698 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1699 }; 1700 } 1701 } 1702 ReceiverDispatcher(BroadcastReceiver receiver, Context context, Handler activityThread, Instrumentation instrumentation, boolean registered)1703 ReceiverDispatcher(BroadcastReceiver receiver, Context context, 1704 Handler activityThread, Instrumentation instrumentation, 1705 boolean registered) { 1706 if (activityThread == null) { 1707 throw new NullPointerException("Handler must not be null"); 1708 } 1709 1710 mIIntentReceiver = new InnerReceiver(this, !registered); 1711 mReceiver = receiver; 1712 mContext = context; 1713 mActivityThread = activityThread; 1714 mInstrumentation = instrumentation; 1715 mRegistered = registered; 1716 mLocation = new IntentReceiverLeaked(null); 1717 mLocation.fillInStackTrace(); 1718 } 1719 validate(Context context, Handler activityThread)1720 void validate(Context context, Handler activityThread) { 1721 if (mContext != context) { 1722 throw new IllegalStateException( 1723 "Receiver " + mReceiver + 1724 " registered with differing Context (was " + 1725 mContext + " now " + context + ")"); 1726 } 1727 if (mActivityThread != activityThread) { 1728 throw new IllegalStateException( 1729 "Receiver " + mReceiver + 1730 " registered with differing handler (was " + 1731 mActivityThread + " now " + activityThread + ")"); 1732 } 1733 } 1734 getLocation()1735 IntentReceiverLeaked getLocation() { 1736 return mLocation; 1737 } 1738 1739 @UnsupportedAppUsage getIntentReceiver()1740 BroadcastReceiver getIntentReceiver() { 1741 return mReceiver; 1742 } 1743 1744 @UnsupportedAppUsage getIIntentReceiver()1745 IIntentReceiver getIIntentReceiver() { 1746 return mIIntentReceiver; 1747 } 1748 setUnregisterLocation(RuntimeException ex)1749 void setUnregisterLocation(RuntimeException ex) { 1750 mUnregisterLocation = ex; 1751 } 1752 getUnregisterLocation()1753 RuntimeException getUnregisterLocation() { 1754 return mUnregisterLocation; 1755 } 1756 performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser)1757 public void performReceive(Intent intent, int resultCode, String data, 1758 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 1759 final Args args = new Args(intent, resultCode, data, extras, ordered, 1760 sticky, sendingUser); 1761 if (intent == null) { 1762 Log.wtf(TAG, "Null intent received"); 1763 } else { 1764 if (ActivityThread.DEBUG_BROADCAST) { 1765 int seq = intent.getIntExtra("seq", -1); 1766 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction() 1767 + " seq=" + seq + " to " + mReceiver); 1768 } 1769 } 1770 if (intent == null || !mActivityThread.post(args.getRunnable())) { 1771 if (mRegistered && ordered) { 1772 IActivityManager mgr = ActivityManager.getService(); 1773 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG, 1774 "Finishing sync broadcast to " + mReceiver); 1775 args.sendFinished(mgr); 1776 } 1777 } 1778 } 1779 1780 } 1781 1782 @UnsupportedAppUsage getServiceDispatcher(ServiceConnection c, Context context, Handler handler, int flags)1783 public final IServiceConnection getServiceDispatcher(ServiceConnection c, 1784 Context context, Handler handler, int flags) { 1785 return getServiceDispatcherCommon(c, context, handler, null, flags); 1786 } 1787 getServiceDispatcher(ServiceConnection c, Context context, Executor executor, int flags)1788 public final IServiceConnection getServiceDispatcher(ServiceConnection c, 1789 Context context, Executor executor, int flags) { 1790 return getServiceDispatcherCommon(c, context, null, executor, flags); 1791 } 1792 getServiceDispatcherCommon(ServiceConnection c, Context context, Handler handler, Executor executor, int flags)1793 private IServiceConnection getServiceDispatcherCommon(ServiceConnection c, 1794 Context context, Handler handler, Executor executor, int flags) { 1795 synchronized (mServices) { 1796 LoadedApk.ServiceDispatcher sd = null; 1797 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); 1798 if (map != null) { 1799 if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c); 1800 sd = map.get(c); 1801 } 1802 if (sd == null) { 1803 if (executor != null) { 1804 sd = new ServiceDispatcher(c, context, executor, flags); 1805 } else { 1806 sd = new ServiceDispatcher(c, context, handler, flags); 1807 } 1808 if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c); 1809 if (map == null) { 1810 map = new ArrayMap<>(); 1811 mServices.put(context, map); 1812 } 1813 map.put(c, sd); 1814 } else { 1815 sd.validate(context, handler, executor); 1816 } 1817 return sd.getIServiceConnection(); 1818 } 1819 } 1820 1821 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) lookupServiceDispatcher(ServiceConnection c, Context context)1822 public IServiceConnection lookupServiceDispatcher(ServiceConnection c, 1823 Context context) { 1824 synchronized (mServices) { 1825 LoadedApk.ServiceDispatcher sd = null; 1826 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); 1827 if (map != null) { 1828 sd = map.get(c); 1829 } 1830 return sd != null ? sd.getIServiceConnection() : null; 1831 } 1832 } 1833 forgetServiceDispatcher(Context context, ServiceConnection c)1834 public final IServiceConnection forgetServiceDispatcher(Context context, 1835 ServiceConnection c) { 1836 synchronized (mServices) { 1837 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map 1838 = mServices.get(context); 1839 LoadedApk.ServiceDispatcher sd = null; 1840 if (map != null) { 1841 sd = map.get(c); 1842 if (sd != null) { 1843 if (DEBUG) Slog.d(TAG, "Removing dispatcher " + sd + " for conn " + c); 1844 map.remove(c); 1845 sd.doForget(); 1846 if (map.size() == 0) { 1847 mServices.remove(context); 1848 } 1849 if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) { 1850 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder 1851 = mUnboundServices.get(context); 1852 if (holder == null) { 1853 holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); 1854 mUnboundServices.put(context, holder); 1855 } 1856 RuntimeException ex = new IllegalArgumentException( 1857 "Originally unbound here:"); 1858 ex.fillInStackTrace(); 1859 sd.setUnbindLocation(ex); 1860 holder.put(c, sd); 1861 } 1862 return sd.getIServiceConnection(); 1863 } 1864 } 1865 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder 1866 = mUnboundServices.get(context); 1867 if (holder != null) { 1868 sd = holder.get(c); 1869 if (sd != null) { 1870 RuntimeException ex = sd.getUnbindLocation(); 1871 throw new IllegalArgumentException( 1872 "Unbinding Service " + c 1873 + " that was already unbound", ex); 1874 } 1875 } 1876 if (context == null) { 1877 throw new IllegalStateException("Unbinding Service " + c 1878 + " from Context that is no longer in use: " + context); 1879 } else { 1880 throw new IllegalArgumentException("Service not registered: " + c); 1881 } 1882 } 1883 } 1884 1885 static final class ServiceDispatcher { 1886 private final ServiceDispatcher.InnerConnection mIServiceConnection; 1887 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1888 private final ServiceConnection mConnection; 1889 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 1890 private final Context mContext; 1891 private final Handler mActivityThread; 1892 private final Executor mActivityExecutor; 1893 private final ServiceConnectionLeaked mLocation; 1894 private final int mFlags; 1895 1896 private RuntimeException mUnbindLocation; 1897 1898 private boolean mForgotten; 1899 1900 private static class ConnectionInfo { 1901 IBinder binder; 1902 IBinder.DeathRecipient deathMonitor; 1903 } 1904 1905 private static class InnerConnection extends IServiceConnection.Stub { 1906 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1907 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher; 1908 InnerConnection(LoadedApk.ServiceDispatcher sd)1909 InnerConnection(LoadedApk.ServiceDispatcher sd) { 1910 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd); 1911 } 1912 connected(ComponentName name, IBinder service, boolean dead)1913 public void connected(ComponentName name, IBinder service, boolean dead) 1914 throws RemoteException { 1915 LoadedApk.ServiceDispatcher sd = mDispatcher.get(); 1916 if (sd != null) { 1917 sd.connected(name, service, dead); 1918 } 1919 } 1920 } 1921 1922 private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections 1923 = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>(); 1924 1925 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) ServiceDispatcher(ServiceConnection conn, Context context, Handler activityThread, int flags)1926 ServiceDispatcher(ServiceConnection conn, 1927 Context context, Handler activityThread, int flags) { 1928 mIServiceConnection = new InnerConnection(this); 1929 mConnection = conn; 1930 mContext = context; 1931 mActivityThread = activityThread; 1932 mActivityExecutor = null; 1933 mLocation = new ServiceConnectionLeaked(null); 1934 mLocation.fillInStackTrace(); 1935 mFlags = flags; 1936 } 1937 ServiceDispatcher(ServiceConnection conn, Context context, Executor activityExecutor, int flags)1938 ServiceDispatcher(ServiceConnection conn, 1939 Context context, Executor activityExecutor, int flags) { 1940 mIServiceConnection = new InnerConnection(this); 1941 mConnection = conn; 1942 mContext = context; 1943 mActivityThread = null; 1944 mActivityExecutor = activityExecutor; 1945 mLocation = new ServiceConnectionLeaked(null); 1946 mLocation.fillInStackTrace(); 1947 mFlags = flags; 1948 } 1949 validate(Context context, Handler activityThread, Executor activityExecutor)1950 void validate(Context context, Handler activityThread, Executor activityExecutor) { 1951 if (mContext != context) { 1952 throw new RuntimeException( 1953 "ServiceConnection " + mConnection + 1954 " registered with differing Context (was " + 1955 mContext + " now " + context + ")"); 1956 } 1957 if (mActivityThread != activityThread) { 1958 throw new RuntimeException( 1959 "ServiceConnection " + mConnection + 1960 " registered with differing handler (was " + 1961 mActivityThread + " now " + activityThread + ")"); 1962 } 1963 if (mActivityExecutor != activityExecutor) { 1964 throw new RuntimeException( 1965 "ServiceConnection " + mConnection + 1966 " registered with differing executor (was " + 1967 mActivityExecutor + " now " + activityExecutor + ")"); 1968 } 1969 } 1970 doForget()1971 void doForget() { 1972 synchronized(this) { 1973 for (int i=0; i<mActiveConnections.size(); i++) { 1974 ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i); 1975 ci.binder.unlinkToDeath(ci.deathMonitor, 0); 1976 } 1977 mActiveConnections.clear(); 1978 mForgotten = true; 1979 } 1980 } 1981 getLocation()1982 ServiceConnectionLeaked getLocation() { 1983 return mLocation; 1984 } 1985 getServiceConnection()1986 ServiceConnection getServiceConnection() { 1987 return mConnection; 1988 } 1989 1990 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getIServiceConnection()1991 IServiceConnection getIServiceConnection() { 1992 return mIServiceConnection; 1993 } 1994 getFlags()1995 int getFlags() { 1996 return mFlags; 1997 } 1998 setUnbindLocation(RuntimeException ex)1999 void setUnbindLocation(RuntimeException ex) { 2000 mUnbindLocation = ex; 2001 } 2002 getUnbindLocation()2003 RuntimeException getUnbindLocation() { 2004 return mUnbindLocation; 2005 } 2006 connected(ComponentName name, IBinder service, boolean dead)2007 public void connected(ComponentName name, IBinder service, boolean dead) { 2008 if (mActivityExecutor != null) { 2009 mActivityExecutor.execute(new RunConnection(name, service, 0, dead)); 2010 } else if (mActivityThread != null) { 2011 mActivityThread.post(new RunConnection(name, service, 0, dead)); 2012 } else { 2013 doConnected(name, service, dead); 2014 } 2015 } 2016 death(ComponentName name, IBinder service)2017 public void death(ComponentName name, IBinder service) { 2018 if (mActivityExecutor != null) { 2019 mActivityExecutor.execute(new RunConnection(name, service, 1, false)); 2020 } else if (mActivityThread != null) { 2021 mActivityThread.post(new RunConnection(name, service, 1, false)); 2022 } else { 2023 doDeath(name, service); 2024 } 2025 } 2026 doConnected(ComponentName name, IBinder service, boolean dead)2027 public void doConnected(ComponentName name, IBinder service, boolean dead) { 2028 ServiceDispatcher.ConnectionInfo old; 2029 ServiceDispatcher.ConnectionInfo info; 2030 2031 synchronized (this) { 2032 if (mForgotten) { 2033 // We unbound before receiving the connection; ignore 2034 // any connection received. 2035 return; 2036 } 2037 old = mActiveConnections.get(name); 2038 if (old != null && old.binder == service) { 2039 // Huh, already have this one. Oh well! 2040 return; 2041 } 2042 2043 if (service != null) { 2044 // A new service is being connected... set it all up. 2045 info = new ConnectionInfo(); 2046 info.binder = service; 2047 info.deathMonitor = new DeathMonitor(name, service); 2048 try { 2049 service.linkToDeath(info.deathMonitor, 0); 2050 mActiveConnections.put(name, info); 2051 } catch (RemoteException e) { 2052 // This service was dead before we got it... just 2053 // don't do anything with it. 2054 mActiveConnections.remove(name); 2055 return; 2056 } 2057 2058 } else { 2059 // The named service is being disconnected... clean up. 2060 mActiveConnections.remove(name); 2061 } 2062 2063 if (old != null) { 2064 old.binder.unlinkToDeath(old.deathMonitor, 0); 2065 } 2066 } 2067 2068 // If there was an old service, it is now disconnected. 2069 if (old != null) { 2070 mConnection.onServiceDisconnected(name); 2071 } 2072 if (dead) { 2073 mConnection.onBindingDied(name); 2074 } else { 2075 // If there is a new viable service, it is now connected. 2076 if (service != null) { 2077 mConnection.onServiceConnected(name, service); 2078 } else { 2079 // The binding machinery worked, but the remote returned null from onBind(). 2080 mConnection.onNullBinding(name); 2081 } 2082 } 2083 } 2084 doDeath(ComponentName name, IBinder service)2085 public void doDeath(ComponentName name, IBinder service) { 2086 synchronized (this) { 2087 ConnectionInfo old = mActiveConnections.get(name); 2088 if (old == null || old.binder != service) { 2089 // Death for someone different than who we last 2090 // reported... just ignore it. 2091 return; 2092 } 2093 mActiveConnections.remove(name); 2094 old.binder.unlinkToDeath(old.deathMonitor, 0); 2095 } 2096 2097 mConnection.onServiceDisconnected(name); 2098 } 2099 2100 private final class RunConnection implements Runnable { RunConnection(ComponentName name, IBinder service, int command, boolean dead)2101 RunConnection(ComponentName name, IBinder service, int command, boolean dead) { 2102 mName = name; 2103 mService = service; 2104 mCommand = command; 2105 mDead = dead; 2106 } 2107 run()2108 public void run() { 2109 if (mCommand == 0) { 2110 doConnected(mName, mService, mDead); 2111 } else if (mCommand == 1) { 2112 doDeath(mName, mService); 2113 } 2114 } 2115 2116 final ComponentName mName; 2117 final IBinder mService; 2118 final int mCommand; 2119 final boolean mDead; 2120 } 2121 2122 private final class DeathMonitor implements IBinder.DeathRecipient 2123 { DeathMonitor(ComponentName name, IBinder service)2124 DeathMonitor(ComponentName name, IBinder service) { 2125 mName = name; 2126 mService = service; 2127 } 2128 binderDied()2129 public void binderDied() { 2130 death(mName, mService); 2131 } 2132 2133 final ComponentName mName; 2134 final IBinder mService; 2135 } 2136 } 2137 } 2138