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