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