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 "android/hw-sensors.h"
     14 #include "android/utils/debug.h"
     15 #include "android/utils/misc.h"
     16 #include "android/utils/system.h"
     17 #include "android/hw-qemud.h"
     18 #include "android/globals.h"
     19 #include "qemu-char.h"
     20 #include "qemu-timer.h"
     21 
     22 #define  D(...)  VERBOSE_PRINT(sensors,__VA_ARGS__)
     23 
     24 /* define T_ACTIVE to 1 to debug transport communications */
     25 #define  T_ACTIVE  0
     26 
     27 #if T_ACTIVE
     28 #define  T(...)  VERBOSE_PRINT(sensors,__VA_ARGS__)
     29 #else
     30 #define  T(...)   ((void)0)
     31 #endif
     32 
     33 /* this code supports emulated sensor hardware
     34  *
     35  * Note that currently, only the accelerometer is really emulated, and only
     36  * for the purpose of allowing auto-rotating the screen in keyboard-less
     37  * configurations.
     38  *
     39  *
     40  */
     41 
     42 
     43 static const struct {
     44     const char*  name;
     45     int          id;
     46 } _sSensors[MAX_SENSORS] = {
     47 #define SENSOR_(x,y)  { y, ANDROID_SENSOR_##x },
     48   SENSORS_LIST
     49 #undef SENSOR_
     50 };
     51 
     52 
     53 static int
     54 _sensorIdFromName( const char*  name )
     55 {
     56     int  nn;
     57     for (nn = 0; nn < MAX_SENSORS; nn++)
     58         if (!strcmp(_sSensors[nn].name,name))
     59             return _sSensors[nn].id;
     60     return -1;
     61 }
     62 
     63 
     64 typedef struct {
     65     float   x, y, z;
     66 } Acceleration;
     67 
     68 
     69 typedef struct {
     70     float  x, y, z;
     71 } MagneticField;
     72 
     73 
     74 typedef struct {
     75     float  azimuth;
     76     float  pitch;
     77     float  roll;
     78 } Orientation;
     79 
     80 
     81 typedef struct {
     82     float  celsius;
     83 } Temperature;
     84 
     85 
     86 typedef struct {
     87     char       enabled;
     88     union {
     89         Acceleration   acceleration;
     90         MagneticField  magnetic;
     91         Orientation    orientation;
     92         Temperature    temperature;
     93     } u;
     94 } Sensor;
     95 
     96 /*
     97  * - when the qemu-specific sensors HAL module starts, it sends
     98  *   "list-sensors"
     99  *
    100  * - this code replies with a string containing an integer corresponding
    101  *   to a bitmap of available hardware sensors in the current AVD
    102  *   configuration (e.g. "1" a.k.a (1 << ANDROID_SENSOR_ACCELERATION))
    103  *
    104  * - the HAL module sends "set:<sensor>:<flag>" to enable or disable
    105  *   the report of a given sensor state. <sensor> must be the name of
    106  *   a given sensor (e.g. "accelerometer"), and <flag> must be either
    107  *   "1" (to enable) or "0" (to disable).
    108  *
    109  * - Once at least one sensor is "enabled", this code should periodically
    110  *   send information about the corresponding enabled sensors. The default
    111  *   period is 200ms.
    112  *
    113  * - the HAL module sends "set-delay:<delay>", where <delay> is an integer
    114  *   corresponding to a time delay in milli-seconds. This corresponds to
    115  *   a new interval between sensor events sent by this code to the HAL
    116  *   module.
    117  *
    118  * - the HAL module can also send a "wake" command. This code should simply
    119  *   send the "wake" back to the module. This is used internally to wake a
    120  *   blocking read that happens in a different thread. This ping-pong makes
    121  *   the code in the HAL module very simple.
    122  *
    123  * - each timer tick, this code sends sensor reports in the following
    124  *   format (each line corresponds to a different line sent to the module):
    125  *
    126  *      acceleration:<x>:<y>:<z>
    127  *      magnetic-field:<x>:<y>:<z>
    128  *      orientation:<azimuth>:<pitch>:<roll>
    129  *      temperature:<celsius>
    130  *      sync:<time_us>
    131  *
    132  *   Where each line before the sync:<time_us> is optional and will only
    133  *   appear if the corresponding sensor has been enabled by the HAL module.
    134  *
    135  *   Note that <time_us> is the VM time in micro-seconds when the report
    136  *   was "taken" by this code. This is adjusted by the HAL module to
    137  *   emulated system time (using the first sync: to compute an adjustment
    138  *   offset).
    139  */
    140 #define  HEADER_SIZE  4
    141 #define  BUFFER_SIZE  512
    142 
    143 typedef struct HwSensorClient   HwSensorClient;
    144 
    145 typedef struct {
    146     QemudService*    service;
    147     Sensor           sensors[MAX_SENSORS];
    148     HwSensorClient*  clients;
    149 } HwSensors;
    150 
    151 struct HwSensorClient {
    152     HwSensorClient*  next;
    153     HwSensors*       sensors;
    154     QemudClient*     client;
    155     QEMUTimer*       timer;
    156     uint32_t         enabledMask;
    157     int32_t          delay_ms;
    158 };
    159 
    160 static void
    161 _hwSensorClient_free( HwSensorClient*  cl )
    162 {
    163     /* remove from sensors's list */
    164     if (cl->sensors) {
    165         HwSensorClient**  pnode = &cl->sensors->clients;
    166         for (;;) {
    167             HwSensorClient*  node = *pnode;
    168             if (node == NULL)
    169                 break;
    170             if (node == cl) {
    171                 *pnode = cl->next;
    172                 break;
    173             }
    174             pnode = &node->next;
    175         }
    176         cl->next    = NULL;
    177         cl->sensors = NULL;
    178     }
    179 
    180     /* close QEMUD client, if any */
    181     if (cl->client) {
    182         qemud_client_close(cl->client);
    183         cl->client = NULL;
    184     }
    185     /* remove timer, if any */
    186     if (cl->timer) {
    187         qemu_del_timer(cl->timer);
    188         qemu_free_timer(cl->timer);
    189         cl->timer = NULL;
    190     }
    191     AFREE(cl);
    192 }
    193 
    194 /* forward */
    195 static void  _hwSensorClient_tick(void*  opaque);
    196 
    197 
    198 static HwSensorClient*
    199 _hwSensorClient_new( HwSensors*  sensors )
    200 {
    201     HwSensorClient*  cl;
    202 
    203     ANEW0(cl);
    204 
    205     cl->sensors     = sensors;
    206     cl->enabledMask = 0;
    207     cl->delay_ms    = 1000;
    208     cl->timer       = qemu_new_timer(vm_clock, _hwSensorClient_tick, cl);
    209 
    210     cl->next         = sensors->clients;
    211     sensors->clients = cl;
    212 
    213     return cl;
    214 }
    215 
    216 /* forward */
    217 
    218 static void  _hwSensorClient_receive( HwSensorClient*  cl,
    219                                       uint8_t*         query,
    220                                       int              querylen );
    221 
    222 /* Qemud service management */
    223 
    224 static void
    225 _hwSensorClient_recv( void*  opaque, uint8_t*  msg, int  msglen,
    226                       QemudClient*  client )
    227 {
    228     HwSensorClient*  cl = opaque;
    229 
    230     _hwSensorClient_receive(cl, msg, msglen);
    231 }
    232 
    233 static void
    234 _hwSensorClient_close( void*  opaque )
    235 {
    236     HwSensorClient*  cl = opaque;
    237 
    238     /* the client is already closed here */
    239     cl->client = NULL;
    240     _hwSensorClient_free(cl);
    241 }
    242 
    243 /* send a one-line message to the HAL module through a qemud channel */
    244 static void
    245 _hwSensorClient_send( HwSensorClient*  cl, const uint8_t*  msg, int  msglen )
    246 {
    247     D("%s: '%s'", __FUNCTION__, quote_bytes((const void*)msg, msglen));
    248     qemud_client_send(cl->client, msg, msglen);
    249 }
    250 
    251 static int
    252 _hwSensorClient_enabled( HwSensorClient*  cl, int  sensorId )
    253 {
    254     return (cl->enabledMask & (1 << sensorId)) != 0;
    255 }
    256 
    257 /* this function is called periodically to send sensor reports
    258  * to the HAL module, and re-arm the timer if necessary
    259  */
    260 static void
    261 _hwSensorClient_tick( void*  opaque )
    262 {
    263     HwSensorClient*  cl = opaque;
    264     HwSensors*       hw  = cl->sensors;
    265     int64_t          delay = cl->delay_ms;
    266     int64_t          now_ns;
    267     uint32_t         mask  = cl->enabledMask;
    268     Sensor*          sensor;
    269     char             buffer[128];
    270 
    271     if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ACCELERATION)) {
    272         sensor = &hw->sensors[ANDROID_SENSOR_ACCELERATION];
    273         snprintf(buffer, sizeof buffer, "acceleration:%g:%g:%g",
    274                  sensor->u.acceleration.x,
    275                  sensor->u.acceleration.y,
    276                  sensor->u.acceleration.z);
    277         _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    278     }
    279 
    280     if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_MAGNETIC_FIELD)) {
    281         sensor = &hw->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
    282         snprintf(buffer, sizeof buffer, "magnetic-field:%g:%g:%g",
    283                  sensor->u.magnetic.x,
    284                  sensor->u.magnetic.y,
    285                  sensor->u.magnetic.z);
    286         _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    287     }
    288 
    289     if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ORIENTATION)) {
    290         sensor = &hw->sensors[ANDROID_SENSOR_ORIENTATION];
    291         snprintf(buffer, sizeof buffer, "orientation:%g:%g:%g",
    292                  sensor->u.orientation.azimuth,
    293                  sensor->u.orientation.pitch,
    294                  sensor->u.orientation.roll);
    295         _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    296     }
    297 
    298     if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_TEMPERATURE)) {
    299         sensor = &hw->sensors[ANDROID_SENSOR_TEMPERATURE];
    300         snprintf(buffer, sizeof buffer, "temperature:%g",
    301                  sensor->u.temperature.celsius);
    302         _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    303     }
    304 
    305     now_ns = qemu_get_clock(vm_clock);
    306 
    307     snprintf(buffer, sizeof buffer, "sync:%lld", now_ns/1000);
    308     _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
    309 
    310     /* rearm timer, use a minimum delay of 20 ms, just to
    311      * be safe.
    312      */
    313     if (mask == 0)
    314         return;
    315 
    316     if (delay < 20)
    317         delay = 20;
    318 
    319     delay *= 1000000LL;  /* convert to nanoseconds */
    320     qemu_mod_timer(cl->timer, now_ns + delay);
    321 }
    322 
    323 /* handle incoming messages from the HAL module */
    324 static void
    325 _hwSensorClient_receive( HwSensorClient*  cl, uint8_t*  msg, int  msglen )
    326 {
    327     HwSensors*  hw = cl->sensors;
    328 
    329     D("%s: '%.*s'", __FUNCTION__, msglen, msg);
    330 
    331     /* "list-sensors" is used to get an integer bit map of
    332      * available emulated sensors. We compute the mask from the
    333      * current hardware configuration.
    334      */
    335     if (msglen == 12 && !memcmp(msg, "list-sensors", 12)) {
    336         char  buff[12];
    337         int   mask = 0;
    338         int   nn;
    339 
    340         for (nn = 0; nn < MAX_SENSORS; nn++) {
    341             if (hw->sensors[nn].enabled)
    342                 mask |= (1 << nn);
    343         }
    344 
    345         snprintf(buff, sizeof buff, "%d", mask);
    346         _hwSensorClient_send(cl, (const uint8_t*)buff, strlen(buff));
    347         return;
    348     }
    349 
    350     /* "wake" is a special message that must be sent back through
    351      * the channel. It is used to exit a blocking read.
    352      */
    353     if (msglen == 4 && !memcmp(msg, "wake", 4)) {
    354         _hwSensorClient_send(cl, (const uint8_t*)"wake", 4);
    355         return;
    356     }
    357 
    358     /* "set-delay:<delay>" is used to set the delay in milliseconds
    359      * between sensor events
    360      */
    361     if (msglen > 10 && !memcmp(msg, "set-delay:", 10)) {
    362         cl->delay_ms = atoi((const char*)msg+10);
    363         if (cl->enabledMask != 0)
    364             _hwSensorClient_tick(cl);
    365 
    366         return;
    367     }
    368 
    369     /* "set:<name>:<state>" is used to enable/disable a given
    370      * sensor. <state> must be 0 or 1
    371      */
    372     if (msglen > 4 && !memcmp(msg, "set:", 4)) {
    373         char*  q;
    374         int    id, enabled, oldEnabledMask = cl->enabledMask;
    375         msg += 4;
    376         q    = strchr((char*)msg, ':');
    377         if (q == NULL) {  /* should not happen */
    378             D("%s: ignore bad 'set' command", __FUNCTION__);
    379             return;
    380         }
    381         *q++ = 0;
    382 
    383         id = _sensorIdFromName((const char*)msg);
    384         if (id < 0 || id >= MAX_SENSORS) {
    385             D("%s: ignore unknown sensor name '%s'", __FUNCTION__, msg);
    386             return;
    387         }
    388 
    389         if (!hw->sensors[id].enabled) {
    390             D("%s: trying to set disabled %s sensor", __FUNCTION__, msg);
    391             return;
    392         }
    393         enabled = (q[0] == '1');
    394 
    395         if (enabled)
    396             cl->enabledMask |= (1 << id);
    397         else
    398             cl->enabledMask &= ~(1 << id);
    399 
    400         if (cl->enabledMask != oldEnabledMask) {
    401             D("%s: %s %s sensor", __FUNCTION__,
    402                 (cl->enabledMask & (1 << id))  ? "enabling" : "disabling",  msg);
    403         }
    404         _hwSensorClient_tick(cl);
    405         return;
    406     }
    407 
    408     D("%s: ignoring unknown query", __FUNCTION__);
    409 }
    410 
    411 
    412 static QemudClient*
    413 _hwSensors_connect( void*  opaque, QemudService*  service, int  channel )
    414 {
    415     HwSensors*       sensors = opaque;
    416     HwSensorClient*  cl      = _hwSensorClient_new(sensors);
    417     QemudClient*     client  = qemud_client_new(service, channel, cl,
    418                                                 _hwSensorClient_recv,
    419                                                 _hwSensorClient_close);
    420     qemud_client_set_framing(client, 1);
    421     cl->client = client;
    422 
    423     return client;
    424 }
    425 
    426 /* change the value of the emulated acceleration vector */
    427 static void
    428 _hwSensors_setAcceleration( HwSensors*  h, float x, float y, float z )
    429 {
    430     Sensor*  s = &h->sensors[ANDROID_SENSOR_ACCELERATION];
    431     s->u.acceleration.x = x;
    432     s->u.acceleration.y = y;
    433     s->u.acceleration.z = z;
    434 }
    435 
    436 #if 0  /* not used yet */
    437 /* change the value of the emulated magnetic vector */
    438 static void
    439 _hwSensors_setMagneticField( HwSensors*  h, float x, float y, float z )
    440 {
    441     Sensor*  s = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
    442     s->u.magnetic.x = x;
    443     s->u.magnetic.y = y;
    444     s->u.magnetic.z = z;
    445 }
    446 
    447 /* change the values of the emulated orientation */
    448 static void
    449 _hwSensors_setOrientation( HwSensors*  h, float azimuth, float pitch, float roll )
    450 {
    451     Sensor*  s = &h->sensors[ANDROID_SENSOR_ORIENTATION];
    452     s->u.orientation.azimuth = azimuth;
    453     s->u.orientation.pitch   = pitch;
    454     s->u.orientation.roll    = roll;
    455 }
    456 
    457 /* change the emulated temperature */
    458 static void
    459 _hwSensors_setTemperature( HwSensors*  h, float celsius )
    460 {
    461     Sensor*  s = &h->sensors[ANDROID_SENSOR_TEMPERATURE];
    462     s->u.temperature.celsius = celsius;
    463 }
    464 #endif
    465 
    466 /* change the coarse orientation (landscape/portrait) of the emulated device */
    467 static void
    468 _hwSensors_setCoarseOrientation( HwSensors*  h, AndroidCoarseOrientation  orient )
    469 {
    470     /* The Android framework computes the orientation by looking at
    471      * the accelerometer sensor (*not* the orientation sensor !)
    472      *
    473      * That's because the gravity is a constant 9.81 vector that
    474      * can be determined quite easily.
    475      *
    476      * Also, for some reason, the framework code considers that the phone should
    477      * be inclined by 30 degrees along the phone's X axis to be considered
    478      * in its ideal "vertical" position
    479      *
    480      * If the phone is completely vertical, rotating it will not do anything !
    481      */
    482     const double  g      = 9.81;
    483     const double  cos_30 = 0.866025403784;
    484     const double  sin_30 = 0.5;
    485 
    486     switch (orient) {
    487     case ANDROID_COARSE_PORTRAIT:
    488         _hwSensors_setAcceleration( h, 0., g*cos_30, g*sin_30 );
    489         break;
    490 
    491     case ANDROID_COARSE_LANDSCAPE:
    492         _hwSensors_setAcceleration( h, g*cos_30, 0., g*sin_30 );
    493         break;
    494     default:
    495         ;
    496     }
    497 }
    498 
    499 
    500 /* initialize the sensors state */
    501 static void
    502 _hwSensors_init( HwSensors*  h )
    503 {
    504     h->service = qemud_service_register("sensors", 0, h,
    505                                         _hwSensors_connect );
    506 
    507     if (android_hw->hw_accelerometer)
    508         h->sensors[ANDROID_SENSOR_ACCELERATION].enabled = 1;
    509 
    510     /* XXX: TODO: Add other tests when we add the corresponding
    511         * properties to hardware-properties.ini et al. */
    512 
    513     _hwSensors_setCoarseOrientation(h, ANDROID_COARSE_PORTRAIT);
    514 }
    515 
    516 static HwSensors    _sensorsState[1];
    517 
    518 void
    519 android_hw_sensors_init( void )
    520 {
    521     HwSensors*  hw = _sensorsState;
    522 
    523     if (hw->service == NULL) {
    524         _hwSensors_init(hw);
    525         D("%s: sensors qemud service initialized", __FUNCTION__);
    526     }
    527 }
    528 
    529 /* change the coarse orientation value */
    530 extern void
    531 android_sensors_set_coarse_orientation( AndroidCoarseOrientation  orient )
    532 {
    533     android_hw_sensors_init();
    534     _hwSensors_setCoarseOrientation(_sensorsState, orient);
    535 }
    536 
    537