1cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton/* 2cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * Copyright (C) 2014 The Android Open Source Project 3cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * 4cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * Licensed under the Apache License, Version 2.0 (the "License"); 5cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * you may not use this file except in compliance with the License. 6cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * You may obtain a copy of the License at 7cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * 8cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * http://www.apache.org/licenses/LICENSE-2.0 9cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * 10cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * Unless required by applicable law or agreed to in writing, software 11cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * distributed under the License is distributed on an "AS IS" BASIS, 12cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * See the License for the specific language governing permissions and 14cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton * limitations under the License. 15cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton */ 16cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 17cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton// Uncomment for verbose logging. 18cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton// #define LOG_NDEBUG 0 19cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#define LOG_TAG "webviewchromiumloader" 20cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 21cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <dlfcn.h> 22cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <errno.h> 23cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <fcntl.h> 24cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <stdio.h> 25cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <stdlib.h> 26cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <string.h> 27cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <unistd.h> 28cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <sys/mman.h> 29cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <sys/stat.h> 30cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <sys/types.h> 31cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 32cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <jni.h> 33cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <android/dlext.h> 34cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <nativeloader/native_loader.h> 35cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#include <utils/Log.h> 36cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 37cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) 38cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 39cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonnamespace android { 40cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonnamespace { 41cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 42cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonvoid* gReservedAddress = NULL; 43cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonsize_t gReservedSize = 0; 44cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 45cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonjint LIBLOAD_SUCCESS; 46cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonjint LIBLOAD_FAILED_TO_OPEN_RELRO_FILE; 47cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonjint LIBLOAD_FAILED_TO_LOAD_LIBRARY; 48cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonjint LIBLOAD_FAILED_JNI_CALL; 49cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonjint LIBLOAD_FAILED_TO_FIND_NAMESPACE; 50cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 51cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonjboolean DoReserveAddressSpace(jlong size) { 52cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton size_t vsize = static_cast<size_t>(size); 53cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 54cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton void* addr = mmap(NULL, vsize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 55cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (addr == MAP_FAILED) { 56cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGE("Failed to reserve %zd bytes of address space for future load of " 57cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton "libwebviewchromium.so: %s", 58cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton vsize, strerror(errno)); 59cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return JNI_FALSE; 60cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 61cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton gReservedAddress = addr; 62cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton gReservedSize = vsize; 63cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGV("Reserved %zd bytes at %p", vsize, addr); 64cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return JNI_TRUE; 65cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} 66cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 67cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonjboolean DoCreateRelroFile(const char* lib, const char* relro) { 68cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // Try to unlink the old file, since if this is being called, the old one is 69cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // obsolete. 70cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (unlink(relro) != 0 && errno != ENOENT) { 71cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // If something went wrong other than the file not existing, log a warning 72cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // but continue anyway in the hope that we can successfully overwrite the 73cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // existing file with rename() later. 74cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGW("Failed to unlink old file %s: %s", relro, strerror(errno)); 75cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 76cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton static const char tmpsuffix[] = ".XXXXXX"; 77cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton char relro_tmp[strlen(relro) + sizeof(tmpsuffix)]; 78cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton strlcpy(relro_tmp, relro, sizeof(relro_tmp)); 79cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton strlcat(relro_tmp, tmpsuffix, sizeof(relro_tmp)); 80cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton int tmp_fd = TEMP_FAILURE_RETRY(mkstemp(relro_tmp)); 81cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (tmp_fd == -1) { 82cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGE("Failed to create temporary file %s: %s", relro_tmp, strerror(errno)); 83cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return JNI_FALSE; 84cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 85cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton android_dlextinfo extinfo; 86cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_WRITE_RELRO; 87cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton extinfo.reserved_addr = gReservedAddress; 88cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton extinfo.reserved_size = gReservedSize; 89cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton extinfo.relro_fd = tmp_fd; 90cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo); 91cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton int close_result = close(tmp_fd); 92cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (handle == NULL) { 93cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGE("Failed to load library %s: %s", lib, dlerror()); 94cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton unlink(relro_tmp); 95cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return JNI_FALSE; 96cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 97cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (close_result != 0 || 98cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton chmod(relro_tmp, S_IRUSR | S_IRGRP | S_IROTH) != 0 || 99cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton rename(relro_tmp, relro) != 0) { 100cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGE("Failed to update relro file %s: %s", relro, strerror(errno)); 101cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton unlink(relro_tmp); 102cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return JNI_FALSE; 103cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 104cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGV("Created relro file %s for library %s", relro, lib); 105cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return JNI_TRUE; 106cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} 107cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 108cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonjint DoLoadWithRelroFile(JNIEnv* env, const char* lib, const char* relro, 109cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton jobject clazzLoader) { 110cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton int relro_fd = TEMP_FAILURE_RETRY(open(relro, O_RDONLY)); 111cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (relro_fd == -1) { 112cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGE("Failed to open relro file %s: %s", relro, strerror(errno)); 113cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return LIBLOAD_FAILED_TO_OPEN_RELRO_FILE; 114cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 115cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton android_namespace_t* ns = 116cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton android::FindNamespaceByClassLoader(env, clazzLoader); 117cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (ns == NULL) { 118cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGE("Failed to find classloader namespace"); 119cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return LIBLOAD_FAILED_TO_FIND_NAMESPACE; 120cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 121cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton android_dlextinfo extinfo; 122cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_USE_RELRO | 123cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ANDROID_DLEXT_USE_NAMESPACE; 124cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton extinfo.reserved_addr = gReservedAddress; 125cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton extinfo.reserved_size = gReservedSize; 126cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton extinfo.relro_fd = relro_fd; 127cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton extinfo.library_namespace = ns; 128cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo); 129cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton close(relro_fd); 130cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (handle == NULL) { 131cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGE("Failed to load library %s: %s", lib, dlerror()); 132cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return LIBLOAD_FAILED_TO_LOAD_LIBRARY; 133cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 134cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGV("Loaded library %s with relro file %s", lib, relro); 135cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return LIBLOAD_SUCCESS; 136cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} 137cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 138cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton/******************************************************************************/ 139cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton/* JNI wrappers - handle string lifetimes and 32/64 ABI choice */ 140cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton/******************************************************************************/ 141cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 142cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonjboolean ReserveAddressSpace(JNIEnv*, jclass, jlong size) { 143cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return DoReserveAddressSpace(size); 144cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} 145cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 146ae498f270230e20b5a777ed2d6387a21767625a3Gustav Senntonjboolean CreateRelroFile(JNIEnv* env, jclass, jstring lib, jstring relro) { 147cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton jboolean ret = JNI_FALSE; 148cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton const char* lib_utf8 = env->GetStringUTFChars(lib, NULL); 149cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (lib_utf8 != NULL) { 150cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton const char* relro_utf8 = env->GetStringUTFChars(relro, NULL); 151cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (relro_utf8 != NULL) { 152cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ret = DoCreateRelroFile(lib_utf8, relro_utf8); 153cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->ReleaseStringUTFChars(relro, relro_utf8); 154cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 155cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->ReleaseStringUTFChars(lib, lib_utf8); 156cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 157cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return ret; 158cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} 159cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 160ae498f270230e20b5a777ed2d6387a21767625a3Gustav Senntonjint LoadWithRelroFile(JNIEnv* env, jclass, jstring lib, jstring relro, 161ae498f270230e20b5a777ed2d6387a21767625a3Gustav Sennton jobject clazzLoader) { 162cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton jint ret = LIBLOAD_FAILED_JNI_CALL; 163cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton const char* lib_utf8 = env->GetStringUTFChars(lib, NULL); 164cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (lib_utf8 != NULL) { 165cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton const char* relro_utf8 = env->GetStringUTFChars(relro, NULL); 166cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (relro_utf8 != NULL) { 167cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ret = DoLoadWithRelroFile(env, lib_utf8, relro_utf8, clazzLoader); 168cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->ReleaseStringUTFChars(relro, relro_utf8); 169cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 170cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->ReleaseStringUTFChars(lib, lib_utf8); 171cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 172cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return ret; 173cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} 174cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 175cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonconst char kWebViewFactoryClassName[] = "android/webkit/WebViewFactory"; 176cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonconst char kWebViewLibraryLoaderClassName[] = 177cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton "android/webkit/WebViewLibraryLoader"; 178cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonconst JNINativeMethod kJniMethods[] = { 179cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton { "nativeReserveAddressSpace", "(J)Z", 180cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton reinterpret_cast<void*>(ReserveAddressSpace) }, 181cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton { "nativeCreateRelroFile", 182ae498f270230e20b5a777ed2d6387a21767625a3Gustav Sennton "(Ljava/lang/String;Ljava/lang/String;)Z", 183cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton reinterpret_cast<void*>(CreateRelroFile) }, 184cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton { "nativeLoadWithRelroFile", 185ae498f270230e20b5a777ed2d6387a21767625a3Gustav Sennton "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)I", 186cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton reinterpret_cast<void*>(LoadWithRelroFile) }, 187cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton}; 188cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 189cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} // namespace 190cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 191cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonvoid RegisterWebViewFactory(JNIEnv* env) { 192cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // If either of these fail, it will set an exception that will be thrown on 193cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // return, so no need to handle errors here. 194cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton jclass clazz = env->FindClass(kWebViewFactoryClassName); 195cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (clazz) { 196cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton LIBLOAD_SUCCESS = env->GetStaticIntField( 197cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton clazz, 198cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->GetStaticFieldID(clazz, "LIBLOAD_SUCCESS", "I")); 199cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 200cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton LIBLOAD_FAILED_TO_OPEN_RELRO_FILE = env->GetStaticIntField( 201cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton clazz, 202cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_TO_OPEN_RELRO_FILE", "I")); 203cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 204cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton LIBLOAD_FAILED_TO_LOAD_LIBRARY = env->GetStaticIntField( 205cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton clazz, 206cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_TO_LOAD_LIBRARY", "I")); 207cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 208cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton LIBLOAD_FAILED_JNI_CALL = env->GetStaticIntField( 209cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton clazz, 210cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_JNI_CALL", "I")); 211cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 212cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton LIBLOAD_FAILED_TO_FIND_NAMESPACE = env->GetStaticIntField( 213cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton clazz, 214cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->GetStaticFieldID(clazz, "LIBLOAD_FAILED_TO_FIND_NAMESPACE", "I")); 215cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 216cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} 217cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 218cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Senntonvoid RegisterWebViewLibraryLoader(JNIEnv* env) { 219cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // If either of these fail, it will set an exception that will be thrown on 220cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // return, so no need to handle errors here. 221cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton jclass clazz = env->FindClass(kWebViewLibraryLoaderClassName); 222cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (clazz) { 223cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods)); 224cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 225cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} 226cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 227cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} // namespace android 228cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton 229cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav SenntonJNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) { 230cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton JNIEnv* env = NULL; 231cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { 232cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton ALOGE("GetEnv failed"); 233cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return JNI_ERR; 234cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 235cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton android::RegisterWebViewFactory(env); 236cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // Ensure there isn't a pending Java exception before registering methods from 237cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton // WebViewLibraryLoader 238cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton if (!env->ExceptionCheck()) { 239cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton android::RegisterWebViewLibraryLoader(env); 240cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton } 241cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton return JNI_VERSION_1_6; 242cd165a9d51e34d7d86d27e5d3220f86846145c14Gustav Sennton} 243