| 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> | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 41 | #include <hardware_legacy/power.h> | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 42 |  | 
| Mathias Agopian | 787ac1b | 2012-09-18 18:49:18 -0700 | [diff] [blame] | 43 | #include "BatteryService.h" | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 44 | #include "CorrectedGyroSensor.h" | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 45 | #include "GravitySensor.h" | 
|  | 46 | #include "LinearAccelerationSensor.h" | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 47 | #include "OrientationSensor.h" | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 48 | #include "RotationVectorSensor.h" | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 49 | #include "SensorFusion.h" | 
|  | 50 | #include "SensorService.h" | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 51 |  | 
|  | 52 | namespace android { | 
|  | 53 | // --------------------------------------------------------------------------- | 
|  | 54 |  | 
| Mathias Agopian | 3301542 | 2011-05-27 18:18:13 -0700 | [diff] [blame] | 55 | /* | 
|  | 56 | * Notes: | 
|  | 57 | * | 
|  | 58 | * - what about a gyro-corrected magnetic-field sensor? | 
| Mathias Agopian | 3301542 | 2011-05-27 18:18:13 -0700 | [diff] [blame] | 59 | * - run mag sensor from time to time to force calibration | 
|  | 60 | * - gravity sensor length is wrong (=> drift in linear-acc sensor) | 
|  | 61 | * | 
|  | 62 | */ | 
|  | 63 |  | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 64 | const char* SensorService::WAKE_LOCK_NAME = "SensorService"; | 
|  | 65 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 66 | SensorService::SensorService() | 
| Mathias Agopian | 1cb1346 | 2011-06-27 16:05:52 -0700 | [diff] [blame] | 67 | : mInitCheck(NO_INIT) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 68 | { | 
|  | 69 | } | 
|  | 70 |  | 
|  | 71 | void SensorService::onFirstRef() | 
|  | 72 | { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 73 | ALOGD("nuSensorService starting..."); | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 74 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 75 | SensorDevice& dev(SensorDevice::getInstance()); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 76 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 77 | if (dev.initCheck() == NO_ERROR) { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 78 | sensor_t const* list; | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 79 | ssize_t count = dev.getSensorList(&list); | 
|  | 80 | if (count > 0) { | 
|  | 81 | ssize_t orientationIndex = -1; | 
|  | 82 | bool hasGyro = false; | 
|  | 83 | uint32_t virtualSensorsNeeds = | 
|  | 84 | (1<<SENSOR_TYPE_GRAVITY) | | 
|  | 85 | (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | | 
|  | 86 | (1<<SENSOR_TYPE_ROTATION_VECTOR); | 
|  | 87 |  | 
|  | 88 | mLastEventSeen.setCapacity(count); | 
|  | 89 | for (ssize_t i=0 ; i<count ; i++) { | 
|  | 90 | registerSensor( new HardwareSensor(list[i]) ); | 
|  | 91 | switch (list[i].type) { | 
|  | 92 | case SENSOR_TYPE_ORIENTATION: | 
|  | 93 | orientationIndex = i; | 
|  | 94 | break; | 
|  | 95 | case SENSOR_TYPE_GYROSCOPE: | 
| Mathias Agopian | 0319306 | 2013-05-10 19:32:39 -0700 | [diff] [blame] | 96 | case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 97 | hasGyro = true; | 
|  | 98 | break; | 
|  | 99 | case SENSOR_TYPE_GRAVITY: | 
|  | 100 | case SENSOR_TYPE_LINEAR_ACCELERATION: | 
|  | 101 | case SENSOR_TYPE_ROTATION_VECTOR: | 
|  | 102 | virtualSensorsNeeds &= ~(1<<list[i].type); | 
|  | 103 | break; | 
|  | 104 | } | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 105 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 106 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 107 | // it's safe to instantiate the SensorFusion object here | 
|  | 108 | // (it wants to be instantiated after h/w sensors have been | 
|  | 109 | // registered) | 
|  | 110 | const SensorFusion& fusion(SensorFusion::getInstance()); | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 111 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 112 | // build the sensor list returned to users | 
|  | 113 | mUserSensorList = mSensorList; | 
| Mathias Agopian | 3326486 | 2012-06-28 19:46:54 -0700 | [diff] [blame] | 114 |  | 
|  | 115 | if (hasGyro) { | 
| Mathias Agopian | 0319306 | 2013-05-10 19:32:39 -0700 | [diff] [blame] | 116 | Sensor aSensor; | 
|  | 117 |  | 
|  | 118 | // Add Android virtual sensors if they're not already | 
|  | 119 | // available in the HAL | 
|  | 120 |  | 
|  | 121 | aSensor = registerVirtualSensor( new RotationVectorSensor() ); | 
|  | 122 | if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { | 
|  | 123 | mUserSensorList.add(aSensor); | 
|  | 124 | } | 
|  | 125 |  | 
|  | 126 | aSensor = registerVirtualSensor( new GravitySensor(list, count) ); | 
|  | 127 | if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) { | 
|  | 128 | mUserSensorList.add(aSensor); | 
|  | 129 | } | 
|  | 130 |  | 
|  | 131 | aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) ); | 
|  | 132 | if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) { | 
|  | 133 | mUserSensorList.add(aSensor); | 
|  | 134 | } | 
|  | 135 |  | 
|  | 136 | aSensor = registerVirtualSensor( new OrientationSensor() ); | 
|  | 137 | if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { | 
|  | 138 | // if we are doing our own rotation-vector, also add | 
|  | 139 | // the orientation sensor and remove the HAL provided one. | 
|  | 140 | mUserSensorList.replaceAt(aSensor, orientationIndex); | 
|  | 141 | } | 
|  | 142 |  | 
| Mathias Agopian | 3326486 | 2012-06-28 19:46:54 -0700 | [diff] [blame] | 143 | // virtual debugging sensors are not added to mUserSensorList | 
| Mathias Agopian | 0319306 | 2013-05-10 19:32:39 -0700 | [diff] [blame] | 144 | registerVirtualSensor( new CorrectedGyroSensor(list, count) ); | 
| Mathias Agopian | 3326486 | 2012-06-28 19:46:54 -0700 | [diff] [blame] | 145 | registerVirtualSensor( new GyroDriftSensor() ); | 
|  | 146 | } | 
|  | 147 |  | 
| Mathias Agopian | 3326486 | 2012-06-28 19:46:54 -0700 | [diff] [blame] | 148 | // debugging sensor list | 
| Mathias Agopian | 0319306 | 2013-05-10 19:32:39 -0700 | [diff] [blame] | 149 | mUserSensorListDebug = mSensorList; | 
| Mathias Agopian | 3326486 | 2012-06-28 19:46:54 -0700 | [diff] [blame] | 150 |  | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 151 | mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED; | 
|  | 152 | FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r"); | 
|  | 153 | char line[128]; | 
|  | 154 | if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) { | 
|  | 155 | line[sizeof(line) - 1] = '\0'; | 
|  | 156 | sscanf(line, "%u", &mSocketBufferSize); | 
|  | 157 | if (mSocketBufferSize > MAX_SOCKET_BUFFER_SIZE_BATCHED) { | 
|  | 158 | mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED; | 
|  | 159 | } | 
|  | 160 | } | 
|  | 161 | ALOGD("Max socket buffer size %u", mSocketBufferSize); | 
|  | 162 | if (fp) { | 
|  | 163 | fclose(fp); | 
|  | 164 | } | 
|  | 165 |  | 
| Mathias Agopian | 7b2b32f | 2011-07-14 16:39:46 -0700 | [diff] [blame] | 166 | run("SensorService", PRIORITY_URGENT_DISPLAY); | 
|  | 167 | mInitCheck = NO_ERROR; | 
|  | 168 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 169 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 170 | } | 
|  | 171 |  | 
| Mathias Agopian | 0319306 | 2013-05-10 19:32:39 -0700 | [diff] [blame] | 172 | Sensor SensorService::registerSensor(SensorInterface* s) | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 173 | { | 
|  | 174 | sensors_event_t event; | 
|  | 175 | memset(&event, 0, sizeof(event)); | 
|  | 176 |  | 
|  | 177 | const Sensor sensor(s->getSensor()); | 
|  | 178 | // add to the sensor list (returned to clients) | 
|  | 179 | mSensorList.add(sensor); | 
|  | 180 | // add to our handle->SensorInterface mapping | 
|  | 181 | mSensorMap.add(sensor.getHandle(), s); | 
|  | 182 | // create an entry in the mLastEventSeen array | 
|  | 183 | mLastEventSeen.add(sensor.getHandle(), event); | 
| Mathias Agopian | 0319306 | 2013-05-10 19:32:39 -0700 | [diff] [blame] | 184 |  | 
|  | 185 | return sensor; | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 186 | } | 
|  | 187 |  | 
| Mathias Agopian | 0319306 | 2013-05-10 19:32:39 -0700 | [diff] [blame] | 188 | Sensor SensorService::registerVirtualSensor(SensorInterface* s) | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 189 | { | 
| Mathias Agopian | 0319306 | 2013-05-10 19:32:39 -0700 | [diff] [blame] | 190 | Sensor sensor = registerSensor(s); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 191 | mVirtualSensorList.add( s ); | 
| Mathias Agopian | 0319306 | 2013-05-10 19:32:39 -0700 | [diff] [blame] | 192 | return sensor; | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 193 | } | 
|  | 194 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 195 | SensorService::~SensorService() | 
|  | 196 | { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 197 | for (size_t i=0 ; i<mSensorMap.size() ; i++) | 
|  | 198 | delete mSensorMap.valueAt(i); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 199 | } | 
|  | 200 |  | 
| Mathias Agopian | 1cb1346 | 2011-06-27 16:05:52 -0700 | [diff] [blame] | 201 | static const String16 sDump("android.permission.DUMP"); | 
|  | 202 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 203 | status_t SensorService::dump(int fd, const Vector<String16>& args) | 
|  | 204 | { | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 205 | String8 result; | 
| Mathias Agopian | 1cb1346 | 2011-06-27 16:05:52 -0700 | [diff] [blame] | 206 | if (!PermissionCache::checkCallingPermission(sDump)) { | 
| Mathias Agopian | ba02cd2 | 2013-07-03 16:20:57 -0700 | [diff] [blame] | 207 | result.appendFormat("Permission Denial: " | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 208 | "can't dump SurfaceFlinger from pid=%d, uid=%d\n", | 
|  | 209 | IPCThreadState::self()->getCallingPid(), | 
|  | 210 | IPCThreadState::self()->getCallingUid()); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 211 | } else { | 
|  | 212 | Mutex::Autolock _l(mLock); | 
| Mathias Agopian | ba02cd2 | 2013-07-03 16:20:57 -0700 | [diff] [blame] | 213 | result.append("Sensor List:\n"); | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 214 | for (size_t i=0 ; i<mSensorList.size() ; i++) { | 
|  | 215 | const Sensor& s(mSensorList[i]); | 
|  | 216 | const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle())); | 
| Mathias Agopian | ba02cd2 | 2013-07-03 16:20:57 -0700 | [diff] [blame] | 217 | result.appendFormat( | 
|  | 218 | "%-48s| %-32s | 0x%08x | ", | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 219 | s.getName().string(), | 
|  | 220 | s.getVendor().string(), | 
| Mathias Agopian | ba02cd2 | 2013-07-03 16:20:57 -0700 | [diff] [blame] | 221 | s.getHandle()); | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 222 |  | 
| Mathias Agopian | ba02cd2 | 2013-07-03 16:20:57 -0700 | [diff] [blame] | 223 | if (s.getMinDelay() > 0) { | 
|  | 224 | result.appendFormat( | 
|  | 225 | "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay()); | 
|  | 226 | } else { | 
|  | 227 | result.append(s.getMinDelay() == 0 | 
|  | 228 | ? "on-demand         | " | 
|  | 229 | : "one-shot          | "); | 
|  | 230 | } | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 231 | if (s.getFifoMaxEventCount() > 0) { | 
|  | 232 | result.appendFormat("getFifoMaxEventCount=%d events | ", s.getFifoMaxEventCount()); | 
|  | 233 | } else { | 
|  | 234 | result.append("no batching support | "); | 
|  | 235 | } | 
| Mathias Agopian | ba02cd2 | 2013-07-03 16:20:57 -0700 | [diff] [blame] | 236 |  | 
|  | 237 | switch (s.getType()) { | 
|  | 238 | case SENSOR_TYPE_ROTATION_VECTOR: | 
|  | 239 | case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: | 
|  | 240 | result.appendFormat( | 
|  | 241 | "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n", | 
|  | 242 | e.data[0], e.data[1], e.data[2], e.data[3], e.data[4]); | 
|  | 243 | break; | 
|  | 244 | case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED: | 
|  | 245 | case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: | 
|  | 246 | result.appendFormat( | 
|  | 247 | "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n", | 
|  | 248 | e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]); | 
|  | 249 | break; | 
|  | 250 | case SENSOR_TYPE_GAME_ROTATION_VECTOR: | 
|  | 251 | result.appendFormat( | 
|  | 252 | "last=<%5.1f,%5.1f,%5.1f,%5.1f>\n", | 
|  | 253 | e.data[0], e.data[1], e.data[2], e.data[3]); | 
|  | 254 | break; | 
|  | 255 | case SENSOR_TYPE_SIGNIFICANT_MOTION: | 
|  | 256 | case SENSOR_TYPE_STEP_DETECTOR: | 
|  | 257 | result.appendFormat( "last=<%f>\n", e.data[0]); | 
|  | 258 | break; | 
|  | 259 | case SENSOR_TYPE_STEP_COUNTER: | 
|  | 260 | result.appendFormat( "last=<%llu>\n", e.u64.step_counter); | 
|  | 261 | break; | 
|  | 262 | default: | 
|  | 263 | // default to 3 values | 
|  | 264 | result.appendFormat( | 
|  | 265 | "last=<%5.1f,%5.1f,%5.1f>\n", | 
|  | 266 | e.data[0], e.data[1], e.data[2]); | 
|  | 267 | break; | 
|  | 268 | } | 
|  | 269 | } | 
|  | 270 | SensorFusion::getInstance().dump(result); | 
|  | 271 | SensorDevice::getInstance().dump(result); | 
|  | 272 |  | 
| Mathias Agopian | ba02cd2 | 2013-07-03 16:20:57 -0700 | [diff] [blame] | 273 | result.append("Active sensors:\n"); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 274 | for (size_t i=0 ; i<mActiveSensors.size() ; i++) { | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 275 | int handle = mActiveSensors.keyAt(i); | 
| Mathias Agopian | ba02cd2 | 2013-07-03 16:20:57 -0700 | [diff] [blame] | 276 | result.appendFormat("%s (handle=0x%08x, connections=%d)\n", | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 277 | getSensorName(handle).string(), | 
|  | 278 | handle, | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 279 | mActiveSensors.valueAt(i)->getNumConnections()); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 280 | } | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 281 |  | 
|  | 282 | result.appendFormat("%u Max Socket Buffer size\n", mSocketBufferSize); | 
|  | 283 | result.appendFormat("%d active connections\n", mActiveConnections.size()); | 
|  | 284 |  | 
|  | 285 | for (size_t i=0 ; i < mActiveConnections.size() ; i++) { | 
|  | 286 | sp<SensorEventConnection> connection(mActiveConnections[i].promote()); | 
|  | 287 | if (connection != 0) { | 
|  | 288 | result.appendFormat("Connection Number: %d \n", i); | 
|  | 289 | connection->dump(result); | 
|  | 290 | } | 
|  | 291 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 292 | } | 
|  | 293 | write(fd, result.string(), result.size()); | 
|  | 294 | return NO_ERROR; | 
|  | 295 | } | 
|  | 296 |  | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 297 | void SensorService::cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection, | 
|  | 298 | sensors_event_t const* buffer, const int count) { | 
| Jaikumar Ganesh | 4c01b1a | 2013-04-16 15:52:23 -0700 | [diff] [blame] | 299 | SensorInterface* sensor; | 
|  | 300 | status_t err = NO_ERROR; | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 301 | for (int i=0 ; i<count ; i++) { | 
|  | 302 | int handle = buffer[i].sensor; | 
| Mathias Agopian | 7438fd1 | 2013-07-08 12:50:39 -0700 | [diff] [blame] | 303 | int type = buffer[i].type; | 
|  | 304 | if (type == SENSOR_TYPE_SIGNIFICANT_MOTION) { | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 305 | if (connection->hasSensor(handle)) { | 
| Jaikumar Ganesh | 4c01b1a | 2013-04-16 15:52:23 -0700 | [diff] [blame] | 306 | sensor = mSensorMap.valueFor(handle); | 
| Mathias Agopian | ac9a96d | 2013-07-12 02:01:16 -0700 | [diff] [blame] | 307 | if (sensor != NULL) { | 
|  | 308 | sensor->autoDisable(connection.get(), handle); | 
| Jaikumar Ganesh | 4c01b1a | 2013-04-16 15:52:23 -0700 | [diff] [blame] | 309 | } | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 310 | cleanupWithoutDisable(connection, handle); | 
|  | 311 | } | 
|  | 312 | } | 
|  | 313 | } | 
|  | 314 | } | 
|  | 315 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 316 | bool SensorService::threadLoop() | 
|  | 317 | { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 318 | ALOGD("nuSensorService thread starting..."); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 319 |  | 
| Mathias Agopian | 90ed3e8 | 2013-09-09 23:36:25 -0700 | [diff] [blame] | 320 | // each virtual sensor could generate an event per "real" event, that's why we need | 
|  | 321 | // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. | 
|  | 322 | // in practice, this is too aggressive, but guaranteed to be enough. | 
|  | 323 | const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; | 
|  | 324 | const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size()); | 
|  | 325 |  | 
| Mathias Agopian | d1920ff | 2012-05-29 19:46:14 -0700 | [diff] [blame] | 326 | sensors_event_t buffer[minBufferSize]; | 
|  | 327 | sensors_event_t scratch[minBufferSize]; | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 328 | SensorDevice& device(SensorDevice::getInstance()); | 
|  | 329 | const size_t vcount = mVirtualSensorList.size(); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 330 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 331 | ssize_t count; | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 332 | bool wakeLockAcquired = false; | 
|  | 333 | const int halVersion = device.getHalDeviceVersion(); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 334 | do { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 335 | count = device.poll(buffer, numEventMax); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 336 | if (count<0) { | 
| Steve Block | f5a1230 | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 337 | ALOGE("sensor poll failed (%s)", strerror(-count)); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 338 | break; | 
|  | 339 | } | 
|  | 340 |  | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 341 | // Poll has returned. Hold a wakelock. | 
|  | 342 | // Todo(): add a flag to the sensors definitions to indicate | 
|  | 343 | // the sensors which can wake up the AP | 
|  | 344 | for (int i = 0; i < count; i++) { | 
| Mathias Agopian | 7438fd1 | 2013-07-08 12:50:39 -0700 | [diff] [blame] | 345 | if (buffer[i].type == SENSOR_TYPE_SIGNIFICANT_MOTION) { | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 346 | acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); | 
|  | 347 | wakeLockAcquired = true; | 
|  | 348 | break; | 
|  | 349 | } | 
|  | 350 | } | 
|  | 351 |  | 
| Mathias Agopian | 94e8f68 | 2010-11-10 17:50:28 -0800 | [diff] [blame] | 352 | recordLastValue(buffer, count); | 
|  | 353 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 354 | // handle virtual sensors | 
|  | 355 | if (count && vcount) { | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 356 | sensors_event_t const * const event = buffer; | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 357 | const DefaultKeyedVector<int, SensorInterface*> virtualSensors( | 
|  | 358 | getActiveVirtualSensors()); | 
|  | 359 | const size_t activeVirtualSensorCount = virtualSensors.size(); | 
|  | 360 | if (activeVirtualSensorCount) { | 
|  | 361 | size_t k = 0; | 
| Mathias Agopian | 984826c | 2011-05-17 22:54:42 -0700 | [diff] [blame] | 362 | SensorFusion& fusion(SensorFusion::getInstance()); | 
|  | 363 | if (fusion.isEnabled()) { | 
|  | 364 | for (size_t i=0 ; i<size_t(count) ; i++) { | 
|  | 365 | fusion.process(event[i]); | 
|  | 366 | } | 
|  | 367 | } | 
| Mathias Agopian | d1920ff | 2012-05-29 19:46:14 -0700 | [diff] [blame] | 368 | for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 369 | for (size_t j=0 ; j<activeVirtualSensorCount ; j++) { | 
| Mathias Agopian | d1920ff | 2012-05-29 19:46:14 -0700 | [diff] [blame] | 370 | if (count + k >= minBufferSize) { | 
|  | 371 | ALOGE("buffer too small to hold all events: " | 
|  | 372 | "count=%u, k=%u, size=%u", | 
|  | 373 | count, k, minBufferSize); | 
|  | 374 | break; | 
|  | 375 | } | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 376 | sensors_event_t out; | 
| Mathias Agopian | d1920ff | 2012-05-29 19:46:14 -0700 | [diff] [blame] | 377 | SensorInterface* si = virtualSensors.valueAt(j); | 
|  | 378 | if (si->process(&out, event[i])) { | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 379 | buffer[count + k] = out; | 
|  | 380 | k++; | 
|  | 381 | } | 
|  | 382 | } | 
|  | 383 | } | 
|  | 384 | if (k) { | 
|  | 385 | // record the last synthesized values | 
|  | 386 | recordLastValue(&buffer[count], k); | 
|  | 387 | count += k; | 
|  | 388 | // sort the buffer by time-stamps | 
|  | 389 | sortEventBuffer(buffer, count); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 390 | } | 
|  | 391 | } | 
|  | 392 | } | 
|  | 393 |  | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 394 | // handle backward compatibility for RotationVector sensor | 
|  | 395 | if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { | 
|  | 396 | for (int i = 0; i < count; i++) { | 
| Mathias Agopian | 7438fd1 | 2013-07-08 12:50:39 -0700 | [diff] [blame] | 397 | if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) { | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 398 | // All the 4 components of the quaternion should be available | 
|  | 399 | // No heading accuracy. Set it to -1 | 
|  | 400 | buffer[i].data[4] = -1; | 
|  | 401 | } | 
|  | 402 | } | 
|  | 403 | } | 
|  | 404 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 405 | // send our events to clients... | 
|  | 406 | const SortedVector< wp<SensorEventConnection> > activeConnections( | 
|  | 407 | getActiveConnections()); | 
|  | 408 | size_t numConnections = activeConnections.size(); | 
|  | 409 | for (size_t i=0 ; i<numConnections ; i++) { | 
|  | 410 | sp<SensorEventConnection> connection( | 
|  | 411 | activeConnections[i].promote()); | 
|  | 412 | if (connection != 0) { | 
|  | 413 | connection->sendEvents(buffer, count, scratch); | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 414 | // Some sensors need to be auto disabled after the trigger | 
|  | 415 | cleanupAutoDisabledSensor(connection, buffer, count); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 416 | } | 
|  | 417 | } | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 418 |  | 
|  | 419 | // We have read the data, upper layers should hold the wakelock. | 
|  | 420 | if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 421 | } while (count >= 0 || Thread::exitPending()); | 
|  | 422 |  | 
| Steve Block | 3c20fbe | 2012-01-05 23:22:43 +0000 | [diff] [blame] | 423 | ALOGW("Exiting SensorService::threadLoop => aborting..."); | 
| Mathias Agopian | 1a62301 | 2011-11-09 17:50:15 -0800 | [diff] [blame] | 424 | abort(); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 425 | return false; | 
|  | 426 | } | 
|  | 427 |  | 
| Mathias Agopian | 94e8f68 | 2010-11-10 17:50:28 -0800 | [diff] [blame] | 428 | void SensorService::recordLastValue( | 
| Aravind Akella | 4b84704 | 2014-03-03 19:02:46 -0800 | [diff] [blame] | 429 | const sensors_event_t* buffer, size_t count) { | 
| Mathias Agopian | 94e8f68 | 2010-11-10 17:50:28 -0800 | [diff] [blame] | 430 | Mutex::Autolock _l(mLock); | 
| Aravind Akella | 4b84704 | 2014-03-03 19:02:46 -0800 | [diff] [blame] | 431 | const sensors_event_t* last = NULL; | 
|  | 432 | for (size_t i = 0; i < count; i++) { | 
|  | 433 | const sensors_event_t* event = &buffer[i]; | 
|  | 434 | if (event->type != SENSOR_TYPE_META_DATA) { | 
|  | 435 | if (last && event->sensor != last->sensor) { | 
|  | 436 | mLastEventSeen.editValueFor(last->sensor) = *last; | 
|  | 437 | } | 
|  | 438 | last = event; | 
| Mathias Agopian | 94e8f68 | 2010-11-10 17:50:28 -0800 | [diff] [blame] | 439 | } | 
|  | 440 | } | 
| Aravind Akella | 4b84704 | 2014-03-03 19:02:46 -0800 | [diff] [blame] | 441 | if (last) { | 
|  | 442 | mLastEventSeen.editValueFor(last->sensor) = *last; | 
|  | 443 | } | 
| Mathias Agopian | 94e8f68 | 2010-11-10 17:50:28 -0800 | [diff] [blame] | 444 | } | 
|  | 445 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 446 | void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) | 
|  | 447 | { | 
|  | 448 | struct compar { | 
|  | 449 | static int cmp(void const* lhs, void const* rhs) { | 
|  | 450 | sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs); | 
|  | 451 | sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs); | 
| Mathias Agopian | a5c106a | 2012-04-19 18:18:24 -0700 | [diff] [blame] | 452 | return l->timestamp - r->timestamp; | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 453 | } | 
|  | 454 | }; | 
|  | 455 | qsort(buffer, count, sizeof(sensors_event_t), compar::cmp); | 
|  | 456 | } | 
|  | 457 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 458 | SortedVector< wp<SensorService::SensorEventConnection> > | 
|  | 459 | SensorService::getActiveConnections() const | 
|  | 460 | { | 
|  | 461 | Mutex::Autolock _l(mLock); | 
|  | 462 | return mActiveConnections; | 
|  | 463 | } | 
|  | 464 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 465 | DefaultKeyedVector<int, SensorInterface*> | 
|  | 466 | SensorService::getActiveVirtualSensors() const | 
|  | 467 | { | 
|  | 468 | Mutex::Autolock _l(mLock); | 
|  | 469 | return mActiveVirtualSensors; | 
|  | 470 | } | 
|  | 471 |  | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 472 | String8 SensorService::getSensorName(int handle) const { | 
| Mathias Agopian | 010e422 | 2011-06-08 20:06:50 -0700 | [diff] [blame] | 473 | size_t count = mUserSensorList.size(); | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 474 | for (size_t i=0 ; i<count ; i++) { | 
| Mathias Agopian | 010e422 | 2011-06-08 20:06:50 -0700 | [diff] [blame] | 475 | const Sensor& sensor(mUserSensorList[i]); | 
| Mathias Agopian | 5d27072 | 2010-07-19 15:20:39 -0700 | [diff] [blame] | 476 | if (sensor.getHandle() == handle) { | 
|  | 477 | return sensor.getName(); | 
|  | 478 | } | 
|  | 479 | } | 
|  | 480 | String8 result("unknown"); | 
|  | 481 | return result; | 
|  | 482 | } | 
|  | 483 |  | 
| Aravind Akella | b4099e7 | 2013-10-15 15:43:10 -0700 | [diff] [blame] | 484 | bool SensorService::isVirtualSensor(int handle) const { | 
|  | 485 | SensorInterface* sensor = mSensorMap.valueFor(handle); | 
|  | 486 | return sensor->isVirtual(); | 
|  | 487 | } | 
|  | 488 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 489 | Vector<Sensor> SensorService::getSensorList() | 
|  | 490 | { | 
| Mathias Agopian | 3326486 | 2012-06-28 19:46:54 -0700 | [diff] [blame] | 491 | char value[PROPERTY_VALUE_MAX]; | 
|  | 492 | property_get("debug.sensors", value, "0"); | 
|  | 493 | if (atoi(value)) { | 
|  | 494 | return mUserSensorListDebug; | 
|  | 495 | } | 
| Mathias Agopian | 010e422 | 2011-06-08 20:06:50 -0700 | [diff] [blame] | 496 | return mUserSensorList; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 497 | } | 
|  | 498 |  | 
|  | 499 | sp<ISensorEventConnection> SensorService::createSensorEventConnection() | 
|  | 500 | { | 
| Mathias Agopian | 5307d17 | 2012-09-18 17:02:43 -0700 | [diff] [blame] | 501 | uid_t uid = IPCThreadState::self()->getCallingUid(); | 
|  | 502 | sp<SensorEventConnection> result(new SensorEventConnection(this, uid)); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 503 | return result; | 
|  | 504 | } | 
|  | 505 |  | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 506 | void SensorService::cleanupConnection(SensorEventConnection* c) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 507 | { | 
|  | 508 | Mutex::Autolock _l(mLock); | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 509 | const wp<SensorEventConnection> connection(c); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 510 | size_t size = mActiveSensors.size(); | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 511 | ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 512 | for (size_t i=0 ; i<size ; ) { | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 513 | int handle = mActiveSensors.keyAt(i); | 
|  | 514 | if (c->hasSensor(handle)) { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 515 | ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 516 | SensorInterface* sensor = mSensorMap.valueFor( handle ); | 
| Steve Block | f5a1230 | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 517 | ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 518 | if (sensor) { | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 519 | sensor->activate(c, false); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 520 | } | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 521 | } | 
|  | 522 | SensorRecord* rec = mActiveSensors.valueAt(i); | 
| Steve Block | f5a1230 | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 523 | ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle); | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 524 | ALOGD_IF(DEBUG_CONNECTIONS, | 
| Mathias Agopian | a1b7db9 | 2011-05-27 16:23:58 -0700 | [diff] [blame] | 525 | "removing connection %p for sensor[%d].handle=0x%08x", | 
|  | 526 | c, i, handle); | 
|  | 527 |  | 
| Mathias Agopian | db5b4bc | 2011-02-03 14:52:47 -0800 | [diff] [blame] | 528 | if (rec && rec->removeConnection(connection)) { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 529 | ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection"); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 530 | mActiveSensors.removeItemsAt(i, 1); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 531 | mActiveVirtualSensors.removeItem(handle); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 532 | delete rec; | 
|  | 533 | size--; | 
|  | 534 | } else { | 
|  | 535 | i++; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 536 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 537 | } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 538 | mActiveConnections.remove(connection); | 
| Mathias Agopian | 787ac1b | 2012-09-18 18:49:18 -0700 | [diff] [blame] | 539 | BatteryService::cleanup(c->getUid()); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 540 | } | 
|  | 541 |  | 
|  | 542 | status_t SensorService::enable(const sp<SensorEventConnection>& connection, | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 543 | int handle, nsecs_t samplingPeriodNs,  nsecs_t maxBatchReportLatencyNs, int reservedFlags) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 544 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 545 | if (mInitCheck != NO_ERROR) | 
|  | 546 | return mInitCheck; | 
|  | 547 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 548 | SensorInterface* sensor = mSensorMap.valueFor(handle); | 
| Mathias Agopian | ac9a96d | 2013-07-12 02:01:16 -0700 | [diff] [blame] | 549 | if (sensor == NULL) { | 
|  | 550 | return BAD_VALUE; | 
|  | 551 | } | 
| Mathias Agopian | ac9a96d | 2013-07-12 02:01:16 -0700 | [diff] [blame] | 552 | Mutex::Autolock _l(mLock); | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 553 | SensorRecord* rec = mActiveSensors.valueFor(handle); | 
|  | 554 | if (rec == 0) { | 
|  | 555 | rec = new SensorRecord(connection); | 
|  | 556 | mActiveSensors.add(handle, rec); | 
|  | 557 | if (sensor->isVirtual()) { | 
|  | 558 | mActiveVirtualSensors.add(handle, sensor); | 
|  | 559 | } | 
|  | 560 | } else { | 
|  | 561 | if (rec->addConnection(connection)) { | 
|  | 562 | // this sensor is already activated, but we are adding a | 
|  | 563 | // connection that uses it. Immediately send down the last | 
|  | 564 | // known value of the requested sensor if it's not a | 
|  | 565 | // "continuous" sensor. | 
|  | 566 | if (sensor->getSensor().getMinDelay() == 0) { | 
|  | 567 | sensors_event_t scratch; | 
|  | 568 | sensors_event_t& event(mLastEventSeen.editValueFor(handle)); | 
|  | 569 | if (event.version == sizeof(sensors_event_t)) { | 
|  | 570 | connection->sendEvents(&event, 1); | 
|  | 571 | } | 
|  | 572 | } | 
|  | 573 | } | 
|  | 574 | } | 
|  | 575 |  | 
|  | 576 | if (connection->addSensor(handle)) { | 
|  | 577 | BatteryService::enableSensor(connection->getUid(), handle); | 
|  | 578 | // the sensor was added (which means it wasn't already there) | 
|  | 579 | // so, see if this connection becomes active | 
|  | 580 | if (mActiveConnections.indexOf(connection) < 0) { | 
|  | 581 | mActiveConnections.add(connection); | 
|  | 582 | } | 
|  | 583 | } else { | 
|  | 584 | ALOGW("sensor %08x already enabled in connection %p (ignoring)", | 
|  | 585 | handle, connection.get()); | 
|  | 586 | } | 
|  | 587 |  | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 588 | nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); | 
|  | 589 | if (samplingPeriodNs < minDelayNs) { | 
|  | 590 | samplingPeriodNs = minDelayNs; | 
|  | 591 | } | 
|  | 592 |  | 
|  | 593 | ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld", | 
|  | 594 | handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs); | 
|  | 595 |  | 
|  | 596 | status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs, | 
|  | 597 | maxBatchReportLatencyNs); | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 598 | if (err == NO_ERROR) { | 
|  | 599 | connection->setFirstFlushPending(handle, true); | 
|  | 600 | status_t err_flush = sensor->flush(connection.get(), handle); | 
|  | 601 | // Flush may return error if the sensor is not activated or the underlying h/w sensor does | 
|  | 602 | // not support flush. | 
|  | 603 | if (err_flush != NO_ERROR) { | 
|  | 604 | connection->setFirstFlushPending(handle, false); | 
|  | 605 | } | 
|  | 606 | } | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 607 |  | 
|  | 608 | if (err == NO_ERROR) { | 
|  | 609 | ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle); | 
|  | 610 | err = sensor->activate(connection.get(), true); | 
|  | 611 | } | 
|  | 612 |  | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 613 | if (err != NO_ERROR) { | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 614 | // batch/activate has failed, reset our state. | 
| Mathias Agopian | ac9a96d | 2013-07-12 02:01:16 -0700 | [diff] [blame] | 615 | cleanupWithoutDisableLocked(connection, handle); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 616 | } | 
|  | 617 | return err; | 
|  | 618 | } | 
|  | 619 |  | 
|  | 620 | status_t SensorService::disable(const sp<SensorEventConnection>& connection, | 
|  | 621 | int handle) | 
|  | 622 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 623 | if (mInitCheck != NO_ERROR) | 
|  | 624 | return mInitCheck; | 
|  | 625 |  | 
| Mathias Agopian | ac9a96d | 2013-07-12 02:01:16 -0700 | [diff] [blame] | 626 | Mutex::Autolock _l(mLock); | 
|  | 627 | status_t err = cleanupWithoutDisableLocked(connection, handle); | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 628 | if (err == NO_ERROR) { | 
|  | 629 | SensorInterface* sensor = mSensorMap.valueFor(handle); | 
|  | 630 | err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE); | 
|  | 631 | } | 
|  | 632 | return err; | 
|  | 633 | } | 
|  | 634 |  | 
| Mathias Agopian | ac9a96d | 2013-07-12 02:01:16 -0700 | [diff] [blame] | 635 | status_t SensorService::cleanupWithoutDisable( | 
|  | 636 | const sp<SensorEventConnection>& connection, int handle) { | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 637 | Mutex::Autolock _l(mLock); | 
| Mathias Agopian | ac9a96d | 2013-07-12 02:01:16 -0700 | [diff] [blame] | 638 | return cleanupWithoutDisableLocked(connection, handle); | 
|  | 639 | } | 
|  | 640 |  | 
|  | 641 | status_t SensorService::cleanupWithoutDisableLocked( | 
|  | 642 | const sp<SensorEventConnection>& connection, int handle) { | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 643 | SensorRecord* rec = mActiveSensors.valueFor(handle); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 644 | if (rec) { | 
|  | 645 | // see if this connection becomes inactive | 
| Mathias Agopian | 787ac1b | 2012-09-18 18:49:18 -0700 | [diff] [blame] | 646 | if (connection->removeSensor(handle)) { | 
|  | 647 | BatteryService::disableSensor(connection->getUid(), handle); | 
|  | 648 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 649 | if (connection->hasAnySensor() == false) { | 
|  | 650 | mActiveConnections.remove(connection); | 
|  | 651 | } | 
|  | 652 | // see if this sensor becomes inactive | 
|  | 653 | if (rec->removeConnection(connection)) { | 
|  | 654 | mActiveSensors.removeItem(handle); | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 655 | mActiveVirtualSensors.removeItem(handle); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 656 | delete rec; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 657 | } | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 658 | return NO_ERROR; | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 659 | } | 
| Jaikumar Ganesh | 4342fdf | 2013-04-08 16:43:12 -0700 | [diff] [blame] | 660 | return BAD_VALUE; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 661 | } | 
|  | 662 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 663 | status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 664 | int handle, nsecs_t ns) | 
|  | 665 | { | 
| Mathias Agopian | 50df295 | 2010-07-19 19:09:10 -0700 | [diff] [blame] | 666 | if (mInitCheck != NO_ERROR) | 
|  | 667 | return mInitCheck; | 
|  | 668 |  | 
| Mathias Agopian | ae09d65 | 2011-11-01 17:37:49 -0700 | [diff] [blame] | 669 | SensorInterface* sensor = mSensorMap.valueFor(handle); | 
|  | 670 | if (!sensor) | 
|  | 671 | return BAD_VALUE; | 
|  | 672 |  | 
| Mathias Agopian | 1cd7000 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 673 | if (ns < 0) | 
|  | 674 | return BAD_VALUE; | 
|  | 675 |  | 
| Mathias Agopian | 62569ec | 2011-11-07 21:21:47 -0800 | [diff] [blame] | 676 | nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); | 
|  | 677 | if (ns < minDelayNs) { | 
|  | 678 | ns = minDelayNs; | 
| Mathias Agopian | ae09d65 | 2011-11-01 17:37:49 -0700 | [diff] [blame] | 679 | } | 
|  | 680 |  | 
| Mathias Agopian | f001c92 | 2010-11-11 17:58:51 -0800 | [diff] [blame] | 681 | return sensor->setDelay(connection.get(), handle, ns); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 682 | } | 
|  | 683 |  | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 684 | status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection, | 
|  | 685 | int handle) { | 
|  | 686 | if (mInitCheck != NO_ERROR) return mInitCheck; | 
|  | 687 | SensorInterface* sensor = mSensorMap.valueFor(handle); | 
| Aravind Akella | 701166d | 2013-10-08 14:59:26 -0700 | [diff] [blame] | 688 | if (sensor == NULL) { | 
|  | 689 | return BAD_VALUE; | 
|  | 690 | } | 
|  | 691 | if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) { | 
|  | 692 | ALOGE("flush called on Significant Motion sensor"); | 
|  | 693 | return INVALID_OPERATION; | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 694 | } | 
|  | 695 | return sensor->flush(connection.get(), handle); | 
|  | 696 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 697 | // --------------------------------------------------------------------------- | 
|  | 698 |  | 
|  | 699 | SensorService::SensorRecord::SensorRecord( | 
|  | 700 | const sp<SensorEventConnection>& connection) | 
|  | 701 | { | 
|  | 702 | mConnections.add(connection); | 
|  | 703 | } | 
|  | 704 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 705 | bool SensorService::SensorRecord::addConnection( | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 706 | const sp<SensorEventConnection>& connection) | 
|  | 707 | { | 
|  | 708 | if (mConnections.indexOf(connection) < 0) { | 
|  | 709 | mConnections.add(connection); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 710 | return true; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 711 | } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 712 | return false; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 713 | } | 
|  | 714 |  | 
|  | 715 | bool SensorService::SensorRecord::removeConnection( | 
|  | 716 | const wp<SensorEventConnection>& connection) | 
|  | 717 | { | 
|  | 718 | ssize_t index = mConnections.indexOf(connection); | 
|  | 719 | if (index >= 0) { | 
|  | 720 | mConnections.removeItemsAt(index, 1); | 
|  | 721 | } | 
|  | 722 | return mConnections.size() ? false : true; | 
|  | 723 | } | 
|  | 724 |  | 
|  | 725 | // --------------------------------------------------------------------------- | 
|  | 726 |  | 
|  | 727 | SensorService::SensorEventConnection::SensorEventConnection( | 
| Mathias Agopian | 5307d17 | 2012-09-18 17:02:43 -0700 | [diff] [blame] | 728 | const sp<SensorService>& service, uid_t uid) | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 729 | : mService(service), mUid(uid) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 730 | { | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 731 | const SensorDevice& device(SensorDevice::getInstance()); | 
|  | 732 | if (device.getHalDeviceVersion() >= SENSORS_DEVICE_API_VERSION_1_1) { | 
|  | 733 | // Increase socket buffer size to 1MB for batching capabilities. | 
|  | 734 | mChannel = new BitTube(service->mSocketBufferSize); | 
|  | 735 | } else { | 
|  | 736 | mChannel = new BitTube(SOCKET_BUFFER_SIZE_NON_BATCHED); | 
|  | 737 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 738 | } | 
|  | 739 |  | 
|  | 740 | SensorService::SensorEventConnection::~SensorEventConnection() | 
|  | 741 | { | 
| Steve Block | a551237 | 2011-12-20 16:23:08 +0000 | [diff] [blame] | 742 | ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 743 | mService->cleanupConnection(this); | 
|  | 744 | } | 
|  | 745 |  | 
|  | 746 | void SensorService::SensorEventConnection::onFirstRef() | 
|  | 747 | { | 
|  | 748 | } | 
|  | 749 |  | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 750 | void SensorService::SensorEventConnection::dump(String8& result) { | 
|  | 751 | Mutex::Autolock _l(mConnectionLock); | 
|  | 752 | for (size_t i = 0; i < mSensorInfo.size(); ++i) { | 
|  | 753 | const FlushInfo& flushInfo = mSensorInfo.valueAt(i); | 
|  | 754 | result.appendFormat("\t %s | status: %s | pending flush events %d\n", | 
|  | 755 | mService->getSensorName(mSensorInfo.keyAt(i)).string(), | 
|  | 756 | flushInfo.mFirstFlushPending ? "First flush pending" : | 
|  | 757 | "active", | 
|  | 758 | flushInfo.mPendingFlushEventsToSend); | 
|  | 759 | } | 
|  | 760 | } | 
|  | 761 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 762 | bool SensorService::SensorEventConnection::addSensor(int32_t handle) { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 763 | Mutex::Autolock _l(mConnectionLock); | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 764 | if (mSensorInfo.indexOfKey(handle) < 0) { | 
|  | 765 | mSensorInfo.add(handle, FlushInfo()); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 766 | return true; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 767 | } | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 768 | return false; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 769 | } | 
|  | 770 |  | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 771 | bool SensorService::SensorEventConnection::removeSensor(int32_t handle) { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 772 | Mutex::Autolock _l(mConnectionLock); | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 773 | if (mSensorInfo.removeItem(handle) >= 0) { | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 774 | return true; | 
|  | 775 | } | 
|  | 776 | return false; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 777 | } | 
|  | 778 |  | 
|  | 779 | bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 780 | Mutex::Autolock _l(mConnectionLock); | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 781 | return mSensorInfo.indexOfKey(handle) >= 0; | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 782 | } | 
|  | 783 |  | 
|  | 784 | bool SensorService::SensorEventConnection::hasAnySensor() const { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 785 | Mutex::Autolock _l(mConnectionLock); | 
| Mathias Agopian | 7c1c531 | 2010-07-21 15:59:50 -0700 | [diff] [blame] | 786 | return mSensorInfo.size() ? true : false; | 
|  | 787 | } | 
|  | 788 |  | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 789 | void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle, | 
|  | 790 | bool value) { | 
|  | 791 | Mutex::Autolock _l(mConnectionLock); | 
|  | 792 | ssize_t index = mSensorInfo.indexOfKey(handle); | 
|  | 793 | if (index >= 0) { | 
|  | 794 | FlushInfo& flushInfo = mSensorInfo.editValueAt(index); | 
|  | 795 | flushInfo.mFirstFlushPending = value; | 
|  | 796 | } | 
|  | 797 | } | 
|  | 798 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 799 | status_t SensorService::SensorEventConnection::sendEvents( | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame] | 800 | sensors_event_t const* buffer, size_t numEvents, | 
|  | 801 | sensors_event_t* scratch) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 802 | { | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame] | 803 | // filter out events not for this connection | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 804 | size_t count = 0; | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 805 |  | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 806 | if (scratch) { | 
| Mathias Agopian | 71d7a5c | 2010-11-14 20:55:25 -0800 | [diff] [blame] | 807 | Mutex::Autolock _l(mConnectionLock); | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 808 | size_t i=0; | 
|  | 809 | while (i<numEvents) { | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 810 | int32_t curr = buffer[i].sensor; | 
|  | 811 | if (buffer[i].type == SENSOR_TYPE_META_DATA) { | 
|  | 812 | ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ", | 
|  | 813 | buffer[i].meta_data.sensor); | 
|  | 814 | // Setting curr to the correct sensor to ensure the sensor events per connection are | 
|  | 815 | // filtered correctly. buffer[i].sensor is zero for meta_data events. | 
|  | 816 | curr = buffer[i].meta_data.sensor; | 
|  | 817 | } | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 818 | ssize_t index = mSensorInfo.indexOfKey(curr); | 
|  | 819 | if (index >= 0 && mSensorInfo[index].mFirstFlushPending == true && | 
|  | 820 | buffer[i].type == SENSOR_TYPE_META_DATA) { | 
|  | 821 | // This is the first flush before activate is called. Events can now be sent for | 
|  | 822 | // this sensor on this connection. | 
|  | 823 | ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ", | 
|  | 824 | buffer[i].meta_data.sensor); | 
|  | 825 | mSensorInfo.editValueAt(index).mFirstFlushPending = false; | 
|  | 826 | } | 
|  | 827 | if (index >= 0 && mSensorInfo[index].mFirstFlushPending == false)  { | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 828 | do { | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 829 | scratch[count++] = buffer[i++]; | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 830 | } while ((i<numEvents) && ((buffer[i].sensor == curr) || | 
|  | 831 | (buffer[i].type == SENSOR_TYPE_META_DATA  && | 
|  | 832 | buffer[i].meta_data.sensor == curr))); | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 833 | } else { | 
|  | 834 | i++; | 
|  | 835 | } | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame] | 836 | } | 
| Mathias Agopian | 3560fb2 | 2010-07-22 21:24:39 -0700 | [diff] [blame] | 837 | } else { | 
|  | 838 | scratch = const_cast<sensors_event_t *>(buffer); | 
|  | 839 | count = numEvents; | 
| Mathias Agopian | cf51001 | 2010-07-22 16:18:10 -0700 | [diff] [blame] | 840 | } | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 841 |  | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 842 | // Send pending flush events (if any) before sending events from the cache. | 
|  | 843 | { | 
|  | 844 | ASensorEvent flushCompleteEvent; | 
|  | 845 | flushCompleteEvent.type = SENSOR_TYPE_META_DATA; | 
|  | 846 | flushCompleteEvent.sensor = 0; | 
|  | 847 | Mutex::Autolock _l(mConnectionLock); | 
|  | 848 | // Loop through all the sensors for this connection and check if there are any pending | 
|  | 849 | // flush complete events to be sent. | 
|  | 850 | for (size_t i = 0; i < mSensorInfo.size(); ++i) { | 
|  | 851 | FlushInfo& flushInfo = mSensorInfo.editValueAt(i); | 
|  | 852 | while (flushInfo.mPendingFlushEventsToSend > 0) { | 
|  | 853 | flushCompleteEvent.meta_data.sensor = mSensorInfo.keyAt(i); | 
|  | 854 | ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1); | 
|  | 855 | if (size < 0) { | 
|  | 856 | // ALOGW("dropping %d events on the floor", count); | 
| Aravind Akella | c551eac | 2013-10-14 17:04:42 -0700 | [diff] [blame] | 857 | countFlushCompleteEventsLocked(scratch, count); | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 858 | return size; | 
|  | 859 | } | 
|  | 860 | ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ", | 
|  | 861 | flushCompleteEvent.meta_data.sensor); | 
|  | 862 | flushInfo.mPendingFlushEventsToSend--; | 
|  | 863 | } | 
|  | 864 | } | 
|  | 865 | } | 
|  | 866 |  | 
| Aravind Akella | b4099e7 | 2013-10-15 15:43:10 -0700 | [diff] [blame] | 867 | // Early return if there are no events for this connection. | 
|  | 868 | if (count == 0) { | 
|  | 869 | return status_t(NO_ERROR); | 
|  | 870 | } | 
|  | 871 |  | 
| Mathias Agopian | 907103b | 2012-04-02 18:38:02 -0700 | [diff] [blame] | 872 | // NOTE: ASensorEvent and sensors_event_t are the same type | 
|  | 873 | ssize_t size = SensorEventQueue::write(mChannel, | 
|  | 874 | reinterpret_cast<ASensorEvent const*>(scratch), count); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 875 | if (size == -EAGAIN) { | 
|  | 876 | // the destination doesn't accept events anymore, it's probably | 
|  | 877 | // full. For now, we just drop the events on the floor. | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 878 | // ALOGW("dropping %d events on the floor", count); | 
| Aravind Akella | c551eac | 2013-10-14 17:04:42 -0700 | [diff] [blame] | 879 | Mutex::Autolock _l(mConnectionLock); | 
|  | 880 | countFlushCompleteEventsLocked(scratch, count); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 881 | return size; | 
|  | 882 | } | 
|  | 883 |  | 
| Jeff Brown | 1e0b1e8 | 2010-09-13 23:17:30 -0700 | [diff] [blame] | 884 | return size < 0 ? status_t(size) : status_t(NO_ERROR); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 885 | } | 
|  | 886 |  | 
| Aravind Akella | c551eac | 2013-10-14 17:04:42 -0700 | [diff] [blame] | 887 | void SensorService::SensorEventConnection::countFlushCompleteEventsLocked( | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 888 | sensors_event_t* scratch, const int numEventsDropped) { | 
|  | 889 | ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped); | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 890 | // Count flushComplete events in the events that are about to the dropped. These will be sent | 
|  | 891 | // separately before the next batch of events. | 
|  | 892 | for (int j = 0; j < numEventsDropped; ++j) { | 
|  | 893 | if (scratch[j].type == SENSOR_TYPE_META_DATA) { | 
|  | 894 | FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor); | 
|  | 895 | flushInfo.mPendingFlushEventsToSend++; | 
|  | 896 | ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d", | 
|  | 897 | flushInfo.mPendingFlushEventsToSend); | 
|  | 898 | } | 
|  | 899 | } | 
|  | 900 | return; | 
|  | 901 | } | 
|  | 902 |  | 
| Mathias Agopian | b398927 | 2011-10-20 18:42:02 -0700 | [diff] [blame] | 903 | sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 904 | { | 
|  | 905 | return mChannel; | 
|  | 906 | } | 
|  | 907 |  | 
|  | 908 | status_t SensorService::SensorEventConnection::enableDisable( | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 909 | int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, | 
|  | 910 | int reservedFlags) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 911 | { | 
|  | 912 | status_t err; | 
|  | 913 | if (enabled) { | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 914 | err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs, | 
|  | 915 | reservedFlags); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 916 | } else { | 
|  | 917 | err = mService->disable(this, handle); | 
|  | 918 | } | 
|  | 919 | return err; | 
|  | 920 | } | 
|  | 921 |  | 
|  | 922 | status_t SensorService::SensorEventConnection::setEventRate( | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 923 | int handle, nsecs_t samplingPeriodNs) | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 924 | { | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 925 | return mService->setEventRate(this, handle, samplingPeriodNs); | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 926 | } | 
|  | 927 |  | 
| Aravind Akella | 701166d | 2013-10-08 14:59:26 -0700 | [diff] [blame] | 928 | status_t  SensorService::SensorEventConnection::flush() { | 
| Aravind Akella | c551eac | 2013-10-14 17:04:42 -0700 | [diff] [blame] | 929 | SensorDevice& dev(SensorDevice::getInstance()); | 
|  | 930 | const int halVersion = dev.getHalDeviceVersion(); | 
| Aravind Akella | 701166d | 2013-10-08 14:59:26 -0700 | [diff] [blame] | 931 | Mutex::Autolock _l(mConnectionLock); | 
|  | 932 | status_t err(NO_ERROR); | 
| Aravind Akella | c551eac | 2013-10-14 17:04:42 -0700 | [diff] [blame] | 933 | // Loop through all sensors for this connection and call flush on each of them. | 
| Aravind Akella | 701166d | 2013-10-08 14:59:26 -0700 | [diff] [blame] | 934 | for (size_t i = 0; i < mSensorInfo.size(); ++i) { | 
|  | 935 | const int handle = mSensorInfo.keyAt(i); | 
| Aravind Akella | b4099e7 | 2013-10-15 15:43:10 -0700 | [diff] [blame] | 936 | if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || mService->isVirtualSensor(handle)) { | 
| Aravind Akella | c551eac | 2013-10-14 17:04:42 -0700 | [diff] [blame] | 937 | // For older devices just increment pending flush count which will send a trivial | 
|  | 938 | // flush complete event. | 
|  | 939 | FlushInfo& flushInfo = mSensorInfo.editValueFor(handle); | 
|  | 940 | flushInfo.mPendingFlushEventsToSend++; | 
|  | 941 | } else { | 
|  | 942 | status_t err_flush = mService->flushSensor(this, handle); | 
|  | 943 | if (err_flush != NO_ERROR) { | 
|  | 944 | ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush)); | 
|  | 945 | } | 
|  | 946 | err = (err_flush != NO_ERROR) ? err_flush : err; | 
| Aravind Akella | 701166d | 2013-10-08 14:59:26 -0700 | [diff] [blame] | 947 | } | 
| Aravind Akella | 701166d | 2013-10-08 14:59:26 -0700 | [diff] [blame] | 948 | } | 
|  | 949 | return err; | 
| Aravind Akella | 724d91d | 2013-06-27 12:04:23 -0700 | [diff] [blame] | 950 | } | 
| Aravind Akella | 4c8b951 | 2013-09-05 17:03:38 -0700 | [diff] [blame] | 951 |  | 
| Mathias Agopian | fc32881 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 952 | // --------------------------------------------------------------------------- | 
|  | 953 | }; // namespace android | 
|  | 954 |  |