android_os_MessageQueue.cpp revision 46b9ac0ae2162309774a7478cd9d4e578747bfc2
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 "MessageQueue-JNI" 18 19#include "JNIHelp.h" 20 21#include <utils/PollLoop.h> 22#include <utils/Log.h> 23#include "android_os_MessageQueue.h" 24 25namespace android { 26 27// ---------------------------------------------------------------------------- 28 29static struct { 30 jclass clazz; 31 32 jfieldID mPtr; // native object attached to the DVM MessageQueue 33} gMessageQueueClassInfo; 34 35// ---------------------------------------------------------------------------- 36 37class NativeMessageQueue { 38public: 39 NativeMessageQueue(); 40 ~NativeMessageQueue(); 41 42 inline sp<PollLoop> getPollLoop() { return mPollLoop; } 43 44 bool pollOnce(int timeoutMillis); 45 void wake(); 46 47private: 48 sp<PollLoop> mPollLoop; 49}; 50 51// ---------------------------------------------------------------------------- 52 53NativeMessageQueue::NativeMessageQueue() { 54 mPollLoop = new PollLoop(); 55} 56 57NativeMessageQueue::~NativeMessageQueue() { 58} 59 60bool NativeMessageQueue::pollOnce(int timeoutMillis) { 61 return mPollLoop->pollOnce(timeoutMillis); 62} 63 64void NativeMessageQueue::wake() { 65 mPollLoop->wake(); 66} 67 68// ---------------------------------------------------------------------------- 69 70static NativeMessageQueue* android_os_MessageQueue_getNativeMessageQueue(JNIEnv* env, 71 jobject messageQueueObj) { 72 jint intPtr = env->GetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr); 73 return reinterpret_cast<NativeMessageQueue*>(intPtr); 74} 75 76static void android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject messageQueueObj, 77 NativeMessageQueue* nativeMessageQueue) { 78 env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr, 79 reinterpret_cast<jint>(nativeMessageQueue)); 80} 81 82sp<PollLoop> android_os_MessageQueue_getPollLoop(JNIEnv* env, jobject messageQueueObj) { 83 NativeMessageQueue* nativeMessageQueue = 84 android_os_MessageQueue_getNativeMessageQueue(env, messageQueueObj); 85 return nativeMessageQueue != NULL ? nativeMessageQueue->getPollLoop() : NULL; 86} 87 88static void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) { 89 NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue(); 90 if (! nativeMessageQueue) { 91 jniThrowRuntimeException(env, "Unable to allocate native queue"); 92 return; 93 } 94 95 android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue); 96} 97 98static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jobject obj) { 99 NativeMessageQueue* nativeMessageQueue = 100 android_os_MessageQueue_getNativeMessageQueue(env, obj); 101 if (nativeMessageQueue) { 102 android_os_MessageQueue_setNativeMessageQueue(env, obj, NULL); 103 delete nativeMessageQueue; 104 } 105} 106 107static void throwQueueNotInitialized(JNIEnv* env) { 108 jniThrowException(env, "java/lang/IllegalStateException", "Message queue not initialized"); 109} 110 111static jboolean android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, 112 jint timeoutMillis) { 113 NativeMessageQueue* nativeMessageQueue = 114 android_os_MessageQueue_getNativeMessageQueue(env, obj); 115 if (! nativeMessageQueue) { 116 throwQueueNotInitialized(env); 117 return false; 118 } 119 return nativeMessageQueue->pollOnce(timeoutMillis); 120} 121 122static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj) { 123 NativeMessageQueue* nativeMessageQueue = 124 android_os_MessageQueue_getNativeMessageQueue(env, obj); 125 if (! nativeMessageQueue) { 126 throwQueueNotInitialized(env); 127 return; 128 } 129 return nativeMessageQueue->wake(); 130} 131 132// ---------------------------------------------------------------------------- 133 134static JNINativeMethod gMessageQueueMethods[] = { 135 /* name, signature, funcPtr */ 136 { "nativeInit", "()V", (void*)android_os_MessageQueue_nativeInit }, 137 { "nativeDestroy", "()V", (void*)android_os_MessageQueue_nativeDestroy }, 138 { "nativePollOnce", "(I)Z", (void*)android_os_MessageQueue_nativePollOnce }, 139 { "nativeWake", "()V", (void*)android_os_MessageQueue_nativeWake } 140}; 141 142#define FIND_CLASS(var, className) \ 143 var = env->FindClass(className); \ 144 LOG_FATAL_IF(! var, "Unable to find class " className); \ 145 var = jclass(env->NewGlobalRef(var)); 146 147#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 148 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 149 LOG_FATAL_IF(! var, "Unable to find field " fieldName); 150 151int register_android_os_MessageQueue(JNIEnv* env) { 152 int res = jniRegisterNativeMethods(env, "android/os/MessageQueue", 153 gMessageQueueMethods, NELEM(gMessageQueueMethods)); 154 LOG_FATAL_IF(res < 0, "Unable to register native methods."); 155 156 FIND_CLASS(gMessageQueueClassInfo.clazz, "android/os/MessageQueue"); 157 158 GET_FIELD_ID(gMessageQueueClassInfo.mPtr, gMessageQueueClassInfo.clazz, 159 "mPtr", "I"); 160 161 return 0; 162} 163 164} // namespace android 165