19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright 2008, The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood#define LOG_TAG "SensorManager" 17270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood 182279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h> 19d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "android_os_MessageQueue.h" 20d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "core_jni_helpers.h" 21d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "jni.h" 229ba7c1c17567c19f0187d73cdca55ca99590674edestradaa 232279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/ScopedUtfChars.h> 242279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/ScopedLocalRef.h> 25d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <android_runtime/AndroidRuntime.h> 267d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu#include <android_runtime/android_hardware_HardwareBuffer.h> 275f73ab7e2a591d45b67a7aaf1b26cc9dcfe58502Jesse Hall#include <vndk/hardware_buffer.h> 28caf8930960ae68d5be2a8952cc127bf3f154f433Mathias Agopian#include <sensor/Sensor.h> 29caf8930960ae68d5be2a8952cc127bf3f154f433Mathias Agopian#include <sensor/SensorEventQueue.h> 30caf8930960ae68d5be2a8952cc127bf3f154f433Mathias Agopian#include <sensor/SensorManager.h> 31fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu#include <cutils/native_handle.h> 32db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include <utils/Log.h> 33db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include <utils/Looper.h> 34a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu#include <utils/Vector.h> 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <map> 37987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 384a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xunamespace { 394a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu 404a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xuusing namespace android; 414a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu 424a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xustruct { 43db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jclass clazz; 44db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jmethodID dispatchSensorEvent; 45b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jmethodID dispatchFlushCompleteEvent; 46a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jmethodID dispatchAdditionalInfoEvent; 479a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh} gBaseEventQueueClassInfo; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct SensorOffsets 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 51a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jclass clazz; 52b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu //fields 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID name; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID vendor; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID version; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID handle; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID range; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID resolution; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID power; 60050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian jfieldID minDelay; 61b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jfieldID fifoReservedEventCount; 62b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jfieldID fifoMaxEventCount; 63cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella jfieldID stringType; 64cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella jfieldID requiredPermission; 652f8b91449efafa5fb0057cd0150233681c65c9e3Aravind Akella jfieldID maxDelay; 6627900358f2f5b89e8b01516b28a916d16c99ba9bAravind Akella jfieldID flags; 67b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu //methods 689ba7c1c17567c19f0187d73cdca55ca99590674edestradaa jmethodID setType; 69b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu jmethodID setUuid; 70a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jmethodID init; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gSensorOffsets; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 73a35b5539a95342799a18e95616c5e5751a198e4cPeng Xustruct ListOffsets { 74a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jclass clazz; 75a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jmethodID add; 76a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu} gListOffsets; 77db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 783e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xustruct StringOffsets { 793e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu jclass clazz; 803e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu jmethodID intern; 813e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu jstring emptyString; 823e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu} gStringOffsets; 833e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 854a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu * nativeClassInit is not inteneded to be thread-safe. It should be called before other native... 864a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu * functions (except nativeCreate). 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 88db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianstatic void 89db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias AgopiannativeClassInit (JNIEnv *_env, jclass _this) 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 91a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu //android.hardware.Sensor 92db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian SensorOffsets& sensorOffsets = gSensorOffsets; 933e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu jclass sensorClass = (jclass) 943e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "android/hardware/Sensor")); 953e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.clazz = sensorClass; 963e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.name = GetFieldIDOrDie(_env, sensorClass, "mName", "Ljava/lang/String;"); 973e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.vendor = GetFieldIDOrDie(_env, sensorClass, "mVendor", "Ljava/lang/String;"); 983e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.version = GetFieldIDOrDie(_env, sensorClass, "mVersion", "I"); 993e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.handle = GetFieldIDOrDie(_env, sensorClass, "mHandle", "I"); 1003e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.range = GetFieldIDOrDie(_env, sensorClass, "mMaxRange", "F"); 1013e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.resolution = GetFieldIDOrDie(_env, sensorClass, "mResolution","F"); 1023e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.power = GetFieldIDOrDie(_env, sensorClass, "mPower", "F"); 1033e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.minDelay = GetFieldIDOrDie(_env, sensorClass, "mMinDelay", "I"); 104b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella sensorOffsets.fifoReservedEventCount = 1053e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu GetFieldIDOrDie(_env,sensorClass, "mFifoReservedEventCount", "I"); 1063e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.fifoMaxEventCount = GetFieldIDOrDie(_env,sensorClass, "mFifoMaxEventCount", "I"); 1073e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.stringType = 1083e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu GetFieldIDOrDie(_env,sensorClass, "mStringType", "Ljava/lang/String;"); 1093e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.requiredPermission = 1103e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu GetFieldIDOrDie(_env,sensorClass, "mRequiredPermission", "Ljava/lang/String;"); 1113e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.maxDelay = GetFieldIDOrDie(_env,sensorClass, "mMaxDelay", "I"); 1123e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.flags = GetFieldIDOrDie(_env,sensorClass, "mFlags", "I"); 1133e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu 1143e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.setType = GetMethodIDOrDie(_env,sensorClass, "setType", "(I)Z"); 1153e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.setUuid = GetMethodIDOrDie(_env,sensorClass, "setUuid", "(JJ)V"); 1163e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu sensorOffsets.init = GetMethodIDOrDie(_env,sensorClass, "<init>", "()V"); 117a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 118a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu // java.util.List; 119a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu ListOffsets& listOffsets = gListOffsets; 1203e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu jclass listClass = (jclass) MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "java/util/List")); 121a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu listOffsets.clazz = listClass; 1223e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu listOffsets.add = GetMethodIDOrDie(_env,listClass, "add", "(Ljava/lang/Object;)Z"); 1233e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu 1243e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu // initialize java.lang.String and empty string intern 1253e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu StringOffsets& stringOffsets = gStringOffsets; 1263e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu stringOffsets.clazz = MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "java/lang/String")); 1273e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu stringOffsets.intern = 1283e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu GetMethodIDOrDie(_env, stringOffsets.clazz, "intern", "()Ljava/lang/String;"); 1293e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu ScopedLocalRef<jstring> empty(_env, _env->NewStringUTF("")); 1303e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu stringOffsets.emptyString = (jstring) 1313e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu MakeGlobalRefOrDie(_env, _env->CallObjectMethod(empty.get(), stringOffsets.intern)); 1329ba7c1c17567c19f0187d73cdca55ca99590674edestradaa} 1339ba7c1c17567c19f0187d73cdca55ca99590674edestradaa 1343e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xustatic jstring getJavaInternedString(JNIEnv *env, const String8 &string) { 1353e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu if (string == "") { 1363e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu return gStringOffsets.emptyString; 1379ba7c1c17567c19f0187d73cdca55ca99590674edestradaa } 1389ba7c1c17567c19f0187d73cdca55ca99590674edestradaa 1393e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu ScopedLocalRef<jstring> javaString(env, env->NewStringUTF(string.string())); 1403e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu jstring internedString = (jstring) 1413e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu env->CallObjectMethod(javaString.get(), gStringOffsets.intern); 1429ba7c1c17567c19f0187d73cdca55ca99590674edestradaa return internedString; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 145b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganovstatic jlong 146b9d71a6f89b1183f6389b1774652445a420c6cbfSvet GanovnativeCreate 147b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov(JNIEnv *env, jclass clazz, jstring opPackageName) 148b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov{ 149b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov ScopedUtfChars opPackageNameUtf(env, opPackageName); 1502af91d0e104b3a80f3e832e464e52893a55a715fAravind Akella return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str())); 151b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov} 152b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov 153a35b5539a95342799a18e95616c5e5751a198e4cPeng Xustatic jobject 154a35b5539a95342799a18e95616c5e5751a198e4cPeng XutranslateNativeSensorToJavaSensor(JNIEnv *env, jobject sensor, const Sensor& nativeSensor) { 155a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu const SensorOffsets& sensorOffsets(gSensorOffsets); 156a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 157a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu if (sensor == NULL) { 158a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu // Sensor sensor = new Sensor(); 159a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu sensor = env->NewObject(sensorOffsets.clazz, sensorOffsets.init, ""); 160a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } 161a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 162a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu if (sensor != NULL) { 1633e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu jstring name = getJavaInternedString(env, nativeSensor.getName()); 1643e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu jstring vendor = getJavaInternedString(env, nativeSensor.getVendor()); 165a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jstring requiredPermission = 1663e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu getJavaInternedString(env, nativeSensor.getRequiredPermission()); 167a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 168a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetObjectField(sensor, sensorOffsets.name, name); 169a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetObjectField(sensor, sensorOffsets.vendor, vendor); 170a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.version, nativeSensor.getVersion()); 171a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.handle, nativeSensor.getHandle()); 172a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetFloatField(sensor, sensorOffsets.range, nativeSensor.getMaxValue()); 173a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetFloatField(sensor, sensorOffsets.resolution, nativeSensor.getResolution()); 174a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetFloatField(sensor, sensorOffsets.power, nativeSensor.getPowerUsage()); 175a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.minDelay, nativeSensor.getMinDelay()); 176a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount, 177a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu nativeSensor.getFifoReservedEventCount()); 178a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount, 179a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu nativeSensor.getFifoMaxEventCount()); 180a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetObjectField(sensor, sensorOffsets.requiredPermission, 181a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu requiredPermission); 182a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.maxDelay, nativeSensor.getMaxDelay()); 183a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.flags, nativeSensor.getFlags()); 184b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu 185a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu if (env->CallBooleanMethod(sensor, sensorOffsets.setType, nativeSensor.getType()) 186a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu == JNI_FALSE) { 1873e13204989f0ebb1706cf44223b2ed28968ea46bPeng Xu jstring stringType = getJavaInternedString(env, nativeSensor.getStringType()); 188a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetObjectField(sensor, sensorOffsets.stringType, stringType); 189a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } 190b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu 191716866d56542c267ccb686992de590ad04c84215Peng Xu // TODO(b/29547335): Rename "setUuid" method to "setId". 192716866d56542c267ccb686992de590ad04c84215Peng Xu int64_t id = nativeSensor.getId(); 193716866d56542c267ccb686992de590ad04c84215Peng Xu env->CallVoidMethod(sensor, sensorOffsets.setUuid, id, 0); 194a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } 195a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu return sensor; 196a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu} 197a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 198516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akellastatic jboolean 199516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind AkellanativeGetSensorAtIndex(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensor, jint index) 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 201b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2031bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian Sensor const* const* sensorList; 204a08c9f52db26fa78e33464b57cc0597981352270Peng Xu ssize_t count = mgr->getSensorList(&sensorList); 205a08c9f52db26fa78e33464b57cc0597981352270Peng Xu if (ssize_t(index) >= count) { 206516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella return false; 2079ba7c1c17567c19f0187d73cdca55ca99590674edestradaa } 208b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 209b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu return translateNativeSensorToJavaSensor(env, sensor, *sensorList[index]) != NULL; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 212a35b5539a95342799a18e95616c5e5751a198e4cPeng Xustatic void 213a35b5539a95342799a18e95616c5e5751a198e4cPeng XunativeGetDynamicSensors(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensorList) { 214a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 215a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 216a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu const ListOffsets& listOffsets(gListOffsets); 217a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 218a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu Vector<Sensor> nativeList; 219a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 220a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu mgr->getDynamicSensorList(nativeList); 221a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 22285ea32b02a2b281ee5092ef8c31c44a0ba3452a4Ben Wagner ALOGI("DYNS native SensorManager.getDynamicSensorList return %zu sensors", nativeList.size()); 223a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu for (size_t i = 0; i < nativeList.size(); ++i) { 224a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jobject sensor = translateNativeSensorToJavaSensor(env, NULL, nativeList[i]); 225a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu // add to list 226a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->CallBooleanMethod(sensorList, listOffsets.add, sensor); 227a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } 228a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu} 229a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 230d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akellastatic jboolean nativeIsDataInjectionEnabled(JNIEnv *_env, jclass _this, jlong sensorManager) { 231b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 232d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella return mgr->isDataInjectionEnabled(); 23318ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella} 23418ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella 235fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xustatic jint nativeCreateDirectChannel(JNIEnv *_env, jclass _this, jlong sensorManager, 2367d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu jlong size, jint channelType, jint fd, jobject hardwareBufferObj) { 2377d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu const native_handle_t *nativeHandle = nullptr; 2387d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu NATIVE_HANDLE_DECLARE_STORAGE(ashmemHandle, 1, 0); 2397d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu 2407d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu if (channelType == SENSOR_DIRECT_MEM_TYPE_ASHMEM) { 2417d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu native_handle_t *handle = native_handle_init(ashmemHandle, 1, 0); 2427d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu handle->data[0] = fd; 2437d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu nativeHandle = handle; 2447d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu } else if (channelType == SENSOR_DIRECT_MEM_TYPE_GRALLOC) { 2457d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu AHardwareBuffer *hardwareBuffer = 2467d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu android_hardware_HardwareBuffer_getNativeHardwareBuffer(_env, hardwareBufferObj); 2477d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu if (hardwareBuffer != nullptr) { 2487d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu nativeHandle = AHardwareBuffer_getNativeHandle(hardwareBuffer); 249fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu } 250fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu } 2517d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu 2527d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu if (nativeHandle == nullptr) { 2537d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu return BAD_VALUE; 2547d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu } 2557d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu 2567d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 2577d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu return mgr->createDirectChannel(size, channelType, nativeHandle); 258fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu} 259fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu 260fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xustatic void nativeDestroyDirectChannel(JNIEnv *_env, jclass _this, jlong sensorManager, 261fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu jint channelHandle) { 262fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 263fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu mgr->destroyDirectChannel(channelHandle); 264fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu} 265fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu 266fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xustatic jint nativeConfigDirectChannel(JNIEnv *_env, jclass _this, jlong sensorManager, 267fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu jint channelHandle, jint sensorHandle, jint rate) { 268fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 269fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu return mgr->configureDirectChannel(channelHandle, sensorHandle, rate); 270fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu} 271fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu 2721cfde25e4019bc050c7f030896825fd90d69baf5Peng Xustatic jint nativeSetOperationParameter(JNIEnv *_env, jclass _this, jlong sensorManager, 2735b5e11c483c14f930d3516042af8497a7b766a47Alexey Polyudov jint handle, jint type, jfloatArray floats, jintArray ints) { 2741cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 2751cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu Vector<float> floatVector; 2761cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu Vector<int32_t> int32Vector; 2771cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu 2781cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu if (floats != nullptr) { 2791cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu floatVector.resize(_env->GetArrayLength(floats)); 2801cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu _env->GetFloatArrayRegion(floats, 0, _env->GetArrayLength(floats), floatVector.editArray()); 2811cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu } 2821cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu 2831cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu if (ints != nullptr) { 2841cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu int32Vector.resize(_env->GetArrayLength(ints)); 2851cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu _env->GetIntArrayRegion(ints, 0, _env->GetArrayLength(ints), int32Vector.editArray()); 2861cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu } 2871cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu 2885b5e11c483c14f930d3516042af8497a7b766a47Alexey Polyudov return mgr->setOperationParameter(handle, type, floatVector, int32Vector); 2891cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu} 2901cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------------- 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 293db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianclass Receiver : public LooperCallback { 294db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> mSensorQueue; 295db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<MessageQueue> mMessageQueue; 2963b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown jobject mReceiverWeakGlobal; 297a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jfloatArray mFloatScratch; 298a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jintArray mIntScratch; 299db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianpublic: 300db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian Receiver(const sp<SensorEventQueue>& sensorQueue, 301db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian const sp<MessageQueue>& messageQueue, 302a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jobject receiverWeak) { 303db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian JNIEnv* env = AndroidRuntime::getJNIEnv(); 304db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mSensorQueue = sensorQueue; 305db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mMessageQueue = messageQueue; 3063b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak); 307a29583553957a19755bfba26f48b6ebe977879cbPeng Xu 308a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16)); 309a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16)); 310db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 311db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ~Receiver() { 312db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian JNIEnv* env = AndroidRuntime::getJNIEnv(); 3133b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown env->DeleteGlobalRef(mReceiverWeakGlobal); 314a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->DeleteGlobalRef(mFloatScratch); 315a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->DeleteGlobalRef(mIntScratch); 316db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 317db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> getSensorEventQueue() const { 318db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return mSensorQueue; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 321db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian void destroy() { 322db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mMessageQueue->getLooper()->removeFd( mSensorQueue->getFd() ); 323270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 325db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianprivate: 326db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian virtual void onFirstRef() { 327db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian LooperCallback::onFirstRef(); 328db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0, 329db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ALOOPER_EVENT_INPUT, this, mSensorQueue.get()); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 331db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 332db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian virtual int handleEvent(int fd, int events, void* data) { 333db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian JNIEnv* env = AndroidRuntime::getJNIEnv(); 334db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data); 3353b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); 3363b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown 337db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ssize_t n; 338db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ASensorEvent buffer[16]; 339db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian while ((n = q->read(buffer, 16)) > 0) { 340db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian for (int i=0 ; i<n ; i++) { 3410288ca63e3f0aee05ad2ede23564e04e53aca950Aravind Akella if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) { 3423c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru // step-counter returns a uint64, but the java API only deals with floats 3433c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru float value = float(buffer[i].u64.step_counter); 344a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetFloatArrayRegion(mFloatScratch, 0, 1, &value); 345a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } else if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) { 346a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu float value[2]; 347a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu value[0] = buffer[i].dynamic_sensor_meta.connected ? 1.f: 0.f; 348a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu value[1] = float(buffer[i].dynamic_sensor_meta.handle); 349a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetFloatArrayRegion(mFloatScratch, 0, 2, value); 350a29583553957a19755bfba26f48b6ebe977879cbPeng Xu } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { 351a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetIntArrayRegion(mIntScratch, 0, 14, 352a29583553957a19755bfba26f48b6ebe977879cbPeng Xu buffer[i].additional_info.data_int32); 353a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetFloatArrayRegion(mFloatScratch, 0, 14, 354a29583553957a19755bfba26f48b6ebe977879cbPeng Xu buffer[i].additional_info.data_float); 3553c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru } else { 356a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetFloatArrayRegion(mFloatScratch, 0, 16, buffer[i].data); 3573c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru } 358db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 359b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 360b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella // This is a flush complete sensor event. Call dispatchFlushCompleteEvent 361b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella // method. 3623b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown if (receiverObj.get()) { 3633b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown env->CallVoidMethod(receiverObj.get(), 3643b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown gBaseEventQueueClassInfo.dispatchFlushCompleteEvent, 3653b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown buffer[i].meta_data.sensor); 3663b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown } 367a29583553957a19755bfba26f48b6ebe977879cbPeng Xu } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { 368a29583553957a19755bfba26f48b6ebe977879cbPeng Xu // This is a flush complete sensor event. Call dispatchAdditionalInfoEvent 369a29583553957a19755bfba26f48b6ebe977879cbPeng Xu // method. 370a29583553957a19755bfba26f48b6ebe977879cbPeng Xu if (receiverObj.get()) { 371a29583553957a19755bfba26f48b6ebe977879cbPeng Xu int type = buffer[i].additional_info.type; 372a29583553957a19755bfba26f48b6ebe977879cbPeng Xu int serial = buffer[i].additional_info.serial; 373a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->CallVoidMethod(receiverObj.get(), 374a29583553957a19755bfba26f48b6ebe977879cbPeng Xu gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent, 375a29583553957a19755bfba26f48b6ebe977879cbPeng Xu buffer[i].sensor, 376a29583553957a19755bfba26f48b6ebe977879cbPeng Xu type, serial, 377a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mFloatScratch, 378a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mIntScratch, 379a29583553957a19755bfba26f48b6ebe977879cbPeng Xu buffer[i].timestamp); 380a29583553957a19755bfba26f48b6ebe977879cbPeng Xu } 381a29583553957a19755bfba26f48b6ebe977879cbPeng Xu }else { 382af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand int8_t status; 383af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand switch (buffer[i].type) { 384af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_ORIENTATION: 385af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_MAGNETIC_FIELD: 386af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_ACCELEROMETER: 387af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_GYROSCOPE: 388f38226ab40feadb63b9b0c48d148db919ecec7f4Aravind Akella case SENSOR_TYPE_GRAVITY: 389f38226ab40feadb63b9b0c48d148db919ecec7f4Aravind Akella case SENSOR_TYPE_LINEAR_ACCELERATION: 390af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status = buffer[i].vector.status; 391af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand break; 392af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_HEART_RATE: 393af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status = buffer[i].heart_rate.status; 394af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand break; 395af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand default: 396af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status = SENSOR_STATUS_ACCURACY_HIGH; 397af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand break; 398af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand } 3993b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown if (receiverObj.get()) { 4003b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown env->CallVoidMethod(receiverObj.get(), 4013b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown gBaseEventQueueClassInfo.dispatchSensorEvent, 4023b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown buffer[i].sensor, 403a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mFloatScratch, 4043b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown status, 4053b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown buffer[i].timestamp); 4063b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown } 407b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 408db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (env->ExceptionCheck()) { 40935187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella mSensorQueue->sendAck(buffer, n); 410db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ALOGE("Exception dispatching input event."); 411db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 1; 412db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 413db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 41435187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella mSensorQueue->sendAck(buffer, n); 415db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 416db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (n<0 && n != -EAGAIN) { 417db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // FIXME: error receiving events, what to do in this case? 418db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 419db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 1; 4200b6d77bdeb99ca92709828c7c4867eec2f727f88Mathias Agopian } 421db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}; 4221bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 423b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganovstatic jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager, 424a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) { 425b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 42688445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella ScopedUtfChars packageUtf(env, packageName); 42788445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella String8 clientName(packageUtf.c_str()); 428b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode)); 429db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 430d9d4e1bc3bcecea31cc0aa055758915b3cbc6befPeng Xu if (queue == NULL) { 431d9d4e1bc3bcecea31cc0aa055758915b3cbc6befPeng Xu jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue."); 432d9d4e1bc3bcecea31cc0aa055758915b3cbc6befPeng Xu return 0; 433d9d4e1bc3bcecea31cc0aa055758915b3cbc6befPeng Xu } 434d9d4e1bc3bcecea31cc0aa055758915b3cbc6befPeng Xu 435db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ); 436db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (messageQueue == NULL) { 437db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jniThrowRuntimeException(env, "MessageQueue is not initialized."); 438db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 0; 439db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 4401bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 441a29583553957a19755bfba26f48b6ebe977879cbPeng Xu sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak); 442b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian receiver->incStrong((void*)nativeInitSensorEventQueue); 4434838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat return jlong(receiver.get()); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4464838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us, 44788445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella jint maxBatchReportLatency) { 448db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 449b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency, 45088445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella 0); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4534838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeDisableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle) { 454db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 455db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return receiver->getSensorEventQueue()->disableSensor(handle); 456db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian} 457db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 45818ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akellastatic void nativeDestroySensorEventQueue(JNIEnv *env, jclass clazz, jlong eventQ) { 459db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 460db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian receiver->destroy(); 461b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian receiver->decStrong((void*)nativeInitSensorEventQueue); 462db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian} 463db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 4644838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeFlushSensor(JNIEnv *env, jclass clazz, jlong eventQ) { 465b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 4664bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella return receiver->getSensorEventQueue()->flush(); 467b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella} 468db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 46918ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akellastatic jint nativeInjectSensorData(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, 47018ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella jfloatArray values, jint accuracy, jlong timestamp) { 47118ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 47218ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella // Create a sensor_event from the above data which can be injected into the HAL. 47318ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella ASensorEvent sensor_event; 47418ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella memset(&sensor_event, 0, sizeof(sensor_event)); 47518ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella sensor_event.sensor = handle; 47618ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella sensor_event.timestamp = timestamp; 47718ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella env->GetFloatArrayRegion(values, 0, env->GetArrayLength(values), sensor_event.data); 47818ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella return receiver->getSensorEventQueue()->injectSensorEvent(sensor_event); 47918ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella} 480db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian//---------------------------------------------------------------------------- 481db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 48276f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gSystemSensorManagerMethods[] = { 483db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeClassInit", 484db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian "()V", 485db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeClassInit }, 486b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov {"nativeCreate", 487b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov "(Ljava/lang/String;)J", 488b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov (void*)nativeCreate }, 489db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 490516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella {"nativeGetSensorAtIndex", 491516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella "(JLandroid/hardware/Sensor;I)Z", 492516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella (void*)nativeGetSensorAtIndex }, 49318ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella 494a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu {"nativeGetDynamicSensors", 495a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu "(JLjava/util/List;)V", 496a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu (void*)nativeGetDynamicSensors }, 497a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 498d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella {"nativeIsDataInjectionEnabled", 499d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella "(J)Z", 500fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu (void*)nativeIsDataInjectionEnabled }, 501fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu 502fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu {"nativeCreateDirectChannel", 5037d96fa0b2acb54a0951dbaf6f9ca5ecc1e2b1f0fPeng Xu "(JJIILandroid/hardware/HardwareBuffer;)I", 504fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu (void*)nativeCreateDirectChannel }, 505fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu 506fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu {"nativeDestroyDirectChannel", 507fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu "(JI)V", 508fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu (void*)nativeDestroyDirectChannel }, 509fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu 510fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu {"nativeConfigDirectChannel", 511fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu "(JIII)I", 512fa2672b71d9501463d8b9de5162f069b9e48384bPeng Xu (void*)nativeConfigDirectChannel }, 5131cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu 5141cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu {"nativeSetOperationParameter", 5155b5e11c483c14f930d3516042af8497a7b766a47Alexey Polyudov "(JII[F[I)I", 5161cfde25e4019bc050c7f030896825fd90d69baf5Peng Xu (void*)nativeSetOperationParameter }, 517db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}; 5181bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 51976f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gBaseEventQueueMethods[] = { 5209a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh {"nativeInitBaseEventQueue", 521a29583553957a19755bfba26f48b6ebe977879cbPeng Xu "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J", 522b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov (void*)nativeInitSensorEventQueue }, 5231bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 524db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeEnableSensor", 52588445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella "(JIII)I", 526db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeEnableSensor }, 527db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 528db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeDisableSensor", 5294838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(JI)I", 530db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeDisableSensor }, 531db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 532db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeDestroySensorEventQueue", 5334838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(J)V", 534db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeDestroySensorEventQueue }, 535b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 536b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella {"nativeFlushSensor", 5374838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(J)I", 538b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella (void*)nativeFlushSensor }, 53918ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella 54018ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella {"nativeInjectSensorData", 54118ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella "(JI[FIJ)I", 54218ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella (void*)nativeInjectSensorData }, 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5454a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu} //unnamed namespace 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_hardware_SensorManager(JNIEnv *env) 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 549987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager", 550db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods)); 551db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 552987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager$BaseEventQueue", 5539a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods)); 554db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 555987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.clazz = FindClassOrDie(env, 556987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe "android/hardware/SystemSensorManager$BaseEventQueue"); 557db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 558987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.dispatchSensorEvent = GetMethodIDOrDie(env, 559987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.clazz, "dispatchSensorEvent", "(I[FIJ)V"); 560db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 561987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.dispatchFlushCompleteEvent = GetMethodIDOrDie(env, 562987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.clazz, "dispatchFlushCompleteEvent", "(I)V"); 563b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 564a29583553957a19755bfba26f48b6ebe977879cbPeng Xu gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent = GetMethodIDOrDie(env, 565a29583553957a19755bfba26f48b6ebe977879cbPeng Xu gBaseEventQueueClassInfo.clazz, "dispatchAdditionalInfoEvent", "(III[F[I)V"); 566a29583553957a19755bfba26f48b6ebe977879cbPeng Xu 567db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 0; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 569