Merge "Use nativeloader to load NativeActivity"
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 413c369..ddb2d46 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -27,7 +27,8 @@
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 @@
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);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index c2bf28a..0120922 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -359,7 +359,15 @@
}
}
- 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 @@
*/
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 {
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index 2e05edb..dcf1c80 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -35,6 +35,8 @@
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
+import dalvik.system.BaseDexClassLoader;
+
import java.io.File;
/**
@@ -93,7 +95,9 @@
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 @@
} 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 @@
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);
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 4c68e01..8641292 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -251,7 +251,8 @@
libminikin \
libprocessgroup \
libnativebridge \
- libradio_metadata
+ libradio_metadata \
+ libnativeloader
LOCAL_SHARED_LIBRARIES += \
libhwui \
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 95be3f2..6ecb3fb 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -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 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 @@
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 @@
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 @@
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 @@
}
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 },