| 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> | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 18 | #include <math.h> | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 19 | #include <sys/types.h> | 
 | 20 |  | 
| Mathias Agopian | 3301542 | 2011-05-27 18:18:13 -0700 | [diff] [blame] | 21 | #include <cutils/properties.h> | 
 | 22 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 23 | #include <utils/SortedVector.h> | 
 | 24 | #include <utils/KeyedVector.h> | 
 | 25 | #include <utils/threads.h> | 
 | 26 | #include <utils/Atomic.h> | 
 | 27 | #include <utils/Errors.h> | 
 | 28 | #include <utils/RefBase.h> | 
| Mathias Agopian | 451beee | 2010-07-19 15:03:55 -0700 | [diff] [blame] | 29 | #include <utils/Singleton.h> | 
| Mathias Agopian | c4a930d | 2010-07-22 22:19:43 -0700 | [diff] [blame] | 30 | #include <utils/String16.h> | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 31 |  | 
 | 32 | #include <binder/BinderService.h> | 
| Mathias Agopian | 451beee | 2010-07-19 15:03:55 -0700 | [diff] [blame] | 33 | #include <binder/IServiceManager.h> | 
| Mathias Agopian | 1cb1346 | 2011-06-27 16:05:52 -0700 | [diff] [blame] | 34 | #include <binder/PermissionCache.h> | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 35 |  | 
 | 36 | #include <gui/ISensorServer.h> | 
 | 37 | #include <gui/ISensorEventConnection.h> | 
| Mathias Agopian | 907103b | 2012-04-02 18:38:02 -0700 | [diff] [blame] | 38 | #include <gui/SensorEventQueue.h> | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 39 |  | 
 | 40 | #include <hardware/sensors.h> | 
 | 41 |  | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 42 | #include "CorrectedGyroSensor.h" | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 43 | #include "GravitySensor.h" | 
 | 44 | #include "LinearAccelerationSensor.h" | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 45 | #include "OrientationSensor.h" | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 46 | #include "RotationVectorSensor.h" | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 47 | #include "SensorFusion.h" | 
 | 48 | #include "SensorService.h" | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 49 |  | 
 | 50 | namespace android { | 
 | 51 | // --------------------------------------------------------------------------- | 
 | 52 |  | 
| Mathias Agopian | 3301542 | 2011-05-27 18:18:13 -0700 | [diff] [blame] | 53 | /* | 
 | 54 |  * Notes: | 
 | 55 |  * | 
 | 56 |  * - what about a gyro-corrected magnetic-field sensor? | 
| Mathias Agopian | 3301542 | 2011-05-27 18:18:13 -0700 | [diff] [blame] | 57 |  * - run mag sensor from time to time to force calibration | 
 | 58 |  * - gravity sensor length is wrong (=> drift in linear-acc sensor) | 
 | 59 |  * | 
 | 60 |  */ | 
 | 61 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 62 | SensorService::SensorService() | 
| Mathias Agopian | 1cb1346 | 2011-06-27 16:05:52 -0700 | [diff] [blame] | 63 |     : mInitCheck(NO_INIT) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 64 | { | 
 | 65 | } | 
 | 66 |  | 
 | 67 | void SensorService::onFirstRef() | 
 | 68 | { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 69 |     ALOGD("nuSensorService starting..."); | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 70 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 71 |     SensorDevice& dev(SensorDevice::getInstance()); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 72 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 73 |     if (dev.initCheck() == NO_ERROR) { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 74 |         sensor_t const* list; | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 75 |         ssize_t count = dev.getSensorList(&list); | 
 | 76 |         if (count > 0) { | 
 | 77 |             ssize_t orientationIndex = -1; | 
 | 78 |             bool hasGyro = false; | 
 | 79 |             uint32_t virtualSensorsNeeds = | 
 | 80 |                     (1<<SENSOR_TYPE_GRAVITY) | | 
 | 81 |                     (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | | 
 | 82 |                     (1<<SENSOR_TYPE_ROTATION_VECTOR); | 
 | 83 |  | 
 | 84 |             mLastEventSeen.setCapacity(count); | 
 | 85 |             for (ssize_t i=0 ; i<count ; i++) { | 
 | 86 |                 registerSensor( new HardwareSensor(list[i]) ); | 
 | 87 |                 switch (list[i].type) { | 
 | 88 |                     case SENSOR_TYPE_ORIENTATION: | 
 | 89 |                         orientationIndex = i; | 
 | 90 |                         break; | 
 | 91 |                     case SENSOR_TYPE_GYROSCOPE: | 
 | 92 |                         hasGyro = true; | 
 | 93 |                         break; | 
 | 94 |                     case SENSOR_TYPE_GRAVITY: | 
 | 95 |                     case SENSOR_TYPE_LINEAR_ACCELERATION: | 
 | 96 |                     case SENSOR_TYPE_ROTATION_VECTOR: | 
 | 97 |                         virtualSensorsNeeds &= ~(1<<list[i].type); | 
 | 98 |                         break; | 
 | 99 |                 } | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 100 |             } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 101 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 102 |             // it's safe to instantiate the SensorFusion object here | 
 | 103 |             // (it wants to be instantiated after h/w sensors have been | 
 | 104 |             // registered) | 
 | 105 |             const SensorFusion& fusion(SensorFusion::getInstance()); | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 106 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 107 |             if (hasGyro) { | 
 | 108 |                 // Always instantiate Android's virtual sensors. Since they are | 
 | 109 |                 // instantiated behind sensors from the HAL, they won't | 
 | 110 |                 // interfere with applications, unless they looks specifically | 
 | 111 |                 // for them (by name). | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 112 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 113 |                 registerVirtualSensor( new RotationVectorSensor() ); | 
 | 114 |                 registerVirtualSensor( new GravitySensor(list, count) ); | 
 | 115 |                 registerVirtualSensor( new LinearAccelerationSensor(list, count) ); | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 116 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 117 |                 // these are optional | 
 | 118 |                 registerVirtualSensor( new OrientationSensor() ); | 
 | 119 |                 registerVirtualSensor( new CorrectedGyroSensor(list, count) ); | 
| Mathias Agopian | 3301542 | 2011-05-27 18:18:13 -0700 | [diff] [blame] | 120 |             } | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 121 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 122 |             // build the sensor list returned to users | 
 | 123 |             mUserSensorList = mSensorList; | 
| Mathias Agopian | 3326486 | 2012-06-28 19:46:54 -0700 | [diff] [blame] | 124 |  | 
 | 125 |             if (hasGyro) { | 
 | 126 |                 // virtual debugging sensors are not added to mUserSensorList | 
 | 127 |                 registerVirtualSensor( new GyroDriftSensor() ); | 
 | 128 |             } | 
 | 129 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 130 |             if (hasGyro && | 
 | 131 |                     (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) { | 
 | 132 |                 // if we have the fancy sensor fusion, and it's not provided by the | 
 | 133 |                 // HAL, use our own (fused) orientation sensor by removing the | 
 | 134 |                 // HAL supplied one form the user list. | 
 | 135 |                 if (orientationIndex >= 0) { | 
 | 136 |                     mUserSensorList.removeItemsAt(orientationIndex); | 
 | 137 |                 } | 
| Mathias Agopian | 010e422 | 2011-06-08 20:06:50 -0700 | [diff] [blame] | 138 |             } | 
| Mathias Agopian | 010e422 | 2011-06-08 20:06:50 -0700 | [diff] [blame] | 139 |  | 
| Mathias Agopian | 3326486 | 2012-06-28 19:46:54 -0700 | [diff] [blame] | 140 |             // debugging sensor list | 
 | 141 |             for (size_t i=0 ; i<mSensorList.size() ; i++) { | 
 | 142 |                 switch (mSensorList[i].getType()) { | 
 | 143 |                     case SENSOR_TYPE_GRAVITY: | 
 | 144 |                     case SENSOR_TYPE_LINEAR_ACCELERATION: | 
 | 145 |                     case SENSOR_TYPE_ROTATION_VECTOR: | 
 | 146 |                         if (strstr(mSensorList[i].getVendor().string(), "Google")) { | 
 | 147 |                             mUserSensorListDebug.add(mSensorList[i]); | 
 | 148 |                         } | 
 | 149 |                         break; | 
 | 150 |                     default: | 
 | 151 |                         mUserSensorListDebug.add(mSensorList[i]); | 
 | 152 |                         break; | 
 | 153 |                 } | 
 | 154 |             } | 
 | 155 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 156 |             run("SensorService", PRIORITY_URGENT_DISPLAY); | 
 | 157 |             mInitCheck = NO_ERROR; | 
 | 158 |         } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 159 |     } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 160 | } | 
 | 161 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 162 | void SensorService::registerSensor(SensorInterface* s) | 
 | 163 | { | 
 | 164 |     sensors_event_t event; | 
 | 165 |     memset(&event, 0, sizeof(event)); | 
 | 166 |  | 
 | 167 |     const Sensor sensor(s->getSensor()); | 
 | 168 |     // add to the sensor list (returned to clients) | 
 | 169 |     mSensorList.add(sensor); | 
 | 170 |     // add to our handle->SensorInterface mapping | 
 | 171 |     mSensorMap.add(sensor.getHandle(), s); | 
 | 172 |     // create an entry in the mLastEventSeen array | 
 | 173 |     mLastEventSeen.add(sensor.getHandle(), event); | 
 | 174 | } | 
 | 175 |  | 
 | 176 | void SensorService::registerVirtualSensor(SensorInterface* s) | 
 | 177 | { | 
 | 178 |     registerSensor(s); | 
 | 179 |     mVirtualSensorList.add( s ); | 
 | 180 | } | 
 | 181 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 182 | SensorService::~SensorService() | 
 | 183 | { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 184 |     for (size_t i=0 ; i<mSensorMap.size() ; i++) | 
 | 185 |         delete mSensorMap.valueAt(i); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 186 | } | 
 | 187 |  | 
| Mathias Agopian | 1cb1346 | 2011-06-27 16:05:52 -0700 | [diff] [blame] | 188 | static const String16 sDump("android.permission.DUMP"); | 
 | 189 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 190 | status_t SensorService::dump(int fd, const Vector<String16>& args) | 
 | 191 | { | 
 | 192 |     const size_t SIZE = 1024; | 
 | 193 |     char buffer[SIZE]; | 
 | 194 |     String8 result; | 
| Mathias Agopian | 1cb1346 | 2011-06-27 16:05:52 -0700 | [diff] [blame] | 195 |     if (!PermissionCache::checkCallingPermission(sDump)) { | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 196 |         snprintf(buffer, SIZE, "Permission Denial: " | 
 | 197 |                 "can't dump SurfaceFlinger from pid=%d, uid=%d\n", | 
 | 198 |                 IPCThreadState::self()->getCallingPid(), | 
 | 199 |                 IPCThreadState::self()->getCallingUid()); | 
 | 200 |         result.append(buffer); | 
 | 201 |     } else { | 
 | 202 |         Mutex::Autolock _l(mLock); | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 203 |         snprintf(buffer, SIZE, "Sensor List:\n"); | 
 | 204 |         result.append(buffer); | 
 | 205 |         for (size_t i=0 ; i<mSensorList.size() ; i++) { | 
 | 206 |             const Sensor& s(mSensorList[i]); | 
 | 207 |             const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle())); | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 208 |             snprintf(buffer, SIZE, | 
 | 209 |                     "%-48s| %-32s | 0x%08x | maxRate=%7.2fHz | " | 
 | 210 |                     "last=<%5.1f,%5.1f,%5.1f>\n", | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 211 |                     s.getName().string(), | 
 | 212 |                     s.getVendor().string(), | 
 | 213 |                     s.getHandle(), | 
| Mathias Agopian | 24d7235 | 2010-11-05 19:12:58 -0700 | [diff] [blame] | 214 |                     s.getMinDelay() ? (1000000.0f / s.getMinDelay()) : 0.0f, | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 215 |                     e.data[0], e.data[1], e.data[2]); | 
 | 216 |             result.append(buffer); | 
 | 217 |         } | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 218 |         SensorFusion::getInstance().dump(result, buffer, SIZE); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 219 |         SensorDevice::getInstance().dump(result, buffer, SIZE); | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 220 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 221 |         snprintf(buffer, SIZE, "%d active connections\n", | 
 | 222 |                 mActiveConnections.size()); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 223 |         result.append(buffer); | 
 | 224 |         snprintf(buffer, SIZE, "Active sensors:\n"); | 
 | 225 |         result.append(buffer); | 
 | 226 |         for (size_t i=0 ; i<mActiveSensors.size() ; i++) { | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 227 |             int handle = mActiveSensors.keyAt(i); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 228 |             snprintf(buffer, SIZE, "%s (handle=0x%08x, connections=%d)\n", | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 229 |                     getSensorName(handle).string(), | 
 | 230 |                     handle, | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 231 |                     mActiveSensors.valueAt(i)->getNumConnections()); | 
 | 232 |             result.append(buffer); | 
 | 233 |         } | 
 | 234 |     } | 
 | 235 |     write(fd, result.string(), result.size()); | 
 | 236 |     return NO_ERROR; | 
 | 237 | } | 
 | 238 |  | 
 | 239 | bool SensorService::threadLoop() | 
 | 240 | { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 241 |     ALOGD("nuSensorService thread starting..."); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 242 |  | 
| Mathias Agopian | d1920ff | 2012-05-29 19:46:14 -0700 | [diff] [blame] | 243 |     const size_t numEventMax = 16; | 
| Mathias Agopian | 8dd4fe8 | 2012-05-30 18:08:30 -0700 | [diff] [blame] | 244 |     const size_t minBufferSize = numEventMax + numEventMax * mVirtualSensorList.size(); | 
| Mathias Agopian | d1920ff | 2012-05-29 19:46:14 -0700 | [diff] [blame] | 245 |     sensors_event_t buffer[minBufferSize]; | 
 | 246 |     sensors_event_t scratch[minBufferSize]; | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 247 |     SensorDevice& device(SensorDevice::getInstance()); | 
 | 248 |     const size_t vcount = mVirtualSensorList.size(); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 249 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 250 |     ssize_t count; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 251 |     do { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 252 |         count = device.poll(buffer, numEventMax); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 253 |         if (count<0) { | 
| Steve Block | f5a1230 | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 254 |             ALOGE("sensor poll failed (%s)", strerror(-count)); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 255 |             break; | 
 | 256 |         } | 
 | 257 |  | 
| Mathias Agopian | 94e8f68 | 2010-11-10 17:50:28 -0800 | [diff] [blame] | 258 |         recordLastValue(buffer, count); | 
 | 259 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 260 |         // handle virtual sensors | 
 | 261 |         if (count && vcount) { | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 262 |             sensors_event_t const * const event = buffer; | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 263 |             const DefaultKeyedVector<int, SensorInterface*> virtualSensors( | 
 | 264 |                     getActiveVirtualSensors()); | 
 | 265 |             const size_t activeVirtualSensorCount = virtualSensors.size(); | 
 | 266 |             if (activeVirtualSensorCount) { | 
 | 267 |                 size_t k = 0; | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 268 |                 SensorFusion& fusion(SensorFusion::getInstance()); | 
 | 269 |                 if (fusion.isEnabled()) { | 
 | 270 |                     for (size_t i=0 ; i<size_t(count) ; i++) { | 
 | 271 |                         fusion.process(event[i]); | 
 | 272 |                     } | 
 | 273 |                 } | 
| Mathias Agopian | d1920ff | 2012-05-29 19:46:14 -0700 | [diff] [blame] | 274 |                 for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 275 |                     for (size_t j=0 ; j<activeVirtualSensorCount ; j++) { | 
| Mathias Agopian | d1920ff | 2012-05-29 19:46:14 -0700 | [diff] [blame] | 276 |                         if (count + k >= minBufferSize) { | 
 | 277 |                             ALOGE("buffer too small to hold all events: " | 
 | 278 |                                     "count=%u, k=%u, size=%u", | 
 | 279 |                                     count, k, minBufferSize); | 
 | 280 |                             break; | 
 | 281 |                         } | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 282 |                         sensors_event_t out; | 
| Mathias Agopian | d1920ff | 2012-05-29 19:46:14 -0700 | [diff] [blame] | 283 |                         SensorInterface* si = virtualSensors.valueAt(j); | 
 | 284 |                         if (si->process(&out, event[i])) { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 285 |                             buffer[count + k] = out; | 
 | 286 |                             k++; | 
 | 287 |                         } | 
 | 288 |                     } | 
 | 289 |                 } | 
 | 290 |                 if (k) { | 
 | 291 |                     // record the last synthesized values | 
 | 292 |                     recordLastValue(&buffer[count], k); | 
 | 293 |                     count += k; | 
 | 294 |                     // sort the buffer by time-stamps | 
 | 295 |                     sortEventBuffer(buffer, count); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 296 |                 } | 
 | 297 |             } | 
 | 298 |         } | 
 | 299 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 300 |         // send our events to clients... | 
 | 301 |         const SortedVector< wp<SensorEventConnection> > activeConnections( | 
 | 302 |                 getActiveConnections()); | 
 | 303 |         size_t numConnections = activeConnections.size(); | 
 | 304 |         for (size_t i=0 ; i<numConnections ; i++) { | 
 | 305 |             sp<SensorEventConnection> connection( | 
 | 306 |                     activeConnections[i].promote()); | 
 | 307 |             if (connection != 0) { | 
 | 308 |                 connection->sendEvents(buffer, count, scratch); | 
 | 309 |             } | 
 | 310 |         } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 311 |     } while (count >= 0 || Thread::exitPending()); | 
 | 312 |  | 
| Steve Block | 3c20fbe | 2012-01-05 23:22:43 +0000 | [diff] [blame] | 313 |     ALOGW("Exiting SensorService::threadLoop => aborting..."); | 
| Mathias Agopian | 1a62301 | 2011-11-09 17:50:15 -0800 | [diff] [blame] | 314 |     abort(); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 315 |     return false; | 
 | 316 | } | 
 | 317 |  | 
| Mathias Agopian | 94e8f68 | 2010-11-10 17:50:28 -0800 | [diff] [blame] | 318 | void SensorService::recordLastValue( | 
 | 319 |         sensors_event_t const * buffer, size_t count) | 
 | 320 | { | 
 | 321 |     Mutex::Autolock _l(mLock); | 
 | 322 |  | 
 | 323 |     // record the last event for each sensor | 
 | 324 |     int32_t prev = buffer[0].sensor; | 
 | 325 |     for (size_t i=1 ; i<count ; i++) { | 
 | 326 |         // record the last event of each sensor type in this buffer | 
 | 327 |         int32_t curr = buffer[i].sensor; | 
 | 328 |         if (curr != prev) { | 
 | 329 |             mLastEventSeen.editValueFor(prev) = buffer[i-1]; | 
 | 330 |             prev = curr; | 
 | 331 |         } | 
 | 332 |     } | 
 | 333 |     mLastEventSeen.editValueFor(prev) = buffer[count-1]; | 
 | 334 | } | 
 | 335 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 336 | void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) | 
 | 337 | { | 
 | 338 |     struct compar { | 
 | 339 |         static int cmp(void const* lhs, void const* rhs) { | 
 | 340 |             sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs); | 
 | 341 |             sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs); | 
| Mathias Agopian | a5c106a | 2012-04-19 18:18:24 -0700 | [diff] [blame] | 342 |             return l->timestamp - r->timestamp; | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 343 |         } | 
 | 344 |     }; | 
 | 345 |     qsort(buffer, count, sizeof(sensors_event_t), compar::cmp); | 
 | 346 | } | 
 | 347 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 348 | SortedVector< wp<SensorService::SensorEventConnection> > | 
 | 349 | SensorService::getActiveConnections() const | 
 | 350 | { | 
 | 351 |     Mutex::Autolock _l(mLock); | 
 | 352 |     return mActiveConnections; | 
 | 353 | } | 
 | 354 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 355 | DefaultKeyedVector<int, SensorInterface*> | 
 | 356 | SensorService::getActiveVirtualSensors() const | 
 | 357 | { | 
 | 358 |     Mutex::Autolock _l(mLock); | 
 | 359 |     return mActiveVirtualSensors; | 
 | 360 | } | 
 | 361 |  | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 362 | String8 SensorService::getSensorName(int handle) const { | 
| Mathias Agopian | 010e422 | 2011-06-08 20:06:50 -0700 | [diff] [blame] | 363 |     size_t count = mUserSensorList.size(); | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 364 |     for (size_t i=0 ; i<count ; i++) { | 
| Mathias Agopian | 010e422 | 2011-06-08 20:06:50 -0700 | [diff] [blame] | 365 |         const Sensor& sensor(mUserSensorList[i]); | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 366 |         if (sensor.getHandle() == handle) { | 
 | 367 |             return sensor.getName(); | 
 | 368 |         } | 
 | 369 |     } | 
 | 370 |     String8 result("unknown"); | 
 | 371 |     return result; | 
 | 372 | } | 
 | 373 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 374 | Vector<Sensor> SensorService::getSensorList() | 
 | 375 | { | 
| Mathias Agopian | 3326486 | 2012-06-28 19:46:54 -0700 | [diff] [blame] | 376 |     char value[PROPERTY_VALUE_MAX]; | 
 | 377 |     property_get("debug.sensors", value, "0"); | 
 | 378 |     if (atoi(value)) { | 
 | 379 |         return mUserSensorListDebug; | 
 | 380 |     } | 
| Mathias Agopian | 010e422 | 2011-06-08 20:06:50 -0700 | [diff] [blame] | 381 |     return mUserSensorList; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 382 | } | 
 | 383 |  | 
 | 384 | sp<ISensorEventConnection> SensorService::createSensorEventConnection() | 
 | 385 | { | 
 | 386 |     sp<SensorEventConnection> result(new SensorEventConnection(this)); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 387 |     return result; | 
 | 388 | } | 
 | 389 |  | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 390 | void SensorService::cleanupConnection(SensorEventConnection* c) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 391 | { | 
 | 392 |     Mutex::Autolock _l(mLock); | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 393 |     const wp<SensorEventConnection> connection(c); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 394 |     size_t size = mActiveSensors.size(); | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 395 |     ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 396 |     for (size_t i=0 ; i<size ; ) { | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 397 |         int handle = mActiveSensors.keyAt(i); | 
 | 398 |         if (c->hasSensor(handle)) { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 399 |             ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 400 |             SensorInterface* sensor = mSensorMap.valueFor( handle ); | 
| Steve Block | f5a1230 | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 401 |             ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 402 |             if (sensor) { | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 403 |                 sensor->activate(c, false); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 404 |             } | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 405 |         } | 
 | 406 |         SensorRecord* rec = mActiveSensors.valueAt(i); | 
| Steve Block | f5a1230 | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 407 |         ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle); | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 408 |         ALOGD_IF(DEBUG_CONNECTIONS, | 
| Mathias Agopian | a1b7db9 | 2011-05-27 16:23:58 -0700 | [diff] [blame] | 409 |                 "removing connection %p for sensor[%d].handle=0x%08x", | 
 | 410 |                 c, i, handle); | 
 | 411 |  | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 412 |         if (rec && rec->removeConnection(connection)) { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 413 |             ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection"); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 414 |             mActiveSensors.removeItemsAt(i, 1); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 415 |             mActiveVirtualSensors.removeItem(handle); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 416 |             delete rec; | 
 | 417 |             size--; | 
 | 418 |         } else { | 
 | 419 |             i++; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 420 |         } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 421 |     } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 422 |     mActiveConnections.remove(connection); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 423 | } | 
 | 424 |  | 
 | 425 | status_t SensorService::enable(const sp<SensorEventConnection>& connection, | 
 | 426 |         int handle) | 
 | 427 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 428 |     if (mInitCheck != NO_ERROR) | 
 | 429 |         return mInitCheck; | 
 | 430 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 431 |     Mutex::Autolock _l(mLock); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 432 |     SensorInterface* sensor = mSensorMap.valueFor(handle); | 
 | 433 |     status_t err = sensor ? sensor->activate(connection.get(), true) : status_t(BAD_VALUE); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 434 |     if (err == NO_ERROR) { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 435 |         SensorRecord* rec = mActiveSensors.valueFor(handle); | 
 | 436 |         if (rec == 0) { | 
 | 437 |             rec = new SensorRecord(connection); | 
 | 438 |             mActiveSensors.add(handle, rec); | 
 | 439 |             if (sensor->isVirtual()) { | 
 | 440 |                 mActiveVirtualSensors.add(handle, sensor); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 441 |             } | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 442 |         } else { | 
 | 443 |             if (rec->addConnection(connection)) { | 
 | 444 |                 // this sensor is already activated, but we are adding a | 
 | 445 |                 // connection that uses it. Immediately send down the last | 
| Mathias Agopian | 3f2f891 | 2011-03-10 15:23:28 -0800 | [diff] [blame] | 446 |                 // known value of the requested sensor if it's not a | 
 | 447 |                 // "continuous" sensor. | 
 | 448 |                 if (sensor->getSensor().getMinDelay() == 0) { | 
 | 449 |                     sensors_event_t scratch; | 
 | 450 |                     sensors_event_t& event(mLastEventSeen.editValueFor(handle)); | 
 | 451 |                     if (event.version == sizeof(sensors_event_t)) { | 
 | 452 |                         connection->sendEvents(&event, 1); | 
 | 453 |                     } | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 454 |                 } | 
 | 455 |             } | 
 | 456 |         } | 
 | 457 |         if (err == NO_ERROR) { | 
 | 458 |             // connection now active | 
 | 459 |             if (connection->addSensor(handle)) { | 
 | 460 |                 // the sensor was added (which means it wasn't already there) | 
 | 461 |                 // so, see if this connection becomes active | 
 | 462 |                 if (mActiveConnections.indexOf(connection) < 0) { | 
 | 463 |                     mActiveConnections.add(connection); | 
 | 464 |                 } | 
 | 465 |             } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 466 |         } | 
 | 467 |     } | 
 | 468 |     return err; | 
 | 469 | } | 
 | 470 |  | 
 | 471 | status_t SensorService::disable(const sp<SensorEventConnection>& connection, | 
 | 472 |         int handle) | 
 | 473 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 474 |     if (mInitCheck != NO_ERROR) | 
 | 475 |         return mInitCheck; | 
 | 476 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 477 |     status_t err = NO_ERROR; | 
 | 478 |     Mutex::Autolock _l(mLock); | 
 | 479 |     SensorRecord* rec = mActiveSensors.valueFor(handle); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 480 |     if (rec) { | 
 | 481 |         // see if this connection becomes inactive | 
 | 482 |         connection->removeSensor(handle); | 
 | 483 |         if (connection->hasAnySensor() == false) { | 
 | 484 |             mActiveConnections.remove(connection); | 
 | 485 |         } | 
 | 486 |         // see if this sensor becomes inactive | 
 | 487 |         if (rec->removeConnection(connection)) { | 
 | 488 |             mActiveSensors.removeItem(handle); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 489 |             mActiveVirtualSensors.removeItem(handle); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 490 |             delete rec; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 491 |         } | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 492 |         SensorInterface* sensor = mSensorMap.valueFor(handle); | 
 | 493 |         err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 494 |     } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 495 |     return err; | 
 | 496 | } | 
 | 497 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 498 | status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 499 |         int handle, nsecs_t ns) | 
 | 500 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 501 |     if (mInitCheck != NO_ERROR) | 
 | 502 |         return mInitCheck; | 
 | 503 |  | 
| Mathias Agopian | ae09d65 | 2011-11-01 17:37:49 -0700 | [diff] [blame] | 504 |     SensorInterface* sensor = mSensorMap.valueFor(handle); | 
 | 505 |     if (!sensor) | 
 | 506 |         return BAD_VALUE; | 
 | 507 |  | 
| Mathias Agopian | 1cd7000 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 508 |     if (ns < 0) | 
 | 509 |         return BAD_VALUE; | 
 | 510 |  | 
| Mathias Agopian | 62569ec | 2011-11-07 21:21:47 -0800 | [diff] [blame] | 511 |     nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); | 
 | 512 |     if (ns < minDelayNs) { | 
 | 513 |         ns = minDelayNs; | 
| Mathias Agopian | ae09d65 | 2011-11-01 17:37:49 -0700 | [diff] [blame] | 514 |     } | 
 | 515 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 516 |     if (ns < MINIMUM_EVENTS_PERIOD) | 
 | 517 |         ns = MINIMUM_EVENTS_PERIOD; | 
| Mathias Agopian | 1cd7000 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 518 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 519 |     return sensor->setDelay(connection.get(), handle, ns); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 520 | } | 
 | 521 |  | 
 | 522 | // --------------------------------------------------------------------------- | 
 | 523 |  | 
 | 524 | SensorService::SensorRecord::SensorRecord( | 
 | 525 |         const sp<SensorEventConnection>& connection) | 
 | 526 | { | 
 | 527 |     mConnections.add(connection); | 
 | 528 | } | 
 | 529 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 530 | bool SensorService::SensorRecord::addConnection( | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 531 |         const sp<SensorEventConnection>& connection) | 
 | 532 | { | 
 | 533 |     if (mConnections.indexOf(connection) < 0) { | 
 | 534 |         mConnections.add(connection); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 535 |         return true; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 536 |     } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 537 |     return false; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 538 | } | 
 | 539 |  | 
 | 540 | bool SensorService::SensorRecord::removeConnection( | 
 | 541 |         const wp<SensorEventConnection>& connection) | 
 | 542 | { | 
 | 543 |     ssize_t index = mConnections.indexOf(connection); | 
 | 544 |     if (index >= 0) { | 
 | 545 |         mConnections.removeItemsAt(index, 1); | 
 | 546 |     } | 
 | 547 |     return mConnections.size() ? false : true; | 
 | 548 | } | 
 | 549 |  | 
 | 550 | // --------------------------------------------------------------------------- | 
 | 551 |  | 
 | 552 | SensorService::SensorEventConnection::SensorEventConnection( | 
 | 553 |         const sp<SensorService>& service) | 
| Mathias Agopian | b398927 | 2011-10-20 18:42:02 -0700 | [diff] [blame] | 554 |     : mService(service), mChannel(new BitTube()) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 555 | { | 
 | 556 | } | 
 | 557 |  | 
 | 558 | SensorService::SensorEventConnection::~SensorEventConnection() | 
 | 559 | { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 560 |     ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 561 |     mService->cleanupConnection(this); | 
 | 562 | } | 
 | 563 |  | 
 | 564 | void SensorService::SensorEventConnection::onFirstRef() | 
 | 565 | { | 
 | 566 | } | 
 | 567 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 568 | bool SensorService::SensorEventConnection::addSensor(int32_t handle) { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 569 |     Mutex::Autolock _l(mConnectionLock); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 570 |     if (mSensorInfo.indexOf(handle) <= 0) { | 
 | 571 |         mSensorInfo.add(handle); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 572 |         return true; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 573 |     } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 574 |     return false; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 575 | } | 
 | 576 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 577 | bool SensorService::SensorEventConnection::removeSensor(int32_t handle) { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 578 |     Mutex::Autolock _l(mConnectionLock); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 579 |     if (mSensorInfo.remove(handle) >= 0) { | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 580 |         return true; | 
 | 581 |     } | 
 | 582 |     return false; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 583 | } | 
 | 584 |  | 
 | 585 | bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 586 |     Mutex::Autolock _l(mConnectionLock); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 587 |     return mSensorInfo.indexOf(handle) >= 0; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 588 | } | 
 | 589 |  | 
 | 590 | bool SensorService::SensorEventConnection::hasAnySensor() const { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 591 |     Mutex::Autolock _l(mConnectionLock); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 592 |     return mSensorInfo.size() ? true : false; | 
 | 593 | } | 
 | 594 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 595 | status_t SensorService::SensorEventConnection::sendEvents( | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame] | 596 |         sensors_event_t const* buffer, size_t numEvents, | 
 | 597 |         sensors_event_t* scratch) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 598 | { | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame] | 599 |     // filter out events not for this connection | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 600 |     size_t count = 0; | 
 | 601 |     if (scratch) { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 602 |         Mutex::Autolock _l(mConnectionLock); | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 603 |         size_t i=0; | 
 | 604 |         while (i<numEvents) { | 
 | 605 |             const int32_t curr = buffer[i].sensor; | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 606 |             if (mSensorInfo.indexOf(curr) >= 0) { | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 607 |                 do { | 
 | 608 |                     scratch[count++] = buffer[i++]; | 
 | 609 |                 } while ((i<numEvents) && (buffer[i].sensor == curr)); | 
 | 610 |             } else { | 
 | 611 |                 i++; | 
 | 612 |             } | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame] | 613 |         } | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 614 |     } else { | 
 | 615 |         scratch = const_cast<sensors_event_t *>(buffer); | 
 | 616 |         count = numEvents; | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame] | 617 |     } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 618 |  | 
| Mathias Agopian | 907103b | 2012-04-02 18:38:02 -0700 | [diff] [blame] | 619 |     // NOTE: ASensorEvent and sensors_event_t are the same type | 
 | 620 |     ssize_t size = SensorEventQueue::write(mChannel, | 
 | 621 |             reinterpret_cast<ASensorEvent const*>(scratch), count); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 622 |     if (size == -EAGAIN) { | 
 | 623 |         // the destination doesn't accept events anymore, it's probably | 
 | 624 |         // full. For now, we just drop the events on the floor. | 
| Steve Block | 3c20fbe | 2012-01-05 23:22:43 +0000 | [diff] [blame] | 625 |         //ALOGW("dropping %d events on the floor", count); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 626 |         return size; | 
 | 627 |     } | 
 | 628 |  | 
| Jeff Brown | 1e0b1e8 | 2010-09-13 23:17:30 -0700 | [diff] [blame] | 629 |     return size < 0 ? status_t(size) : status_t(NO_ERROR); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 630 | } | 
 | 631 |  | 
| Mathias Agopian | b398927 | 2011-10-20 18:42:02 -0700 | [diff] [blame] | 632 | sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 633 | { | 
 | 634 |     return mChannel; | 
 | 635 | } | 
 | 636 |  | 
 | 637 | status_t SensorService::SensorEventConnection::enableDisable( | 
 | 638 |         int handle, bool enabled) | 
 | 639 | { | 
 | 640 |     status_t err; | 
 | 641 |     if (enabled) { | 
 | 642 |         err = mService->enable(this, handle); | 
 | 643 |     } else { | 
 | 644 |         err = mService->disable(this, handle); | 
 | 645 |     } | 
 | 646 |     return err; | 
 | 647 | } | 
 | 648 |  | 
 | 649 | status_t SensorService::SensorEventConnection::setEventRate( | 
 | 650 |         int handle, nsecs_t ns) | 
 | 651 | { | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 652 |     return mService->setEventRate(this, handle, ns); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 653 | } | 
 | 654 |  | 
 | 655 | // --------------------------------------------------------------------------- | 
 | 656 | }; // namespace android | 
 | 657 |  |