SensorService.cpp revision 451beee076cac09f817abae78a990dea108a9482
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 80SensorService::SensorService() 81 : Thread(false), 82 mDump("android.permission.DUMP") 83{ 84} 85 86void SensorService::onFirstRef() 87{ 88 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, 89 (hw_module_t const**)&mSensorModule); 90 91 LOGE_IF(err, "couldn't load %s module (%s)", 92 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 93 94 err = sensors_open(&mSensorModule->common, &mSensorDevice); 95 96 LOGE_IF(err, "couldn't open device for module %s (%s)", 97 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 98 99 LOGD("nuSensorService starting..."); 100 101 struct sensor_t const* list; 102 int count = mSensorModule->get_sensors_list(mSensorModule, &list); 103 for (int i=0 ; i<count ; i++) { 104 Sensor sensor(list + i); 105 LOGI("%s", sensor.getName().string()); 106 mSensorList.add(sensor); 107 mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0); 108 } 109 110 run("SensorService", PRIORITY_URGENT_DISPLAY); 111} 112 113SensorService::~SensorService() 114{ 115} 116 117status_t SensorService::dump(int fd, const Vector<String16>& args) 118{ 119 const size_t SIZE = 1024; 120 char buffer[SIZE]; 121 String8 result; 122 if (!mDump.checkCalling()) { 123 snprintf(buffer, SIZE, "Permission Denial: " 124 "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 125 IPCThreadState::self()->getCallingPid(), 126 IPCThreadState::self()->getCallingUid()); 127 result.append(buffer); 128 } else { 129 Mutex::Autolock _l(mLock); 130 snprintf(buffer, SIZE, "%d connections / %d active\n", 131 mConnections.size(), mActiveConnections.size()); 132 result.append(buffer); 133 snprintf(buffer, SIZE, "Active sensors:\n"); 134 result.append(buffer); 135 for (size_t i=0 ; i<mActiveSensors.size() ; i++) { 136 snprintf(buffer, SIZE, "handle=%d, connections=%d\n", 137 mActiveSensors.keyAt(i), 138 mActiveSensors.valueAt(i)->getNumConnections()); 139 result.append(buffer); 140 } 141 } 142 write(fd, result.string(), result.size()); 143 return NO_ERROR; 144} 145 146bool SensorService::threadLoop() 147{ 148 LOGD("nuSensorService thread starting..."); 149 150 sensors_event_t buffer[16]; 151 struct sensors_poll_device_t* device = mSensorDevice; 152 ssize_t count; 153 154 do { 155 count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer)); 156 if (count<0) { 157 LOGE("sensor poll failed (%s)", strerror(-count)); 158 break; 159 } 160 161 const SortedVector< wp<SensorEventConnection> > activeConnections( 162 getActiveConnections()); 163 164 size_t numConnections = activeConnections.size(); 165 if (numConnections) { 166 for (size_t i=0 ; i<numConnections ; i++) { 167 sp<SensorEventConnection> connection(activeConnections[i].promote()); 168 if (connection != 0) { 169 connection->sendEvents(buffer, count); 170 } 171 } 172 } 173 174 } while (count >= 0 || Thread::exitPending()); 175 176 LOGW("Exiting SensorService::threadLoop!"); 177 return false; 178} 179 180SortedVector< wp<SensorService::SensorEventConnection> > 181SensorService::getActiveConnections() const 182{ 183 Mutex::Autolock _l(mLock); 184 return mActiveConnections; 185} 186 187Vector<Sensor> SensorService::getSensorList() 188{ 189 return mSensorList; 190} 191 192sp<ISensorEventConnection> SensorService::createSensorEventConnection() 193{ 194 sp<SensorEventConnection> result(new SensorEventConnection(this)); 195 Mutex::Autolock _l(mLock); 196 mConnections.add(result); 197 return result; 198} 199 200void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection) 201{ 202 Mutex::Autolock _l(mLock); 203 ssize_t index = mConnections.indexOf(connection); 204 if (index >= 0) { 205 206 size_t size = mActiveSensors.size(); 207 for (size_t i=0 ; i<size ; ) { 208 SensorRecord* rec = mActiveSensors.valueAt(i); 209 if (rec && rec->removeConnection(connection)) { 210 mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0); 211 mActiveSensors.removeItemsAt(i, 1); 212 delete rec; 213 size--; 214 } else { 215 i++; 216 } 217 } 218 219 mActiveConnections.remove(connection); 220 mConnections.removeItemsAt(index, 1); 221 } 222} 223 224status_t SensorService::enable(const sp<SensorEventConnection>& connection, 225 int handle) 226{ 227 status_t err = NO_ERROR; 228 Mutex::Autolock _l(mLock); 229 SensorRecord* rec = mActiveSensors.valueFor(handle); 230 if (rec == 0) { 231 rec = new SensorRecord(connection); 232 mActiveSensors.add(handle, rec); 233 err = mSensorDevice->activate(mSensorDevice, handle, 1); 234 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err)); 235 if (err == 0) { 236 BatteryService::getInstance().enableSensor(handle); 237 } 238 } else { 239 err = rec->addConnection(connection); 240 } 241 if (err == NO_ERROR) { 242 // connection now active 243 connection->addSensor(handle); 244 if (mActiveConnections.indexOf(connection) < 0) { 245 mActiveConnections.add(connection); 246 } 247 } 248 return err; 249} 250 251status_t SensorService::disable(const sp<SensorEventConnection>& connection, 252 int handle) 253{ 254 status_t err = NO_ERROR; 255 Mutex::Autolock _l(mLock); 256 SensorRecord* rec = mActiveSensors.valueFor(handle); 257 LOGW("sensor (handle=%d) is not enabled", handle); 258 if (rec) { 259 // see if this connection becomes inactive 260 connection->removeSensor(handle); 261 if (connection->hasAnySensor() == false) { 262 mActiveConnections.remove(connection); 263 } 264 // see if this sensor becomes inactive 265 if (rec->removeConnection(connection)) { 266 mActiveSensors.removeItem(handle); 267 delete rec; 268 err = mSensorDevice->activate(mSensorDevice, handle, 0); 269 if (err == 0) { 270 BatteryService::getInstance().disableSensor(handle); 271 } 272 } 273 } 274 return err; 275} 276 277status_t SensorService::setRate(const sp<SensorEventConnection>& connection, 278 int handle, nsecs_t ns) 279{ 280 status_t err = NO_ERROR; 281 Mutex::Autolock _l(mLock); 282 283 err = mSensorDevice->setDelay(mSensorDevice, handle, ns); 284 285 // TODO: handle rate per connection 286 return err; 287} 288 289// --------------------------------------------------------------------------- 290 291SensorService::SensorRecord::SensorRecord( 292 const sp<SensorEventConnection>& connection) 293{ 294 mConnections.add(connection); 295} 296 297status_t SensorService::SensorRecord::addConnection( 298 const sp<SensorEventConnection>& connection) 299{ 300 if (mConnections.indexOf(connection) < 0) { 301 mConnections.add(connection); 302 } 303 return NO_ERROR; 304} 305 306bool SensorService::SensorRecord::removeConnection( 307 const wp<SensorEventConnection>& connection) 308{ 309 ssize_t index = mConnections.indexOf(connection); 310 if (index >= 0) { 311 mConnections.removeItemsAt(index, 1); 312 } 313 return mConnections.size() ? false : true; 314} 315 316// --------------------------------------------------------------------------- 317 318SensorService::SensorEventConnection::SensorEventConnection( 319 const sp<SensorService>& service) 320 : mService(service), mChannel(new SensorChannel()) 321{ 322} 323 324SensorService::SensorEventConnection::~SensorEventConnection() 325{ 326 mService->cleanupConnection(this); 327} 328 329void SensorService::SensorEventConnection::onFirstRef() 330{ 331} 332 333void SensorService::SensorEventConnection::addSensor(int32_t handle) { 334 if (mSensorList.indexOf(handle) <= 0) { 335 mSensorList.add(handle); 336 } 337} 338 339void SensorService::SensorEventConnection::removeSensor(int32_t handle) { 340 mSensorList.remove(handle); 341} 342 343bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const { 344 return mSensorList.indexOf(handle) >= 0; 345} 346 347bool SensorService::SensorEventConnection::hasAnySensor() const { 348 return mSensorList.size() ? true : false; 349} 350 351status_t SensorService::SensorEventConnection::sendEvents( 352 sensors_event_t const* buffer, size_t count) 353{ 354 // TODO: we should only send the events for the sensors this connection 355 // is registered for. 356 357 ssize_t size = mChannel->write(buffer, count*sizeof(sensors_event_t)); 358 if (size == -EAGAIN) { 359 // the destination doesn't accept events anymore, it's probably 360 // full. For now, we just drop the events on the floor. 361 LOGW("dropping %d events on the floor", count); 362 return size; 363 } 364 365 LOGE_IF(size<0, "dropping %d events on the floor (%s)", 366 count, strerror(-size)); 367 368 return size < 0 ? size : NO_ERROR; 369} 370 371sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const 372{ 373 return mChannel; 374} 375 376status_t SensorService::SensorEventConnection::enableDisable( 377 int handle, bool enabled) 378{ 379 status_t err; 380 if (enabled) { 381 err = mService->enable(this, handle); 382 } else { 383 err = mService->disable(this, handle); 384 } 385 return err; 386} 387 388status_t SensorService::SensorEventConnection::setEventRate( 389 int handle, nsecs_t ns) 390{ 391 return mService->setRate(this, handle, ns); 392} 393 394// --------------------------------------------------------------------------- 395}; // namespace android 396 397