19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright 2008, The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
16270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood#define LOG_TAG "SensorManager"
17270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood
18d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "JNIHelp.h"
19d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "android_os_MessageQueue.h"
20d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "core_jni_helpers.h"
21d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include "jni.h"
229ba7c1c17567c19f0187d73cdca55ca99590674edestradaa
2388445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella#include <ScopedUtfChars.h>
243b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown#include <ScopedLocalRef.h>
25d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <android_runtime/AndroidRuntime.h>
26d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <gui/Sensor.h>
27d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <gui/SensorEventQueue.h>
28d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <gui/SensorManager.h>
29db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include <utils/Log.h>
30db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian#include <utils/Looper.h>
31a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu#include <utils/Vector.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33d5ec5f919dc835ca302d97c3cdc8f5b11f0584f0Peng Xu#include <map>
34987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe
354a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xunamespace {
364a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu
374a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xuusing namespace android;
384a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu
394a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xustruct {
40db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    jclass clazz;
41db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    jmethodID dispatchSensorEvent;
42b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    jmethodID dispatchFlushCompleteEvent;
43a29583553957a19755bfba26f48b6ebe977879cbPeng Xu    jmethodID dispatchAdditionalInfoEvent;
449a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh} gBaseEventQueueClassInfo;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct SensorOffsets
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
48a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    jclass      clazz;
49b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu    //fields
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    name;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    vendor;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    version;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    handle;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    range;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    resolution;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jfieldID    power;
57050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian    jfieldID    minDelay;
58b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    jfieldID    fifoReservedEventCount;
59b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    jfieldID    fifoMaxEventCount;
60cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    jfieldID    stringType;
61cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    jfieldID    requiredPermission;
622f8b91449efafa5fb0057cd0150233681c65c9e3Aravind Akella    jfieldID    maxDelay;
6327900358f2f5b89e8b01516b28a916d16c99ba9bAravind Akella    jfieldID    flags;
64b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu    //methods
659ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    jmethodID   setType;
66b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu    jmethodID   setUuid;
67a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    jmethodID   init;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gSensorOffsets;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
70a35b5539a95342799a18e95616c5e5751a198e4cPeng Xustruct ListOffsets {
71a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    jclass      clazz;
72a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    jmethodID   add;
73a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu} gListOffsets;
74db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
764a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu * nativeClassInit is not inteneded to be thread-safe. It should be called before other native...
774a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu * functions (except nativeCreate).
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
79db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianstatic void
80db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias AgopiannativeClassInit (JNIEnv *_env, jclass _this)
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
82a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    //android.hardware.Sensor
83db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    SensorOffsets& sensorOffsets = gSensorOffsets;
84a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    jclass sensorClass = (jclass) _env->NewGlobalRef(_env->FindClass("android/hardware/Sensor"));
85a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    sensorOffsets.clazz       = sensorClass;
86db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");
87db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");
88db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");
89db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.handle      = _env->GetFieldID(sensorClass, "mHandle",    "I");
90db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.range       = _env->GetFieldID(sensorClass, "mMaxRange",  "F");
91db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
92db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
93db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sensorOffsets.minDelay    = _env->GetFieldID(sensorClass, "mMinDelay",  "I");
94b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    sensorOffsets.fifoReservedEventCount =
95b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella            _env->GetFieldID(sensorClass, "mFifoReservedEventCount",  "I");
96b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount",  "I");
97cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    sensorOffsets.stringType = _env->GetFieldID(sensorClass, "mStringType", "Ljava/lang/String;");
98cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella    sensorOffsets.requiredPermission = _env->GetFieldID(sensorClass, "mRequiredPermission",
99cd9a7bb3ba742606f93dcbd549d6d6eeb1cb5247Aravind Akella                                                        "Ljava/lang/String;");
1002f8b91449efafa5fb0057cd0150233681c65c9e3Aravind Akella    sensorOffsets.maxDelay    = _env->GetFieldID(sensorClass, "mMaxDelay",  "I");
10127900358f2f5b89e8b01516b28a916d16c99ba9bAravind Akella    sensorOffsets.flags = _env->GetFieldID(sensorClass, "mFlags",  "I");
102a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
1039ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    sensorOffsets.setType = _env->GetMethodID(sensorClass, "setType", "(I)Z");
104b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu    sensorOffsets.setUuid = _env->GetMethodID(sensorClass, "setUuid", "(JJ)V");
105a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    sensorOffsets.init = _env->GetMethodID(sensorClass, "<init>", "()V");
106a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
107a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    // java.util.List;
108a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    ListOffsets& listOffsets = gListOffsets;
109a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    jclass listClass = (jclass) _env->NewGlobalRef(_env->FindClass("java/util/List"));
110a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    listOffsets.clazz = listClass;
111a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    listOffsets.add = _env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
1129ba7c1c17567c19f0187d73cdca55ca99590674edestradaa}
1139ba7c1c17567c19f0187d73cdca55ca99590674edestradaa
1149ba7c1c17567c19f0187d73cdca55ca99590674edestradaa/**
1159ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * A key comparator predicate.
1169ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * It is used to intern strings associated with Sensor data.
1179ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * It defines a 'Strict weak ordering' for the interned strings.
1189ba7c1c17567c19f0187d73cdca55ca99590674edestradaa */
1199ba7c1c17567c19f0187d73cdca55ca99590674edestradaaclass InternedStringCompare {
1209ba7c1c17567c19f0187d73cdca55ca99590674edestradaapublic:
1219ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    bool operator()(const String8* string1, const String8* string2) const {
1229ba7c1c17567c19f0187d73cdca55ca99590674edestradaa        if (string1 == NULL) {
1239ba7c1c17567c19f0187d73cdca55ca99590674edestradaa            return string2 != NULL;
1249ba7c1c17567c19f0187d73cdca55ca99590674edestradaa        }
12588445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella        if (string2 == NULL) {
12688445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella            return false;
12788445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella        }
1289ba7c1c17567c19f0187d73cdca55ca99590674edestradaa        return string1->compare(*string2) < 0;
1299ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    }
1309ba7c1c17567c19f0187d73cdca55ca99590674edestradaa};
1319ba7c1c17567c19f0187d73cdca55ca99590674edestradaa
1329ba7c1c17567c19f0187d73cdca55ca99590674edestradaa/**
1339ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * A localized interning mechanism for Sensor strings.
1349ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * We implement our own interning to avoid the overhead of using java.lang.String#intern().
1359ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * It is common that Vendor, StringType, and RequirePermission data is common between many of the
1369ba7c1c17567c19f0187d73cdca55ca99590674edestradaa * Sensors, by interning the memory usage to represent Sensors is optimized.
1379ba7c1c17567c19f0187d73cdca55ca99590674edestradaa */
1389ba7c1c17567c19f0187d73cdca55ca99590674edestradaastatic jstring
1399ba7c1c17567c19f0187d73cdca55ca99590674edestradaagetInternedString(JNIEnv *env, const String8* string) {
1409ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    static std::map<const String8*, jstring, InternedStringCompare> internedStrings;
1419ba7c1c17567c19f0187d73cdca55ca99590674edestradaa
1429ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    jstring internedString;
1439ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    std::map<const String8*, jstring>::iterator iterator = internedStrings.find(string);
1449ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    if (iterator != internedStrings.end()) {
1459ba7c1c17567c19f0187d73cdca55ca99590674edestradaa        internedString = iterator->second;
1469ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    } else {
1479ba7c1c17567c19f0187d73cdca55ca99590674edestradaa        jstring localString = env->NewStringUTF(string->string());
1489ba7c1c17567c19f0187d73cdca55ca99590674edestradaa        // we are implementing our own interning so expect these strings to be backed by global refs
1499ba7c1c17567c19f0187d73cdca55ca99590674edestradaa        internedString = (jstring) env->NewGlobalRef(localString);
1509ba7c1c17567c19f0187d73cdca55ca99590674edestradaa        internedStrings.insert(std::make_pair(string, internedString));
1519ba7c1c17567c19f0187d73cdca55ca99590674edestradaa        env->DeleteLocalRef(localString);
1529ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    }
1539ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    return internedString;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
156b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganovstatic jlong
157b9d71a6f89b1183f6389b1774652445a420c6cbfSvet GanovnativeCreate
158b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov(JNIEnv *env, jclass clazz, jstring opPackageName)
159b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov{
160b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov    ScopedUtfChars opPackageNameUtf(env, opPackageName);
1612af91d0e104b3a80f3e832e464e52893a55a715fAravind Akella    return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
162b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov}
163b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov
164a35b5539a95342799a18e95616c5e5751a198e4cPeng Xustatic jobject
165a35b5539a95342799a18e95616c5e5751a198e4cPeng XutranslateNativeSensorToJavaSensor(JNIEnv *env, jobject sensor, const Sensor& nativeSensor) {
166a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    const SensorOffsets& sensorOffsets(gSensorOffsets);
167a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
168a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    if (sensor == NULL) {
169a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        // Sensor sensor = new Sensor();
170a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        sensor = env->NewObject(sensorOffsets.clazz, sensorOffsets.init, "");
171a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    }
172a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
173a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    if (sensor != NULL) {
174a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        jstring name = env->NewStringUTF(nativeSensor.getName().string());
175a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        jstring vendor = env->NewStringUTF(nativeSensor.getVendor().string());
176a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        jstring requiredPermission =
177a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu                env->NewStringUTF(nativeSensor.getRequiredPermission().string());
178a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
179a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetObjectField(sensor, sensorOffsets.name,      name);
180a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
181a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetIntField(sensor, sensorOffsets.version,      nativeSensor.getVersion());
182a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetIntField(sensor, sensorOffsets.handle,       nativeSensor.getHandle());
183a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetFloatField(sensor, sensorOffsets.range,      nativeSensor.getMaxValue());
184a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetFloatField(sensor, sensorOffsets.resolution, nativeSensor.getResolution());
185a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetFloatField(sensor, sensorOffsets.power,      nativeSensor.getPowerUsage());
186a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetIntField(sensor, sensorOffsets.minDelay,     nativeSensor.getMinDelay());
187a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount,
188a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu                         nativeSensor.getFifoReservedEventCount());
189a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount,
190a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu                         nativeSensor.getFifoMaxEventCount());
191a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetObjectField(sensor, sensorOffsets.requiredPermission,
192a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu                            requiredPermission);
193a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetIntField(sensor, sensorOffsets.maxDelay, nativeSensor.getMaxDelay());
194a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->SetIntField(sensor, sensorOffsets.flags, nativeSensor.getFlags());
195b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu
196a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        if (env->CallBooleanMethod(sensor, sensorOffsets.setType, nativeSensor.getType())
197a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu                == JNI_FALSE) {
198a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu            jstring stringType = getInternedString(env, &nativeSensor.getStringType());
199a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu            env->SetObjectField(sensor, sensorOffsets.stringType, stringType);
200a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        }
201b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu
202716866d56542c267ccb686992de590ad04c84215Peng Xu        // TODO(b/29547335): Rename "setUuid" method to "setId".
203716866d56542c267ccb686992de590ad04c84215Peng Xu        int64_t id = nativeSensor.getId();
204716866d56542c267ccb686992de590ad04c84215Peng Xu        env->CallVoidMethod(sensor, sensorOffsets.setUuid, id, 0);
205a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    }
206a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    return sensor;
207a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu}
208a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
209516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akellastatic jboolean
210516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind AkellanativeGetSensorAtIndex(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensor, jint index)
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
212b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2141bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian    Sensor const* const* sensorList;
215a08c9f52db26fa78e33464b57cc0597981352270Peng Xu    ssize_t count = mgr->getSensorList(&sensorList);
216a08c9f52db26fa78e33464b57cc0597981352270Peng Xu    if (ssize_t(index) >= count) {
217516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella        return false;
2189ba7c1c17567c19f0187d73cdca55ca99590674edestradaa    }
219b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella
220b85b1fed45eef4c4a095c7697156054cd2acf4e1Peng Xu    return translateNativeSensorToJavaSensor(env, sensor, *sensorList[index]) != NULL;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
223a35b5539a95342799a18e95616c5e5751a198e4cPeng Xustatic void
224a35b5539a95342799a18e95616c5e5751a198e4cPeng XunativeGetDynamicSensors(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensorList) {
225a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
226a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
227a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    const ListOffsets& listOffsets(gListOffsets);
228a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
229a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    Vector<Sensor> nativeList;
230a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
231a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    mgr->getDynamicSensorList(nativeList);
232a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
233a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    ALOGI("DYNS native SensorManager.getDynamicSensorList return %d sensors", nativeList.size());
234a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    for (size_t i = 0; i < nativeList.size(); ++i) {
235a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        jobject sensor = translateNativeSensorToJavaSensor(env, NULL, nativeList[i]);
236a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        // add to list
237a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu        env->CallBooleanMethod(sensorList, listOffsets.add, sensor);
238a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    }
239a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu}
240a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
241d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akellastatic jboolean nativeIsDataInjectionEnabled(JNIEnv *_env, jclass _this, jlong sensorManager) {
242b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
243d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella    return mgr->isDataInjectionEnabled();
24418ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella}
24518ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//----------------------------------------------------------------------------
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
248db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianclass Receiver : public LooperCallback {
249db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<SensorEventQueue> mSensorQueue;
250db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<MessageQueue> mMessageQueue;
2513b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown    jobject mReceiverWeakGlobal;
252a29583553957a19755bfba26f48b6ebe977879cbPeng Xu    jfloatArray mFloatScratch;
253a29583553957a19755bfba26f48b6ebe977879cbPeng Xu    jintArray   mIntScratch;
254db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianpublic:
255db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    Receiver(const sp<SensorEventQueue>& sensorQueue,
256db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            const sp<MessageQueue>& messageQueue,
257a29583553957a19755bfba26f48b6ebe977879cbPeng Xu            jobject receiverWeak) {
258db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        JNIEnv* env = AndroidRuntime::getJNIEnv();
259db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mSensorQueue = sensorQueue;
260db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mMessageQueue = messageQueue;
2613b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown        mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak);
262a29583553957a19755bfba26f48b6ebe977879cbPeng Xu
263a29583553957a19755bfba26f48b6ebe977879cbPeng Xu        mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16));
264a29583553957a19755bfba26f48b6ebe977879cbPeng Xu        mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16));
265db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    }
266db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    ~Receiver() {
267db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        JNIEnv* env = AndroidRuntime::getJNIEnv();
2683b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown        env->DeleteGlobalRef(mReceiverWeakGlobal);
269a29583553957a19755bfba26f48b6ebe977879cbPeng Xu        env->DeleteGlobalRef(mFloatScratch);
270a29583553957a19755bfba26f48b6ebe977879cbPeng Xu        env->DeleteGlobalRef(mIntScratch);
271db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    }
272db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<SensorEventQueue> getSensorEventQueue() const {
273db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        return mSensorQueue;
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
276db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    void destroy() {
277db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mMessageQueue->getLooper()->removeFd( mSensorQueue->getFd() );
278270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood    }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
280db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianprivate:
281db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    virtual void onFirstRef() {
282db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        LooperCallback::onFirstRef();
283db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
284db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
286db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
287db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    virtual int handleEvent(int fd, int events, void* data) {
288db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        JNIEnv* env = AndroidRuntime::getJNIEnv();
289db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
2903b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown        ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
2913b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown
292db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        ssize_t n;
293db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        ASensorEvent buffer[16];
294db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        while ((n = q->read(buffer, 16)) > 0) {
295db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            for (int i=0 ; i<n ; i++) {
2960288ca63e3f0aee05ad2ede23564e04e53aca950Aravind Akella                if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
2973c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                    // step-counter returns a uint64, but the java API only deals with floats
2983c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                    float value = float(buffer[i].u64.step_counter);
299a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                    env->SetFloatArrayRegion(mFloatScratch, 0, 1, &value);
300a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu                } else if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
301a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu                    float value[2];
302a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu                    value[0] = buffer[i].dynamic_sensor_meta.connected ? 1.f: 0.f;
303a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu                    value[1] = float(buffer[i].dynamic_sensor_meta.handle);
304a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                    env->SetFloatArrayRegion(mFloatScratch, 0, 2, value);
305a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
306a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                    env->SetIntArrayRegion(mIntScratch, 0, 14,
307a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                                           buffer[i].additional_info.data_int32);
308a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                    env->SetFloatArrayRegion(mFloatScratch, 0, 14,
309a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                                             buffer[i].additional_info.data_float);
3103c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                } else {
311a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                    env->SetFloatArrayRegion(mFloatScratch, 0, 16, buffer[i].data);
3123c9c0918635143f373817fff1ce5131b995282cfJean-Baptiste Queru                }
313db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
314b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
315b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                    // This is a flush complete sensor event. Call dispatchFlushCompleteEvent
316b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                    // method.
3173b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                    if (receiverObj.get()) {
3183b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                        env->CallVoidMethod(receiverObj.get(),
3193b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                                            gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
3203b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                                            buffer[i].meta_data.sensor);
3213b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                    }
322a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
323a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                    // This is a flush complete sensor event. Call dispatchAdditionalInfoEvent
324a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                    // method.
325a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                    if (receiverObj.get()) {
326a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                        int type = buffer[i].additional_info.type;
327a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                        int serial = buffer[i].additional_info.serial;
328a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                        env->CallVoidMethod(receiverObj.get(),
329a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                                            gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent,
330a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                                            buffer[i].sensor,
331a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                                            type, serial,
332a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                                            mFloatScratch,
333a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                                            mIntScratch,
334a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                                            buffer[i].timestamp);
335a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                    }
336a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                }else {
337af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                    int8_t status;
338af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                    switch (buffer[i].type) {
339af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                    case SENSOR_TYPE_ORIENTATION:
340af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                    case SENSOR_TYPE_MAGNETIC_FIELD:
341af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                    case SENSOR_TYPE_ACCELEROMETER:
342af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                    case SENSOR_TYPE_GYROSCOPE:
343f38226ab40feadb63b9b0c48d148db919ecec7f4Aravind Akella                    case SENSOR_TYPE_GRAVITY:
344f38226ab40feadb63b9b0c48d148db919ecec7f4Aravind Akella                    case SENSOR_TYPE_LINEAR_ACCELERATION:
345af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                        status = buffer[i].vector.status;
346af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                        break;
347af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                    case SENSOR_TYPE_HEART_RATE:
348af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                        status = buffer[i].heart_rate.status;
349af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                        break;
350af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                    default:
351af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                        status = SENSOR_STATUS_ACCURACY_HIGH;
352af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                        break;
353af80510e85b301c8d8ba1e28e7edc7a0c9156a1aEtienne Le Grand                    }
3543b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                    if (receiverObj.get()) {
3553b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                        env->CallVoidMethod(receiverObj.get(),
3563b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                                            gBaseEventQueueClassInfo.dispatchSensorEvent,
3573b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                                            buffer[i].sensor,
358a29583553957a19755bfba26f48b6ebe977879cbPeng Xu                                            mFloatScratch,
3593b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                                            status,
3603b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                                            buffer[i].timestamp);
3613b4049e79b1ea2872891cc0e87146e146111d502Jeff Brown                    }
362b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella                }
363db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                if (env->ExceptionCheck()) {
36435187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella                    mSensorQueue->sendAck(buffer, n);
365db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                    ALOGE("Exception dispatching input event.");
366db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                    return 1;
367db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian                }
368db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            }
36935187bd5c1e40ea52a672c525411d05cbcdd6482Aravind Akella            mSensorQueue->sendAck(buffer, n);
370db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        }
371db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        if (n<0 && n != -EAGAIN) {
372db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            // FIXME: error receiving events, what to do in this case?
373db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        }
374db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        return 1;
3750b6d77bdeb99ca92709828c7c4867eec2f727f88Mathias Agopian    }
376db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian};
3771bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian
378b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganovstatic jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
379a29583553957a19755bfba26f48b6ebe977879cbPeng Xu        jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
380b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
38188445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella    ScopedUtfChars packageUtf(env, packageName);
38288445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella    String8 clientName(packageUtf.c_str());
383b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov    sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));
384db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
385db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
386db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    if (messageQueue == NULL) {
387db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
388db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian        return 0;
389db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    }
3901bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian
391a29583553957a19755bfba26f48b6ebe977879cbPeng Xu    sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);
392b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian    receiver->incStrong((void*)nativeInitSensorEventQueue);
3934838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat    return jlong(receiver.get());
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3964838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
39788445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella                               jint maxBatchReportLatency) {
398db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
399b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
40088445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella                                                         0);
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4034838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeDisableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle) {
404db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
405db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    return receiver->getSensorEventQueue()->disableSensor(handle);
406db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}
407db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
40818ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akellastatic void nativeDestroySensorEventQueue(JNIEnv *env, jclass clazz, jlong eventQ) {
409db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
410db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    receiver->destroy();
411b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian    receiver->decStrong((void*)nativeInitSensorEventQueue);
412db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian}
413db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
4144838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhatstatic jint nativeFlushSensor(JNIEnv *env, jclass clazz, jlong eventQ) {
415b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
4164bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella    return receiver->getSensorEventQueue()->flush();
417b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella}
418db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
41918ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akellastatic jint nativeInjectSensorData(JNIEnv *env, jclass clazz, jlong eventQ, jint handle,
42018ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella        jfloatArray values, jint accuracy, jlong timestamp) {
42118ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
42218ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella    // Create a sensor_event from the above data which can be injected into the HAL.
42318ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella    ASensorEvent sensor_event;
42418ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella    memset(&sensor_event, 0, sizeof(sensor_event));
42518ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella    sensor_event.sensor = handle;
42618ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella    sensor_event.timestamp = timestamp;
42718ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella    env->GetFloatArrayRegion(values, 0, env->GetArrayLength(values), sensor_event.data);
42818ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella    return receiver->getSensorEventQueue()->injectSensorEvent(sensor_event);
42918ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella}
430db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian//----------------------------------------------------------------------------
431db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
43276f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gSystemSensorManagerMethods[] = {
433db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    {"nativeClassInit",
434db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            "()V",
435db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeClassInit },
436b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov    {"nativeCreate",
437b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov             "(Ljava/lang/String;)J",
438b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov             (void*)nativeCreate },
439db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
440516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella    {"nativeGetSensorAtIndex",
441516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella            "(JLandroid/hardware/Sensor;I)Z",
442516e40ea5d73cf577d8dec559c7902b79cf483d0Aravind Akella            (void*)nativeGetSensorAtIndex },
44318ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella
444a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu    {"nativeGetDynamicSensors",
445a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu            "(JLjava/util/List;)V",
446a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu            (void*)nativeGetDynamicSensors },
447a35b5539a95342799a18e95616c5e5751a198e4cPeng Xu
448d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella    {"nativeIsDataInjectionEnabled",
449d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella            "(J)Z",
450d123b51f8b14047804612cb1b15288cca81ed4f9Aravind Akella            (void*)nativeIsDataInjectionEnabled},
451db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian};
4521bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian
45376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gBaseEventQueueMethods[] = {
4549a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh    {"nativeInitBaseEventQueue",
455a29583553957a19755bfba26f48b6ebe977879cbPeng Xu             "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J",
456b9d71a6f89b1183f6389b1774652445a420c6cbfSvet Ganov             (void*)nativeInitSensorEventQueue },
4571bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian
458db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    {"nativeEnableSensor",
45988445990b426499f25a9f37bc3b75f6e0267b4cbAravind Akella            "(JIII)I",
460db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeEnableSensor },
461db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
462db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    {"nativeDisableSensor",
4634838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat            "(JI)I",
464db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeDisableSensor },
465db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
466db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    {"nativeDestroySensorEventQueue",
4674838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat            "(J)V",
468db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            (void*)nativeDestroySensorEventQueue },
469b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella
470b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella    {"nativeFlushSensor",
4714838e338129e09a37b8c8ad5e44f85ec5cd3aea1Ashok Bhat            "(J)I",
472b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella            (void*)nativeFlushSensor },
47318ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella
47418ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella    {"nativeInjectSensorData",
47518ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella            "(JI[FIJ)I",
47618ebf732b84d0575c871db35b25bf000e0c7c6a6Aravind Akella            (void*)nativeInjectSensorData },
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4794a4baef431195f3f0a7ce3ea8b8bc316ed68228cPeng Xu} //unnamed namespace
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_hardware_SensorManager(JNIEnv *env)
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
483987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager",
484db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian            gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));
485db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
486987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager$BaseEventQueue",
4879a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh            gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));
488db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
489987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    gBaseEventQueueClassInfo.clazz = FindClassOrDie(env,
490987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe            "android/hardware/SystemSensorManager$BaseEventQueue");
491db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
492987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    gBaseEventQueueClassInfo.dispatchSensorEvent = GetMethodIDOrDie(env,
493987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe            gBaseEventQueueClassInfo.clazz, "dispatchSensorEvent", "(I[FIJ)V");
494db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian
495987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe    gBaseEventQueueClassInfo.dispatchFlushCompleteEvent = GetMethodIDOrDie(env,
496987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe            gBaseEventQueueClassInfo.clazz, "dispatchFlushCompleteEvent", "(I)V");
497b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella
498a29583553957a19755bfba26f48b6ebe977879cbPeng Xu    gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent = GetMethodIDOrDie(env,
499a29583553957a19755bfba26f48b6ebe977879cbPeng Xu            gBaseEventQueueClassInfo.clazz, "dispatchAdditionalInfoEvent", "(III[F[I)V");
500a29583553957a19755bfba26f48b6ebe977879cbPeng Xu
501db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian    return 0;
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
503