blob: 75aa458035bdb0fa33a8fd62855014d3029ad2ac [file] [log] [blame]
/*
* Copyright 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "Sensors"
#include <hardware/sensors.h>
#include "jni.h"
#include "JNIHelp.h"
namespace android {
struct SensorOffsets
{
jfieldID name;
jfieldID vendor;
jfieldID version;
jfieldID handle;
jfieldID type;
jfieldID range;
jfieldID resolution;
jfieldID power;
} gSensorOffsets;
/*
* The method below are not thread-safe and not intended to be
*/
static sensors_module_t* sSensorModule = 0;
static sensors_data_device_t* sSensorDevice = 0;
static jint
sensors_module_init(JNIEnv *env, jclass clazz)
{
int err = 0;
sensors_module_t const* module;
err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (const hw_module_t **)&module);
if (err == 0)
sSensorModule = (sensors_module_t*)module;
return err;
}
static jint
sensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next)
{
if (sSensorModule == NULL)
return 0;
SensorOffsets& sensorOffsets = gSensorOffsets;
const struct sensor_t* list;
int count = sSensorModule->get_sensors_list(sSensorModule, &list);
if (next >= count)
return -1;
list += next;
jstring name = env->NewStringUTF(list->name);
jstring vendor = env->NewStringUTF(list->vendor);
env->SetObjectField(sensor, sensorOffsets.name, name);
env->SetObjectField(sensor, sensorOffsets.vendor, vendor);
env->SetIntField(sensor, sensorOffsets.version, list->version);
env->SetIntField(sensor, sensorOffsets.handle, list->handle);
env->SetIntField(sensor, sensorOffsets.type, list->type);
env->SetFloatField(sensor, sensorOffsets.range, list->maxRange);
env->SetFloatField(sensor, sensorOffsets.resolution, list->resolution);
env->SetFloatField(sensor, sensorOffsets.power, list->power);
next++;
return next<count ? next : 0;
}
//----------------------------------------------------------------------------
static jint
sensors_data_init(JNIEnv *env, jclass clazz)
{
if (sSensorModule == NULL)
return -1;
int err = sensors_data_open(&sSensorModule->common, &sSensorDevice);
return err;
}
static jint
sensors_data_uninit(JNIEnv *env, jclass clazz)
{
int err = 0;
if (sSensorDevice) {
err = sensors_data_close(sSensorDevice);
if (err == 0)
sSensorDevice = 0;
}
return err;
}
static jint
sensors_data_open(JNIEnv *env, jclass clazz, jobject fdo)
{
jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
jfieldID offset = env->GetFieldID(FileDescriptor, "descriptor", "I");
int fd = env->GetIntField(fdo, offset);
return sSensorDevice->data_open(sSensorDevice, fd); // doesn't take ownership of fd
}
static jint
sensors_data_close(JNIEnv *env, jclass clazz)
{
return sSensorDevice->data_close(sSensorDevice);
}
static jint
sensors_data_poll(JNIEnv *env, jclass clazz,
jfloatArray values, jintArray status, jlongArray timestamp)
{
sensors_data_t data;
int res = sSensorDevice->poll(sSensorDevice, &data);
if (res >= 0) {
jint accuracy = data.vector.status;
env->SetFloatArrayRegion(values, 0, 3, data.vector.v);
env->SetIntArrayRegion(status, 0, 1, &accuracy);
env->SetLongArrayRegion(timestamp, 0, 1, &data.time);
}
return res;
}
static void
nativeClassInit (JNIEnv *_env, jclass _this)
{
jclass sensorClass = _env->FindClass("android/hardware/Sensor");
SensorOffsets& sensorOffsets = gSensorOffsets;
sensorOffsets.name = _env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;");
sensorOffsets.vendor = _env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;");
sensorOffsets.version = _env->GetFieldID(sensorClass, "mVersion", "I");
sensorOffsets.handle = _env->GetFieldID(sensorClass, "mHandle", "I");
sensorOffsets.type = _env->GetFieldID(sensorClass, "mType", "I");
sensorOffsets.range = _env->GetFieldID(sensorClass, "mMaxRange", "F");
sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F");
sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F");
}
static JNINativeMethod gMethods[] = {
{"nativeClassInit", "()V", (void*)nativeClassInit },
{"sensors_module_init","()I", (void*)sensors_module_init },
{"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
(void*)sensors_module_get_next_sensor },
{"sensors_data_init", "()I", (void*)sensors_data_init },
{"sensors_data_uninit", "()I", (void*)sensors_data_uninit },
{"sensors_data_open", "(Ljava/io/FileDescriptor;)I", (void*)sensors_data_open },
{"sensors_data_close", "()I", (void*)sensors_data_close },
{"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll },
};
}; // namespace android
using namespace android;
int register_android_hardware_SensorManager(JNIEnv *env)
{
return jniRegisterNativeMethods(env, "android/hardware/SensorManager",
gMethods, NELEM(gMethods));
}