blob: 3c1b9c84cf4630b1e7e1bb2823874c4fb39031f4 [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
Mike Lockwood270e87f2009-05-22 10:02:14 -040019#include "utils/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
Mathias Agopian1bf79782010-07-14 23:41:37 -070021#include <gui/Sensor.h>
22#include <gui/SensorManager.h>
23#include <gui/SensorEventQueue.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;
Mathias Agopian050b5622010-07-29 16:51:38 -070041 jfieldID minDelay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042} gSensorOffsets;
43
44/*
45 * The method below are not thread-safe and not intended to be
46 */
47
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048
49static jint
50sensors_module_init(JNIEnv *env, jclass clazz)
51{
Mathias Agopian1bf79782010-07-14 23:41:37 -070052 SensorManager::getInstance();
53 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054}
55
56static jint
57sensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next)
58{
Mathias Agopian1bf79782010-07-14 23:41:37 -070059 SensorManager& mgr(SensorManager::getInstance());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
Mathias Agopian1bf79782010-07-14 23:41:37 -070061 Sensor const* const* sensorList;
62 size_t count = mgr.getSensorList(&sensorList);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -070063 if (size_t(next) >= count)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 return -1;
65
Mathias Agopian1bf79782010-07-14 23:41:37 -070066 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());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 env->SetObjectField(sensor, sensorOffsets.name, name);
71 env->SetObjectField(sensor, sensorOffsets.vendor, vendor);
Mathias Agopian277d1b22012-05-04 15:51:29 -070072 env->SetIntField(sensor, sensorOffsets.version, list->getVersion());
Mathias Agopian1bf79782010-07-14 23:41:37 -070073 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());
Mathias Agopian050b5622010-07-29 16:51:38 -070078 env->SetIntField(sensor, sensorOffsets.minDelay, list->getMinDelay());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
80 next++;
Jeff Brown4fe6c3e2010-09-13 23:17:30 -070081 return size_t(next) < count ? next : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082}
83
84//----------------------------------------------------------------------------
85static jint
Mathias Agopian1bf79782010-07-14 23:41:37 -070086sensors_create_queue(JNIEnv *env, jclass clazz)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087{
Mathias Agopian1bf79782010-07-14 23:41:37 -070088 SensorManager& mgr(SensorManager::getInstance());
89 sp<SensorEventQueue> queue(mgr.createEventQueue());
90 queue->incStrong(clazz);
91 return reinterpret_cast<int>(queue.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092}
93
Mathias Agopian1bf79782010-07-14 23:41:37 -070094static void
95sensors_destroy_queue(JNIEnv *env, jclass clazz, jint nativeQueue)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096{
Mathias Agopian1bf79782010-07-14 23:41:37 -070097 sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
98 if (queue != 0) {
99 queue->decStrong(clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101}
102
Mathias Agopian1bf79782010-07-14 23:41:37 -0700103static jboolean
104sensors_enable_sensor(JNIEnv *env, jclass clazz,
Mathias Agopian23e8de22010-07-21 15:59:50 -0700105 jint nativeQueue, jstring name, jint sensor, jint delay)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106{
Mathias Agopian1bf79782010-07-14 23:41:37 -0700107 sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
108 if (queue == 0) return JNI_FALSE;
109 status_t res;
Mathias Agopian23e8de22010-07-21 15:59:50 -0700110 if (delay >= 0) {
111 res = queue->enableSensor(sensor, delay);
Mathias Agopian1bf79782010-07-14 23:41:37 -0700112 } else {
113 res = queue->disableSensor(sensor);
Mike Lockwood270e87f2009-05-22 10:02:14 -0400114 }
Mathias Agopian1bf79782010-07-14 23:41:37 -0700115 return res == NO_ERROR ? true : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116}
117
118static jint
Mathias Agopian1bf79782010-07-14 23:41:37 -0700119sensors_data_poll(JNIEnv *env, jclass clazz, jint nativeQueue,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 jfloatArray values, jintArray status, jlongArray timestamp)
121{
Mathias Agopian1bf79782010-07-14 23:41:37 -0700122 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);
Mathias Agopianbb9ba8b2011-11-29 11:42:32 -0800129 if (res == 0) {
Mathias Agopian1bf79782010-07-14 23:41:37 -0700130 res = queue->waitForEvent();
131 if (res != NO_ERROR)
132 return -1;
Mathias Agopian0b6d77b2012-05-07 18:27:06 -0700133 // here we're guaranteed to have an event
Mathias Agopian1bf79782010-07-14 23:41:37 -0700134 res = queue->read(&event, 1);
Mathias Agopian0b6d77b2012-05-07 18:27:06 -0700135 ALOGE_IF(res==0, "sensors_data_poll: nothing to read after waitForEvent()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 }
Mathias Agopian0b6d77b2012-05-07 18:27:06 -0700137 if (res <= 0) {
Mathias Agopian1bf79782010-07-14 23:41:37 -0700138 return -1;
Mathias Agopian0b6d77b2012-05-07 18:27:06 -0700139 }
Mathias Agopian1bf79782010-07-14 23:41:37 -0700140
141 jint accuracy = event.vector.status;
142 env->SetFloatArrayRegion(values, 0, 3, event.vector.v);
143 env->SetIntArrayRegion(status, 0, 1, &accuracy);
144 env->SetLongArrayRegion(timestamp, 0, 1, &event.timestamp);
145
146 return event.sensor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147}
148
149static void
150nativeClassInit (JNIEnv *_env, jclass _this)
151{
152 jclass sensorClass = _env->FindClass("android/hardware/Sensor");
153 SensorOffsets& sensorOffsets = gSensorOffsets;
154 sensorOffsets.name = _env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;");
155 sensorOffsets.vendor = _env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;");
156 sensorOffsets.version = _env->GetFieldID(sensorClass, "mVersion", "I");
157 sensorOffsets.handle = _env->GetFieldID(sensorClass, "mHandle", "I");
158 sensorOffsets.type = _env->GetFieldID(sensorClass, "mType", "I");
159 sensorOffsets.range = _env->GetFieldID(sensorClass, "mMaxRange", "F");
160 sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F");
161 sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F");
Mathias Agopian050b5622010-07-29 16:51:38 -0700162 sensorOffsets.minDelay = _env->GetFieldID(sensorClass, "mMinDelay", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163}
164
165static JNINativeMethod gMethods[] = {
166 {"nativeClassInit", "()V", (void*)nativeClassInit },
167 {"sensors_module_init","()I", (void*)sensors_module_init },
168 {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
169 (void*)sensors_module_get_next_sensor },
Mathias Agopian1bf79782010-07-14 23:41:37 -0700170
171 {"sensors_create_queue", "()I", (void*)sensors_create_queue },
172 {"sensors_destroy_queue", "(I)V", (void*)sensors_destroy_queue },
173 {"sensors_enable_sensor", "(ILjava/lang/String;II)Z",
174 (void*)sensors_enable_sensor },
175
176 {"sensors_data_poll", "(I[F[I[J)I", (void*)sensors_data_poll },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177};
178
179}; // namespace android
180
181using namespace android;
182
183int register_android_hardware_SensorManager(JNIEnv *env)
184{
Jeff Brown25157e42012-04-16 12:13:05 -0700185 return jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 gMethods, NELEM(gMethods));
187}