Handle WebView assets correctly when multiple APKs are used.
Add all splits and shared libraries used by the WebView implementation to the application's asset path, instead of just the base APK. Fix the asset manipulation code path in WebViewFactory to reuse the modern implementation in WebViewDelegate (using appendLibAssetForMainAssetPath) instead of relying on addAssetPathAsSharedLibrary. Add a new variant of appendLibAssetForMainAssetPath which accepts multiple paths at once, to make it more efficient. Bug: 124116212 Test: atest CtsWebkitTestCases Change-Id: Ie55525d78089a4595c5b0b126e4ff1530303afe8
This commit is contained in:
@@ -1091,6 +1091,16 @@ public class ResourcesManager {
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public void appendLibAssetForMainAssetPath(String assetPath, String libAsset) {
|
||||
appendLibAssetsForMainAssetPath(assetPath, new String[] { libAsset });
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the library asset paths to any ResourcesImpl object that contains the main
|
||||
* assetPath.
|
||||
* @param assetPath The main asset path for which to add the library asset path.
|
||||
* @param libAssets The library asset paths to add.
|
||||
*/
|
||||
public void appendLibAssetsForMainAssetPath(String assetPath, String[] libAssets) {
|
||||
synchronized (this) {
|
||||
// Record which ResourcesImpl need updating
|
||||
// (and what ResourcesKey they should update to).
|
||||
@@ -1102,15 +1112,13 @@ public class ResourcesManager {
|
||||
final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
|
||||
final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
|
||||
if (impl != null && Objects.equals(key.mResDir, 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;
|
||||
String[] newLibAssets = key.mLibDirs;
|
||||
for (String libAsset : libAssets) {
|
||||
newLibAssets =
|
||||
ArrayUtils.appendElement(String.class, newLibAssets, libAsset);
|
||||
}
|
||||
|
||||
if (newLibAssets != key.mLibDirs) {
|
||||
updatedResourceKeys.put(impl, new ResourcesKey(
|
||||
key.mResDir,
|
||||
key.mSplitResDirs,
|
||||
|
||||
@@ -209,19 +209,17 @@ public final class WebViewDelegate {
|
||||
* Adds the WebView asset path to {@link android.content.res.AssetManager}.
|
||||
*/
|
||||
public void addWebViewAssetPath(Context context) {
|
||||
final String newAssetPath = WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir;
|
||||
|
||||
final String[] newAssetPaths =
|
||||
WebViewFactory.getLoadedPackageInfo().applicationInfo.getAllApkPaths();
|
||||
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;
|
||||
|
||||
// Build the new library asset path list.
|
||||
String[] newLibAssets = appInfo.sharedLibraryFiles;
|
||||
for (String newAssetPath : newAssetPaths) {
|
||||
newLibAssets = ArrayUtils.appendElement(String.class, newLibAssets, newAssetPath);
|
||||
}
|
||||
|
||||
if (newLibAssets != appInfo.sharedLibraryFiles) {
|
||||
// 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
|
||||
@@ -230,8 +228,8 @@ public final class WebViewDelegate {
|
||||
appInfo.sharedLibraryFiles = newLibAssets;
|
||||
|
||||
// Update existing Resources with the WebView library.
|
||||
ResourcesManager.getInstance().appendLibAssetForMainAssetPath(
|
||||
appInfo.getBaseResourcePath(), newAssetPath);
|
||||
ResourcesManager.getInstance().appendLibAssetsForMainAssetPath(
|
||||
appInfo.getBaseResourcePath(), newAssetPaths);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -448,8 +448,7 @@ public final class WebViewFactory {
|
||||
|
||||
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getChromiumProviderClass()");
|
||||
try {
|
||||
initialApplication.getAssets().addAssetPathAsSharedLibrary(
|
||||
webViewContext.getApplicationInfo().sourceDir);
|
||||
new WebViewDelegate().addWebViewAssetPath(initialApplication);
|
||||
ClassLoader clazzLoader = webViewContext.getClassLoader();
|
||||
|
||||
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()");
|
||||
|
||||
Reference in New Issue
Block a user