12352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown/* 22352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Copyright (C) 2011 The Android Open Source Project 32352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 42352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 52352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * you may not use this file except in compliance with the License. 62352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * You may obtain a copy of the License at 72352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 82352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 92352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * 102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * Unless required by applicable law or agreed to in writing, software 112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * See the License for the specific language governing permissions and 142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown * limitations under the License. 152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown */ 162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define LOG_TAG "PointerIcon-JNI" 182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include "JNIHelp.h" 202352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include "android_view_PointerIcon.h" 222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 232352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <android_runtime/AndroidRuntime.h> 242352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <utils/Log.h> 252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <android/graphics/GraphicsJNI.h> 262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownnamespace android { 282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 292352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatic struct { 302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jclass clazz; 312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mStyle; 322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mBitmap; 332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mHotSpotX; 342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mHotSpotY; 352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jmethodID getSystemIcon; 362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jmethodID load; 372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} gPointerIconClassInfo; 382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// --- Global Functions --- 412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownjobject android_view_PointerIcon_getSystemIcon(JNIEnv* env, jobject contextObj, int32_t style) { 432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject pointerIconObj = env->CallStaticObjectMethod(gPointerIconClassInfo.clazz, 442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.getSystemIcon, contextObj, style); 452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (env->ExceptionCheck()) { 468564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("An exception occurred while getting a pointer icon with style %d.", style); 472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOGW_EX(env); 482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->ExceptionClear(); 492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return NULL; 502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return pointerIconObj; 522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatus_t android_view_PointerIcon_load(JNIEnv* env, jobject pointerIconObj, jobject contextObj, 552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown PointerIcon* outPointerIcon) { 562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->reset(); 572352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (!pointerIconObj) { 592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return OK; 602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject loadedPointerIconObj = env->CallObjectMethod(pointerIconObj, 632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.load, contextObj); 642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (env->ExceptionCheck() || !loadedPointerIconObj) { 658564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("An exception occurred while loading a pointer icon."); 662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOGW_EX(env); 672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->ExceptionClear(); 682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return UNKNOWN_ERROR; 692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->style = env->GetIntField(loadedPointerIconObj, 722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.mStyle); 732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->hotSpotX = env->GetFloatField(loadedPointerIconObj, 742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.mHotSpotX); 752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->hotSpotY = env->GetFloatField(loadedPointerIconObj, 762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.mHotSpotY); 772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject bitmapObj = env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmap); 792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (bitmapObj) { 802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown SkBitmap* bitmap = GraphicsJNI::getNativeBitmap(env, bitmapObj); 812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (bitmap) { 822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->bitmap = *bitmap; // use a shared pixel ref 832352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->DeleteLocalRef(bitmapObj); 852352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 872352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->DeleteLocalRef(loadedPointerIconObj); 882352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return OK; 892352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatus_t android_view_PointerIcon_loadSystemIcon(JNIEnv* env, jobject contextObj, 922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown int32_t style, PointerIcon* outPointerIcon) { 932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject pointerIconObj = android_view_PointerIcon_getSystemIcon(env, contextObj, style); 942352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (!pointerIconObj) { 952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->reset(); 962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return UNKNOWN_ERROR; 972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 982352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 992352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown status_t status = android_view_PointerIcon_load(env, pointerIconObj, 1002352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown contextObj, outPointerIcon); 1012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->DeleteLocalRef(pointerIconObj); 1022352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return status; 1032352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 1042352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1052352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1062352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// --- JNI Registration --- 1072352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1082352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define FIND_CLASS(var, className) \ 1092352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = env->FindClass(className); \ 1102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); \ 1112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = jclass(env->NewGlobalRef(var)); 1122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 1142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \ 1152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOG_FATAL_IF(! var, "Unable to find method " methodName); 1162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 1182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 1192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOG_FATAL_IF(! var, "Unable to find method " methodName); 1202352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 1222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 1232352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOG_FATAL_IF(! var, "Unable to find field " fieldName); 1242352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownint register_android_view_PointerIcon(JNIEnv* env) { 1262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown FIND_CLASS(gPointerIconClassInfo.clazz, "android/view/PointerIcon"); 1272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_FIELD_ID(gPointerIconClassInfo.mBitmap, gPointerIconClassInfo.clazz, 1292352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mBitmap", "Landroid/graphics/Bitmap;"); 1302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_FIELD_ID(gPointerIconClassInfo.mStyle, gPointerIconClassInfo.clazz, 1322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mStyle", "I"); 1332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_FIELD_ID(gPointerIconClassInfo.mHotSpotX, gPointerIconClassInfo.clazz, 1352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mHotSpotX", "F"); 1362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_FIELD_ID(gPointerIconClassInfo.mHotSpotY, gPointerIconClassInfo.clazz, 1382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mHotSpotY", "F"); 1392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_STATIC_METHOD_ID(gPointerIconClassInfo.getSystemIcon, gPointerIconClassInfo.clazz, 1412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "getSystemIcon", "(Landroid/content/Context;I)Landroid/view/PointerIcon;"); 1422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_METHOD_ID(gPointerIconClassInfo.load, gPointerIconClassInfo.clazz, 1442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "load", "(Landroid/content/Context;)Landroid/view/PointerIcon;"); 1452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return 0; 1472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 1482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} // namespace android 150