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 */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood#define LOG_TAG "SensorManager" 18270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood 19db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include <utils/Log.h> 20db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include <utils/Looper.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 221bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian#include <gui/Sensor.h> 231bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian#include <gui/SensorManager.h> 241bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian#include <gui/SensorEventQueue.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 28db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include "android_os_MessageQueue.h" 29db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include <android_runtime/AndroidRuntime.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianstatic struct { 32db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jclass clazz; 33db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jmethodID dispatchSensorEvent; 34b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jmethodID dispatchFlushCompleteEvent; 359a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh} gBaseEventQueueClassInfo; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct SensorOffsets 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID name; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID vendor; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID version; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID handle; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID type; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID range; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID resolution; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfieldID power; 49050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian jfieldID minDelay; 50b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jfieldID fifoReservedEventCount; 51b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jfieldID fifoMaxEventCount; 52cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella jfieldID stringType; 53cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella jfieldID requiredPermission; 542f8b91449efafa5fb0057cd0150233681c65c9e3Aravind Akella jfieldID maxDelay; 5527900358f2f5b89e8b01516b28a916d16c99ba9bAravind Akella jfieldID flags; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gSensorOffsets; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 58db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The method below are not thread-safe and not intended to be 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 63db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianstatic void 64db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias AgopiannativeClassInit (JNIEnv *_env, jclass _this) 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 66db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jclass sensorClass = _env->FindClass("android/hardware/Sensor"); 67db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian SensorOffsets& sensorOffsets = gSensorOffsets; 68db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.name = _env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;"); 69db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.vendor = _env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;"); 70db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.version = _env->GetFieldID(sensorClass, "mVersion", "I"); 71db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.handle = _env->GetFieldID(sensorClass, "mHandle", "I"); 72db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.type = _env->GetFieldID(sensorClass, "mType", "I"); 73db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.range = _env->GetFieldID(sensorClass, "mMaxRange", "F"); 74db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F"); 75db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F"); 76db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sensorOffsets.minDelay = _env->GetFieldID(sensorClass, "mMinDelay", "I"); 77b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella sensorOffsets.fifoReservedEventCount = 78b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella _env->GetFieldID(sensorClass, "mFifoReservedEventCount", "I"); 79b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount", "I"); 80cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella sensorOffsets.stringType = _env->GetFieldID(sensorClass, "mStringType", "Ljava/lang/String;"); 81cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella sensorOffsets.requiredPermission = _env->GetFieldID(sensorClass, "mRequiredPermission", 82cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella "Ljava/lang/String;"); 832f8b91449efafa5fb0057cd0150233681c65c9e3Aravind Akella sensorOffsets.maxDelay = _env->GetFieldID(sensorClass, "mMaxDelay", "I"); 8427900358f2f5b89e8b01516b28a916d16c99ba9bAravind Akella sensorOffsets.flags = _env->GetFieldID(sensorClass, "mFlags", "I"); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint 88db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias AgopiannativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next) 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 901bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian SensorManager& mgr(SensorManager::getInstance()); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 921bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian Sensor const* const* sensorList; 931bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian size_t count = mgr.getSensorList(&sensorList); 944fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (size_t(next) >= count) 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 96b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 971bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian Sensor const* const list = sensorList[next]; 981bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian const SensorOffsets& sensorOffsets(gSensorOffsets); 991bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian jstring name = env->NewStringUTF(list->getName().string()); 1001bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian jstring vendor = env->NewStringUTF(list->getVendor().string()); 101cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella jstring stringType = env->NewStringUTF(list->getStringType().string()); 102cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella jstring requiredPermission = env->NewStringUTF(list->getRequiredPermission().string()); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetObjectField(sensor, sensorOffsets.name, name); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->SetObjectField(sensor, sensorOffsets.vendor, vendor); 105277d1b2f49897e90a8ec9bd0f05ea4ed62d2ff28Mathias Agopian env->SetIntField(sensor, sensorOffsets.version, list->getVersion()); 1061bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian env->SetIntField(sensor, sensorOffsets.handle, list->getHandle()); 1071bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian env->SetIntField(sensor, sensorOffsets.type, list->getType()); 1081bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian env->SetFloatField(sensor, sensorOffsets.range, list->getMaxValue()); 1091bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution()); 1101bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian env->SetFloatField(sensor, sensorOffsets.power, list->getPowerUsage()); 111050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian env->SetIntField(sensor, sensorOffsets.minDelay, list->getMinDelay()); 112b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount, 113b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella list->getFifoReservedEventCount()); 114cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount, 115cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella list->getFifoMaxEventCount()); 116cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella env->SetObjectField(sensor, sensorOffsets.stringType, stringType); 117cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella env->SetObjectField(sensor, sensorOffsets.requiredPermission, 118cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella requiredPermission); 1192f8b91449efafa5fb0057cd0150233681c65c9e3Aravind Akella env->SetIntField(sensor, sensorOffsets.maxDelay, list->getMaxDelay()); 12027900358f2f5b89e8b01516b28a916d16c99ba9bAravind Akella env->SetIntField(sensor, sensorOffsets.flags, list->getFlags()); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project next++; 1224fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return size_t(next) < count ? next : 0; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------------- 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 127db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianclass Receiver : public LooperCallback { 128db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> mSensorQueue; 129db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<MessageQueue> mMessageQueue; 130db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jobject mReceiverObject; 131db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jfloatArray mScratch; 132db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianpublic: 133db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian Receiver(const sp<SensorEventQueue>& sensorQueue, 134db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian const sp<MessageQueue>& messageQueue, 135db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jobject receiverObject, jfloatArray scratch) { 136db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian JNIEnv* env = AndroidRuntime::getJNIEnv(); 137db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mSensorQueue = sensorQueue; 138db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mMessageQueue = messageQueue; 139db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mReceiverObject = env->NewGlobalRef(receiverObject); 140db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mScratch = (jfloatArray)env->NewGlobalRef(scratch); 141db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 142db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ~Receiver() { 143db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian JNIEnv* env = AndroidRuntime::getJNIEnv(); 144db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian env->DeleteGlobalRef(mReceiverObject); 145db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian env->DeleteGlobalRef(mScratch); 146db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 147db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> getSensorEventQueue() const { 148db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return mSensorQueue; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 151db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian void destroy() { 152db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mMessageQueue->getLooper()->removeFd( mSensorQueue->getFd() ); 153270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 155db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianprivate: 156db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian virtual void onFirstRef() { 157db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian LooperCallback::onFirstRef(); 158db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0, 159db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ALOOPER_EVENT_INPUT, this, mSensorQueue.get()); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 161db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 162db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian virtual int handleEvent(int fd, int events, void* data) { 163db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian JNIEnv* env = AndroidRuntime::getJNIEnv(); 164db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data); 165db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ssize_t n; 166db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ASensorEvent buffer[16]; 167db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian while ((n = q->read(buffer, 16)) > 0) { 168db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian for (int i=0 ; i<n ; i++) { 1690288ca63e3f0aee05ad2ede23564e04e53aca950Aravind Akella if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) { 1703c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru // step-counter returns a uint64, but the java API only deals with floats 1713c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru float value = float(buffer[i].u64.step_counter); 1723c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru env->SetFloatArrayRegion(mScratch, 0, 1, &value); 1733c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru } else { 1743c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data); 1753c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru } 176db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 177b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 178b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella // This is a flush complete sensor event. Call dispatchFlushCompleteEvent 179b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella // method. 180b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella env->CallVoidMethod(mReceiverObject, 181b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella gBaseEventQueueClassInfo.dispatchFlushCompleteEvent, 182b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella buffer[i].meta_data.sensor); 183b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } else { 184af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand int8_t status; 185af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand switch (buffer[i].type) { 186af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_ORIENTATION: 187af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_MAGNETIC_FIELD: 188af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_ACCELEROMETER: 189af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_GYROSCOPE: 190af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status = buffer[i].vector.status; 191af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand break; 192af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand case SENSOR_TYPE_HEART_RATE: 193af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status = buffer[i].heart_rate.status; 194af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand break; 195af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand default: 196af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status = SENSOR_STATUS_ACCURACY_HIGH; 197af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand break; 198af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand } 199b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella env->CallVoidMethod(mReceiverObject, 200b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella gBaseEventQueueClassInfo.dispatchSensorEvent, 201b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella buffer[i].sensor, 202b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella mScratch, 203af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand status, 204b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella buffer[i].timestamp); 205b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 206db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (env->ExceptionCheck()) { 20735187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella mSensorQueue->sendAck(buffer, n); 208db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian ALOGE("Exception dispatching input event."); 209db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 1; 210db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 211db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 21235187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella mSensorQueue->sendAck(buffer, n); 213db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 214db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (n<0 && n != -EAGAIN) { 215db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // FIXME: error receiving events, what to do in this case? 216db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 217db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 1; 2180b6d77bdeb99ca92709828c7c4867eec2f727f88Mathias Agopian } 219db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}; 2201bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 2214838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQ, jobject msgQ, jfloatArray scratch) { 222db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian SensorManager& mgr(SensorManager::getInstance()); 223db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<SensorEventQueue> queue(mgr.createEventQueue()); 224db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 225db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ); 226db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (messageQueue == NULL) { 227db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jniThrowRuntimeException(env, "MessageQueue is not initialized."); 228db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 0; 229db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 2301bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 231db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQ, scratch); 232b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian receiver->incStrong((void*)nativeInitSensorEventQueue); 2334838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat return jlong(receiver.get()); 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2364838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us, 237b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella jint maxBatchReportLatency, jint reservedFlags) { 238db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 239b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency, 240b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella reservedFlags); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2434838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeDisableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle) { 244db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 245db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return receiver->getSensorEventQueue()->disableSensor(handle); 246db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian} 247db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 2484838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic void nativeDestroySensorEventQueue(JNIEnv *env, jclass clazz, jlong eventQ, jint handle) { 249db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 250db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian receiver->destroy(); 251b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian receiver->decStrong((void*)nativeInitSensorEventQueue); 252db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian} 253db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 2544838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeFlushSensor(JNIEnv *env, jclass clazz, jlong eventQ) { 255b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ)); 2564bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella return receiver->getSensorEventQueue()->flush(); 257b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella} 258db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 259db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian//---------------------------------------------------------------------------- 260db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 261db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianstatic JNINativeMethod gSystemSensorManagerMethods[] = { 262db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeClassInit", 263db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian "()V", 264db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeClassInit }, 265db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 266db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeGetNextSensor", 267db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian "(Landroid/hardware/Sensor;I)I", 268db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeGetNextSensor }, 269db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}; 2701bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 2719a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganeshstatic JNINativeMethod gBaseEventQueueMethods[] = { 2729a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh {"nativeInitBaseEventQueue", 2734838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(Landroid/hardware/SystemSensorManager$BaseEventQueue;Landroid/os/MessageQueue;[F)J", 274db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeInitSensorEventQueue }, 2751bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian 276db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeEnableSensor", 2774838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(JIIII)I", 278db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeEnableSensor }, 279db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 280db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeDisableSensor", 2814838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(JI)I", 282db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeDisableSensor }, 283db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 284db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian {"nativeDestroySensorEventQueue", 2854838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(J)V", 286db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian (void*)nativeDestroySensorEventQueue }, 287b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 288b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella {"nativeFlushSensor", 2894838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat "(J)I", 290b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella (void*)nativeFlushSensor }, 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 297db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#define FIND_CLASS(var, className) \ 298db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian var = env->FindClass(className); \ 299db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian LOG_FATAL_IF(! var, "Unable to find class " className); \ 300db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian var = jclass(env->NewGlobalRef(var)); 301db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 302db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 303db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 304db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian LOG_FATAL_IF(! var, "Unable to find method " methodName); 305db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_hardware_SensorManager(JNIEnv *env) 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 308db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager", 309db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods)); 310db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 3119a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$BaseEventQueue", 3129a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods)); 313db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 3149a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh FIND_CLASS(gBaseEventQueueClassInfo.clazz, "android/hardware/SystemSensorManager$BaseEventQueue"); 315db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 3169a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchSensorEvent, 3179a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh gBaseEventQueueClassInfo.clazz, 318db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian "dispatchSensorEvent", "(I[FIJ)V"); 319db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 320b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchFlushCompleteEvent, 321b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella gBaseEventQueueClassInfo.clazz, 322b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella "dispatchFlushCompleteEvent", "(I)V"); 323b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 324db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return 0; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 326