blob: 12a77d53db25b10d1922020b706ced5b5caea1fa [file] [log] [blame]
Christopher Tatefa9e7c02010-05-06 12:07:10 -07001/*
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
Jeff Brown46b9ac02010-04-22 18:58:52 -070017#define LOG_TAG "MessageQueue-JNI"
Christopher Tatefa9e7c02010-05-06 12:07:10 -070018
19#include "JNIHelp.h"
20
Jeff Brown4fe6c3e2010-09-13 23:17:30 -070021#include <utils/Looper.h>
Christopher Tatefa9e7c02010-05-06 12:07:10 -070022#include <utils/Log.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070023#include "android_os_MessageQueue.h"
Christopher Tatefa9e7c02010-05-06 12:07:10 -070024
25namespace android {
Christopher Tatefa9e7c02010-05-06 12:07:10 -070026
Jeff Brown46b9ac02010-04-22 18:58:52 -070027// ----------------------------------------------------------------------------
Christopher Tatefa9e7c02010-05-06 12:07:10 -070028
Jeff Brown46b9ac02010-04-22 18:58:52 -070029static struct {
Jeff Brown46b9ac02010-04-22 18:58:52 -070030 jfieldID mPtr; // native object attached to the DVM MessageQueue
31} gMessageQueueClassInfo;
32
33// ----------------------------------------------------------------------------
34
35class NativeMessageQueue {
36public:
37 NativeMessageQueue();
38 ~NativeMessageQueue();
39
Jeff Brown4fe6c3e2010-09-13 23:17:30 -070040 inline sp<Looper> getLooper() { return mLooper; }
Jeff Brown46b9ac02010-04-22 18:58:52 -070041
Jeff Brown415d8c32010-10-05 15:35:37 -070042 void pollOnce(int timeoutMillis);
Jeff Brown46b9ac02010-04-22 18:58:52 -070043 void wake();
44
45private:
Jeff Brown4fe6c3e2010-09-13 23:17:30 -070046 sp<Looper> mLooper;
Jeff Brown46b9ac02010-04-22 18:58:52 -070047};
48
49// ----------------------------------------------------------------------------
50
51NativeMessageQueue::NativeMessageQueue() {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -070052 mLooper = Looper::getForThread();
53 if (mLooper == NULL) {
54 mLooper = new Looper(false);
55 Looper::setForThread(mLooper);
Dianne Hackborn68267412010-07-02 18:52:01 -070056 }
Christopher Tatefa9e7c02010-05-06 12:07:10 -070057}
58
Jeff Brown46b9ac02010-04-22 18:58:52 -070059NativeMessageQueue::~NativeMessageQueue() {
Christopher Tatefa9e7c02010-05-06 12:07:10 -070060}
61
Jeff Brown415d8c32010-10-05 15:35:37 -070062void NativeMessageQueue::pollOnce(int timeoutMillis) {
63 mLooper->pollOnce(timeoutMillis);
Christopher Tatefa9e7c02010-05-06 12:07:10 -070064}
65
Jeff Brown46b9ac02010-04-22 18:58:52 -070066void NativeMessageQueue::wake() {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -070067 mLooper->wake();
Christopher Tatefa9e7c02010-05-06 12:07:10 -070068}
69
70// ----------------------------------------------------------------------------
71
Jeff Brown46b9ac02010-04-22 18:58:52 -070072static NativeMessageQueue* android_os_MessageQueue_getNativeMessageQueue(JNIEnv* env,
73 jobject messageQueueObj) {
74 jint intPtr = env->GetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr);
75 return reinterpret_cast<NativeMessageQueue*>(intPtr);
76}
77
78static void android_os_MessageQueue_setNativeMessageQueue(JNIEnv* env, jobject messageQueueObj,
79 NativeMessageQueue* nativeMessageQueue) {
80 env->SetIntField(messageQueueObj, gMessageQueueClassInfo.mPtr,
81 reinterpret_cast<jint>(nativeMessageQueue));
82}
83
Jeff Brown4fe6c3e2010-09-13 23:17:30 -070084sp<Looper> android_os_MessageQueue_getLooper(JNIEnv* env, jobject messageQueueObj) {
Jeff Brown46b9ac02010-04-22 18:58:52 -070085 NativeMessageQueue* nativeMessageQueue =
86 android_os_MessageQueue_getNativeMessageQueue(env, messageQueueObj);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -070087 return nativeMessageQueue != NULL ? nativeMessageQueue->getLooper() : NULL;
Jeff Brown46b9ac02010-04-22 18:58:52 -070088}
89
90static void android_os_MessageQueue_nativeInit(JNIEnv* env, jobject obj) {
91 NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
92 if (! nativeMessageQueue) {
93 jniThrowRuntimeException(env, "Unable to allocate native queue");
94 return;
95 }
96
97 android_os_MessageQueue_setNativeMessageQueue(env, obj, nativeMessageQueue);
98}
99
100static void android_os_MessageQueue_nativeDestroy(JNIEnv* env, jobject obj) {
101 NativeMessageQueue* nativeMessageQueue =
102 android_os_MessageQueue_getNativeMessageQueue(env, obj);
103 if (nativeMessageQueue) {
104 android_os_MessageQueue_setNativeMessageQueue(env, obj, NULL);
105 delete nativeMessageQueue;
106 }
107}
108
109static void throwQueueNotInitialized(JNIEnv* env) {
110 jniThrowException(env, "java/lang/IllegalStateException", "Message queue not initialized");
111}
112
Jeff Brown415d8c32010-10-05 15:35:37 -0700113static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
114 jint ptr, jint timeoutMillis) {
115 NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
116 nativeMessageQueue->pollOnce(timeoutMillis);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700117}
118
Jeff Brown415d8c32010-10-05 15:35:37 -0700119static void android_os_MessageQueue_nativeWake(JNIEnv* env, jobject obj, jint ptr) {
120 NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700121 return nativeMessageQueue->wake();
122}
123
124// ----------------------------------------------------------------------------
Christopher Tatefa9e7c02010-05-06 12:07:10 -0700125
126static JNINativeMethod gMessageQueueMethods[] = {
127 /* name, signature, funcPtr */
Jeff Brown46b9ac02010-04-22 18:58:52 -0700128 { "nativeInit", "()V", (void*)android_os_MessageQueue_nativeInit },
129 { "nativeDestroy", "()V", (void*)android_os_MessageQueue_nativeDestroy },
Jeff Brown415d8c32010-10-05 15:35:37 -0700130 { "nativePollOnce", "(II)V", (void*)android_os_MessageQueue_nativePollOnce },
131 { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake }
Christopher Tatefa9e7c02010-05-06 12:07:10 -0700132};
133
Jeff Brown46b9ac02010-04-22 18:58:52 -0700134#define FIND_CLASS(var, className) \
135 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800136 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700137
138#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
139 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
140 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
141
Christopher Tatefa9e7c02010-05-06 12:07:10 -0700142int register_android_os_MessageQueue(JNIEnv* env) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700143 int res = jniRegisterNativeMethods(env, "android/os/MessageQueue",
Christopher Tatefa9e7c02010-05-06 12:07:10 -0700144 gMessageQueueMethods, NELEM(gMessageQueueMethods));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700145 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
146
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800147 jclass clazz;
148 FIND_CLASS(clazz, "android/os/MessageQueue");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700149
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800150 GET_FIELD_ID(gMessageQueueClassInfo.mPtr, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700151 "mPtr", "I");
152
153 return 0;
Christopher Tatefa9e7c02010-05-06 12:07:10 -0700154}
155
Jeff Brown46b9ac02010-04-22 18:58:52 -0700156} // namespace android