static void onSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jlong handle, jobject surface) { LOG_TRACE("onSurfaceDestroyed_native"); if (handle != 0) { NativeCode* code = (NativeCode*)handle; if (code->nativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) { code->callbacks.onNativeWindowDestroyed(code, code->nativeWindow.get()); } code->setSurface(NULL); } }
static void onSurfaceCreated_native(JNIEnv* env, jobject clazz, jlong handle, jobject surface) { if (kLogTrace) { ALOGD("onSurfaceCreated_native"); } if (handle != 0) { NativeCode* code = (NativeCode*)handle; code->setSurface(surface); if (code->nativeWindow != NULL && code->callbacks.onNativeWindowCreated != NULL) { code->callbacks.onNativeWindowCreated(code, code->nativeWindow.get()); } } }
static void onSurfaceChanged_native(JNIEnv* env, jobject clazz, jlong handle, jobject surface, jint format, jint width, jint height) { if (kLogTrace) { ALOGD("onSurfaceChanged_native"); } if (handle != 0) { NativeCode* code = (NativeCode*)handle; sp<ANativeWindow> oldNativeWindow = code->nativeWindow; code->setSurface(surface); if (oldNativeWindow != code->nativeWindow) { if (oldNativeWindow != NULL && code->callbacks.onNativeWindowDestroyed != NULL) { code->callbacks.onNativeWindowDestroyed(code, oldNativeWindow.get()); } if (code->nativeWindow != NULL) { if (code->callbacks.onNativeWindowCreated != NULL) { code->callbacks.onNativeWindowCreated(code, code->nativeWindow.get()); } code->lastWindowWidth = getWindowProp(code->nativeWindow.get(), NATIVE_WINDOW_WIDTH); code->lastWindowHeight = getWindowProp(code->nativeWindow.get(), NATIVE_WINDOW_HEIGHT); } } else { // Maybe it resized? int32_t newWidth = getWindowProp(code->nativeWindow.get(), NATIVE_WINDOW_WIDTH); int32_t newHeight = getWindowProp(code->nativeWindow.get(), NATIVE_WINDOW_HEIGHT); if (newWidth != code->lastWindowWidth || newHeight != code->lastWindowHeight) { if (code->callbacks.onNativeWindowResized != NULL) { code->callbacks.onNativeWindowResized(code, code->nativeWindow.get()); } } } } }
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) { LOG_TRACE("loadNativeCode_native"); const char* pathStr = env->GetStringUTFChars(path, NULL); NativeCode* code = NULL; bool needNativeBridge = false; void* handle = dlopen(pathStr, RTLD_LAZY); if (handle == NULL) { if (NativeBridgeIsSupported(pathStr)) { handle = NativeBridgeLoadLibrary(pathStr, RTLD_LAZY); needNativeBridge = true; } } env->ReleaseStringUTFChars(path, pathStr); if (handle != NULL) { void* funcPtr = NULL; const char* funcStr = env->GetStringUTFChars(funcName, NULL); if (needNativeBridge) { funcPtr = NativeBridgeGetTrampoline(handle, funcStr, NULL, 0); } else { funcPtr = dlsym(handle, funcStr); } code = 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]; code->mainWorkWrite = msgpipe[1]; int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK); SLOGW_IF(result != 0, "Could not make main work read pipe " "non-blocking: %s", strerror(errno)); result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK); 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->ANativeActivity::callbacks = &code->callbacks; if (env->GetJavaVM(&code->vm) < 0) { ALOGW("NativeActivity GetJavaVM failed"); delete code; return 0; } code->env = env; code->clazz = env->NewGlobalRef(clazz); const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL); code->internalDataPathObj = dirStr; code->internalDataPath = code->internalDataPathObj.string(); env->ReleaseStringUTFChars(internalDataDir, dirStr); if (externalDataDir != NULL) { dirStr = env->GetStringUTFChars(externalDataDir, NULL); code->externalDataPathObj = dirStr; env->ReleaseStringUTFChars(externalDataDir, dirStr); } code->externalDataPath = code->externalDataPathObj.string(); code->sdkVersion = sdkVersion; code->assetManager = assetManagerForJavaObject(env, jAssetMgr); if (obbDir != NULL) { dirStr = env->GetStringUTFChars(obbDir, NULL); code->obbPathObj = dirStr; env->ReleaseStringUTFChars(obbDir, dirStr); } code->obbPath = code->obbPathObj.string(); jbyte* rawSavedState = NULL; jsize rawSavedSize = 0; if (savedState != NULL) { rawSavedState = env->GetByteArrayElements(savedState, NULL); rawSavedSize = env->GetArrayLength(savedState); } code->createActivityFunc(code, rawSavedState, rawSavedSize); if (rawSavedState != NULL) { env->ReleaseByteArrayElements(savedState, rawSavedState, 0); } } return (jlong)code; }