android_os_MessageQueue.cpp revision 4fe6c3e51be77e35f40872cdbca6c80f8f8b7ecb
1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/* 2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright (C) 2010 The Android Open Source Project 3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License"); 5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License. 6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at 7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * http://www.apache.org/licenses/LICENSE-2.0 9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software 11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS, 12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and 14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License. 15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#define LOG_TAG "MessageQueue-JNI" 18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#include "JNIHelp.h" 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#include <utils/Looper.h> 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#include <utils/Log.h> 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks#include "android_os_MessageQueue.h" 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksnamespace android { 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks// ---------------------------------------------------------------------------- 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksstatic struct { 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks jclass clazz; 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks jfieldID mPtr; // native object attached to the DVM MessageQueue 33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks} gMessageQueueClassInfo; 34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks// ---------------------------------------------------------------------------- 36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksclass NativeMessageQueue { 38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic: 39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks NativeMessageQueue(); 40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ~NativeMessageQueue(); 41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks inline sp<Looper> getLooper() { return mLooper; } 43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks bool pollOnce(int timeoutMillis); 45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks void wake(); 46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksprivate: 48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sp<Looper> mLooper; 49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks}; 50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks// ---------------------------------------------------------------------------- 52 53NativeMessageQueue::NativeMessageQueue() { 54 mLooper = Looper::getForThread(); 55 if (mLooper == NULL) { 56 mLooper = new Looper(false); 57 Looper::setForThread(mLooper); 58 } 59} 60 61NativeMessageQueue::~NativeMessageQueue() { 62} 63 64bool NativeMessageQueue::pollOnce(int timeoutMillis) { 65 return mLooper->pollOnce(timeoutMillis) != ALOOPER_POLL_TIMEOUT; 66} 67 68void NativeMessageQueue::wake() { 69 mLooper->wake(); 70} 71 72// ---------------------------------------------------------------------------- 73 74static NativeMessageQueue* android_os_MessageQueue_getNativeMessageQueue(JNIEnv* env, 75 jobject messageQueueObj) { 76 jint intPtr = env->GetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr); 77 return reinterpret_cast<NativeMessageQueue*>(intPtr); 78} 79 80static void android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject messageQueueObj, 81 NativeMessageQueue* nativeMessageQueue) { 82 env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr, 83 reinterpret_cast<jint>(nativeMessageQueue)); 84} 85 86sp<Looper> android_os_MessageQueue_getLooper(JNIEnv* env, jobject messageQueueObj) { 87 NativeMessageQueue* nativeMessageQueue = 88 android_os_MessageQueue_getNativeMessageQueue(env, messageQueueObj); 89 return nativeMessageQueue != NULL ? nativeMessageQueue->getLooper() : NULL; 90} 91 92static void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) { 93 NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue(); 94 if (! nativeMessageQueue) { 95 jniThrowRuntimeException(env, "Unable to allocate native queue"); 96 return; 97 } 98 99 android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue); 100} 101 102static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jobject obj) { 103 NativeMessageQueue* nativeMessageQueue = 104 android_os_MessageQueue_getNativeMessageQueue(env, obj); 105 if (nativeMessageQueue) { 106 android_os_MessageQueue_setNativeMessageQueue(env, obj, NULL); 107 delete nativeMessageQueue; 108 } 109} 110 111static void throwQueueNotInitialized(JNIEnv* env) { 112 jniThrowException(env, "java/lang/IllegalStateException", "Message queue not initialized"); 113} 114 115static jboolean android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, 116 jint timeoutMillis) { 117 NativeMessageQueue* nativeMessageQueue = 118 android_os_MessageQueue_getNativeMessageQueue(env, obj); 119 if (! nativeMessageQueue) { 120 throwQueueNotInitialized(env); 121 return false; 122 } 123 return nativeMessageQueue->pollOnce(timeoutMillis); 124} 125 126static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj) { 127 NativeMessageQueue* nativeMessageQueue = 128 android_os_MessageQueue_getNativeMessageQueue(env, obj); 129 if (! nativeMessageQueue) { 130 throwQueueNotInitialized(env); 131 return; 132 } 133 return nativeMessageQueue->wake(); 134} 135 136// ---------------------------------------------------------------------------- 137 138static JNINativeMethod gMessageQueueMethods[] = { 139 /* name, signature, funcPtr */ 140 { "nativeInit", "()V", (void*)android_os_MessageQueue_nativeInit }, 141 { "nativeDestroy", "()V", (void*)android_os_MessageQueue_nativeDestroy }, 142 { "nativePollOnce", "(I)Z", (void*)android_os_MessageQueue_nativePollOnce }, 143 { "nativeWake", "()V", (void*)android_os_MessageQueue_nativeWake } 144}; 145 146#define FIND_CLASS(var, className) \ 147 var = env->FindClass(className); \ 148 LOG_FATAL_IF(! var, "Unable to find class " className); \ 149 var = jclass(env->NewGlobalRef(var)); 150 151#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 152 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 153 LOG_FATAL_IF(! var, "Unable to find field " fieldName); 154 155int register_android_os_MessageQueue(JNIEnv* env) { 156 int res = jniRegisterNativeMethods(env, "android/os/MessageQueue", 157 gMessageQueueMethods, NELEM(gMessageQueueMethods)); 158 LOG_FATAL_IF(res < 0, "Unable to register native methods."); 159 160 FIND_CLASS(gMessageQueueClassInfo.clazz, "android/os/MessageQueue"); 161 162 GET_FIELD_ID(gMessageQueueClassInfo.mPtr, gMessageQueueClassInfo.clazz, 163 "mPtr", "I"); 164 165 return 0; 166} 167 168} // namespace android 169