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 18d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "JNIHelp.h" 19d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "android_os_MessageQueue.h" 20d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "core_jni_helpers.h" 21d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "jni.h" 229ba7c1c17567c19f0187d73cdca55ca99590674edestradaa 2388445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella#include <ScopedUtfChars.h> 243b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown#include <ScopedLocalRef.h> 25d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <android_runtime/AndroidRuntime.h> 26d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <gui/Sensor.h> 27d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <gui/SensorEventQueue.h> 28d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <gui/SensorManager.h> 29db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include <utils/Log.h> 30db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include <utils/Looper.h> 31a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu#include <utils/Vector.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <map> 34987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 354a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xunamespace { 364a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu 374a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xuusing namespace android; 384a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu 394a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xustruct { 40db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jclass clazz; 41db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jmethodID dispatchSensorEvent; 42b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jmethodID dispatchFlushCompleteEvent; 43a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jmethodID dispatchAdditionalInfoEvent; 449a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh} gBaseEventQueueClassInfo; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct SensorOffsets 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 48a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jclass clazz; 49b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu //fields 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID name; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID vendor; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID version; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID handle; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID range; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID resolution; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID power; 57050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian jfieldID minDelay; 58b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jfieldID fifoReservedEventCount; 59b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jfieldID fifoMaxEventCount; 60cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella jfieldID stringType; 61cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella jfieldID requiredPermission; 622f8b91449efafa5fb0057cd0150233681c65c9e3Aravind Akella jfieldID maxDelay; 6327900358f2f5b89e8b01516b28a916d16c99ba9bAravind Akella jfieldID flags; 64b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu //methods 659ba7c1c17567c19f0187d73cdca55ca99590674edestradaa jmethodID setType; 66b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu jmethodID setUuid; 67a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jmethodID init; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gSensorOffsets; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 70a35b5539a95342799a18e95616c5e5751a198e4cPeng Xustruct ListOffsets { 71a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jclass clazz; 72a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jmethodID add; 73a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu} gListOffsets; 74db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 764a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu * nativeClassInit is not inteneded to be thread-safe. It should be called before other native... 774a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu * functions (except nativeCreate). 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 79db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianstatic void 80db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias AgopiannativeClassInit (JNIEnv *_env, jclass _this) 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 82a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu //android.hardware.Sensor 83db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian SensorOffsets& sensorOffsets = gSensorOffsets; 84a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jclass sensorClass = (jclass) _env->NewGlobalRef(_env->FindClass("android/hardware/Sensor")); 85a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu sensorOffsets.clazz = sensorClass; 86db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.name = _env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;"); 87db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.vendor = _env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;"); 88db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.version = _env->GetFieldID(sensorClass, "mVersion", "I"); 89db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.handle = _env->GetFieldID(sensorClass, "mHandle", "I"); 90db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.range = _env->GetFieldID(sensorClass, "mMaxRange", "F"); 91db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F"); 92db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F"); 93db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.minDelay = _env->GetFieldID(sensorClass, "mMinDelay", "I"); 94b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella sensorOffsets.fifoReservedEventCount = 95b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella _env->GetFieldID(sensorClass, "mFifoReservedEventCount", "I"); 96b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount", "I"); 97cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella sensorOffsets.stringType = _env->GetFieldID(sensorClass, "mStringType", "Ljava/lang/String;"); 98cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella sensorOffsets.requiredPermission = _env->GetFieldID(sensorClass, "mRequiredPermission", 99cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella "Ljava/lang/String;"); 1002f8b91449efafa5fb0057cd0150233681c65c9e3Aravind Akella sensorOffsets.maxDelay = _env->GetFieldID(sensorClass, "mMaxDelay", "I"); 10127900358f2f5b89e8b01516b28a916d16c99ba9bAravind Akella sensorOffsets.flags = _env->GetFieldID(sensorClass, "mFlags", "I"); 102a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 1039ba7c1c17567c19f0187d73cdca55ca99590674edestradaa sensorOffsets.setType = _env->GetMethodID(sensorClass, "setType", "(I)Z"); 104b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu sensorOffsets.setUuid = _env->GetMethodID(sensorClass, "setUuid", "(JJ)V"); 105a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu sensorOffsets.init = _env->GetMethodID(sensorClass, "<init>", "()V"); 106a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 107a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu // java.util.List; 108a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu ListOffsets& listOffsets = gListOffsets; 109a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jclass listClass = (jclass) _env->NewGlobalRef(_env->FindClass("java/util/List")); 110a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu listOffsets.clazz = listClass; 111a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu listOffsets.add = _env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z"); 1129ba7c1c17567c19f0187d73cdca55ca99590674edestradaa} 1139ba7c1c17567c19f0187d73cdca55ca99590674edestradaa 1149ba7c1c17567c19f0187d73cdca55ca99590674edestradaa/** 1159ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * A key comparator predicate. 1169ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * It is used to intern strings associated with Sensor data. 1179ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * It defines a 'Strict weak ordering' for the interned strings. 1189ba7c1c17567c19f0187d73cdca55ca99590674edestradaa */ 1199ba7c1c17567c19f0187d73cdca55ca99590674edestradaaclass InternedStringCompare { 1209ba7c1c17567c19f0187d73cdca55ca99590674edestradaapublic: 1219ba7c1c17567c19f0187d73cdca55ca99590674edestradaa bool operator()(const String8* string1, const String8* string2) const { 1229ba7c1c17567c19f0187d73cdca55ca99590674edestradaa if (string1 == NULL) { 1239ba7c1c17567c19f0187d73cdca55ca99590674edestradaa return string2 != NULL; 1249ba7c1c17567c19f0187d73cdca55ca99590674edestradaa } 12588445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella if (string2 == NULL) { 12688445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella return false; 12788445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella } 1289ba7c1c17567c19f0187d73cdca55ca99590674edestradaa return string1->compare(*string2) < 0; 1299ba7c1c17567c19f0187d73cdca55ca99590674edestradaa } 1309ba7c1c17567c19f0187d73cdca55ca99590674edestradaa}; 1319ba7c1c17567c19f0187d73cdca55ca99590674edestradaa 1329ba7c1c17567c19f0187d73cdca55ca99590674edestradaa/** 1339ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * A localized interning mechanism for Sensor strings. 1349ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * We implement our own interning to avoid the overhead of using java.lang.String#intern(). 1359ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * It is common that Vendor, StringType, and RequirePermission data is common between many of the 1369ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * Sensors, by interning the memory usage to represent Sensors is optimized. 1379ba7c1c17567c19f0187d73cdca55ca99590674edestradaa */ 1389ba7c1c17567c19f0187d73cdca55ca99590674edestradaastatic jstring 1399ba7c1c17567c19f0187d73cdca55ca99590674edestradaagetInternedString(JNIEnv *env, const String8* string) { 1409ba7c1c17567c19f0187d73cdca55ca99590674edestradaa static std::map<const String8*, jstring, InternedStringCompare> internedStrings; 1419ba7c1c17567c19f0187d73cdca55ca99590674edestradaa 1429ba7c1c17567c19f0187d73cdca55ca99590674edestradaa jstring internedString; 1439ba7c1c17567c19f0187d73cdca55ca99590674edestradaa std::map<const String8*, jstring>::iterator iterator = internedStrings.find(string); 1449ba7c1c17567c19f0187d73cdca55ca99590674edestradaa if (iterator != internedStrings.end()) { 1459ba7c1c17567c19f0187d73cdca55ca99590674edestradaa internedString = iterator->second; 1469ba7c1c17567c19f0187d73cdca55ca99590674edestradaa } else { 1479ba7c1c17567c19f0187d73cdca55ca99590674edestradaa jstring localString = env->NewStringUTF(string->string()); 1489ba7c1c17567c19f0187d73cdca55ca99590674edestradaa // we are implementing our own interning so expect these strings to be backed by global refs 1499ba7c1c17567c19f0187d73cdca55ca99590674edestradaa internedString = (jstring) env->NewGlobalRef(localString); 1509ba7c1c17567c19f0187d73cdca55ca99590674edestradaa internedStrings.insert(std::make_pair(string, internedString)); 1519ba7c1c17567c19f0187d73cdca55ca99590674edestradaa env->DeleteLocalRef(localString); 1529ba7c1c17567c19f0187d73cdca55ca99590674edestradaa } 1539ba7c1c17567c19f0187d73cdca55ca99590674edestradaa return internedString; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 156b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganovstatic jlong 157b9d71a6f89b1183f6389b1774652445a420c6cbfSvet GanovnativeCreate 158b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov(JNIEnv *env, jclass clazz, jstring opPackageName) 159b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov{ 160b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov ScopedUtfChars opPackageNameUtf(env, opPackageName); 1612af91d0e104b3a80f3e832e464e52893a55a715fAravind Akella return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str())); 162b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov} 163b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov 164a35b5539a95342799a18e95616c5e5751a198e4cPeng Xustatic jobject 165a35b5539a95342799a18e95616c5e5751a198e4cPeng XutranslateNativeSensorToJavaSensor(JNIEnv *env, jobject sensor, const Sensor& nativeSensor) { 166a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu const SensorOffsets& sensorOffsets(gSensorOffsets); 167a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 168a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu if (sensor == NULL) { 169a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu // Sensor sensor = new Sensor(); 170a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu sensor = env->NewObject(sensorOffsets.clazz, sensorOffsets.init, ""); 171a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } 172a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 173a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu if (sensor != NULL) { 174a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jstring name = env->NewStringUTF(nativeSensor.getName().string()); 175a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jstring vendor = env->NewStringUTF(nativeSensor.getVendor().string()); 176a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jstring requiredPermission = 177a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->NewStringUTF(nativeSensor.getRequiredPermission().string()); 178a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 179a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetObjectField(sensor, sensorOffsets.name, name); 180a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetObjectField(sensor, sensorOffsets.vendor, vendor); 181a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.version, nativeSensor.getVersion()); 182a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.handle, nativeSensor.getHandle()); 183a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetFloatField(sensor, sensorOffsets.range, nativeSensor.getMaxValue()); 184a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetFloatField(sensor, sensorOffsets.resolution, nativeSensor.getResolution()); 185a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetFloatField(sensor, sensorOffsets.power, nativeSensor.getPowerUsage()); 186a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.minDelay, nativeSensor.getMinDelay()); 187a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount, 188a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu nativeSensor.getFifoReservedEventCount()); 189a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount, 190a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu nativeSensor.getFifoMaxEventCount()); 191a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetObjectField(sensor, sensorOffsets.requiredPermission, 192a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu requiredPermission); 193a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.maxDelay, nativeSensor.getMaxDelay()); 194a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetIntField(sensor, sensorOffsets.flags, nativeSensor.getFlags()); 195b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu 196a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu if (env->CallBooleanMethod(sensor, sensorOffsets.setType, nativeSensor.getType()) 197a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu == JNI_FALSE) { 198a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jstring stringType = getInternedString(env, &nativeSensor.getStringType()); 199a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->SetObjectField(sensor, sensorOffsets.stringType, stringType); 200a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } 201b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu 202716866d56542c267ccb686992de590ad04c84215Peng Xu // TODO(b/29547335): Rename "setUuid" method to "setId". 203716866d56542c267ccb686992de590ad04c84215Peng Xu int64_t id = nativeSensor.getId(); 204716866d56542c267ccb686992de590ad04c84215Peng Xu env->CallVoidMethod(sensor, sensorOffsets.setUuid, id, 0); 205a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } 206a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu return sensor; 207a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu} 208a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 209516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akellastatic jboolean 210516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind AkellanativeGetSensorAtIndex(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensor, jint index) 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 212b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2141bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian Sensor const* const* sensorList; 215a08c9f52db26fa78e33464b57cc0597981352270Peng Xu ssize_t count = mgr->getSensorList(&sensorList); 216a08c9f52db26fa78e33464b57cc0597981352270Peng Xu if (ssize_t(index) >= count) { 217516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella return false; 2189ba7c1c17567c19f0187d73cdca55ca99590674edestradaa } 219b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 220b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu return translateNativeSensorToJavaSensor(env, sensor, *sensorList[index]) != NULL; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 223a35b5539a95342799a18e95616c5e5751a198e4cPeng Xustatic void 224a35b5539a95342799a18e95616c5e5751a198e4cPeng XunativeGetDynamicSensors(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensorList) { 225a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 226a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 227a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu const ListOffsets& listOffsets(gListOffsets); 228a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 229a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu Vector<Sensor> nativeList; 230a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 231a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu mgr->getDynamicSensorList(nativeList); 232a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 233a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu ALOGI("DYNS native SensorManager.getDynamicSensorList return %d sensors", nativeList.size()); 234a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu for (size_t i = 0; i < nativeList.size(); ++i) { 235a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu jobject sensor = translateNativeSensorToJavaSensor(env, NULL, nativeList[i]); 236a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu // add to list 237a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu env->CallBooleanMethod(sensorList, listOffsets.add, sensor); 238a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } 239a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu} 240a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 241d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akellastatic jboolean nativeIsDataInjectionEnabled(JNIEnv *_env, jclass _this, jlong sensorManager) { 242b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 243d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella return mgr->isDataInjectionEnabled(); 24418ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella} 24518ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------------- 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 248db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianclass Receiver : public LooperCallback { 249db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> mSensorQueue; 250db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<MessageQueue> mMessageQueue; 2513b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown jobject mReceiverWeakGlobal; 252a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jfloatArray mFloatScratch; 253a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jintArray mIntScratch; 254db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianpublic: 255db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian Receiver(const sp<SensorEventQueue>& sensorQueue, 256db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian const sp<MessageQueue>& messageQueue, 257a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jobject receiverWeak) { 258db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian JNIEnv* env = AndroidRuntime::getJNIEnv(); 259db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mSensorQueue = sensorQueue; 260db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mMessageQueue = messageQueue; 2613b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak); 262a29583553957a19755bfba26f48b6ebe977879cbPeng Xu 263a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16)); 264a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16)); 265db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 266db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ~Receiver() { 267db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian JNIEnv* env = AndroidRuntime::getJNIEnv(); 2683b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown env->DeleteGlobalRef(mReceiverWeakGlobal); 269a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->DeleteGlobalRef(mFloatScratch); 270a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->DeleteGlobalRef(mIntScratch); 271db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 272db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> getSensorEventQueue() const { 273db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return mSensorQueue; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 276db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian void destroy() { 277db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mMessageQueue->getLooper()->removeFd( mSensorQueue->getFd() ); 278270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 280db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianprivate: 281db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian virtual void onFirstRef() { 282db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian LooperCallback::onFirstRef(); 283db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0, 284db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ALOOPER_EVENT_INPUT, this, mSensorQueue.get()); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 286db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 287db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian virtual int handleEvent(int fd, int events, void* data) { 288db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian JNIEnv* env = AndroidRuntime::getJNIEnv(); 289db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data); 2903b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); 2913b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown 292db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ssize_t n; 293db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ASensorEvent buffer[16]; 294db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian while ((n = q->read(buffer, 16)) > 0) { 295db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian for (int i=0 ; i<n ; i++) { 2960288ca63e3f0aee05ad2ede23564e04e53aca950Aravind Akella if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) { 2973c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru // step-counter returns a uint64, but the java API only deals with floats 2983c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru float value = float(buffer[i].u64.step_counter); 299a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetFloatArrayRegion(mFloatScratch, 0, 1, &value); 300a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu } else if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) { 301a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu float value[2]; 302a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu value[0] = buffer[i].dynamic_sensor_meta.connected ? 1.f: 0.f; 303a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu value[1] = float(buffer[i].dynamic_sensor_meta.handle); 304a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetFloatArrayRegion(mFloatScratch, 0, 2, value); 305a29583553957a19755bfba26f48b6ebe977879cbPeng Xu } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { 306a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetIntArrayRegion(mIntScratch, 0, 14, 307a29583553957a19755bfba26f48b6ebe977879cbPeng Xu buffer[i].additional_info.data_int32); 308a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetFloatArrayRegion(mFloatScratch, 0, 14, 309a29583553957a19755bfba26f48b6ebe977879cbPeng Xu buffer[i].additional_info.data_float); 3103c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru } else { 311a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->SetFloatArrayRegion(mFloatScratch, 0, 16, buffer[i].data); 3123c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru } 313db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 314b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 315b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella // This is a flush complete sensor event. Call dispatchFlushCompleteEvent 316b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella // method. 3173b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown if (receiverObj.get()) { 3183b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown env->CallVoidMethod(receiverObj.get(), 3193b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown gBaseEventQueueClassInfo.dispatchFlushCompleteEvent, 3203b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown buffer[i].meta_data.sensor); 3213b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown } 322a29583553957a19755bfba26f48b6ebe977879cbPeng Xu } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { 323a29583553957a19755bfba26f48b6ebe977879cbPeng Xu // This is a flush complete sensor event. Call dispatchAdditionalInfoEvent 324a29583553957a19755bfba26f48b6ebe977879cbPeng Xu // method. 325a29583553957a19755bfba26f48b6ebe977879cbPeng Xu if (receiverObj.get()) { 326a29583553957a19755bfba26f48b6ebe977879cbPeng Xu int type = buffer[i].additional_info.type; 327a29583553957a19755bfba26f48b6ebe977879cbPeng Xu int serial = buffer[i].additional_info.serial; 328a29583553957a19755bfba26f48b6ebe977879cbPeng Xu env->CallVoidMethod(receiverObj.get(), 329a29583553957a19755bfba26f48b6ebe977879cbPeng Xu gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent, 330a29583553957a19755bfba26f48b6ebe977879cbPeng Xu buffer[i].sensor, 331a29583553957a19755bfba26f48b6ebe977879cbPeng Xu type, serial, 332a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mFloatScratch, 333a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mIntScratch, 334a29583553957a19755bfba26f48b6ebe977879cbPeng Xu buffer[i].timestamp); 335a29583553957a19755bfba26f48b6ebe977879cbPeng Xu } 336a29583553957a19755bfba26f48b6ebe977879cbPeng Xu }else { 337af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand int8_t status; 338af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand switch (buffer[i].type) { 339af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_ORIENTATION: 340af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_MAGNETIC_FIELD: 341af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_ACCELEROMETER: 342af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_GYROSCOPE: 343f38226ab40feadb63b9b0c48d148db919ecec7f4Aravind Akella case SENSOR_TYPE_GRAVITY: 344f38226ab40feadb63b9b0c48d148db919ecec7f4Aravind Akella case SENSOR_TYPE_LINEAR_ACCELERATION: 345af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status = buffer[i].vector.status; 346af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand break; 347af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_HEART_RATE: 348af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status = buffer[i].heart_rate.status; 349af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand break; 350af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand default: 351af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status = SENSOR_STATUS_ACCURACY_HIGH; 352af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand break; 353af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand } 3543b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown if (receiverObj.get()) { 3553b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown env->CallVoidMethod(receiverObj.get(), 3563b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown gBaseEventQueueClassInfo.dispatchSensorEvent, 3573b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown buffer[i].sensor, 358a29583553957a19755bfba26f48b6ebe977879cbPeng Xu mFloatScratch, 3593b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown status, 3603b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown buffer[i].timestamp); 3613b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown } 362b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 363db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (env->ExceptionCheck()) { 36435187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella mSensorQueue->sendAck(buffer, n); 365db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ALOGE("Exception dispatching input event."); 366db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 1; 367db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 368db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 36935187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella mSensorQueue->sendAck(buffer, n); 370db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 371db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (n<0 && n != -EAGAIN) { 372db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // FIXME: error receiving events, what to do in this case? 373db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 374db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 1; 3750b6d77bdeb99ca92709828c7c4867eec2f727f88Mathias Agopian } 376db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}; 3771bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 378b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganovstatic jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager, 379a29583553957a19755bfba26f48b6ebe977879cbPeng Xu jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) { 380b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); 38188445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella ScopedUtfChars packageUtf(env, packageName); 38288445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella String8 clientName(packageUtf.c_str()); 383b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode)); 384db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 385db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ); 386db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (messageQueue == NULL) { 387db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jniThrowRuntimeException(env, "MessageQueue is not initialized."); 388db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 0; 389db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 3901bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 391a29583553957a19755bfba26f48b6ebe977879cbPeng Xu sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak); 392b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian receiver->incStrong((void*)nativeInitSensorEventQueue); 3934838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat return jlong(receiver.get()); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3964838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us, 39788445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella jint maxBatchReportLatency) { 398db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 399b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency, 40088445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella 0); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4034838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeDisableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle) { 404db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 405db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return receiver->getSensorEventQueue()->disableSensor(handle); 406db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian} 407db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 40818ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akellastatic void nativeDestroySensorEventQueue(JNIEnv *env, jclass clazz, jlong eventQ) { 409db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 410db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian receiver->destroy(); 411b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian receiver->decStrong((void*)nativeInitSensorEventQueue); 412db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian} 413db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 4144838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeFlushSensor(JNIEnv *env, jclass clazz, jlong eventQ) { 415b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 4164bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella return receiver->getSensorEventQueue()->flush(); 417b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella} 418db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 41918ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akellastatic jint nativeInjectSensorData(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, 42018ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella jfloatArray values, jint accuracy, jlong timestamp) { 42118ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 42218ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella // Create a sensor_event from the above data which can be injected into the HAL. 42318ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella ASensorEvent sensor_event; 42418ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella memset(&sensor_event, 0, sizeof(sensor_event)); 42518ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella sensor_event.sensor = handle; 42618ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella sensor_event.timestamp = timestamp; 42718ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella env->GetFloatArrayRegion(values, 0, env->GetArrayLength(values), sensor_event.data); 42818ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella return receiver->getSensorEventQueue()->injectSensorEvent(sensor_event); 42918ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella} 430db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian//---------------------------------------------------------------------------- 431db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 43276f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gSystemSensorManagerMethods[] = { 433db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeClassInit", 434db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian "()V", 435db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeClassInit }, 436b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov {"nativeCreate", 437b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov "(Ljava/lang/String;)J", 438b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov (void*)nativeCreate }, 439db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 440516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella {"nativeGetSensorAtIndex", 441516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella "(JLandroid/hardware/Sensor;I)Z", 442516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella (void*)nativeGetSensorAtIndex }, 44318ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella 444a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu {"nativeGetDynamicSensors", 445a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu "(JLjava/util/List;)V", 446a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu (void*)nativeGetDynamicSensors }, 447a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu 448d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella {"nativeIsDataInjectionEnabled", 449d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella "(J)Z", 450d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella (void*)nativeIsDataInjectionEnabled}, 451db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}; 4521bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 45376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gBaseEventQueueMethods[] = { 4549a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh {"nativeInitBaseEventQueue", 455a29583553957a19755bfba26f48b6ebe977879cbPeng Xu "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J", 456b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov (void*)nativeInitSensorEventQueue }, 4571bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 458db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeEnableSensor", 45988445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella "(JIII)I", 460db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeEnableSensor }, 461db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 462db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeDisableSensor", 4634838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(JI)I", 464db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeDisableSensor }, 465db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 466db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeDestroySensorEventQueue", 4674838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(J)V", 468db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeDestroySensorEventQueue }, 469b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 470b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella {"nativeFlushSensor", 4714838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(J)I", 472b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella (void*)nativeFlushSensor }, 47318ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella 47418ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella {"nativeInjectSensorData", 47518ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella "(JI[FIJ)I", 47618ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella (void*)nativeInjectSensorData }, 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4794a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu} //unnamed namespace 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_hardware_SensorManager(JNIEnv *env) 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 483987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager", 484db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods)); 485db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 486987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager$BaseEventQueue", 4879a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods)); 488db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 489987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.clazz = FindClassOrDie(env, 490987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe "android/hardware/SystemSensorManager$BaseEventQueue"); 491db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 492987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.dispatchSensorEvent = GetMethodIDOrDie(env, 493987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.clazz, "dispatchSensorEvent", "(I[FIJ)V"); 494db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 495987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.dispatchFlushCompleteEvent = GetMethodIDOrDie(env, 496987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gBaseEventQueueClassInfo.clazz, "dispatchFlushCompleteEvent", "(I)V"); 497b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 498a29583553957a19755bfba26f48b6ebe977879cbPeng Xu gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent = GetMethodIDOrDie(env, 499a29583553957a19755bfba26f48b6ebe977879cbPeng Xu gBaseEventQueueClassInfo.clazz, "dispatchAdditionalInfoEvent", "(III[F[I)V"); 500a29583553957a19755bfba26f48b6ebe977879cbPeng Xu 501db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 0; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 503