2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "VelocityTracker-JNI"
21 #include <android_runtime/AndroidRuntime.h>
22 #include <utils/Log.h>
23 #include <input/Input.h>
24 #include <input/VelocityTracker.h>
25 #include "android_view_MotionEvent.h"
27 #include <ScopedUtfChars.h>
29 #include "core_jni_helpers.h"
33 // Special constant to request the velocity of the active pointer.
34 static const int ACTIVE_POINTER_ID = -1;
41 } gEstimatorClassInfo;
44 // --- VelocityTrackerState ---
46 class VelocityTrackerState {
48 VelocityTrackerState(const char* strategy);
51 void addMovement(const MotionEvent* event);
52 void computeCurrentVelocity(int32_t units, float maxVelocity);
53 void getVelocity(int32_t id, float* outVx, float* outVy);
54 bool getEstimator(int32_t id, VelocityTracker::Estimator* outEstimator);
61 VelocityTracker mVelocityTracker;
62 int32_t mActivePointerId;
63 BitSet32 mCalculatedIdBits;
64 Velocity mCalculatedVelocity[MAX_POINTERS];
67 VelocityTrackerState::VelocityTrackerState(const char* strategy) :
68 mVelocityTracker(strategy), mActivePointerId(-1) {
71 void VelocityTrackerState::clear() {
72 mVelocityTracker.clear();
73 mActivePointerId = -1;
74 mCalculatedIdBits.clear();
77 void VelocityTrackerState::addMovement(const MotionEvent* event) {
78 mVelocityTracker.addMovement(event);
81 void VelocityTrackerState::computeCurrentVelocity(int32_t units, float maxVelocity) {
82 BitSet32 idBits(mVelocityTracker.getCurrentPointerIdBits());
83 mCalculatedIdBits = idBits;
85 for (uint32_t index = 0; !idBits.isEmpty(); index++) {
86 uint32_t id = idBits.clearFirstMarkedBit();
89 mVelocityTracker.getVelocity(id, &vx, &vy);
91 vx = vx * units / 1000;
92 vy = vy * units / 1000;
94 if (vx > maxVelocity) {
96 } else if (vx < -maxVelocity) {
99 if (vy > maxVelocity) {
101 } else if (vy < -maxVelocity) {
105 Velocity& velocity = mCalculatedVelocity[index];
111 void VelocityTrackerState::getVelocity(int32_t id, float* outVx, float* outVy) {
112 if (id == ACTIVE_POINTER_ID) {
113 id = mVelocityTracker.getActivePointerId();
117 if (id >= 0 && id <= MAX_POINTER_ID && mCalculatedIdBits.hasBit(id)) {
118 uint32_t index = mCalculatedIdBits.getIndexOfBit(id);
119 const Velocity& velocity = mCalculatedVelocity[index];
135 bool VelocityTrackerState::getEstimator(int32_t id, VelocityTracker::Estimator* outEstimator) {
136 return mVelocityTracker.getEstimator(id, outEstimator);
140 // --- JNI Methods ---
142 static jlong android_view_VelocityTracker_nativeInitialize(JNIEnv* env, jclass clazz,
143 jstring strategyStr) {
145 ScopedUtfChars strategy(env, strategyStr);
146 return reinterpret_cast<jlong>(new VelocityTrackerState(strategy.c_str()));
148 return reinterpret_cast<jlong>(new VelocityTrackerState(NULL));
151 static void android_view_VelocityTracker_nativeDispose(JNIEnv* env, jclass clazz, jlong ptr) {
152 VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
156 static void android_view_VelocityTracker_nativeClear(JNIEnv* env, jclass clazz, jlong ptr) {
157 VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
161 static void android_view_VelocityTracker_nativeAddMovement(JNIEnv* env, jclass clazz, jlong ptr,
163 const MotionEvent* event = android_view_MotionEvent_getNativePtr(env, eventObj);
165 ALOGW("nativeAddMovement failed because MotionEvent was finalized.");
169 VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
170 state->addMovement(event);
173 static void android_view_VelocityTracker_nativeComputeCurrentVelocity(JNIEnv* env, jclass clazz,
174 jlong ptr, jint units, jfloat maxVelocity) {
175 VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
176 state->computeCurrentVelocity(units, maxVelocity);
179 static jfloat android_view_VelocityTracker_nativeGetXVelocity(JNIEnv* env, jclass clazz,
180 jlong ptr, jint id) {
181 VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
183 state->getVelocity(id, &vx, NULL);
187 static jfloat android_view_VelocityTracker_nativeGetYVelocity(JNIEnv* env, jclass clazz,
188 jlong ptr, jint id) {
189 VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
191 state->getVelocity(id, NULL, &vy);
195 static jboolean android_view_VelocityTracker_nativeGetEstimator(JNIEnv* env, jclass clazz,
196 jlong ptr, jint id, jobject outEstimatorObj) {
197 VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
198 VelocityTracker::Estimator estimator;
199 bool result = state->getEstimator(id, &estimator);
201 jfloatArray xCoeffObj = jfloatArray(env->GetObjectField(outEstimatorObj,
202 gEstimatorClassInfo.xCoeff));
203 jfloatArray yCoeffObj = jfloatArray(env->GetObjectField(outEstimatorObj,
204 gEstimatorClassInfo.yCoeff));
206 env->SetFloatArrayRegion(xCoeffObj, 0, VelocityTracker::Estimator::MAX_DEGREE + 1,
208 env->SetFloatArrayRegion(yCoeffObj, 0, VelocityTracker::Estimator::MAX_DEGREE + 1,
210 env->SetIntField(outEstimatorObj, gEstimatorClassInfo.degree, estimator.degree);
211 env->SetFloatField(outEstimatorObj, gEstimatorClassInfo.confidence, estimator.confidence);
216 // --- JNI Registration ---
218 static JNINativeMethod gVelocityTrackerMethods[] = {
219 /* name, signature, funcPtr */
220 { "nativeInitialize",
221 "(Ljava/lang/String;)J",
222 (void*)android_view_VelocityTracker_nativeInitialize },
225 (void*)android_view_VelocityTracker_nativeDispose },
228 (void*)android_view_VelocityTracker_nativeClear },
229 { "nativeAddMovement",
230 "(JLandroid/view/MotionEvent;)V",
231 (void*)android_view_VelocityTracker_nativeAddMovement },
232 { "nativeComputeCurrentVelocity",
234 (void*)android_view_VelocityTracker_nativeComputeCurrentVelocity },
235 { "nativeGetXVelocity",
237 (void*)android_view_VelocityTracker_nativeGetXVelocity },
238 { "nativeGetYVelocity",
240 (void*)android_view_VelocityTracker_nativeGetYVelocity },
241 { "nativeGetEstimator",
242 "(JILandroid/view/VelocityTracker$Estimator;)Z",
243 (void*)android_view_VelocityTracker_nativeGetEstimator },
246 int register_android_view_VelocityTracker(JNIEnv* env) {
247 int res = RegisterMethodsOrDie(env, "android/view/VelocityTracker", gVelocityTrackerMethods,
248 NELEM(gVelocityTrackerMethods));
250 jclass clazz = FindClassOrDie(env, "android/view/VelocityTracker$Estimator");
252 gEstimatorClassInfo.xCoeff = GetFieldIDOrDie(env, clazz, "xCoeff", "[F");
253 gEstimatorClassInfo.yCoeff = GetFieldIDOrDie(env, clazz, "yCoeff", "[F");
254 gEstimatorClassInfo.degree = GetFieldIDOrDie(env, clazz, "degree", "I");
255 gEstimatorClassInfo.confidence = GetFieldIDOrDie(env, clazz, "confidence", "F");
260 } // namespace android