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