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