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
showHelp()41 void showHelp()
42 {
43 printf("Usage: sensortest [-h] [-l] [-e <type> <rate_usecs>] [-b <type> <rate_usecs> <batch_usecs>] [-c]\n");
44 }
45
printSensorList()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
findSensorTypeInSensorList(int type)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
findSensorTypeInConfigList(int type)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
parseArguments(int argc,char ** argv)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
hasReceivedAllEvents()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
main(int argc,char ** argv)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