SensorService.cpp revision fc32881fcc68640d008c7515cdd1bcd866f72cd5
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 27#include <binder/BinderService.h> 28 29#include <gui/ISensorServer.h> 30#include <gui/ISensorEventConnection.h> 31 32#include <hardware/sensors.h> 33 34#include "SensorService.h" 35 36namespace android { 37// --------------------------------------------------------------------------- 38 39/* 40 * TODO: 41 * - handle per-connection event rate 42 * - filter events per connection 43 * - make sure to keep the last value of each event type so we can quickly 44 * send something to application when they enable a sensor that is already 45 * active (the issue here is that it can take time before a value is 46 * produced by the h/w if the rate is low or if it's a one-shot sensor). 47 */ 48 49SensorService::SensorService() 50 : Thread(false), 51 mDump("android.permission.DUMP") 52{ 53} 54 55void SensorService::onFirstRef() 56{ 57 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, 58 (hw_module_t const**)&mSensorModule); 59 60 LOGE_IF(err, "couldn't load %s module (%s)", 61 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 62 63 err = sensors_open(&mSensorModule->common, &mSensorDevice); 64 65 LOGE_IF(err, "couldn't open device for module %s (%s)", 66 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 67 68 LOGD("nuSensorService starting..."); 69 70 struct sensor_t const* list; 71 int count = mSensorModule->get_sensors_list(mSensorModule, &list); 72 for (int i=0 ; i<count ; i++) { 73 Sensor sensor(list + i); 74 LOGI("%s", sensor.getName().string()); 75 mSensorList.add(sensor); 76 mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0); 77 } 78 79 run("SensorService", PRIORITY_URGENT_DISPLAY); 80} 81 82SensorService::~SensorService() 83{ 84} 85 86status_t SensorService::dump(int fd, const Vector<String16>& args) 87{ 88 const size_t SIZE = 1024; 89 char buffer[SIZE]; 90 String8 result; 91 if (!mDump.checkCalling()) { 92 snprintf(buffer, SIZE, "Permission Denial: " 93 "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 94 IPCThreadState::self()->getCallingPid(), 95 IPCThreadState::self()->getCallingUid()); 96 result.append(buffer); 97 } else { 98 Mutex::Autolock _l(mLock); 99 snprintf(buffer, SIZE, "%d connections / %d active\n", 100 mConnections.size(), mActiveConnections.size()); 101 result.append(buffer); 102 snprintf(buffer, SIZE, "Active sensors:\n"); 103 result.append(buffer); 104 for (size_t i=0 ; i<mActiveSensors.size() ; i++) { 105 snprintf(buffer, SIZE, "handle=%d, connections=%d\n", 106 mActiveSensors.keyAt(i), 107 mActiveSensors.valueAt(i)->getNumConnections()); 108 result.append(buffer); 109 } 110 } 111 write(fd, result.string(), result.size()); 112 return NO_ERROR; 113} 114 115bool SensorService::threadLoop() 116{ 117 LOGD("nuSensorService thread starting..."); 118 119 sensors_event_t buffer[16]; 120 struct sensors_poll_device_t* device = mSensorDevice; 121 ssize_t count; 122 123 do { 124 count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer)); 125 if (count<0) { 126 LOGE("sensor poll failed (%s)", strerror(-count)); 127 break; 128 } 129 130 const SortedVector< wp<SensorEventConnection> > activeConnections( 131 getActiveConnections()); 132 133 size_t numConnections = activeConnections.size(); 134 if (numConnections) { 135 for (size_t i=0 ; i<numConnections ; i++) { 136 sp<SensorEventConnection> connection(activeConnections[i].promote()); 137 if (connection != 0) { 138 connection->sendEvents(buffer, count); 139 } 140 } 141 } 142 143 } while (count >= 0 || Thread::exitPending()); 144 145 LOGW("Exiting SensorService::threadLoop!"); 146 return false; 147} 148 149SortedVector< wp<SensorService::SensorEventConnection> > 150SensorService::getActiveConnections() const 151{ 152 Mutex::Autolock _l(mLock); 153 return mActiveConnections; 154} 155 156Vector<Sensor> SensorService::getSensorList() 157{ 158 return mSensorList; 159} 160 161sp<ISensorEventConnection> SensorService::createSensorEventConnection() 162{ 163 sp<SensorEventConnection> result(new SensorEventConnection(this)); 164 Mutex::Autolock _l(mLock); 165 mConnections.add(result); 166 return result; 167} 168 169void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection) 170{ 171 Mutex::Autolock _l(mLock); 172 ssize_t index = mConnections.indexOf(connection); 173 if (index >= 0) { 174 175 size_t size = mActiveSensors.size(); 176 for (size_t i=0 ; i<size ; ) { 177 SensorRecord* rec = mActiveSensors.valueAt(i); 178 if (rec && rec->removeConnection(connection)) { 179 mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0); 180 mActiveSensors.removeItemsAt(i, 1); 181 delete rec; 182 size--; 183 } else { 184 i++; 185 } 186 } 187 188 mActiveConnections.remove(connection); 189 mConnections.removeItemsAt(index, 1); 190 } 191} 192 193status_t SensorService::enable(const sp<SensorEventConnection>& connection, 194 int handle) 195{ 196 status_t err = NO_ERROR; 197 Mutex::Autolock _l(mLock); 198 SensorRecord* rec = mActiveSensors.valueFor(handle); 199 if (rec == 0) { 200 rec = new SensorRecord(connection); 201 mActiveSensors.add(handle, rec); 202 err = mSensorDevice->activate(mSensorDevice, handle, 1); 203 LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err)); 204 } else { 205 err = rec->addConnection(connection); 206 } 207 if (err == NO_ERROR) { 208 // connection now active 209 connection->addSensor(handle); 210 if (mActiveConnections.indexOf(connection) < 0) { 211 mActiveConnections.add(connection); 212 } 213 } 214 return err; 215} 216 217status_t SensorService::disable(const sp<SensorEventConnection>& connection, 218 int handle) 219{ 220 status_t err = NO_ERROR; 221 Mutex::Autolock _l(mLock); 222 SensorRecord* rec = mActiveSensors.valueFor(handle); 223 LOGW("sensor (handle=%d) is not enabled", handle); 224 if (rec) { 225 // see if this connection becomes inactive 226 connection->removeSensor(handle); 227 if (connection->hasAnySensor() == false) { 228 mActiveConnections.remove(connection); 229 } 230 // see if this sensor becomes inactive 231 if (rec->removeConnection(connection)) { 232 mActiveSensors.removeItem(handle); 233 delete rec; 234 err = mSensorDevice->activate(mSensorDevice, handle, 0); 235 } 236 } 237 return err; 238} 239 240status_t SensorService::setRate(const sp<SensorEventConnection>& connection, 241 int handle, nsecs_t ns) 242{ 243 status_t err = NO_ERROR; 244 Mutex::Autolock _l(mLock); 245 246 err = mSensorDevice->setDelay(mSensorDevice, handle, ns); 247 248 // TODO: handle rate per connection 249 return err; 250} 251 252// --------------------------------------------------------------------------- 253 254SensorService::SensorRecord::SensorRecord( 255 const sp<SensorEventConnection>& connection) 256{ 257 mConnections.add(connection); 258} 259 260status_t SensorService::SensorRecord::addConnection( 261 const sp<SensorEventConnection>& connection) 262{ 263 if (mConnections.indexOf(connection) < 0) { 264 mConnections.add(connection); 265 } 266 return NO_ERROR; 267} 268 269bool SensorService::SensorRecord::removeConnection( 270 const wp<SensorEventConnection>& connection) 271{ 272 ssize_t index = mConnections.indexOf(connection); 273 if (index >= 0) { 274 mConnections.removeItemsAt(index, 1); 275 } 276 return mConnections.size() ? false : true; 277} 278 279// --------------------------------------------------------------------------- 280 281SensorService::SensorEventConnection::SensorEventConnection( 282 const sp<SensorService>& service) 283 : mService(service), mChannel(new SensorChannel()) 284{ 285} 286 287SensorService::SensorEventConnection::~SensorEventConnection() 288{ 289 mService->cleanupConnection(this); 290} 291 292void SensorService::SensorEventConnection::onFirstRef() 293{ 294} 295 296void SensorService::SensorEventConnection::addSensor(int32_t handle) { 297 if (mSensorList.indexOf(handle) <= 0) { 298 mSensorList.add(handle); 299 } 300} 301 302void SensorService::SensorEventConnection::removeSensor(int32_t handle) { 303 mSensorList.remove(handle); 304} 305 306bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const { 307 return mSensorList.indexOf(handle) >= 0; 308} 309 310bool SensorService::SensorEventConnection::hasAnySensor() const { 311 return mSensorList.size() ? true : false; 312} 313 314status_t SensorService::SensorEventConnection::sendEvents( 315 sensors_event_t const* buffer, size_t count) 316{ 317 // TODO: we should only send the events for the sensors this connection 318 // is registered for. 319 320 ssize_t size = mChannel->write(buffer, count*sizeof(sensors_event_t)); 321 if (size == -EAGAIN) { 322 // the destination doesn't accept events anymore, it's probably 323 // full. For now, we just drop the events on the floor. 324 LOGW("dropping %d events on the floor", count); 325 return size; 326 } 327 328 LOGE_IF(size<0, "dropping %d events on the floor (%s)", 329 count, strerror(-size)); 330 331 return size < 0 ? size : NO_ERROR; 332} 333 334sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const 335{ 336 return mChannel; 337} 338 339status_t SensorService::SensorEventConnection::enableDisable( 340 int handle, bool enabled) 341{ 342 status_t err; 343 if (enabled) { 344 err = mService->enable(this, handle); 345 } else { 346 err = mService->disable(this, handle); 347 } 348 return err; 349} 350 351status_t SensorService::SensorEventConnection::setEventRate( 352 int handle, nsecs_t ns) 353{ 354 return mService->setRate(this, handle, ns); 355} 356 357// --------------------------------------------------------------------------- 358}; // namespace android 359 360