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