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> 2487eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include <android_runtime/Log.h> 252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <utils/Log.h> 262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#include <android/graphics/GraphicsJNI.h> 272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownnamespace android { 292352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatic struct { 312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jclass clazz; 322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mStyle; 332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mBitmap; 342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mHotSpotX; 352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mHotSpotY; 362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jmethodID getSystemIcon; 372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jmethodID load; 382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} gPointerIconClassInfo; 392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// --- Global Functions --- 422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownjobject android_view_PointerIcon_getSystemIcon(JNIEnv* env, jobject contextObj, int32_t style) { 442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject pointerIconObj = env->CallStaticObjectMethod(gPointerIconClassInfo.clazz, 452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.getSystemIcon, contextObj, style); 462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (env->ExceptionCheck()) { 478564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("An exception occurred while getting a pointer icon with style %d.", style); 482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOGW_EX(env); 492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->ExceptionClear(); 502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return NULL; 512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return pointerIconObj; 532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatus_t android_view_PointerIcon_load(JNIEnv* env, jobject pointerIconObj, jobject contextObj, 562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown PointerIcon* outPointerIcon) { 572352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->reset(); 582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (!pointerIconObj) { 602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return OK; 612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject loadedPointerIconObj = env->CallObjectMethod(pointerIconObj, 642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.load, contextObj); 652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (env->ExceptionCheck() || !loadedPointerIconObj) { 668564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("An exception occurred while loading a pointer icon."); 672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOGW_EX(env); 682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->ExceptionClear(); 692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return UNKNOWN_ERROR; 702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->style = env->GetIntField(loadedPointerIconObj, 732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.mStyle); 742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->hotSpotX = env->GetFloatField(loadedPointerIconObj, 752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.mHotSpotX); 762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->hotSpotY = env->GetFloatField(loadedPointerIconObj, 772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.mHotSpotY); 782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject bitmapObj = env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmap); 802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (bitmapObj) { 812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown SkBitmap* bitmap = GraphicsJNI::getNativeBitmap(env, bitmapObj); 822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (bitmap) { 832352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->bitmap = *bitmap; // use a shared pixel ref 842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 852352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->DeleteLocalRef(bitmapObj); 862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 872352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 882352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->DeleteLocalRef(loadedPointerIconObj); 892352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return OK; 902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatus_t android_view_PointerIcon_loadSystemIcon(JNIEnv* env, jobject contextObj, 932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown int32_t style, PointerIcon* outPointerIcon) { 942352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject pointerIconObj = android_view_PointerIcon_getSystemIcon(env, contextObj, style); 952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (!pointerIconObj) { 962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->reset(); 972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return UNKNOWN_ERROR; 982352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 992352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1002352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown status_t status = android_view_PointerIcon_load(env, pointerIconObj, 1012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown contextObj, outPointerIcon); 1022352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->DeleteLocalRef(pointerIconObj); 1032352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return status; 1042352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 1052352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1062352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1072352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// --- JNI Registration --- 1082352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1092352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define FIND_CLASS(var, className) \ 1102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = env->FindClass(className); \ 1112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); \ 1122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = jclass(env->NewGlobalRef(var)); 1132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 1152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \ 1162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOG_FATAL_IF(! var, "Unable to find method " methodName); 1172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 1192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 1202352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOG_FATAL_IF(! var, "Unable to find method " methodName); 1212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 1232352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 1242352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOG_FATAL_IF(! var, "Unable to find field " fieldName); 1252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownint register_android_view_PointerIcon(JNIEnv* env) { 1272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown FIND_CLASS(gPointerIconClassInfo.clazz, "android/view/PointerIcon"); 1282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1292352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_FIELD_ID(gPointerIconClassInfo.mBitmap, gPointerIconClassInfo.clazz, 1302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mBitmap", "Landroid/graphics/Bitmap;"); 1312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_FIELD_ID(gPointerIconClassInfo.mStyle, gPointerIconClassInfo.clazz, 1332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mStyle", "I"); 1342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_FIELD_ID(gPointerIconClassInfo.mHotSpotX, gPointerIconClassInfo.clazz, 1362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mHotSpotX", "F"); 1372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_FIELD_ID(gPointerIconClassInfo.mHotSpotY, gPointerIconClassInfo.clazz, 1392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mHotSpotY", "F"); 1402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_STATIC_METHOD_ID(gPointerIconClassInfo.getSystemIcon, gPointerIconClassInfo.clazz, 1422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "getSystemIcon", "(Landroid/content/Context;I)Landroid/view/PointerIcon;"); 1432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown GET_METHOD_ID(gPointerIconClassInfo.load, gPointerIconClassInfo.clazz, 1452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "load", "(Landroid/content/Context;)Landroid/view/PointerIcon;"); 1462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return 0; 1482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 1492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} // namespace android 151