Merge "Use nativeloader to load NativeActivity"

This commit is contained in:
Dimitry Ivanov
2015-12-11 20:30:32 +00:00
committed by Gerrit Code Review
5 changed files with 55 additions and 34 deletions

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -251,7 +251,8 @@ LOCAL_SHARED_LIBRARIES := \
libminikin \
libprocessgroup \
libnativebridge \
libradio_metadata
libradio_metadata \
libnativeloader
LOCAL_SHARED_LIBRARIES += \
libhwui \

View File

@@ -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 },