Home | History | Annotate | Download | only in android
      1 /* Copyright (C) 2009 The Android Open Source Project
      2 **
      3 ** This software is licensed under the terms of the GNU General Public
      4 ** License version 2, as published by the Free Software Foundation, and
      5 ** may be copied, distributed, and modified under those terms.
      6 **
      7 ** This program is distributed in the hope that it will be useful,
      8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 ** GNU General Public License for more details.
     11 */
     12 
     13 #include <math.h>
     14 #include "android/hw-sensors.h"
     15 #include "android/utils/debug.h"
     16 #include "android/utils/misc.h"
     17 #include "android/utils/system.h"
     18 #include "android/hw-qemud.h"
     19 #include "android/globals.h"
     20 #include "hw/hw.h"
     21 #include "sysemu/char.h"
     22 #include "qemu/timer.h"
     23 #include "android/sensors-port.h"
     24 
     25 #define  E(...)    derror(__VA_ARGS__)
     26 #define  W(...)    dwarning(__VA_ARGS__)
     27 #define  D(...)  VERBOSE_PRINT(sensors,__VA_ARGS__)
     28 #define  V(...)  VERBOSE_PRINT(init,__VA_ARGS__)
     29 
     30 /* define T_ACTIVE to 1 to debug transport communications */
     31 #define  T_ACTIVE  0
     32 
     33 #if T_ACTIVE
     34 #define  T(...)  VERBOSE_PRINT(sensors,__VA_ARGS__)
     35 #else
     36 #define  T(...)   ((void)0)
     37 #endif
     38 
     39 /* this code supports emulated sensor hardware
     40  *
     41  * Note that currently, only the accelerometer is really emulated, and only
     42  * for the purpose of allowing auto-rotating the screen in keyboard-less
     43  * configurations.
     44  *
     45  *
     46  */
     47 
     48 
     49 static const struct {
     50     const char*  name;
     51     int          id;
     52 } _sSensors[MAX_SENSORS] = {
     53 #define SENSOR_(x,y)  { y, ANDROID_SENSOR_##x },
     54   SENSORS_LIST
     55 #undef SENSOR_
     56 };
     57 
     58 
     59 static int
     60 _sensorIdFromName( const char*  name )
     61 {
     62     int  nn;
     63     for (nn = 0; nn < MAX_SENSORS; nn++)
     64         if (!strcmp(_sSensors[nn].name,name))
     65             return _sSensors[nn].id;
     66     return -1;
     67 }
     68 
     69 static const char*
     70 _sensorNameFromId( int  id )
     71 {
     72     int  nn;
     73     for (nn = 0; nn < MAX_SENSORS; nn++)
     74         if (id == _sSensors[nn].id)
     75             return _sSensors[nn].name;
     76     return NULL;
     77 }
     78 
     79 /* For common Sensor Value struct */
     80 typedef struct {
     81     float a, b, c;
     82 } SensorValues;
     83 
     84 typedef struct {
     85     float   x, y, z;
     86 } Acceleration;
     87 
     88 
     89 typedef struct {
     90     float  x, y, z;
     91 } MagneticField;
     92 
     93 
     94 typedef struct {
     95     float  azimuth;
     96     float  pitch;
     97     float  roll;
     98 } Orientation;
     99 
    100 
    101 typedef struct {
    102     float  celsius;
    103 } Temperature;
    104 
    105 
    106 typedef struct {
    107     float  value;
    108 } Proximity;
    109 
    110 typedef struct {
    111     char       enabled;
    112     union {
    113         SensorValues   value;
    114         Acceleration   acceleration;
    115         MagneticField  magnetic;
    116         Orientation    orientation;
    117         Temperature    temperature;
    118         Proximity      proximity;
    119     } u;
    120 } Sensor;
    121 
    122 /*
    123  * - when the qemu-specific sensors HAL module starts, it sends
    124  *   "list-sensors"
    125  *
    126  * - this code replies with a string containing an integer corresponding
    127  *   to a bitmap of available hardware sensors in the current AVD
    128  *   configuration (e.g. "1" a.k.a (1 << ANDROID_SENSOR_ACCELERATION))
    129  *
    130  * - the HAL module sends "set:<sensor>:<flag>" to enable or disable
    131  *   the report of a given sensor state. <sensor> must be the name of
    132  *   a given sensor (e.g. "accelerometer"), and <flag> must be either
    133  *   "1" (to enable) or "0" (to disable).
    134  *
    135  * - Once at least one sensor is "enabled", this code should periodically
    136  *   send information about the corresponding enabled sensors. The default
    137  *   period is 200ms.
    138  *
    139  * - the HAL module sends "set-delay:<delay>", where <delay> is an integer
    140  *   corresponding to a time delay in milli-seconds. This corresponds to
    141  *   a new interval between sensor events sent by this code to the HAL
    142  *   module.
    143  *
    144  * - the HAL module can also send a "wake" command. This code should simply
    145  *   send the "wake" back to the module. This is used internally to wake a
    146  *   blocking read that happens in a different thread. This ping-pong makes
    147  *   the code in the HAL module very simple.
    148  *
    149  * - each timer tick, this code sends sensor reports in the following
    150  *   format (each line corresponds to a different line sent to the module):
    151  *
    152  *      acceleration:<x>:<y>:<z>
    153  *      magnetic-field:<x>:<y>:<z>
    154  *      orientation:<azimuth>:<pitch>:<roll>
    155  *      temperature:<celsius>
    156  *      sync:<time_us>
    157  *
    158  *   Where each line before the sync:<time_us> is optional and will only
    159  *   appear if the corresponding sensor has been enabled by the HAL module.
    160  *
    161  *   Note that <time_us> is the VM time in micro-seconds when the report
    162  *   was "taken" by this code. This is adjusted by the HAL module to
    163  *   emulated system time (using the first sync: to compute an adjustment
    164  *   offset).
    165  */
    166 #define  HEADER_SIZE  4
    167 #define  BUFFER_SIZE  512
    168 
    169 typedef struct HwSensorClient   HwSensorClient;
    170 
    171 typedef struct {
    172     QemudService*       service;
    173     Sensor              sensors[MAX_SENSORS];
    174     HwSensorClient*     clients;
    175     AndroidSensorsPort* sensors_port;
    176 } HwSensors;
    177 
    178 struct HwSensorClient {
    179     HwSensorClient*  next;
    180     HwSensors*       sensors;
    181     QemudClient*     client;
    182     QEMUTimer*       timer;
    183     uint32_t         enabledMask;
    184     int32_t          delay_ms;
    185 };
    186 
    187 static void
    188 _hwSensorClient_free( HwSensorClient*  cl )
    189 {
    190     /* remove from sensors's list */
    191     if (cl->sensors) {
    192         HwSensorClient**  pnode = &cl->sensors->clients;
    193         for (;;) {
    194             HwSensorClient*  node = *pnode;
    195             if (node == NULL)
    196                 break;
    197             if (node == cl) {
    198                 *pnode = cl->next;
    199                 break;
    200             }
    201             pnode = &node->next;
    202         }
    203         cl->next    = NULL;
    204         cl->sensors = NULL;
    205     }
    206 
    207     /* close QEMUD client, if any */
    208     if (cl->client) {
    209         qemud_client_close(cl->client);
    210         cl->client = NULL;
    211     }
    212     /* remove timer, if any */
    213     if (cl->timer) {
    214         timer_del(cl->timer);
    215         timer_free(cl->timer);
    216         cl->timer = NULL;
    217     }
    218     AFREE(cl);
    219 }
    220 
    221 /* forward */
    222 static void  _hwSensorClient_tick(void*  opaque);
    223 
    224 
    225 static HwSensorClient*
    226 _hwSensorClient_new( HwSensors*  sensors )
    227 {
    228     HwSensorClient*  cl;
    229 
    230     ANEW0(cl);
    231 
    232     cl->sensors     = sensors;
    233     cl->enabledMask = 0;
    234     cl->delay_ms    = 800;
    235     cl->timer       = timer_new(QEMU_CLOCK_VIRTUAL, SCALE_NS, _hwSensorClient_tick, cl);
    236 
    237     cl->next         = sensors->clients;
    238     sensors->clients = cl;
    239 
    240     return cl;
    241 }
    242 
    243 /* forward */
    244 
    245 static void  _hwSensorClient_receive( HwSensorClient*  cl,
    246                                       uint8_t*         query,
    247                                       int              querylen );
    248 
    249 /* Qemud service management */
    250 
    251 static void
    252 _hwSensorClient_recv( void*  opaque, uint8_t*  msg, int  msglen,
    253                       QemudClient*  client )
    254 {
    255     HwSensorClient*  cl = opaque;
    256 
    257     _hwSensorClient_receive(cl, msg, msglen);
    258 }
    259 
    260 static void
    261 _hwSensorClient_close( void*  opaque )
    262 {
    263     HwSensorClient*  cl = opaque;
    264 
    265     /* the client is already closed here */
    266     cl->client = NULL;
    267     _hwSensorClient_free(cl);
    268 }
    269 
    270 /* send a one-line message to the HAL module through a qemud channel */
    271 static void
    272 _hwSensorClient_send( HwSensorClient*  cl, const uint8_t*  msg, int  msglen )
    273 {
    274     D("%s: '%s'", __FUNCTION__, quote_bytes((const void*)msg, msglen));
    275     qemud_client_send(cl->client, msg, msglen);
    276 }
    277 
    278 static int
    279 _hwSensorClient_enabled( HwSensorClient*  cl, int  sensorId )
    280 {
    281     return (cl->enabledMask & (1 << sensorId)) != 0;
    282 }
    283 
    284 /* this function is called periodically to send sensor reports
    285  * to the HAL module, and re-arm the timer if necessary
    286  */
    287 static void
    288 _hwSensorClient_tick( void*  opaque )
    289 {
    290     HwSensorClient*  cl = opaque;
    291     HwSensors*       hw  = cl->sensors;
    292     int64_t          delay = cl->delay_ms;
    293     int64_t          now_ns;
    294     uint32_t         mask  = cl->enabledMask;
    295     Sensor*          sensor;
    296     char             buffer[128];
    297 
    298     if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ACCELERATION)) {
    299         sensor = &hw->sensors[ANDROID_SENSOR_ACCELERATION];
    300         snprintf(buffer, sizeof buffer, "acceleration:%g:%g:%g",
    301                  sensor->u.acceleration.x,
    302                  sensor->u.acceleration.y,
    303                  sensor->u.acceleration.z);
    304         _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    305     }
    306 
    307     if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_MAGNETIC_FIELD)) {
    308         sensor = &hw->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
    309         /* NOTE: sensors HAL expects "magnetic", not "magnetic-field" name here. */
    310         snprintf(buffer, sizeof buffer, "magnetic:%g:%g:%g",
    311                  sensor->u.magnetic.x,
    312                  sensor->u.magnetic.y,
    313                  sensor->u.magnetic.z);
    314         _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    315     }
    316 
    317     if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ORIENTATION)) {
    318         sensor = &hw->sensors[ANDROID_SENSOR_ORIENTATION];
    319         snprintf(buffer, sizeof buffer, "orientation:%g:%g:%g",
    320                  sensor->u.orientation.azimuth,
    321                  sensor->u.orientation.pitch,
    322                  sensor->u.orientation.roll);
    323         _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    324     }
    325 
    326     if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_TEMPERATURE)) {
    327         sensor = &hw->sensors[ANDROID_SENSOR_TEMPERATURE];
    328         snprintf(buffer, sizeof buffer, "temperature:%g",
    329                  sensor->u.temperature.celsius);
    330         _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    331     }
    332 
    333     if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_PROXIMITY)) {
    334         sensor = &hw->sensors[ANDROID_SENSOR_PROXIMITY];
    335         snprintf(buffer, sizeof buffer, "proximity:%g",
    336                  sensor->u.proximity.value);
    337         _hwSensorClient_send(cl, (uint8_t*) buffer, strlen(buffer));
    338     }
    339 
    340     now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    341 
    342     snprintf(buffer, sizeof buffer, "sync:%" PRId64, now_ns/1000);
    343     _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    344 
    345     /* rearm timer, use a minimum delay of 20 ms, just to
    346      * be safe.
    347      */
    348     if (mask == 0)
    349         return;
    350 
    351     if (delay < 20)
    352         delay = 20;
    353 
    354     delay *= 1000000LL;  /* convert to nanoseconds */
    355     timer_mod(cl->timer, now_ns + delay);
    356 }
    357 
    358 /* handle incoming messages from the HAL module */
    359 static void
    360 _hwSensorClient_receive( HwSensorClient*  cl, uint8_t*  msg, int  msglen )
    361 {
    362     HwSensors*  hw = cl->sensors;
    363 
    364     D("%s: '%.*s'", __FUNCTION__, msglen, msg);
    365 
    366     /* "list-sensors" is used to get an integer bit map of
    367      * available emulated sensors. We compute the mask from the
    368      * current hardware configuration.
    369      */
    370     if (msglen == 12 && !memcmp(msg, "list-sensors", 12)) {
    371         char  buff[12];
    372         int   mask = 0;
    373         int   nn;
    374 
    375         for (nn = 0; nn < MAX_SENSORS; nn++) {
    376             if (hw->sensors[nn].enabled)
    377                 mask |= (1 << nn);
    378         }
    379 
    380         snprintf(buff, sizeof buff, "%d", mask);
    381         _hwSensorClient_send(cl, (const uint8_t*)buff, strlen(buff));
    382         return;
    383     }
    384 
    385     /* "wake" is a special message that must be sent back through
    386      * the channel. It is used to exit a blocking read.
    387      */
    388     if (msglen == 4 && !memcmp(msg, "wake", 4)) {
    389         _hwSensorClient_send(cl, (const uint8_t*)"wake", 4);
    390         return;
    391     }
    392 
    393     /* "set-delay:<delay>" is used to set the delay in milliseconds
    394      * between sensor events
    395      */
    396     if (msglen > 10 && !memcmp(msg, "set-delay:", 10)) {
    397         cl->delay_ms = atoi((const char*)msg+10);
    398         if (cl->enabledMask != 0)
    399             _hwSensorClient_tick(cl);
    400 
    401         return;
    402     }
    403 
    404     /* "set:<name>:<state>" is used to enable/disable a given
    405      * sensor. <state> must be 0 or 1
    406      */
    407     if (msglen > 4 && !memcmp(msg, "set:", 4)) {
    408         char*  q;
    409         int    id, enabled, oldEnabledMask = cl->enabledMask;
    410         msg += 4;
    411         q    = strchr((char*)msg, ':');
    412         if (q == NULL) {  /* should not happen */
    413             D("%s: ignore bad 'set' command", __FUNCTION__);
    414             return;
    415         }
    416         *q++ = 0;
    417 
    418         id = _sensorIdFromName((const char*)msg);
    419         if (id < 0 || id >= MAX_SENSORS) {
    420             D("%s: ignore unknown sensor name '%s'", __FUNCTION__, msg);
    421             return;
    422         }
    423 
    424         if (!hw->sensors[id].enabled) {
    425             D("%s: trying to set disabled %s sensor", __FUNCTION__, msg);
    426             return;
    427         }
    428         enabled = (q[0] == '1');
    429 
    430         if (enabled)
    431             cl->enabledMask |= (1 << id);
    432         else
    433             cl->enabledMask &= ~(1 << id);
    434 
    435         if (cl->enabledMask != oldEnabledMask) {
    436             D("%s: %s %s sensor", __FUNCTION__,
    437                 (cl->enabledMask & (1 << id))  ? "enabling" : "disabling",  msg);
    438         }
    439 
    440         /* If emulating device is connected update sensor state there too. */
    441         if (hw->sensors_port != NULL) {
    442             if (enabled) {
    443                 sensors_port_enable_sensor(hw->sensors_port, (const char*)msg);
    444             } else {
    445                 sensors_port_disable_sensor(hw->sensors_port, (const char*)msg);
    446             }
    447         }
    448 
    449         _hwSensorClient_tick(cl);
    450         return;
    451     }
    452 
    453     D("%s: ignoring unknown query", __FUNCTION__);
    454 }
    455 
    456 /* Saves sensor-specific client data to snapshot */
    457 static void
    458 _hwSensorClient_save( QEMUFile*  f, QemudClient*  client, void*  opaque  )
    459 {
    460     HwSensorClient* sc = opaque;
    461 
    462     qemu_put_be32(f, sc->delay_ms);
    463     qemu_put_be32(f, sc->enabledMask);
    464     timer_put(f, sc->timer);
    465 }
    466 
    467 /* Loads sensor-specific client data from snapshot */
    468 static int
    469 _hwSensorClient_load( QEMUFile*  f, QemudClient*  client, void*  opaque  )
    470 {
    471     HwSensorClient* sc = opaque;
    472 
    473     sc->delay_ms = qemu_get_be32(f);
    474     sc->enabledMask = qemu_get_be32(f);
    475     timer_get(f, sc->timer);
    476 
    477     return 0;
    478 }
    479 
    480 static QemudClient*
    481 _hwSensors_connect( void*  opaque,
    482                     QemudService*  service,
    483                     int  channel,
    484                     const char* client_param )
    485 {
    486     HwSensors*       sensors = opaque;
    487     HwSensorClient*  cl      = _hwSensorClient_new(sensors);
    488     QemudClient*     client  = qemud_client_new(service, channel, client_param, cl,
    489                                                 _hwSensorClient_recv,
    490                                                 _hwSensorClient_close,
    491                                                 _hwSensorClient_save,
    492                                                 _hwSensorClient_load );
    493     qemud_client_set_framing(client, 1);
    494     cl->client = client;
    495 
    496     return client;
    497 }
    498 
    499 /* change the value of the emulated sensor vector */
    500 static void
    501 _hwSensors_setSensorValue( HwSensors*  h, int sensor_id, float a, float b, float c )
    502 {
    503     Sensor* s = &h->sensors[sensor_id];
    504 
    505     s->u.value.a = a;
    506     s->u.value.b = b;
    507     s->u.value.c = c;
    508 }
    509 
    510 /* Saves available sensors to allow checking availability when loaded.
    511  */
    512 static void
    513 _hwSensors_save( QEMUFile*  f, QemudService*  sv, void*  opaque)
    514 {
    515     HwSensors* h = opaque;
    516 
    517     // number of sensors
    518     qemu_put_be32(f, MAX_SENSORS);
    519     AndroidSensor i;
    520     for (i = 0 ; i < MAX_SENSORS; i++) {
    521         Sensor* s = &h->sensors[i];
    522         qemu_put_be32(f, s->enabled);
    523 
    524         /* this switch ensures that a warning is raised when a new sensor is
    525          * added and is not added here as well.
    526          */
    527         switch (i) {
    528         case ANDROID_SENSOR_ACCELERATION:
    529             qemu_put_float(f, s->u.acceleration.x);
    530             qemu_put_float(f, s->u.acceleration.y);
    531             qemu_put_float(f, s->u.acceleration.z);
    532             break;
    533         case ANDROID_SENSOR_MAGNETIC_FIELD:
    534             qemu_put_float(f, s->u.magnetic.x);
    535             qemu_put_float(f, s->u.magnetic.y);
    536             qemu_put_float(f, s->u.magnetic.z);
    537             break;
    538         case ANDROID_SENSOR_ORIENTATION:
    539             qemu_put_float(f, s->u.orientation.azimuth);
    540             qemu_put_float(f, s->u.orientation.pitch);
    541             qemu_put_float(f, s->u.orientation.roll);
    542             break;
    543         case ANDROID_SENSOR_TEMPERATURE:
    544             qemu_put_float(f, s->u.temperature.celsius);
    545             break;
    546         case ANDROID_SENSOR_PROXIMITY:
    547             qemu_put_float(f, s->u.proximity.value);
    548             break;
    549         case MAX_SENSORS:
    550             break;
    551         }
    552     }
    553 }
    554 
    555 
    556 static int
    557 _hwSensors_load( QEMUFile*  f, QemudService*  s, void*  opaque)
    558 {
    559     HwSensors* h = opaque;
    560 
    561     /* check number of sensors */
    562     int32_t num_sensors = qemu_get_be32(f);
    563     if (num_sensors > MAX_SENSORS) {
    564         D("%s: cannot load: snapshot requires %d sensors, %d available\n",
    565           __FUNCTION__, num_sensors, MAX_SENSORS);
    566         return -EIO;
    567     }
    568 
    569     /* load sensor state */
    570     AndroidSensor i;
    571     for (i = 0 ; i < num_sensors; i++) {
    572         Sensor* s = &h->sensors[i];
    573         s->enabled = qemu_get_be32(f);
    574 
    575         /* this switch ensures that a warning is raised when a new sensor is
    576          * added and is not added here as well.
    577          */
    578         switch (i) {
    579         case ANDROID_SENSOR_ACCELERATION:
    580             s->u.acceleration.x = qemu_get_float(f);
    581             s->u.acceleration.y = qemu_get_float(f);
    582             s->u.acceleration.z = qemu_get_float(f);
    583             break;
    584         case ANDROID_SENSOR_MAGNETIC_FIELD:
    585             s->u.magnetic.x = qemu_get_float(f);
    586             s->u.magnetic.y = qemu_get_float(f);
    587             s->u.magnetic.z = qemu_get_float(f);
    588             break;
    589         case ANDROID_SENSOR_ORIENTATION:
    590             s->u.orientation.azimuth = qemu_get_float(f);
    591             s->u.orientation.pitch   = qemu_get_float(f);
    592             s->u.orientation.roll    = qemu_get_float(f);
    593             break;
    594         case ANDROID_SENSOR_TEMPERATURE:
    595             s->u.temperature.celsius = qemu_get_float(f);
    596             break;
    597         case ANDROID_SENSOR_PROXIMITY:
    598             s->u.proximity.value = qemu_get_float(f);
    599             break;
    600         case MAX_SENSORS:
    601             break;
    602         }
    603     }
    604 
    605     /* The following is necessary when we resume a snaphost
    606      * created by an older version of the emulator that provided
    607      * less hardware sensors.
    608      */
    609     for ( ; i < MAX_SENSORS; i++ ) {
    610         h->sensors[i].enabled = 0;
    611     }
    612 
    613     return 0;
    614 }
    615 
    616 
    617 /* change the emulated proximity */
    618 static void
    619 _hwSensors_setProximity( HwSensors*  h, float value )
    620 {
    621     Sensor*  s = &h->sensors[ANDROID_SENSOR_PROXIMITY];
    622     s->u.proximity.value = value;
    623 }
    624 
    625 /* change the coarse orientation (landscape/portrait) of the emulated device */
    626 static void
    627 _hwSensors_setCoarseOrientation( HwSensors*  h, AndroidCoarseOrientation  orient )
    628 {
    629     /* The Android framework computes the orientation by looking at
    630      * the accelerometer sensor (*not* the orientation sensor !)
    631      *
    632      * That's because the gravity is a constant 9.81 vector that
    633      * can be determined quite easily.
    634      *
    635      * Also, for some reason, the framework code considers that the phone should
    636      * be inclined by 30 degrees along the phone's X axis to be considered
    637      * in its ideal "vertical" position
    638      *
    639      * If the phone is completely vertical, rotating it will not do anything !
    640      */
    641     const double  g      = 9.81;
    642     const double  angle  = 20.0;
    643     const double  cos_angle = cos(angle/M_PI);
    644     const double  sin_angle = sin(angle/M_PI);
    645 
    646     switch (orient) {
    647     case ANDROID_COARSE_PORTRAIT:
    648         _hwSensors_setSensorValue( h, ANDROID_SENSOR_ACCELERATION, 0., g*cos_angle, g*sin_angle );
    649         break;
    650 
    651     case ANDROID_COARSE_LANDSCAPE:
    652         _hwSensors_setSensorValue( h, ANDROID_SENSOR_ACCELERATION, g*cos_angle, 0., g*sin_angle );
    653         break;
    654     default:
    655         ;
    656     }
    657 }
    658 
    659 
    660 /* initialize the sensors state */
    661 static void
    662 _hwSensors_init( HwSensors*  h )
    663 {
    664     /* Try to see if there is a device attached that can be used for
    665      * sensor emulation. */
    666     h->sensors_port = sensors_port_create(h);
    667     if (h->sensors_port == NULL) {
    668         V("Realistic sensor emulation is not available, since the remote controller is not accessible:\n %s",
    669           strerror(errno));
    670     }
    671 
    672     h->service = qemud_service_register("sensors", 0, h, _hwSensors_connect,
    673                                         _hwSensors_save, _hwSensors_load);
    674 
    675     if (android_hw->hw_accelerometer) {
    676         h->sensors[ANDROID_SENSOR_ACCELERATION].enabled = 1;
    677     }
    678 
    679     if (android_hw->hw_sensors_proximity) {
    680         h->sensors[ANDROID_SENSOR_PROXIMITY].enabled = 1;
    681     }
    682 
    683     if (android_hw->hw_sensors_magnetic_field) {
    684         h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD].enabled = 1;
    685     }
    686 
    687     if (android_hw->hw_sensors_orientation) {
    688         h->sensors[ANDROID_SENSOR_ORIENTATION].enabled = 1;
    689     }
    690 
    691     if (android_hw->hw_sensors_temperature) {
    692         h->sensors[ANDROID_SENSOR_TEMPERATURE].enabled = 1;
    693     }
    694 
    695     /* XXX: TODO: Add other tests when we add the corresponding
    696         * properties to hardware-properties.ini et al. */
    697 
    698     _hwSensors_setCoarseOrientation(h, ANDROID_COARSE_PORTRAIT);
    699     _hwSensors_setProximity(h, 1);
    700 }
    701 
    702 static HwSensors    _sensorsState[1];
    703 
    704 void
    705 android_hw_sensors_init( void )
    706 {
    707     HwSensors*  hw = _sensorsState;
    708 
    709     if (hw->service == NULL) {
    710         _hwSensors_init(hw);
    711         D("%s: sensors qemud service initialized", __FUNCTION__);
    712     }
    713 }
    714 
    715 /* change the coarse orientation value */
    716 extern void
    717 android_sensors_set_coarse_orientation( AndroidCoarseOrientation  orient )
    718 {
    719     android_hw_sensors_init();
    720     _hwSensors_setCoarseOrientation(_sensorsState, orient);
    721 }
    722 
    723 /* Get sensor name from sensor id */
    724 extern const char*
    725 android_sensors_get_name_from_id( int sensor_id )
    726 {
    727     if (sensor_id < 0 || sensor_id >= MAX_SENSORS)
    728         return NULL;
    729 
    730     return _sensorNameFromId(sensor_id);
    731 }
    732 
    733 /* Get sensor id from sensor name */
    734 extern int
    735 android_sensors_get_id_from_name( char* sensorname )
    736 {
    737     HwSensors* hw = _sensorsState;
    738 
    739     if (sensorname == NULL)
    740         return SENSOR_STATUS_UNKNOWN;
    741 
    742     int id = _sensorIdFromName(sensorname);
    743 
    744     if (id < 0 || id >= MAX_SENSORS)
    745         return SENSOR_STATUS_UNKNOWN;
    746 
    747     if (hw->service != NULL) {
    748         if (! hw->sensors[id].enabled)
    749             return SENSOR_STATUS_DISABLED;
    750     } else
    751         return SENSOR_STATUS_NO_SERVICE;
    752 
    753     return id;
    754 }
    755 
    756 /* Interface of reading the data for all sensors */
    757 extern int
    758 android_sensors_get( int sensor_id, float* a, float* b, float* c )
    759 {
    760     HwSensors* hw = _sensorsState;
    761 
    762     *a = 0;
    763     *b = 0;
    764     *c = 0;
    765 
    766     if (sensor_id < 0 || sensor_id >= MAX_SENSORS)
    767         return SENSOR_STATUS_UNKNOWN;
    768 
    769     Sensor* sensor = &hw->sensors[sensor_id];
    770     if (hw->service != NULL) {
    771         if (! sensor->enabled)
    772             return SENSOR_STATUS_DISABLED;
    773     } else
    774         return SENSOR_STATUS_NO_SERVICE;
    775 
    776     *a = sensor->u.value.a;
    777     *b = sensor->u.value.b;
    778     *c = sensor->u.value.c;
    779 
    780     return SENSOR_STATUS_OK;
    781 }
    782 
    783 /* Interface of setting the data for all sensors */
    784 extern int
    785 android_sensors_set( int sensor_id, float a, float b, float c )
    786 {
    787     HwSensors* hw = _sensorsState;
    788 
    789     if (sensor_id < 0 || sensor_id >= MAX_SENSORS)
    790         return SENSOR_STATUS_UNKNOWN;
    791 
    792     if (hw->service != NULL) {
    793         if (! hw->sensors[sensor_id].enabled)
    794             return SENSOR_STATUS_DISABLED;
    795     } else
    796         return SENSOR_STATUS_NO_SERVICE;
    797 
    798     _hwSensors_setSensorValue(hw, sensor_id, a, b, c);
    799 
    800     return SENSOR_STATUS_OK;
    801 }
    802 
    803 /* Get Sensor from sensor id */
    804 extern uint8_t
    805 android_sensors_get_sensor_status( int sensor_id )
    806 {
    807     HwSensors* hw = _sensorsState;
    808 
    809     if (sensor_id < 0 || sensor_id >= MAX_SENSORS)
    810         return SENSOR_STATUS_UNKNOWN;
    811 
    812     return hw->sensors[sensor_id].enabled;
    813 }
    814