diff --git a/api/current.xml b/api/current.xml index 1a7fad8e6f7e1..61fedf3943bec 100644 --- a/api/current.xml +++ b/api/current.xml @@ -26276,6 +26276,34 @@ + + + + + + + + + + + +#include "JNIHelp.h" +#include +#include + +#include + +namespace android +{ + +struct NativeCode { + android_activity_t activity; + android_activity_callbacks_t callbacks; + + void* dlhandle; + + android_activity_create_t* createActivityFunc; + void* clientContext; +}; + +static jint +loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path) +{ + const char* pathStr = env->GetStringUTFChars(path, NULL); + NativeCode* code = NULL; + + void* handle = dlopen(pathStr, RTLD_LAZY); + + env->ReleaseStringUTFChars(path, pathStr); + + if (handle != NULL) { + code = new NativeCode(); + code->dlhandle = handle; + code->createActivityFunc = (android_activity_create_t*) + dlsym(handle, "android_onCreateActivity"); + if (code->createActivityFunc == NULL) { + LOGW("android_onCreateActivity not found"); + delete code; + dlclose(handle); + return 0; + } + memset(&code->activity, sizeof(code->activity), 0); + memset(&code->callbacks, sizeof(code->callbacks), 0); + code->activity.callbacks = &code->callbacks; + code->activity.env = env; + code->activity.clazz = clazz; + code->createActivityFunc(&code->activity, NULL, 0); + } + + return (jint)code; +} + +static void +unloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle) +{ + if (handle != 0) { + NativeCode* code = (NativeCode*)handle; + if (code->callbacks.onDestroy != NULL) { + code->callbacks.onDestroy(&code->activity); + } + dlclose(code->dlhandle); + delete code; + } +} + +static void +onStart_native(JNIEnv* env, jobject clazz, jint handle) +{ + if (handle != 0) { + NativeCode* code = (NativeCode*)handle; + if (code->callbacks.onStart != NULL) { + code->callbacks.onStart(&code->activity); + } + } +} + +static void +onResume_native(JNIEnv* env, jobject clazz, jint handle) +{ + if (handle != 0) { + NativeCode* code = (NativeCode*)handle; + if (code->callbacks.onResume != NULL) { + code->callbacks.onResume(&code->activity); + } + } +} + +static void +onSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle) +{ + if (handle != 0) { + NativeCode* code = (NativeCode*)handle; + if (code->callbacks.onSaveInstanceState != NULL) { + size_t len = 0; + code->callbacks.onSaveInstanceState(&code->activity, &len); + } + } +} + +static void +onPause_native(JNIEnv* env, jobject clazz, jint handle) +{ + if (handle != 0) { + NativeCode* code = (NativeCode*)handle; + if (code->callbacks.onPause != NULL) { + code->callbacks.onPause(&code->activity); + } + } +} + +static void +onStop_native(JNIEnv* env, jobject clazz, jint handle) +{ + if (handle != 0) { + NativeCode* code = (NativeCode*)handle; + if (code->callbacks.onStop != NULL) { + code->callbacks.onStop(&code->activity); + } + } +} + +static void +onLowMemory_native(JNIEnv* env, jobject clazz, jint handle) +{ + if (handle != 0) { + NativeCode* code = (NativeCode*)handle; + if (code->callbacks.onLowMemory != NULL) { + code->callbacks.onLowMemory(&code->activity); + } + } +} + +static void +onWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean focused) +{ + if (handle != 0) { + NativeCode* code = (NativeCode*)handle; + if (code->callbacks.onWindowFocusChanged != NULL) { + code->callbacks.onWindowFocusChanged(&code->activity, focused ? 1 : 0); + } + } +} + +static const JNINativeMethod g_methods[] = { + { "loadNativeCode", "(Ljava/lang/String;)I", (void*)loadNativeCode_native }, + { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native }, + { "onStartNative", "(I)V", (void*)onStart_native }, + { "onResumeNative", "(I)V", (void*)onResume_native }, + { "onSaveInstanceStateNative", "(I)V", (void*)onSaveInstanceState_native }, + { "onPauseNative", "(I)V", (void*)onPause_native }, + { "onStopNative", "(I)V", (void*)onStop_native }, + { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native }, + { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native }, +}; + +static const char* const kNativeActivityPathName = "android/app/NativeActivity"; + +int register_android_app_NativeActivity(JNIEnv* env) +{ + //LOGD("register_android_app_NativeActivity"); + + jclass clazz; + + clazz = env->FindClass(kNativeActivityPathName); + LOG_FATAL_IF(clazz == NULL, "Unable to find class android.app.NativeActivity"); + + return AndroidRuntime::registerNativeMethods( + env, kNativeActivityPathName, + g_methods, NELEM(g_methods)); +} + +} diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h new file mode 100644 index 0000000000000..8b09461c8d0f9 --- /dev/null +++ b/native/include/android/native_activity.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_NATIVE_ACTIVITY_H +#define ANDROID_NATIVE_ACTIVITY_H + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct android_activity_callbacks_t; + +typedef struct android_activity_t { + struct android_activity_callbacks_t* callbacks; + + JNIEnv* env; + jobject clazz; + + void* instance; +} android_activity_t; + +typedef struct android_activity_callbacks_t { + void (*onStart)(android_activity_t* activity); + void (*onResume)(android_activity_t* activity); + void* (*onSaveInstanceState)(android_activity_t* activity, size_t* outSize); + void (*onPause)(android_activity_t* activity); + void (*onStop)(android_activity_t* activity); + void (*onDestroy)(android_activity_t* activity); + + void (*onLowMemory)(android_activity_t* activity); + void (*onWindowFocusChanged)(android_activity_t* activity, int hasFocus); +} android_activity_callbacks_t; + +typedef void android_activity_create_t(android_activity_t* activity, + void* savedState, size_t savedStateSize); + +extern android_activity_create_t android_onCreateActivity; + +#if 0 +extern android_onCreateActivity(android_activity_t activity, + void* savedState, size_t savedStateSize); +#endif + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_NATIVE_ACTIVITY_H +