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