android_os_MessageQueue.cpp revision 415d8c38199e258dfce92cdb0c69e056b3b51ef8
1fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate/* 2fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * Copyright (C) 2010 The Android Open Source Project 3fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * 4fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * Licensed under the Apache License, Version 2.0 (the "License"); 5fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * you may not use this file except in compliance with the License. 6fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * You may obtain a copy of the License at 7fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * 8fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * http://www.apache.org/licenses/LICENSE-2.0 9fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * 10fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * Unless required by applicable law or agreed to in writing, software 11fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * distributed under the License is distributed on an "AS IS" BASIS, 12fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * See the License for the specific language governing permissions and 14fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * limitations under the License. 15fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate */ 16fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "MessageQueue-JNI" 18fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 19fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate#include "JNIHelp.h" 20fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 214fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#include <utils/Looper.h> 22fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate#include <utils/Log.h> 2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_os_MessageQueue.h" 24fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 2546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android { 26fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 27fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate// ---------------------------------------------------------------------------- 28fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 29fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tatestatic struct { 3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jclass clazz; 31fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mPtr; // native object attached to the DVM MessageQueue 3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gMessageQueueClassInfo; 34fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 35fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate// ---------------------------------------------------------------------------- 36fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownclass NativeMessageQueue { 38fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tatepublic: 3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeMessageQueue(); 4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown ~NativeMessageQueue(); 41fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 424fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown inline sp<Looper> getLooper() { return mLooper; } 43fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 44415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown void pollOnce(int timeoutMillis); 4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown void wake(); 46fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 47fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tateprivate: 484fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown sp<Looper> mLooper; 49fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate}; 50fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 52fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 5346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownNativeMessageQueue::NativeMessageQueue() { 544fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown mLooper = Looper::getForThread(); 554fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (mLooper == NULL) { 564fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown mLooper = new Looper(false); 574fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown Looper::setForThread(mLooper); 58682674154e3fe88f6061245145f934f25f1a2eb8Dianne Hackborn } 59fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 60fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownNativeMessageQueue::~NativeMessageQueue() { 62fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 63fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 64415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brownvoid NativeMessageQueue::pollOnce(int timeoutMillis) { 65415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mLooper->pollOnce(timeoutMillis); 66fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 67fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 6846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid NativeMessageQueue::wake() { 694fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown mLooper->wake(); 70fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 71fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 7246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 73fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 7446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic NativeMessageQueue* android_os_MessageQueue_getNativeMessageQueue(JNIEnv* env, 7546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jobject messageQueueObj) { 7646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint intPtr = env->GetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr); 7746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return reinterpret_cast<NativeMessageQueue*>(intPtr); 78fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 79fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 8046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject messageQueueObj, 8146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeMessageQueue* nativeMessageQueue) { 8246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr, 8346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown reinterpret_cast<jint>(nativeMessageQueue)); 84fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 85fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 864fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownsp<Looper> android_os_MessageQueue_getLooper(JNIEnv* env, jobject messageQueueObj) { 8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeMessageQueue* nativeMessageQueue = 8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_os_MessageQueue_getNativeMessageQueue(env, messageQueueObj); 894fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return nativeMessageQueue != NULL ? nativeMessageQueue->getLooper() : NULL; 9046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 91fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 9246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) { 9346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue(); 9446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (! nativeMessageQueue) { 9546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jniThrowRuntimeException(env, "Unable to allocate native queue"); 9646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return; 97fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate } 98fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 9946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue); 100fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 101fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 10246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jobject obj) { 10346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown NativeMessageQueue* nativeMessageQueue = 10446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_os_MessageQueue_getNativeMessageQueue(env, obj); 10546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (nativeMessageQueue) { 10646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown android_os_MessageQueue_setNativeMessageQueue(env, obj, NULL); 10746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown delete nativeMessageQueue; 108fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate } 109fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 110fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 11146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic void throwQueueNotInitialized(JNIEnv* env) { 11246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jniThrowException(env, "java/lang/IllegalStateException", "Message queue not initialized"); 113fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 114fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 115415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brownstatic void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, 116415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown jint ptr, jint timeoutMillis) { 117415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr); 118415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown nativeMessageQueue->pollOnce(timeoutMillis); 119fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 120fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 121415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brownstatic void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint ptr) { 122415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr); 12346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return nativeMessageQueue->wake(); 124fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 125fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 126fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate// ---------------------------------------------------------------------------- 127fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 128fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tatestatic JNINativeMethod gMessageQueueMethods[] = { 129fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate /* name, signature, funcPtr */ 13046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown { "nativeInit", "()V", (void*)android_os_MessageQueue_nativeInit }, 13146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown { "nativeDestroy", "()V", (void*)android_os_MessageQueue_nativeDestroy }, 132415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown { "nativePollOnce", "(II)V", (void*)android_os_MessageQueue_nativePollOnce }, 133415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake } 134fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate}; 135fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 13646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define FIND_CLASS(var, className) \ 13746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = env->FindClass(className); \ 13846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); \ 13946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = jclass(env->NewGlobalRef(var)); 14046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 14146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 14246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 14346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown LOG_FATAL_IF(! var, "Unable to find field " fieldName); 14446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 145fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tateint register_android_os_MessageQueue(JNIEnv* env) { 14646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int res = jniRegisterNativeMethods(env, "android/os/MessageQueue", 14746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown gMessageQueueMethods, NELEM(gMessageQueueMethods)); 14846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown LOG_FATAL_IF(res < 0, "Unable to register native methods."); 14946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 15046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown FIND_CLASS(gMessageQueueClassInfo.clazz, "android/os/MessageQueue"); 151fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 15246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gMessageQueueClassInfo.mPtr, gMessageQueueClassInfo.clazz, 15346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mPtr", "I"); 154fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 15546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown return 0; 156fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate} 157fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate 15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android 159