1/*
2 * Copyright (C) 2010 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#include <stdio.h>
18#include <assert.h>
19
20#include "jni.h"
21#include "core_jni_helpers.h"
22#include <utils/misc.h>
23
24// ----------------------------------------------------------------------------
25
26namespace android {
27
28// ----------------------------------------------------------------------------
29
30const char* const kClassPathName = "android/animation/PropertyValuesHolder";
31
32static jlong android_animation_PropertyValuesHolder_getIntMethod(
33        JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName)
34{
35    const char *nativeString = env->GetStringUTFChars(methodName, 0);
36    jmethodID mid = env->GetMethodID(targetClass, nativeString, "(I)V");
37    env->ReleaseStringUTFChars(methodName, nativeString);
38    return reinterpret_cast<jlong>(mid);
39}
40
41static jlong android_animation_PropertyValuesHolder_getFloatMethod(
42        JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName)
43{
44    const char *nativeString = env->GetStringUTFChars(methodName, 0);
45    jmethodID mid = env->GetMethodID(targetClass, nativeString, "(F)V");
46    env->ReleaseStringUTFChars(methodName, nativeString);
47    return reinterpret_cast<jlong>(mid);
48}
49
50static jlong getMultiparameterMethod(JNIEnv* env, jclass targetClass, jstring methodName,
51    jint parameterCount, char parameterType)
52{
53    const char *nativeString = env->GetStringUTFChars(methodName, 0);
54    char *signature = new char[parameterCount + 4];
55    signature[0] = '(';
56    memset(&(signature[1]), parameterType, parameterCount);
57    strcpy(&(signature[parameterCount + 1]), ")V");
58    jmethodID mid = env->GetMethodID(targetClass, nativeString, signature);
59    delete[] signature;
60    env->ReleaseStringUTFChars(methodName, nativeString);
61    return reinterpret_cast<jlong>(mid);
62}
63
64static jlong android_animation_PropertyValuesHolder_getMultipleFloatMethod(
65        JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount)
66{
67    return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'F');
68}
69
70static jlong android_animation_PropertyValuesHolder_getMultipleIntMethod(
71        JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount)
72{
73    return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'I');
74}
75
76static void android_animation_PropertyValuesHolder_callIntMethod(
77        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jint arg)
78{
79    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg);
80}
81
82static void android_animation_PropertyValuesHolder_callFloatMethod(
83        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jfloat arg)
84{
85    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg);
86}
87
88static void android_animation_PropertyValuesHolder_callTwoFloatMethod(
89        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, float arg1, float arg2)
90{
91    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2);
92}
93
94static void android_animation_PropertyValuesHolder_callFourFloatMethod(
95        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, float arg1, float arg2,
96        float arg3, float arg4)
97{
98    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2, arg3, arg4);
99}
100
101static void android_animation_PropertyValuesHolder_callMultipleFloatMethod(
102        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jfloatArray arg)
103{
104    jsize parameterCount = env->GetArrayLength(arg);
105    jfloat *floatValues = env->GetFloatArrayElements(arg, NULL);
106    jvalue* values = new jvalue[parameterCount];
107    for (int i = 0; i < parameterCount; i++) {
108        values[i].f = floatValues[i];
109    }
110    env->CallVoidMethodA(target, reinterpret_cast<jmethodID>(methodID), values);
111    delete[] values;
112    env->ReleaseFloatArrayElements(arg, floatValues, JNI_ABORT);
113}
114
115static void android_animation_PropertyValuesHolder_callTwoIntMethod(
116        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, int arg1, int arg2)
117{
118    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2);
119}
120
121static void android_animation_PropertyValuesHolder_callFourIntMethod(
122        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, int arg1, int arg2,
123        int arg3, int arg4)
124{
125    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2, arg3, arg4);
126}
127
128static void android_animation_PropertyValuesHolder_callMultipleIntMethod(
129        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jintArray arg)
130{
131    jsize parameterCount = env->GetArrayLength(arg);
132    jint *intValues = env->GetIntArrayElements(arg, NULL);
133    jvalue* values = new jvalue[parameterCount];
134    for (int i = 0; i < parameterCount; i++) {
135        values[i].i = intValues[i];
136    }
137    env->CallVoidMethodA(target, reinterpret_cast<jmethodID>(methodID), values);
138    delete[] values;
139    env->ReleaseIntArrayElements(arg, intValues, JNI_ABORT);
140}
141
142static const JNINativeMethod gMethods[] = {
143    {   "nGetIntMethod", "(Ljava/lang/Class;Ljava/lang/String;)J",
144            (void*)android_animation_PropertyValuesHolder_getIntMethod },
145    {   "nGetFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;)J",
146            (void*)android_animation_PropertyValuesHolder_getFloatMethod },
147    {   "nGetMultipleFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;I)J",
148            (void*)android_animation_PropertyValuesHolder_getMultipleFloatMethod },
149    {   "nGetMultipleIntMethod", "(Ljava/lang/Class;Ljava/lang/String;I)J",
150            (void*)android_animation_PropertyValuesHolder_getMultipleIntMethod },
151    {   "nCallIntMethod", "(Ljava/lang/Object;JI)V",
152            (void*)android_animation_PropertyValuesHolder_callIntMethod },
153    {   "nCallFloatMethod", "(Ljava/lang/Object;JF)V",
154            (void*)android_animation_PropertyValuesHolder_callFloatMethod },
155    {   "nCallTwoFloatMethod", "(Ljava/lang/Object;JFF)V",
156            (void*)android_animation_PropertyValuesHolder_callTwoFloatMethod },
157    {   "nCallFourFloatMethod", "(Ljava/lang/Object;JFFFF)V",
158            (void*)android_animation_PropertyValuesHolder_callFourFloatMethod },
159    {   "nCallMultipleFloatMethod", "(Ljava/lang/Object;J[F)V",
160            (void*)android_animation_PropertyValuesHolder_callMultipleFloatMethod },
161    {   "nCallTwoIntMethod", "(Ljava/lang/Object;JII)V",
162            (void*)android_animation_PropertyValuesHolder_callTwoIntMethod },
163    {   "nCallFourIntMethod", "(Ljava/lang/Object;JIIII)V",
164            (void*)android_animation_PropertyValuesHolder_callFourIntMethod },
165    {   "nCallMultipleIntMethod", "(Ljava/lang/Object;J[I)V",
166            (void*)android_animation_PropertyValuesHolder_callMultipleIntMethod },
167};
168
169int register_android_animation_PropertyValuesHolder(JNIEnv* env)
170{
171    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
172}
173
174};
175