1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* this implements a sensors hardware library for the Android emulator. 18 * the following code should be built as a shared library that will be 19 * placed into /system/lib/hw/sensors.goldfish.so 20 * 21 * it will be loaded by the code in hardware/libhardware/hardware.c 22 * which is itself called from com_android_server_SensorService.cpp 23 */ 24 25 26 /* we connect with the emulator through the "sensors" qemud service 27 */ 28 #define SENSORS_SERVICE_NAME "sensors" 29 30 #define LOG_TAG "QemuSensors" 31 32 #include <unistd.h> 33 #include <fcntl.h> 34 #include <errno.h> 35 #include <string.h> 36 #include <cutils/log.h> 37 #include <cutils/sockets.h> 38 #include <hardware/sensors.h> 39 40 #if 0 41 #define D(...) ALOGD(__VA_ARGS__) 42 #else 43 #define D(...) ((void)0) 44 #endif 45 46 #define E(...) ALOGE(__VA_ARGS__) 47 48 #include <hardware/qemud.h> 49 50 /** SENSOR IDS AND NAMES 51 **/ 52 53 #define MAX_NUM_SENSORS 8 54 55 #define SUPPORTED_SENSORS ((1<<MAX_NUM_SENSORS)-1) 56 57 #define ID_BASE SENSORS_HANDLE_BASE 58 #define ID_ACCELERATION (ID_BASE+0) 59 #define ID_MAGNETIC_FIELD (ID_BASE+1) 60 #define ID_ORIENTATION (ID_BASE+2) 61 #define ID_TEMPERATURE (ID_BASE+3) 62 #define ID_PROXIMITY (ID_BASE+4) 63 #define ID_LIGHT (ID_BASE+5) 64 #define ID_PRESSURE (ID_BASE+6) 65 #define ID_HUMIDITY (ID_BASE+7) 66 67 #define SENSORS_ACCELERATION (1 << ID_ACCELERATION) 68 #define SENSORS_MAGNETIC_FIELD (1 << ID_MAGNETIC_FIELD) 69 #define SENSORS_ORIENTATION (1 << ID_ORIENTATION) 70 #define SENSORS_TEMPERATURE (1 << ID_TEMPERATURE) 71 #define SENSORS_PROXIMITY (1 << ID_PROXIMITY) 72 #define SENSORS_LIGHT (1 << ID_LIGHT) 73 #define SENSORS_PRESSURE (1 << ID_PRESSURE) 74 #define SENSORS_HUMIDITY (1 << ID_HUMIDITY) 75 76 #define ID_CHECK(x) ((unsigned)((x) - ID_BASE) < MAX_NUM_SENSORS) 77 78 #define SENSORS_LIST \ 79 SENSOR_(ACCELERATION,"acceleration") \ 80 SENSOR_(MAGNETIC_FIELD,"magnetic-field") \ 81 SENSOR_(ORIENTATION,"orientation") \ 82 SENSOR_(TEMPERATURE,"temperature") \ 83 SENSOR_(PROXIMITY,"proximity") \ 84 SENSOR_(LIGHT, "light") \ 85 SENSOR_(PRESSURE, "pressure") \ 86 SENSOR_(HUMIDITY, "humidity") 87 88 static const struct { 89 const char* name; 90 int id; } _sensorIds[MAX_NUM_SENSORS] = 91 { 92 #define SENSOR_(x,y) { y, ID_##x }, 93 SENSORS_LIST 94 #undef SENSOR_ 95 }; 96 97 static const char* 98 _sensorIdToName( int id ) 99 { 100 int nn; 101 for (nn = 0; nn < MAX_NUM_SENSORS; nn++) 102 if (id == _sensorIds[nn].id) 103 return _sensorIds[nn].name; 104 return "<UNKNOWN>"; 105 } 106 107 static int 108 _sensorIdFromName( const char* name ) 109 { 110 int nn; 111 112 if (name == NULL) 113 return -1; 114 115 for (nn = 0; nn < MAX_NUM_SENSORS; nn++) 116 if (!strcmp(name, _sensorIds[nn].name)) 117 return _sensorIds[nn].id; 118 119 return -1; 120 } 121 122 /* return the current time in nanoseconds */ 123 static int64_t now_ns(void) { 124 struct timespec ts; 125 clock_gettime(CLOCK_MONOTONIC, &ts); 126 return (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec; 127 } 128 129 /** SENSORS POLL DEVICE 130 ** 131 ** This one is used to read sensor data from the hardware. 132 ** We implement this by simply reading the data from the 133 ** emulator through the QEMUD channel. 134 **/ 135 136 typedef struct SensorDevice { 137 struct sensors_poll_device_1 device; 138 sensors_event_t sensors[MAX_NUM_SENSORS]; 139 uint32_t pendingSensors; 140 int64_t timeStart; 141 int64_t timeOffset; 142 uint32_t active_sensors; 143 int fd; 144 pthread_mutex_t lock; 145 } SensorDevice; 146 147 /* Grab the file descriptor to the emulator's sensors service pipe. 148 * This function returns a file descriptor on success, or -errno on 149 * failure, and assumes the SensorDevice instance's lock is held. 150 * 151 * This is needed because set_delay(), poll() and activate() can be called 152 * from different threads, and poll() is blocking. 153 * 154 * Note that the emulator's sensors service creates a new client for each 155 * connection through qemud_channel_open(), where each client has its own 156 * delay and set of activated sensors. This precludes calling 157 * qemud_channel_open() on each request, because a typical emulated system 158 * will do something like: 159 * 160 * 1) On a first thread, de-activate() all sensors first, then call poll(), 161 * which results in the thread blocking. 162 * 163 * 2) On a second thread, slightly later, call set_delay() then activate() 164 * to enable the acceleration sensor. 165 * 166 * The system expects this to unblock the first thread which will receive 167 * new sensor events after the activate() call in 2). 168 * 169 * This cannot work if both threads don't use the same connection. 170 * 171 * TODO(digit): This protocol is brittle, implement another control channel 172 * for set_delay()/activate()/batch() when supporting HAL 1.3 173 */ 174 static int sensor_device_get_fd_locked(SensorDevice* dev) { 175 /* Create connection to service on first call */ 176 if (dev->fd < 0) { 177 dev->fd = qemud_channel_open(SENSORS_SERVICE_NAME); 178 if (dev->fd < 0) { 179 int ret = -errno; 180 E("%s: Could not open connection to service: %s", __FUNCTION__, 181 strerror(-ret)); 182 return ret; 183 } 184 } 185 return dev->fd; 186 } 187 188 /* Send a command to the sensors virtual device. |dev| is a device instance and 189 * |cmd| is a zero-terminated command string. Return 0 on success, or -errno 190 * on failure. */ 191 static int sensor_device_send_command_locked(SensorDevice* dev, 192 const char* cmd) { 193 int fd = sensor_device_get_fd_locked(dev); 194 if (fd < 0) { 195 return fd; 196 } 197 198 int ret = 0; 199 if (qemud_channel_send(fd, cmd, strlen(cmd)) < 0) { 200 ret = -errno; 201 E("%s(fd=%d): ERROR: %s", __FUNCTION__, fd, strerror(errno)); 202 } 203 return ret; 204 } 205 206 /* Pick up one pending sensor event. On success, this returns the sensor 207 * id, and sets |*event| accordingly. On failure, i.e. if there are no 208 * pending events, return -EINVAL. 209 * 210 * Note: The device's lock must be acquired. 211 */ 212 static int sensor_device_pick_pending_event_locked(SensorDevice* d, 213 sensors_event_t* event) 214 { 215 uint32_t mask = SUPPORTED_SENSORS & d->pendingSensors; 216 if (mask) { 217 uint32_t i = 31 - __builtin_clz(mask); 218 d->pendingSensors &= ~(1U << i); 219 *event = d->sensors[i]; 220 event->sensor = i; 221 event->version = sizeof(*event); 222 223 D("%s: %d [%f, %f, %f]", __FUNCTION__, 224 i, 225 event->data[0], 226 event->data[1], 227 event->data[2]); 228 return i; 229 } 230 E("No sensor to return!!! pendingSensors=0x%08x", d->pendingSensors); 231 // we may end-up in a busy loop, slow things down, just in case. 232 usleep(100000); 233 return -EINVAL; 234 } 235 236 /* Block until new sensor events are reported by the emulator, or if a 237 * 'wake' command is received through the service. On succes, return 0 238 * and updates the |pendingEvents| and |sensors| fields of |dev|. 239 * On failure, return -errno. 240 * 241 * Note: The device lock must be acquired when calling this function, and 242 * will still be held on return. However, the function releases the 243 * lock temporarily during the blocking wait. 244 */ 245 static int sensor_device_poll_event_locked(SensorDevice* dev) 246 { 247 D("%s: dev=%p", __FUNCTION__, dev); 248 249 int fd = sensor_device_get_fd_locked(dev); 250 if (fd < 0) { 251 E("%s: Could not get pipe channel: %s", __FUNCTION__, strerror(-fd)); 252 return fd; 253 } 254 255 // Accumulate pending events into |events| and |new_sensors| mask 256 // until a 'sync' or 'wake' command is received. This also simplifies the 257 // code a bit. 258 uint32_t new_sensors = 0U; 259 sensors_event_t* events = dev->sensors; 260 261 int64_t event_time = -1; 262 int ret = 0; 263 264 for (;;) { 265 /* Release the lock since we're going to block on recv() */ 266 pthread_mutex_unlock(&dev->lock); 267 268 /* read the next event */ 269 char buff[256]; 270 int len = qemud_channel_recv(fd, buff, sizeof(buff) - 1U); 271 /* re-acquire the lock to modify the device state. */ 272 pthread_mutex_lock(&dev->lock); 273 274 if (len < 0) { 275 ret = -errno; 276 E("%s(fd=%d): Could not receive event data len=%d, errno=%d: %s", 277 __FUNCTION__, fd, len, errno, strerror(errno)); 278 break; 279 } 280 buff[len] = 0; 281 D("%s(fd=%d): received [%s]", __FUNCTION__, fd, buff); 282 283 284 /* "wake" is sent from the emulator to exit this loop. */ 285 /* TODO(digit): Is it still needed? */ 286 if (!strcmp((const char*)buff, "wake")) { 287 ret = 0x7FFFFFFF; 288 break; 289 } 290 291 float params[3]; 292 293 /* "acceleration:<x>:<y>:<z>" corresponds to an acceleration event */ 294 if (sscanf(buff, "acceleration:%g:%g:%g", params+0, params+1, params+2) 295 == 3) { 296 new_sensors |= SENSORS_ACCELERATION; 297 events[ID_ACCELERATION].acceleration.x = params[0]; 298 events[ID_ACCELERATION].acceleration.y = params[1]; 299 events[ID_ACCELERATION].acceleration.z = params[2]; 300 events[ID_ACCELERATION].type = SENSOR_TYPE_ACCELEROMETER; 301 continue; 302 } 303 304 /* "orientation:<azimuth>:<pitch>:<roll>" is sent when orientation 305 * changes */ 306 if (sscanf(buff, "orientation:%g:%g:%g", params+0, params+1, params+2) 307 == 3) { 308 new_sensors |= SENSORS_ORIENTATION; 309 events[ID_ORIENTATION].orientation.azimuth = params[0]; 310 events[ID_ORIENTATION].orientation.pitch = params[1]; 311 events[ID_ORIENTATION].orientation.roll = params[2]; 312 events[ID_ORIENTATION].orientation.status = 313 SENSOR_STATUS_ACCURACY_HIGH; 314 events[ID_ORIENTATION].type = SENSOR_TYPE_ORIENTATION; 315 continue; 316 } 317 318 /* "magnetic:<x>:<y>:<z>" is sent for the params of the magnetic 319 * field */ 320 if (sscanf(buff, "magnetic:%g:%g:%g", params+0, params+1, params+2) 321 == 3) { 322 new_sensors |= SENSORS_MAGNETIC_FIELD; 323 events[ID_MAGNETIC_FIELD].magnetic.x = params[0]; 324 events[ID_MAGNETIC_FIELD].magnetic.y = params[1]; 325 events[ID_MAGNETIC_FIELD].magnetic.z = params[2]; 326 events[ID_MAGNETIC_FIELD].magnetic.status = 327 SENSOR_STATUS_ACCURACY_HIGH; 328 events[ID_MAGNETIC_FIELD].type = SENSOR_TYPE_MAGNETIC_FIELD; 329 continue; 330 } 331 332 /* "temperature:<celsius>" */ 333 if (sscanf(buff, "temperature:%g", params+0) == 1) { 334 new_sensors |= SENSORS_TEMPERATURE; 335 events[ID_TEMPERATURE].temperature = params[0]; 336 events[ID_TEMPERATURE].type = SENSOR_TYPE_TEMPERATURE; 337 continue; 338 } 339 340 /* "proximity:<value>" */ 341 if (sscanf(buff, "proximity:%g", params+0) == 1) { 342 new_sensors |= SENSORS_PROXIMITY; 343 events[ID_PROXIMITY].distance = params[0]; 344 events[ID_PROXIMITY].type = SENSOR_TYPE_PROXIMITY; 345 continue; 346 } 347 /* "light:<lux>" */ 348 if (sscanf(buff, "light:%g", params+0) == 1) { 349 new_sensors |= SENSORS_LIGHT; 350 events[ID_LIGHT].light = params[0]; 351 events[ID_LIGHT].type = SENSOR_TYPE_LIGHT; 352 continue; 353 } 354 355 /* "pressure:<hpa>" */ 356 if (sscanf(buff, "pressure:%g", params+0) == 1) { 357 new_sensors |= SENSORS_PRESSURE; 358 events[ID_PRESSURE].pressure = params[0]; 359 events[ID_PRESSURE].type = SENSOR_TYPE_PRESSURE; 360 continue; 361 } 362 363 /* "humidity:<percent>" */ 364 if (sscanf(buff, "humidity:%g", params+0) == 1) { 365 new_sensors |= SENSORS_HUMIDITY; 366 events[ID_HUMIDITY].relative_humidity = params[0]; 367 events[ID_HUMIDITY].type = SENSOR_TYPE_RELATIVE_HUMIDITY; 368 continue; 369 } 370 371 /* "sync:<time>" is sent after a series of sensor events. 372 * where 'time' is expressed in micro-seconds and corresponds 373 * to the VM time when the real poll occured. 374 */ 375 if (sscanf(buff, "sync:%lld", &event_time) == 1) { 376 if (new_sensors) { 377 goto out; 378 } 379 D("huh ? sync without any sensor data ?"); 380 continue; 381 } 382 D("huh ? unsupported command"); 383 } 384 out: 385 if (new_sensors) { 386 /* update the time of each new sensor event. */ 387 dev->pendingSensors |= new_sensors; 388 int64_t t = (event_time < 0) ? 0 : event_time * 1000LL; 389 390 /* use the time at the first sync: as the base for later 391 * time values */ 392 if (dev->timeStart == 0) { 393 dev->timeStart = now_ns(); 394 dev->timeOffset = dev->timeStart - t; 395 } 396 t += dev->timeOffset; 397 398 while (new_sensors) { 399 uint32_t i = 31 - __builtin_clz(new_sensors); 400 new_sensors &= ~(1U << i); 401 dev->sensors[i].timestamp = t; 402 } 403 } 404 return ret; 405 } 406 407 /** SENSORS POLL DEVICE FUNCTIONS **/ 408 409 static int sensor_device_close(struct hw_device_t* dev0) 410 { 411 SensorDevice* dev = (void*)dev0; 412 // Assume that there are no other threads blocked on poll() 413 if (dev->fd >= 0) { 414 close(dev->fd); 415 dev->fd = -1; 416 } 417 pthread_mutex_destroy(&dev->lock); 418 free(dev); 419 return 0; 420 } 421 422 /* Return an array of sensor data. This function blocks until there is sensor 423 * related events to report. On success, it will write the events into the 424 * |data| array, which contains |count| items. The function returns the number 425 * of events written into the array, which shall never be greater than |count|. 426 * On error, return -errno code. 427 * 428 * Note that according to the sensor HAL [1], it shall never return 0! 429 * 430 * [1] http://source.android.com/devices/sensors/hal-interface.html 431 */ 432 static int sensor_device_poll(struct sensors_poll_device_t *dev0, 433 sensors_event_t* data, int count) 434 { 435 SensorDevice* dev = (void*)dev0; 436 D("%s: dev=%p data=%p count=%d ", __FUNCTION__, dev, data, count); 437 438 if (count <= 0) { 439 return -EINVAL; 440 } 441 442 int result = 0; 443 pthread_mutex_lock(&dev->lock); 444 if (!dev->pendingSensors) { 445 /* Block until there are pending events. Note that this releases 446 * the lock during the blocking call, then re-acquires it before 447 * returning. */ 448 int ret = sensor_device_poll_event_locked(dev); 449 if (ret < 0) { 450 result = ret; 451 goto out; 452 } 453 if (!dev->pendingSensors) { 454 /* 'wake' event received before any sensor data. */ 455 result = -EIO; 456 goto out; 457 } 458 } 459 /* Now read as many pending events as needed. */ 460 int i; 461 for (i = 0; i < count; i++) { 462 if (!dev->pendingSensors) { 463 break; 464 } 465 int ret = sensor_device_pick_pending_event_locked(dev, data); 466 if (ret < 0) { 467 if (!result) { 468 result = ret; 469 } 470 break; 471 } 472 data++; 473 result++; 474 } 475 out: 476 pthread_mutex_unlock(&dev->lock); 477 D("%s: result=%d", __FUNCTION__, result); 478 return result; 479 } 480 481 static int sensor_device_activate(struct sensors_poll_device_t *dev0, 482 int handle, 483 int enabled) 484 { 485 SensorDevice* dev = (void*)dev0; 486 487 D("%s: handle=%s (%d) enabled=%d", __FUNCTION__, 488 _sensorIdToName(handle), handle, enabled); 489 490 /* Sanity check */ 491 if (!ID_CHECK(handle)) { 492 E("%s: bad handle ID", __FUNCTION__); 493 return -EINVAL; 494 } 495 496 /* Exit early if sensor is already enabled/disabled. */ 497 uint32_t mask = (1U << handle); 498 uint32_t sensors = enabled ? mask : 0; 499 500 pthread_mutex_lock(&dev->lock); 501 502 uint32_t active = dev->active_sensors; 503 uint32_t new_sensors = (active & ~mask) | (sensors & mask); 504 uint32_t changed = active ^ new_sensors; 505 506 int ret = 0; 507 if (changed) { 508 /* Send command to the emulator. */ 509 char command[64]; 510 snprintf(command, 511 sizeof command, 512 "set:%s:%d", 513 _sensorIdToName(handle), 514 enabled != 0); 515 516 ret = sensor_device_send_command_locked(dev, command); 517 if (ret < 0) { 518 E("%s: when sending command errno=%d: %s", __FUNCTION__, -ret, 519 strerror(-ret)); 520 } else { 521 dev->active_sensors = new_sensors; 522 } 523 } 524 pthread_mutex_unlock(&dev->lock); 525 return ret; 526 } 527 528 static int sensor_device_set_delay(struct sensors_poll_device_t *dev0, 529 int handle __unused, 530 int64_t ns) 531 { 532 SensorDevice* dev = (void*)dev0; 533 534 int ms = (int)(ns / 1000000); 535 D("%s: dev=%p delay-ms=%d", __FUNCTION__, dev, ms); 536 537 char command[64]; 538 snprintf(command, sizeof command, "set-delay:%d", ms); 539 540 pthread_mutex_lock(&dev->lock); 541 int ret = sensor_device_send_command_locked(dev, command); 542 pthread_mutex_unlock(&dev->lock); 543 if (ret < 0) { 544 E("%s: Could not send command: %s", __FUNCTION__, strerror(-ret)); 545 } 546 return ret; 547 } 548 549 /** MODULE REGISTRATION SUPPORT 550 ** 551 ** This is required so that hardware/libhardware/hardware.c 552 ** will dlopen() this library appropriately. 553 **/ 554 555 /* 556 * the following is the list of all supported sensors. 557 * this table is used to build sSensorList declared below 558 * according to which hardware sensors are reported as 559 * available from the emulator (see get_sensors_list below) 560 * 561 * note: numerical values for maxRange/resolution/power for 562 * all sensors but light, pressure and humidity were 563 * taken from the reference AK8976A implementation 564 */ 565 static const struct sensor_t sSensorListInit[] = { 566 { .name = "Goldfish 3-axis Accelerometer", 567 .vendor = "The Android Open Source Project", 568 .version = 1, 569 .handle = ID_ACCELERATION, 570 .type = SENSOR_TYPE_ACCELEROMETER, 571 .maxRange = 2.8f, 572 .resolution = 1.0f/4032.0f, 573 .power = 3.0f, 574 .reserved = {} 575 }, 576 577 { .name = "Goldfish 3-axis Magnetic field sensor", 578 .vendor = "The Android Open Source Project", 579 .version = 1, 580 .handle = ID_MAGNETIC_FIELD, 581 .type = SENSOR_TYPE_MAGNETIC_FIELD, 582 .maxRange = 2000.0f, 583 .resolution = 1.0f, 584 .power = 6.7f, 585 .reserved = {} 586 }, 587 588 { .name = "Goldfish Orientation sensor", 589 .vendor = "The Android Open Source Project", 590 .version = 1, 591 .handle = ID_ORIENTATION, 592 .type = SENSOR_TYPE_ORIENTATION, 593 .maxRange = 360.0f, 594 .resolution = 1.0f, 595 .power = 9.7f, 596 .reserved = {} 597 }, 598 599 { .name = "Goldfish Temperature sensor", 600 .vendor = "The Android Open Source Project", 601 .version = 1, 602 .handle = ID_TEMPERATURE, 603 .type = SENSOR_TYPE_TEMPERATURE, 604 .maxRange = 80.0f, 605 .resolution = 1.0f, 606 .power = 0.0f, 607 .reserved = {} 608 }, 609 610 { .name = "Goldfish Proximity sensor", 611 .vendor = "The Android Open Source Project", 612 .version = 1, 613 .handle = ID_PROXIMITY, 614 .type = SENSOR_TYPE_PROXIMITY, 615 .maxRange = 1.0f, 616 .resolution = 1.0f, 617 .power = 20.0f, 618 .reserved = {} 619 }, 620 621 { .name = "Goldfish Light sensor", 622 .vendor = "The Android Open Source Project", 623 .version = 1, 624 .handle = ID_LIGHT, 625 .type = SENSOR_TYPE_LIGHT, 626 .maxRange = 40000.0f, 627 .resolution = 1.0f, 628 .power = 20.0f, 629 .reserved = {} 630 }, 631 632 { .name = "Goldfish Pressure sensor", 633 .vendor = "The Android Open Source Project", 634 .version = 1, 635 .handle = ID_PRESSURE, 636 .type = SENSOR_TYPE_PRESSURE, 637 .maxRange = 800.0f, 638 .resolution = 1.0f, 639 .power = 20.0f, 640 .reserved = {} 641 }, 642 643 { .name = "Goldfish Humidity sensor", 644 .vendor = "The Android Open Source Project", 645 .version = 1, 646 .handle = ID_HUMIDITY, 647 .type = SENSOR_TYPE_RELATIVE_HUMIDITY, 648 .maxRange = 100.0f, 649 .resolution = 1.0f, 650 .power = 20.0f, 651 .reserved = {} 652 } 653 }; 654 655 static struct sensor_t sSensorList[MAX_NUM_SENSORS]; 656 657 static int sensors__get_sensors_list(struct sensors_module_t* module __unused, 658 struct sensor_t const** list) 659 { 660 int fd = qemud_channel_open(SENSORS_SERVICE_NAME); 661 char buffer[12]; 662 int mask, nn, count; 663 int ret = 0; 664 665 if (fd < 0) { 666 E("%s: no qemud connection", __FUNCTION__); 667 goto out; 668 } 669 ret = qemud_channel_send(fd, "list-sensors", -1); 670 if (ret < 0) { 671 E("%s: could not query sensor list: %s", __FUNCTION__, 672 strerror(errno)); 673 goto out; 674 } 675 ret = qemud_channel_recv(fd, buffer, sizeof buffer-1); 676 if (ret < 0) { 677 E("%s: could not receive sensor list: %s", __FUNCTION__, 678 strerror(errno)); 679 goto out; 680 } 681 buffer[ret] = 0; 682 683 /* the result is a integer used as a mask for available sensors */ 684 mask = atoi(buffer); 685 count = 0; 686 for (nn = 0; nn < MAX_NUM_SENSORS; nn++) { 687 if (((1 << nn) & mask) == 0) 688 continue; 689 690 sSensorList[count++] = sSensorListInit[nn]; 691 } 692 D("%s: returned %d sensors (mask=%d)", __FUNCTION__, count, mask); 693 *list = sSensorList; 694 695 ret = count; 696 out: 697 if (fd >= 0) { 698 close(fd); 699 } 700 return ret; 701 } 702 703 704 static int 705 open_sensors(const struct hw_module_t* module, 706 const char* name, 707 struct hw_device_t* *device) 708 { 709 int status = -EINVAL; 710 711 D("%s: name=%s", __FUNCTION__, name); 712 713 if (!strcmp(name, SENSORS_HARDWARE_POLL)) { 714 SensorDevice *dev = malloc(sizeof(*dev)); 715 716 memset(dev, 0, sizeof(*dev)); 717 718 dev->device.common.tag = HARDWARE_DEVICE_TAG; 719 dev->device.common.version = SENSORS_DEVICE_API_VERSION_1_0; 720 dev->device.common.module = (struct hw_module_t*) module; 721 dev->device.common.close = sensor_device_close; 722 dev->device.poll = sensor_device_poll; 723 dev->device.activate = sensor_device_activate; 724 dev->device.setDelay = sensor_device_set_delay; 725 726 dev->fd = -1; 727 pthread_mutex_init(&dev->lock, NULL); 728 729 *device = &dev->device.common; 730 status = 0; 731 } 732 return status; 733 } 734 735 736 static struct hw_module_methods_t sensors_module_methods = { 737 .open = open_sensors 738 }; 739 740 struct sensors_module_t HAL_MODULE_INFO_SYM = { 741 .common = { 742 .tag = HARDWARE_MODULE_TAG, 743 .version_major = 1, 744 .version_minor = 0, 745 .id = SENSORS_HARDWARE_MODULE_ID, 746 .name = "Goldfish SENSORS Module", 747 .author = "The Android Open Source Project", 748 .methods = &sensors_module_methods, 749 }, 750 .get_sensors_list = sensors__get_sensors_list 751 }; 752