android_hardware_SensorManager.cpp revision 35187bd5c1e40ea52a672c525411d05cbcdd6482
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;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gSensorOffsets;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
56db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The method below are not thread-safe and not intended to be
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianstatic void
62db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias AgopiannativeClassInit (JNIEnv *_env, jclass _this)
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
64db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    jclass sensorClass = _env->FindClass("android/hardware/Sensor");
65db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    SensorOffsets& sensorOffsets = gSensorOffsets;
66db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");
67db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");
68db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");
69db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");
70db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.type        = _env->GetFieldID(sensorClass, "mType",      "I");
71db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.range       = _env->GetFieldID(sensorClass, "mMaxRange",  "F");
72db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
73db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
74db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.minDelay    = _env->GetFieldID(sensorClass, "mMinDelay",  "I");
75b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    sensorOffsets.fifoReservedEventCount =
76b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella            _env->GetFieldID(sensorClass, "mFifoReservedEventCount",  "I");
77b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount",  "I");
78cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    sensorOffsets.stringType = _env->GetFieldID(sensorClass, "mStringType", "Ljava/lang/String;");
79cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    sensorOffsets.requiredPermission = _env->GetFieldID(sensorClass, "mRequiredPermission",
80cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella                                                        "Ljava/lang/String;");
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint
84db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias AgopiannativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next)
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
861bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    SensorManager& mgr(SensorManager::getInstance());
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
881bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    Sensor const* const* sensorList;
891bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    size_t count = mgr.getSensorList(&sensorList);
904fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    if (size_t(next) >= count)
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
92b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella
931bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    Sensor const* const list = sensorList[next];
941bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    const SensorOffsets& sensorOffsets(gSensorOffsets);
951bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    jstring name = env->NewStringUTF(list->getName().string());
961bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    jstring vendor = env->NewStringUTF(list->getVendor().string());
97cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    jstring stringType = env->NewStringUTF(list->getStringType().string());
98cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    jstring requiredPermission = env->NewStringUTF(list->getRequiredPermission().string());
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetObjectField(sensor, sensorOffsets.name,      name);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
101277d1b2f49897e90a8ec9bd0f05ea4ed62d2ff28Mathias Agopian    env->SetIntField(sensor, sensorOffsets.version,      list->getVersion());
1021bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    env->SetIntField(sensor, sensorOffsets.handle,       list->getHandle());
1031bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    env->SetIntField(sensor, sensorOffsets.type,         list->getType());
1041bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    env->SetFloatField(sensor, sensorOffsets.range,      list->getMaxValue());
1051bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());
1061bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    env->SetFloatField(sensor, sensorOffsets.power,      list->getPowerUsage());
107050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian    env->SetIntField(sensor, sensorOffsets.minDelay,     list->getMinDelay());
108b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount,
109b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                     list->getFifoReservedEventCount());
110cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount,
111cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella                     list->getFifoMaxEventCount());
112cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    env->SetObjectField(sensor, sensorOffsets.stringType, stringType);
113cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    env->SetObjectField(sensor, sensorOffsets.requiredPermission,
114cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella                        requiredPermission);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    next++;
1164fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    return size_t(next) < count ? next : 0;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------------
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
121db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianclass Receiver : public LooperCallback {
122db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<SensorEventQueue> mSensorQueue;
123db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<MessageQueue> mMessageQueue;
124db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    jobject mReceiverObject;
125db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    jfloatArray mScratch;
126db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianpublic:
127db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    Receiver(const sp<SensorEventQueue>& sensorQueue,
128db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            const sp<MessageQueue>& messageQueue,
129db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            jobject receiverObject, jfloatArray scratch) {
130db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        JNIEnv* env = AndroidRuntime::getJNIEnv();
131db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mSensorQueue = sensorQueue;
132db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mMessageQueue = messageQueue;
133db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mReceiverObject = env->NewGlobalRef(receiverObject);
134db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mScratch = (jfloatArray)env->NewGlobalRef(scratch);
135db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    }
136db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    ~Receiver() {
137db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        JNIEnv* env = AndroidRuntime::getJNIEnv();
138db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        env->DeleteGlobalRef(mReceiverObject);
139db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        env->DeleteGlobalRef(mScratch);
140db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    }
141db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<SensorEventQueue> getSensorEventQueue() const {
142db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        return mSensorQueue;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
145db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    void destroy() {
146db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mMessageQueue->getLooper()->removeFd( mSensorQueue->getFd() );
147270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood    }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
149db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianprivate:
150db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    virtual void onFirstRef() {
151db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        LooperCallback::onFirstRef();
152db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
153db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
155db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
156db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    virtual int handleEvent(int fd, int events, void* data) {
157db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        JNIEnv* env = AndroidRuntime::getJNIEnv();
158db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
159db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        ssize_t n;
160db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        ASensorEvent buffer[16];
161db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        while ((n = q->read(buffer, 16)) > 0) {
162db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            for (int i=0 ; i<n ; i++) {
1633c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
1643c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                    // step-counter returns a uint64, but the java API only deals with floats
1653c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                    float value = float(buffer[i].u64.step_counter);
1663c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                    env->SetFloatArrayRegion(mScratch, 0, 1, &value);
1673c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                } else {
1683c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                    env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
1693c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                }
170db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
171b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
172b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                    // This is a flush complete sensor event. Call dispatchFlushCompleteEvent
173b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                    // method.
174b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                    env->CallVoidMethod(mReceiverObject,
175b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                                        gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
176b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                                        buffer[i].meta_data.sensor);
177b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                } else {
178b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                    env->CallVoidMethod(mReceiverObject,
179b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                                        gBaseEventQueueClassInfo.dispatchSensorEvent,
180b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                                        buffer[i].sensor,
181b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                                        mScratch,
182b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                                        buffer[i].vector.status,
183b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                                        buffer[i].timestamp);
184b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                }
185db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                if (env->ExceptionCheck()) {
18635187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella                    mSensorQueue->sendAck(buffer, n);
187db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                    ALOGE("Exception dispatching input event.");
188db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                    return 1;
189db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                }
190db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            }
19135187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella            mSensorQueue->sendAck(buffer, n);
192db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        }
193db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        if (n<0 && n != -EAGAIN) {
194db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            // FIXME: error receiving events, what to do in this case?
195db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        }
196db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        return 1;
1970b6d77bdeb99ca92709828c7c4867eec2f727f88Mathias Agopian    }
198db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian};
1991bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian
2004838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQ, jobject msgQ, jfloatArray scratch) {
201db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    SensorManager& mgr(SensorManager::getInstance());
202db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<SensorEventQueue> queue(mgr.createEventQueue());
203db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
204db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
205db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    if (messageQueue == NULL) {
206db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
207db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        return 0;
208db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    }
2091bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian
210db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQ, scratch);
211b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian    receiver->incStrong((void*)nativeInitSensorEventQueue);
2124838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat    return jlong(receiver.get());
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2154838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
216b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                               jint maxBatchReportLatency, jint reservedFlags) {
217db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
218b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
219b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                                                         reservedFlags);
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2224838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeDisableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle) {
223db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
224db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    return receiver->getSensorEventQueue()->disableSensor(handle);
225db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}
226db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
2274838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic void nativeDestroySensorEventQueue(JNIEnv *env, jclass clazz, jlong eventQ, jint handle) {
228db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
229db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    receiver->destroy();
230b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian    receiver->decStrong((void*)nativeInitSensorEventQueue);
231db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}
232db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
2334838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeFlushSensor(JNIEnv *env, jclass clazz, jlong eventQ) {
234b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
2354bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella    return receiver->getSensorEventQueue()->flush();
236b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella}
237db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
238db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian//----------------------------------------------------------------------------
239db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
240db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianstatic JNINativeMethod gSystemSensorManagerMethods[] = {
241db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    {"nativeClassInit",
242db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            "()V",
243db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeClassInit },
244db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
245db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    {"nativeGetNextSensor",
246db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            "(Landroid/hardware/Sensor;I)I",
247db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeGetNextSensor },
248db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian};
2491bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian
2509a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganeshstatic JNINativeMethod gBaseEventQueueMethods[] = {
2519a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh    {"nativeInitBaseEventQueue",
2524838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat            "(Landroid/hardware/SystemSensorManager$BaseEventQueue;Landroid/os/MessageQueue;[F)J",
253db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeInitSensorEventQueue },
2541bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian
255db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    {"nativeEnableSensor",
2564838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat            "(JIIII)I",
257db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeEnableSensor },
258db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
259db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    {"nativeDisableSensor",
2604838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat            "(JI)I",
261db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeDisableSensor },
262db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
263db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    {"nativeDestroySensorEventQueue",
2644838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat            "(J)V",
265db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeDestroySensorEventQueue },
266b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella
267b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    {"nativeFlushSensor",
2684838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat            "(J)I",
269b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella            (void*)nativeFlushSensor },
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android;
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
276db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#define FIND_CLASS(var, className) \
277db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        var = env->FindClass(className); \
278db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        LOG_FATAL_IF(! var, "Unable to find class " className); \
279db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        var = jclass(env->NewGlobalRef(var));
280db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
281db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
282db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
283db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        LOG_FATAL_IF(! var, "Unable to find method " methodName);
284db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_hardware_SensorManager(JNIEnv *env)
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
287db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager",
288db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));
289db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
2909a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh    jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$BaseEventQueue",
2919a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh            gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));
292db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
2939a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh    FIND_CLASS(gBaseEventQueueClassInfo.clazz, "android/hardware/SystemSensorManager$BaseEventQueue");
294db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
2959a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh    GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchSensorEvent,
2969a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh            gBaseEventQueueClassInfo.clazz,
297db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            "dispatchSensorEvent", "(I[FIJ)V");
298db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
299b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
300b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                  gBaseEventQueueClassInfo.clazz,
301b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                  "dispatchFlushCompleteEvent", "(I)V");
302b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella
303db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    return 0;
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
305