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