Always call into native loader when load a native library

Namespace has been enabled at native bridge side. And, native loader
wraps both dynamic linker and native bridge now. Frameworks on longer
call native bridge directly when it load a native library, but still
remember whether native bridge is needed for each library.

Bug: http://b/28242460
Change-Id: I6b25e0621168cea0885c890c544b355a68309fa7
Signed-off-by: Zhenhua WANG <zhenhua.wang@intel.com>
This commit is contained in:
Dimitry Ivanov
2016-07-06 14:17:52 -07:00
parent 189bbd9f6d
commit 569834d861

View File

@@ -45,6 +45,7 @@
#include "core_jni_helpers.h" #include "core_jni_helpers.h"
#include "ScopedUtfChars.h"
#define LOG_TRACE(...) #define LOG_TRACE(...)
//#define LOG_TRACE(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__) //#define LOG_TRACE(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
@@ -264,101 +265,106 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName
ALOGD("loadNativeCode_native"); ALOGD("loadNativeCode_native");
} }
const char* pathStr = env->GetStringUTFChars(path, NULL); ScopedUtfChars pathStr(env, path);
std::unique_ptr<NativeCode> code; std::unique_ptr<NativeCode> code;
bool needNativeBridge = false; bool needs_native_bridge = false;
std::string error_msg;
void* handle = OpenNativeLibrary(env, sdkVersion, pathStr, classLoader, libraryPath); void* handle = OpenNativeLibrary(env,
if (handle == NULL) { sdkVersion,
if (NativeBridgeIsSupported(pathStr)) { pathStr.c_str(),
handle = NativeBridgeLoadLibrary(pathStr, RTLD_LAZY); classLoader,
needNativeBridge = true; libraryPath,
} &needs_native_bridge,
&error_msg);
if (handle == nullptr) {
ALOGW("NativeActivity LoadNativeLibrary(\"%s\") failed: %s",
pathStr.c_str(),
error_msg.c_str());
return 0;
} }
env->ReleaseStringUTFChars(path, pathStr);
if (handle != NULL) { void* funcPtr = NULL;
void* funcPtr = NULL; const char* funcStr = env->GetStringUTFChars(funcName, NULL);
const char* funcStr = env->GetStringUTFChars(funcName, NULL); if (needs_native_bridge) {
if (needNativeBridge) { funcPtr = NativeBridgeGetTrampoline(handle, funcStr, NULL, 0);
funcPtr = NativeBridgeGetTrampoline(handle, funcStr, NULL, 0); } else {
} else { funcPtr = dlsym(handle, funcStr);
funcPtr = dlsym(handle, funcStr); }
}
code.reset(new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr)); code.reset(new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr));
env->ReleaseStringUTFChars(funcName, funcStr); env->ReleaseStringUTFChars(funcName, funcStr);
if (code->createActivityFunc == NULL) { if (code->createActivityFunc == NULL) {
ALOGW("ANativeActivity_onCreate not found"); ALOGW("ANativeActivity_onCreate not found");
return 0; return 0;
} }
code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue); code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
if (code->messageQueue == NULL) { if (code->messageQueue == NULL) {
ALOGW("Unable to retrieve native MessageQueue"); ALOGW("Unable to retrieve native MessageQueue");
return 0; return 0;
} }
int msgpipe[2]; int msgpipe[2];
if (pipe(msgpipe)) { if (pipe(msgpipe)) {
ALOGW("could not create pipe: %s", strerror(errno)); ALOGW("could not create pipe: %s", strerror(errno));
return 0; return 0;
} }
code->mainWorkRead = msgpipe[0]; code->mainWorkRead = msgpipe[0];
code->mainWorkWrite = msgpipe[1]; code->mainWorkWrite = msgpipe[1];
int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK); int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK);
SLOGW_IF(result != 0, "Could not make main work read pipe " SLOGW_IF(result != 0, "Could not make main work read pipe "
"non-blocking: %s", strerror(errno)); "non-blocking: %s", strerror(errno));
result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK); result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
SLOGW_IF(result != 0, "Could not make main work write pipe " SLOGW_IF(result != 0, "Could not make main work write pipe "
"non-blocking: %s", strerror(errno)); "non-blocking: %s", strerror(errno));
code->messageQueue->getLooper()->addFd( code->messageQueue->getLooper()->addFd(
code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code.get()); code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code.get());
code->ANativeActivity::callbacks = &code->callbacks; code->ANativeActivity::callbacks = &code->callbacks;
if (env->GetJavaVM(&code->vm) < 0) { if (env->GetJavaVM(&code->vm) < 0) {
ALOGW("NativeActivity GetJavaVM failed"); ALOGW("NativeActivity GetJavaVM failed");
return 0; return 0;
} }
code->env = env; code->env = env;
code->clazz = env->NewGlobalRef(clazz); code->clazz = env->NewGlobalRef(clazz);
const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL); const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL);
code->internalDataPathObj = dirStr; code->internalDataPathObj = dirStr;
code->internalDataPath = code->internalDataPathObj.string(); code->internalDataPath = code->internalDataPathObj.string();
env->ReleaseStringUTFChars(internalDataDir, dirStr); env->ReleaseStringUTFChars(internalDataDir, dirStr);
if (externalDataDir != NULL) { if (externalDataDir != NULL) {
dirStr = env->GetStringUTFChars(externalDataDir, NULL); dirStr = env->GetStringUTFChars(externalDataDir, NULL);
code->externalDataPathObj = dirStr; code->externalDataPathObj = dirStr;
env->ReleaseStringUTFChars(externalDataDir, dirStr); env->ReleaseStringUTFChars(externalDataDir, dirStr);
} }
code->externalDataPath = code->externalDataPathObj.string(); code->externalDataPath = code->externalDataPathObj.string();
code->sdkVersion = sdkVersion; code->sdkVersion = sdkVersion;
code->assetManager = assetManagerForJavaObject(env, jAssetMgr); code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
if (obbDir != NULL) { if (obbDir != NULL) {
dirStr = env->GetStringUTFChars(obbDir, NULL); dirStr = env->GetStringUTFChars(obbDir, NULL);
code->obbPathObj = dirStr; code->obbPathObj = dirStr;
env->ReleaseStringUTFChars(obbDir, dirStr); env->ReleaseStringUTFChars(obbDir, dirStr);
} }
code->obbPath = code->obbPathObj.string(); code->obbPath = code->obbPathObj.string();
jbyte* rawSavedState = NULL; jbyte* rawSavedState = NULL;
jsize rawSavedSize = 0; jsize rawSavedSize = 0;
if (savedState != NULL) { if (savedState != NULL) {
rawSavedState = env->GetByteArrayElements(savedState, NULL); rawSavedState = env->GetByteArrayElements(savedState, NULL);
rawSavedSize = env->GetArrayLength(savedState); rawSavedSize = env->GetArrayLength(savedState);
} }
code->createActivityFunc(code.get(), rawSavedState, rawSavedSize); code->createActivityFunc(code.get(), rawSavedState, rawSavedSize);
if (rawSavedState != NULL) { if (rawSavedState != NULL) {
env->ReleaseByteArrayElements(savedState, rawSavedState, 0); env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
}
} }
return (jlong)code.release(); return (jlong)code.release();