android_hardware_SensorManager.cpp revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
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 "Sensors"
18
19#include <hardware/sensors.h>
20
21#include "jni.h"
22#include "JNIHelp.h"
23
24
25namespace android {
26
27struct SensorOffsets
28{
29    jfieldID    name;
30    jfieldID    vendor;
31    jfieldID    version;
32    jfieldID    handle;
33    jfieldID    type;
34    jfieldID    range;
35    jfieldID    resolution;
36    jfieldID    power;
37} gSensorOffsets;
38
39/*
40 * The method below are not thread-safe and not intended to be
41 */
42
43static sensors_module_t* sSensorModule = 0;
44static sensors_data_device_t* sSensorDevice = 0;
45
46static jint
47sensors_module_init(JNIEnv *env, jclass clazz)
48{
49    int err = 0;
50    sensors_module_t const* module;
51    err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t **)&module);
52    if (err == 0)
53        sSensorModule = (sensors_module_t*)module;
54    return err;
55}
56
57static jint
58sensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next)
59{
60    if (sSensorModule == NULL)
61        return 0;
62
63    SensorOffsets& sensorOffsets = gSensorOffsets;
64    const struct sensor_t* list;
65    int count = sSensorModule->get_sensors_list(sSensorModule, &list);
66    if (next >= count)
67        return -1;
68
69    list += next;
70
71    jstring name = env->NewStringUTF(list->name);
72    jstring vendor = env->NewStringUTF(list->vendor);
73    env->SetObjectField(sensor, sensorOffsets.name,      name);
74    env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
75    env->SetIntField(sensor, sensorOffsets.version,      list->version);
76    env->SetIntField(sensor, sensorOffsets.handle,       list->handle);
77    env->SetIntField(sensor, sensorOffsets.type,         list->type);
78    env->SetFloatField(sensor, sensorOffsets.range,      list->maxRange);
79    env->SetFloatField(sensor, sensorOffsets.resolution, list->resolution);
80    env->SetFloatField(sensor, sensorOffsets.power,      list->power);
81
82    next++;
83    return next<count ? next : 0;
84}
85
86//----------------------------------------------------------------------------
87static jint
88sensors_data_init(JNIEnv *env, jclass clazz)
89{
90    if (sSensorModule == NULL)
91        return -1;
92    int err = sensors_data_open(&sSensorModule->common, &sSensorDevice);
93    return err;
94}
95
96static jint
97sensors_data_uninit(JNIEnv *env, jclass clazz)
98{
99    int err = 0;
100    if (sSensorDevice) {
101        err = sensors_data_close(sSensorDevice);
102        if (err == 0)
103            sSensorDevice = 0;
104    }
105    return err;
106}
107
108static jint
109sensors_data_open(JNIEnv *env, jclass clazz, jobject fdo)
110{
111    jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
112    jfieldID offset = env->GetFieldID(FileDescriptor, "descriptor", "I");
113    int fd = env->GetIntField(fdo, offset);
114    return sSensorDevice->data_open(sSensorDevice, fd); // doesn't take ownership of fd
115}
116
117static jint
118sensors_data_close(JNIEnv *env, jclass clazz)
119{
120    return sSensorDevice->data_close(sSensorDevice);
121}
122
123static jint
124sensors_data_poll(JNIEnv *env, jclass clazz,
125        jfloatArray values, jintArray status, jlongArray timestamp)
126{
127    sensors_data_t data;
128    int res = sSensorDevice->poll(sSensorDevice, &data);
129    if (res >= 0) {
130        jint accuracy = data.vector.status;
131        env->SetFloatArrayRegion(values, 0, 3, data.vector.v);
132        env->SetIntArrayRegion(status, 0, 1, &accuracy);
133        env->SetLongArrayRegion(timestamp, 0, 1, &data.time);
134    }
135    return res;
136}
137
138static void
139nativeClassInit (JNIEnv *_env, jclass _this)
140{
141    jclass sensorClass = _env->FindClass("android/hardware/Sensor");
142    SensorOffsets& sensorOffsets = gSensorOffsets;
143    sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");
144    sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");
145    sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");
146    sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");
147    sensorOffsets.type        = _env->GetFieldID(sensorClass, "mType",      "I");
148    sensorOffsets.range       = _env->GetFieldID(sensorClass, "mMaxRange",  "F");
149    sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
150    sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
151}
152
153static JNINativeMethod gMethods[] = {
154    {"nativeClassInit", "()V",              (void*)nativeClassInit },
155    {"sensors_module_init","()I",           (void*)sensors_module_init },
156    {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
157                                            (void*)sensors_module_get_next_sensor },
158    {"sensors_data_init", "()I",            (void*)sensors_data_init },
159    {"sensors_data_uninit", "()I",          (void*)sensors_data_uninit },
160    {"sensors_data_open",  "(Ljava/io/FileDescriptor;)I",  (void*)sensors_data_open },
161    {"sensors_data_close", "()I",           (void*)sensors_data_close },
162    {"sensors_data_poll",  "([F[I[J)I",     (void*)sensors_data_poll },
163};
164
165}; // namespace android
166
167using namespace android;
168
169int register_android_hardware_SensorManager(JNIEnv *env)
170{
171    return jniRegisterNativeMethods(env, "android/hardware/SensorManager",
172            gMethods, NELEM(gMethods));
173}
174