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