Loading core/java/android/app/ActivityThread.java +86 −14 Original line number Diff line number Diff line Loading @@ -1788,7 +1788,8 @@ public final class ActivityThread { } /** * Creates the top level resources for the given package. * Creates the top level resources for the given package. Will return an existing * Resources if one has already been created. */ Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs, String[] libDirs, int displayId, Configuration overrideConfiguration, Loading @@ -1798,6 +1799,19 @@ public final class ActivityThread { pkgInfo.getClassLoader()); } /** * Creates a new top level resources for the given package. Will always create a new * Resources, regardless if one has already been created. */ Resources getNewTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs, String[] libDirs, int displayId, Configuration overrideConfiguration, LoadedApk pkgInfo) { mResourcesManager.removeTopLevelResources( resDir, displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo()); return getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs, displayId, overrideConfiguration, pkgInfo); } final Handler getHandler() { return mH; } Loading Loading @@ -4749,13 +4763,18 @@ public final class ActivityThread { final void handleDispatchPackageBroadcast(int cmd, String[] packages) { boolean hasPkgInfo = false; if (packages != null) { switch (cmd) { case IApplicationThread.PACKAGE_REMOVED: case IApplicationThread.PACKAGE_REMOVED_DONT_KILL: { final boolean killApp = cmd == IApplicationThread.PACKAGE_REMOVED; if (packages == null) { break; } synchronized (mResourcesManager) { for (int i = packages.length - 1; i >= 0; i--) { //Slog.i(TAG, "Cleaning old package: " + packages[i]); if (!hasPkgInfo) { WeakReference<LoadedApk> ref; ref = mPackages.get(packages[i]); WeakReference<LoadedApk> ref = mPackages.get(packages[i]); if (ref != null && ref.get() != null) { hasPkgInfo = true; } else { Loading @@ -4765,13 +4784,66 @@ public final class ActivityThread { } } } if (killApp) { mPackages.remove(packages[i]); mResourcePackages.remove(packages[i]); } } } ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo); break; } case IApplicationThread.PACKAGE_REPLACED: { if (packages == null) { break; } synchronized (mResourcesManager) { for (int i = packages.length - 1; i >= 0; i--) { WeakReference<LoadedApk> ref = mPackages.get(packages[i]); LoadedApk pkgInfo = ref != null ? ref.get() : null; if (pkgInfo != null) { hasPkgInfo = true; } else { ref = mResourcePackages.get(packages[i]); pkgInfo = ref != null ? ref.get() : null; if (pkgInfo != null) { hasPkgInfo = true; } } // If the package is being replaced, yet it still has a valid // LoadedApk object, the package was updated with _DONT_KILL. // Adjust it's internal references to the application info and // resources. if (pkgInfo != null) { try { final String packageName = packages[i]; final ApplicationInfo aInfo = sPackageManager.getApplicationInfo( packageName, 0 /*flags*/, UserHandle.myUserId()); if (mActivities.size() > 0) { for (ActivityClientRecord ar : mActivities.values()) { if (ar.activityInfo.applicationInfo.packageName .equals(packageName)) { ar.activityInfo.applicationInfo = aInfo; ar.packageInfo = pkgInfo; } } } final List<String> oldPaths = sPackageManager.getPreviousCodePaths(packageName); pkgInfo.updateApplicationInfo(aInfo, oldPaths); } catch (RemoteException e) { } } } } break; } } ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo); } final void handleLowMemory() { Loading core/java/android/app/ApplicationLoaders.java +12 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,18 @@ class ApplicationLoaders { String libraryPermittedPath, boolean isShared); /** * Adds a new path the classpath of the given loader. * @throws IllegalStateException if the provided class loader is not a {@link PathClassLoader}. */ void addPath(ClassLoader classLoader, String dexPath) { if (!(classLoader instanceof PathClassLoader)) { throw new IllegalStateException("class loader is not a PathClassLoader"); } final PathClassLoader baseDexClassLoader = (PathClassLoader) classLoader; baseDexClassLoader.addDexPath(dexPath); } private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<String, ClassLoader>(); private static final ApplicationLoaders gApplicationLoaders Loading core/java/android/app/IApplicationThread.java +5 −0 Original line number Diff line number Diff line Loading @@ -123,8 +123,13 @@ public interface IApplicationThread extends IInterface { void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) throws RemoteException; void setSchedulingGroup(int group) throws RemoteException; // the package has been removed, clean up internal references static final int PACKAGE_REMOVED = 0; static final int EXTERNAL_STORAGE_UNAVAILABLE = 1; // the package is being modified in-place, don't kill it and retain references to it static final int PACKAGE_REMOVED_DONT_KILL = 2; // a previously removed package was replaced with a new version [eg. upgrade, split added, ...] static final int PACKAGE_REPLACED = 3; void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException; void scheduleCrash(String msg) throws RemoteException; void dumpActivity(FileDescriptor fd, IBinder servicetoken, String prefix, String[] args) Loading core/java/android/app/LoadedApk.java +203 −131 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ import java.lang.reflect.Method; import java.net.URL; import java.util.List; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.Objects; Loading @@ -83,24 +84,25 @@ public final class LoadedApk { private static final String TAG = "LoadedApk"; private final ActivityThread mActivityThread; private ApplicationInfo mApplicationInfo; final String mPackageName; private final String mAppDir; private final String mResDir; private final String[] mSplitAppDirs; private final String[] mSplitResDirs; private final String[] mOverlayDirs; private final String[] mSharedLibraries; private final String mDataDir; private final String mLibDir; private final File mDataDirFile; private final File mDeviceEncryptedDataDirFile; private final File mCredentialEncryptedDataDirFile; private ApplicationInfo mApplicationInfo; private String mAppDir; private String mResDir; private String[] mSplitAppDirs; private String[] mSplitResDirs; private String[] mOverlayDirs; private String[] mSharedLibraries; private String mDataDir; private String mLibDir; private File mDataDirFile; private File mDeviceEncryptedDataDirFile; private File mCredentialEncryptedDataDirFile; private final ClassLoader mBaseClassLoader; private final boolean mSecurityViolation; private final boolean mIncludeCode; private final boolean mRegisterPackage; private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments(); /** WARNING: This may change. Don't hold external references to it. */ Resources mResources; private ClassLoader mClassLoader; private Application mApplication; Loading Loading @@ -129,23 +131,10 @@ public final class LoadedApk { public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, boolean includeCode, boolean registerPackage) { final int myUid = Process.myUid(); aInfo = adjustNativeLibraryPaths(aInfo); mActivityThread = activityThread; mApplicationInfo = aInfo; setApplicationInfo(aInfo); mPackageName = aInfo.packageName; mAppDir = aInfo.sourceDir; mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir; mSplitAppDirs = aInfo.splitSourceDirs; mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs; mOverlayDirs = aInfo.resourceDirs; mSharedLibraries = aInfo.sharedLibraryFiles; mDataDir = aInfo.dataDir; mDataDirFile = FileUtils.newFileOrNull(mDataDir); mDeviceEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceEncryptedDataDir); mCredentialEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialEncryptedDataDir); mLibDir = aInfo.nativeLibraryDir; mBaseClassLoader = baseLoader; mSecurityViolation = securityViolation; mIncludeCode = includeCode; Loading Loading @@ -266,51 +255,74 @@ public final class LoadedApk { return ai.sharedLibraryFiles; } public ClassLoader getClassLoader() { synchronized (this) { if (mClassLoader != null) { return mClassLoader; } public void updateApplicationInfo(ApplicationInfo aInfo, List<String> oldPaths) { setApplicationInfo(aInfo); if (mPackageName.equals("android")) { if (mBaseClassLoader == null) { mClassLoader = ClassLoader.getSystemClassLoader(); final List<String> newPaths = new ArrayList<>(); makePaths(mActivityThread, aInfo, newPaths, null /*libPaths*/); final List<String> addedPaths = new ArrayList<>(newPaths.size()); if (oldPaths != null) { for (String path : newPaths) { final String apkName = path.substring(path.lastIndexOf(File.separator)); boolean match = false; for (String oldPath : oldPaths) { final String oldApkName = oldPath.substring(path.lastIndexOf(File.separator)); if (apkName.equals(oldApkName)) { match = true; break; } } if (!match) { addedPaths.add(path); } } } else { mClassLoader = mBaseClassLoader; addedPaths.addAll(newPaths); } return mClassLoader; synchronized (this) { mClassLoader = createOrUpdateClassLoaderLocked(addedPaths); if (mResources != null) { mResources = mActivityThread.getNewTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs, mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null /*overrideConfiguration*/, this); } // Avoid the binder call when the package is the current application package. // The activity manager will perform ensure that dexopt is performed before // spinning up the process. if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) { final String isa = VMRuntime.getRuntime().vmInstructionSet(); try { ActivityThread.getPackageManager().notifyPackageUse(mPackageName); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } final List<String> zipPaths = new ArrayList<>(); final List<String> apkPaths = new ArrayList<>(); final List<String> libPaths = new ArrayList<>(); if (mRegisterPackage) { try { ActivityManagerNative.getDefault().addPackageDependency(mPackageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } private void setApplicationInfo(ApplicationInfo aInfo) { final int myUid = Process.myUid(); aInfo = adjustNativeLibraryPaths(aInfo); mApplicationInfo = aInfo; mAppDir = aInfo.sourceDir; mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir; mSplitAppDirs = aInfo.splitSourceDirs; mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs; mOverlayDirs = aInfo.resourceDirs; mSharedLibraries = aInfo.sharedLibraryFiles; mDataDir = aInfo.dataDir; mLibDir = aInfo.nativeLibraryDir; mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir); mDeviceEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceEncryptedDataDir); mCredentialEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialEncryptedDataDir); } zipPaths.add(mAppDir); if (mSplitAppDirs != null) { Collections.addAll(zipPaths, mSplitAppDirs); public static void makePaths(ActivityThread activityThread, ApplicationInfo aInfo, List<String> outZipPaths, List<String> outLibPaths) { final String appDir = aInfo.sourceDir; final String[] splitAppDirs = aInfo.splitSourceDirs; final String libDir = aInfo.nativeLibraryDir; final String[] sharedLibraries = aInfo.sharedLibraryFiles; outZipPaths.clear(); outZipPaths.add(appDir); if (splitAppDirs != null) { Collections.addAll(outZipPaths, splitAppDirs); } libPaths.add(mLibDir); if (outLibPaths != null) { outLibPaths.clear(); } /* * The following is a bit of a hack to inject Loading @@ -321,75 +333,111 @@ public final class LoadedApk { * concatenation of both apps' shared library lists. */ String instrumentationPackageName = mActivityThread.mInstrumentationPackageName; String instrumentationAppDir = mActivityThread.mInstrumentationAppDir; String[] instrumentationSplitAppDirs = mActivityThread.mInstrumentationSplitAppDirs; String instrumentationLibDir = mActivityThread.mInstrumentationLibDir; String instrumentationPackageName = activityThread.mInstrumentationPackageName; String instrumentationAppDir = activityThread.mInstrumentationAppDir; String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs; String instrumentationLibDir = activityThread.mInstrumentationLibDir; String instrumentedAppDir = mActivityThread.mInstrumentedAppDir; String[] instrumentedSplitAppDirs = mActivityThread.mInstrumentedSplitAppDirs; String instrumentedLibDir = mActivityThread.mInstrumentedLibDir; String instrumentedAppDir = activityThread.mInstrumentedAppDir; String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs; String instrumentedLibDir = activityThread.mInstrumentedLibDir; String[] instrumentationLibs = null; if (mAppDir.equals(instrumentationAppDir) || mAppDir.equals(instrumentedAppDir)) { zipPaths.clear(); zipPaths.add(instrumentationAppDir); if (appDir.equals(instrumentationAppDir) || appDir.equals(instrumentedAppDir)) { outZipPaths.clear(); outZipPaths.add(instrumentationAppDir); if (instrumentationSplitAppDirs != null) { Collections.addAll(zipPaths, instrumentationSplitAppDirs); Collections.addAll(outZipPaths, instrumentationSplitAppDirs); } zipPaths.add(instrumentedAppDir); outZipPaths.add(instrumentedAppDir); if (instrumentedSplitAppDirs != null) { Collections.addAll(zipPaths, instrumentedSplitAppDirs); Collections.addAll(outZipPaths, instrumentedSplitAppDirs); } libPaths.clear(); libPaths.add(instrumentationLibDir); libPaths.add(instrumentedLibDir); if (outLibPaths != null) { outLibPaths.add(instrumentationLibDir); outLibPaths.add(instrumentedLibDir); } if (!instrumentedAppDir.equals(instrumentationAppDir)) { instrumentationLibs = getLibrariesFor(instrumentationPackageName); } } apkPaths.addAll(zipPaths); if (outLibPaths != null) { if (outLibPaths.isEmpty()) { outLibPaths.add(libDir); } // Add path to libraries in apk for current abi. Do this now because more entries // will be added to zipPaths that shouldn't be part of the library path. if (aInfo.primaryCpuAbi != null) { for (String apk : outZipPaths) { outLibPaths.add(apk + "!/lib/" + aInfo.primaryCpuAbi); } } if (aInfo.isSystemApp() && !aInfo.isUpdatedSystemApp()) { // Add path to system libraries to libPaths; // Access to system libs should be limited // to bundled applications; this is why updated // system apps are not included. outLibPaths.add(System.getProperty("java.library.path")); } } if (mSharedLibraries != null) { for (String lib : mSharedLibraries) { if (!zipPaths.contains(lib)) { zipPaths.add(0, lib); if (sharedLibraries != null) { for (String lib : sharedLibraries) { if (!outZipPaths.contains(lib)) { outZipPaths.add(0, lib); } } } if (instrumentationLibs != null) { for (String lib : instrumentationLibs) { if (!zipPaths.contains(lib)) { zipPaths.add(0, lib); if (!outZipPaths.contains(lib)) { outZipPaths.add(0, lib); } } } final String zip = mIncludeCode ? TextUtils.join(File.pathSeparator, zipPaths) : ""; final String zip = TextUtils.join(File.pathSeparator, outZipPaths); } // Add path to libraries in apk for current abi if (mApplicationInfo.primaryCpuAbi != null) { for (String apk : apkPaths) { libPaths.add(apk + "!/lib/" + mApplicationInfo.primaryCpuAbi); private ClassLoader createOrUpdateClassLoaderLocked(List<String> addedPaths) { final ClassLoader classLoader; if (mIncludeCode && !mPackageName.equals("android")) { // Avoid the binder call when the package is the current application package. // The activity manager will perform ensure that dexopt is performed before // spinning up the process. if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) { VMRuntime.getRuntime().vmInstructionSet(); try { ActivityThread.getPackageManager().notifyPackageUse(mPackageName); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } String libraryPermittedPath = mDataDir; boolean isBundledApp = false; final List<String> zipPaths = new ArrayList<>(); final List<String> libPaths = new ArrayList<>(); if (mApplicationInfo.isSystemApp() && !mApplicationInfo.isUpdatedSystemApp()) { isBundledApp = true; // Add path to system libraries to libPaths; // Access to system libs should be limited // to bundled applications; this is why updated // system apps are not included. libPaths.add(System.getProperty("java.library.path")); if (mRegisterPackage) { try { ActivityManagerNative.getDefault().addPackageDependency(mPackageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } makePaths(mActivityThread, mApplicationInfo, zipPaths, libPaths); final String zip = TextUtils.join(File.pathSeparator, zipPaths); final boolean isBundledApp = mApplicationInfo.isSystemApp() && !mApplicationInfo.isUpdatedSystemApp(); String libraryPermittedPath = mDataDir; if (isBundledApp) { // This is necessary to grant bundled apps access to // libraries located in subdirectories of /system/lib libraryPermittedPath += File.pathSeparator + Loading @@ -414,15 +462,42 @@ public final class LoadedApk { Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + librarySearchPath); if (mClassLoader == null) { // Temporarily disable logging of disk reads on the Looper thread // as this is early and necessary. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, classLoader = ApplicationLoaders.getDefault().getClassLoader(zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath, libraryPermittedPath, mBaseClassLoader); StrictMode.setThreadPolicy(oldPolicy); } else if (addedPaths != null && addedPaths.size() > 0) { final String add = TextUtils.join(File.pathSeparator, addedPaths); ApplicationLoaders.getDefault().addPath(mClassLoader, add); classLoader = mClassLoader; } else { classLoader = mClassLoader; } } else { if (mClassLoader == null) { if (mBaseClassLoader == null) { classLoader = ClassLoader.getSystemClassLoader(); } else { classLoader = mBaseClassLoader; } } else { classLoader = mClassLoader; } } return classLoader; } public ClassLoader getClassLoader() { synchronized (this) { if (mClassLoader == null) { mClassLoader = createOrUpdateClassLoaderLocked(null /*addedPaths*/); } return mClassLoader; } } Loading Loading @@ -1103,7 +1178,6 @@ public final class LoadedApk { private RuntimeException mUnbindLocation; private boolean mDied; private boolean mForgotten; private static class ConnectionInfo { Loading Loading @@ -1202,7 +1276,6 @@ public final class LoadedApk { ServiceDispatcher.ConnectionInfo old; synchronized (this) { mDied = true; old = mActiveConnections.remove(name); if (old == null || old.binder != service) { // Death for someone different than who we last Loading Loading @@ -1237,7 +1310,6 @@ public final class LoadedApk { if (service != null) { // A new service is being connected... set it all up. mDied = false; info = new ConnectionInfo(); info.binder = service; info.deathMonitor = new DeathMonitor(name, service); Loading core/java/android/app/ResourcesManager.java +13 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/app/ActivityThread.java +86 −14 Original line number Diff line number Diff line Loading @@ -1788,7 +1788,8 @@ public final class ActivityThread { } /** * Creates the top level resources for the given package. * Creates the top level resources for the given package. Will return an existing * Resources if one has already been created. */ Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs, String[] libDirs, int displayId, Configuration overrideConfiguration, Loading @@ -1798,6 +1799,19 @@ public final class ActivityThread { pkgInfo.getClassLoader()); } /** * Creates a new top level resources for the given package. Will always create a new * Resources, regardless if one has already been created. */ Resources getNewTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs, String[] libDirs, int displayId, Configuration overrideConfiguration, LoadedApk pkgInfo) { mResourcesManager.removeTopLevelResources( resDir, displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo()); return getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs, displayId, overrideConfiguration, pkgInfo); } final Handler getHandler() { return mH; } Loading Loading @@ -4749,13 +4763,18 @@ public final class ActivityThread { final void handleDispatchPackageBroadcast(int cmd, String[] packages) { boolean hasPkgInfo = false; if (packages != null) { switch (cmd) { case IApplicationThread.PACKAGE_REMOVED: case IApplicationThread.PACKAGE_REMOVED_DONT_KILL: { final boolean killApp = cmd == IApplicationThread.PACKAGE_REMOVED; if (packages == null) { break; } synchronized (mResourcesManager) { for (int i = packages.length - 1; i >= 0; i--) { //Slog.i(TAG, "Cleaning old package: " + packages[i]); if (!hasPkgInfo) { WeakReference<LoadedApk> ref; ref = mPackages.get(packages[i]); WeakReference<LoadedApk> ref = mPackages.get(packages[i]); if (ref != null && ref.get() != null) { hasPkgInfo = true; } else { Loading @@ -4765,13 +4784,66 @@ public final class ActivityThread { } } } if (killApp) { mPackages.remove(packages[i]); mResourcePackages.remove(packages[i]); } } } ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo); break; } case IApplicationThread.PACKAGE_REPLACED: { if (packages == null) { break; } synchronized (mResourcesManager) { for (int i = packages.length - 1; i >= 0; i--) { WeakReference<LoadedApk> ref = mPackages.get(packages[i]); LoadedApk pkgInfo = ref != null ? ref.get() : null; if (pkgInfo != null) { hasPkgInfo = true; } else { ref = mResourcePackages.get(packages[i]); pkgInfo = ref != null ? ref.get() : null; if (pkgInfo != null) { hasPkgInfo = true; } } // If the package is being replaced, yet it still has a valid // LoadedApk object, the package was updated with _DONT_KILL. // Adjust it's internal references to the application info and // resources. if (pkgInfo != null) { try { final String packageName = packages[i]; final ApplicationInfo aInfo = sPackageManager.getApplicationInfo( packageName, 0 /*flags*/, UserHandle.myUserId()); if (mActivities.size() > 0) { for (ActivityClientRecord ar : mActivities.values()) { if (ar.activityInfo.applicationInfo.packageName .equals(packageName)) { ar.activityInfo.applicationInfo = aInfo; ar.packageInfo = pkgInfo; } } } final List<String> oldPaths = sPackageManager.getPreviousCodePaths(packageName); pkgInfo.updateApplicationInfo(aInfo, oldPaths); } catch (RemoteException e) { } } } } break; } } ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo); } final void handleLowMemory() { Loading
core/java/android/app/ApplicationLoaders.java +12 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,18 @@ class ApplicationLoaders { String libraryPermittedPath, boolean isShared); /** * Adds a new path the classpath of the given loader. * @throws IllegalStateException if the provided class loader is not a {@link PathClassLoader}. */ void addPath(ClassLoader classLoader, String dexPath) { if (!(classLoader instanceof PathClassLoader)) { throw new IllegalStateException("class loader is not a PathClassLoader"); } final PathClassLoader baseDexClassLoader = (PathClassLoader) classLoader; baseDexClassLoader.addDexPath(dexPath); } private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<String, ClassLoader>(); private static final ApplicationLoaders gApplicationLoaders Loading
core/java/android/app/IApplicationThread.java +5 −0 Original line number Diff line number Diff line Loading @@ -123,8 +123,13 @@ public interface IApplicationThread extends IInterface { void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) throws RemoteException; void setSchedulingGroup(int group) throws RemoteException; // the package has been removed, clean up internal references static final int PACKAGE_REMOVED = 0; static final int EXTERNAL_STORAGE_UNAVAILABLE = 1; // the package is being modified in-place, don't kill it and retain references to it static final int PACKAGE_REMOVED_DONT_KILL = 2; // a previously removed package was replaced with a new version [eg. upgrade, split added, ...] static final int PACKAGE_REPLACED = 3; void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException; void scheduleCrash(String msg) throws RemoteException; void dumpActivity(FileDescriptor fd, IBinder servicetoken, String prefix, String[] args) Loading
core/java/android/app/LoadedApk.java +203 −131 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ import java.lang.reflect.Method; import java.net.URL; import java.util.List; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.Objects; Loading @@ -83,24 +84,25 @@ public final class LoadedApk { private static final String TAG = "LoadedApk"; private final ActivityThread mActivityThread; private ApplicationInfo mApplicationInfo; final String mPackageName; private final String mAppDir; private final String mResDir; private final String[] mSplitAppDirs; private final String[] mSplitResDirs; private final String[] mOverlayDirs; private final String[] mSharedLibraries; private final String mDataDir; private final String mLibDir; private final File mDataDirFile; private final File mDeviceEncryptedDataDirFile; private final File mCredentialEncryptedDataDirFile; private ApplicationInfo mApplicationInfo; private String mAppDir; private String mResDir; private String[] mSplitAppDirs; private String[] mSplitResDirs; private String[] mOverlayDirs; private String[] mSharedLibraries; private String mDataDir; private String mLibDir; private File mDataDirFile; private File mDeviceEncryptedDataDirFile; private File mCredentialEncryptedDataDirFile; private final ClassLoader mBaseClassLoader; private final boolean mSecurityViolation; private final boolean mIncludeCode; private final boolean mRegisterPackage; private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments(); /** WARNING: This may change. Don't hold external references to it. */ Resources mResources; private ClassLoader mClassLoader; private Application mApplication; Loading Loading @@ -129,23 +131,10 @@ public final class LoadedApk { public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, boolean includeCode, boolean registerPackage) { final int myUid = Process.myUid(); aInfo = adjustNativeLibraryPaths(aInfo); mActivityThread = activityThread; mApplicationInfo = aInfo; setApplicationInfo(aInfo); mPackageName = aInfo.packageName; mAppDir = aInfo.sourceDir; mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir; mSplitAppDirs = aInfo.splitSourceDirs; mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs; mOverlayDirs = aInfo.resourceDirs; mSharedLibraries = aInfo.sharedLibraryFiles; mDataDir = aInfo.dataDir; mDataDirFile = FileUtils.newFileOrNull(mDataDir); mDeviceEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceEncryptedDataDir); mCredentialEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialEncryptedDataDir); mLibDir = aInfo.nativeLibraryDir; mBaseClassLoader = baseLoader; mSecurityViolation = securityViolation; mIncludeCode = includeCode; Loading Loading @@ -266,51 +255,74 @@ public final class LoadedApk { return ai.sharedLibraryFiles; } public ClassLoader getClassLoader() { synchronized (this) { if (mClassLoader != null) { return mClassLoader; } public void updateApplicationInfo(ApplicationInfo aInfo, List<String> oldPaths) { setApplicationInfo(aInfo); if (mPackageName.equals("android")) { if (mBaseClassLoader == null) { mClassLoader = ClassLoader.getSystemClassLoader(); final List<String> newPaths = new ArrayList<>(); makePaths(mActivityThread, aInfo, newPaths, null /*libPaths*/); final List<String> addedPaths = new ArrayList<>(newPaths.size()); if (oldPaths != null) { for (String path : newPaths) { final String apkName = path.substring(path.lastIndexOf(File.separator)); boolean match = false; for (String oldPath : oldPaths) { final String oldApkName = oldPath.substring(path.lastIndexOf(File.separator)); if (apkName.equals(oldApkName)) { match = true; break; } } if (!match) { addedPaths.add(path); } } } else { mClassLoader = mBaseClassLoader; addedPaths.addAll(newPaths); } return mClassLoader; synchronized (this) { mClassLoader = createOrUpdateClassLoaderLocked(addedPaths); if (mResources != null) { mResources = mActivityThread.getNewTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs, mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null /*overrideConfiguration*/, this); } // Avoid the binder call when the package is the current application package. // The activity manager will perform ensure that dexopt is performed before // spinning up the process. if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) { final String isa = VMRuntime.getRuntime().vmInstructionSet(); try { ActivityThread.getPackageManager().notifyPackageUse(mPackageName); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } final List<String> zipPaths = new ArrayList<>(); final List<String> apkPaths = new ArrayList<>(); final List<String> libPaths = new ArrayList<>(); if (mRegisterPackage) { try { ActivityManagerNative.getDefault().addPackageDependency(mPackageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } private void setApplicationInfo(ApplicationInfo aInfo) { final int myUid = Process.myUid(); aInfo = adjustNativeLibraryPaths(aInfo); mApplicationInfo = aInfo; mAppDir = aInfo.sourceDir; mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir; mSplitAppDirs = aInfo.splitSourceDirs; mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs; mOverlayDirs = aInfo.resourceDirs; mSharedLibraries = aInfo.sharedLibraryFiles; mDataDir = aInfo.dataDir; mLibDir = aInfo.nativeLibraryDir; mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir); mDeviceEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceEncryptedDataDir); mCredentialEncryptedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialEncryptedDataDir); } zipPaths.add(mAppDir); if (mSplitAppDirs != null) { Collections.addAll(zipPaths, mSplitAppDirs); public static void makePaths(ActivityThread activityThread, ApplicationInfo aInfo, List<String> outZipPaths, List<String> outLibPaths) { final String appDir = aInfo.sourceDir; final String[] splitAppDirs = aInfo.splitSourceDirs; final String libDir = aInfo.nativeLibraryDir; final String[] sharedLibraries = aInfo.sharedLibraryFiles; outZipPaths.clear(); outZipPaths.add(appDir); if (splitAppDirs != null) { Collections.addAll(outZipPaths, splitAppDirs); } libPaths.add(mLibDir); if (outLibPaths != null) { outLibPaths.clear(); } /* * The following is a bit of a hack to inject Loading @@ -321,75 +333,111 @@ public final class LoadedApk { * concatenation of both apps' shared library lists. */ String instrumentationPackageName = mActivityThread.mInstrumentationPackageName; String instrumentationAppDir = mActivityThread.mInstrumentationAppDir; String[] instrumentationSplitAppDirs = mActivityThread.mInstrumentationSplitAppDirs; String instrumentationLibDir = mActivityThread.mInstrumentationLibDir; String instrumentationPackageName = activityThread.mInstrumentationPackageName; String instrumentationAppDir = activityThread.mInstrumentationAppDir; String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs; String instrumentationLibDir = activityThread.mInstrumentationLibDir; String instrumentedAppDir = mActivityThread.mInstrumentedAppDir; String[] instrumentedSplitAppDirs = mActivityThread.mInstrumentedSplitAppDirs; String instrumentedLibDir = mActivityThread.mInstrumentedLibDir; String instrumentedAppDir = activityThread.mInstrumentedAppDir; String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs; String instrumentedLibDir = activityThread.mInstrumentedLibDir; String[] instrumentationLibs = null; if (mAppDir.equals(instrumentationAppDir) || mAppDir.equals(instrumentedAppDir)) { zipPaths.clear(); zipPaths.add(instrumentationAppDir); if (appDir.equals(instrumentationAppDir) || appDir.equals(instrumentedAppDir)) { outZipPaths.clear(); outZipPaths.add(instrumentationAppDir); if (instrumentationSplitAppDirs != null) { Collections.addAll(zipPaths, instrumentationSplitAppDirs); Collections.addAll(outZipPaths, instrumentationSplitAppDirs); } zipPaths.add(instrumentedAppDir); outZipPaths.add(instrumentedAppDir); if (instrumentedSplitAppDirs != null) { Collections.addAll(zipPaths, instrumentedSplitAppDirs); Collections.addAll(outZipPaths, instrumentedSplitAppDirs); } libPaths.clear(); libPaths.add(instrumentationLibDir); libPaths.add(instrumentedLibDir); if (outLibPaths != null) { outLibPaths.add(instrumentationLibDir); outLibPaths.add(instrumentedLibDir); } if (!instrumentedAppDir.equals(instrumentationAppDir)) { instrumentationLibs = getLibrariesFor(instrumentationPackageName); } } apkPaths.addAll(zipPaths); if (outLibPaths != null) { if (outLibPaths.isEmpty()) { outLibPaths.add(libDir); } // Add path to libraries in apk for current abi. Do this now because more entries // will be added to zipPaths that shouldn't be part of the library path. if (aInfo.primaryCpuAbi != null) { for (String apk : outZipPaths) { outLibPaths.add(apk + "!/lib/" + aInfo.primaryCpuAbi); } } if (aInfo.isSystemApp() && !aInfo.isUpdatedSystemApp()) { // Add path to system libraries to libPaths; // Access to system libs should be limited // to bundled applications; this is why updated // system apps are not included. outLibPaths.add(System.getProperty("java.library.path")); } } if (mSharedLibraries != null) { for (String lib : mSharedLibraries) { if (!zipPaths.contains(lib)) { zipPaths.add(0, lib); if (sharedLibraries != null) { for (String lib : sharedLibraries) { if (!outZipPaths.contains(lib)) { outZipPaths.add(0, lib); } } } if (instrumentationLibs != null) { for (String lib : instrumentationLibs) { if (!zipPaths.contains(lib)) { zipPaths.add(0, lib); if (!outZipPaths.contains(lib)) { outZipPaths.add(0, lib); } } } final String zip = mIncludeCode ? TextUtils.join(File.pathSeparator, zipPaths) : ""; final String zip = TextUtils.join(File.pathSeparator, outZipPaths); } // Add path to libraries in apk for current abi if (mApplicationInfo.primaryCpuAbi != null) { for (String apk : apkPaths) { libPaths.add(apk + "!/lib/" + mApplicationInfo.primaryCpuAbi); private ClassLoader createOrUpdateClassLoaderLocked(List<String> addedPaths) { final ClassLoader classLoader; if (mIncludeCode && !mPackageName.equals("android")) { // Avoid the binder call when the package is the current application package. // The activity manager will perform ensure that dexopt is performed before // spinning up the process. if (!Objects.equals(mPackageName, ActivityThread.currentPackageName())) { VMRuntime.getRuntime().vmInstructionSet(); try { ActivityThread.getPackageManager().notifyPackageUse(mPackageName); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } String libraryPermittedPath = mDataDir; boolean isBundledApp = false; final List<String> zipPaths = new ArrayList<>(); final List<String> libPaths = new ArrayList<>(); if (mApplicationInfo.isSystemApp() && !mApplicationInfo.isUpdatedSystemApp()) { isBundledApp = true; // Add path to system libraries to libPaths; // Access to system libs should be limited // to bundled applications; this is why updated // system apps are not included. libPaths.add(System.getProperty("java.library.path")); if (mRegisterPackage) { try { ActivityManagerNative.getDefault().addPackageDependency(mPackageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } makePaths(mActivityThread, mApplicationInfo, zipPaths, libPaths); final String zip = TextUtils.join(File.pathSeparator, zipPaths); final boolean isBundledApp = mApplicationInfo.isSystemApp() && !mApplicationInfo.isUpdatedSystemApp(); String libraryPermittedPath = mDataDir; if (isBundledApp) { // This is necessary to grant bundled apps access to // libraries located in subdirectories of /system/lib libraryPermittedPath += File.pathSeparator + Loading @@ -414,15 +462,42 @@ public final class LoadedApk { Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + librarySearchPath); if (mClassLoader == null) { // Temporarily disable logging of disk reads on the Looper thread // as this is early and necessary. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, classLoader = ApplicationLoaders.getDefault().getClassLoader(zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath, libraryPermittedPath, mBaseClassLoader); StrictMode.setThreadPolicy(oldPolicy); } else if (addedPaths != null && addedPaths.size() > 0) { final String add = TextUtils.join(File.pathSeparator, addedPaths); ApplicationLoaders.getDefault().addPath(mClassLoader, add); classLoader = mClassLoader; } else { classLoader = mClassLoader; } } else { if (mClassLoader == null) { if (mBaseClassLoader == null) { classLoader = ClassLoader.getSystemClassLoader(); } else { classLoader = mBaseClassLoader; } } else { classLoader = mClassLoader; } } return classLoader; } public ClassLoader getClassLoader() { synchronized (this) { if (mClassLoader == null) { mClassLoader = createOrUpdateClassLoaderLocked(null /*addedPaths*/); } return mClassLoader; } } Loading Loading @@ -1103,7 +1178,6 @@ public final class LoadedApk { private RuntimeException mUnbindLocation; private boolean mDied; private boolean mForgotten; private static class ConnectionInfo { Loading Loading @@ -1202,7 +1276,6 @@ public final class LoadedApk { ServiceDispatcher.ConnectionInfo old; synchronized (this) { mDied = true; old = mActiveConnections.remove(name); if (old == null || old.binder != service) { // Death for someone different than who we last Loading Loading @@ -1237,7 +1310,6 @@ public final class LoadedApk { if (service != null) { // A new service is being connected... set it all up. mDied = false; info = new ConnectionInfo(); info.binder = service; info.deathMonitor = new DeathMonitor(name, service); Loading
core/java/android/app/ResourcesManager.java +13 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes