1 /* 2 * Copyright (C) 2011 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 "InputApplicationHandle" 18 19 #include "JNIHelp.h" 20 #include "jni.h" 21 #include <android_runtime/AndroidRuntime.h> 22 #include <utils/threads.h> 23 24 #include "com_android_server_InputApplicationHandle.h" 25 26 namespace android { 27 28 static struct { 29 jfieldID ptr; 30 jfieldID name; 31 jfieldID dispatchingTimeoutNanos; 32 } gInputApplicationHandleClassInfo; 33 34 static Mutex gHandleMutex; 35 36 37 // --- NativeInputApplicationHandle --- 38 39 NativeInputApplicationHandle::NativeInputApplicationHandle(jweak objWeak) : 40 mObjWeak(objWeak) { 41 } 42 43 NativeInputApplicationHandle::~NativeInputApplicationHandle() { 44 JNIEnv* env = AndroidRuntime::getJNIEnv(); 45 env->DeleteWeakGlobalRef(mObjWeak); 46 } 47 48 jobject NativeInputApplicationHandle::getInputApplicationHandleObjLocalRef(JNIEnv* env) { 49 return env->NewLocalRef(mObjWeak); 50 } 51 52 bool NativeInputApplicationHandle::updateInfo() { 53 JNIEnv* env = AndroidRuntime::getJNIEnv(); 54 jobject obj = env->NewLocalRef(mObjWeak); 55 if (!obj) { 56 releaseInfo(); 57 return false; 58 } 59 60 if (!mInfo) { 61 mInfo = new InputApplicationInfo(); 62 } 63 64 jstring nameObj = jstring(env->GetObjectField(obj, 65 gInputApplicationHandleClassInfo.name)); 66 if (nameObj) { 67 const char* nameStr = env->GetStringUTFChars(nameObj, NULL); 68 mInfo->name.setTo(nameStr); 69 env->ReleaseStringUTFChars(nameObj, nameStr); 70 env->DeleteLocalRef(nameObj); 71 } else { 72 mInfo->name.setTo("<null>"); 73 } 74 75 mInfo->dispatchingTimeout = env->GetLongField(obj, 76 gInputApplicationHandleClassInfo.dispatchingTimeoutNanos); 77 78 env->DeleteLocalRef(obj); 79 return true; 80 } 81 82 83 // --- Global functions --- 84 85 sp<InputApplicationHandle> android_server_InputApplicationHandle_getHandle( 86 JNIEnv* env, jobject inputApplicationHandleObj) { 87 if (!inputApplicationHandleObj) { 88 return NULL; 89 } 90 91 AutoMutex _l(gHandleMutex); 92 93 int ptr = env->GetIntField(inputApplicationHandleObj, gInputApplicationHandleClassInfo.ptr); 94 NativeInputApplicationHandle* handle; 95 if (ptr) { 96 handle = reinterpret_cast<NativeInputApplicationHandle*>(ptr); 97 } else { 98 jweak objWeak = env->NewWeakGlobalRef(inputApplicationHandleObj); 99 handle = new NativeInputApplicationHandle(objWeak); 100 handle->incStrong(inputApplicationHandleObj); 101 env->SetIntField(inputApplicationHandleObj, gInputApplicationHandleClassInfo.ptr, 102 reinterpret_cast<int>(handle)); 103 } 104 return handle; 105 } 106 107 108 // --- JNI --- 109 110 static void android_server_InputApplicationHandle_nativeDispose(JNIEnv* env, jobject obj) { 111 AutoMutex _l(gHandleMutex); 112 113 int ptr = env->GetIntField(obj, gInputApplicationHandleClassInfo.ptr); 114 if (ptr) { 115 env->SetIntField(obj, gInputApplicationHandleClassInfo.ptr, 0); 116 117 NativeInputApplicationHandle* handle = reinterpret_cast<NativeInputApplicationHandle*>(ptr); 118 handle->decStrong(obj); 119 } 120 } 121 122 123 static JNINativeMethod gInputApplicationHandleMethods[] = { 124 /* name, signature, funcPtr */ 125 { "nativeDispose", "()V", 126 (void*) android_server_InputApplicationHandle_nativeDispose }, 127 }; 128 129 #define FIND_CLASS(var, className) \ 130 var = env->FindClass(className); \ 131 LOG_FATAL_IF(! var, "Unable to find class " className); 132 133 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 134 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 135 LOG_FATAL_IF(! var, "Unable to find field " fieldName); 136 137 int register_android_server_InputApplicationHandle(JNIEnv* env) { 138 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputApplicationHandle", 139 gInputApplicationHandleMethods, NELEM(gInputApplicationHandleMethods)); 140 LOG_FATAL_IF(res < 0, "Unable to register native methods."); 141 142 jclass clazz; 143 FIND_CLASS(clazz, "com/android/server/wm/InputApplicationHandle"); 144 145 GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, clazz, 146 "ptr", "I"); 147 148 GET_FIELD_ID(gInputApplicationHandleClassInfo.name, clazz, 149 "name", "Ljava/lang/String;"); 150 151 GET_FIELD_ID(gInputApplicationHandleClassInfo.dispatchingTimeoutNanos, 152 clazz, 153 "dispatchingTimeoutNanos", "J"); 154 155 return 0; 156 } 157 158 } /* namespace android */ 159