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 192279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/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> 272279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/ScopedLocalRef.h> 282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 29987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe#include "core_jni_helpers.h" 30987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 312352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownnamespace android { 322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatic struct { 342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jclass clazz; 35f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright jfieldID mType; 362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mBitmap; 372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mHotSpotX; 382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jfieldID mHotSpotY; 39808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai jfieldID mBitmapFrames; 40808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai jfieldID mDurationPerFrame; 412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jmethodID getSystemIcon; 422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jmethodID load; 432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} gPointerIconClassInfo; 442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// --- Global Functions --- 472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 482352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownjobject android_view_PointerIcon_getSystemIcon(JNIEnv* env, jobject contextObj, int32_t style) { 492352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject pointerIconObj = env->CallStaticObjectMethod(gPointerIconClassInfo.clazz, 502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown gPointerIconClassInfo.getSystemIcon, contextObj, style); 512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (env->ExceptionCheck()) { 528564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("An exception occurred while getting a pointer icon with style %d.", style); 532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOGW_EX(env); 542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->ExceptionClear(); 552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return NULL; 562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 572352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return pointerIconObj; 582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatus_t android_view_PointerIcon_load(JNIEnv* env, jobject pointerIconObj, jobject contextObj, 612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown PointerIcon* outPointerIcon) { 622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->reset(); 632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (!pointerIconObj) { 652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return OK; 662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 68d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai ScopedLocalRef<jobject> loadedPointerIconObj(env, env->CallObjectMethod(pointerIconObj, 69d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai gPointerIconClassInfo.load, contextObj)); 70d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai if (env->ExceptionCheck() || !loadedPointerIconObj.get()) { 718564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("An exception occurred while loading a pointer icon."); 722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown LOGW_EX(env); 732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->ExceptionClear(); 742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return UNKNOWN_ERROR; 752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 76d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai return android_view_PointerIcon_getLoadedIcon(env, loadedPointerIconObj.get(), outPointerIcon); 77d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai} 782352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 79d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukaistatus_t android_view_PointerIcon_getLoadedIcon(JNIEnv* env, jobject pointerIconObj, 80d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai PointerIcon* outPointerIcon) { 8135068079c833b5ea508c378701b159b99ee39279Michael Wright if (!pointerIconObj) { 8235068079c833b5ea508c378701b159b99ee39279Michael Wright return BAD_VALUE; 8335068079c833b5ea508c378701b159b99ee39279Michael Wright } 84f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright outPointerIcon->style = env->GetIntField(pointerIconObj, gPointerIconClassInfo.mType); 85d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai outPointerIcon->hotSpotX = env->GetFloatField(pointerIconObj, gPointerIconClassInfo.mHotSpotX); 86d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai outPointerIcon->hotSpotY = env->GetFloatField(pointerIconObj, gPointerIconClassInfo.mHotSpotY); 87d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai 88d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai ScopedLocalRef<jobject> bitmapObj( 89d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai env, env->GetObjectField(pointerIconObj, gPointerIconClassInfo.mBitmap)); 90d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai if (bitmapObj.get()) { 91d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai GraphicsJNI::getSkBitmap(env, bitmapObj.get(), &(outPointerIcon->bitmap)); 922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 94808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai ScopedLocalRef<jobjectArray> bitmapFramesObj(env, reinterpret_cast<jobjectArray>( 95d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai env->GetObjectField(pointerIconObj, gPointerIconClassInfo.mBitmapFrames))); 96808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai if (bitmapFramesObj.get()) { 97808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai outPointerIcon->durationPerFrame = env->GetIntField( 98d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai pointerIconObj, gPointerIconClassInfo.mDurationPerFrame); 99808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai jsize size = env->GetArrayLength(bitmapFramesObj.get()); 100808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai outPointerIcon->bitmapFrames.resize(size); 101808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai for (jsize i = 0; i < size; ++i) { 102808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai ScopedLocalRef<jobject> bitmapObj(env, env->GetObjectArrayElement(bitmapFramesObj.get(), i)); 103808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai GraphicsJNI::getSkBitmap(env, bitmapObj.get(), &(outPointerIcon->bitmapFrames[i])); 104808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai } 105808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai } 106808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai 1072352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return OK; 1082352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 1092352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatus_t android_view_PointerIcon_loadSystemIcon(JNIEnv* env, jobject contextObj, 1112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown int32_t style, PointerIcon* outPointerIcon) { 1122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown jobject pointerIconObj = android_view_PointerIcon_getSystemIcon(env, contextObj, style); 1132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown if (!pointerIconObj) { 1142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown outPointerIcon->reset(); 1152352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return UNKNOWN_ERROR; 1162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown } 1172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown status_t status = android_view_PointerIcon_load(env, pointerIconObj, 1192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown contextObj, outPointerIcon); 1202352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown env->DeleteLocalRef(pointerIconObj); 1212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return status; 1222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 1232352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1242352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown// --- JNI Registration --- 1262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownint register_android_view_PointerIcon(JNIEnv* env) { 128987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe jclass clazz = FindClassOrDie(env, "android/view/PointerIcon"); 129987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gPointerIconClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); 1302352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 131987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gPointerIconClassInfo.mBitmap = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz, 1322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mBitmap", "Landroid/graphics/Bitmap;"); 1332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 134f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright gPointerIconClassInfo.mType = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz, 135f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright "mType", "I"); 1362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 137987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gPointerIconClassInfo.mHotSpotX = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz, 1382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mHotSpotX", "F"); 1392352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 140987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gPointerIconClassInfo.mHotSpotY = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz, 1412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "mHotSpotY", "F"); 1422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 143808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai gPointerIconClassInfo.mBitmapFrames = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz, 144808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai "mBitmapFrames", "[Landroid/graphics/Bitmap;"); 145808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai 146808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai gPointerIconClassInfo.mDurationPerFrame = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz, 147808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai "mDurationPerFrame", "I"); 148808196f139e93395f1f331f6c7e92ddd66c05979Jun Mukai 149987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gPointerIconClassInfo.getSystemIcon = GetStaticMethodIDOrDie(env, gPointerIconClassInfo.clazz, 1502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "getSystemIcon", "(Landroid/content/Context;I)Landroid/view/PointerIcon;"); 1512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 152987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gPointerIconClassInfo.load = GetMethodIDOrDie(env, gPointerIconClassInfo.clazz, 1532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown "load", "(Landroid/content/Context;)Landroid/view/PointerIcon;"); 1542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown return 0; 1562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} 1572352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 1582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown} // namespace android 159