android_view_RenderNodeAnimator.cpp revision 119907cd2575c56b1ebf66348b52e67aaf6a88d8
1e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck/*
2e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Copyright (C) 2013 The Android Open Source Project
3e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck *
4e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
5e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * you may not use this file except in compliance with the License.
6e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * You may obtain a copy of the License at
7e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck *
8e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
9e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck *
10e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Unless required by applicable law or agreed to in writing, software
11e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
12e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * See the License for the specific language governing permissions and
14e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * limitations under the License.
15e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck */
16e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
17e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#define LOG_TAG "OpenGLRenderer"
18e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
19e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "jni.h"
20e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "GraphicsJNI.h"
21e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <nativehelper/JNIHelp.h>
22e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <android_runtime/AndroidRuntime.h>
23e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
24e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <Animator.h>
25e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <Interpolator.h>
26e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <RenderProperties.h>
27e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
28e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Recknamespace android {
29e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
30e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckusing namespace uirenderer;
31e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
32e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic struct {
33e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    jclass clazz;
34e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
35e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    jmethodID callOnFinished;
36e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} gRenderNodeAnimatorClassInfo;
37e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
38496b8770c19c573299e4be525e877acc977a2dadJohn Reck#ifdef USE_OPENGL_RENDERER
39496b8770c19c573299e4be525e877acc977a2dadJohn Reck
40e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic JNIEnv* getEnv(JavaVM* vm) {
41e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    JNIEnv* env;
42e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
43e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        return 0;
44e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    }
45e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    return env;
46e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck}
47e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
4852244fff29042926e21fa897ef5ab11148e35299John Reckclass AnimationListenerBridge : public AnimationListener {
4952244fff29042926e21fa897ef5ab11148e35299John Reckpublic:
5052244fff29042926e21fa897ef5ab11148e35299John Reck    // This holds a strong reference to a Java WeakReference<T> object. This avoids
5152244fff29042926e21fa897ef5ab11148e35299John Reck    // cyclic-references-of-doom. If you think "I know, just use NewWeakGlobalRef!"
5252244fff29042926e21fa897ef5ab11148e35299John Reck    // then you end up with basically a PhantomReference, which is totally not
5352244fff29042926e21fa897ef5ab11148e35299John Reck    // what we want.
54119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    AnimationListenerBridge(JNIEnv* env, jobject finishListener) {
55119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mFinishListener = env->NewGlobalRef(finishListener);
5652244fff29042926e21fa897ef5ab11148e35299John Reck        env->GetJavaVM(&mJvm);
5752244fff29042926e21fa897ef5ab11148e35299John Reck    }
58e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
5952244fff29042926e21fa897ef5ab11148e35299John Reck    virtual ~AnimationListenerBridge() {
60119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        if (mFinishListener) {
61119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            onAnimationFinished(NULL);
62119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        }
6352244fff29042926e21fa897ef5ab11148e35299John Reck    }
64e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
65ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    virtual void onAnimationFinished(BaseRenderNodeAnimator*) {
66119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        LOG_ALWAYS_FATAL_IF(!mFinishListener, "Finished listener twice?");
6752244fff29042926e21fa897ef5ab11148e35299John Reck        JNIEnv* env = getEnv(mJvm);
6852244fff29042926e21fa897ef5ab11148e35299John Reck        env->CallStaticVoidMethod(
6952244fff29042926e21fa897ef5ab11148e35299John Reck                gRenderNodeAnimatorClassInfo.clazz,
7052244fff29042926e21fa897ef5ab11148e35299John Reck                gRenderNodeAnimatorClassInfo.callOnFinished,
71119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                mFinishListener);
72119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        releaseJavaObject();
7352244fff29042926e21fa897ef5ab11148e35299John Reck    }
74e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
7552244fff29042926e21fa897ef5ab11148e35299John Reckprivate:
76119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    void releaseJavaObject() {
77119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        JNIEnv* env = getEnv(mJvm);
78119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        env->DeleteGlobalRef(mFinishListener);
79119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        mFinishListener = NULL;
80119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
81119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
8252244fff29042926e21fa897ef5ab11148e35299John Reck    JavaVM* mJvm;
83119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    jobject mFinishListener;
8452244fff29042926e21fa897ef5ab11148e35299John Reck};
8552244fff29042926e21fa897ef5ab11148e35299John Reck
8652244fff29042926e21fa897ef5ab11148e35299John Reckstatic inline RenderPropertyAnimator::RenderProperty toRenderProperty(jint property) {
8752244fff29042926e21fa897ef5ab11148e35299John Reck    LOG_ALWAYS_FATAL_IF(property < 0 || property > RenderPropertyAnimator::ALPHA,
88e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck            "Invalid property %d", property);
8952244fff29042926e21fa897ef5ab11148e35299John Reck    return static_cast<RenderPropertyAnimator::RenderProperty>(property);
9052244fff29042926e21fa897ef5ab11148e35299John Reck}
9152244fff29042926e21fa897ef5ab11148e35299John Reck
9252244fff29042926e21fa897ef5ab11148e35299John Reckstatic inline CanvasPropertyPaintAnimator::PaintField toPaintField(jint field) {
9352244fff29042926e21fa897ef5ab11148e35299John Reck    LOG_ALWAYS_FATAL_IF(field < 0
9452244fff29042926e21fa897ef5ab11148e35299John Reck            || field > CanvasPropertyPaintAnimator::ALPHA,
9552244fff29042926e21fa897ef5ab11148e35299John Reck            "Invalid paint field %d", field);
9652244fff29042926e21fa897ef5ab11148e35299John Reck    return static_cast<CanvasPropertyPaintAnimator::PaintField>(field);
9752244fff29042926e21fa897ef5ab11148e35299John Reck}
9852244fff29042926e21fa897ef5ab11148e35299John Reck
99119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckstatic jlong createAnimator(JNIEnv* env, jobject clazz,
100ff941dcd815021bb20d6504eb486acb1e50592c3John Reck        jint propertyRaw, jfloat finalValue) {
10152244fff29042926e21fa897ef5ab11148e35299John Reck    RenderPropertyAnimator::RenderProperty property = toRenderProperty(propertyRaw);
102ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    BaseRenderNodeAnimator* animator = new RenderPropertyAnimator(property, finalValue);
10352244fff29042926e21fa897ef5ab11148e35299John Reck    return reinterpret_cast<jlong>( animator );
10452244fff29042926e21fa897ef5ab11148e35299John Reck}
10552244fff29042926e21fa897ef5ab11148e35299John Reck
10652244fff29042926e21fa897ef5ab11148e35299John Reckstatic jlong createCanvasPropertyFloatAnimator(JNIEnv* env, jobject clazz,
107119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        jlong canvasPropertyPtr, jfloat finalValue) {
10852244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPrimitive* canvasProperty = reinterpret_cast<CanvasPropertyPrimitive*>(canvasPropertyPtr);
109ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    BaseRenderNodeAnimator* animator = new CanvasPropertyPrimitiveAnimator(canvasProperty, finalValue);
11052244fff29042926e21fa897ef5ab11148e35299John Reck    return reinterpret_cast<jlong>( animator );
11152244fff29042926e21fa897ef5ab11148e35299John Reck}
112e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
11352244fff29042926e21fa897ef5ab11148e35299John Reckstatic jlong createCanvasPropertyPaintAnimator(JNIEnv* env, jobject clazz,
114119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        jlong canvasPropertyPtr, jint paintFieldRaw,
115ff941dcd815021bb20d6504eb486acb1e50592c3John Reck        jfloat finalValue) {
11652244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPaint* canvasProperty = reinterpret_cast<CanvasPropertyPaint*>(canvasPropertyPtr);
11752244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasPropertyPaintAnimator::PaintField paintField = toPaintField(paintFieldRaw);
118ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    BaseRenderNodeAnimator* animator = new CanvasPropertyPaintAnimator(
119ff941dcd815021bb20d6504eb486acb1e50592c3John Reck            canvasProperty, paintField, finalValue);
120e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    return reinterpret_cast<jlong>( animator );
121e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck}
122e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
123119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckstatic jlong createRevealAnimator(JNIEnv* env, jobject clazz,
124af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik        jint centerX, jint centerY, jfloat startRadius, jfloat endRadius) {
125af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik    BaseRenderNodeAnimator* animator = new RevealAnimator(centerX, centerY, startRadius, endRadius);
126d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck    return reinterpret_cast<jlong>( animator );
127d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck}
128d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck
129c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reckstatic void setStartValue(JNIEnv* env, jobject clazz, jlong animatorPtr, jfloat startValue) {
130c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
131c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck    animator->setStartValue(startValue);
132c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck}
133c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck
134ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverettestatic void setDuration(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong duration) {
135e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    LOG_ALWAYS_FATAL_IF(duration < 0, "Duration cannot be negative");
136ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
137e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    animator->setDuration(duration);
138e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck}
139e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
140ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverettestatic jlong getDuration(JNIEnv* env, jobject clazz, jlong animatorPtr) {
141ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
142ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    return static_cast<jlong>(animator->duration());
143ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette}
144ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette
145ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverettestatic void setStartDelay(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong startDelay) {
146ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    LOG_ALWAYS_FATAL_IF(startDelay < 0, "Start delay cannot be negative");
147ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
148ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    animator->setStartDelay(startDelay);
149ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette}
150ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette
151ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverettestatic jlong getStartDelay(JNIEnv* env, jobject clazz, jlong animatorPtr) {
152ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
153ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    return static_cast<jlong>(animator->startDelay());
154315c329544d7c593d1072b071cbb92d9afe74021John Reck}
155315c329544d7c593d1072b071cbb92d9afe74021John Reck
156315c329544d7c593d1072b071cbb92d9afe74021John Reckstatic void setInterpolator(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong interpolatorPtr) {
157ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
158315c329544d7c593d1072b071cbb92d9afe74021John Reck    Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr);
159315c329544d7c593d1072b071cbb92d9afe74021John Reck    animator->setInterpolator(interpolator);
160315c329544d7c593d1072b071cbb92d9afe74021John Reck}
161315c329544d7c593d1072b071cbb92d9afe74021John Reck
162119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reckstatic void start(JNIEnv* env, jobject clazz, jlong animatorPtr, jobject finishListener) {
1638d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
164119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    if (finishListener) {
165119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        animator->setListener(new AnimationListenerBridge(env, finishListener));
166119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
1678d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck    animator->start();
1688d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck}
1698d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck
170d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reckstatic void end(JNIEnv* env, jobject clazz, jlong animatorPtr) {
17168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck    BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
172d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck    animator->end();
17368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck}
17468bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck
175496b8770c19c573299e4be525e877acc977a2dadJohn Reck#endif
176496b8770c19c573299e4be525e877acc977a2dadJohn Reck
177e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// ----------------------------------------------------------------------------
178e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// JNI Glue
179e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck// ----------------------------------------------------------------------------
180e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
181e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckconst char* const kClassPathName = "android/view/RenderNodeAnimator";
182e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
183e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckstatic JNINativeMethod gMethods[] = {
184496b8770c19c573299e4be525e877acc977a2dadJohn Reck#ifdef USE_OPENGL_RENDERER
185119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    { "nCreateAnimator", "(IF)J", (void*) createAnimator },
186119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    { "nCreateCanvasPropertyFloatAnimator", "(JF)J", (void*) createCanvasPropertyFloatAnimator },
187119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    { "nCreateCanvasPropertyPaintAnimator", "(JIF)J", (void*) createCanvasPropertyPaintAnimator },
188119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    { "nCreateRevealAnimator", "(IIFF)J", (void*) createRevealAnimator },
189c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck    { "nSetStartValue", "(JF)V", (void*) setStartValue },
190ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    { "nSetDuration", "(JJ)V", (void*) setDuration },
191ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    { "nGetDuration", "(J)J", (void*) getDuration },
192ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    { "nSetStartDelay", "(JJ)V", (void*) setStartDelay },
193315c329544d7c593d1072b071cbb92d9afe74021John Reck    { "nSetInterpolator", "(JJ)V", (void*) setInterpolator },
194119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    { "nStart", "(JLandroid/view/RenderNodeAnimator;)V", (void*) start },
195d3de42cae84fadfa1befd082a2cf1bf72f9ad82aJohn Reck    { "nEnd", "(J)V", (void*) end },
196496b8770c19c573299e4be525e877acc977a2dadJohn Reck#endif
197e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck};
198e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
199e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#define FIND_CLASS(var, className) \
200e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        var = env->FindClass(className); \
201e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        LOG_FATAL_IF(! var, "Unable to find class " className);
202e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
203e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
204e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
205e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        LOG_FATAL_IF(! var, "Unable to find method " methodName);
206e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
207e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckint register_android_view_RenderNodeAnimator(JNIEnv* env) {
208e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    FIND_CLASS(gRenderNodeAnimatorClassInfo.clazz, kClassPathName);
209e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    gRenderNodeAnimatorClassInfo.clazz = jclass(env->NewGlobalRef(gRenderNodeAnimatorClassInfo.clazz));
210e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
211e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    GET_STATIC_METHOD_ID(gRenderNodeAnimatorClassInfo.callOnFinished, gRenderNodeAnimatorClassInfo.clazz,
212119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            "callOnFinished", "(Landroid/view/RenderNodeAnimator;)V");
213e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
214e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
215e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck}
216e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
217e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
218e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck} // namespace android
219