• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
_sensorIdFromName(const char * name)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*
_sensorNameFromId(int id)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
_hwSensorClient_free(HwSensorClient * cl)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*
_hwSensorClient_new(HwSensors * sensors)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
_hwSensorClient_recv(void * opaque,uint8_t * msg,int msglen,QemudClient * client)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
_hwSensorClient_close(void * opaque)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
_hwSensorClient_send(HwSensorClient * cl,const uint8_t * msg,int msglen)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
_hwSensorClient_enabled(HwSensorClient * cl,int sensorId)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
_hwSensorClient_tick(void * opaque)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
_hwSensorClient_receive(HwSensorClient * cl,uint8_t * msg,int msglen)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
_hwSensorClient_save(QEMUFile * f,QemudClient * client,void * opaque)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
_hwSensorClient_load(QEMUFile * f,QemudClient * client,void * opaque)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*
_hwSensors_connect(void * opaque,QemudService * service,int channel,const char * client_param)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
_hwSensors_setSensorValue(HwSensors * h,int sensor_id,float a,float b,float c)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
_hwSensors_save(QEMUFile * f,QemudService * sv,void * opaque)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
_hwSensors_load(QEMUFile * f,QemudService * s,void * opaque)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
_hwSensors_setProximity(HwSensors * h,float value)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
_hwSensors_setCoarseOrientation(HwSensors * h,AndroidCoarseOrientation orient)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
_hwSensors_init(HwSensors * h)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
android_hw_sensors_init(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
android_sensors_set_coarse_orientation(AndroidCoarseOrientation orient)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*
android_sensors_get_name_from_id(int sensor_id)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
android_sensors_get_id_from_name(char * sensorname)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
android_sensors_get(int sensor_id,float * a,float * b,float * c)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
android_sensors_set(int sensor_id,float a,float b,float c)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
android_sensors_get_sensor_status(int sensor_id)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