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