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