From 06d019ef0a21f6765cc477f30f7ef60526f20d82 Mon Sep 17 00:00:00 2001 From: Gustav Sennton Date: Wed, 21 Jun 2017 18:03:49 +0100 Subject: Move the WebView loader to frameworks/base. Bug: 62445369 Test: run WebView using app and ensure it loads WebView. Change-Id: I8d5f85a746203222bfb582317e5caff44cf06724 --- chromium/Android.mk | 25 +---- chromium/loader/loader.cpp | 261 --------------------------------------------- 2 files changed, 1 insertion(+), 285 deletions(-) delete mode 100644 chromium/loader/loader.cpp diff --git a/chromium/Android.mk b/chromium/Android.mk index 7595858..1e92077 100644 --- a/chromium/Android.mk +++ b/chromium/Android.mk @@ -14,8 +14,7 @@ # limitations under the License. # -# This package provides the system interfaces required to load WebView and allow -# it to render. +# This package provides the system interfaces allowing WebView to render. LOCAL_PATH := $(call my-dir) @@ -52,25 +51,3 @@ LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS := -Wno-unused-parameter include $(BUILD_SHARED_LIBRARY) - - -# Loader library which handles address space reservation and relro sharing. -# Does NOT link any native chromium code. -include $(CLEAR_VARS) - -LOCAL_MODULE:= libwebviewchromium_loader - -LOCAL_SRC_FILES := \ - loader/loader.cpp \ - -LOCAL_CFLAGS := \ - -Werror \ - -LOCAL_SHARED_LIBRARIES += \ - libdl \ - liblog \ - libnativeloader \ - -LOCAL_MODULE_TAGS := optional - -include $(BUILD_SHARED_LIBRARY) diff --git a/chromium/loader/loader.cpp b/chromium/loader/loader.cpp deleted file mode 100644 index 565c6b0..0000000 --- a/chromium/loader/loader.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2014 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. - */ - -// Uncomment for verbose logging. -// #define LOG_NDEBUG 0 -#define LOG_TAG "webviewchromiumloader" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) - -namespace android { -namespace { - -void* gReservedAddress = NULL; -size_t gReservedSize = 0; - -jint LIBLOAD_SUCCESS; -jint LIBLOAD_FAILED_TO_OPEN_RELRO_FILE; -jint LIBLOAD_FAILED_TO_LOAD_LIBRARY; -jint LIBLOAD_FAILED_JNI_CALL; -jint LIBLOAD_FAILED_TO_FIND_NAMESPACE; - -jboolean DoReserveAddressSpace(jlong size) { - size_t vsize = static_cast(size); - - void* addr = mmap(NULL, vsize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (addr == MAP_FAILED) { - ALOGE("Failed to reserve %zd bytes of address space for future load of " - "libwebviewchromium.so: %s", - vsize, strerror(errno)); - return JNI_FALSE; - } - gReservedAddress = addr; - gReservedSize = vsize; - ALOGV("Reserved %zd bytes at %p", vsize, addr); - return JNI_TRUE; -} - -jboolean DoCreateRelroFile(const char* lib, const char* relro) { - // Try to unlink the old file, since if this is being called, the old one is - // obsolete. - if (unlink(relro) != 0 && errno != ENOENT) { - // If something went wrong other than the file not existing, log a warning - // but continue anyway in the hope that we can successfully overwrite the - // existing file with rename() later. - ALOGW("Failed to unlink old file %s: %s", relro, strerror(errno)); - } - static const char tmpsuffix[] = ".XXXXXX"; - char relro_tmp[strlen(relro) + sizeof(tmpsuffix)]; - strlcpy(relro_tmp, relro, sizeof(relro_tmp)); - strlcat(relro_tmp, tmpsuffix, sizeof(relro_tmp)); - int tmp_fd = TEMP_FAILURE_RETRY(mkstemp(relro_tmp)); - if (tmp_fd == -1) { - ALOGE("Failed to create temporary file %s: %s", relro_tmp, strerror(errno)); - return JNI_FALSE; - } - android_dlextinfo extinfo; - extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_WRITE_RELRO; - extinfo.reserved_addr = gReservedAddress; - extinfo.reserved_size = gReservedSize; - extinfo.relro_fd = tmp_fd; - void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo); - int close_result = close(tmp_fd); - if (handle == NULL) { - ALOGE("Failed to load library %s: %s", lib, dlerror()); - unlink(relro_tmp); - return JNI_FALSE; - } - if (close_result != 0 || - chmod(relro_tmp, S_IRUSR | S_IRGRP | S_IROTH) != 0 || - rename(relro_tmp, relro) != 0) { - ALOGE("Failed to update relro file %s: %s", relro, strerror(errno)); - unlink(relro_tmp); - return JNI_FALSE; - } - ALOGV("Created relro file %s for library %s", relro, lib); - return JNI_TRUE; -} - -jint DoLoadWithRelroFile(JNIEnv* env, const char* lib, const char* relro, - jobject clazzLoader) { - int relro_fd = TEMP_FAILURE_RETRY(open(relro, O_RDONLY)); - if (relro_fd == -1) { - ALOGE("Failed to open relro file %s: %s", relro, strerror(errno)); - return LIBLOAD_FAILED_TO_OPEN_RELRO_FILE; - } - android_namespace_t* ns = - android::FindNamespaceByClassLoader(env, clazzLoader); - if (ns == NULL) { - ALOGE("Failed to find classloader namespace"); - return LIBLOAD_FAILED_TO_FIND_NAMESPACE; - } - android_dlextinfo extinfo; - extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_USE_RELRO | - ANDROID_DLEXT_USE_NAMESPACE; - extinfo.reserved_addr = gReservedAddress; - extinfo.reserved_size = gReservedSize; - extinfo.relro_fd = relro_fd; - extinfo.library_namespace = ns; - void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo); - close(relro_fd); - if (handle == NULL) { - ALOGE("Failed to load library %s: %s", lib, dlerror()); - return LIBLOAD_FAILED_TO_LOAD_LIBRARY; - } - ALOGV("Loaded library %s with relro file %s", lib, relro); - return LIBLOAD_SUCCESS; -} - -/******************************************************************************/ -/* JNI wrappers - handle string lifetimes and 32/64 ABI choice */ -/******************************************************************************/ - -jboolean ReserveAddressSpace(JNIEnv*, jclass, jlong size) { - return DoReserveAddressSpace(size); -} - -jboolean CreateRelroFile(JNIEnv* env, jclass, jstring lib32, jstring lib64, - jstring relro32, jstring relro64) { -#ifdef __LP64__ - jstring lib = lib64; - jstring relro = relro64; - (void)lib32; (void)relro32; -#else - jstring lib = lib32; - jstring relro = relro32; - (void)lib64; (void)relro64; -#endif - jboolean ret = JNI_FALSE; - const char* lib_utf8 = env->GetStringUTFChars(lib, NULL); - if (lib_utf8 != NULL) { - const char* relro_utf8 = env->GetStringUTFChars(relro, NULL); - if (relro_utf8 != NULL) { - ret = DoCreateRelroFile(lib_utf8, relro_utf8); - env->ReleaseStringUTFChars(relro, relro_utf8); - } - env->ReleaseStringUTFChars(lib, lib_utf8); - } - return ret; -} - -jint LoadWithRelroFile(JNIEnv* env, jclass, jstring lib32, jstring lib64, - jstring relro32, jstring relro64, jobject clazzLoader) { -#ifdef __LP64__ - jstring lib = lib64; - jstring relro = relro64; - (void)lib32; (void)relro32; -#else - jstring lib = lib32; - jstring relro = relro32; - (void)lib64; (void)relro64; -#endif - jint ret = LIBLOAD_FAILED_JNI_CALL; - const char* lib_utf8 = env->GetStringUTFChars(lib, NULL); - if (lib_utf8 != NULL) { - const char* relro_utf8 = env->GetStringUTFChars(relro, NULL); - if (relro_utf8 != NULL) { - ret = DoLoadWithRelroFile(env, lib_utf8, relro_utf8, clazzLoader); - env->ReleaseStringUTFChars(relro, relro_utf8); - } - env->ReleaseStringUTFChars(lib, lib_utf8); - } - return ret; -} - -const char kWebViewFactoryClassName[] = "android/webkit/WebViewFactory"; -const char kWebViewLibraryLoaderClassName[] = - "android/webkit/WebViewLibraryLoader"; -const JNINativeMethod kJniMethods[] = { - { "nativeReserveAddressSpace", "(J)Z", - reinterpret_cast(ReserveAddressSpace) }, - { "nativeCreateRelroFile", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", - reinterpret_cast(CreateRelroFile) }, - { "nativeLoadWithRelroFile", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)I", - reinterpret_cast(LoadWithRelroFile) }, -}; - -} // namespace - -void RegisterWebViewFactory(JNIEnv* env) { - // If either of these fail, it will set an exception that will be thrown on - // return, so no need to handle errors here. - jclass clazz = env->FindClass(kWebViewFactoryClassName); - if (clazz) { - LIBLOAD_SUCCESS = env->GetStaticIntField( - clazz, - env->GetStaticFieldID(clazz, "LIBLOAD_SUCCESS", "I")); - - LIBLOAD_FAILED_TO_OPEN_RELRO_FILE = env->GetStaticIntField( - clazz, - env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_TO_OPEN_RELRO_FILE", "I")); - - LIBLOAD_FAILED_TO_LOAD_LIBRARY = env->GetStaticIntField( - clazz, - env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_TO_LOAD_LIBRARY", "I")); - - LIBLOAD_FAILED_JNI_CALL = env->GetStaticIntField( - clazz, - env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_JNI_CALL", "I")); - - LIBLOAD_FAILED_TO_FIND_NAMESPACE = env->GetStaticIntField( - clazz, - env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_TO_FIND_NAMESPACE", "I")); - } -} - -void RegisterWebViewLibraryLoader(JNIEnv* env) { - // If either of these fail, it will set an exception that will be thrown on - // return, so no need to handle errors here. - jclass clazz = env->FindClass(kWebViewLibraryLoaderClassName); - if (clazz) { - env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods)); - } -} - -} // namespace android - -JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { - JNIEnv* env = NULL; - if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { - ALOGE("GetEnv failed"); - return JNI_ERR; - } - android::RegisterWebViewFactory(env); - // Ensure there isn't a pending Java exception before registering methods from - // WebViewLibraryLoader - if (!env->ExceptionCheck()) { - android::RegisterWebViewLibraryLoader(env); - } - return JNI_VERSION_1_6; -} -- cgit v1.2.3