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 "PointerIcon-JNI" 18 19 #include "JNIHelp.h" 20 21 #include "android_view_PointerIcon.h" 22 23 #include <android_runtime/AndroidRuntime.h> 24 #include <android_runtime/Log.h> 25 #include <utils/Log.h> 26 #include <android/graphics/GraphicsJNI.h> 27 28 namespace android { 29 30 static struct { 31 jclass clazz; 32 jfieldID mStyle; 33 jfieldID mBitmap; 34 jfieldID mHotSpotX; 35 jfieldID mHotSpotY; 36 jmethodID getSystemIcon; 37 jmethodID load; 38 } gPointerIconClassInfo; 39 40 41 // --- Global Functions --- 42 43 jobject android_view_PointerIcon_getSystemIcon(JNIEnv* env, jobject contextObj, int32_t style) { 44 jobject pointerIconObj = env->CallStaticObjectMethod(gPointerIconClassInfo.clazz, 45 gPointerIconClassInfo.getSystemIcon, contextObj, style); 46 if (env->ExceptionCheck()) { 47 ALOGW("An exception occurred while getting a pointer icon with style %d.", style); 48 LOGW_EX(env); 49 env->ExceptionClear(); 50 return NULL; 51 } 52 return pointerIconObj; 53 } 54 55 status_t android_view_PointerIcon_load(JNIEnv* env, jobject pointerIconObj, jobject contextObj, 56 PointerIcon* outPointerIcon) { 57 outPointerIcon->reset(); 58 59 if (!pointerIconObj) { 60 return OK; 61 } 62 63 jobject loadedPointerIconObj = env->CallObjectMethod(pointerIconObj, 64 gPointerIconClassInfo.load, contextObj); 65 if (env->ExceptionCheck() || !loadedPointerIconObj) { 66 ALOGW("An exception occurred while loading a pointer icon."); 67 LOGW_EX(env); 68 env->ExceptionClear(); 69 return UNKNOWN_ERROR; 70 } 71 72 outPointerIcon->style = env->GetIntField(loadedPointerIconObj, 73 gPointerIconClassInfo.mStyle); 74 outPointerIcon->hotSpotX = env->GetFloatField(loadedPointerIconObj, 75 gPointerIconClassInfo.mHotSpotX); 76 outPointerIcon->hotSpotY = env->GetFloatField(loadedPointerIconObj, 77 gPointerIconClassInfo.mHotSpotY); 78 79 jobject bitmapObj = env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmap); 80 if (bitmapObj) { 81 SkBitmap* bitmap = GraphicsJNI::getNativeBitmap(env, bitmapObj); 82 if (bitmap) { 83 outPointerIcon->bitmap = *bitmap; // use a shared pixel ref 84 } 85 env->DeleteLocalRef(bitmapObj); 86 } 87 88 env->DeleteLocalRef(loadedPointerIconObj); 89 return OK; 90 } 91 92 status_t android_view_PointerIcon_loadSystemIcon(JNIEnv* env, jobject contextObj, 93 int32_t style, PointerIcon* outPointerIcon) { 94 jobject pointerIconObj = android_view_PointerIcon_getSystemIcon(env, contextObj, style); 95 if (!pointerIconObj) { 96 outPointerIcon->reset(); 97 return UNKNOWN_ERROR; 98 } 99 100 status_t status = android_view_PointerIcon_load(env, pointerIconObj, 101 contextObj, outPointerIcon); 102 env->DeleteLocalRef(pointerIconObj); 103 return status; 104 } 105 106 107 // --- JNI Registration --- 108 109 #define FIND_CLASS(var, className) \ 110 var = env->FindClass(className); \ 111 LOG_FATAL_IF(! var, "Unable to find class " className); \ 112 var = jclass(env->NewGlobalRef(var)); 113 114 #define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 115 var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \ 116 LOG_FATAL_IF(! var, "Unable to find method " methodName); 117 118 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 119 var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 120 LOG_FATAL_IF(! var, "Unable to find method " methodName); 121 122 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 123 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 124 LOG_FATAL_IF(! var, "Unable to find field " fieldName); 125 126 int register_android_view_PointerIcon(JNIEnv* env) { 127 FIND_CLASS(gPointerIconClassInfo.clazz, "android/view/PointerIcon"); 128 129 GET_FIELD_ID(gPointerIconClassInfo.mBitmap, gPointerIconClassInfo.clazz, 130 "mBitmap", "Landroid/graphics/Bitmap;"); 131 132 GET_FIELD_ID(gPointerIconClassInfo.mStyle, gPointerIconClassInfo.clazz, 133 "mStyle", "I"); 134 135 GET_FIELD_ID(gPointerIconClassInfo.mHotSpotX, gPointerIconClassInfo.clazz, 136 "mHotSpotX", "F"); 137 138 GET_FIELD_ID(gPointerIconClassInfo.mHotSpotY, gPointerIconClassInfo.clazz, 139 "mHotSpotY", "F"); 140 141 GET_STATIC_METHOD_ID(gPointerIconClassInfo.getSystemIcon, gPointerIconClassInfo.clazz, 142 "getSystemIcon", "(Landroid/content/Context;I)Landroid/view/PointerIcon;"); 143 144 GET_METHOD_ID(gPointerIconClassInfo.load, gPointerIconClassInfo.clazz, 145 "load", "(Landroid/content/Context;)Landroid/view/PointerIcon;"); 146 147 return 0; 148 } 149 150 } // namespace android 151