Merge "Modify service example to use aidl."
diff --git a/lights_example/example-app/Android.mk b/lights_example/example-app/Android.mk
index 2f7feec..6e3caae 100644
--- a/lights_example/example-app/Android.mk
+++ b/lights_example/example-app/Android.mk
@@ -21,6 +21,7 @@
 LOCAL_MODULE := lights-hal-example-app
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := hal-example-app.cpp
+LOCAL_CFLAGS := -Wall -Werror
 LOCAL_SHARED_LIBRARIES := \
   libc \
   libhardware \
diff --git a/lights_example/example-app/hal-example-app.cpp b/lights_example/example-app/hal-example-app.cpp
index ea5faf4..f014bd0 100644
--- a/lights_example/example-app/hal-example-app.cpp
+++ b/lights_example/example-app/hal-example-app.cpp
@@ -38,30 +38,28 @@
   }
 
   struct light_state_t state = {
-      color: 1,
-      flashMode: LIGHT_FLASH_NONE,
-      flashOnMS: 0,
-      flashOffMS: 0,
-      brightnessMode: 0,
-  };
-  struct light_state_t state_flash = {
-      color: 1,
-      flashMode: LIGHT_FLASH_TIMED,
-      flashOnMS: 50,
-      flashOffMS: 50,
-      brightnessMode: 0,
+      .color = 0,
+      .flashMode = LIGHT_FLASH_NONE,
+      .flashOnMS = 0,
+      .flashOffMS = 0,
+      .brightnessMode = 0,
   };
 
-  // On for three seconds.
+  // Turn light on for three seconds.
+  state.color = 1;
   light_device->set_light(light_device, &state);
   sleep(3);
 
   // Flash for three seconds.
-  light_device->set_light(light_device, &state_flash);
+  state.flashMode = LIGHT_FLASH_TIMED;
+  state.flashOnMS = 50;
+  state.flashOffMS = 50;
+  light_device->set_light(light_device, &state);
   sleep(3);
 
-  // Off.
+  // Turn light off.
   state.color = 0;
+  state.flashMode = LIGHT_FLASH_NONE;
   light_device->set_light(light_device, &state);
 
   light_device->common.close(
diff --git a/sensors_example/hal-example-app.cpp b/sensors_example/hal-example-app.cpp
index 2a7cf83..dfec435 100644
--- a/sensors_example/hal-example-app.cpp
+++ b/sensors_example/hal-example-app.cpp
@@ -14,34 +14,155 @@
  * limitations under the License.
  */
 
-// This file constains an example app that uses sensors HAL.
+/* This file contains an example app that uses sensors HAL.
+ * 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 <sys/types.h>
 #include <unistd.h>
 
 #include <hardware/hardware.h>
 #include <hardware/sensors.h>
 
-int main(int argc, char* argv[]) {
-  sensors_module_t* sensor_module = nullptr;
+#include <sys/types.h>
 
-  int ret = hw_get_module(
-      SENSORS_HARDWARE_MODULE_ID,
+#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 HAL by direct calling.\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 sensors_event_t *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->orientation.y),
+              static_cast<double>(data->orientation.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->orientation.x, data->orientation.y,
+             data->orientation.z);
+      }
+      break;
+  }
+}
+
+int main(int argc, char* argv[]) {
+  pgm_options options = {DEFAULT_SENSOR_TYPE};
+  if (ReadOpts(argc, argv, &options) < 0)
+    return 1;
+
+  sensors_module_t* sensor_module = nullptr;
+  int ret = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
       const_cast<hw_module_t const**>(
-          reinterpret_cast<hw_module_t**>(&sensor_module)));
+      reinterpret_cast<hw_module_t**>(&sensor_module)));
   if (ret || !sensor_module) {
     fprintf(stderr, "Failed to load %s module: %s\n",
             SENSORS_HARDWARE_MODULE_ID, strerror(-ret));
     return 1;
   }
 
-  sensor_t const* sensor_list = nullptr;
-
-  int sensor_count = sensor_module->get_sensors_list(sensor_module, &sensor_list);
+  const sensor_t *sensor_list = nullptr;
+  int sensor_count =
+      sensor_module->get_sensors_list(sensor_module, &sensor_list);
   printf("Found %d supported sensors\n", sensor_count);
-
   for (int i = 0; i < sensor_count; i++) {
     printf("HAL supports sensor %s\n", sensor_list[i].name);
   }
@@ -54,66 +175,63 @@
     return 1;
   }
 
-  // Find the first accellerometer that can be opened
-  int accelerometer_index = -1;
+  // Find the first sensor of the specified type that can be opened
+  bool sensor_found = false;
+  const sensor_t *sensor = nullptr;
   for (int i = 0; i < sensor_count; i++) {
-    if (sensor_list[i].type != SENSOR_TYPE_ACCELEROMETER)
+    sensor = &sensor_list[i];
+    if (sensor->type != options.sensor_type)
       continue;
-    ret = sensor_device->activate(
-      reinterpret_cast<sensors_poll_device_t*>(sensor_device),
-      sensor_list[i].handle, 1 /* enabled */);
-    if (ret) {
-      fprintf(stderr, "Unable to activate %s\n", sensor_list[i].name);
+    if (sensor_device->activate(
+        reinterpret_cast<sensors_poll_device_t*>(sensor_device),
+        sensor->handle, 1 /* enabled */) < 0) {
       continue;
     }
 
-    // found an equipped accelerometer.
-    accelerometer_index = i;
+    // Found an equipped sensor of the specified type.
+    sensor_found = true;
     break;
   }
 
-  if (ret) {
-    fprintf(stderr, "No accelerometer found\n");
+  if (!sensor_found) {
+    fprintf(stderr, "No sensor of the specified type found\n");
     ret = sensors_close_1(sensor_device);
     if (ret)
-      fprintf(stderr, "Failed to close the accelerometer device\n");
+      fprintf(stderr, "Failed to close the sensor device\n");
     return 1;
   }
+  printf("\nSensor %s activated\n", sensor->name);
 
-  printf("\nSensor %s activated\n", sensor_list[accelerometer_index].name);
-
-  const int kNumSamples = 10;
   const int kNumEvents = 1;
+  const int kNumSamples = 10;
   const int kWaitTimeSecs = 1;
-
   for (int i = 0; i < kNumSamples; i++) {
-    sensors_event_t data;
+    sensors_event_t data[kNumEvents];
+    memset(data, 0, sizeof(data));
     int event_count = sensor_device->poll(
         reinterpret_cast<sensors_poll_device_t*>(sensor_device),
-        &data, kNumEvents);
+        data, kNumEvents);
     if (!event_count) {
-      fprintf(stderr, "Failed to read data from the accelerometer\n");
-      break;
-    } else {
-      printf("Acceleration: x = %f, y = %f, z = %f\n",
-             data.acceleration.x, data.acceleration.y, data.acceleration.z);
+      fprintf(stderr, "Failed to read data from the sensor.\n");
+      continue;
     }
 
+    DisplaySensorData(options.sensor_type, data);
     sleep(kWaitTimeSecs);
   }
 
   ret = sensor_device->activate(
       reinterpret_cast<sensors_poll_device_t*>(sensor_device),
-      sensor_list[accelerometer_index].handle, 0 /* disabled */);
+      sensor->handle, 0 /* disabled */);
   if (ret) {
-    fprintf(stderr, "Failed to disable the accelerometer\n");
+    fprintf(stderr, "Failed to disable %s: %s\n", sensor->name, strerror(ret));
     return 1;
   }
 
   // sensors_close_1 is used in HAL versions >= 1.0.
   ret = sensors_close_1(sensor_device);
   if (ret) {
-    fprintf(stderr, "Failed to close the accelerometer device\n");
+    fprintf(stderr, "Failed to close the sensor device\n");
     return 1;
   }
 
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" },
-  };
-
-  const int kNumSamples = 10;
-  const int kNumEvents = 1;
+  // Find the first sensor of the specified type that can be opened
+  const int kTimeoutMicroSecs = 1000000;
   const int kTimeoutMilliSecs = 1000;
-  const int kWaitTimeSecs = 1;
-
-  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);
-      }
-
-      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());
+  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;
   }
 
-  int ret = ASensorManager_destroyEventQueue(sensor_manager, queue);
-  if (ret) {
-    fprintf(stderr, "Failed to destroy event queue: %s\n", strerror(ret));
+  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 kNumEvents = 1;
+  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;
+    }
+
+    DisplaySensorData(options.sensor_type, data);
+    sleep(kWaitTimeSecs);
+  }
+
+  int ret = ASensorEventQueue_disableSensor(queue, sensor);
+  if (ret < 0) {
+    fprintf(stderr, "Failed to disable %s: %s\n",
+            ASensor_getName(sensor), strerror(-ret));
+  }
+
+  ret = ASensorManager_destroyEventQueue(sensor_manager, queue);
+  if (ret < 0) {
+    fprintf(stderr, "Failed to destroy event queue: %s\n", strerror(-ret));
     return 1;
   }