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