Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4152a9c authored by Adam Lesinski's avatar Adam Lesinski Committed by android-build-merger
Browse files

Merge \\"ResourcesManager: Allow managed addition of library asset paths\\"...

Merge \\"ResourcesManager: Allow managed addition of library asset paths\\" into nyc-dev am: 464bda8a
am: c3ab1b7c

Change-Id: I6d268a2d0871de19a57358ff7755c525906aae1c
parents 960187cf c3ab1b7c
Loading
Loading
Loading
Loading
+88 −1
Original line number Diff line number Diff line
@@ -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.");
                    }
@@ -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.
@@ -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));
                        }
                    }
                }
            }
        }
    }
}
+28 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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}.
@@ -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);
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -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++;
    }