android_view_VelocityTracker.cpp revision be1aa8250cee7819c49741e819e81659d1d03823
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>
232ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown#include <ui/Input.h>
242ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown#include "android_view_MotionEvent.h"
252ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
262ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
272ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownnamespace android {
282ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
292ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown// Special constant to request the velocity of the active pointer.
302ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic const int ACTIVE_POINTER_ID = -1;
312ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
322ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown// --- VelocityTrackerState ---
332ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
342ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownclass VelocityTrackerState {
352ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownpublic:
362ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState();
372ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
382ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    void clear();
392ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    void addMovement(const MotionEvent* event);
402ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    void computeCurrentVelocity(int32_t units, float maxVelocity);
412ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    void getVelocity(int32_t id, float* outVx, float* outVy);
422ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
432ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownprivate:
442ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    struct Velocity {
452ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        float vx, vy;
462ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    };
472ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
482ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTracker mVelocityTracker;
492ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    int32_t mActivePointerId;
502ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    BitSet32 mCalculatedIdBits;
512ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    Velocity mCalculatedVelocity[MAX_POINTERS];
522ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown};
532ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
542ed2462aa29c564f5231f317c27b3188da875e52Jeff BrownVelocityTrackerState::VelocityTrackerState() : mActivePointerId(-1) {
552ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
562ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
572ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTrackerState::clear() {
582ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mVelocityTracker.clear();
592ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mActivePointerId = -1;
602ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mCalculatedIdBits.clear();
612ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
622ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
632ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTrackerState::addMovement(const MotionEvent* event) {
642ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mVelocityTracker.addMovement(event);
652ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
662ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
672ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTrackerState::computeCurrentVelocity(int32_t units, float maxVelocity) {
682ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    BitSet32 idBits(mVelocityTracker.getCurrentPointerIdBits());
692ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    mCalculatedIdBits = idBits;
702ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
712ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    for (uint32_t index = 0; !idBits.isEmpty(); index++) {
72be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
732ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
742ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        float vx, vy;
752ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        mVelocityTracker.getVelocity(id, &vx, &vy);
762ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
772ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vx = vx * units / 1000;
782ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vy = vy * units / 1000;
792ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
802ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        if (vx > maxVelocity) {
812ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            vx = maxVelocity;
822ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        } else if (vx < -maxVelocity) {
832ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            vx = -maxVelocity;
842ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        }
852ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        if (vy > maxVelocity) {
862ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            vy = maxVelocity;
872ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        } else if (vy < -maxVelocity) {
882ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            vy = -maxVelocity;
892ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        }
902ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
912ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        Velocity& velocity = mCalculatedVelocity[index];
922ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        velocity.vx = vx;
932ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        velocity.vy = vy;
942ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
952ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
962ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
972ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTrackerState::getVelocity(int32_t id, float* outVx, float* outVy) {
982ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (id == ACTIVE_POINTER_ID) {
992ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        id = mVelocityTracker.getActivePointerId();
1002ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1012ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1022ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    float vx, vy;
1032ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (id >= 0 && id <= MAX_POINTER_ID && mCalculatedIdBits.hasBit(id)) {
1042ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        uint32_t index = mCalculatedIdBits.getIndexOfBit(id);
1052ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        const Velocity& velocity = mCalculatedVelocity[index];
1062ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vx = velocity.vx;
1072ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vy = velocity.vy;
1082ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    } else {
1092ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vx = 0;
1102ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        vy = 0;
1112ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1122ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1132ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (outVx) {
1142ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        *outVx = vx;
1152ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1162ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (outVy) {
1172ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        *outVy = vy;
1182ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1192ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1202ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1212ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1222ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown// --- JNI Methods ---
1232ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1242ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic jint android_view_VelocityTracker_nativeInitialize(JNIEnv* env, jclass clazz) {
1252ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    return reinterpret_cast<jint>(new VelocityTrackerState());
1262ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1272ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1282ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic void android_view_VelocityTracker_nativeDispose(JNIEnv* env, jclass clazz, jint ptr) {
1292ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1302ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    delete state;
1312ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1322ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1332ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic void android_view_VelocityTracker_nativeClear(JNIEnv* env, jclass clazz, jint ptr) {
1342ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1352ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->clear();
1362ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1372ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1382ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic void android_view_VelocityTracker_nativeAddMovement(JNIEnv* env, jclass clazz, jint ptr,
1392ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        jobject eventObj) {
1402ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    const MotionEvent* event = android_view_MotionEvent_getNativePtr(env, eventObj);
1412ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    if (!event) {
1422ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        LOGW("nativeAddMovement failed because MotionEvent was finalized.");
1432ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        return;
1442ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    }
1452ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1462ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1472ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->addMovement(event);
1482ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1492ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1502ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic void android_view_VelocityTracker_nativeComputeCurrentVelocity(JNIEnv* env, jclass clazz,
1512ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        jint ptr, jint units, jfloat maxVelocity) {
1522ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1532ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->computeCurrentVelocity(units, maxVelocity);
1542ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1552ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1562ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic jfloat android_view_VelocityTracker_nativeGetXVelocity(JNIEnv* env, jclass clazz,
1572ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        jint ptr, jint id) {
1582ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1592ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    float vx;
1602ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->getVelocity(id, &vx, NULL);
1612ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    return vx;
1622ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1632ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1642ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic jfloat android_view_VelocityTracker_nativeGetYVelocity(JNIEnv* env, jclass clazz,
1652ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown        jint ptr, jint id) {
1662ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
1672ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    float vy;
1682ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    state->getVelocity(id, NULL, &vy);
1692ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    return vy;
1702ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
1712ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1722ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1732ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown// --- JNI Registration ---
1742ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
1752ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownstatic JNINativeMethod gVelocityTrackerMethods[] = {
1762ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    /* name, signature, funcPtr */
1772ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeInitialize",
1782ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "()I",
1792ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeInitialize },
1802ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeDispose",
1812ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(I)V",
1822ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeDispose },
1832ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeClear",
1842ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(I)V",
1852ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeClear },
1862ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeAddMovement",
1872ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(ILandroid/view/MotionEvent;)V",
1882ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeAddMovement },
1892ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeComputeCurrentVelocity",
1902ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(IIF)V",
1912ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeComputeCurrentVelocity },
1922ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeGetXVelocity",
1932ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(II)F",
1942ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeGetXVelocity },
1952ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    { "nativeGetYVelocity",
1962ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            "(II)F",
1972ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            (void*)android_view_VelocityTracker_nativeGetYVelocity },
1982ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown};
1992ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
2002ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownint register_android_view_VelocityTracker(JNIEnv* env) {
2012ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    int res = jniRegisterNativeMethods(env, "android/view/VelocityTracker",
2022ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown            gVelocityTrackerMethods, NELEM(gVelocityTrackerMethods));
2032ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
2042ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown    return 0;
2052ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown}
2062ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown
2072ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown} // namespace android
208