Merge "Use nativeloader to load NativeActivity"
am: 317456bc52
* commit '317456bc520549cbc1ac4ad102df8b0d22b22a99':
Use nativeloader to load NativeActivity
This commit is contained in:
@@ -27,7 +27,8 @@ class ApplicationLoaders
|
||||
return gApplicationLoaders;
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader(String zip, String libPath, ClassLoader parent)
|
||||
public ClassLoader getClassLoader(String zip, String librarySearchPath,
|
||||
String libraryPermittedPath, ClassLoader parent)
|
||||
{
|
||||
/*
|
||||
* This is the parent we use if they pass "null" in. In theory
|
||||
@@ -55,7 +56,7 @@ class ApplicationLoaders
|
||||
|
||||
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
|
||||
PathClassLoader pathClassloader =
|
||||
new PathClassLoader(zip, libPath, parent);
|
||||
new PathClassLoader(zip, librarySearchPath, libraryPermittedPath, parent);
|
||||
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
|
||||
|
||||
mLoaders.put(zip, pathClassloader);
|
||||
|
||||
@@ -359,7 +359,15 @@ public final class LoadedApk {
|
||||
}
|
||||
}
|
||||
|
||||
final String lib = TextUtils.join(File.pathSeparator, libPaths);
|
||||
if (mApplicationInfo.isSystemApp()) {
|
||||
// Add path to system libraries to libPaths;
|
||||
// Access to system libs should be limited
|
||||
// to bundled applications; this is why updated
|
||||
// system apps are not included.
|
||||
libPaths.add(System.getProperty("java.library.path"));
|
||||
}
|
||||
|
||||
final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
|
||||
|
||||
/*
|
||||
* With all the combination done (if necessary, actually
|
||||
@@ -367,14 +375,17 @@ public final class LoadedApk {
|
||||
*/
|
||||
|
||||
if (ActivityThread.localLOGV)
|
||||
Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + lib);
|
||||
Slog.v(ActivityThread.TAG, "Class path: " + zip +
|
||||
", JNI path: " + librarySearchPath);
|
||||
|
||||
// Temporarily disable logging of disk reads on the Looper thread
|
||||
// as this is early and necessary.
|
||||
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
|
||||
|
||||
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, lib,
|
||||
mBaseClassLoader);
|
||||
String libraryPermittedPath = mAppDir + File.pathSeparator + mDataDir;
|
||||
|
||||
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, librarySearchPath,
|
||||
libraryPermittedPath, mBaseClassLoader);
|
||||
|
||||
StrictMode.setThreadPolicy(oldPolicy);
|
||||
} else {
|
||||
|
||||
@@ -35,6 +35,8 @@ import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import dalvik.system.BaseDexClassLoader;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
@@ -93,7 +95,9 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
|
||||
|
||||
private native long loadNativeCode(String path, String funcname, MessageQueue queue,
|
||||
String internalDataPath, String obbPath, String externalDataPath, int sdkVersion,
|
||||
AssetManager assetMgr, byte[] savedState);
|
||||
AssetManager assetMgr, byte[] savedState, ClassLoader classLoader, String libraryPath,
|
||||
String isolationPath);
|
||||
private native String getDlError();
|
||||
private native void unloadNativeCode(long handle);
|
||||
private native void onStartNative(long handle);
|
||||
private native void onResumeNative(long handle);
|
||||
@@ -157,15 +161,10 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
throw new RuntimeException("Error getting activity info", e);
|
||||
}
|
||||
|
||||
String path = null;
|
||||
|
||||
File libraryFile = new File(ai.applicationInfo.nativeLibraryDir,
|
||||
System.mapLibraryName(libname));
|
||||
if (libraryFile.exists()) {
|
||||
path = libraryFile.getPath();
|
||||
}
|
||||
|
||||
|
||||
BaseDexClassLoader classLoader = (BaseDexClassLoader) getClassLoader();
|
||||
String path = classLoader.findLibrary(libname);
|
||||
|
||||
if (path == null) {
|
||||
throw new IllegalArgumentException("Unable to find native library: " + libname);
|
||||
}
|
||||
@@ -176,10 +175,13 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2,
|
||||
mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(),
|
||||
getAbsolutePath(getFilesDir()), getAbsolutePath(getObbDir()),
|
||||
getAbsolutePath(getExternalFilesDir(null)),
|
||||
Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
|
||||
Build.VERSION.SDK_INT, getAssets(), nativeSavedState,
|
||||
classLoader, classLoader.getLdLibraryPath(),
|
||||
classLoader.getLibraryPermittedPath());
|
||||
|
||||
if (mNativeHandle == 0) {
|
||||
throw new IllegalArgumentException("Unable to load native library: " + path);
|
||||
throw new UnsatisfiedLinkError(
|
||||
"Unable to load native library \"" + path + "\": " + getDlError());
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@@ -251,7 +251,8 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
libminikin \
|
||||
libprocessgroup \
|
||||
libnativebridge \
|
||||
libradio_metadata
|
||||
libradio_metadata \
|
||||
libnativeloader
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += \
|
||||
libhwui \
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <dlfcn.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <android_runtime/android_app_NativeActivity.h>
|
||||
#include <android_runtime/android_util_AssetManager.h>
|
||||
#include <android_runtime/android_view_Surface.h>
|
||||
@@ -39,6 +41,7 @@
|
||||
#include "android_view_KeyEvent.h"
|
||||
|
||||
#include "nativebridge/native_bridge.h"
|
||||
#include "nativeloader/native_loader.h"
|
||||
|
||||
#include "core_jni_helpers.h"
|
||||
|
||||
@@ -255,18 +258,19 @@ static int mainWorkCallback(int fd, int events, void* data) {
|
||||
static jlong
|
||||
loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName,
|
||||
jobject messageQueue, jstring internalDataDir, jstring obbDir,
|
||||
jstring externalDataDir, jint sdkVersion,
|
||||
jobject jAssetMgr, jbyteArray savedState)
|
||||
{
|
||||
jstring externalDataDir, jint sdkVersion, jobject jAssetMgr,
|
||||
jbyteArray savedState, jobject classLoader, jstring libraryPath,
|
||||
jstring isolationPath) {
|
||||
if (kLogTrace) {
|
||||
ALOGD("loadNativeCode_native");
|
||||
}
|
||||
|
||||
const char* pathStr = env->GetStringUTFChars(path, NULL);
|
||||
NativeCode* code = NULL;
|
||||
std::unique_ptr<NativeCode> code;
|
||||
bool needNativeBridge = false;
|
||||
|
||||
void* handle = dlopen(pathStr, RTLD_LAZY);
|
||||
void* handle = OpenNativeLibrary(env, sdkVersion, pathStr, classLoader,
|
||||
libraryPath, isolationPath);
|
||||
if (handle == NULL) {
|
||||
if (NativeBridgeIsSupported(pathStr)) {
|
||||
handle = NativeBridgeLoadLibrary(pathStr, RTLD_LAZY);
|
||||
@@ -284,26 +288,23 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName
|
||||
funcPtr = dlsym(handle, funcStr);
|
||||
}
|
||||
|
||||
code = new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr);
|
||||
code.reset(new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr));
|
||||
env->ReleaseStringUTFChars(funcName, funcStr);
|
||||
|
||||
if (code->createActivityFunc == NULL) {
|
||||
ALOGW("ANativeActivity_onCreate not found");
|
||||
delete code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
|
||||
if (code->messageQueue == NULL) {
|
||||
ALOGW("Unable to retrieve native MessageQueue");
|
||||
delete code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msgpipe[2];
|
||||
if (pipe(msgpipe)) {
|
||||
ALOGW("could not create pipe: %s", strerror(errno));
|
||||
delete code;
|
||||
return 0;
|
||||
}
|
||||
code->mainWorkRead = msgpipe[0];
|
||||
@@ -315,12 +316,11 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName
|
||||
SLOGW_IF(result != 0, "Could not make main work write pipe "
|
||||
"non-blocking: %s", strerror(errno));
|
||||
code->messageQueue->getLooper()->addFd(
|
||||
code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code);
|
||||
code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code.get());
|
||||
|
||||
code->ANativeActivity::callbacks = &code->callbacks;
|
||||
if (env->GetJavaVM(&code->vm) < 0) {
|
||||
ALOGW("NativeActivity GetJavaVM failed");
|
||||
delete code;
|
||||
return 0;
|
||||
}
|
||||
code->env = env;
|
||||
@@ -356,14 +356,18 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName
|
||||
rawSavedSize = env->GetArrayLength(savedState);
|
||||
}
|
||||
|
||||
code->createActivityFunc(code, rawSavedState, rawSavedSize);
|
||||
code->createActivityFunc(code.get(), rawSavedState, rawSavedSize);
|
||||
|
||||
if (rawSavedState != NULL) {
|
||||
env->ReleaseByteArrayElements(savedState, rawSavedState, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return (jlong)code;
|
||||
return (jlong)code.release();
|
||||
}
|
||||
|
||||
static jstring getDlError_native(JNIEnv* env, jobject clazz) {
|
||||
return env->NewStringUTF(dlerror());
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -651,8 +655,10 @@ onContentRectChanged_native(JNIEnv* env, jobject clazz, jlong handle,
|
||||
}
|
||||
|
||||
static const JNINativeMethod g_methods[] = {
|
||||
{ "loadNativeCode", "(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)J",
|
||||
(void*)loadNativeCode_native },
|
||||
{ "loadNativeCode",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[BLjava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)J",
|
||||
(void*)loadNativeCode_native },
|
||||
{ "getDlError", "()Ljava/lang/String;", (void*) getDlError_native },
|
||||
{ "unloadNativeCode", "(J)V", (void*)unloadNativeCode_native },
|
||||
{ "onStartNative", "(J)V", (void*)onStart_native },
|
||||
{ "onResumeNative", "(J)V", (void*)onResume_native },
|
||||
|
||||
Reference in New Issue
Block a user