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