Merge "Added function to explicitly initialize a namespace" into nyc-dev

This commit is contained in:
Dimitry Ivanov 2016-02-26 18:03:54 +00:00 committed by Android (Google) Code Review
commit 94da34a8fa
2 changed files with 69 additions and 22 deletions

View File

@ -29,9 +29,19 @@ __attribute__((visibility("default")))
void PreloadPublicNativeLibraries();
__attribute__((visibility("default")))
void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
jobject class_loader, bool is_shared, jstring library_path,
jstring permitted_path);
jstring CreateClassLoaderNamespace(JNIEnv* env,
int32_t target_sdk_version,
jobject class_loader,
bool is_shared,
jstring library_path,
jstring permitted_path);
__attribute__((visibility("default")))
void* OpenNativeLibrary(JNIEnv* env,
int32_t target_sdk_version,
const char* path,
jobject class_loader,
jstring library_path);
#if defined(__ANDROID__)
// Look up linker namespace by class_loader. Returns nullptr if

View File

@ -21,6 +21,7 @@
#ifdef __ANDROID__
#include <android/dlext.h>
#include "cutils/properties.h"
#include "log/log.h"
#endif
#include <algorithm>
@ -61,11 +62,12 @@ class LibraryNamespaces {
public:
LibraryNamespaces() : initialized_(false) { }
android_namespace_t* GetOrCreate(JNIEnv* env, jobject class_loader,
bool is_shared,
jstring java_library_path,
jstring java_permitted_path,
int32_t target_sdk_version) {
android_namespace_t* Create(JNIEnv* env,
jobject class_loader,
bool is_shared,
jstring java_library_path,
jstring java_permitted_path,
int32_t target_sdk_version) {
ScopedUtfChars library_path(env, java_library_path);
std::string permitted_path;
@ -82,9 +84,7 @@ class LibraryNamespaces {
android_namespace_t* ns = FindNamespaceByClassLoader(env, class_loader);
if (ns != nullptr) {
return ns;
}
LOG_FATAL_IF(ns != nullptr, "There is already a namespace associated with this classloader");
uint64_t namespace_type = ANDROID_NAMESPACE_TYPE_ISOLATED;
if (is_shared) {
@ -99,7 +99,9 @@ class LibraryNamespaces {
permitted_path.c_str() :
nullptr);
namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns));
if (ns != nullptr) {
namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), ns));
}
return ns;
}
@ -147,6 +149,10 @@ class LibraryNamespaces {
};
static LibraryNamespaces* g_namespaces = new LibraryNamespaces;
static bool namespaces_enabled(uint32_t target_sdk_version) {
return target_sdk_version > 0;
}
#endif
void PreloadPublicNativeLibraries() {
@ -156,20 +162,52 @@ void PreloadPublicNativeLibraries() {
}
void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
jobject class_loader, bool is_shared, jstring java_library_path,
jstring java_permitted_path) {
jstring CreateClassLoaderNamespace(JNIEnv* env,
int32_t target_sdk_version,
jobject class_loader,
bool is_shared,
jstring library_path,
jstring permitted_path) {
#if defined(__ANDROID__)
if (target_sdk_version == 0 || class_loader == nullptr) {
if (!namespaces_enabled(target_sdk_version)) {
return nullptr;
}
android_namespace_t* ns = g_namespaces->Create(env,
class_loader,
is_shared,
library_path,
permitted_path,
target_sdk_version);
if (ns == nullptr) {
return env->NewStringUTF(dlerror());
}
#else
UNUSED(env, target_sdk_version, class_loader, is_shared,
library_path, permitted_path);
#endif
return nullptr;
}
void* OpenNativeLibrary(JNIEnv* env,
int32_t target_sdk_version,
const char* path,
jobject class_loader,
jstring library_path) {
#if defined(__ANDROID__)
if (!namespaces_enabled(target_sdk_version) || class_loader == nullptr) {
return dlopen(path, RTLD_NOW);
}
android_namespace_t* ns =
g_namespaces->GetOrCreate(env, class_loader, is_shared,
java_library_path, java_permitted_path, target_sdk_version);
android_namespace_t* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader);
if (ns == nullptr) {
return nullptr;
// This is the case where the classloader was not created by ApplicationLoaders
// In this case we create an isolated not-shared namespace for it.
ns = g_namespaces->Create(env, class_loader, false, library_path, nullptr, target_sdk_version);
if (ns == nullptr) {
return nullptr;
}
}
android_dlextinfo extinfo;
@ -178,8 +216,7 @@ void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* pat
return android_dlopen_ext(path, RTLD_NOW, &extinfo);
#else
UNUSED(env, target_sdk_version, class_loader, is_shared,
java_library_path, java_permitted_path);
UNUSED(env, target_sdk_version, class_loader, library_path);
return dlopen(path, RTLD_NOW);
#endif
}