Merge \"ResourcesManager: Allow managed addition of library asset paths\" into nyc-dev
am: 464bda8a2b
Change-Id: I352c56482aca030efab49ca39301679b51e44e05
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user