blob: 690bb49557675b2ad40154cf9d1cef8d06097932 [file] [log] [blame]
The Android Open Source Project9877e2e2009-03-18 17:39:44 -07001/* 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"
David 'Digit' Turner5998b892009-06-11 14:43:03 +020016#include "android/utils/system.h"
The Android Open Source Project9877e2e2009-03-18 17:39:44 -070017#include "android/hw-qemud.h"
18#include "android/globals.h"
Ot ten Thije871da2a2010-09-20 10:29:22 +010019#include "hw/hw.h"
The Android Open Source Project9877e2e2009-03-18 17:39:44 -070020#include "qemu-char.h"
21#include "qemu-timer.h"
22
23#define D(...) VERBOSE_PRINT(sensors,__VA_ARGS__)
24
25/* define T_ACTIVE to 1 to debug transport communications */
26#define T_ACTIVE 0
27
28#if T_ACTIVE
29#define T(...) VERBOSE_PRINT(sensors,__VA_ARGS__)
30#else
31#define T(...) ((void)0)
32#endif
33
34/* this code supports emulated sensor hardware
35 *
36 * Note that currently, only the accelerometer is really emulated, and only
37 * for the purpose of allowing auto-rotating the screen in keyboard-less
38 * configurations.
39 *
40 *
41 */
42
43
44static const struct {
45 const char* name;
46 int id;
47} _sSensors[MAX_SENSORS] = {
48#define SENSOR_(x,y) { y, ANDROID_SENSOR_##x },
49 SENSORS_LIST
50#undef SENSOR_
51};
52
53
54static int
55_sensorIdFromName( const char* name )
56{
57 int nn;
58 for (nn = 0; nn < MAX_SENSORS; nn++)
59 if (!strcmp(_sSensors[nn].name,name))
60 return _sSensors[nn].id;
61 return -1;
62}
63
64
65typedef struct {
66 float x, y, z;
67} Acceleration;
68
69
70typedef struct {
71 float x, y, z;
72} MagneticField;
73
74
75typedef struct {
76 float azimuth;
77 float pitch;
78 float roll;
79} Orientation;
80
81
82typedef struct {
83 float celsius;
84} Temperature;
85
86
87typedef struct {
Ot ten Thije871da2a2010-09-20 10:29:22 +010088 uint8_t enabled;
The Android Open Source Project9877e2e2009-03-18 17:39:44 -070089 union {
90 Acceleration acceleration;
91 MagneticField magnetic;
92 Orientation orientation;
93 Temperature temperature;
94 } u;
95} Sensor;
96
97/*
98 * - when the qemu-specific sensors HAL module starts, it sends
99 * "list-sensors"
100 *
101 * - this code replies with a string containing an integer corresponding
102 * to a bitmap of available hardware sensors in the current AVD
103 * configuration (e.g. "1" a.k.a (1 << ANDROID_SENSOR_ACCELERATION))
104 *
105 * - the HAL module sends "set:<sensor>:<flag>" to enable or disable
106 * the report of a given sensor state. <sensor> must be the name of
107 * a given sensor (e.g. "accelerometer"), and <flag> must be either
108 * "1" (to enable) or "0" (to disable).
109 *
110 * - Once at least one sensor is "enabled", this code should periodically
111 * send information about the corresponding enabled sensors. The default
112 * period is 200ms.
113 *
114 * - the HAL module sends "set-delay:<delay>", where <delay> is an integer
115 * corresponding to a time delay in milli-seconds. This corresponds to
116 * a new interval between sensor events sent by this code to the HAL
117 * module.
118 *
119 * - the HAL module can also send a "wake" command. This code should simply
120 * send the "wake" back to the module. This is used internally to wake a
121 * blocking read that happens in a different thread. This ping-pong makes
122 * the code in the HAL module very simple.
123 *
124 * - each timer tick, this code sends sensor reports in the following
125 * format (each line corresponds to a different line sent to the module):
126 *
127 * acceleration:<x>:<y>:<z>
128 * magnetic-field:<x>:<y>:<z>
129 * orientation:<azimuth>:<pitch>:<roll>
130 * temperature:<celsius>
131 * sync:<time_us>
132 *
133 * Where each line before the sync:<time_us> is optional and will only
134 * appear if the corresponding sensor has been enabled by the HAL module.
135 *
136 * Note that <time_us> is the VM time in micro-seconds when the report
137 * was "taken" by this code. This is adjusted by the HAL module to
138 * emulated system time (using the first sync: to compute an adjustment
139 * offset).
140 */
141#define HEADER_SIZE 4
142#define BUFFER_SIZE 512
143
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200144typedef struct HwSensorClient HwSensorClient;
145
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700146typedef struct {
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200147 QemudService* service;
148 Sensor sensors[MAX_SENSORS];
149 HwSensorClient* clients;
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700150} HwSensors;
151
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200152struct HwSensorClient {
153 HwSensorClient* next;
154 HwSensors* sensors;
155 QemudClient* client;
156 QEMUTimer* timer;
157 uint32_t enabledMask;
158 int32_t delay_ms;
159};
160
161static void
162_hwSensorClient_free( HwSensorClient* cl )
163{
164 /* remove from sensors's list */
165 if (cl->sensors) {
166 HwSensorClient** pnode = &cl->sensors->clients;
167 for (;;) {
168 HwSensorClient* node = *pnode;
169 if (node == NULL)
170 break;
171 if (node == cl) {
172 *pnode = cl->next;
173 break;
174 }
175 pnode = &node->next;
176 }
177 cl->next = NULL;
178 cl->sensors = NULL;
179 }
180
181 /* close QEMUD client, if any */
182 if (cl->client) {
183 qemud_client_close(cl->client);
184 cl->client = NULL;
185 }
186 /* remove timer, if any */
187 if (cl->timer) {
188 qemu_del_timer(cl->timer);
189 qemu_free_timer(cl->timer);
190 cl->timer = NULL;
191 }
192 AFREE(cl);
193}
194
195/* forward */
196static void _hwSensorClient_tick(void* opaque);
197
198
199static HwSensorClient*
200_hwSensorClient_new( HwSensors* sensors )
201{
202 HwSensorClient* cl;
203
204 ANEW0(cl);
205
206 cl->sensors = sensors;
207 cl->enabledMask = 0;
208 cl->delay_ms = 1000;
209 cl->timer = qemu_new_timer(vm_clock, _hwSensorClient_tick, cl);
210
211 cl->next = sensors->clients;
212 sensors->clients = cl;
213
214 return cl;
215}
216
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700217/* forward */
218
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200219static void _hwSensorClient_receive( HwSensorClient* cl,
220 uint8_t* query,
221 int querylen );
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700222
223/* Qemud service management */
224
225static void
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200226_hwSensorClient_recv( void* opaque, uint8_t* msg, int msglen,
227 QemudClient* client )
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700228{
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200229 HwSensorClient* cl = opaque;
230
231 _hwSensorClient_receive(cl, msg, msglen);
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700232}
233
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200234static void
235_hwSensorClient_close( void* opaque )
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700236{
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200237 HwSensorClient* cl = opaque;
238
239 /* the client is already closed here */
240 cl->client = NULL;
241 _hwSensorClient_free(cl);
242}
243
244/* send a one-line message to the HAL module through a qemud channel */
245static void
246_hwSensorClient_send( HwSensorClient* cl, const uint8_t* msg, int msglen )
247{
248 D("%s: '%s'", __FUNCTION__, quote_bytes((const void*)msg, msglen));
249 qemud_client_send(cl->client, msg, msglen);
250}
251
252static int
253_hwSensorClient_enabled( HwSensorClient* cl, int sensorId )
254{
255 return (cl->enabledMask & (1 << sensorId)) != 0;
256}
257
258/* this function is called periodically to send sensor reports
259 * to the HAL module, and re-arm the timer if necessary
260 */
261static void
262_hwSensorClient_tick( void* opaque )
263{
264 HwSensorClient* cl = opaque;
265 HwSensors* hw = cl->sensors;
266 int64_t delay = cl->delay_ms;
267 int64_t now_ns;
268 uint32_t mask = cl->enabledMask;
269 Sensor* sensor;
270 char buffer[128];
271
272 if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ACCELERATION)) {
273 sensor = &hw->sensors[ANDROID_SENSOR_ACCELERATION];
274 snprintf(buffer, sizeof buffer, "acceleration:%g:%g:%g",
275 sensor->u.acceleration.x,
276 sensor->u.acceleration.y,
277 sensor->u.acceleration.z);
278 _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
279 }
280
281 if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_MAGNETIC_FIELD)) {
282 sensor = &hw->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
283 snprintf(buffer, sizeof buffer, "magnetic-field:%g:%g:%g",
284 sensor->u.magnetic.x,
285 sensor->u.magnetic.y,
286 sensor->u.magnetic.z);
287 _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
288 }
289
290 if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_ORIENTATION)) {
291 sensor = &hw->sensors[ANDROID_SENSOR_ORIENTATION];
292 snprintf(buffer, sizeof buffer, "orientation:%g:%g:%g",
293 sensor->u.orientation.azimuth,
294 sensor->u.orientation.pitch,
295 sensor->u.orientation.roll);
296 _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
297 }
298
299 if (_hwSensorClient_enabled(cl, ANDROID_SENSOR_TEMPERATURE)) {
300 sensor = &hw->sensors[ANDROID_SENSOR_TEMPERATURE];
301 snprintf(buffer, sizeof buffer, "temperature:%g",
302 sensor->u.temperature.celsius);
303 _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
304 }
305
306 now_ns = qemu_get_clock(vm_clock);
307
308 snprintf(buffer, sizeof buffer, "sync:%lld", now_ns/1000);
309 _hwSensorClient_send(cl, (uint8_t*)buffer, strlen(buffer));
310
311 /* rearm timer, use a minimum delay of 20 ms, just to
312 * be safe.
313 */
314 if (mask == 0)
315 return;
316
317 if (delay < 20)
318 delay = 20;
319
320 delay *= 1000000LL; /* convert to nanoseconds */
321 qemu_mod_timer(cl->timer, now_ns + delay);
322}
323
324/* handle incoming messages from the HAL module */
325static void
326_hwSensorClient_receive( HwSensorClient* cl, uint8_t* msg, int msglen )
327{
328 HwSensors* hw = cl->sensors;
329
330 D("%s: '%.*s'", __FUNCTION__, msglen, msg);
331
332 /* "list-sensors" is used to get an integer bit map of
333 * available emulated sensors. We compute the mask from the
334 * current hardware configuration.
335 */
336 if (msglen == 12 && !memcmp(msg, "list-sensors", 12)) {
337 char buff[12];
338 int mask = 0;
339 int nn;
340
341 for (nn = 0; nn < MAX_SENSORS; nn++) {
342 if (hw->sensors[nn].enabled)
343 mask |= (1 << nn);
344 }
345
346 snprintf(buff, sizeof buff, "%d", mask);
347 _hwSensorClient_send(cl, (const uint8_t*)buff, strlen(buff));
348 return;
349 }
350
351 /* "wake" is a special message that must be sent back through
352 * the channel. It is used to exit a blocking read.
353 */
354 if (msglen == 4 && !memcmp(msg, "wake", 4)) {
355 _hwSensorClient_send(cl, (const uint8_t*)"wake", 4);
356 return;
357 }
358
359 /* "set-delay:<delay>" is used to set the delay in milliseconds
360 * between sensor events
361 */
362 if (msglen > 10 && !memcmp(msg, "set-delay:", 10)) {
363 cl->delay_ms = atoi((const char*)msg+10);
364 if (cl->enabledMask != 0)
365 _hwSensorClient_tick(cl);
366
367 return;
368 }
369
370 /* "set:<name>:<state>" is used to enable/disable a given
371 * sensor. <state> must be 0 or 1
372 */
373 if (msglen > 4 && !memcmp(msg, "set:", 4)) {
374 char* q;
375 int id, enabled, oldEnabledMask = cl->enabledMask;
376 msg += 4;
377 q = strchr((char*)msg, ':');
378 if (q == NULL) { /* should not happen */
379 D("%s: ignore bad 'set' command", __FUNCTION__);
380 return;
381 }
382 *q++ = 0;
383
384 id = _sensorIdFromName((const char*)msg);
385 if (id < 0 || id >= MAX_SENSORS) {
386 D("%s: ignore unknown sensor name '%s'", __FUNCTION__, msg);
387 return;
388 }
389
390 if (!hw->sensors[id].enabled) {
391 D("%s: trying to set disabled %s sensor", __FUNCTION__, msg);
392 return;
393 }
394 enabled = (q[0] == '1');
395
396 if (enabled)
397 cl->enabledMask |= (1 << id);
398 else
399 cl->enabledMask &= ~(1 << id);
400
401 if (cl->enabledMask != oldEnabledMask) {
402 D("%s: %s %s sensor", __FUNCTION__,
403 (cl->enabledMask & (1 << id)) ? "enabling" : "disabling", msg);
404 }
405 _hwSensorClient_tick(cl);
406 return;
407 }
408
409 D("%s: ignoring unknown query", __FUNCTION__);
410}
411
Ot ten Thije871da2a2010-09-20 10:29:22 +0100412/* Saves sensor-specific client data to snapshot */
413static void
414_hwSensorClient_save( QEMUFile* f, QemudClient* client, void* opaque )
415{
416 HwSensorClient* sc = opaque;
417
418 qemu_put_be32(f, sc->delay_ms);
419 qemu_put_be32(f, sc->enabledMask);
420 qemu_put_timer(f, sc->timer);
421}
422
423/* Loads sensor-specific client data from snapshot */
424static int
425_hwSensorClient_load( QEMUFile* f, QemudClient* client, void* opaque )
426{
427 HwSensorClient* sc = opaque;
428
429 sc->delay_ms = qemu_get_be32(f);
430 sc->enabledMask = qemu_get_be32(f);
431 qemu_get_timer(f, sc->timer);
432
433 return 0;
434}
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200435
436static QemudClient*
437_hwSensors_connect( void* opaque, QemudService* service, int channel )
438{
439 HwSensors* sensors = opaque;
440 HwSensorClient* cl = _hwSensorClient_new(sensors);
441 QemudClient* client = qemud_client_new(service, channel, cl,
442 _hwSensorClient_recv,
Ot ten Thije871da2a2010-09-20 10:29:22 +0100443 _hwSensorClient_close,
444 _hwSensorClient_save,
445 _hwSensorClient_load );
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700446 qemud_client_set_framing(client, 1);
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200447 cl->client = client;
448
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700449 return client;
450}
451
452/* change the value of the emulated acceleration vector */
453static void
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200454_hwSensors_setAcceleration( HwSensors* h, float x, float y, float z )
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700455{
456 Sensor* s = &h->sensors[ANDROID_SENSOR_ACCELERATION];
457 s->u.acceleration.x = x;
458 s->u.acceleration.y = y;
459 s->u.acceleration.z = z;
460}
461
Ot ten Thije871da2a2010-09-20 10:29:22 +0100462/* Saves available sensors to allow checking availability when loaded.
463 */
464static void
465_hwSensors_save( QEMUFile* f, QemudService* sv, void* opaque)
466{
467 HwSensors* h = opaque;
468
469 // number of sensors
470 qemu_put_be32(f, MAX_SENSORS);
471 AndroidSensor i;
472 for (i = 0 ; i < MAX_SENSORS; i++) {
473 Sensor* s = &h->sensors[i];
474 qemu_put_be32(f, s->enabled);
475
476 /* this switch ensures that a warning is raised when a new sensor is
477 * added and is not added here as well.
478 */
479 switch (i) {
480 case ANDROID_SENSOR_ACCELERATION:
481 qemu_put_float(f, s->u.acceleration.x);
482 qemu_put_float(f, s->u.acceleration.y);
483 qemu_put_float(f, s->u.acceleration.z);
484 break;
485 case ANDROID_SENSOR_MAGNETIC_FIELD:
486 qemu_put_float(f, s->u.magnetic.x);
487 qemu_put_float(f, s->u.magnetic.y);
488 qemu_put_float(f, s->u.magnetic.z);
489 break;
490 case ANDROID_SENSOR_ORIENTATION:
491 qemu_put_float(f, s->u.orientation.azimuth);
492 qemu_put_float(f, s->u.orientation.pitch);
493 qemu_put_float(f, s->u.orientation.roll);
494 break;
495 case ANDROID_SENSOR_TEMPERATURE:
496 qemu_put_float(f, s->u.temperature.celsius);
497 break;
498 case MAX_SENSORS:
499 break;
500 }
501 }
502}
503
504
505static int
506_hwSensors_load( QEMUFile* f, QemudService* s, void* opaque)
507{
508 HwSensors* h = opaque;
509
510 /* check number of sensors */
511 int32_t num_sensors = qemu_get_be32(f);
512 if (num_sensors != MAX_SENSORS) {
513 D("%s: cannot load: snapshot requires %d sensors, %d available\n",
514 __FUNCTION__, num_sensors, MAX_SENSORS);
515 return -EIO;
516 }
517
518 /* load sensor state */
519 AndroidSensor i;
520 for (i = 0 ; i < MAX_SENSORS; i++) {
521 Sensor* s = &h->sensors[i];
522 s->enabled = qemu_get_be32(f);
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 s->u.acceleration.x = qemu_get_float(f);
530 s->u.acceleration.y = qemu_get_float(f);
531 s->u.acceleration.z = qemu_get_float(f);
532 break;
533 case ANDROID_SENSOR_MAGNETIC_FIELD:
534 s->u.magnetic.x = qemu_get_float(f);
535 s->u.magnetic.y = qemu_get_float(f);
536 s->u.magnetic.z = qemu_get_float(f);
537 break;
538 case ANDROID_SENSOR_ORIENTATION:
539 s->u.orientation.azimuth = qemu_get_float(f);
540 s->u.orientation.pitch = qemu_get_float(f);
541 s->u.orientation.roll = qemu_get_float(f);
542 break;
543 case ANDROID_SENSOR_TEMPERATURE:
544 s->u.temperature.celsius = qemu_get_float(f);
545 break;
546 case MAX_SENSORS:
547 break;
548 }
549 }
550
551 return 0;
552}
553
554
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700555#if 0 /* not used yet */
556/* change the value of the emulated magnetic vector */
557static void
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200558_hwSensors_setMagneticField( HwSensors* h, float x, float y, float z )
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700559{
560 Sensor* s = &h->sensors[ANDROID_SENSOR_MAGNETIC_FIELD];
561 s->u.magnetic.x = x;
562 s->u.magnetic.y = y;
563 s->u.magnetic.z = z;
564}
565
566/* change the values of the emulated orientation */
567static void
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200568_hwSensors_setOrientation( HwSensors* h, float azimuth, float pitch, float roll )
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700569{
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200570 Sensor* s = &h->sensors[ANDROID_SENSOR_ORIENTATION];
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700571 s->u.orientation.azimuth = azimuth;
572 s->u.orientation.pitch = pitch;
573 s->u.orientation.roll = roll;
574}
575
576/* change the emulated temperature */
577static void
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200578_hwSensors_setTemperature( HwSensors* h, float celsius )
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700579{
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200580 Sensor* s = &h->sensors[ANDROID_SENSOR_TEMPERATURE];
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700581 s->u.temperature.celsius = celsius;
582}
583#endif
584
585/* change the coarse orientation (landscape/portrait) of the emulated device */
586static void
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200587_hwSensors_setCoarseOrientation( HwSensors* h, AndroidCoarseOrientation orient )
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700588{
589 /* The Android framework computes the orientation by looking at
590 * the accelerometer sensor (*not* the orientation sensor !)
591 *
592 * That's because the gravity is a constant 9.81 vector that
593 * can be determined quite easily.
594 *
595 * Also, for some reason, the framework code considers that the phone should
596 * be inclined by 30 degrees along the phone's X axis to be considered
597 * in its ideal "vertical" position
598 *
599 * If the phone is completely vertical, rotating it will not do anything !
600 */
601 const double g = 9.81;
602 const double cos_30 = 0.866025403784;
603 const double sin_30 = 0.5;
604
605 switch (orient) {
606 case ANDROID_COARSE_PORTRAIT:
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200607 _hwSensors_setAcceleration( h, 0., g*cos_30, g*sin_30 );
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700608 break;
609
610 case ANDROID_COARSE_LANDSCAPE:
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200611 _hwSensors_setAcceleration( h, g*cos_30, 0., g*sin_30 );
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700612 break;
613 default:
614 ;
615 }
616}
617
618
619/* initialize the sensors state */
620static void
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200621_hwSensors_init( HwSensors* h )
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700622{
Ot ten Thije871da2a2010-09-20 10:29:22 +0100623 h->service = qemud_service_register("sensors", 0, h, _hwSensors_connect,
624 _hwSensors_save, _hwSensors_load);
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700625
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200626 if (android_hw->hw_accelerometer)
627 h->sensors[ANDROID_SENSOR_ACCELERATION].enabled = 1;
628
629 /* XXX: TODO: Add other tests when we add the corresponding
630 * properties to hardware-properties.ini et al. */
631
632 _hwSensors_setCoarseOrientation(h, ANDROID_COARSE_PORTRAIT);
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700633}
634
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700635static HwSensors _sensorsState[1];
636
637void
638android_hw_sensors_init( void )
639{
640 HwSensors* hw = _sensorsState;
641
642 if (hw->service == NULL) {
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200643 _hwSensors_init(hw);
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700644 D("%s: sensors qemud service initialized", __FUNCTION__);
645 }
646}
647
648/* change the coarse orientation value */
649extern void
650android_sensors_set_coarse_orientation( AndroidCoarseOrientation orient )
651{
652 android_hw_sensors_init();
David 'Digit' Turner5998b892009-06-11 14:43:03 +0200653 _hwSensors_setCoarseOrientation(_sensorsState, orient);
The Android Open Source Project9877e2e2009-03-18 17:39:44 -0700654}
655