android_app_NativeActivity.cpp revision 69969e48f2bca9339662dddfacff0bbf6374ed7f
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "NativeActivity" 18#include <utils/Log.h> 19 20#include "JNIHelp.h" 21#include <android_runtime/AndroidRuntime.h> 22#include <android/native_activity.h> 23 24#include <dlfcn.h> 25 26namespace android 27{ 28 29struct NativeCode { 30 android_activity_t activity; 31 android_activity_callbacks_t callbacks; 32 33 void* dlhandle; 34 35 android_activity_create_t* createActivityFunc; 36 void* clientContext; 37}; 38 39static jint 40loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path) 41{ 42 const char* pathStr = env->GetStringUTFChars(path, NULL); 43 NativeCode* code = NULL; 44 45 void* handle = dlopen(pathStr, RTLD_LAZY); 46 47 env->ReleaseStringUTFChars(path, pathStr); 48 49 if (handle != NULL) { 50 code = new NativeCode(); 51 code->dlhandle = handle; 52 code->createActivityFunc = (android_activity_create_t*) 53 dlsym(handle, "android_onCreateActivity"); 54 if (code->createActivityFunc == NULL) { 55 LOGW("android_onCreateActivity not found"); 56 delete code; 57 dlclose(handle); 58 return 0; 59 } 60 memset(&code->activity, sizeof(code->activity), 0); 61 memset(&code->callbacks, sizeof(code->callbacks), 0); 62 code->activity.callbacks = &code->callbacks; 63 code->activity.env = env; 64 code->activity.clazz = clazz; 65 code->createActivityFunc(&code->activity, NULL, 0); 66 } 67 68 return (jint)code; 69} 70 71static void 72unloadNativeCode_native(JNIEnv* env, jobject clazz, jint handle) 73{ 74 if (handle != 0) { 75 NativeCode* code = (NativeCode*)handle; 76 if (code->callbacks.onDestroy != NULL) { 77 code->callbacks.onDestroy(&code->activity); 78 } 79 dlclose(code->dlhandle); 80 delete code; 81 } 82} 83 84static void 85onStart_native(JNIEnv* env, jobject clazz, jint handle) 86{ 87 if (handle != 0) { 88 NativeCode* code = (NativeCode*)handle; 89 if (code->callbacks.onStart != NULL) { 90 code->callbacks.onStart(&code->activity); 91 } 92 } 93} 94 95static void 96onResume_native(JNIEnv* env, jobject clazz, jint handle) 97{ 98 if (handle != 0) { 99 NativeCode* code = (NativeCode*)handle; 100 if (code->callbacks.onResume != NULL) { 101 code->callbacks.onResume(&code->activity); 102 } 103 } 104} 105 106static void 107onSaveInstanceState_native(JNIEnv* env, jobject clazz, jint handle) 108{ 109 if (handle != 0) { 110 NativeCode* code = (NativeCode*)handle; 111 if (code->callbacks.onSaveInstanceState != NULL) { 112 size_t len = 0; 113 code->callbacks.onSaveInstanceState(&code->activity, &len); 114 } 115 } 116} 117 118static void 119onPause_native(JNIEnv* env, jobject clazz, jint handle) 120{ 121 if (handle != 0) { 122 NativeCode* code = (NativeCode*)handle; 123 if (code->callbacks.onPause != NULL) { 124 code->callbacks.onPause(&code->activity); 125 } 126 } 127} 128 129static void 130onStop_native(JNIEnv* env, jobject clazz, jint handle) 131{ 132 if (handle != 0) { 133 NativeCode* code = (NativeCode*)handle; 134 if (code->callbacks.onStop != NULL) { 135 code->callbacks.onStop(&code->activity); 136 } 137 } 138} 139 140static void 141onLowMemory_native(JNIEnv* env, jobject clazz, jint handle) 142{ 143 if (handle != 0) { 144 NativeCode* code = (NativeCode*)handle; 145 if (code->callbacks.onLowMemory != NULL) { 146 code->callbacks.onLowMemory(&code->activity); 147 } 148 } 149} 150 151static void 152onWindowFocusChanged_native(JNIEnv* env, jobject clazz, jint handle, jboolean focused) 153{ 154 if (handle != 0) { 155 NativeCode* code = (NativeCode*)handle; 156 if (code->callbacks.onWindowFocusChanged != NULL) { 157 code->callbacks.onWindowFocusChanged(&code->activity, focused ? 1 : 0); 158 } 159 } 160} 161 162static const JNINativeMethod g_methods[] = { 163 { "loadNativeCode", "(Ljava/lang/String;)I", (void*)loadNativeCode_native }, 164 { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native }, 165 { "onStartNative", "(I)V", (void*)onStart_native }, 166 { "onResumeNative", "(I)V", (void*)onResume_native }, 167 { "onSaveInstanceStateNative", "(I)V", (void*)onSaveInstanceState_native }, 168 { "onPauseNative", "(I)V", (void*)onPause_native }, 169 { "onStopNative", "(I)V", (void*)onStop_native }, 170 { "onLowMemoryNative", "(I)V", (void*)onLowMemory_native }, 171 { "onWindowFocusChangedNative", "(IZ)V", (void*)onWindowFocusChanged_native }, 172}; 173 174static const char* const kNativeActivityPathName = "android/app/NativeActivity"; 175 176int register_android_app_NativeActivity(JNIEnv* env) 177{ 178 //LOGD("register_android_app_NativeActivity"); 179 180 jclass clazz; 181 182 clazz = env->FindClass(kNativeActivityPathName); 183 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.app.NativeActivity"); 184 185 return AndroidRuntime::registerNativeMethods( 186 env, kNativeActivityPathName, 187 g_methods, NELEM(g_methods)); 188} 189 190} 191