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