Loading core/java/android/app/ResourcesManager.java +35 −85 Original line number Diff line number Diff line Loading @@ -174,54 +174,22 @@ public class ResourcesManager { } /** * Apply the registered library paths to the passed AssetManager. If may create a new * AssetManager if any changes are needed and it isn't allowed to reuse the old one. * * @return new AssetManager and the hash code for the current version of the registered paths * Apply the registered library paths to the passed impl object * @return the hash code for the current version of the registered paths */ public @NonNull Pair<AssetManager, Integer> updateResourceImplAssetsWithRegisteredLibs( @NonNull AssetManager assets, boolean reuseAssets) { public int updateResourceImplWithRegisteredLibs(@NonNull ResourcesImpl impl) { if (!Flags.registerResourcePaths()) { return new Pair<>(assets, 0); return 0; } final int size; final PathCollector collector; synchronized (mLock) { size = mSharedLibAssetsMap.size(); if (assets == AssetManager.getSystem()) { return new Pair<>(assets, size); } collector = new PathCollector(resourcesKeyFromAssets(assets)); final var collector = new PathCollector(null); final int size = mSharedLibAssetsMap.size(); for (int i = 0; i < size; i++) { final var libraryKey = mSharedLibAssetsMap.valueAt(i).getResourcesKey(); collector.appendKey(libraryKey); } } if (collector.isSameAsOriginal()) { return new Pair<>(assets, size); } if (reuseAssets) { assets.addPresetApkKeys(extractApkKeys(collector.collectedKey())); return new Pair<>(assets, size); } final var newAssetsBuilder = new AssetManager.Builder(); for (final var asset : assets.getApkAssets()) { if (!asset.isForLoader()) { newAssetsBuilder.addApkAssets(asset); } } for (final var key : extractApkKeys(collector.collectedKey())) { try { final var asset = loadApkAssets(key); newAssetsBuilder.addApkAssets(asset); } catch (IOException e) { Log.e(TAG, "Couldn't load assets for key " + key, e); } } assets.getLoaders().forEach(newAssetsBuilder::addLoader); return new Pair<>(newAssetsBuilder.build(), size); impl.getAssets().addPresetApkKeys(extractApkKeys(collector.collectedKey())); return size; } public static class ApkKey { Loading Loading @@ -656,23 +624,6 @@ public class ResourcesManager { return apkKeys; } private ResourcesKey resourcesKeyFromAssets(@NonNull AssetManager assets) { final var libs = new ArrayList<String>(); final var overlays = new ArrayList<String>(); for (final ApkAssets asset : assets.getApkAssets()) { if (asset.isSystem() || asset.isForLoader()) { continue; } if (asset.isOverlay()) { overlays.add(asset.getAssetPath()); } else if (asset.isSharedLib()) { libs.add(asset.getAssetPath()); } } return new ResourcesKey(null, null, overlays.toArray(new String[0]), libs.toArray(new String[0]), 0, null, null); } /** * Creates an AssetManager from the paths within the ResourcesKey. * Loading Loading @@ -801,7 +752,7 @@ public class ResourcesManager { final Configuration config = generateConfig(key); final DisplayMetrics displayMetrics = getDisplayMetrics(generateDisplayId(key), daj); final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj, true); final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj); if (DEBUG) { Slog.d(TAG, "- creating impl=" + impl + " with key: " + key); Loading Loading @@ -1881,9 +1832,7 @@ public class ResourcesManager { for (int i = 0; i < resourcesCount; i++) { final WeakReference<Resources> ref = mAllResourceReferences.get(i); final Resources r = ref != null ? ref.get() : null; if (r == null) { continue; } if (r != null) { final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); if (key != null) { final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key); Loading @@ -1896,17 +1845,18 @@ public class ResourcesManager { // Resources created by application through Resources constructor and was not // managed by ResourcesManager, so the ResourcesImpl needs to be recreated to // have shared library asset paths appended if there are any. if (r.getImpl() != null) { final ResourcesImpl oldImpl = r.getImpl(); if (oldImpl != null) { final AssetManager oldAssets = oldImpl.getAssets(); // ResourcesImpl constructor will help to append shared library asset paths. if (oldAssets != AssetManager.getSystem()) { if (oldAssets.isUpToDate()) { final ResourcesImpl newImpl = new ResourcesImpl(oldImpl); if (oldAssets != AssetManager.getSystem() && oldAssets.isUpToDate()) { final ResourcesImpl newImpl = new ResourcesImpl(oldAssets, oldImpl.getMetrics(), oldImpl.getConfiguration(), oldImpl.getDisplayAdjustments()); r.setImpl(newImpl); } else { Slog.w(TAG, "Skip appending shared library asset paths for " + "the Resources as its assets are not up to date."); Slog.w(TAG, "Skip appending shared library asset paths for the " + "Resource as its assets are not up to date."); } } } Loading core/java/android/content/res/ApkAssets.java +8 −25 Original line number Diff line number Diff line Loading @@ -124,13 +124,11 @@ public final class ApkAssets { @Nullable @GuardedBy("this") private StringBlock mStringBlock; // null or closed if mNativePtr = 0. private final StringBlock mStringBlock; // null or closed if mNativePtr = 0. @PropertyFlags private final int mFlags; private final boolean mIsOverlay; @Nullable private final AssetsProvider mAssets; Loading Loading @@ -304,43 +302,40 @@ public final class ApkAssets { private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { this(format, flags, assets); Objects.requireNonNull(path, "path"); mFlags = flags; mNativePtr = nativeLoad(format, path, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); mAssets = assets; } private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { this(format, flags, assets); Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mFlags = flags; mNativePtr = nativeLoadFd(format, fd, friendlyName, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); mAssets = assets; } private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { this(format, flags, assets); Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mFlags = flags; mNativePtr = nativeLoadFdOffsets(format, fd, friendlyName, offset, length, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); mAssets = assets; } private ApkAssets(@PropertyFlags int flags, @Nullable AssetsProvider assets) { this(FORMAT_APK, flags, assets); mFlags = flags; mNativePtr = nativeLoadEmpty(flags, assets); mStringBlock = null; } private ApkAssets(@FormatType int format, @PropertyFlags int flags, @Nullable AssetsProvider assets) { mFlags = flags; mAssets = assets; mIsOverlay = format == FORMAT_IDMAP; } @UnsupportedAppUsage Loading Loading @@ -430,18 +425,6 @@ public final class ApkAssets { } } public boolean isSystem() { return (mFlags & PROPERTY_SYSTEM) != 0; } public boolean isSharedLib() { return (mFlags & PROPERTY_DYNAMIC) != 0; } public boolean isOverlay() { return mIsOverlay; } @Override public String toString() { return "ApkAssets{path=" + getDebugName() + "}"; Loading core/java/android/content/res/ResourcesImpl.java +3 −19 Original line number Diff line number Diff line Loading @@ -203,25 +203,9 @@ public class ResourcesImpl { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics, @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments) { // Don't reuse assets by default as we have no control over whether they're already // inside some other ResourcesImpl. this(assets, metrics, config, displayAdjustments, false); } public ResourcesImpl(@NonNull ResourcesImpl orig) { // We know for sure that the other assets are in use, so can't reuse the object here. this(orig.getAssets(), orig.getMetrics(), orig.getConfiguration(), orig.getDisplayAdjustments(), false); } public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics, @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments, boolean reuseAssets) { final var assetsAndHash = ResourcesManager.getInstance().updateResourceImplAssetsWithRegisteredLibs(assets, reuseAssets); mAssets = assetsAndHash.first; mAppliedSharedLibsHash = assetsAndHash.second; mAssets = assets; mAppliedSharedLibsHash = ResourcesManager.getInstance().updateResourceImplWithRegisteredLibs(this); mMetrics.setToDefaults(); mDisplayAdjustments = displayAdjustments; mConfiguration.setToDefaults(); Loading Loading
core/java/android/app/ResourcesManager.java +35 −85 Original line number Diff line number Diff line Loading @@ -174,54 +174,22 @@ public class ResourcesManager { } /** * Apply the registered library paths to the passed AssetManager. If may create a new * AssetManager if any changes are needed and it isn't allowed to reuse the old one. * * @return new AssetManager and the hash code for the current version of the registered paths * Apply the registered library paths to the passed impl object * @return the hash code for the current version of the registered paths */ public @NonNull Pair<AssetManager, Integer> updateResourceImplAssetsWithRegisteredLibs( @NonNull AssetManager assets, boolean reuseAssets) { public int updateResourceImplWithRegisteredLibs(@NonNull ResourcesImpl impl) { if (!Flags.registerResourcePaths()) { return new Pair<>(assets, 0); return 0; } final int size; final PathCollector collector; synchronized (mLock) { size = mSharedLibAssetsMap.size(); if (assets == AssetManager.getSystem()) { return new Pair<>(assets, size); } collector = new PathCollector(resourcesKeyFromAssets(assets)); final var collector = new PathCollector(null); final int size = mSharedLibAssetsMap.size(); for (int i = 0; i < size; i++) { final var libraryKey = mSharedLibAssetsMap.valueAt(i).getResourcesKey(); collector.appendKey(libraryKey); } } if (collector.isSameAsOriginal()) { return new Pair<>(assets, size); } if (reuseAssets) { assets.addPresetApkKeys(extractApkKeys(collector.collectedKey())); return new Pair<>(assets, size); } final var newAssetsBuilder = new AssetManager.Builder(); for (final var asset : assets.getApkAssets()) { if (!asset.isForLoader()) { newAssetsBuilder.addApkAssets(asset); } } for (final var key : extractApkKeys(collector.collectedKey())) { try { final var asset = loadApkAssets(key); newAssetsBuilder.addApkAssets(asset); } catch (IOException e) { Log.e(TAG, "Couldn't load assets for key " + key, e); } } assets.getLoaders().forEach(newAssetsBuilder::addLoader); return new Pair<>(newAssetsBuilder.build(), size); impl.getAssets().addPresetApkKeys(extractApkKeys(collector.collectedKey())); return size; } public static class ApkKey { Loading Loading @@ -656,23 +624,6 @@ public class ResourcesManager { return apkKeys; } private ResourcesKey resourcesKeyFromAssets(@NonNull AssetManager assets) { final var libs = new ArrayList<String>(); final var overlays = new ArrayList<String>(); for (final ApkAssets asset : assets.getApkAssets()) { if (asset.isSystem() || asset.isForLoader()) { continue; } if (asset.isOverlay()) { overlays.add(asset.getAssetPath()); } else if (asset.isSharedLib()) { libs.add(asset.getAssetPath()); } } return new ResourcesKey(null, null, overlays.toArray(new String[0]), libs.toArray(new String[0]), 0, null, null); } /** * Creates an AssetManager from the paths within the ResourcesKey. * Loading Loading @@ -801,7 +752,7 @@ public class ResourcesManager { final Configuration config = generateConfig(key); final DisplayMetrics displayMetrics = getDisplayMetrics(generateDisplayId(key), daj); final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj, true); final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj); if (DEBUG) { Slog.d(TAG, "- creating impl=" + impl + " with key: " + key); Loading Loading @@ -1881,9 +1832,7 @@ public class ResourcesManager { for (int i = 0; i < resourcesCount; i++) { final WeakReference<Resources> ref = mAllResourceReferences.get(i); final Resources r = ref != null ? ref.get() : null; if (r == null) { continue; } if (r != null) { final ResourcesKey key = updatedResourceKeys.get(r.getImpl()); if (key != null) { final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key); Loading @@ -1896,17 +1845,18 @@ public class ResourcesManager { // Resources created by application through Resources constructor and was not // managed by ResourcesManager, so the ResourcesImpl needs to be recreated to // have shared library asset paths appended if there are any. if (r.getImpl() != null) { final ResourcesImpl oldImpl = r.getImpl(); if (oldImpl != null) { final AssetManager oldAssets = oldImpl.getAssets(); // ResourcesImpl constructor will help to append shared library asset paths. if (oldAssets != AssetManager.getSystem()) { if (oldAssets.isUpToDate()) { final ResourcesImpl newImpl = new ResourcesImpl(oldImpl); if (oldAssets != AssetManager.getSystem() && oldAssets.isUpToDate()) { final ResourcesImpl newImpl = new ResourcesImpl(oldAssets, oldImpl.getMetrics(), oldImpl.getConfiguration(), oldImpl.getDisplayAdjustments()); r.setImpl(newImpl); } else { Slog.w(TAG, "Skip appending shared library asset paths for " + "the Resources as its assets are not up to date."); Slog.w(TAG, "Skip appending shared library asset paths for the " + "Resource as its assets are not up to date."); } } } Loading
core/java/android/content/res/ApkAssets.java +8 −25 Original line number Diff line number Diff line Loading @@ -124,13 +124,11 @@ public final class ApkAssets { @Nullable @GuardedBy("this") private StringBlock mStringBlock; // null or closed if mNativePtr = 0. private final StringBlock mStringBlock; // null or closed if mNativePtr = 0. @PropertyFlags private final int mFlags; private final boolean mIsOverlay; @Nullable private final AssetsProvider mAssets; Loading Loading @@ -304,43 +302,40 @@ public final class ApkAssets { private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { this(format, flags, assets); Objects.requireNonNull(path, "path"); mFlags = flags; mNativePtr = nativeLoad(format, path, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); mAssets = assets; } private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { this(format, flags, assets); Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mFlags = flags; mNativePtr = nativeLoadFd(format, fd, friendlyName, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); mAssets = assets; } private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException { this(format, flags, assets); Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mFlags = flags; mNativePtr = nativeLoadFdOffsets(format, fd, friendlyName, offset, length, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); mAssets = assets; } private ApkAssets(@PropertyFlags int flags, @Nullable AssetsProvider assets) { this(FORMAT_APK, flags, assets); mFlags = flags; mNativePtr = nativeLoadEmpty(flags, assets); mStringBlock = null; } private ApkAssets(@FormatType int format, @PropertyFlags int flags, @Nullable AssetsProvider assets) { mFlags = flags; mAssets = assets; mIsOverlay = format == FORMAT_IDMAP; } @UnsupportedAppUsage Loading Loading @@ -430,18 +425,6 @@ public final class ApkAssets { } } public boolean isSystem() { return (mFlags & PROPERTY_SYSTEM) != 0; } public boolean isSharedLib() { return (mFlags & PROPERTY_DYNAMIC) != 0; } public boolean isOverlay() { return mIsOverlay; } @Override public String toString() { return "ApkAssets{path=" + getDebugName() + "}"; Loading
core/java/android/content/res/ResourcesImpl.java +3 −19 Original line number Diff line number Diff line Loading @@ -203,25 +203,9 @@ public class ResourcesImpl { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics, @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments) { // Don't reuse assets by default as we have no control over whether they're already // inside some other ResourcesImpl. this(assets, metrics, config, displayAdjustments, false); } public ResourcesImpl(@NonNull ResourcesImpl orig) { // We know for sure that the other assets are in use, so can't reuse the object here. this(orig.getAssets(), orig.getMetrics(), orig.getConfiguration(), orig.getDisplayAdjustments(), false); } public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics, @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments, boolean reuseAssets) { final var assetsAndHash = ResourcesManager.getInstance().updateResourceImplAssetsWithRegisteredLibs(assets, reuseAssets); mAssets = assetsAndHash.first; mAppliedSharedLibsHash = assetsAndHash.second; mAssets = assets; mAppliedSharedLibsHash = ResourcesManager.getInstance().updateResourceImplWithRegisteredLibs(this); mMetrics.setToDefaults(); mDisplayAdjustments = displayAdjustments; mConfiguration.setToDefaults(); Loading