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 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* 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 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* 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 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 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 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 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 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 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 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 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* 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 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 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 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 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 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 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 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 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* 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 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 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 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 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