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