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