1 /* 2 * Copyright (C) 2016 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 17 #include <inttypes.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <unistd.h> 22 23 #include <android/sensor.h> 24 25 struct SensorConfig { 26 int listIndex; 27 int type; 28 int32_t rate; 29 int64_t reportLatency; 30 bool receivedEvent; 31 }; 32 33 34 ASensorManager *mSensorManager; 35 ASensorList mSensorList; 36 int mNumSensors; 37 bool mContinuousMode; 38 SensorConfig mSensorConfigList[16]; 39 int mNumSensorConfigs; 40 41 void showHelp() 42 { 43 printf("Usage: sensortest [-h] [-l] [-e <type> <rate_usecs>] [-b <type> <rate_usecs> <batch_usecs>] [-c]\n"); 44 } 45 46 void printSensorList() 47 { 48 int prevMinType = -1; 49 int currMinType; 50 int currMinIndex = 0; 51 52 printf("[Type] - Name\n"); 53 54 for (int i = 0; i < mNumSensors; i++) { 55 currMinType = INT_MAX; 56 57 for (int j = 0; j < mNumSensors; j++) { 58 if ((ASensor_getType(mSensorList[j]) > prevMinType) && 59 (ASensor_getType(mSensorList[j]) < currMinType)) { 60 currMinType = ASensor_getType(mSensorList[j]); 61 currMinIndex = j; 62 } 63 } 64 65 printf("[%d] = \"%s\"\n", currMinType, ASensor_getName(mSensorList[currMinIndex])); 66 67 prevMinType = currMinType; 68 } 69 } 70 71 int findSensorTypeInSensorList(int type) 72 { 73 for (int i = 0; i < mNumSensors; i++) { 74 if (ASensor_getType(mSensorList[i]) == type) { 75 return i; 76 } 77 } 78 79 return -1; 80 } 81 82 int findSensorTypeInConfigList(int type) 83 { 84 for (int i = 0; i < mNumSensorConfigs; i++) { 85 if (mSensorConfigList[i].type == type) { 86 return i; 87 } 88 } 89 90 return -1; 91 } 92 93 bool parseArguments(int argc, char **argv) 94 { 95 int currArgumentIndex = 1; 96 int sensorIndex; 97 int existingSensorConfigIndex; 98 99 mNumSensorConfigs = 0; 100 101 while (currArgumentIndex < argc) { 102 if (!strcmp(argv[currArgumentIndex], "-h")) { 103 return false; 104 } else if (!strcmp(argv[currArgumentIndex], "-l")) { 105 printSensorList(); 106 currArgumentIndex++; 107 } else if (!strcmp(argv[currArgumentIndex], "-e")) { 108 if (currArgumentIndex + 2 >= argc) { 109 printf ("Not enough arguments for enable option\n"); 110 return false; 111 } 112 113 if ((sensorIndex = findSensorTypeInSensorList(atoi(argv[currArgumentIndex+1]))) < 0) { 114 printf ("No sensor found with type \"%d\"\n", atoi(argv[currArgumentIndex+1])); 115 return false; 116 } 117 118 existingSensorConfigIndex = findSensorTypeInConfigList(atoi(argv[currArgumentIndex+1])); 119 120 if (existingSensorConfigIndex >= 0) { 121 printf("Replacing previous config for sensor type %d\n", atoi(argv[currArgumentIndex+1])); 122 mSensorConfigList[existingSensorConfigIndex] = (SensorConfig) { 123 .listIndex = sensorIndex, 124 .type = atoi(argv[currArgumentIndex+1]), 125 .rate = atoi(argv[currArgumentIndex+2]), 126 .reportLatency = 0, 127 .receivedEvent = false 128 }; 129 } else { 130 mSensorConfigList[(mNumSensorConfigs)++] = (SensorConfig) { 131 .listIndex = sensorIndex, 132 .type = atoi(argv[currArgumentIndex+1]), 133 .rate = atoi(argv[currArgumentIndex+2]), 134 .reportLatency = 0, 135 .receivedEvent = false 136 }; 137 } 138 139 currArgumentIndex += 3; 140 } else if (!strcmp(argv[currArgumentIndex], "-b")) { 141 if (currArgumentIndex + 3 >= argc) { 142 printf ("Not enough arguments for batch option\n"); 143 return false; 144 } 145 146 if ((sensorIndex = findSensorTypeInSensorList(atoi(argv[currArgumentIndex+1]))) < 0) { 147 printf ("No sensor found with type \"%d\"\n", atoi(argv[currArgumentIndex+1])); 148 return false; 149 } 150 151 existingSensorConfigIndex = findSensorTypeInConfigList(atoi(argv[currArgumentIndex+1])); 152 153 if (existingSensorConfigIndex >= 0) { 154 printf("Replacing previous config for sensor type %d\n", atoi(argv[currArgumentIndex+1])); 155 mSensorConfigList[existingSensorConfigIndex] = (SensorConfig) { 156 .listIndex = sensorIndex, 157 .type = atoi(argv[currArgumentIndex+1]), 158 .rate = atoi(argv[currArgumentIndex+2]), 159 .reportLatency = atoi(argv[currArgumentIndex+3]), 160 .receivedEvent = false 161 }; 162 } else { 163 mSensorConfigList[(mNumSensorConfigs)++] = (SensorConfig) { 164 .listIndex = sensorIndex, 165 .type = atoi(argv[currArgumentIndex+1]), 166 .rate = atoi(argv[currArgumentIndex+2]), 167 .reportLatency = atoi(argv[currArgumentIndex+3]), 168 .receivedEvent = false 169 }; 170 } 171 172 currArgumentIndex += 4; 173 } else if (!strcmp(argv[currArgumentIndex], "-c")) { 174 mContinuousMode = true; 175 currArgumentIndex++; 176 } else { 177 printf("Invalid argument \"%s\"\n", argv[currArgumentIndex]); 178 return false; 179 } 180 } 181 182 return true; 183 } 184 185 bool hasReceivedAllEvents() 186 { 187 for (int i = 0; i < mNumSensorConfigs; i++) { 188 if (!mSensorConfigList[i].receivedEvent) { 189 return false; 190 } 191 } 192 193 return true; 194 }; 195 196 int main(int argc, char **argv) { 197 int numSensorEvents; 198 ASensorEvent sensorEvents[16]; 199 int configListIndex; 200 201 mSensorManager = ASensorManager_getInstanceForPackage(""); 202 mNumSensors = ASensorManager_getSensorList(mSensorManager, &mSensorList); 203 204 if ((argc == 1) || !parseArguments(argc, argv)) { 205 showHelp(); 206 return -1; 207 } 208 209 if (mNumSensorConfigs <= 0) 210 return 0; 211 212 ALooper *mLooper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); 213 ASensorEventQueue *sensorEventQueue = ASensorManager_createEventQueue(mSensorManager, mLooper, 0, NULL, NULL); 214 215 for (int i = 0; i < mNumSensorConfigs; i++) { 216 if (ASensorEventQueue_registerSensor(sensorEventQueue, mSensorList[mSensorConfigList[i].listIndex], 217 mSensorConfigList[i].rate, mSensorConfigList[i].reportLatency) < 0) { 218 printf("Unable to register sensor %d with rate %d and report latency %" PRId64 "\n", 219 mSensorConfigList[i].listIndex, mSensorConfigList[i].rate, 220 mSensorConfigList[i].reportLatency); 221 } 222 223 } 224 225 while (mContinuousMode || !hasReceivedAllEvents()) { 226 if ((numSensorEvents = ASensorEventQueue_getEvents(sensorEventQueue, sensorEvents, 16)) < 0) { 227 printf("An error occurred while polling for events\n"); 228 break; 229 } else if (numSensorEvents > 0) { 230 for (int i = 0; i < numSensorEvents; i++) { 231 if ((configListIndex = findSensorTypeInConfigList(sensorEvents[i].type)) < 0) { 232 printf("Received unexpected event for type %d\n", sensorEvents[i].type); 233 break; 234 } 235 236 if (mContinuousMode || !mSensorConfigList[configListIndex].receivedEvent) { 237 printf("[%d] = %f, %f, %f @ %" PRId64 "\n", sensorEvents[i].type, 238 sensorEvents[i].data[0], sensorEvents[i].data[1], 239 sensorEvents[i].data[2], sensorEvents[i].timestamp); 240 241 mSensorConfigList[configListIndex].receivedEvent = true; 242 243 if (!mContinuousMode) { 244 ASensorEventQueue_disableSensor(sensorEventQueue, mSensorList[mSensorConfigList[configListIndex].listIndex]); 245 } 246 } 247 } 248 } 249 250 fflush(stdout); 251 } 252 253 ASensorManager_destroyEventQueue(mSensorManager, sensorEventQueue); 254 255 return 0; 256 } 257