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 "InputWindowHandle" 18 19 #include "JNIHelp.h" 20 #include "jni.h" 21 #include <android_runtime/AndroidRuntime.h> 22 #include <utils/threads.h> 23 24 #include <android_view_InputChannel.h> 25 #include <android/graphics/Region.h> 26 27 #include "com_android_server_input_InputWindowHandle.h" 28 #include "com_android_server_input_InputApplicationHandle.h" 29 30 namespace android { 31 32 static struct { 33 jfieldID ptr; 34 jfieldID inputApplicationHandle; 35 jfieldID inputChannel; 36 jfieldID name; 37 jfieldID layoutParamsFlags; 38 jfieldID layoutParamsPrivateFlags; 39 jfieldID layoutParamsType; 40 jfieldID dispatchingTimeoutNanos; 41 jfieldID frameLeft; 42 jfieldID frameTop; 43 jfieldID frameRight; 44 jfieldID frameBottom; 45 jfieldID scaleFactor; 46 jfieldID touchableRegion; 47 jfieldID visible; 48 jfieldID canReceiveKeys; 49 jfieldID hasFocus; 50 jfieldID hasWallpaper; 51 jfieldID paused; 52 jfieldID layer; 53 jfieldID ownerPid; 54 jfieldID ownerUid; 55 jfieldID inputFeatures; 56 jfieldID displayId; 57 } gInputWindowHandleClassInfo; 58 59 static Mutex gHandleMutex; 60 61 62 // --- NativeInputWindowHandle --- 63 64 NativeInputWindowHandle::NativeInputWindowHandle( 65 const sp<InputApplicationHandle>& inputApplicationHandle, jweak objWeak) : 66 InputWindowHandle(inputApplicationHandle), 67 mObjWeak(objWeak) { 68 } 69 70 NativeInputWindowHandle::~NativeInputWindowHandle() { 71 JNIEnv* env = AndroidRuntime::getJNIEnv(); 72 env->DeleteWeakGlobalRef(mObjWeak); 73 } 74 75 jobject NativeInputWindowHandle::getInputWindowHandleObjLocalRef(JNIEnv* env) { 76 return env->NewLocalRef(mObjWeak); 77 } 78 79 bool NativeInputWindowHandle::updateInfo() { 80 JNIEnv* env = AndroidRuntime::getJNIEnv(); 81 jobject obj = env->NewLocalRef(mObjWeak); 82 if (!obj) { 83 releaseInfo(); 84 return false; 85 } 86 87 if (!mInfo) { 88 mInfo = new InputWindowInfo(); 89 } 90 91 jobject inputChannelObj = env->GetObjectField(obj, 92 gInputWindowHandleClassInfo.inputChannel); 93 if (inputChannelObj) { 94 mInfo->inputChannel = android_view_InputChannel_getInputChannel(env, inputChannelObj); 95 env->DeleteLocalRef(inputChannelObj); 96 } else { 97 mInfo->inputChannel.clear(); 98 } 99 100 jstring nameObj = jstring(env->GetObjectField(obj, 101 gInputWindowHandleClassInfo.name)); 102 if (nameObj) { 103 const char* nameStr = env->GetStringUTFChars(nameObj, NULL); 104 mInfo->name.setTo(nameStr); 105 env->ReleaseStringUTFChars(nameObj, nameStr); 106 env->DeleteLocalRef(nameObj); 107 } else { 108 mInfo->name.setTo("<null>"); 109 } 110 111 mInfo->layoutParamsFlags = env->GetIntField(obj, 112 gInputWindowHandleClassInfo.layoutParamsFlags); 113 mInfo->layoutParamsPrivateFlags = env->GetIntField(obj, 114 gInputWindowHandleClassInfo.layoutParamsPrivateFlags); 115 mInfo->layoutParamsType = env->GetIntField(obj, 116 gInputWindowHandleClassInfo.layoutParamsType); 117 mInfo->dispatchingTimeout = env->GetLongField(obj, 118 gInputWindowHandleClassInfo.dispatchingTimeoutNanos); 119 mInfo->frameLeft = env->GetIntField(obj, 120 gInputWindowHandleClassInfo.frameLeft); 121 mInfo->frameTop = env->GetIntField(obj, 122 gInputWindowHandleClassInfo.frameTop); 123 mInfo->frameRight = env->GetIntField(obj, 124 gInputWindowHandleClassInfo.frameRight); 125 mInfo->frameBottom = env->GetIntField(obj, 126 gInputWindowHandleClassInfo.frameBottom); 127 mInfo->scaleFactor = env->GetFloatField(obj, 128 gInputWindowHandleClassInfo.scaleFactor); 129 130 jobject regionObj = env->GetObjectField(obj, 131 gInputWindowHandleClassInfo.touchableRegion); 132 if (regionObj) { 133 SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj); 134 mInfo->touchableRegion.set(*region); 135 env->DeleteLocalRef(regionObj); 136 } else { 137 mInfo->touchableRegion.setEmpty(); 138 } 139 140 mInfo->visible = env->GetBooleanField(obj, 141 gInputWindowHandleClassInfo.visible); 142 mInfo->canReceiveKeys = env->GetBooleanField(obj, 143 gInputWindowHandleClassInfo.canReceiveKeys); 144 mInfo->hasFocus = env->GetBooleanField(obj, 145 gInputWindowHandleClassInfo.hasFocus); 146 mInfo->hasWallpaper = env->GetBooleanField(obj, 147 gInputWindowHandleClassInfo.hasWallpaper); 148 mInfo->paused = env->GetBooleanField(obj, 149 gInputWindowHandleClassInfo.paused); 150 mInfo->layer = env->GetIntField(obj, 151 gInputWindowHandleClassInfo.layer); 152 mInfo->ownerPid = env->GetIntField(obj, 153 gInputWindowHandleClassInfo.ownerPid); 154 mInfo->ownerUid = env->GetIntField(obj, 155 gInputWindowHandleClassInfo.ownerUid); 156 mInfo->inputFeatures = env->GetIntField(obj, 157 gInputWindowHandleClassInfo.inputFeatures); 158 mInfo->displayId = env->GetIntField(obj, 159 gInputWindowHandleClassInfo.displayId); 160 161 env->DeleteLocalRef(obj); 162 return true; 163 } 164 165 166 // --- Global functions --- 167 168 sp<NativeInputWindowHandle> android_server_InputWindowHandle_getHandle( 169 JNIEnv* env, jobject inputWindowHandleObj) { 170 if (!inputWindowHandleObj) { 171 return NULL; 172 } 173 174 AutoMutex _l(gHandleMutex); 175 176 int ptr = env->GetIntField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr); 177 NativeInputWindowHandle* handle; 178 if (ptr) { 179 handle = reinterpret_cast<NativeInputWindowHandle*>(ptr); 180 } else { 181 jobject inputApplicationHandleObj = env->GetObjectField(inputWindowHandleObj, 182 gInputWindowHandleClassInfo.inputApplicationHandle); 183 sp<InputApplicationHandle> inputApplicationHandle = 184 android_server_InputApplicationHandle_getHandle(env, inputApplicationHandleObj); 185 env->DeleteLocalRef(inputApplicationHandleObj); 186 187 jweak objWeak = env->NewWeakGlobalRef(inputWindowHandleObj); 188 handle = new NativeInputWindowHandle(inputApplicationHandle, objWeak); 189 handle->incStrong((void*)android_server_InputWindowHandle_getHandle); 190 env->SetIntField(inputWindowHandleObj, gInputWindowHandleClassInfo.ptr, 191 reinterpret_cast<int>(handle)); 192 } 193 return handle; 194 } 195 196 197 // --- JNI --- 198 199 static void android_server_InputWindowHandle_nativeDispose(JNIEnv* env, jobject obj) { 200 AutoMutex _l(gHandleMutex); 201 202 int ptr = env->GetIntField(obj, gInputWindowHandleClassInfo.ptr); 203 if (ptr) { 204 env->SetIntField(obj, gInputWindowHandleClassInfo.ptr, 0); 205 206 NativeInputWindowHandle* handle = reinterpret_cast<NativeInputWindowHandle*>(ptr); 207 handle->decStrong((void*)android_server_InputWindowHandle_getHandle); 208 } 209 } 210 211 212 static JNINativeMethod gInputWindowHandleMethods[] = { 213 /* name, signature, funcPtr */ 214 { "nativeDispose", "()V", 215 (void*) android_server_InputWindowHandle_nativeDispose }, 216 }; 217 218 #define FIND_CLASS(var, className) \ 219 var = env->FindClass(className); \ 220 LOG_FATAL_IF(! var, "Unable to find class " className); 221 222 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 223 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 224 LOG_FATAL_IF(! var, "Unable to find field " fieldName); 225 226 int register_android_server_InputWindowHandle(JNIEnv* env) { 227 int res = jniRegisterNativeMethods(env, "com/android/server/input/InputWindowHandle", 228 gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods)); 229 LOG_FATAL_IF(res < 0, "Unable to register native methods."); 230 231 jclass clazz; 232 FIND_CLASS(clazz, "com/android/server/input/InputWindowHandle"); 233 234 GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, clazz, 235 "ptr", "I"); 236 237 GET_FIELD_ID(gInputWindowHandleClassInfo.inputApplicationHandle, 238 clazz, 239 "inputApplicationHandle", "Lcom/android/server/input/InputApplicationHandle;"); 240 241 GET_FIELD_ID(gInputWindowHandleClassInfo.inputChannel, clazz, 242 "inputChannel", "Landroid/view/InputChannel;"); 243 244 GET_FIELD_ID(gInputWindowHandleClassInfo.name, clazz, 245 "name", "Ljava/lang/String;"); 246 247 GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsFlags, clazz, 248 "layoutParamsFlags", "I"); 249 250 GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsPrivateFlags, clazz, 251 "layoutParamsPrivateFlags", "I"); 252 253 GET_FIELD_ID(gInputWindowHandleClassInfo.layoutParamsType, clazz, 254 "layoutParamsType", "I"); 255 256 GET_FIELD_ID(gInputWindowHandleClassInfo.dispatchingTimeoutNanos, clazz, 257 "dispatchingTimeoutNanos", "J"); 258 259 GET_FIELD_ID(gInputWindowHandleClassInfo.frameLeft, clazz, 260 "frameLeft", "I"); 261 262 GET_FIELD_ID(gInputWindowHandleClassInfo.frameTop, clazz, 263 "frameTop", "I"); 264 265 GET_FIELD_ID(gInputWindowHandleClassInfo.frameRight, clazz, 266 "frameRight", "I"); 267 268 GET_FIELD_ID(gInputWindowHandleClassInfo.frameBottom, clazz, 269 "frameBottom", "I"); 270 271 GET_FIELD_ID(gInputWindowHandleClassInfo.scaleFactor, clazz, 272 "scaleFactor", "F"); 273 274 GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz, 275 "touchableRegion", "Landroid/graphics/Region;"); 276 277 GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz, 278 "visible", "Z"); 279 280 GET_FIELD_ID(gInputWindowHandleClassInfo.canReceiveKeys, clazz, 281 "canReceiveKeys", "Z"); 282 283 GET_FIELD_ID(gInputWindowHandleClassInfo.hasFocus, clazz, 284 "hasFocus", "Z"); 285 286 GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz, 287 "hasWallpaper", "Z"); 288 289 GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz, 290 "paused", "Z"); 291 292 GET_FIELD_ID(gInputWindowHandleClassInfo.layer, clazz, 293 "layer", "I"); 294 295 GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz, 296 "ownerPid", "I"); 297 298 GET_FIELD_ID(gInputWindowHandleClassInfo.ownerUid, clazz, 299 "ownerUid", "I"); 300 301 GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz, 302 "inputFeatures", "I"); 303 304 GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz, 305 "displayId", "I"); 306 return 0; 307 } 308 309 } /* namespace android */ 310