| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 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> | 
| Mathias Agopian | 451beee | 2010-07-19 15:03:55 -0700 | [diff] [blame] | 26 | #include <utils/Singleton.h> | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 27 |  | 
|  | 28 | #include <binder/BinderService.h> | 
| Mathias Agopian | 451beee | 2010-07-19 15:03:55 -0700 | [diff] [blame] | 29 | #include <binder/IServiceManager.h> | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 30 |  | 
|  | 31 | #include <gui/ISensorServer.h> | 
|  | 32 | #include <gui/ISensorEventConnection.h> | 
|  | 33 |  | 
|  | 34 | #include <hardware/sensors.h> | 
|  | 35 |  | 
|  | 36 | #include "SensorService.h" | 
|  | 37 |  | 
|  | 38 | namespace android { | 
|  | 39 | // --------------------------------------------------------------------------- | 
|  | 40 |  | 
|  | 41 | /* | 
|  | 42 | * TODO: | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 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). | 
| Mathias Agopian | 451beee | 2010-07-19 15:03:55 -0700 | [diff] [blame] | 47 | * - send sensor info to battery service | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 48 | */ | 
|  | 49 |  | 
| Mathias Agopian | 451beee | 2010-07-19 15:03:55 -0700 | [diff] [blame] | 50 | // --------------------------------------------------------------------------- | 
|  | 51 |  | 
|  | 52 | class BatteryService : public Singleton<BatteryService> { | 
|  | 53 | friend class Singleton<BatteryService>; | 
|  | 54 | sp<IBinder> mBatteryStatService; | 
|  | 55 | BatteryService() { | 
|  | 56 | const String16 name("batteryinfo"); | 
|  | 57 | //getService(name, &mBatteryStatService); | 
|  | 58 | } | 
|  | 59 | public: | 
|  | 60 | void enableSensor(int handle) { | 
|  | 61 | if (mBatteryStatService != 0) { | 
|  | 62 | int uid = IPCThreadState::self()->getCallingUid(); | 
|  | 63 | //mBatteryStatService->noteStartSensor(uid, handle); | 
|  | 64 | } | 
|  | 65 | } | 
|  | 66 | void disableSensor(int handle) { | 
|  | 67 | if (mBatteryStatService != 0) { | 
|  | 68 | int uid = IPCThreadState::self()->getCallingUid(); | 
|  | 69 | //mBatteryStatService->noteStopSensor(uid, handle); | 
|  | 70 | } | 
|  | 71 | } | 
|  | 72 | }; | 
|  | 73 |  | 
|  | 74 | ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService) | 
|  | 75 |  | 
|  | 76 | // --------------------------------------------------------------------------- | 
|  | 77 |  | 
| Mathias Agopian | 1cd7000 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 78 | // 100 events/s max | 
|  | 79 | static const nsecs_t MINIMUM_EVENT_PERIOD = ms2ns(10); | 
|  | 80 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 81 | SensorService::SensorService() | 
|  | 82 | : Thread(false), | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 83 | mSensorDevice(0), | 
|  | 84 | mSensorModule(0), | 
|  | 85 | mDump("android.permission.DUMP"), | 
|  | 86 | mInitCheck(NO_INIT) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 87 | { | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | void SensorService::onFirstRef() | 
|  | 91 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 92 | LOGD("nuSensorService starting..."); | 
|  | 93 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 94 | status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, | 
|  | 95 | (hw_module_t const**)&mSensorModule); | 
|  | 96 |  | 
|  | 97 | LOGE_IF(err, "couldn't load %s module (%s)", | 
|  | 98 | SENSORS_HARDWARE_MODULE_ID, strerror(-err)); | 
|  | 99 |  | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 100 | if (mSensorModule) { | 
|  | 101 | err = sensors_open(&mSensorModule->common, &mSensorDevice); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 102 |  | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 103 | LOGE_IF(err, "couldn't open device for module %s (%s)", | 
|  | 104 | SENSORS_HARDWARE_MODULE_ID, strerror(-err)); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 105 |  | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 106 | struct sensor_t const* list; | 
|  | 107 | int count = mSensorModule->get_sensors_list(mSensorModule, &list); | 
|  | 108 | for (int i=0 ; i<count ; i++) { | 
|  | 109 | Sensor sensor(list + i); | 
|  | 110 | LOGI("%s", sensor.getName().string()); | 
|  | 111 | mSensorList.add(sensor); | 
|  | 112 | if (mSensorDevice) { | 
|  | 113 | mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0); | 
|  | 114 | } | 
|  | 115 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 116 |  | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 117 | if (mSensorDevice) { | 
|  | 118 | run("SensorService", PRIORITY_URGENT_DISPLAY); | 
|  | 119 | mInitCheck = NO_ERROR; | 
|  | 120 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 121 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 122 | } | 
|  | 123 |  | 
|  | 124 | SensorService::~SensorService() | 
|  | 125 | { | 
|  | 126 | } | 
|  | 127 |  | 
|  | 128 | status_t SensorService::dump(int fd, const Vector<String16>& args) | 
|  | 129 | { | 
|  | 130 | const size_t SIZE = 1024; | 
|  | 131 | char buffer[SIZE]; | 
|  | 132 | String8 result; | 
|  | 133 | if (!mDump.checkCalling()) { | 
|  | 134 | snprintf(buffer, SIZE, "Permission Denial: " | 
|  | 135 | "can't dump SurfaceFlinger from pid=%d, uid=%d\n", | 
|  | 136 | IPCThreadState::self()->getCallingPid(), | 
|  | 137 | IPCThreadState::self()->getCallingUid()); | 
|  | 138 | result.append(buffer); | 
|  | 139 | } else { | 
|  | 140 | Mutex::Autolock _l(mLock); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 141 | snprintf(buffer, SIZE, "%d active connections\n", | 
|  | 142 | mActiveConnections.size()); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 143 | result.append(buffer); | 
|  | 144 | snprintf(buffer, SIZE, "Active sensors:\n"); | 
|  | 145 | result.append(buffer); | 
|  | 146 | for (size_t i=0 ; i<mActiveSensors.size() ; i++) { | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 147 | int handle = mActiveSensors.keyAt(i); | 
|  | 148 | snprintf(buffer, SIZE, "%s (handle=%d, connections=%d)\n", | 
|  | 149 | getSensorName(handle).string(), | 
|  | 150 | handle, | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 151 | mActiveSensors.valueAt(i)->getNumConnections()); | 
|  | 152 | result.append(buffer); | 
|  | 153 | } | 
|  | 154 | } | 
|  | 155 | write(fd, result.string(), result.size()); | 
|  | 156 | return NO_ERROR; | 
|  | 157 | } | 
|  | 158 |  | 
|  | 159 | bool SensorService::threadLoop() | 
|  | 160 | { | 
|  | 161 | LOGD("nuSensorService thread starting..."); | 
|  | 162 |  | 
|  | 163 | sensors_event_t buffer[16]; | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame^] | 164 | sensors_event_t scratch[16]; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 165 | struct sensors_poll_device_t* device = mSensorDevice; | 
|  | 166 | ssize_t count; | 
|  | 167 |  | 
|  | 168 | do { | 
|  | 169 | count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer)); | 
|  | 170 | if (count<0) { | 
|  | 171 | LOGE("sensor poll failed (%s)", strerror(-count)); | 
|  | 172 | break; | 
|  | 173 | } | 
|  | 174 |  | 
|  | 175 | const SortedVector< wp<SensorEventConnection> > activeConnections( | 
|  | 176 | getActiveConnections()); | 
|  | 177 |  | 
|  | 178 | size_t numConnections = activeConnections.size(); | 
|  | 179 | if (numConnections) { | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame^] | 180 | Mutex::Autolock _l(mLock); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 181 | for (size_t i=0 ; i<numConnections ; i++) { | 
|  | 182 | sp<SensorEventConnection> connection(activeConnections[i].promote()); | 
|  | 183 | if (connection != 0) { | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame^] | 184 | connection->sendEvents(buffer, count, scratch); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 185 | } | 
|  | 186 | } | 
|  | 187 | } | 
|  | 188 |  | 
|  | 189 | } while (count >= 0 || Thread::exitPending()); | 
|  | 190 |  | 
|  | 191 | LOGW("Exiting SensorService::threadLoop!"); | 
|  | 192 | return false; | 
|  | 193 | } | 
|  | 194 |  | 
|  | 195 | SortedVector< wp<SensorService::SensorEventConnection> > | 
|  | 196 | SensorService::getActiveConnections() const | 
|  | 197 | { | 
|  | 198 | Mutex::Autolock _l(mLock); | 
|  | 199 | return mActiveConnections; | 
|  | 200 | } | 
|  | 201 |  | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 202 | String8 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 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 214 | Vector<Sensor> SensorService::getSensorList() | 
|  | 215 | { | 
|  | 216 | return mSensorList; | 
|  | 217 | } | 
|  | 218 |  | 
|  | 219 | sp<ISensorEventConnection> SensorService::createSensorEventConnection() | 
|  | 220 | { | 
|  | 221 | sp<SensorEventConnection> result(new SensorEventConnection(this)); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 222 | return result; | 
|  | 223 | } | 
|  | 224 |  | 
|  | 225 | void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection) | 
|  | 226 | { | 
|  | 227 | Mutex::Autolock _l(mLock); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 228 | size_t size = mActiveSensors.size(); | 
|  | 229 | for (size_t i=0 ; i<size ; ) { | 
|  | 230 | SensorRecord* rec = mActiveSensors.valueAt(i); | 
|  | 231 | if (rec && rec->removeConnection(connection)) { | 
|  | 232 | mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0); | 
|  | 233 | mActiveSensors.removeItemsAt(i, 1); | 
|  | 234 | delete rec; | 
|  | 235 | size--; | 
|  | 236 | } else { | 
|  | 237 | i++; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 238 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 239 | } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 240 | mActiveConnections.remove(connection); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 241 | } | 
|  | 242 |  | 
|  | 243 | status_t SensorService::enable(const sp<SensorEventConnection>& connection, | 
|  | 244 | int handle) | 
|  | 245 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 246 | if (mInitCheck != NO_ERROR) | 
|  | 247 | return mInitCheck; | 
|  | 248 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 249 | status_t err = NO_ERROR; | 
|  | 250 | Mutex::Autolock _l(mLock); | 
|  | 251 | SensorRecord* rec = mActiveSensors.valueFor(handle); | 
|  | 252 | if (rec == 0) { | 
|  | 253 | rec = new SensorRecord(connection); | 
|  | 254 | mActiveSensors.add(handle, rec); | 
|  | 255 | err = mSensorDevice->activate(mSensorDevice, handle, 1); | 
|  | 256 | LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err)); | 
| Mathias Agopian | 451beee | 2010-07-19 15:03:55 -0700 | [diff] [blame] | 257 | if (err == 0) { | 
|  | 258 | BatteryService::getInstance().enableSensor(handle); | 
|  | 259 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 260 | } else { | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 261 | rec->addConnection(connection); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 262 | } | 
|  | 263 | if (err == NO_ERROR) { | 
|  | 264 | // connection now active | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 265 | if (connection->addSensor(handle)) { | 
|  | 266 | // the sensor was added (which means it wasn't already there) | 
|  | 267 | // so, see if this connection becomes active | 
|  | 268 | if (mActiveConnections.indexOf(connection) < 0) { | 
|  | 269 | mActiveConnections.add(connection); | 
|  | 270 | } | 
|  | 271 | // this could change the sensor event delivery speed | 
|  | 272 | recomputeEventsPeriodLocked(handle); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 273 | } | 
|  | 274 | } | 
|  | 275 | return err; | 
|  | 276 | } | 
|  | 277 |  | 
|  | 278 | status_t SensorService::disable(const sp<SensorEventConnection>& connection, | 
|  | 279 | int handle) | 
|  | 280 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 281 | if (mInitCheck != NO_ERROR) | 
|  | 282 | return mInitCheck; | 
|  | 283 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 284 | status_t err = NO_ERROR; | 
|  | 285 | Mutex::Autolock _l(mLock); | 
|  | 286 | SensorRecord* rec = mActiveSensors.valueFor(handle); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 287 | if (rec) { | 
|  | 288 | // see if this connection becomes inactive | 
|  | 289 | connection->removeSensor(handle); | 
|  | 290 | if (connection->hasAnySensor() == false) { | 
|  | 291 | mActiveConnections.remove(connection); | 
|  | 292 | } | 
|  | 293 | // see if this sensor becomes inactive | 
|  | 294 | if (rec->removeConnection(connection)) { | 
|  | 295 | mActiveSensors.removeItem(handle); | 
|  | 296 | delete rec; | 
|  | 297 | err = mSensorDevice->activate(mSensorDevice, handle, 0); | 
| Mathias Agopian | 451beee | 2010-07-19 15:03:55 -0700 | [diff] [blame] | 298 | if (err == 0) { | 
|  | 299 | BatteryService::getInstance().disableSensor(handle); | 
|  | 300 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 301 | } | 
|  | 302 | } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 303 | if (err == NO_ERROR) { | 
|  | 304 | recomputeEventsPeriodLocked(handle); | 
|  | 305 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 306 | return err; | 
|  | 307 | } | 
|  | 308 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 309 | status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 310 | int handle, nsecs_t ns) | 
|  | 311 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 312 | if (mInitCheck != NO_ERROR) | 
|  | 313 | return mInitCheck; | 
|  | 314 |  | 
| Mathias Agopian | 1cd7000 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 315 | if (ns < 0) | 
|  | 316 | return BAD_VALUE; | 
|  | 317 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 318 | if (ns < MINIMUM_EVENTS_PERIOD) | 
|  | 319 | ns = MINIMUM_EVENTS_PERIOD; | 
| Mathias Agopian | 1cd7000 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 320 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 321 | Mutex::Autolock _l(mLock); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 322 | status_t err = connection->setEventRateLocked(handle, ns); | 
|  | 323 | if (err == NO_ERROR) { | 
|  | 324 | recomputeEventsPeriodLocked(handle); | 
|  | 325 | } | 
|  | 326 | return err; | 
|  | 327 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 328 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 329 | status_t SensorService::recomputeEventsPeriodLocked(int32_t handle) | 
|  | 330 | { | 
|  | 331 | status_t err = NO_ERROR; | 
|  | 332 | nsecs_t wanted = ms2ns(1000); | 
|  | 333 | size_t count = mActiveConnections.size(); | 
|  | 334 | for (size_t i=0 ; i<count ; i++) { | 
|  | 335 | sp<SensorEventConnection> connection(mActiveConnections[i].promote()); | 
|  | 336 | if (connection != NULL) { | 
|  | 337 | nsecs_t ns = connection->getEventRateForSensor(handle); | 
|  | 338 | if (ns) { | 
|  | 339 | wanted = wanted < ns ? wanted : ns; | 
|  | 340 | } | 
|  | 341 | } | 
|  | 342 | } | 
|  | 343 | err = mSensorDevice->setDelay(mSensorDevice, handle, wanted); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 344 | return err; | 
|  | 345 | } | 
|  | 346 |  | 
|  | 347 | // --------------------------------------------------------------------------- | 
|  | 348 |  | 
|  | 349 | SensorService::SensorRecord::SensorRecord( | 
|  | 350 | const sp<SensorEventConnection>& connection) | 
|  | 351 | { | 
|  | 352 | mConnections.add(connection); | 
|  | 353 | } | 
|  | 354 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 355 | bool SensorService::SensorRecord::addConnection( | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 356 | const sp<SensorEventConnection>& connection) | 
|  | 357 | { | 
|  | 358 | if (mConnections.indexOf(connection) < 0) { | 
|  | 359 | mConnections.add(connection); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 360 | return true; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 361 | } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 362 | return false; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 363 | } | 
|  | 364 |  | 
|  | 365 | bool SensorService::SensorRecord::removeConnection( | 
|  | 366 | const wp<SensorEventConnection>& connection) | 
|  | 367 | { | 
|  | 368 | ssize_t index = mConnections.indexOf(connection); | 
|  | 369 | if (index >= 0) { | 
|  | 370 | mConnections.removeItemsAt(index, 1); | 
|  | 371 | } | 
|  | 372 | return mConnections.size() ? false : true; | 
|  | 373 | } | 
|  | 374 |  | 
|  | 375 | // --------------------------------------------------------------------------- | 
|  | 376 |  | 
|  | 377 | SensorService::SensorEventConnection::SensorEventConnection( | 
|  | 378 | const sp<SensorService>& service) | 
|  | 379 | : mService(service), mChannel(new SensorChannel()) | 
|  | 380 | { | 
|  | 381 | } | 
|  | 382 |  | 
|  | 383 | SensorService::SensorEventConnection::~SensorEventConnection() | 
|  | 384 | { | 
|  | 385 | mService->cleanupConnection(this); | 
|  | 386 | } | 
|  | 387 |  | 
|  | 388 | void SensorService::SensorEventConnection::onFirstRef() | 
|  | 389 | { | 
|  | 390 | } | 
|  | 391 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 392 | bool SensorService::SensorEventConnection::addSensor(int32_t handle) { | 
|  | 393 | if (mSensorInfo.indexOfKey(handle) <= 0) { | 
|  | 394 | SensorInfo info; | 
|  | 395 | mSensorInfo.add(handle, info); | 
|  | 396 | return true; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 397 | } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 398 | return false; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 399 | } | 
|  | 400 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 401 | bool SensorService::SensorEventConnection::removeSensor(int32_t handle) { | 
|  | 402 | if (mSensorInfo.removeItem(handle) >= 0) { | 
|  | 403 | return true; | 
|  | 404 | } | 
|  | 405 | return false; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 406 | } | 
|  | 407 |  | 
|  | 408 | bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const { | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 409 | return mSensorInfo.indexOfKey(handle) >= 0; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 410 | } | 
|  | 411 |  | 
|  | 412 | bool SensorService::SensorEventConnection::hasAnySensor() const { | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 413 | return mSensorInfo.size() ? true : false; | 
|  | 414 | } | 
|  | 415 |  | 
|  | 416 | status_t SensorService::SensorEventConnection::setEventRateLocked( | 
|  | 417 | int handle, nsecs_t ns) | 
|  | 418 | { | 
|  | 419 | ssize_t index = mSensorInfo.indexOfKey(handle); | 
|  | 420 | if (index >= 0) { | 
|  | 421 | SensorInfo& info = mSensorInfo.editValueFor(handle); | 
|  | 422 | info.ns = ns; | 
|  | 423 | return NO_ERROR; | 
|  | 424 | } | 
|  | 425 | return status_t(index); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 426 | } | 
|  | 427 |  | 
|  | 428 | status_t SensorService::SensorEventConnection::sendEvents( | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame^] | 429 | sensors_event_t const* buffer, size_t numEvents, | 
|  | 430 | sensors_event_t* scratch) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 431 | { | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame^] | 432 | // filter out events not for this connection | 
|  | 433 | size_t count=0, i=0; | 
|  | 434 | while (i<numEvents) { | 
|  | 435 | const int32_t curr = buffer[i].sensor; | 
|  | 436 | if (mSensorInfo.indexOfKey(curr) >= 0) { | 
|  | 437 | do { | 
|  | 438 | scratch[count++] = buffer[i++]; | 
|  | 439 | } while ((i<numEvents) && (buffer[i].sensor == curr)); | 
|  | 440 | } else { | 
|  | 441 | i++; | 
|  | 442 | } | 
|  | 443 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 444 |  | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame^] | 445 | ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t)); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 446 | if (size == -EAGAIN) { | 
|  | 447 | // the destination doesn't accept events anymore, it's probably | 
|  | 448 | // full. For now, we just drop the events on the floor. | 
|  | 449 | LOGW("dropping %d events on the floor", count); | 
|  | 450 | return size; | 
|  | 451 | } | 
|  | 452 |  | 
|  | 453 | LOGE_IF(size<0, "dropping %d events on the floor (%s)", | 
|  | 454 | count, strerror(-size)); | 
|  | 455 |  | 
|  | 456 | return size < 0 ? size : NO_ERROR; | 
|  | 457 | } | 
|  | 458 |  | 
|  | 459 | sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const | 
|  | 460 | { | 
|  | 461 | return mChannel; | 
|  | 462 | } | 
|  | 463 |  | 
|  | 464 | status_t SensorService::SensorEventConnection::enableDisable( | 
|  | 465 | int handle, bool enabled) | 
|  | 466 | { | 
|  | 467 | status_t err; | 
|  | 468 | if (enabled) { | 
|  | 469 | err = mService->enable(this, handle); | 
|  | 470 | } else { | 
|  | 471 | err = mService->disable(this, handle); | 
|  | 472 | } | 
|  | 473 | return err; | 
|  | 474 | } | 
|  | 475 |  | 
|  | 476 | status_t SensorService::SensorEventConnection::setEventRate( | 
|  | 477 | int handle, nsecs_t ns) | 
|  | 478 | { | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 479 | return mService->setEventRate(this, handle, ns); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 480 | } | 
|  | 481 |  | 
|  | 482 | // --------------------------------------------------------------------------- | 
|  | 483 | }; // namespace android | 
|  | 484 |  |