blob: 3e27978ec02e8e2fc9a27a765286269c9badfc1a [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Mike Lockwood270e87f2009-05-22 10:02:14 -040017#define LOG_TAG "SensorManager"
18
19#define LOG_NDEBUG 0
20#include "utils/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021
22#include <hardware/sensors.h>
Mike Lockwood270e87f2009-05-22 10:02:14 -040023#include <cutils/native_handle.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
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
47static sensors_module_t* sSensorModule = 0;
48static sensors_data_device_t* sSensorDevice = 0;
49
50static jint
51sensors_module_init(JNIEnv *env, jclass clazz)
52{
53 int err = 0;
54 sensors_module_t const* module;
55 err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t **)&module);
56 if (err == 0)
57 sSensorModule = (sensors_module_t*)module;
58 return err;
59}
60
61static jint
62sensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next)
63{
64 if (sSensorModule == NULL)
65 return 0;
66
67 SensorOffsets& sensorOffsets = gSensorOffsets;
68 const struct sensor_t* list;
69 int count = sSensorModule->get_sensors_list(sSensorModule, &list);
70 if (next >= count)
71 return -1;
72
73 list += next;
74
75 jstring name = env->NewStringUTF(list->name);
76 jstring vendor = env->NewStringUTF(list->vendor);
77 env->SetObjectField(sensor, sensorOffsets.name, name);
78 env->SetObjectField(sensor, sensorOffsets.vendor, vendor);
79 env->SetIntField(sensor, sensorOffsets.version, list->version);
80 env->SetIntField(sensor, sensorOffsets.handle, list->handle);
81 env->SetIntField(sensor, sensorOffsets.type, list->type);
82 env->SetFloatField(sensor, sensorOffsets.range, list->maxRange);
83 env->SetFloatField(sensor, sensorOffsets.resolution, list->resolution);
84 env->SetFloatField(sensor, sensorOffsets.power, list->power);
85
86 next++;
87 return next<count ? next : 0;
88}
89
90//----------------------------------------------------------------------------
91static jint
92sensors_data_init(JNIEnv *env, jclass clazz)
93{
94 if (sSensorModule == NULL)
95 return -1;
96 int err = sensors_data_open(&sSensorModule->common, &sSensorDevice);
97 return err;
98}
99
100static jint
101sensors_data_uninit(JNIEnv *env, jclass clazz)
102{
103 int err = 0;
104 if (sSensorDevice) {
105 err = sensors_data_close(sSensorDevice);
106 if (err == 0)
107 sSensorDevice = 0;
108 }
109 return err;
110}
111
112static jint
Mike Lockwood270e87f2009-05-22 10:02:14 -0400113sensors_data_open(JNIEnv *env, jclass clazz, jobjectArray fdArray, jintArray intArray)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114{
115 jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
Mike Lockwood270e87f2009-05-22 10:02:14 -0400116 jfieldID fieldOffset = env->GetFieldID(FileDescriptor, "descriptor", "I");
117 int numFds = (fdArray ? env->GetArrayLength(fdArray) : 0);
118 int numInts = (intArray ? env->GetArrayLength(intArray) : 0);
119 native_handle_t* handle = native_handle_create(numFds, numInts);
120 int offset = 0;
121
122 for (int i = 0; i < numFds; i++) {
123 jobject fdo = env->GetObjectArrayElement(fdArray, i);
124 if (fdo) {
125 handle->data[offset++] = env->GetIntField(fdo, fieldOffset);
126 } else {
127 handle->data[offset++] = -1;
128 }
129 }
130 if (numInts > 0) {
131 jint* ints = env->GetIntArrayElements(intArray, 0);
132 for (int i = 0; i < numInts; i++) {
133 handle->data[offset++] = ints[i];
134 }
135 env->ReleaseIntArrayElements(intArray, ints, 0);
136 }
137
138 // doesn't take ownership of the native handle
139 return sSensorDevice->data_open(sSensorDevice, handle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140}
141
142static jint
143sensors_data_close(JNIEnv *env, jclass clazz)
144{
145 return sSensorDevice->data_close(sSensorDevice);
146}
147
148static jint
149sensors_data_poll(JNIEnv *env, jclass clazz,
150 jfloatArray values, jintArray status, jlongArray timestamp)
151{
152 sensors_data_t data;
153 int res = sSensorDevice->poll(sSensorDevice, &data);
154 if (res >= 0) {
155 jint accuracy = data.vector.status;
156 env->SetFloatArrayRegion(values, 0, 3, data.vector.v);
157 env->SetIntArrayRegion(status, 0, 1, &accuracy);
158 env->SetLongArrayRegion(timestamp, 0, 1, &data.time);
159 }
160 return res;
161}
162
163static void
164nativeClassInit (JNIEnv *_env, jclass _this)
165{
166 jclass sensorClass = _env->FindClass("android/hardware/Sensor");
167 SensorOffsets& sensorOffsets = gSensorOffsets;
168 sensorOffsets.name = _env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;");
169 sensorOffsets.vendor = _env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;");
170 sensorOffsets.version = _env->GetFieldID(sensorClass, "mVersion", "I");
171 sensorOffsets.handle = _env->GetFieldID(sensorClass, "mHandle", "I");
172 sensorOffsets.type = _env->GetFieldID(sensorClass, "mType", "I");
173 sensorOffsets.range = _env->GetFieldID(sensorClass, "mMaxRange", "F");
174 sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F");
175 sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F");
176}
177
178static JNINativeMethod gMethods[] = {
179 {"nativeClassInit", "()V", (void*)nativeClassInit },
180 {"sensors_module_init","()I", (void*)sensors_module_init },
181 {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
182 (void*)sensors_module_get_next_sensor },
183 {"sensors_data_init", "()I", (void*)sensors_data_init },
184 {"sensors_data_uninit", "()I", (void*)sensors_data_uninit },
Mike Lockwood270e87f2009-05-22 10:02:14 -0400185 {"sensors_data_open", "([Ljava/io/FileDescriptor;[I)I", (void*)sensors_data_open },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 {"sensors_data_close", "()I", (void*)sensors_data_close },
187 {"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll },
188};
189
190}; // namespace android
191
192using namespace android;
193
194int register_android_hardware_SensorManager(JNIEnv *env)
195{
196 return jniRegisterNativeMethods(env, "android/hardware/SensorManager",
197 gMethods, NELEM(gMethods));
198}