1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // +build android
6
7 #include <stdlib.h>
8 #include <jni.h>
9
10 #include <android/sensor.h>
11
12 #define GO_ANDROID_SENSOR_LOOPER_ID 100
13
14 #define GO_ANDROID_READ_TIMEOUT_MS 1000
15
16 ASensorEventQueue* queue = NULL;
17 ALooper* looper = NULL;
18
getSensorManager()19 static ASensorManager* getSensorManager() {
20 #pragma clang diagnostic push
21 // Builders convert C warnings to errors, so suppress the
22 // error from ASensorManager_getInstance being deprecated
23 // in Android 26.
24 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
25 return ASensorManager_getInstance();
26 #pragma clang diagnostic pop
27 }
28
GoAndroid_createManager()29 void GoAndroid_createManager() {
30 ASensorManager* manager = getSensorManager();
31 looper = ALooper_forThread();
32 if (looper == NULL) {
33 looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
34 }
35 queue = ASensorManager_createEventQueue(manager, looper, GO_ANDROID_SENSOR_LOOPER_ID, NULL, NULL);
36 }
37
GoAndroid_enableSensor(int s,int32_t usec)38 int GoAndroid_enableSensor(int s, int32_t usec) {
39 ASensorManager* manager = getSensorManager();
40 const ASensor* sensor = ASensorManager_getDefaultSensor(manager, s);
41 if (sensor == NULL) {
42 return 1;
43 }
44 ASensorEventQueue_enableSensor(queue, sensor);
45 ASensorEventQueue_setEventRate(queue, sensor, usec);
46 return 0;
47 }
48
GoAndroid_disableSensor(int s)49 void GoAndroid_disableSensor(int s) {
50 ASensorManager* manager = getSensorManager();
51 const ASensor* sensor = ASensorManager_getDefaultSensor(manager, s);
52 ASensorEventQueue_disableSensor(queue, sensor);
53 }
54
GoAndroid_readQueue(int n,int32_t * types,int64_t * timestamps,float * vectors)55 int GoAndroid_readQueue(int n, int32_t* types, int64_t* timestamps, float* vectors) {
56 int id;
57 int events;
58 ASensorEvent event;
59 int i = 0;
60 // Try n times read from the event queue.
61 // If anytime timeout occurs, don't retry to read and immediately return.
62 // Consume the event queue entirely between polls.
63 while (i < n && (id = ALooper_pollAll(GO_ANDROID_READ_TIMEOUT_MS, NULL, &events, NULL)) >= 0) {
64 if (id != GO_ANDROID_SENSOR_LOOPER_ID) {
65 continue;
66 }
67 while (i < n && ASensorEventQueue_getEvents(queue, &event, 1)) {
68 types[i] = event.type;
69 timestamps[i] = event.timestamp;
70 vectors[i*3] = event.vector.x;
71 vectors[i*3+1] = event.vector.y;
72 vectors[i*3+2] = event.vector.z;
73 i++;
74 }
75 }
76 return i;
77 }
78
GoAndroid_destroyManager()79 void GoAndroid_destroyManager() {
80 ASensorManager* manager = getSensorManager();
81 ASensorManager_destroyEventQueue(manager, queue);
82 queue = NULL;
83 looper = NULL;
84 }
85