android_hardware_SensorManager.cpp revision 1bf797857e025e8a71db86fb9e79765a767ec1eb
1/*
2 * Copyright 2008, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "SensorManager"
18
19#include "utils/Log.h"
20
21#include <gui/Sensor.h>
22#include <gui/SensorManager.h>
23#include <gui/SensorEventQueue.h>
24
25#include "jni.h"
26#include "JNIHelp.h"
27
28
29namespace android {
30
31struct SensorOffsets
32{
33    jfieldID    name;
34    jfieldID    vendor;
35    jfieldID    version;
36    jfieldID    handle;
37    jfieldID    type;
38    jfieldID    range;
39    jfieldID    resolution;
40    jfieldID    power;
41} gSensorOffsets;
42
43/*
44 * The method below are not thread-safe and not intended to be
45 */
46
47
48static jint
49sensors_module_init(JNIEnv *env, jclass clazz)
50{
51    SensorManager::getInstance();
52    return 0;
53}
54
55static jint
56sensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next)
57{
58    SensorManager& mgr(SensorManager::getInstance());
59
60    Sensor const* const* sensorList;
61    size_t count = mgr.getSensorList(&sensorList);
62    if (next >= count)
63        return -1;
64
65    Sensor const* const list = sensorList[next];
66    const SensorOffsets& sensorOffsets(gSensorOffsets);
67    jstring name = env->NewStringUTF(list->getName().string());
68    jstring vendor = env->NewStringUTF(list->getVendor().string());
69    env->SetObjectField(sensor, sensorOffsets.name,      name);
70    env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
71    env->SetIntField(sensor, sensorOffsets.version,      1);
72    env->SetIntField(sensor, sensorOffsets.handle,       list->getHandle());
73    env->SetIntField(sensor, sensorOffsets.type,         list->getType());
74    env->SetFloatField(sensor, sensorOffsets.range,      list->getMaxValue());
75    env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());
76    env->SetFloatField(sensor, sensorOffsets.power,      list->getPowerUsage());
77
78    next++;
79    return next<count ? next : 0;
80}
81
82//----------------------------------------------------------------------------
83static jint
84sensors_create_queue(JNIEnv *env, jclass clazz)
85{
86    SensorManager& mgr(SensorManager::getInstance());
87    sp<SensorEventQueue> queue(mgr.createEventQueue());
88    queue->incStrong(clazz);
89    return reinterpret_cast<int>(queue.get());
90}
91
92static void
93sensors_destroy_queue(JNIEnv *env, jclass clazz, jint nativeQueue)
94{
95    sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
96    if (queue != 0) {
97        queue->decStrong(clazz);
98    }
99}
100
101static jboolean
102sensors_enable_sensor(JNIEnv *env, jclass clazz,
103        jint nativeQueue, jstring name, jint sensor, jint enable)
104{
105    sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
106    if (queue == 0) return JNI_FALSE;
107    status_t res;
108    if (enable) {
109        res = queue->enableSensor(sensor);
110    } else {
111        res = queue->disableSensor(sensor);
112    }
113    return res == NO_ERROR ? true : false;
114}
115
116static jint
117sensors_data_poll(JNIEnv *env, jclass clazz, jint nativeQueue,
118        jfloatArray values, jintArray status, jlongArray timestamp)
119{
120    sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
121    if (queue == 0) return -1;
122
123    status_t res;
124    ASensorEvent event;
125
126    res = queue->read(&event, 1);
127    if (res == -EAGAIN) {
128        res = queue->waitForEvent();
129        if (res != NO_ERROR)
130            return -1;
131        res = queue->read(&event, 1);
132    }
133    if (res < 0)
134        return -1;
135
136    jint accuracy = event.vector.status;
137    env->SetFloatArrayRegion(values, 0, 3, event.vector.v);
138    env->SetIntArrayRegion(status, 0, 1, &accuracy);
139    env->SetLongArrayRegion(timestamp, 0, 1, &event.timestamp);
140
141    return event.sensor;
142}
143
144static void
145nativeClassInit (JNIEnv *_env, jclass _this)
146{
147    jclass sensorClass = _env->FindClass("android/hardware/Sensor");
148    SensorOffsets& sensorOffsets = gSensorOffsets;
149    sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");
150    sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");
151    sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");
152    sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");
153    sensorOffsets.type        = _env->GetFieldID(sensorClass, "mType",      "I");
154    sensorOffsets.range       = _env->GetFieldID(sensorClass, "mMaxRange",  "F");
155    sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
156    sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
157}
158
159static JNINativeMethod gMethods[] = {
160    {"nativeClassInit", "()V",              (void*)nativeClassInit },
161    {"sensors_module_init","()I",           (void*)sensors_module_init },
162    {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
163                                            (void*)sensors_module_get_next_sensor },
164
165    {"sensors_create_queue",  "()I",        (void*)sensors_create_queue },
166    {"sensors_destroy_queue", "(I)V",       (void*)sensors_destroy_queue },
167    {"sensors_enable_sensor", "(ILjava/lang/String;II)Z",
168                                            (void*)sensors_enable_sensor },
169
170    {"sensors_data_poll",  "(I[F[I[J)I",     (void*)sensors_data_poll },
171};
172
173}; // namespace android
174
175using namespace android;
176
177int register_android_hardware_SensorManager(JNIEnv *env)
178{
179    return jniRegisterNativeMethods(env, "android/hardware/SensorManager",
180            gMethods, NELEM(gMethods));
181}
182