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