Loading core/java/android/app/ResourcesManager.java +88 −1 Original line number Diff line number Diff line Loading @@ -274,7 +274,7 @@ public class ResourcesManager { if (libDir.endsWith(".apk")) { // Avoid opening files we know do not have resources, // like code-only .jar files. if (assets.addAssetPath(libDir) == 0) { if (assets.addAssetPathAsSharedLibrary(libDir) == 0) { Log.w(TAG, "Asset path '" + libDir + "' does not exist or contains no resources."); } Loading Loading @@ -329,6 +329,22 @@ public class ResourcesManager { return null; } /** * Finds a cached ResourcesImpl object that matches the given ResourcesKey, or * creates a new one and caches it for future use. * @param key The key to match. * @return a ResourcesImpl object matching the key. */ private @NonNull ResourcesImpl findOrCreateResourcesImplForKeyLocked( @NonNull ResourcesKey key) { ResourcesImpl impl = findResourcesImplForKeyLocked(key); if (impl == null) { impl = createResourcesImpl(key); mResourceImpls.put(key, new WeakReference<>(impl)); } return impl; } /** * Find the ResourcesKey that this ResourcesImpl object is associated with. * @return the ResourcesKey or null if none was found. Loading Loading @@ -811,4 +827,75 @@ public class ResourcesManager { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } /** * Appends the library asset path to any ResourcesImpl object that contains the main * assetPath. * @param assetPath The main asset path for which to add the library asset path. * @param libAsset The library asset path to add. */ public void appendLibAssetForMainAssetPath(String assetPath, String libAsset) { synchronized (this) { // Record which ResourcesImpl need updating // (and what ResourcesKey they should update to). final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>(); final int implCount = mResourceImpls.size(); for (int i = 0; i < implCount; i++) { final ResourcesImpl impl = mResourceImpls.valueAt(i).get(); final ResourcesKey key = mResourceImpls.keyAt(i); if (impl != null && key.mResDir.equals(assetPath)) { if (!ArrayUtils.contains(key.mLibDirs, libAsset)) { final int newLibAssetCount = 1 + (key.mLibDirs != null ? key.mLibDirs.length : 0); final String[] newLibAssets = new String[newLibAssetCount]; if (key.mLibDirs != null) { System.arraycopy(key.mLibDirs, 0, newLibAssets, 0, key.mLibDirs.length); } newLibAssets[newLibAssetCount - 1] = libAsset; updatedResourceKeys.put(impl, new ResourcesKey( key.mResDir, key.mSplitResDirs, key.mOverlayDirs, newLibAssets, key.mDisplayId, key.mOverrideConfiguration, key.mCompatInfo)); } } } // Bail early if there is no work to do. if (updatedResourceKeys.isEmpty()) { return; } // Update any references to ResourcesImpl that require reloading. final int resourcesCount = mResourceReferences.size(); for (int i = 0; i < resourcesCount; i++) { final Resources r = mResourceReferences.get(i).get(); if (r != null) { final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); if (key != null) { r.setImpl(findOrCreateResourcesImplForKeyLocked(key)); } } } // Update any references to ResourcesImpl that require reloading for each Activity. for (ActivityResources activityResources : mActivityResourceReferences.values()) { final int resCount = activityResources.activityResources.size(); for (int i = 0; i < resCount; i++) { final Resources r = activityResources.activityResources.get(i).get(); if (r != null) { final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); if (key != null) { r.setImpl(findOrCreateResourcesImplForKeyLocked(key)); } } } } } } } core/java/android/webkit/WebViewDelegate.java +28 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.ActivityThread; import android.app.Application; import android.app.ResourcesManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.graphics.Canvas; import android.os.SystemProperties; Loading @@ -31,6 +33,8 @@ import android.view.DisplayListCanvas; import android.view.View; import android.view.ViewRootImpl; import com.android.internal.util.ArrayUtils; /** * Delegate used by the WebView provider implementation to access * the required framework functionality needed to implement a {@link WebView}. Loading Loading @@ -177,7 +181,29 @@ public final class WebViewDelegate { * Adds the WebView asset path to {@link android.content.res.AssetManager}. */ public void addWebViewAssetPath(Context context) { context.getAssets().addAssetPathAsSharedLibrary( WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir); final String newAssetPath = WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir; final ApplicationInfo appInfo = context.getApplicationInfo(); final String[] libs = appInfo.sharedLibraryFiles; if (!ArrayUtils.contains(libs, newAssetPath)) { // Build the new library asset path list. final int newLibAssetsCount = 1 + (libs != null ? libs.length : 0); final String[] newLibAssets = new String[newLibAssetsCount]; if (libs != null) { System.arraycopy(libs, 0, newLibAssets, 0, libs.length); } newLibAssets[newLibAssetsCount - 1] = newAssetPath; // Update the ApplicationInfo object with the new list. // We know this will persist and future Resources created via ResourcesManager // will include the shared library because this ApplicationInfo comes from the // underlying LoadedApk in ContextImpl, which does not change during the life of the // application. appInfo.sharedLibraryFiles = newLibAssets; // Update existing Resources with the WebView library. ResourcesManager.getInstance().appendLibAssetForMainAssetPath( appInfo.getBaseResourcePath(), newAssetPath); } } } libs/androidfw/ResourceTypes.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -6174,7 +6174,7 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, if (id >= 256) { LOG_ALWAYS_FATAL("Package id out of range"); return NO_ERROR; } else if (id == 0 || appAsLib || isSystemAsset) { } else if (id == 0 || (id == 0x7f && appAsLib) || isSystemAsset) { // This is a library or a system asset, so assign an ID id = mNextPackageId++; } Loading Loading
core/java/android/app/ResourcesManager.java +88 −1 Original line number Diff line number Diff line Loading @@ -274,7 +274,7 @@ public class ResourcesManager { if (libDir.endsWith(".apk")) { // Avoid opening files we know do not have resources, // like code-only .jar files. if (assets.addAssetPath(libDir) == 0) { if (assets.addAssetPathAsSharedLibrary(libDir) == 0) { Log.w(TAG, "Asset path '" + libDir + "' does not exist or contains no resources."); } Loading Loading @@ -329,6 +329,22 @@ public class ResourcesManager { return null; } /** * Finds a cached ResourcesImpl object that matches the given ResourcesKey, or * creates a new one and caches it for future use. * @param key The key to match. * @return a ResourcesImpl object matching the key. */ private @NonNull ResourcesImpl findOrCreateResourcesImplForKeyLocked( @NonNull ResourcesKey key) { ResourcesImpl impl = findResourcesImplForKeyLocked(key); if (impl == null) { impl = createResourcesImpl(key); mResourceImpls.put(key, new WeakReference<>(impl)); } return impl; } /** * Find the ResourcesKey that this ResourcesImpl object is associated with. * @return the ResourcesKey or null if none was found. Loading Loading @@ -811,4 +827,75 @@ public class ResourcesManager { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } } /** * Appends the library asset path to any ResourcesImpl object that contains the main * assetPath. * @param assetPath The main asset path for which to add the library asset path. * @param libAsset The library asset path to add. */ public void appendLibAssetForMainAssetPath(String assetPath, String libAsset) { synchronized (this) { // Record which ResourcesImpl need updating // (and what ResourcesKey they should update to). final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>(); final int implCount = mResourceImpls.size(); for (int i = 0; i < implCount; i++) { final ResourcesImpl impl = mResourceImpls.valueAt(i).get(); final ResourcesKey key = mResourceImpls.keyAt(i); if (impl != null && key.mResDir.equals(assetPath)) { if (!ArrayUtils.contains(key.mLibDirs, libAsset)) { final int newLibAssetCount = 1 + (key.mLibDirs != null ? key.mLibDirs.length : 0); final String[] newLibAssets = new String[newLibAssetCount]; if (key.mLibDirs != null) { System.arraycopy(key.mLibDirs, 0, newLibAssets, 0, key.mLibDirs.length); } newLibAssets[newLibAssetCount - 1] = libAsset; updatedResourceKeys.put(impl, new ResourcesKey( key.mResDir, key.mSplitResDirs, key.mOverlayDirs, newLibAssets, key.mDisplayId, key.mOverrideConfiguration, key.mCompatInfo)); } } } // Bail early if there is no work to do. if (updatedResourceKeys.isEmpty()) { return; } // Update any references to ResourcesImpl that require reloading. final int resourcesCount = mResourceReferences.size(); for (int i = 0; i < resourcesCount; i++) { final Resources r = mResourceReferences.get(i).get(); if (r != null) { final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); if (key != null) { r.setImpl(findOrCreateResourcesImplForKeyLocked(key)); } } } // Update any references to ResourcesImpl that require reloading for each Activity. for (ActivityResources activityResources : mActivityResourceReferences.values()) { final int resCount = activityResources.activityResources.size(); for (int i = 0; i < resCount; i++) { final Resources r = activityResources.activityResources.get(i).get(); if (r != null) { final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); if (key != null) { r.setImpl(findOrCreateResourcesImplForKeyLocked(key)); } } } } } } }
core/java/android/webkit/WebViewDelegate.java +28 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.ActivityThread; import android.app.Application; import android.app.ResourcesManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.graphics.Canvas; import android.os.SystemProperties; Loading @@ -31,6 +33,8 @@ import android.view.DisplayListCanvas; import android.view.View; import android.view.ViewRootImpl; import com.android.internal.util.ArrayUtils; /** * Delegate used by the WebView provider implementation to access * the required framework functionality needed to implement a {@link WebView}. Loading Loading @@ -177,7 +181,29 @@ public final class WebViewDelegate { * Adds the WebView asset path to {@link android.content.res.AssetManager}. */ public void addWebViewAssetPath(Context context) { context.getAssets().addAssetPathAsSharedLibrary( WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir); final String newAssetPath = WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir; final ApplicationInfo appInfo = context.getApplicationInfo(); final String[] libs = appInfo.sharedLibraryFiles; if (!ArrayUtils.contains(libs, newAssetPath)) { // Build the new library asset path list. final int newLibAssetsCount = 1 + (libs != null ? libs.length : 0); final String[] newLibAssets = new String[newLibAssetsCount]; if (libs != null) { System.arraycopy(libs, 0, newLibAssets, 0, libs.length); } newLibAssets[newLibAssetsCount - 1] = newAssetPath; // Update the ApplicationInfo object with the new list. // We know this will persist and future Resources created via ResourcesManager // will include the shared library because this ApplicationInfo comes from the // underlying LoadedApk in ContextImpl, which does not change during the life of the // application. appInfo.sharedLibraryFiles = newLibAssets; // Update existing Resources with the WebView library. ResourcesManager.getInstance().appendLibAssetForMainAssetPath( appInfo.getBaseResourcePath(), newAssetPath); } } }
libs/androidfw/ResourceTypes.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -6174,7 +6174,7 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, if (id >= 256) { LOG_ALWAYS_FATAL("Package id out of range"); return NO_ERROR; } else if (id == 0 || appAsLib || isSystemAsset) { } else if (id == 0 || (id == 0x7f && appAsLib) || isSystemAsset) { // This is a library or a system asset, so assign an ID id = mNextPackageId++; } Loading