diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index 5ad60ec0e7ee6..222578a955130 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -48,10 +48,10 @@ public class MessageQueue { // Barriers are indicated by messages with a null target whose arg1 field carries the token. private int mNextBarrierToken; - private native void nativeInit(); - private native void nativeDestroy(); - private native void nativePollOnce(int ptr, int timeoutMillis); - private native void nativeWake(int ptr); + private native static int nativeInit(); + private native static void nativeDestroy(int ptr); + private native static void nativePollOnce(int ptr, int timeoutMillis); + private native static void nativeWake(int ptr); /** * Callback interface for discovering when a thread is going to block @@ -102,18 +102,25 @@ public class MessageQueue { MessageQueue(boolean quitAllowed) { mQuitAllowed = quitAllowed; - nativeInit(); + mPtr = nativeInit(); } @Override protected void finalize() throws Throwable { try { - nativeDestroy(); + dispose(); } finally { super.finalize(); } } + private void dispose() { + if (mPtr != 0) { + nativeDestroy(mPtr); + mPtr = 0; + } + } + final Message next() { int pendingIdleHandlerCount = -1; // -1 only during first iteration int nextPollTimeoutMillis = 0; @@ -126,6 +133,7 @@ public class MessageQueue { synchronized (this) { if (mQuiting) { + dispose(); return null; } diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp index a4dcac6d886a1..75406458c177f 100644 --- a/core/jni/android_os_MessageQueue.cpp +++ b/core/jni/android_os_MessageQueue.cpp @@ -109,55 +109,34 @@ void NativeMessageQueue::wake() { // ---------------------------------------------------------------------------- -static NativeMessageQueue* android_os_MessageQueue_getNativeMessageQueue(JNIEnv* env, - jobject messageQueueObj) { +sp android_os_MessageQueue_getMessageQueue(JNIEnv* env, jobject messageQueueObj) { jint intPtr = env->GetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr); return reinterpret_cast(intPtr); } -static void android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject messageQueueObj, - NativeMessageQueue* nativeMessageQueue) { - env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr, - reinterpret_cast(nativeMessageQueue)); -} - -sp android_os_MessageQueue_getMessageQueue(JNIEnv* env, jobject messageQueueObj) { - NativeMessageQueue* nativeMessageQueue = - android_os_MessageQueue_getNativeMessageQueue(env, messageQueueObj); - return nativeMessageQueue; -} - -static void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) { +static jint android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) { NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue(); if (!nativeMessageQueue) { jniThrowRuntimeException(env, "Unable to allocate native queue"); - return; + return 0; } nativeMessageQueue->incStrong(env); - android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue); + return reinterpret_cast(nativeMessageQueue); } -static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jobject obj) { - NativeMessageQueue* nativeMessageQueue = - android_os_MessageQueue_getNativeMessageQueue(env, obj); - if (nativeMessageQueue) { - android_os_MessageQueue_setNativeMessageQueue(env, obj, NULL); - nativeMessageQueue->decStrong(env); - } +static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jclass clazz, jint ptr) { + NativeMessageQueue* nativeMessageQueue = reinterpret_cast(ptr); + nativeMessageQueue->decStrong(env); } -static void throwQueueNotInitialized(JNIEnv* env) { - jniThrowException(env, "java/lang/IllegalStateException", "Message queue not initialized"); -} - -static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, +static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jclass clazz, jint ptr, jint timeoutMillis) { NativeMessageQueue* nativeMessageQueue = reinterpret_cast(ptr); nativeMessageQueue->pollOnce(env, timeoutMillis); } -static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint ptr) { +static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jint ptr) { NativeMessageQueue* nativeMessageQueue = reinterpret_cast(ptr); return nativeMessageQueue->wake(); } @@ -166,8 +145,8 @@ static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint pt static JNINativeMethod gMessageQueueMethods[] = { /* name, signature, funcPtr */ - { "nativeInit", "()V", (void*)android_os_MessageQueue_nativeInit }, - { "nativeDestroy", "()V", (void*)android_os_MessageQueue_nativeDestroy }, + { "nativeInit", "()I", (void*)android_os_MessageQueue_nativeInit }, + { "nativeDestroy", "(I)V", (void*)android_os_MessageQueue_nativeDestroy }, { "nativePollOnce", "(II)V", (void*)android_os_MessageQueue_nativePollOnce }, { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake } }; diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp index a97becfd64741..57803e362c17d 100644 --- a/services/jni/com_android_server_input_InputManagerService.cpp +++ b/services/jni/com_android_server_input_InputManagerService.cpp @@ -975,6 +975,11 @@ void NativeInputManager::loadPointerResources(PointerResources* outResources) { static jint nativeInit(JNIEnv* env, jclass clazz, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); + if (messageQueue == NULL) { + jniThrowRuntimeException(env, "MessageQueue is not initialized."); + return 0; + } + NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, messageQueue->getLooper()); im->incStrong(serviceObj);