summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Beare <bbeare1@gmail.com>2015-12-27 09:49:38 -0800
committerBruce Beare <bruce.j.beare@intel.com>2015-12-30 13:23:26 -0800
commit71737fb913bb95fba3cac000d1dcc8d8d9d41344 (patch)
tree478d45ae238b6d4f3353e8c17eef2abd0fbefe7f
parent19825459f79869ed8517b7ac4a6c2e2784c6da8a (diff)
downloadcommon-71737fb913bb95fba3cac000d1dcc8d8d9d41344.tar.gz
sensors:ndk-example-app: rewrite to work with multiple sensors
Code is brought into feature alignment with the sensor HAL test. Additional sensor types added. Each sensor of every type are activated and if successful, data is returned. BUG=none Change-Id: Ieff446aed388c04014c57670c6fae2e113f229f2 Signed-off-by: Bruce Beare <bruce.j.beare@intel.com>
-rw-r--r--sensors_example/ndk-example-app.cpp263
1 files changed, 188 insertions, 75 deletions
diff --git a/sensors_example/ndk-example-app.cpp b/sensors_example/ndk-example-app.cpp
index 78b13ad..628068d 100644
--- a/sensors_example/ndk-example-app.cpp
+++ b/sensors_example/ndk-example-app.cpp
@@ -14,117 +14,230 @@
* limitations under the License.
*/
-// This file contains an example app that uses sensors NDK API.
+/* This file contains an example app that uses sensors NDK.
+ * It accepts a sensor type as an input argument and reads data from a
+ * sensor of that type.
+ *
+ * For any specified sensor type, there may be multiple such sensors defined
+ * in the HAL. Some or all of the defined sensors will actually be equipped.
+ * This test program will scan the HAL for the first equipped sensor of
+ * the specified sensor type and dump data from that sensor.
+ */
+#include <getopt.h>
+#include <math.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <map>
-#include <string>
-
#include <android/looper.h>
#include <android/sensor.h>
#include <hardware/sensors.h>
-const char kPackageName[] = "ndk-example-app";
-const int kLooperId = 1;
+#define DEFAULT_SENSOR_TYPE SENSOR_TYPE_ACCELEROMETER
+
+// Structure to hold the decoded command line options
+struct pgm_options {
+ int sensor_type;
+};
+
+// Be sure to keep the options for longopts and shortopts in the same order
+// so that Usage() is correct.
+static struct option longopts[] = {
+ {"help", no_argument, NULL, '?'},
+ {"accel", no_argument, NULL, 'a'},
+ {"temp", no_argument, NULL, 't'},
+ {"light", no_argument, NULL, 'l'},
+ {"orient", no_argument, NULL, 'o'},
+ {"prox", no_argument, NULL, 'p'},
+ {"motion", no_argument, NULL, 'm'},
+ {NULL, 0, NULL, 0}
+};
+static char shortopts[] = "?atlopm";
+
+// Describes the options for this program.
+void Usage(char *pgm_name) {
+ printf("Usage: %s [options...]\n", pgm_name);
+ printf("Exercises the sensors NDK by calling into the sensorserver.\n");
+ printf("Options:\n");
+ for (int i = 0; longopts[i].name; i++) {
+ printf(" --%-6s or -%c\n", longopts[i].name, shortopts[i]);
+ }
+}
+
+// Processes all command line options.
+// sets the options members for commnd line options
+// returns (0) on success, -1 otherwise.
+int ReadOpts(int argc, char **argv, struct pgm_options *options) {
+ int ch = 0;
+
+ if (!options) {
+ fprintf(stderr, "Invalid options pointer\n");
+ return 1;
+ }
+
+ while ((ch = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
+ switch (ch) {
+ case 'a':
+ options->sensor_type = SENSOR_TYPE_ACCELEROMETER;
+ break;
+ case 't':
+ options->sensor_type = SENSOR_TYPE_TEMPERATURE;
+ break;
+ case 'l':
+ options->sensor_type = SENSOR_TYPE_LIGHT;
+ break;
+ case 'o':
+ options->sensor_type = SENSOR_TYPE_ORIENTATION;
+ break;
+ case 'p':
+ options->sensor_type = SENSOR_TYPE_PROXIMITY;
+ break;
+ case 'm':
+ options->sensor_type = SENSOR_TYPE_SIGNIFICANT_MOTION;
+ break;
+ default:
+ Usage(argv[0]);
+ return -1;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ return 0;
+}
+
+// Prints data associated with each supported sensor type.
+// Be sure to provide a case for each sensor type supported in
+// the ReadOpts() function.
+void DisplaySensorData(int sensor_type, const ASensorEvent *data) {
+ switch (sensor_type) {
+ case SENSOR_TYPE_PROXIMITY:
+ printf("Proximity distance: %f\n", data->distance);
+ break;
+ case SENSOR_TYPE_SIGNIFICANT_MOTION:
+ if (data->data[0] == 1) {
+ printf("Significant motion detected\n");
+ }
+ break;
+ case SENSOR_TYPE_ACCELEROMETER:
+ printf("Acceleration: x = %f, y = %f, z = %f\n",
+ data->acceleration.x, data->acceleration.y, data->acceleration.z);
+ break;
+ case SENSOR_TYPE_TEMPERATURE:
+ printf("Temperature: %f\n", data->temperature);
+ break;
+ case SENSOR_TYPE_LIGHT:
+ printf("Light: %f\n", data->light);
+ break;
+ case SENSOR_TYPE_ORIENTATION: {
+ float heading =
+ atan2(static_cast<double>(data->magnetic.y),
+ static_cast<double>(data->magnetic.x)) * 180.0 / M_PI;
+ if (heading < 0.0)
+ heading += 360.0;
+ printf("Heading: %f, Orientation: x = %f, y = %f, z = %f\n",
+ heading, data->magnetic.x, data->magnetic.y, data->magnetic.z);
+ }
+ break;
+ }
+}
int main(int argc, char* argv[]) {
+ pgm_options options = {DEFAULT_SENSOR_TYPE};
+ if (ReadOpts(argc, argv, &options) < 0)
+ return 1;
+
+ const char kPackageName[] = "ndk-example-app";
ASensorManager* sensor_manager =
- ASensorManager_getInstanceForPackage(kPackageName);
+ ASensorManager_getInstanceForPackage(kPackageName);
if (!sensor_manager) {
fprintf(stderr, "Failed to get a sensor manager\n");
return 1;
}
- ASensorList sensor_list;
+ ASensorList sensor_list = nullptr;
int sensor_count = ASensorManager_getSensorList(sensor_manager, &sensor_list);
- printf("Found %d sensors\n", sensor_count);
+ printf("Found %d supported sensors\n", sensor_count);
for (int i = 0; i < sensor_count; i++) {
- printf("Found %s\n", ASensor_getName(sensor_list[i]));
+ printf("HAL supports sensor %s\n", ASensor_getName(sensor_list[i]));
}
+ const int kLooperId = 1;
ASensorEventQueue* queue = ASensorManager_createEventQueue(
sensor_manager,
ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS),
- kLooperId, NULL /* no callback */, NULL /* no data */);
+ kLooperId,
+ NULL, /* no callback */
+ NULL /* no private data for a callback */);
if (!queue) {
fprintf(stderr, "Failed to create a sensor event queue\n");
return 1;
}
- const std::map<int, std::string> kSensorSamples = {
- /*
- * Accelerometer:
- * Reporting mode: continuous. Events are generated continuously.
- */
- { SENSOR_TYPE_ACCELEROMETER, "accelerometer" },
-
- /*
- * Proximity sensor:
- * Reporting mode: on-change. Events are generated only when proximity
- * value has changed.
- */
- { SENSOR_TYPE_PROXIMITY, "proximity sensor" },
-
- /*
- * Significant motion sensor:
- * Reporting mode: one-shot. An event is generated when significant
- * motion is detected. After that, the sensor will be disabled by
- * itself.
- */
- { SENSOR_TYPE_SIGNIFICANT_MOTION, "significant motion sensor" },
- };
+ // Find the first sensor of the specified type that can be opened
+ const int kTimeoutMicroSecs = 1000000;
+ const int kTimeoutMilliSecs = 1000;
+ ASensorRef sensor = nullptr;
+ bool sensor_found = false;
+ for (int i = 0; i < sensor_count; i++) {
+ sensor = sensor_list[i];
+ if (ASensor_getType(sensor) != options.sensor_type)
+ continue;
+ if (ASensorEventQueue_enableSensor(queue, sensor) < 0)
+ continue;
+ if (ASensorEventQueue_setEventRate(queue, sensor, kTimeoutMicroSecs) < 0) {
+ fprintf(stderr, "Failed to set the %s sample rate\n",
+ ASensor_getName(sensor));
+ return 1;
+ }
+
+ // Found an equipped sensor of the specified type.
+ sensor_found = true;
+ break;
+ }
+
+ if (!sensor_found) {
+ fprintf(stderr, "No sensor of the specified type found\n");
+ int ret = ASensorManager_destroyEventQueue(sensor_manager, queue);
+ if (ret < 0)
+ fprintf(stderr, "Failed to destroy event queue: %s\n", strerror(-ret));
+ return 1;
+ }
+ printf("\nSensor %s activated\n", ASensor_getName(sensor));
- const int kNumSamples = 10;
const int kNumEvents = 1;
- const int kTimeoutMilliSecs = 1000;
+ const int kNumSamples = 10;
const int kWaitTimeSecs = 1;
+ for (int i = 0; i < kNumSamples; i++) {
+ ASensorEvent data[kNumEvents];
+ memset(data, 0, sizeof(data));
+ int ident = ALooper_pollAll(
+ kTimeoutMilliSecs,
+ NULL /* no output file descriptor */,
+ NULL /* no output event */,
+ NULL /* no output data */);
+ if (ident != kLooperId) {
+ fprintf(stderr, "Incorrect Looper ident read from poll.\n");
+ continue;
+ }
+ if (ASensorEventQueue_getEvents(queue, data, kNumEvents) <= 0) {
+ fprintf(stderr, "Failed to read data from the sensor.\n");
+ continue;
+ }
- for (auto& sensor_type : kSensorSamples) {
- const ASensor* sensor = ASensorManager_getDefaultSensor(sensor_manager,
- sensor_type.first);
- if (sensor && !ASensorEventQueue_enableSensor(queue, sensor)) {
- for (int i = 0; i < kNumSamples; i++) {
- int ident = ALooper_pollAll(kTimeoutMilliSecs,
- NULL /* no output file descriptor */,
- NULL /* no output event */,
- NULL /* no output data */);
- if (ident == kLooperId) {
- ASensorEvent data;
- if (ASensorEventQueue_getEvents(queue, &data, kNumEvents)) {
- if (sensor_type.first == SENSOR_TYPE_ACCELEROMETER) {
- printf("Acceleration: x = %f, y = %f, z = %f\n",
- data.acceleration.x, data.acceleration.y,
- data.acceleration.z);
- } else if (sensor_type.first == SENSOR_TYPE_PROXIMITY) {
- printf("Proximity distance: %f\n", data.distance);
- } else if (sensor_type.first == SENSOR_TYPE_SIGNIFICANT_MOTION) {
- if (data.data[0] == 1) {
- printf("Significant motion detected\n");
- break;
- }
- }
- }
- }
- sleep(kWaitTimeSecs);
- }
+ DisplaySensorData(options.sensor_type, data);
+ sleep(kWaitTimeSecs);
+ }
- int ret = ASensorEventQueue_disableSensor(queue, sensor);
- if (ret) {
- fprintf(stderr, "Failed to disable %s: %s\n",
- sensor_type.second.c_str(), strerror(ret));
- }
- } else {
- fprintf(stderr, "No %s found or failed to enable it\n",
- sensor_type.second.c_str());
- }
+ int ret = ASensorEventQueue_disableSensor(queue, sensor);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to disable %s: %s\n",
+ ASensor_getName(sensor), strerror(-ret));
}
- int ret = ASensorManager_destroyEventQueue(sensor_manager, queue);
- if (ret) {
- fprintf(stderr, "Failed to destroy event queue: %s\n", strerror(ret));
+ ret = ASensorManager_destroyEventQueue(sensor_manager, queue);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to destroy event queue: %s\n", strerror(-ret));
return 1;
}