/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <android/sensor.h> struct SensorConfig { int listIndex; int type; int32_t rate; int64_t reportLatency; bool receivedEvent; }; ASensorManager *mSensorManager; ASensorList mSensorList; int mNumSensors; bool mContinuousMode; SensorConfig mSensorConfigList[16]; int mNumSensorConfigs; void showHelp() { printf("Usage: sensortest [-h] [-l] [-e <type> <rate_usecs>] [-b <type> <rate_usecs> <batch_usecs>] [-c]\n"); } void printSensorList() { int prevMinType = -1; int currMinType; int currMinIndex = 0; printf("[Type] - Name\n"); for (int i = 0; i < mNumSensors; i++) { currMinType = INT_MAX; for (int j = 0; j < mNumSensors; j++) { if ((ASensor_getType(mSensorList[j]) > prevMinType) && (ASensor_getType(mSensorList[j]) < currMinType)) { currMinType = ASensor_getType(mSensorList[j]); currMinIndex = j; } } printf("[%d] = \"%s\"\n", currMinType, ASensor_getName(mSensorList[currMinIndex])); prevMinType = currMinType; } } int findSensorTypeInSensorList(int type) { for (int i = 0; i < mNumSensors; i++) { if (ASensor_getType(mSensorList[i]) == type) { return i; } } return -1; } int findSensorTypeInConfigList(int type) { for (int i = 0; i < mNumSensorConfigs; i++) { if (mSensorConfigList[i].type == type) { return i; } } return -1; } bool parseArguments(int argc, char **argv) { int currArgumentIndex = 1; int sensorIndex; int existingSensorConfigIndex; mNumSensorConfigs = 0; while (currArgumentIndex < argc) { if (!strcmp(argv[currArgumentIndex], "-h")) { return false; } else if (!strcmp(argv[currArgumentIndex], "-l")) { printSensorList(); currArgumentIndex++; } else if (!strcmp(argv[currArgumentIndex], "-e")) { if (currArgumentIndex + 2 >= argc) { printf ("Not enough arguments for enable option\n"); return false; } if ((sensorIndex = findSensorTypeInSensorList(atoi(argv[currArgumentIndex+1]))) < 0) { printf ("No sensor found with type \"%d\"\n", atoi(argv[currArgumentIndex+1])); return false; } existingSensorConfigIndex = findSensorTypeInConfigList(atoi(argv[currArgumentIndex+1])); if (existingSensorConfigIndex >= 0) { printf("Replacing previous config for sensor type %d\n", atoi(argv[currArgumentIndex+1])); mSensorConfigList[existingSensorConfigIndex] = (SensorConfig) { .listIndex = sensorIndex, .type = atoi(argv[currArgumentIndex+1]), .rate = atoi(argv[currArgumentIndex+2]), .reportLatency = 0, .receivedEvent = false }; } else { mSensorConfigList[(mNumSensorConfigs)++] = (SensorConfig) { .listIndex = sensorIndex, .type = atoi(argv[currArgumentIndex+1]), .rate = atoi(argv[currArgumentIndex+2]), .reportLatency = 0, .receivedEvent = false }; } currArgumentIndex += 3; } else if (!strcmp(argv[currArgumentIndex], "-b")) { if (currArgumentIndex + 3 >= argc) { printf ("Not enough arguments for batch option\n"); return false; } if ((sensorIndex = findSensorTypeInSensorList(atoi(argv[currArgumentIndex+1]))) < 0) { printf ("No sensor found with type \"%d\"\n", atoi(argv[currArgumentIndex+1])); return false; } existingSensorConfigIndex = findSensorTypeInConfigList(atoi(argv[currArgumentIndex+1])); if (existingSensorConfigIndex >= 0) { printf("Replacing previous config for sensor type %d\n", atoi(argv[currArgumentIndex+1])); mSensorConfigList[existingSensorConfigIndex] = (SensorConfig) { .listIndex = sensorIndex, .type = atoi(argv[currArgumentIndex+1]), .rate = atoi(argv[currArgumentIndex+2]), .reportLatency = atoi(argv[currArgumentIndex+3]), .receivedEvent = false }; } else { mSensorConfigList[(mNumSensorConfigs)++] = (SensorConfig) { .listIndex = sensorIndex, .type = atoi(argv[currArgumentIndex+1]), .rate = atoi(argv[currArgumentIndex+2]), .reportLatency = atoi(argv[currArgumentIndex+3]), .receivedEvent = false }; } currArgumentIndex += 4; } else if (!strcmp(argv[currArgumentIndex], "-c")) { mContinuousMode = true; currArgumentIndex++; } else { printf("Invalid argument \"%s\"\n", argv[currArgumentIndex]); return false; } } return true; } bool hasReceivedAllEvents() { for (int i = 0; i < mNumSensorConfigs; i++) { if (!mSensorConfigList[i].receivedEvent) { return false; } } return true; }; int main(int argc, char **argv) { int numSensorEvents; ASensorEvent sensorEvents[16]; int configListIndex; mSensorManager = ASensorManager_getInstanceForPackage(""); mNumSensors = ASensorManager_getSensorList(mSensorManager, &mSensorList); if ((argc == 1) || !parseArguments(argc, argv)) { showHelp(); return -1; } if (mNumSensorConfigs <= 0) return 0; ALooper *mLooper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ASensorEventQueue *sensorEventQueue = ASensorManager_createEventQueue(mSensorManager, mLooper, 0, NULL, NULL); for (int i = 0; i < mNumSensorConfigs; i++) { if (ASensorEventQueue_registerSensor(sensorEventQueue, mSensorList[mSensorConfigList[i].listIndex], mSensorConfigList[i].rate, mSensorConfigList[i].reportLatency) < 0) { printf("Unable to register sensor %d with rate %d and report latency %" PRId64 "\n", mSensorConfigList[i].listIndex, mSensorConfigList[i].rate, mSensorConfigList[i].reportLatency); } } while (mContinuousMode || !hasReceivedAllEvents()) { if ((numSensorEvents = ASensorEventQueue_getEvents(sensorEventQueue, sensorEvents, 16)) < 0) { printf("An error occurred while polling for events\n"); break; } else if (numSensorEvents > 0) { for (int i = 0; i < numSensorEvents; i++) { if ((configListIndex = findSensorTypeInConfigList(sensorEvents[i].type)) < 0) { printf("Received unexpected event for type %d\n", sensorEvents[i].type); break; } if (mContinuousMode || !mSensorConfigList[configListIndex].receivedEvent) { printf("[%d] = %f, %f, %f @ %" PRId64 "\n", sensorEvents[i].type, sensorEvents[i].data[0], sensorEvents[i].data[1], sensorEvents[i].data[2], sensorEvents[i].timestamp); mSensorConfigList[configListIndex].receivedEvent = true; if (!mContinuousMode) { ASensorEventQueue_disableSensor(sensorEventQueue, mSensorList[mSensorConfigList[configListIndex].listIndex]); } } } } fflush(stdout); } ASensorManager_destroyEventQueue(mSensorManager, sensorEventQueue); return 0; }