Home | History | Annotate | Download | only in jni
      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 <gui/Sensor.h>
     22 #include <gui/SensorManager.h>
     23 #include <gui/SensorEventQueue.h>
     24 
     25 #include "jni.h"
     26 #include "JNIHelp.h"
     27 
     28 
     29 namespace android {
     30 
     31 struct 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     jfieldID    minDelay;
     42 } gSensorOffsets;
     43 
     44 /*
     45  * The method below are not thread-safe and not intended to be
     46  */
     47 
     48 
     49 static jint
     50 sensors_module_init(JNIEnv *env, jclass clazz)
     51 {
     52     SensorManager::getInstance();
     53     return 0;
     54 }
     55 
     56 static jint
     57 sensors_module_get_next_sensor(JNIEnv *env, jobject clazz, jobject sensor, jint next)
     58 {
     59     SensorManager& mgr(SensorManager::getInstance());
     60 
     61     Sensor const* const* sensorList;
     62     size_t count = mgr.getSensorList(&sensorList);
     63     if (size_t(next) >= count)
     64         return -1;
     65 
     66     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());
     70     env->SetObjectField(sensor, sensorOffsets.name,      name);
     71     env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
     72     env->SetIntField(sensor, sensorOffsets.version,      1);
     73     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());
     78     env->SetIntField(sensor, sensorOffsets.minDelay,     list->getMinDelay());
     79 
     80     next++;
     81     return size_t(next) < count ? next : 0;
     82 }
     83 
     84 //----------------------------------------------------------------------------
     85 static jint
     86 sensors_create_queue(JNIEnv *env, jclass clazz)
     87 {
     88     SensorManager& mgr(SensorManager::getInstance());
     89     sp<SensorEventQueue> queue(mgr.createEventQueue());
     90     queue->incStrong(clazz);
     91     return reinterpret_cast<int>(queue.get());
     92 }
     93 
     94 static void
     95 sensors_destroy_queue(JNIEnv *env, jclass clazz, jint nativeQueue)
     96 {
     97     sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
     98     if (queue != 0) {
     99         queue->decStrong(clazz);
    100     }
    101 }
    102 
    103 static jboolean
    104 sensors_enable_sensor(JNIEnv *env, jclass clazz,
    105         jint nativeQueue, jstring name, jint sensor, jint delay)
    106 {
    107     sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));
    108     if (queue == 0) return JNI_FALSE;
    109     status_t res;
    110     if (delay >= 0) {
    111         res = queue->enableSensor(sensor, delay);
    112     } else {
    113         res = queue->disableSensor(sensor);
    114     }
    115     return res == NO_ERROR ? true : false;
    116 }
    117 
    118 static jint
    119 sensors_data_poll(JNIEnv *env, jclass clazz, jint nativeQueue,
    120         jfloatArray values, jintArray status, jlongArray timestamp)
    121 {
    122     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);
    129     if (res == -EAGAIN) {
    130         res = queue->waitForEvent();
    131         if (res != NO_ERROR)
    132             return -1;
    133         res = queue->read(&event, 1);
    134     }
    135     if (res < 0)
    136         return -1;
    137 
    138     jint accuracy = event.vector.status;
    139     env->SetFloatArrayRegion(values, 0, 3, event.vector.v);
    140     env->SetIntArrayRegion(status, 0, 1, &accuracy);
    141     env->SetLongArrayRegion(timestamp, 0, 1, &event.timestamp);
    142 
    143     return event.sensor;
    144 }
    145 
    146 static void
    147 nativeClassInit (JNIEnv *_env, jclass _this)
    148 {
    149     jclass sensorClass = _env->FindClass("android/hardware/Sensor");
    150     SensorOffsets& sensorOffsets = gSensorOffsets;
    151     sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");
    152     sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");
    153     sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");
    154     sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");
    155     sensorOffsets.type        = _env->GetFieldID(sensorClass, "mType",      "I");
    156     sensorOffsets.range       = _env->GetFieldID(sensorClass, "mMaxRange",  "F");
    157     sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
    158     sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
    159     sensorOffsets.minDelay    = _env->GetFieldID(sensorClass, "mMinDelay",  "I");
    160 }
    161 
    162 static JNINativeMethod gMethods[] = {
    163     {"nativeClassInit", "()V",              (void*)nativeClassInit },
    164     {"sensors_module_init","()I",           (void*)sensors_module_init },
    165     {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
    166                                             (void*)sensors_module_get_next_sensor },
    167 
    168     {"sensors_create_queue",  "()I",        (void*)sensors_create_queue },
    169     {"sensors_destroy_queue", "(I)V",       (void*)sensors_destroy_queue },
    170     {"sensors_enable_sensor", "(ILjava/lang/String;II)Z",
    171                                             (void*)sensors_enable_sensor },
    172 
    173     {"sensors_data_poll",  "(I[F[I[J)I",     (void*)sensors_data_poll },
    174 };
    175 
    176 }; // namespace android
    177 
    178 using namespace android;
    179 
    180 int register_android_hardware_SensorManager(JNIEnv *env)
    181 {
    182     return jniRegisterNativeMethods(env, "android/hardware/SensorManager",
    183             gMethods, NELEM(gMethods));
    184 }
    185