1 /* 2 * Copyright (C) 2010 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 #include <stdint.h> 18 #include <math.h> 19 #include <sys/types.h> 20 21 #include <cutils/properties.h> 22 23 #include <utils/SortedVector.h> 24 #include <utils/KeyedVector.h> 25 #include <utils/threads.h> 26 #include <utils/Atomic.h> 27 #include <utils/Errors.h> 28 #include <utils/RefBase.h> 29 #include <utils/Singleton.h> 30 #include <utils/String16.h> 31 32 #include <binder/BinderService.h> 33 #include <binder/IServiceManager.h> 34 #include <binder/PermissionCache.h> 35 36 #include <gui/ISensorServer.h> 37 #include <gui/ISensorEventConnection.h> 38 39 #include <hardware/sensors.h> 40 41 #include "CorrectedGyroSensor.h" 42 #include "GravitySensor.h" 43 #include "LinearAccelerationSensor.h" 44 #include "OrientationSensor.h" 45 #include "RotationVectorSensor.h" 46 #include "SensorFusion.h" 47 #include "SensorService.h" 48 49 namespace android { 50 // --------------------------------------------------------------------------- 51 52 /* 53 * Notes: 54 * 55 * - what about a gyro-corrected magnetic-field sensor? 56 * - run mag sensor from time to time to force calibration 57 * - gravity sensor length is wrong (=> drift in linear-acc sensor) 58 * 59 */ 60 61 SensorService::SensorService() 62 : mInitCheck(NO_INIT) 63 { 64 } 65 66 void SensorService::onFirstRef() 67 { 68 LOGD("nuSensorService starting..."); 69 70 SensorDevice& dev(SensorDevice::getInstance()); 71 72 if (dev.initCheck() == NO_ERROR) { 73 sensor_t const* list; 74 ssize_t count = dev.getSensorList(&list); 75 if (count > 0) { 76 ssize_t orientationIndex = -1; 77 bool hasGyro = false; 78 uint32_t virtualSensorsNeeds = 79 (1<<SENSOR_TYPE_GRAVITY) | 80 (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | 81 (1<<SENSOR_TYPE_ROTATION_VECTOR); 82 83 mLastEventSeen.setCapacity(count); 84 for (ssize_t i=0 ; i<count ; i++) { 85 registerSensor( new HardwareSensor(list[i]) ); 86 switch (list[i].type) { 87 case SENSOR_TYPE_ORIENTATION: 88 orientationIndex = i; 89 break; 90 case SENSOR_TYPE_GYROSCOPE: 91 hasGyro = true; 92 break; 93 case SENSOR_TYPE_GRAVITY: 94 case SENSOR_TYPE_LINEAR_ACCELERATION: 95 case SENSOR_TYPE_ROTATION_VECTOR: 96 virtualSensorsNeeds &= ~(1<<list[i].type); 97 break; 98 } 99 } 100 101 // it's safe to instantiate the SensorFusion object here 102 // (it wants to be instantiated after h/w sensors have been 103 // registered) 104 const SensorFusion& fusion(SensorFusion::getInstance()); 105 106 if (hasGyro) { 107 // Always instantiate Android's virtual sensors. Since they are 108 // instantiated behind sensors from the HAL, they won't 109 // interfere with applications, unless they looks specifically 110 // for them (by name). 111 112 registerVirtualSensor( new RotationVectorSensor() ); 113 registerVirtualSensor( new GravitySensor(list, count) ); 114 registerVirtualSensor( new LinearAccelerationSensor(list, count) ); 115 116 // these are optional 117 registerVirtualSensor( new OrientationSensor() ); 118 registerVirtualSensor( new CorrectedGyroSensor(list, count) ); 119 120 // virtual debugging sensors... 121 char value[PROPERTY_VALUE_MAX]; 122 property_get("debug.sensors", value, "0"); 123 if (atoi(value)) { 124 registerVirtualSensor( new GyroDriftSensor() ); 125 } 126 } 127 128 // build the sensor list returned to users 129 mUserSensorList = mSensorList; 130 if (hasGyro && 131 (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) { 132 // if we have the fancy sensor fusion, and it's not provided by the 133 // HAL, use our own (fused) orientation sensor by removing the 134 // HAL supplied one form the user list. 135 if (orientationIndex >= 0) { 136 mUserSensorList.removeItemsAt(orientationIndex); 137 } 138 } 139 140 run("SensorService", PRIORITY_URGENT_DISPLAY); 141 mInitCheck = NO_ERROR; 142 } 143 } 144 } 145 146 void SensorService::registerSensor(SensorInterface* s) 147 { 148 sensors_event_t event; 149 memset(&event, 0, sizeof(event)); 150 151 const Sensor sensor(s->getSensor()); 152 // add to the sensor list (returned to clients) 153 mSensorList.add(sensor); 154 // add to our handle->SensorInterface mapping 155 mSensorMap.add(sensor.getHandle(), s); 156 // create an entry in the mLastEventSeen array 157 mLastEventSeen.add(sensor.getHandle(), event); 158 } 159 160 void SensorService::registerVirtualSensor(SensorInterface* s) 161 { 162 registerSensor(s); 163 mVirtualSensorList.add( s ); 164 } 165 166 SensorService::~SensorService() 167 { 168 for (size_t i=0 ; i<mSensorMap.size() ; i++) 169 delete mSensorMap.valueAt(i); 170 } 171 172 static const String16 sDump("android.permission.DUMP"); 173 174 status_t SensorService::dump(int fd, const Vector<String16>& args) 175 { 176 const size_t SIZE = 1024; 177 char buffer[SIZE]; 178 String8 result; 179 if (!PermissionCache::checkCallingPermission(sDump)) { 180 snprintf(buffer, SIZE, "Permission Denial: " 181 "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 182 IPCThreadState::self()->getCallingPid(), 183 IPCThreadState::self()->getCallingUid()); 184 result.append(buffer); 185 } else { 186 Mutex::Autolock _l(mLock); 187 snprintf(buffer, SIZE, "Sensor List:\n"); 188 result.append(buffer); 189 for (size_t i=0 ; i<mSensorList.size() ; i++) { 190 const Sensor& s(mSensorList[i]); 191 const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle())); 192 snprintf(buffer, SIZE, 193 "%-48s| %-32s | 0x%08x | maxRate=%7.2fHz | " 194 "last=<%5.1f,%5.1f,%5.1f>\n", 195 s.getName().string(), 196 s.getVendor().string(), 197 s.getHandle(), 198 s.getMinDelay() ? (1000000.0f / s.getMinDelay()) : 0.0f, 199 e.data[0], e.data[1], e.data[2]); 200 result.append(buffer); 201 } 202 SensorFusion::getInstance().dump(result, buffer, SIZE); 203 SensorDevice::getInstance().dump(result, buffer, SIZE); 204 205 snprintf(buffer, SIZE, "%d active connections\n", 206 mActiveConnections.size()); 207 result.append(buffer); 208 snprintf(buffer, SIZE, "Active sensors:\n"); 209 result.append(buffer); 210 for (size_t i=0 ; i<mActiveSensors.size() ; i++) { 211 int handle = mActiveSensors.keyAt(i); 212 snprintf(buffer, SIZE, "%s (handle=0x%08x, connections=%d)\n", 213 getSensorName(handle).string(), 214 handle, 215 mActiveSensors.valueAt(i)->getNumConnections()); 216 result.append(buffer); 217 } 218 } 219 write(fd, result.string(), result.size()); 220 return NO_ERROR; 221 } 222 223 bool SensorService::threadLoop() 224 { 225 LOGD("nuSensorService thread starting..."); 226 227 const size_t numEventMax = 16 * (1 + mVirtualSensorList.size()); 228 sensors_event_t buffer[numEventMax]; 229 sensors_event_t scratch[numEventMax]; 230 SensorDevice& device(SensorDevice::getInstance()); 231 const size_t vcount = mVirtualSensorList.size(); 232 233 ssize_t count; 234 do { 235 count = device.poll(buffer, numEventMax); 236 if (count<0) { 237 LOGE("sensor poll failed (%s)", strerror(-count)); 238 break; 239 } 240 241 recordLastValue(buffer, count); 242 243 // handle virtual sensors 244 if (count && vcount) { 245 sensors_event_t const * const event = buffer; 246 const DefaultKeyedVector<int, SensorInterface*> virtualSensors( 247 getActiveVirtualSensors()); 248 const size_t activeVirtualSensorCount = virtualSensors.size(); 249 if (activeVirtualSensorCount) { 250 size_t k = 0; 251 SensorFusion& fusion(SensorFusion::getInstance()); 252 if (fusion.isEnabled()) { 253 for (size_t i=0 ; i<size_t(count) ; i++) { 254 fusion.process(event[i]); 255 } 256 } 257 for (size_t i=0 ; i<size_t(count) ; i++) { 258 for (size_t j=0 ; j<activeVirtualSensorCount ; j++) { 259 sensors_event_t out; 260 if (virtualSensors.valueAt(j)->process(&out, event[i])) { 261 buffer[count + k] = out; 262 k++; 263 } 264 } 265 } 266 if (k) { 267 // record the last synthesized values 268 recordLastValue(&buffer[count], k); 269 count += k; 270 // sort the buffer by time-stamps 271 sortEventBuffer(buffer, count); 272 } 273 } 274 } 275 276 // send our events to clients... 277 const SortedVector< wp<SensorEventConnection> > activeConnections( 278 getActiveConnections()); 279 size_t numConnections = activeConnections.size(); 280 for (size_t i=0 ; i<numConnections ; i++) { 281 sp<SensorEventConnection> connection( 282 activeConnections[i].promote()); 283 if (connection != 0) { 284 connection->sendEvents(buffer, count, scratch); 285 } 286 } 287 } while (count >= 0 || Thread::exitPending()); 288 289 LOGW("Exiting SensorService::threadLoop!"); 290 return false; 291 } 292 293 void SensorService::recordLastValue( 294 sensors_event_t const * buffer, size_t count) 295 { 296 Mutex::Autolock _l(mLock); 297 298 // record the last event for each sensor 299 int32_t prev = buffer[0].sensor; 300 for (size_t i=1 ; i<count ; i++) { 301 // record the last event of each sensor type in this buffer 302 int32_t curr = buffer[i].sensor; 303 if (curr != prev) { 304 mLastEventSeen.editValueFor(prev) = buffer[i-1]; 305 prev = curr; 306 } 307 } 308 mLastEventSeen.editValueFor(prev) = buffer[count-1]; 309 } 310 311 void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) 312 { 313 struct compar { 314 static int cmp(void const* lhs, void const* rhs) { 315 sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs); 316 sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs); 317 return r->timestamp - l->timestamp; 318 } 319 }; 320 qsort(buffer, count, sizeof(sensors_event_t), compar::cmp); 321 } 322 323 SortedVector< wp<SensorService::SensorEventConnection> > 324 SensorService::getActiveConnections() const 325 { 326 Mutex::Autolock _l(mLock); 327 return mActiveConnections; 328 } 329 330 DefaultKeyedVector<int, SensorInterface*> 331 SensorService::getActiveVirtualSensors() const 332 { 333 Mutex::Autolock _l(mLock); 334 return mActiveVirtualSensors; 335 } 336 337 String8 SensorService::getSensorName(int handle) const { 338 size_t count = mUserSensorList.size(); 339 for (size_t i=0 ; i<count ; i++) { 340 const Sensor& sensor(mUserSensorList[i]); 341 if (sensor.getHandle() == handle) { 342 return sensor.getName(); 343 } 344 } 345 String8 result("unknown"); 346 return result; 347 } 348 349 Vector<Sensor> SensorService::getSensorList() 350 { 351 return mUserSensorList; 352 } 353 354 sp<ISensorEventConnection> SensorService::createSensorEventConnection() 355 { 356 sp<SensorEventConnection> result(new SensorEventConnection(this)); 357 return result; 358 } 359 360 void SensorService::cleanupConnection(SensorEventConnection* c) 361 { 362 Mutex::Autolock _l(mLock); 363 const wp<SensorEventConnection> connection(c); 364 size_t size = mActiveSensors.size(); 365 LOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size); 366 for (size_t i=0 ; i<size ; ) { 367 int handle = mActiveSensors.keyAt(i); 368 if (c->hasSensor(handle)) { 369 LOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle); 370 SensorInterface* sensor = mSensorMap.valueFor( handle ); 371 LOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle); 372 if (sensor) { 373 sensor->activate(c, false); 374 } 375 } 376 SensorRecord* rec = mActiveSensors.valueAt(i); 377 LOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle); 378 LOGD_IF(DEBUG_CONNECTIONS, 379 "removing connection %p for sensor[%d].handle=0x%08x", 380 c, i, handle); 381 382 if (rec && rec->removeConnection(connection)) { 383 LOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection"); 384 mActiveSensors.removeItemsAt(i, 1); 385 mActiveVirtualSensors.removeItem(handle); 386 delete rec; 387 size--; 388 } else { 389 i++; 390 } 391 } 392 mActiveConnections.remove(connection); 393 } 394 395 status_t SensorService::enable(const sp<SensorEventConnection>& connection, 396 int handle) 397 { 398 if (mInitCheck != NO_ERROR) 399 return mInitCheck; 400 401 Mutex::Autolock _l(mLock); 402 SensorInterface* sensor = mSensorMap.valueFor(handle); 403 status_t err = sensor ? sensor->activate(connection.get(), true) : status_t(BAD_VALUE); 404 if (err == NO_ERROR) { 405 SensorRecord* rec = mActiveSensors.valueFor(handle); 406 if (rec == 0) { 407 rec = new SensorRecord(connection); 408 mActiveSensors.add(handle, rec); 409 if (sensor->isVirtual()) { 410 mActiveVirtualSensors.add(handle, sensor); 411 } 412 } else { 413 if (rec->addConnection(connection)) { 414 // this sensor is already activated, but we are adding a 415 // connection that uses it. Immediately send down the last 416 // known value of the requested sensor if it's not a 417 // "continuous" sensor. 418 if (sensor->getSensor().getMinDelay() == 0) { 419 sensors_event_t scratch; 420 sensors_event_t& event(mLastEventSeen.editValueFor(handle)); 421 if (event.version == sizeof(sensors_event_t)) { 422 connection->sendEvents(&event, 1); 423 } 424 } 425 } 426 } 427 if (err == NO_ERROR) { 428 // connection now active 429 if (connection->addSensor(handle)) { 430 // the sensor was added (which means it wasn't already there) 431 // so, see if this connection becomes active 432 if (mActiveConnections.indexOf(connection) < 0) { 433 mActiveConnections.add(connection); 434 } 435 } 436 } 437 } 438 return err; 439 } 440 441 status_t SensorService::disable(const sp<SensorEventConnection>& connection, 442 int handle) 443 { 444 if (mInitCheck != NO_ERROR) 445 return mInitCheck; 446 447 status_t err = NO_ERROR; 448 Mutex::Autolock _l(mLock); 449 SensorRecord* rec = mActiveSensors.valueFor(handle); 450 if (rec) { 451 // see if this connection becomes inactive 452 connection->removeSensor(handle); 453 if (connection->hasAnySensor() == false) { 454 mActiveConnections.remove(connection); 455 } 456 // see if this sensor becomes inactive 457 if (rec->removeConnection(connection)) { 458 mActiveSensors.removeItem(handle); 459 mActiveVirtualSensors.removeItem(handle); 460 delete rec; 461 } 462 SensorInterface* sensor = mSensorMap.valueFor(handle); 463 err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE); 464 } 465 return err; 466 } 467 468 status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, 469 int handle, nsecs_t ns) 470 { 471 if (mInitCheck != NO_ERROR) 472 return mInitCheck; 473 474 if (ns < 0) 475 return BAD_VALUE; 476 477 if (ns < MINIMUM_EVENTS_PERIOD) 478 ns = MINIMUM_EVENTS_PERIOD; 479 480 SensorInterface* sensor = mSensorMap.valueFor(handle); 481 if (!sensor) return BAD_VALUE; 482 return sensor->setDelay(connection.get(), handle, ns); 483 } 484 485 // --------------------------------------------------------------------------- 486 487 SensorService::SensorRecord::SensorRecord( 488 const sp<SensorEventConnection>& connection) 489 { 490 mConnections.add(connection); 491 } 492 493 bool SensorService::SensorRecord::addConnection( 494 const sp<SensorEventConnection>& connection) 495 { 496 if (mConnections.indexOf(connection) < 0) { 497 mConnections.add(connection); 498 return true; 499 } 500 return false; 501 } 502 503 bool SensorService::SensorRecord::removeConnection( 504 const wp<SensorEventConnection>& connection) 505 { 506 ssize_t index = mConnections.indexOf(connection); 507 if (index >= 0) { 508 mConnections.removeItemsAt(index, 1); 509 } 510 return mConnections.size() ? false : true; 511 } 512 513 // --------------------------------------------------------------------------- 514 515 SensorService::SensorEventConnection::SensorEventConnection( 516 const sp<SensorService>& service) 517 : mService(service), mChannel(new SensorChannel()) 518 { 519 } 520 521 SensorService::SensorEventConnection::~SensorEventConnection() 522 { 523 LOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this); 524 mService->cleanupConnection(this); 525 } 526 527 void SensorService::SensorEventConnection::onFirstRef() 528 { 529 } 530 531 bool SensorService::SensorEventConnection::addSensor(int32_t handle) { 532 Mutex::Autolock _l(mConnectionLock); 533 if (mSensorInfo.indexOf(handle) <= 0) { 534 mSensorInfo.add(handle); 535 return true; 536 } 537 return false; 538 } 539 540 bool SensorService::SensorEventConnection::removeSensor(int32_t handle) { 541 Mutex::Autolock _l(mConnectionLock); 542 if (mSensorInfo.remove(handle) >= 0) { 543 return true; 544 } 545 return false; 546 } 547 548 bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const { 549 Mutex::Autolock _l(mConnectionLock); 550 return mSensorInfo.indexOf(handle) >= 0; 551 } 552 553 bool SensorService::SensorEventConnection::hasAnySensor() const { 554 Mutex::Autolock _l(mConnectionLock); 555 return mSensorInfo.size() ? true : false; 556 } 557 558 status_t SensorService::SensorEventConnection::sendEvents( 559 sensors_event_t const* buffer, size_t numEvents, 560 sensors_event_t* scratch) 561 { 562 // filter out events not for this connection 563 size_t count = 0; 564 if (scratch) { 565 Mutex::Autolock _l(mConnectionLock); 566 size_t i=0; 567 while (i<numEvents) { 568 const int32_t curr = buffer[i].sensor; 569 if (mSensorInfo.indexOf(curr) >= 0) { 570 do { 571 scratch[count++] = buffer[i++]; 572 } while ((i<numEvents) && (buffer[i].sensor == curr)); 573 } else { 574 i++; 575 } 576 } 577 } else { 578 scratch = const_cast<sensors_event_t *>(buffer); 579 count = numEvents; 580 } 581 582 if (count == 0) 583 return 0; 584 585 ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t)); 586 if (size == -EAGAIN) { 587 // the destination doesn't accept events anymore, it's probably 588 // full. For now, we just drop the events on the floor. 589 //LOGW("dropping %d events on the floor", count); 590 return size; 591 } 592 593 //LOGE_IF(size<0, "dropping %d events on the floor (%s)", 594 // count, strerror(-size)); 595 596 return size < 0 ? status_t(size) : status_t(NO_ERROR); 597 } 598 599 sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const 600 { 601 return mChannel; 602 } 603 604 status_t SensorService::SensorEventConnection::enableDisable( 605 int handle, bool enabled) 606 { 607 status_t err; 608 if (enabled) { 609 err = mService->enable(this, handle); 610 } else { 611 err = mService->disable(this, handle); 612 } 613 return err; 614 } 615 616 status_t SensorService::SensorEventConnection::setEventRate( 617 int handle, nsecs_t ns) 618 { 619 return mService->setEventRate(this, handle, ns); 620 } 621 622 // --------------------------------------------------------------------------- 623 }; // namespace android 624 625