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