summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dmitriy Ivanov <dimitry@google.com> 2015-11-15 14:58:36 -0800
committer Dimitry Ivanov <dimitry@google.com> 2015-12-11 10:44:16 -0800
commit6f06ad7df1362e9e5b252689f452bdeee2e5af46 (patch)
treed6172cafac2de9a6af70e5c7acac743fb978a588
parentcb299b858f4f073e2abd4ad45aa944dc0dfd0aa2 (diff)
Use nativeloader to load NativeActivity
System apps are the exception and they can access internal platform libraries (this is needed for bundled apps to work correctly). Also fix the way NativeActivity loads the native library to correspond to the way BaseDexClassloader does it. Bug: http://b/22548808 Bub: http://b/25777936 Change-Id: Idc94cdded182ea2cb1cbebc76c336cc3394c7ebe
-rw-r--r--core/java/android/app/ApplicationLoaders.java5
-rw-r--r--core/java/android/app/LoadedApk.java19
-rw-r--r--core/java/android/app/NativeActivity.java26
-rw-r--r--core/jni/Android.mk3
-rw-r--r--core/jni/android_app_NativeActivity.cpp36
5 files changed, 55 insertions, 34 deletions
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 413c3699db08..ddb2d46eb118 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -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);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index c2bf28a931c8..01209227273e 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -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 {
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index 2e05edb2e7d9..dcf1c8019d4f 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -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);
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 4c68e015e531..86412926b3ce 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -251,7 +251,8 @@ LOCAL_SHARED_LIBRARIES := \
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 95be3f27b625..6ecb3fb19f62 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 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 },