12ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown/*
22ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown * Copyright (C) 2011 The Android Open Source Project
32ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown *
42ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
52ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown * you may not use this file except in compliance with the License.
62ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown * You may obtain a copy of the License at
72ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown *
82ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
92ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown *
102ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown * Unless required by applicable law or agreed to in writing, software
112ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
122ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown * See the License for the specific language governing permissions and
142ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown * limitations under the License.
152ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown */
162ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
172ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown#define LOG_TAG "VelocityTracker-JNI"
182ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
192ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown#include "JNIHelp.h"
202ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
212ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown#include <android_runtime/AndroidRuntime.h>
222ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown#include <utils/Log.h>
23b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian#include <androidfw/Input.h>
248a90e6e3174083f274538567d851f98478fc83e9Jeff Brown#include <androidfw/VelocityTracker.h>
252ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown#include "android_view_MotionEvent.h"
262ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
279eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown#include <ScopedUtfChars.h>
289eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown
292ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
302ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownnamespace android {
312ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
322ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown// Special constant to request the velocity of the active pointer.
332ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic const int ACTIVE_POINTER_ID = -1;
342ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
35b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brownstatic struct {
36b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    jfieldID xCoeff;
37b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    jfieldID yCoeff;
38b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    jfieldID degree;
39b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    jfieldID confidence;
40b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown} gEstimatorClassInfo;
41b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
42b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
432ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown// --- VelocityTrackerState ---
442ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
452ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownclass VelocityTrackerState {
462ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownpublic:
479eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown    VelocityTrackerState(const char* strategy);
482ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
492ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    void clear();
502ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    void addMovement(const MotionEvent* event);
512ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    void computeCurrentVelocity(int32_t units, float maxVelocity);
522ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    void getVelocity(int32_t id, float* outVx, float* outVy);
5385bd0d62830a098c1bdc720dfdcf4fe1b18b657cJeff Brown    bool getEstimator(int32_t id, VelocityTracker::Estimator* outEstimator);
542ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
552ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownprivate:
562ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    struct Velocity {
572ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        float vx, vy;
582ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    };
592ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
602ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTracker mVelocityTracker;
612ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    int32_t mActivePointerId;
622ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    BitSet32 mCalculatedIdBits;
632ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    Velocity mCalculatedVelocity[MAX_POINTERS];
642ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown};
652ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
669eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff BrownVelocityTrackerState::VelocityTrackerState(const char* strategy) :
679eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown        mVelocityTracker(strategy), mActivePointerId(-1) {
682ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
692ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
702ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTrackerState::clear() {
712ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mVelocityTracker.clear();
722ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mActivePointerId = -1;
732ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mCalculatedIdBits.clear();
742ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
752ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
762ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTrackerState::addMovement(const MotionEvent* event) {
772ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mVelocityTracker.addMovement(event);
782ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
792ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
802ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTrackerState::computeCurrentVelocity(int32_t units, float maxVelocity) {
812ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    BitSet32 idBits(mVelocityTracker.getCurrentPointerIdBits());
822ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mCalculatedIdBits = idBits;
832ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
842ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    for (uint32_t index = 0; !idBits.isEmpty(); index++) {
85be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
862ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
872ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        float vx, vy;
882ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        mVelocityTracker.getVelocity(id, &vx, &vy);
892ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
902ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vx = vx * units / 1000;
912ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vy = vy * units / 1000;
922ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
932ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        if (vx > maxVelocity) {
942ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            vx = maxVelocity;
952ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        } else if (vx < -maxVelocity) {
962ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            vx = -maxVelocity;
972ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        }
982ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        if (vy > maxVelocity) {
992ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            vy = maxVelocity;
1002ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        } else if (vy < -maxVelocity) {
1012ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            vy = -maxVelocity;
1022ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        }
1032ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1042ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        Velocity& velocity = mCalculatedVelocity[index];
1052ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        velocity.vx = vx;
1062ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        velocity.vy = vy;
1072ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1082ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1092ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1102ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTrackerState::getVelocity(int32_t id, float* outVx, float* outVy) {
1112ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (id == ACTIVE_POINTER_ID) {
1122ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        id = mVelocityTracker.getActivePointerId();
1132ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1142ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1152ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    float vx, vy;
1162ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (id >= 0 && id <= MAX_POINTER_ID && mCalculatedIdBits.hasBit(id)) {
1172ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        uint32_t index = mCalculatedIdBits.getIndexOfBit(id);
1182ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        const Velocity& velocity = mCalculatedVelocity[index];
1192ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vx = velocity.vx;
1202ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vy = velocity.vy;
1212ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    } else {
1222ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vx = 0;
1232ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vy = 0;
1242ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1252ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1262ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (outVx) {
1272ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        *outVx = vx;
1282ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1292ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (outVy) {
1302ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        *outVy = vy;
1312ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1322ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1332ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
13485bd0d62830a098c1bdc720dfdcf4fe1b18b657cJeff Brownbool VelocityTrackerState::getEstimator(int32_t id, VelocityTracker::Estimator* outEstimator) {
13585bd0d62830a098c1bdc720dfdcf4fe1b18b657cJeff Brown    return mVelocityTracker.getEstimator(id, outEstimator);
136b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown}
137b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
1382ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1392ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown// --- JNI Methods ---
1402ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1419eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brownstatic jint android_view_VelocityTracker_nativeInitialize(JNIEnv* env, jclass clazz,
1429eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown        jstring strategyStr) {
1439eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown    if (strategyStr) {
1449eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown        ScopedUtfChars strategy(env, strategyStr);
1459eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown        return reinterpret_cast<jint>(new VelocityTrackerState(strategy.c_str()));
1469eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown    }
1479eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown    return reinterpret_cast<jint>(new VelocityTrackerState(NULL));
1482ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1492ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1502ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic void android_view_VelocityTracker_nativeDispose(JNIEnv* env, jclass clazz, jint ptr) {
1512ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1522ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    delete state;
1532ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1542ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1552ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic void android_view_VelocityTracker_nativeClear(JNIEnv* env, jclass clazz, jint ptr) {
1562ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1572ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->clear();
1582ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1592ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1602ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic void android_view_VelocityTracker_nativeAddMovement(JNIEnv* env, jclass clazz, jint ptr,
1612ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        jobject eventObj) {
1622ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    const MotionEvent* event = android_view_MotionEvent_getNativePtr(env, eventObj);
1632ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (!event) {
1648564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("nativeAddMovement failed because MotionEvent was finalized.");
1652ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        return;
1662ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1672ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1682ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1692ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->addMovement(event);
1702ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1712ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1722ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic void android_view_VelocityTracker_nativeComputeCurrentVelocity(JNIEnv* env, jclass clazz,
1732ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        jint ptr, jint units, jfloat maxVelocity) {
1742ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1752ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->computeCurrentVelocity(units, maxVelocity);
1762ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1772ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1782ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic jfloat android_view_VelocityTracker_nativeGetXVelocity(JNIEnv* env, jclass clazz,
1792ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        jint ptr, jint id) {
1802ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1812ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    float vx;
1822ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->getVelocity(id, &vx, NULL);
1832ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    return vx;
1842ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1852ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1862ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic jfloat android_view_VelocityTracker_nativeGetYVelocity(JNIEnv* env, jclass clazz,
1872ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        jint ptr, jint id) {
1882ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1892ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    float vy;
1902ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->getVelocity(id, NULL, &vy);
1912ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    return vy;
1922ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1932ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
194b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brownstatic jboolean android_view_VelocityTracker_nativeGetEstimator(JNIEnv* env, jclass clazz,
19585bd0d62830a098c1bdc720dfdcf4fe1b18b657cJeff Brown        jint ptr, jint id, jobject outEstimatorObj) {
196b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
197b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    VelocityTracker::Estimator estimator;
19885bd0d62830a098c1bdc720dfdcf4fe1b18b657cJeff Brown    bool result = state->getEstimator(id, &estimator);
199b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
200b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    jfloatArray xCoeffObj = jfloatArray(env->GetObjectField(outEstimatorObj,
201b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown            gEstimatorClassInfo.xCoeff));
202b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    jfloatArray yCoeffObj = jfloatArray(env->GetObjectField(outEstimatorObj,
203b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown            gEstimatorClassInfo.yCoeff));
204b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
205b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    env->SetFloatArrayRegion(xCoeffObj, 0, VelocityTracker::Estimator::MAX_DEGREE + 1,
206b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown            estimator.xCoeff);
207b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    env->SetFloatArrayRegion(yCoeffObj, 0, VelocityTracker::Estimator::MAX_DEGREE + 1,
208b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown            estimator.yCoeff);
209b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    env->SetIntField(outEstimatorObj, gEstimatorClassInfo.degree, estimator.degree);
210b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    env->SetFloatField(outEstimatorObj, gEstimatorClassInfo.confidence, estimator.confidence);
211b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    return result;
212b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown}
213b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
2142ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
2152ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown// --- JNI Registration ---
2162ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
2172ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic JNINativeMethod gVelocityTrackerMethods[] = {
2182ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    /* name, signature, funcPtr */
2192ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeInitialize",
2209eb7d86181729c3eb769d71123c4ce9ffc868f08Jeff Brown            "(Ljava/lang/String;)I",
2212ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeInitialize },
2222ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeDispose",
2232ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(I)V",
2242ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeDispose },
2252ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeClear",
2262ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(I)V",
2272ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeClear },
2282ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeAddMovement",
2292ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(ILandroid/view/MotionEvent;)V",
2302ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeAddMovement },
2312ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeComputeCurrentVelocity",
2322ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(IIF)V",
2332ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeComputeCurrentVelocity },
2342ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeGetXVelocity",
2352ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(II)F",
2362ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeGetXVelocity },
2372ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeGetYVelocity",
2382ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(II)F",
2392ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeGetYVelocity },
240b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    { "nativeGetEstimator",
24185bd0d62830a098c1bdc720dfdcf4fe1b18b657cJeff Brown            "(IILandroid/view/VelocityTracker$Estimator;)Z",
242b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown            (void*)android_view_VelocityTracker_nativeGetEstimator },
2432ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown};
2442ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
245b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown#define FIND_CLASS(var, className) \
246b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown        var = env->FindClass(className); \
247b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown        LOG_FATAL_IF(! var, "Unable to find class " className);
248b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
249b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
250b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
251b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
252b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
2532ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownint register_android_view_VelocityTracker(JNIEnv* env) {
2542ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    int res = jniRegisterNativeMethods(env, "android/view/VelocityTracker",
2552ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            gVelocityTrackerMethods, NELEM(gVelocityTrackerMethods));
2562ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
257b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
258b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    jclass clazz;
259b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    FIND_CLASS(clazz, "android/view/VelocityTracker$Estimator");
260b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown
261b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    GET_FIELD_ID(gEstimatorClassInfo.xCoeff, clazz,
262b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown            "xCoeff", "[F");
263b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    GET_FIELD_ID(gEstimatorClassInfo.yCoeff, clazz,
264b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown            "yCoeff", "[F");
265b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    GET_FIELD_ID(gEstimatorClassInfo.degree, clazz,
266b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown            "degree", "I");
267b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown    GET_FIELD_ID(gEstimatorClassInfo.confidence, clazz,
268b59ab9f41faafb358afb4f951de96f34a656e0b4Jeff Brown            "confidence", "F");
2692ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    return 0;
2702ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
2712ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
2722ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown} // namespace android
273