This fixes the hardware emulation to support several clients listening
to the "sensors" service at the same time. Each client can decide to
listen to different sensors, with different delays too.

The previous implementation only allowed a single client, which blocked
anything application that tried to read the sensors (since the framework
was already the only allowed client)

Signed-off-by: David 'Digit' Turner <digit@google.com>
diff --git a/android/hw-sensors.c b/android/hw-sensors.c
index 37d4af7..1fa12dc 100644
--- a/android/hw-sensors.c
+++ b/android/hw-sensors.c
@@ -13,6 +13,7 @@
 #include "android/hw-sensors.h"
 #include "android/utils/debug.h"
 #include "android/utils/misc.h"
+#include "android/utils/system.h"
 #include "android/hw-qemud.h"
 #include "android/globals.h"
 #include "qemu-char.h"
@@ -139,46 +140,292 @@
 #define  HEADER_SIZE  4
 #define  BUFFER_SIZE  512
 
+typedef struct HwSensorClient   HwSensorClient;
+
 typedef struct {
-    QemudService*   service;
-    int32_t         delay_ms;
-    uint32_t        enabledMask;
-    QEMUTimer*      timer;
-    Sensor          sensors[MAX_SENSORS];
+    QemudService*    service;
+    Sensor           sensors[MAX_SENSORS];
+    HwSensorClient*  clients;
 } HwSensors;
 
+struct HwSensorClient {
+    HwSensorClient*  next;
+    HwSensors*       sensors;
+    QemudClient*     client;
+    QEMUTimer*       timer;
+    uint32_t         enabledMask;
+    int32_t          delay_ms;
+};
+
+static void
+_hwSensorClient_free( HwSensorClient*  cl )
+{
+    /* remove from sensors's list */
+    if (cl->sensors) {
+        HwSensorClient**  pnode = &cl->sensors->clients;
+        for (;;) {
+            HwSensorClient*  node = *pnode;
+            if (node == NULL)
+                break;
+            if (node == cl) {
+                *pnode = cl->next;
+                break;
+            }
+            pnode = &node->next;
+        }
+        cl->next    = NULL;
+        cl->sensors = NULL;
+    }
+
+    /* close QEMUD client, if any */
+    if (cl->client) {
+        qemud_client_close(cl->client);
+        cl->client = NULL;
+    }
+    /* remove timer, if any */
+    if (cl->timer) {
+        qemu_del_timer(cl->timer);
+        qemu_free_timer(cl->timer);
+        cl->timer = NULL;
+    }
+    AFREE(cl);
+}
+
+/* forward */
+static void  _hwSensorClient_tick(void*  opaque);
+
+
+static HwSensorClient*
+_hwSensorClient_new( HwSensors*  sensors )
+{
+    HwSensorClient*  cl;
+
+    ANEW0(cl);
+
+    cl->sensors     = sensors;
+    cl->enabledMask = 0;
+    cl->delay_ms    = 1000;
+    cl->timer       = qemu_new_timer(vm_clock, _hwSensorClient_tick, cl);
+
+    cl->next         = sensors->clients;
+    sensors->clients = cl;
+
+    return cl;
+}
+
 /* forward */
 
-static void  hw_sensors_receive( HwSensors*  h,
-                                 uint8_t*    query,
-                                 int         querylen );
-
-static void  hw_sensors_timer_tick(void*  opaque);
+static void  _hwSensorClient_receive( HwSensorClient*  cl,
+                                      uint8_t*         query,
+                                      int              querylen );
 
 /* Qemud service management */
 
 static void
-_hw_sensors_qemud_client_recv( void*  opaque, uint8_t*  msg, int  msglen,
-                               QemudClient*  client )
+_hwSensorClient_recv( void*  opaque, uint8_t*  msg, int  msglen,
+                      QemudClient*  client )
 {
-    hw_sensors_receive(opaque, msg, msglen);
+    HwSensorClient*  cl = opaque;
+
+    _hwSensorClient_receive(cl, msg, msglen);
 }
 
-static QemudClient*
-_hw_sensors_service_connect( void*  opaque, QemudService*  service, int  channel )
+static void
+_hwSensorClient_close( void*  opaque )
 {
-    HwSensors*    sensors = opaque;
-    QemudClient*  client  = qemud_client_new(service, channel,
-                                             sensors,
-                                             _hw_sensors_qemud_client_recv,
-                                             NULL);
+    HwSensorClient*  cl = opaque;
+
+    /* the client is already closed here */
+    cl->client = NULL;
+    _hwSensorClient_free(cl);
+}
+
+/* send a one-line message to the HAL module through a qemud channel */
+static void
+_hwSensorClient_send( HwSensorClient*  cl, const uint8_t*  msg, int  msglen )
+{
+    D("%s: '%s'", __FUNCTION__, quote_bytes((const void*)msg, msglen));
+    qemud_client_send(cl->client, msg, msglen);
+}
+
+static int
+_hwSensorClient_enabled( HwSensorClient*  cl, int  sensorId )
+{
+    return (cl->enabledMask & (1 << sensorId)) != 0;
+}
+
+/* this function is called periodically to send sensor reports
+ * to the HAL module, and re-arm the timer if necessary
+ */
+static void
+_hwSensorClient_tick( void*  opaque )
+{
+    HwSensorClient*  cl = opaque;
+    HwSensors*       hw  = cl->sensors;
+    int64_t          delay = cl->delay_ms;
+    int64_t          now_ns;
+    uint32_t         mask  = cl->enabledMask;
+    Sensor*          sensor;
+    char             buffer[128];
+
+    if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ACCELERATION)) {
+        sensor = &hw->sensors[ANDROID_SENSOR_ACCELERATION];
+        snprintf(buffer, sizeof buffer, "acceleration:%g:%g:%g",
+                 sensor->u.acceleration.x,
+                 sensor->u.acceleration.y,
+                 sensor->u.acceleration.z);
+        _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
+    }
+
+    if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_MAGNETIC_FIELD)) {
+        sensor = &hw->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
+        snprintf(buffer, sizeof buffer, "magnetic-field:%g:%g:%g",
+                 sensor->u.magnetic.x,
+                 sensor->u.magnetic.y,
+                 sensor->u.magnetic.z);
+        _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
+    }
+
+    if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ORIENTATION)) {
+        sensor = &hw->sensors[ANDROID_SENSOR_ORIENTATION];
+        snprintf(buffer, sizeof buffer, "orientation:%g:%g:%g",
+                 sensor->u.orientation.azimuth,
+                 sensor->u.orientation.pitch,
+                 sensor->u.orientation.roll);
+        _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
+    }
+
+    if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_TEMPERATURE)) {
+        sensor = &hw->sensors[ANDROID_SENSOR_TEMPERATURE];
+        snprintf(buffer, sizeof buffer, "temperature:%g",
+                 sensor->u.temperature.celsius);
+        _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
+    }
+
+    now_ns = qemu_get_clock(vm_clock);
+
+    snprintf(buffer, sizeof buffer, "sync:%lld", now_ns/1000);
+    _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
+
+    /* rearm timer, use a minimum delay of 20 ms, just to
+     * be safe.
+     */
+    if (mask == 0)
+        return;
+
+    if (delay < 20)
+        delay = 20;
+
+    delay *= 1000000LL;  /* convert to nanoseconds */
+    qemu_mod_timer(cl->timer, now_ns + delay);
+}
+
+/* handle incoming messages from the HAL module */
+static void
+_hwSensorClient_receive( HwSensorClient*  cl, uint8_t*  msg, int  msglen )
+{
+    HwSensors*  hw = cl->sensors;
+
+    D("%s: '%.*s'", __FUNCTION__, msglen, msg);
+
+    /* "list-sensors" is used to get an integer bit map of
+     * available emulated sensors. We compute the mask from the
+     * current hardware configuration.
+     */
+    if (msglen == 12 && !memcmp(msg, "list-sensors", 12)) {
+        char  buff[12];
+        int   mask = 0;
+        int   nn;
+
+        for (nn = 0; nn < MAX_SENSORS; nn++) {
+            if (hw->sensors[nn].enabled)
+                mask |= (1 << nn);
+        }
+
+        snprintf(buff, sizeof buff, "%d", mask);
+        _hwSensorClient_send(cl, (const uint8_t*)buff, strlen(buff));
+        return;
+    }
+
+    /* "wake" is a special message that must be sent back through
+     * the channel. It is used to exit a blocking read.
+     */
+    if (msglen == 4 && !memcmp(msg, "wake", 4)) {
+        _hwSensorClient_send(cl, (const uint8_t*)"wake", 4);
+        return;
+    }
+
+    /* "set-delay:<delay>" is used to set the delay in milliseconds
+     * between sensor events
+     */
+    if (msglen > 10 && !memcmp(msg, "set-delay:", 10)) {
+        cl->delay_ms = atoi((const char*)msg+10);
+        if (cl->enabledMask != 0)
+            _hwSensorClient_tick(cl);
+
+        return;
+    }
+
+    /* "set:<name>:<state>" is used to enable/disable a given
+     * sensor. <state> must be 0 or 1
+     */
+    if (msglen > 4 && !memcmp(msg, "set:", 4)) {
+        char*  q;
+        int    id, enabled, oldEnabledMask = cl->enabledMask;
+        msg += 4;
+        q    = strchr((char*)msg, ':');
+        if (q == NULL) {  /* should not happen */
+            D("%s: ignore bad 'set' command", __FUNCTION__);
+            return;
+        }
+        *q++ = 0;
+
+        id = _sensorIdFromName((const char*)msg);
+        if (id < 0 || id >= MAX_SENSORS) {
+            D("%s: ignore unknown sensor name '%s'", __FUNCTION__, msg);
+            return;
+        }
+
+        if (!hw->sensors[id].enabled) {
+            D("%s: trying to set disabled %s sensor", __FUNCTION__, msg);
+            return;
+        }
+        enabled = (q[0] == '1');
+
+        if (enabled)
+            cl->enabledMask |= (1 << id);
+        else
+            cl->enabledMask &= ~(1 << id);
+
+        if (cl->enabledMask != oldEnabledMask) {
+            D("%s: %s %s sensor", __FUNCTION__,
+                (cl->enabledMask & (1 << id))  ? "enabling" : "disabling",  msg);
+        }
+        _hwSensorClient_tick(cl);
+        return;
+    }
+
+    D("%s: ignoring unknown query", __FUNCTION__);
+}
+
+
+static QemudClient*
+_hwSensors_connect( void*  opaque, QemudService*  service, int  channel )
+{
+    HwSensors*       sensors = opaque;
+    HwSensorClient*  cl      = _hwSensorClient_new(sensors);
+    QemudClient*     client  = qemud_client_new(service, channel, cl,
+                                                _hwSensorClient_recv,
+                                                _hwSensorClient_close);
     qemud_client_set_framing(client, 1);
+    cl->client = client;
+
     return client;
 }
 
 /* change the value of the emulated acceleration vector */
 static void
-hw_sensors_set_acceleration( HwSensors*  h, float x, float y, float z )
+_hwSensors_setAcceleration( HwSensors*  h, float x, float y, float z )
 {
     Sensor*  s = &h->sensors[ANDROID_SENSOR_ACCELERATION];
     s->u.acceleration.x = x;
@@ -189,7 +436,7 @@
 #if 0  /* not used yet */
 /* change the value of the emulated magnetic vector */
 static void
-hw_sensors_set_magnetic_field( HwSensors*  h, float x, float y, float z )
+_hwSensors_setMagneticField( HwSensors*  h, float x, float y, float z )
 {
     Sensor*  s = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
     s->u.magnetic.x = x;
@@ -199,9 +446,9 @@
 
 /* change the values of the emulated orientation */
 static void
-hw_sensors_set_orientation( HwSensors*  h, float azimuth, float pitch, float roll )
+_hwSensors_setOrientation( HwSensors*  h, float azimuth, float pitch, float roll )
 {
-    Sensor*  s = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
+    Sensor*  s = &h->sensors[ANDROID_SENSOR_ORIENTATION];
     s->u.orientation.azimuth = azimuth;
     s->u.orientation.pitch   = pitch;
     s->u.orientation.roll    = roll;
@@ -209,16 +456,16 @@
 
 /* change the emulated temperature */
 static void
-hw_sensors_set_temperature( HwSensors*  h, float celsius )
+_hwSensors_setTemperature( HwSensors*  h, float celsius )
 {
-    Sensor*  s = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
+    Sensor*  s = &h->sensors[ANDROID_SENSOR_TEMPERATURE];
     s->u.temperature.celsius = celsius;
 }
 #endif
 
 /* change the coarse orientation (landscape/portrait) of the emulated device */
 static void
-hw_sensors_set_coarse_orientation( HwSensors*  h, AndroidCoarseOrientation  orient )
+_hwSensors_setCoarseOrientation( HwSensors*  h, AndroidCoarseOrientation  orient )
 {
     /* The Android framework computes the orientation by looking at
      * the accelerometer sensor (*not* the orientation sensor !)
@@ -238,11 +485,11 @@
 
     switch (orient) {
     case ANDROID_COARSE_PORTRAIT:
-        hw_sensors_set_acceleration( h, 0., g*cos_30, g*sin_30 );
+        _hwSensors_setAcceleration( h, 0., g*cos_30, g*sin_30 );
         break;
 
     case ANDROID_COARSE_LANDSCAPE:
-        hw_sensors_set_acceleration( h, g*cos_30, 0., g*sin_30 );
+        _hwSensors_setAcceleration( h, g*cos_30, 0., g*sin_30 );
         break;
     default:
         ;
@@ -252,182 +499,20 @@
 
 /* initialize the sensors state */
 static void
-hw_sensors_init( HwSensors*  h )
+_hwSensors_init( HwSensors*  h )
 {
-    h->service = qemud_service_register("sensors", 1, h,
-                                        _hw_sensors_service_connect );
-    h->enabledMask = 0;
-    h->delay_ms    = 1000;
-    h->timer       = qemu_new_timer(vm_clock, hw_sensors_timer_tick, h);
+    h->service = qemud_service_register("sensors", 0, h,
+                                        _hwSensors_connect );
 
-    hw_sensors_set_coarse_orientation(h, ANDROID_COARSE_PORTRAIT);
+    if (android_hw->hw_accelerometer)
+        h->sensors[ANDROID_SENSOR_ACCELERATION].enabled = 1;
+
+    /* XXX: TODO: Add other tests when we add the corresponding
+        * properties to hardware-properties.ini et al. */
+
+    _hwSensors_setCoarseOrientation(h, ANDROID_COARSE_PORTRAIT);
 }
 
-/* send a one-line message to the HAL module through a qemud channel */
-static void
-hw_sensors_send( HwSensors*  hw, const uint8_t*  msg, int  msglen )
-{
-    D("%s: '%s'", __FUNCTION__, quote_bytes((const void*)msg, msglen));
-    qemud_service_broadcast(hw->service, msg, msglen);
-}
-
-/* this function is called periodically to send sensor reports
- * to the HAL module, and re-arm the timer if necessary
- */
-static void
-hw_sensors_timer_tick( void*  opaque )
-{
-    HwSensors*  h = opaque;
-    int64_t     delay = h->delay_ms;
-    int64_t     now_ns;
-    uint32_t    mask  = h->enabledMask;
-    Sensor*     sensor;
-    char        buffer[128];
-
-    sensor = &h->sensors[ANDROID_SENSOR_ACCELERATION];
-    if (sensor->enabled) {
-        snprintf(buffer, sizeof buffer, "acceleration:%g:%g:%g",
-                 sensor->u.acceleration.x,
-                 sensor->u.acceleration.y,
-                 sensor->u.acceleration.z);
-        hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer));
-    }
-
-    sensor = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
-    if (sensor->enabled) {
-        snprintf(buffer, sizeof buffer, "magnetic-field:%g:%g:%g",
-                 sensor->u.magnetic.x,
-                 sensor->u.magnetic.y,
-                 sensor->u.magnetic.z);
-        hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer));
-    }
-
-    sensor = &h->sensors[ANDROID_SENSOR_ORIENTATION];
-    if (sensor->enabled) {
-        snprintf(buffer, sizeof buffer, "orientation:%g:%g:%g",
-                 sensor->u.orientation.azimuth,
-                 sensor->u.orientation.pitch,
-                 sensor->u.orientation.roll);
-        hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer));
-    }
-
-    sensor = &h->sensors[ANDROID_SENSOR_TEMPERATURE];
-    if (sensor->enabled) {
-        snprintf(buffer, sizeof buffer, "temperature:%g",
-                 sensor->u.temperature.celsius);
-        hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer));
-    }
-
-    now_ns = qemu_get_clock(vm_clock);
-
-    snprintf(buffer, sizeof buffer, "sync:%lld", now_ns/1000);
-    hw_sensors_send(h, (uint8_t*)buffer, strlen(buffer));
-
-    /* rearm timer, use a minimum delay of 20 ms, just to
-     * be safe.
-     */
-    if (mask == 0)
-        return;
-
-    if (delay < 20)
-        delay = 20;
-
-    delay *= 1000000LL;  /* convert to nanoseconds */
-    qemu_mod_timer(h->timer, now_ns + delay);
-}
-
-/* handle incoming messages from the HAL module */
-static void
-hw_sensors_receive( HwSensors*  hw, uint8_t*  msg, int  msglen )
-{
-    D("%s: '%.*s'", __FUNCTION__, msglen, msg);
-
-    /* "list-sensors" is used to get an integer bit map of
-     * available emulated sensors. We compute the mask from the
-     * current hardware configuration.
-     */
-    if (msglen == 12 && !memcmp(msg, "list-sensors", 12)) {
-        char  buff[12];
-        int   mask = 0;
-
-        if (android_hw->hw_accelerometer)
-            mask |= (1 << ANDROID_SENSOR_ACCELERATION);
-
-        /* XXX: TODO: Add other tests when we add the corresponding
-         * properties to hardware-properties.ini et al. */
-
-        snprintf(buff, sizeof buff, "%d", mask);
-        hw_sensors_send(hw, (const uint8_t*)buff, strlen(buff));
-        return;
-    }
-
-    /* "wake" is a special message that must be sent back through
-     * the channel. It is used to exit a blocking read.
-     */
-    if (msglen == 4 && !memcmp(msg, "wake", 4)) {
-        hw_sensors_send(hw, (const uint8_t*)"wake", 4);
-        return;
-    }
-
-    /* "set-delay:<delay>" is used to set the delay in milliseconds
-     * between sensor events
-     */
-    if (msglen > 10 && !memcmp(msg, "set-delay:", 10)) {
-        hw->delay_ms = atoi((const char*)msg+10);
-        if (hw->enabledMask != 0)
-            hw_sensors_timer_tick(hw);
-
-        return;
-    }
-
-    /* "set:<name>:<state>" is used to enable/disable a given
-     * sensor. <state> must be 0 or 1
-     */
-    if (msglen > 4 && !memcmp(msg, "set:", 4)) {
-        char*  q;
-        int    id, enabled, oldEnabledMask = hw->enabledMask;
-        msg += 4;
-        q    = strchr((char*)msg, ':');
-        if (q == NULL) {  /* should not happen */
-            D("%s: ignore bad 'set' command", __FUNCTION__);
-            return;
-        }
-        *q++ = 0;
-
-        id = _sensorIdFromName((const char*)msg);
-        if (id < 0) {
-            D("%s: ignore unknown sensor name '%s'", __FUNCTION__, msg);
-            return;
-        }
-
-        enabled = (q[0] == '1');
-
-        hw->sensors[id].enabled = (char) enabled;
-        if (enabled)
-            hw->enabledMask |= (1 << id);
-        else
-            hw->enabledMask &= ~(1 << id);
-
-        D("%s: %s %s sensor", __FUNCTION__,
-          hw->sensors[id].enabled ? "enabling" : "disabling",  msg);
-
-        if (oldEnabledMask == 0 && enabled) {
-            /* we enabled our first sensor, start event reporting */
-            D("%s: starting event reporting (mask=%04x)", __FUNCTION__,
-              hw->enabledMask);
-        }
-        else if (hw->enabledMask == 0 && !enabled) {
-            /* we disabled our last sensor, stop event reporting */
-            D("%s: stopping event reporting", __FUNCTION__);
-        }
-        hw_sensors_timer_tick(hw);
-        return;
-    }
-
-    D("%s: ignoring unknown query", __FUNCTION__);
-}
-
-
 static HwSensors    _sensorsState[1];
 
 void
@@ -436,7 +521,7 @@
     HwSensors*  hw = _sensorsState;
 
     if (hw->service == NULL) {
-        hw_sensors_init(hw);
+        _hwSensors_init(hw);
         D("%s: sensors qemud service initialized", __FUNCTION__);
     }
 }
@@ -446,6 +531,6 @@
 android_sensors_set_coarse_orientation( AndroidCoarseOrientation  orient )
 {
     android_hw_sensors_init();
-    hw_sensors_set_coarse_orientation(_sensorsState, orient);
+    _hwSensors_setCoarseOrientation(_sensorsState, orient);
 }