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