android_hardware_SensorManager.cpp revision 270e87f71abc2edf446dbec20c725c823e8c7f37
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#define LOG_NDEBUG 0 20#include "utils/Log.h" 21 22#include <hardware/sensors.h> 23#include <cutils/native_handle.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 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 113sensors_data_open(JNIEnv *env, jclass clazz, jobjectArray fdArray, jintArray intArray) 114{ 115 jclass FileDescriptor = env->FindClass("java/io/FileDescriptor"); 116 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); 140} 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 }, 185 {"sensors_data_open", "([Ljava/io/FileDescriptor;[I)I", (void*)sensors_data_open }, 186 {"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} 199