android_hardware_SensorManager.cpp revision bb9ba8bae551305acba4f60577b0f461a9421bc5
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    jfieldID    minDelay;
42} gSensorOffsets;
43
44/*
45 * The method below are not thread-safe and not intended to be
46 */
47
48
49static jint
50sensors_module_init(JNIEnv *env, jclass clazz)
51{
52    SensorManager::getInstance();
53    return 0;
54}
55
56static jint
57sensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next)
58{
59    SensorManager& mgr(SensorManager::getInstance());
60
61    Sensor const* const* sensorList;
62    size_t count = mgr.getSensorList(&sensorList);
63    if (size_t(next) >= count)
64        return -1;
65
66    Sensor const* const list = sensorList[next];
67    const SensorOffsets& sensorOffsets(gSensorOffsets);
68    jstring name = env->NewStringUTF(list->getName().string());
69    jstring vendor = env->NewStringUTF(list->getVendor().string());
70    env->SetObjectField(sensor, sensorOffsets.name,      name);
71    env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
72    env->SetIntField(sensor, sensorOffsets.version,      1);
73    env->SetIntField(sensor, sensorOffsets.handle,       list->getHandle());
74    env->SetIntField(sensor, sensorOffsets.type,         list->getType());
75    env->SetFloatField(sensor, sensorOffsets.range,      list->getMaxValue());
76    env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());
77    env->SetFloatField(sensor, sensorOffsets.power,      list->getPowerUsage());
78    env->SetIntField(sensor, sensorOffsets.minDelay,     list->getMinDelay());
79
80    next++;
81    return size_t(next) < count ? next : 0;
82}
83
84//----------------------------------------------------------------------------
85static jint
86sensors_create_queue(JNIEnv *env, jclass clazz)
87{
88    SensorManager& mgr(SensorManager::getInstance());
89    sp<SensorEventQueue> queue(mgr.createEventQueue());
90    queue->incStrong(clazz);
91    return reinterpret_cast<int>(queue.get());
92}
93
94static void
95sensors_destroy_queue(JNIEnv *env, jclass clazz, jint nativeQueue)
96{
97    sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
98    if (queue != 0) {
99        queue->decStrong(clazz);
100    }
101}
102
103static jboolean
104sensors_enable_sensor(JNIEnv *env, jclass clazz,
105        jint nativeQueue, jstring name, jint sensor, jint delay)
106{
107    sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
108    if (queue == 0) return JNI_FALSE;
109    status_t res;
110    if (delay >= 0) {
111        res = queue->enableSensor(sensor, delay);
112    } else {
113        res = queue->disableSensor(sensor);
114    }
115    return res == NO_ERROR ? true : false;
116}
117
118static jint
119sensors_data_poll(JNIEnv *env, jclass clazz, jint nativeQueue,
120        jfloatArray values, jintArray status, jlongArray timestamp)
121{
122    sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
123    if (queue == 0) return -1;
124
125    status_t res;
126    ASensorEvent event;
127
128    res = queue->read(&event, 1);
129    if (res == 0) {
130        res = queue->waitForEvent();
131        if (res != NO_ERROR)
132            return -1;
133        res = queue->read(&event, 1);
134    }
135    if (res < 0)
136        return -1;
137
138    jint accuracy = event.vector.status;
139    env->SetFloatArrayRegion(values, 0, 3, event.vector.v);
140    env->SetIntArrayRegion(status, 0, 1, &accuracy);
141    env->SetLongArrayRegion(timestamp, 0, 1, &event.timestamp);
142
143    return event.sensor;
144}
145
146static void
147nativeClassInit (JNIEnv *_env, jclass _this)
148{
149    jclass sensorClass = _env->FindClass("android/hardware/Sensor");
150    SensorOffsets& sensorOffsets = gSensorOffsets;
151    sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");
152    sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");
153    sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");
154    sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");
155    sensorOffsets.type        = _env->GetFieldID(sensorClass, "mType",      "I");
156    sensorOffsets.range       = _env->GetFieldID(sensorClass, "mMaxRange",  "F");
157    sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
158    sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
159    sensorOffsets.minDelay    = _env->GetFieldID(sensorClass, "mMinDelay",  "I");
160}
161
162static JNINativeMethod gMethods[] = {
163    {"nativeClassInit", "()V",              (void*)nativeClassInit },
164    {"sensors_module_init","()I",           (void*)sensors_module_init },
165    {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
166                                            (void*)sensors_module_get_next_sensor },
167
168    {"sensors_create_queue",  "()I",        (void*)sensors_create_queue },
169    {"sensors_destroy_queue", "(I)V",       (void*)sensors_destroy_queue },
170    {"sensors_enable_sensor", "(ILjava/lang/String;II)Z",
171                                            (void*)sensors_enable_sensor },
172
173    {"sensors_data_poll",  "(I[F[I[J)I",     (void*)sensors_data_poll },
174};
175
176}; // namespace android
177
178using namespace android;
179
180int register_android_hardware_SensorManager(JNIEnv *env)
181{
182    return jniRegisterNativeMethods(env, "android/hardware/SensorManager",
183            gMethods, NELEM(gMethods));
184}
185