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 #define LOG_TAG "SensorManager"
17 
18 #include <nativehelper/JNIHelp.h>
19 #include "android_os_MessageQueue.h"
20 #include "core_jni_helpers.h"
21 #include "jni.h"
22 
23 #include <nativehelper/ScopedUtfChars.h>
24 #include <nativehelper/ScopedLocalRef.h>
25 #include <android_runtime/AndroidRuntime.h>
26 #include <android_runtime/android_hardware_HardwareBuffer.h>
27 #include <vndk/hardware_buffer.h>
28 #include <sensor/Sensor.h>
29 #include <sensor/SensorEventQueue.h>
30 #include <sensor/SensorManager.h>
31 #include <cutils/native_handle.h>
32 #include <utils/Log.h>
33 #include <utils/Looper.h>
34 #include <utils/Vector.h>
35 
36 #include <map>
37 
38 namespace {
39 
40 using namespace android;
41 
42 struct {
43     jclass clazz;
44     jmethodID dispatchSensorEvent;
45     jmethodID dispatchFlushCompleteEvent;
46     jmethodID dispatchAdditionalInfoEvent;
47 } gBaseEventQueueClassInfo;
48 
49 struct SensorOffsets
50 {
51     jclass      clazz;
52     //fields
53     jfieldID    name;
54     jfieldID    vendor;
55     jfieldID    version;
56     jfieldID    handle;
57     jfieldID    range;
58     jfieldID    resolution;
59     jfieldID    power;
60     jfieldID    minDelay;
61     jfieldID    fifoReservedEventCount;
62     jfieldID    fifoMaxEventCount;
63     jfieldID    stringType;
64     jfieldID    requiredPermission;
65     jfieldID    maxDelay;
66     jfieldID    flags;
67     //methods
68     jmethodID   setType;
69     jmethodID   setUuid;
70     jmethodID   init;
71 } gSensorOffsets;
72 
73 struct ListOffsets {
74     jclass      clazz;
75     jmethodID   add;
76 } gListOffsets;
77 
78 struct StringOffsets {
79     jclass      clazz;
80     jmethodID   intern;
81     jstring     emptyString;
82 } gStringOffsets;
83 
84 /*
85  * nativeClassInit is not inteneded to be thread-safe. It should be called before other native...
86  * functions (except nativeCreate).
87  */
88 static void
nativeClassInit(JNIEnv * _env,jclass _this)89 nativeClassInit (JNIEnv *_env, jclass _this)
90 {
91     //android.hardware.Sensor
92     SensorOffsets& sensorOffsets = gSensorOffsets;
93     jclass sensorClass = (jclass)
94             MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "android/hardware/Sensor"));
95     sensorOffsets.clazz = sensorClass;
96     sensorOffsets.name = GetFieldIDOrDie(_env, sensorClass, "mName", "Ljava/lang/String;");
97     sensorOffsets.vendor = GetFieldIDOrDie(_env, sensorClass, "mVendor", "Ljava/lang/String;");
98     sensorOffsets.version = GetFieldIDOrDie(_env, sensorClass, "mVersion", "I");
99     sensorOffsets.handle = GetFieldIDOrDie(_env, sensorClass, "mHandle", "I");
100     sensorOffsets.range = GetFieldIDOrDie(_env, sensorClass, "mMaxRange", "F");
101     sensorOffsets.resolution = GetFieldIDOrDie(_env, sensorClass, "mResolution","F");
102     sensorOffsets.power = GetFieldIDOrDie(_env, sensorClass, "mPower", "F");
103     sensorOffsets.minDelay = GetFieldIDOrDie(_env, sensorClass, "mMinDelay", "I");
104     sensorOffsets.fifoReservedEventCount =
105             GetFieldIDOrDie(_env,sensorClass, "mFifoReservedEventCount", "I");
106     sensorOffsets.fifoMaxEventCount = GetFieldIDOrDie(_env,sensorClass, "mFifoMaxEventCount", "I");
107     sensorOffsets.stringType =
108             GetFieldIDOrDie(_env,sensorClass, "mStringType", "Ljava/lang/String;");
109     sensorOffsets.requiredPermission =
110             GetFieldIDOrDie(_env,sensorClass, "mRequiredPermission", "Ljava/lang/String;");
111     sensorOffsets.maxDelay = GetFieldIDOrDie(_env,sensorClass, "mMaxDelay", "I");
112     sensorOffsets.flags = GetFieldIDOrDie(_env,sensorClass, "mFlags", "I");
113 
114     sensorOffsets.setType = GetMethodIDOrDie(_env,sensorClass, "setType", "(I)Z");
115     sensorOffsets.setUuid = GetMethodIDOrDie(_env,sensorClass, "setUuid", "(JJ)V");
116     sensorOffsets.init = GetMethodIDOrDie(_env,sensorClass, "<init>", "()V");
117 
118     // java.util.List;
119     ListOffsets& listOffsets = gListOffsets;
120     jclass listClass = (jclass) MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "java/util/List"));
121     listOffsets.clazz = listClass;
122     listOffsets.add = GetMethodIDOrDie(_env,listClass, "add", "(Ljava/lang/Object;)Z");
123 
124     // initialize java.lang.String and empty string intern
125     StringOffsets& stringOffsets = gStringOffsets;
126     stringOffsets.clazz = MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "java/lang/String"));
127     stringOffsets.intern =
128             GetMethodIDOrDie(_env, stringOffsets.clazz, "intern", "()Ljava/lang/String;");
129     ScopedLocalRef<jstring> empty(_env, _env->NewStringUTF(""));
130     stringOffsets.emptyString = (jstring)
131             MakeGlobalRefOrDie(_env, _env->CallObjectMethod(empty.get(), stringOffsets.intern));
132 }
133 
getJavaInternedString(JNIEnv * env,const String8 & string)134 static jstring getJavaInternedString(JNIEnv *env, const String8 &string) {
135     if (string == "") {
136         return gStringOffsets.emptyString;
137     }
138 
139     ScopedLocalRef<jstring> javaString(env, env->NewStringUTF(string.string()));
140     jstring internedString = (jstring)
141             env->CallObjectMethod(javaString.get(), gStringOffsets.intern);
142     return internedString;
143 }
144 
145 static jlong
nativeCreate(JNIEnv * env,jclass clazz,jstring opPackageName)146 nativeCreate
147 (JNIEnv *env, jclass clazz, jstring opPackageName)
148 {
149     ScopedUtfChars opPackageNameUtf(env, opPackageName);
150     return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
151 }
152 
153 static jobject
translateNativeSensorToJavaSensor(JNIEnv * env,jobject sensor,const Sensor & nativeSensor)154 translateNativeSensorToJavaSensor(JNIEnv *env, jobject sensor, const Sensor& nativeSensor) {
155     const SensorOffsets& sensorOffsets(gSensorOffsets);
156 
157     if (sensor == NULL) {
158         // Sensor sensor = new Sensor();
159         sensor = env->NewObject(sensorOffsets.clazz, sensorOffsets.init, "");
160     }
161 
162     if (sensor != NULL) {
163         jstring name = getJavaInternedString(env, nativeSensor.getName());
164         jstring vendor = getJavaInternedString(env, nativeSensor.getVendor());
165         jstring requiredPermission =
166                 getJavaInternedString(env, nativeSensor.getRequiredPermission());
167 
168         env->SetObjectField(sensor, sensorOffsets.name,      name);
169         env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
170         env->SetIntField(sensor, sensorOffsets.version,      nativeSensor.getVersion());
171         env->SetIntField(sensor, sensorOffsets.handle,       nativeSensor.getHandle());
172         env->SetFloatField(sensor, sensorOffsets.range,      nativeSensor.getMaxValue());
173         env->SetFloatField(sensor, sensorOffsets.resolution, nativeSensor.getResolution());
174         env->SetFloatField(sensor, sensorOffsets.power,      nativeSensor.getPowerUsage());
175         env->SetIntField(sensor, sensorOffsets.minDelay,     nativeSensor.getMinDelay());
176         env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount,
177                          nativeSensor.getFifoReservedEventCount());
178         env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount,
179                          nativeSensor.getFifoMaxEventCount());
180         env->SetObjectField(sensor, sensorOffsets.requiredPermission,
181                             requiredPermission);
182         env->SetIntField(sensor, sensorOffsets.maxDelay, nativeSensor.getMaxDelay());
183         env->SetIntField(sensor, sensorOffsets.flags, nativeSensor.getFlags());
184 
185         if (env->CallBooleanMethod(sensor, sensorOffsets.setType, nativeSensor.getType())
186                 == JNI_FALSE) {
187             jstring stringType = getJavaInternedString(env, nativeSensor.getStringType());
188             env->SetObjectField(sensor, sensorOffsets.stringType, stringType);
189         }
190 
191         // TODO(b/29547335): Rename "setUuid" method to "setId".
192         int64_t id = nativeSensor.getId();
193         env->CallVoidMethod(sensor, sensorOffsets.setUuid, id, 0);
194     }
195     return sensor;
196 }
197 
198 static jboolean
nativeGetSensorAtIndex(JNIEnv * env,jclass clazz,jlong sensorManager,jobject sensor,jint index)199 nativeGetSensorAtIndex(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensor, jint index)
200 {
201     SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
202 
203     Sensor const* const* sensorList;
204     ssize_t count = mgr->getSensorList(&sensorList);
205     if (ssize_t(index) >= count) {
206         return false;
207     }
208 
209     return translateNativeSensorToJavaSensor(env, sensor, *sensorList[index]) != NULL;
210 }
211 
212 static void
nativeGetDynamicSensors(JNIEnv * env,jclass clazz,jlong sensorManager,jobject sensorList)213 nativeGetDynamicSensors(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensorList) {
214 
215     SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
216     const ListOffsets& listOffsets(gListOffsets);
217 
218     Vector<Sensor> nativeList;
219 
220     mgr->getDynamicSensorList(nativeList);
221 
222     ALOGI("DYNS native SensorManager.getDynamicSensorList return %zu sensors", nativeList.size());
223     for (size_t i = 0; i < nativeList.size(); ++i) {
224         jobject sensor = translateNativeSensorToJavaSensor(env, NULL, nativeList[i]);
225         // add to list
226         env->CallBooleanMethod(sensorList, listOffsets.add, sensor);
227     }
228 }
229 
nativeIsDataInjectionEnabled(JNIEnv * _env,jclass _this,jlong sensorManager)230 static jboolean nativeIsDataInjectionEnabled(JNIEnv *_env, jclass _this, jlong sensorManager) {
231     SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
232     return mgr->isDataInjectionEnabled();
233 }
234 
nativeCreateDirectChannel(JNIEnv * _env,jclass _this,jlong sensorManager,jlong size,jint channelType,jint fd,jobject hardwareBufferObj)235 static jint nativeCreateDirectChannel(JNIEnv *_env, jclass _this, jlong sensorManager,
236         jlong size, jint channelType, jint fd, jobject hardwareBufferObj) {
237     const native_handle_t *nativeHandle = nullptr;
238     NATIVE_HANDLE_DECLARE_STORAGE(ashmemHandle, 1, 0);
239 
240     if (channelType == SENSOR_DIRECT_MEM_TYPE_ASHMEM) {
241         native_handle_t *handle = native_handle_init(ashmemHandle, 1, 0);
242         handle->data[0] = fd;
243         nativeHandle = handle;
244     } else if (channelType == SENSOR_DIRECT_MEM_TYPE_GRALLOC) {
245         AHardwareBuffer *hardwareBuffer =
246                 android_hardware_HardwareBuffer_getNativeHardwareBuffer(_env, hardwareBufferObj);
247         if (hardwareBuffer != nullptr) {
248             nativeHandle = AHardwareBuffer_getNativeHandle(hardwareBuffer);
249         }
250     }
251 
252     if (nativeHandle == nullptr) {
253         return BAD_VALUE;
254     }
255 
256     SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
257     return mgr->createDirectChannel(size, channelType, nativeHandle);
258 }
259 
nativeDestroyDirectChannel(JNIEnv * _env,jclass _this,jlong sensorManager,jint channelHandle)260 static void nativeDestroyDirectChannel(JNIEnv *_env, jclass _this, jlong sensorManager,
261         jint channelHandle) {
262     SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
263     mgr->destroyDirectChannel(channelHandle);
264 }
265 
nativeConfigDirectChannel(JNIEnv * _env,jclass _this,jlong sensorManager,jint channelHandle,jint sensorHandle,jint rate)266 static jint nativeConfigDirectChannel(JNIEnv *_env, jclass _this, jlong sensorManager,
267         jint channelHandle, jint sensorHandle, jint rate) {
268     SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
269     return mgr->configureDirectChannel(channelHandle, sensorHandle, rate);
270 }
271 
nativeSetOperationParameter(JNIEnv * _env,jclass _this,jlong sensorManager,jint handle,jint type,jfloatArray floats,jintArray ints)272 static jint nativeSetOperationParameter(JNIEnv *_env, jclass _this, jlong sensorManager,
273         jint handle, jint type, jfloatArray floats, jintArray ints) {
274     SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
275     Vector<float> floatVector;
276     Vector<int32_t> int32Vector;
277 
278     if (floats != nullptr) {
279         floatVector.resize(_env->GetArrayLength(floats));
280         _env->GetFloatArrayRegion(floats, 0, _env->GetArrayLength(floats), floatVector.editArray());
281     }
282 
283     if (ints != nullptr) {
284         int32Vector.resize(_env->GetArrayLength(ints));
285         _env->GetIntArrayRegion(ints, 0, _env->GetArrayLength(ints), int32Vector.editArray());
286     }
287 
288     return mgr->setOperationParameter(handle, type, floatVector, int32Vector);
289 }
290 
291 //----------------------------------------------------------------------------
292 
293 class Receiver : public LooperCallback {
294     sp<SensorEventQueue> mSensorQueue;
295     sp<MessageQueue> mMessageQueue;
296     jobject mReceiverWeakGlobal;
297     jfloatArray mFloatScratch;
298     jintArray   mIntScratch;
299 public:
Receiver(const sp<SensorEventQueue> & sensorQueue,const sp<MessageQueue> & messageQueue,jobject receiverWeak)300     Receiver(const sp<SensorEventQueue>& sensorQueue,
301             const sp<MessageQueue>& messageQueue,
302             jobject receiverWeak) {
303         JNIEnv* env = AndroidRuntime::getJNIEnv();
304         mSensorQueue = sensorQueue;
305         mMessageQueue = messageQueue;
306         mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak);
307 
308         mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16));
309         mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16));
310     }
~Receiver()311     ~Receiver() {
312         JNIEnv* env = AndroidRuntime::getJNIEnv();
313         env->DeleteGlobalRef(mReceiverWeakGlobal);
314         env->DeleteGlobalRef(mFloatScratch);
315         env->DeleteGlobalRef(mIntScratch);
316     }
getSensorEventQueue() const317     sp<SensorEventQueue> getSensorEventQueue() const {
318         return mSensorQueue;
319     }
320 
destroy()321     void destroy() {
322         mMessageQueue->getLooper()->removeFd( mSensorQueue->getFd() );
323     }
324 
325 private:
onFirstRef()326     virtual void onFirstRef() {
327         LooperCallback::onFirstRef();
328         mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
329                 ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
330     }
331 
handleEvent(int fd,int events,void * data)332     virtual int handleEvent(int fd, int events, void* data) {
333         JNIEnv* env = AndroidRuntime::getJNIEnv();
334         sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
335         ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
336 
337         ssize_t n;
338         ASensorEvent buffer[16];
339         while ((n = q->read(buffer, 16)) > 0) {
340             for (int i=0 ; i<n ; i++) {
341                 if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
342                     // step-counter returns a uint64, but the java API only deals with floats
343                     float value = float(buffer[i].u64.step_counter);
344                     env->SetFloatArrayRegion(mFloatScratch, 0, 1, &value);
345                 } else if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
346                     float value[2];
347                     value[0] = buffer[i].dynamic_sensor_meta.connected ? 1.f: 0.f;
348                     value[1] = float(buffer[i].dynamic_sensor_meta.handle);
349                     env->SetFloatArrayRegion(mFloatScratch, 0, 2, value);
350                 } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
351                     env->SetIntArrayRegion(mIntScratch, 0, 14,
352                                            buffer[i].additional_info.data_int32);
353                     env->SetFloatArrayRegion(mFloatScratch, 0, 14,
354                                              buffer[i].additional_info.data_float);
355                 } else {
356                     env->SetFloatArrayRegion(mFloatScratch, 0, 16, buffer[i].data);
357                 }
358 
359                 if (buffer[i].type == SENSOR_TYPE_META_DATA) {
360                     // This is a flush complete sensor event. Call dispatchFlushCompleteEvent
361                     // method.
362                     if (receiverObj.get()) {
363                         env->CallVoidMethod(receiverObj.get(),
364                                             gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
365                                             buffer[i].meta_data.sensor);
366                     }
367                 } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
368                     // This is a flush complete sensor event. Call dispatchAdditionalInfoEvent
369                     // method.
370                     if (receiverObj.get()) {
371                         int type = buffer[i].additional_info.type;
372                         int serial = buffer[i].additional_info.serial;
373                         env->CallVoidMethod(receiverObj.get(),
374                                             gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent,
375                                             buffer[i].sensor,
376                                             type, serial,
377                                             mFloatScratch,
378                                             mIntScratch,
379                                             buffer[i].timestamp);
380                     }
381                 }else {
382                     int8_t status;
383                     switch (buffer[i].type) {
384                     case SENSOR_TYPE_ORIENTATION:
385                     case SENSOR_TYPE_MAGNETIC_FIELD:
386                     case SENSOR_TYPE_ACCELEROMETER:
387                     case SENSOR_TYPE_GYROSCOPE:
388                     case SENSOR_TYPE_GRAVITY:
389                     case SENSOR_TYPE_LINEAR_ACCELERATION:
390                         status = buffer[i].vector.status;
391                         break;
392                     case SENSOR_TYPE_HEART_RATE:
393                         status = buffer[i].heart_rate.status;
394                         break;
395                     default:
396                         status = SENSOR_STATUS_ACCURACY_HIGH;
397                         break;
398                     }
399                     if (receiverObj.get()) {
400                         env->CallVoidMethod(receiverObj.get(),
401                                             gBaseEventQueueClassInfo.dispatchSensorEvent,
402                                             buffer[i].sensor,
403                                             mFloatScratch,
404                                             status,
405                                             buffer[i].timestamp);
406                     }
407                 }
408                 if (env->ExceptionCheck()) {
409                     mSensorQueue->sendAck(buffer, n);
410                     ALOGE("Exception dispatching input event.");
411                     return 1;
412                 }
413             }
414             mSensorQueue->sendAck(buffer, n);
415         }
416         if (n<0 && n != -EAGAIN) {
417             // FIXME: error receiving events, what to do in this case?
418         }
419         return 1;
420     }
421 };
422 
nativeInitSensorEventQueue(JNIEnv * env,jclass clazz,jlong sensorManager,jobject eventQWeak,jobject msgQ,jstring packageName,jint mode,jstring opPackageName,jstring attributionTag)423 static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
424                                         jobject eventQWeak, jobject msgQ, jstring packageName,
425                                         jint mode, jstring opPackageName, jstring attributionTag) {
426     SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
427     ScopedUtfChars packageUtf(env, packageName);
428     String8 clientName(packageUtf.c_str());
429 
430     String16 attributionTagName("");
431     if (attributionTag != nullptr) {
432         ScopedUtfChars attrUtf(env, attributionTag);
433         attributionTagName = String16(attrUtf.c_str());
434     }
435     sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode, attributionTagName));
436 
437     if (queue == NULL) {
438         jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue.");
439         return 0;
440     }
441 
442     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
443     if (messageQueue == NULL) {
444         jniThrowRuntimeException(env, "MessageQueue is not initialized.");
445         return 0;
446     }
447 
448     sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);
449     receiver->incStrong((void*)nativeInitSensorEventQueue);
450     return jlong(receiver.get());
451 }
452 
nativeEnableSensor(JNIEnv * env,jclass clazz,jlong eventQ,jint handle,jint rate_us,jint maxBatchReportLatency)453 static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
454                                jint maxBatchReportLatency) {
455     sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
456     return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
457                                                          0);
458 }
459 
nativeDisableSensor(JNIEnv * env,jclass clazz,jlong eventQ,jint handle)460 static jint nativeDisableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle) {
461     sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
462     return receiver->getSensorEventQueue()->disableSensor(handle);
463 }
464 
nativeDestroySensorEventQueue(JNIEnv * env,jclass clazz,jlong eventQ)465 static void nativeDestroySensorEventQueue(JNIEnv *env, jclass clazz, jlong eventQ) {
466     sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
467     receiver->destroy();
468     receiver->decStrong((void*)nativeInitSensorEventQueue);
469 }
470 
nativeFlushSensor(JNIEnv * env,jclass clazz,jlong eventQ)471 static jint nativeFlushSensor(JNIEnv *env, jclass clazz, jlong eventQ) {
472     sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
473     return receiver->getSensorEventQueue()->flush();
474 }
475 
nativeInjectSensorData(JNIEnv * env,jclass clazz,jlong eventQ,jint handle,jfloatArray values,jint accuracy,jlong timestamp)476 static jint nativeInjectSensorData(JNIEnv *env, jclass clazz, jlong eventQ, jint handle,
477         jfloatArray values, jint accuracy, jlong timestamp) {
478     sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
479     // Create a sensor_event from the above data which can be injected into the HAL.
480     ASensorEvent sensor_event;
481     memset(&sensor_event, 0, sizeof(sensor_event));
482     sensor_event.sensor = handle;
483     sensor_event.timestamp = timestamp;
484     env->GetFloatArrayRegion(values, 0, env->GetArrayLength(values), sensor_event.data);
485     return receiver->getSensorEventQueue()->injectSensorEvent(sensor_event);
486 }
487 //----------------------------------------------------------------------------
488 
489 static const JNINativeMethod gSystemSensorManagerMethods[] = {
490     {"nativeClassInit",
491             "()V",
492             (void*)nativeClassInit },
493     {"nativeCreate",
494              "(Ljava/lang/String;)J",
495              (void*)nativeCreate },
496 
497     {"nativeGetSensorAtIndex",
498             "(JLandroid/hardware/Sensor;I)Z",
499             (void*)nativeGetSensorAtIndex },
500 
501     {"nativeGetDynamicSensors",
502             "(JLjava/util/List;)V",
503             (void*)nativeGetDynamicSensors },
504 
505     {"nativeIsDataInjectionEnabled",
506             "(J)Z",
507             (void*)nativeIsDataInjectionEnabled },
508 
509     {"nativeCreateDirectChannel",
510             "(JJIILandroid/hardware/HardwareBuffer;)I",
511             (void*)nativeCreateDirectChannel },
512 
513     {"nativeDestroyDirectChannel",
514             "(JI)V",
515             (void*)nativeDestroyDirectChannel },
516 
517     {"nativeConfigDirectChannel",
518             "(JIII)I",
519             (void*)nativeConfigDirectChannel },
520 
521     {"nativeSetOperationParameter",
522             "(JII[F[I)I",
523             (void*)nativeSetOperationParameter },
524 };
525 
526 static const JNINativeMethod gBaseEventQueueMethods[] = {
527         {"nativeInitBaseEventQueue",
528          "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/"
529          "String;Ljava/lang/String;)J",
530          (void *)nativeInitSensorEventQueue},
531 
532         {"nativeEnableSensor", "(JIII)I", (void *)nativeEnableSensor},
533 
534         {"nativeDisableSensor", "(JI)I", (void *)nativeDisableSensor},
535 
536         {"nativeDestroySensorEventQueue", "(J)V", (void *)nativeDestroySensorEventQueue},
537 
538         {"nativeFlushSensor", "(J)I", (void *)nativeFlushSensor},
539 
540         {"nativeInjectSensorData", "(JI[FIJ)I", (void *)nativeInjectSensorData},
541 };
542 
543 } //unnamed namespace
544 
register_android_hardware_SensorManager(JNIEnv * env)545 int register_android_hardware_SensorManager(JNIEnv *env)
546 {
547     RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager",
548             gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));
549 
550     RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager$BaseEventQueue",
551             gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));
552 
553     gBaseEventQueueClassInfo.clazz = FindClassOrDie(env,
554             "android/hardware/SystemSensorManager$BaseEventQueue");
555 
556     gBaseEventQueueClassInfo.dispatchSensorEvent = GetMethodIDOrDie(env,
557             gBaseEventQueueClassInfo.clazz, "dispatchSensorEvent", "(I[FIJ)V");
558 
559     gBaseEventQueueClassInfo.dispatchFlushCompleteEvent = GetMethodIDOrDie(env,
560             gBaseEventQueueClassInfo.clazz, "dispatchFlushCompleteEvent", "(I)V");
561 
562     gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent = GetMethodIDOrDie(env,
563             gBaseEventQueueClassInfo.clazz, "dispatchAdditionalInfoEvent", "(III[F[I)V");
564 
565     return 0;
566 }
567