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

Commit 20102bf1 authored by Salvador Martinez's avatar Salvador Martinez
Browse files

Revert "[WebView] Clean up code for finding paths and sizes of native libs"

This reverts commit dec7d603.

Change-Id: Ifc8e0c23e554f69abd18c01df95e56ab7dd55aec
parent dec7d603
Loading
Loading
Loading
Loading
+105 −124
Original line number Original line Diff line number Diff line
@@ -16,8 +16,6 @@


package android.webkit;
package android.webkit;


import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfo;
@@ -28,7 +26,6 @@ import android.os.SystemProperties;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.Log;
import android.util.Log;


import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.LocalServices;


import dalvik.system.VMRuntime;
import dalvik.system.VMRuntime;
@@ -39,11 +36,7 @@ import java.util.Arrays;
import java.util.zip.ZipEntry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipFile;


/**
class WebViewLibraryLoader {
 * @hide
 */
@VisibleForTesting
public class WebViewLibraryLoader {
    private static final String LOGTAG = WebViewLibraryLoader.class.getSimpleName();
    private static final String LOGTAG = WebViewLibraryLoader.class.getSimpleName();


    private static final String CHROMIUM_WEBVIEW_NATIVE_RELRO_32 =
    private static final String CHROMIUM_WEBVIEW_NATIVE_RELRO_32 =
@@ -101,7 +94,7 @@ public class WebViewLibraryLoader {
    /**
    /**
     * Create a single relro file by invoking an isolated process that to do the actual work.
     * Create a single relro file by invoking an isolated process that to do the actual work.
     */
     */
    static void createRelroFile(final boolean is64Bit, @NonNull WebViewNativeLibrary nativeLib) {
    static void createRelroFile(final boolean is64Bit, String nativeLibraryPath) {
        final String abi =
        final String abi =
                is64Bit ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
                is64Bit ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];


@@ -119,12 +112,12 @@ public class WebViewLibraryLoader {
        };
        };


        try {
        try {
            if (nativeLib == null || nativeLib.path == null) {
            if (nativeLibraryPath == null) {
                throw new IllegalArgumentException(
                throw new IllegalArgumentException(
                        "Native library paths to the WebView RelRo process must not be null!");
                        "Native library paths to the WebView RelRo process must not be null!");
            }
            }
            int pid = LocalServices.getService(ActivityManagerInternal.class).startIsolatedProcess(
            int pid = LocalServices.getService(ActivityManagerInternal.class).startIsolatedProcess(
                    RelroFileCreator.class.getName(), new String[] { nativeLib.path },
                    RelroFileCreator.class.getName(), new String[] { nativeLibraryPath },
                    "WebViewLoader-" + abi, abi, Process.SHARED_RELRO_UID, crashHandler);
                    "WebViewLoader-" + abi, abi, Process.SHARED_RELRO_UID, crashHandler);
            if (pid <= 0) throw new Exception("Failed to start the relro file creator process");
            if (pid <= 0) throw new Exception("Failed to start the relro file creator process");
        } catch (Throwable t) {
        } catch (Throwable t) {
@@ -134,49 +127,26 @@ public class WebViewLibraryLoader {
        }
        }
    }
    }


    /**
     * Perform preparations needed to allow loading WebView from an application. This method should
     * be called whenever we change WebView provider.
     * @return the number of relro processes started.
     */
    static int prepareNativeLibraries(PackageInfo webviewPackageInfo)
    static int prepareNativeLibraries(PackageInfo webviewPackageInfo)
            throws WebViewFactory.MissingWebViewPackageException {
            throws WebViewFactory.MissingWebViewPackageException {
        WebViewNativeLibrary nativeLib32bit =
        String[] nativeLibs = updateWebViewZygoteVmSize(webviewPackageInfo);
                getWebViewNativeLibrary(webviewPackageInfo, false /* is64bit */);
        WebViewNativeLibrary nativeLib64bit =
                getWebViewNativeLibrary(webviewPackageInfo, true /* is64bit */);
        updateWebViewZygoteVmSize(nativeLib32bit, nativeLib64bit);

        return createRelros(nativeLib32bit, nativeLib64bit);
    }

    /**
     * @return the number of relro processes started.
     */
    private static int createRelros(@Nullable WebViewNativeLibrary nativeLib32bit,
            @Nullable WebViewNativeLibrary nativeLib64bit) {
        if (DEBUG) Log.v(LOGTAG, "creating relro files");
        if (DEBUG) Log.v(LOGTAG, "creating relro files");
        int numRelros = 0;
        int numRelros = 0;


        // We must always trigger createRelRo regardless of the value of nativeLibraryPaths. Any
        // unexpected values will be handled there to ensure that we trigger notifying any process
        // waiting on relro creation.
        if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
        if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
            if (nativeLib32bit == null) {
                Log.e(LOGTAG, "No 32-bit WebView library path, skipping relro creation.");
            } else {
            if (DEBUG) Log.v(LOGTAG, "Create 32 bit relro");
            if (DEBUG) Log.v(LOGTAG, "Create 32 bit relro");
                createRelroFile(false /* is64Bit */, nativeLib32bit);
            createRelroFile(false /* is64Bit */, nativeLibs[0]);
            numRelros++;
            numRelros++;
        }
        }
        }


        if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
        if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
            if (nativeLib64bit == null) {
                Log.e(LOGTAG, "No 64-bit WebView library path, skipping relro creation.");
            } else {
            if (DEBUG) Log.v(LOGTAG, "Create 64 bit relro");
            if (DEBUG) Log.v(LOGTAG, "Create 64 bit relro");
                createRelroFile(true /* is64Bit */, nativeLib64bit);
            createRelroFile(true /* is64Bit */, nativeLibs[1]);
            numRelros++;
            numRelros++;
        }
        }
        }
        return numRelros;
        return numRelros;
    }
    }


@@ -184,16 +154,39 @@ public class WebViewLibraryLoader {
     *
     *
     * @return the native WebView libraries in the new WebView APK.
     * @return the native WebView libraries in the new WebView APK.
     */
     */
    private static void updateWebViewZygoteVmSize(
    private static String[] updateWebViewZygoteVmSize(PackageInfo packageInfo)
            @Nullable WebViewNativeLibrary nativeLib32bit,
            @Nullable WebViewNativeLibrary nativeLib64bit)
            throws WebViewFactory.MissingWebViewPackageException {
            throws WebViewFactory.MissingWebViewPackageException {
        // Find the native libraries of the new WebView package, to change the size of the
        // Find the native libraries of the new WebView package, to change the size of the
        // memory region in the Zygote reserved for the library.
        // memory region in the Zygote reserved for the library.
        String[] nativeLibs = getWebViewNativeLibraryPaths(packageInfo);
        if (nativeLibs != null) {
            long newVmSize = 0L;
            long newVmSize = 0L;


        if (nativeLib32bit != null) newVmSize = Math.max(newVmSize, nativeLib32bit.size);
            for (String path : nativeLibs) {
        if (nativeLib64bit != null) newVmSize = Math.max(newVmSize, nativeLib64bit.size);
                if (path == null || TextUtils.isEmpty(path)) continue;
                if (DEBUG) Log.d(LOGTAG, "Checking file size of " + path);
                File f = new File(path);
                if (f.exists()) {
                    newVmSize = Math.max(newVmSize, f.length());
                    continue;
                }
                if (path.contains("!/")) {
                    String[] split = TextUtils.split(path, "!/");
                    if (split.length == 2) {
                        try (ZipFile z = new ZipFile(split[0])) {
                            ZipEntry e = z.getEntry(split[1]);
                            if (e != null && e.getMethod() == ZipEntry.STORED) {
                                newVmSize = Math.max(newVmSize, e.getSize());
                                continue;
                            }
                        }
                        catch (IOException e) {
                            Log.e(LOGTAG, "error reading APK file " + split[0] + ", ", e);
                        }
                    }
                }
                Log.e(LOGTAG, "error sizing load for " + path);
            }


            if (DEBUG) {
            if (DEBUG) {
                Log.v(LOGTAG, "Based on library size, need " + newVmSize
                Log.v(LOGTAG, "Based on library size, need " + newVmSize
@@ -207,6 +200,8 @@ public class WebViewLibraryLoader {
            Log.d(LOGTAG, "Setting new address space to " + newVmSize);
            Log.d(LOGTAG, "Setting new address space to " + newVmSize);
            setWebViewZygoteVmSize(newVmSize);
            setWebViewZygoteVmSize(newVmSize);
        }
        }
        return nativeLibs;
    }


    /**
    /**
     * Reserve space for the native library to be loaded into.
     * Reserve space for the native library to be loaded into.
@@ -255,76 +250,62 @@ public class WebViewLibraryLoader {


    /**
    /**
     * Fetch WebView's native library paths from {@param packageInfo}.
     * Fetch WebView's native library paths from {@param packageInfo}.
     * @hide
     */
     */
    @Nullable
    static String[] getWebViewNativeLibraryPaths(PackageInfo packageInfo)
    @VisibleForTesting
            throws WebViewFactory.MissingWebViewPackageException {
    public static WebViewNativeLibrary getWebViewNativeLibrary(PackageInfo packageInfo,
            boolean is64bit) throws WebViewFactory.MissingWebViewPackageException {
        ApplicationInfo ai = packageInfo.applicationInfo;
        ApplicationInfo ai = packageInfo.applicationInfo;
        final String nativeLibFileName = WebViewFactory.getWebViewLibrary(ai);
        final String nativeLibFileName = WebViewFactory.getWebViewLibrary(ai);


        String dir = getWebViewNativeLibraryDirectory(ai, is64bit /* 64bit */);
        String path32;

        String path64;
        WebViewNativeLibrary lib = findNativeLibrary(ai, nativeLibFileName,
        boolean primaryArchIs64bit = VMRuntime.is64BitAbi(ai.primaryCpuAbi);
                is64bit ? Build.SUPPORTED_64_BIT_ABIS : Build.SUPPORTED_32_BIT_ABIS, dir);

        if (DEBUG) {
            Log.v(LOGTAG, String.format("Native %d-bit lib: %s", is64bit ? 64 : 32, lib.path));
        }
        return lib;
    }

    /**
     * @return the directory of the native WebView library with bitness {@param is64bit}.
     * @hide
     */
    @VisibleForTesting
    public static String getWebViewNativeLibraryDirectory(ApplicationInfo ai, boolean is64bit) {
        // Primary arch has the same bitness as the library we are looking for.
        if (is64bit == VMRuntime.is64BitAbi(ai.primaryCpuAbi)) return ai.nativeLibraryDir;

        // Secondary arch has the same bitness as the library we are looking for.
        if (!TextUtils.isEmpty(ai.secondaryCpuAbi)) {
        if (!TextUtils.isEmpty(ai.secondaryCpuAbi)) {
            return ai.secondaryNativeLibraryDir;
            // Multi-arch case.
            if (primaryArchIs64bit) {
                // Primary arch: 64-bit, secondary: 32-bit.
                path64 = ai.nativeLibraryDir;
                path32 = ai.secondaryNativeLibraryDir;
            } else {
                // Primary arch: 32-bit, secondary: 64-bit.
                path64 = ai.secondaryNativeLibraryDir;
                path32 = ai.nativeLibraryDir;
            }
        } else if (primaryArchIs64bit) {
            // Single-arch 64-bit.
            path64 = ai.nativeLibraryDir;
            path32 = "";
        } else {
            // Single-arch 32-bit.
            path32 = ai.nativeLibraryDir;
            path64 = "";
        }
        }


        return "";
        // Form the full paths to the extracted native libraries.
        // If libraries were not extracted, try load from APK paths instead.
        if (!TextUtils.isEmpty(path32)) {
            path32 += "/" + nativeLibFileName;
            File f = new File(path32);
            if (!f.exists()) {
                path32 = getLoadFromApkPath(ai.sourceDir,
                                            Build.SUPPORTED_32_BIT_ABIS,
                                            nativeLibFileName);
            }
            }

    /**
     * @return an object describing a native WebView library given the directory path of that
     * library, or null if the library couldn't be found.
     */
    @Nullable
    private static WebViewNativeLibrary findNativeLibrary(ApplicationInfo ai,
            String nativeLibFileName, String[] abiList, String libDirectory)
            throws WebViewFactory.MissingWebViewPackageException {
        if (TextUtils.isEmpty(libDirectory)) return null;
        String libPath = libDirectory + "/" + nativeLibFileName;
        File f = new File(libPath);
        if (f.exists()) {
            return new WebViewNativeLibrary(libPath, f.length());
        } else {
            return getLoadFromApkPath(ai.sourceDir, abiList, nativeLibFileName);
        }
        }
        if (!TextUtils.isEmpty(path64)) {
            path64 += "/" + nativeLibFileName;
            File f = new File(path64);
            if (!f.exists()) {
                path64 = getLoadFromApkPath(ai.sourceDir,
                                            Build.SUPPORTED_64_BIT_ABIS,
                                            nativeLibFileName);
            }
            }

    /**
     * @hide
     */
    @VisibleForTesting
    public static class WebViewNativeLibrary {
        public final String path;
        public final long size;

        WebViewNativeLibrary(String path, long size) {
            this.path = path;
            this.size = size;
        }
        }

        if (DEBUG) Log.v(LOGTAG, "Native 32-bit lib: " + path32 + ", 64-bit lib: " + path64);
        return new String[] { path32, path64 };
    }
    }


    private static WebViewNativeLibrary getLoadFromApkPath(String apkPath,
    private static String getLoadFromApkPath(String apkPath,
                                             String[] abiList,
                                             String[] abiList,
                                             String nativeLibFileName)
                                             String nativeLibFileName)
            throws WebViewFactory.MissingWebViewPackageException {
            throws WebViewFactory.MissingWebViewPackageException {
@@ -335,13 +316,13 @@ public class WebViewLibraryLoader {
                ZipEntry e = z.getEntry(entry);
                ZipEntry e = z.getEntry(entry);
                if (e != null && e.getMethod() == ZipEntry.STORED) {
                if (e != null && e.getMethod() == ZipEntry.STORED) {
                    // Return a path formatted for dlopen() load from APK.
                    // Return a path formatted for dlopen() load from APK.
                    return new WebViewNativeLibrary(apkPath + "!/" + entry, e.getSize());
                    return apkPath + "!/" + entry;
                }
                }
            }
            }
        } catch (IOException e) {
        } catch (IOException e) {
            throw new WebViewFactory.MissingWebViewPackageException(e);
            throw new WebViewFactory.MissingWebViewPackageException(e);
        }
        }
        return null;
        return "";
    }
    }


    /**
    /**

core/tests/webkit/Android.mk

deleted100644 → 0
+0 −44
Original line number Original line Diff line number Diff line
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

# We only want this apk build for tests.
LOCAL_MODULE_TAGS := tests

LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)


# Include all test java files.
LOCAL_SRC_FILES := \
	$(call all-java-files-under, unit_tests_src)

LOCAL_JAVA_LIBRARIES := android.test.runner

LOCAL_STATIC_JAVA_LIBRARIES := \
	android-support-test

LOCAL_PACKAGE_NAME := WebViewLoadingTests
LOCAL_CERTIFICATE := platform

LOCAL_COMPATIBILITY_SUITE := device-tests

LOCAL_ADDITIONAL_DEPENDENCIES := \
	WebViewLoadingOnDiskTestApk \
	WebViewLoadingFromApkTestApk

include $(BUILD_PACKAGE)

include $(call all-makefiles-under,$(LOCAL_PATH))
+0 −30
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.android.webkit.tests"
          android:sharedUserId="android.uid.system">

    <application>
        <uses-library android:name="android.test.runner" />
    </application>

    <instrumentation
            android:name="android.support.test.runner.AndroidJUnitRunner"
            android:targetPackage="com.android.webkit.tests"
            android:label="Frameworks WebView Loader Tests" />

</manifest>

core/tests/webkit/AndroidTest.xml

deleted100644 → 0
+0 −29
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<configuration description="Runs Frameworks WebView Loading Tests.">
    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
        <option name="test-file-name" value="WebViewLoadingTests.apk" />
        <option name="test-file-name" value="WebViewLoadingOnDiskTestApk.apk" />
        <option name="test-file-name" value="WebViewLoadingFromApkTestApk.apk" />
        <option name="cleanup-apks" value="true" />
        <option name="alt-dir" value="out" />
    </target_preparer>

    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
        <option name="package" value="com.android.webkit.tests" />
        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
    </test>
</configuration>
+0 −66
Original line number Original line Diff line number Diff line
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

LOCAL_PATH := $(call my-dir)
MY_PATH := $(LOCAL_PATH)

# Set shared variables
MY_MODULE_TAGS := optional
MY_JNI_SHARED_LIBRARIES := libwebviewtest_jni
MY_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
MY_SRC_FILES := $(call all-java-files-under, src)
MY_SDK_VERSION := system_current
MY_PROGUARD_ENABLED := disabled
MY_MULTILIB := both

# Recurse down the file tree.
include $(call all-subdir-makefiles)



# Builds an apk containing native libraries that will be unzipped on the device.
include $(CLEAR_VARS)

LOCAL_PATH := $(MY_PATH)
LOCAL_PACKAGE_NAME := WebViewLoadingOnDiskTestApk
LOCAL_MANIFEST_FILE := ondisk/AndroidManifest.xml

LOCAL_MODULE_TAGS := $(MY_MODULE_TAGS)
LOCAL_JNI_SHARED_LIBRARIES := $(MY_JNI_SHARED_LIBRARIES)
LOCAL_MODULE_PATH := $(MY_MODULE_PATH)
LOCAL_SRC_FILES := $(MY_SRC_FILES)
LOCAL_SDK_VERSION := $(MY_SDK_VERSION)
LOCAL_PROGUARD_ENABLED := $(MY_PROGUARD_ENABLED)
LOCAL_MULTILIB := $(MY_MULTILIB)

include $(BUILD_PACKAGE)


# Builds an apk containing uncompressed native libraries that have to be
# accessed through the APK itself on the device.
include $(CLEAR_VARS)

LOCAL_PATH := $(MY_PATH)
LOCAL_PACKAGE_NAME := WebViewLoadingFromApkTestApk
LOCAL_MANIFEST_FILE := inapk/AndroidManifest.xml

LOCAL_MODULE_TAGS := $(MY_MODULE_TAGS)
LOCAL_JNI_SHARED_LIBRARIES := $(MY_JNI_SHARED_LIBRARIES)
LOCAL_MODULE_PATH := $(MY_MODULE_PATH)
LOCAL_SRC_FILES := $(MY_SRC_FILES)
LOCAL_SDK_VERSION := $(MY_SDK_VERSION)
LOCAL_PROGUARD_ENABLED := $(MY_PROGUARD_ENABLED)
LOCAL_MULTILIB := $(MY_MULTILIB)

include $(BUILD_PACKAGE)
Loading