1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdint.h> 18 #include <math.h> 19 #include <sys/types.h> 20 21 #include <utils/Atomic.h> 22 #include <utils/Errors.h> 23 #include <utils/Singleton.h> 24 25 #include <binder/BinderService.h> 26 #include <binder/Parcel.h> 27 #include <binder/IServiceManager.h> 28 29 #include <hardware/sensors.h> 30 31 #include "SensorDevice.h" 32 #include "SensorService.h" 33 34 namespace android { 35 // --------------------------------------------------------------------------- 36 37 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice) 38 39 SensorDevice::SensorDevice() 40 : mSensorDevice(0), 41 mSensorModule(0) 42 { 43 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, 44 (hw_module_t const**)&mSensorModule); 45 46 ALOGE_IF(err, "couldn't load %s module (%s)", 47 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 48 49 if (mSensorModule) { 50 err = sensors_open_1(&mSensorModule->common, &mSensorDevice); 51 52 ALOGE_IF(err, "couldn't open device for module %s (%s)", 53 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 54 55 if (mSensorDevice) { 56 sensor_t const* list; 57 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); 58 mActivationCount.setCapacity(count); 59 Info model; 60 for (size_t i=0 ; i<size_t(count) ; i++) { 61 mActivationCount.add(list[i].handle, model); 62 mSensorDevice->activate( 63 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), 64 list[i].handle, 0); 65 } 66 } 67 } 68 } 69 70 void SensorDevice::dump(String8& result) 71 { 72 if (!mSensorModule) return; 73 sensor_t const* list; 74 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); 75 76 result.appendFormat("%d h/w sensors:\n", int(count)); 77 78 Mutex::Autolock _l(mLock); 79 for (size_t i=0 ; i<size_t(count) ; i++) { 80 const Info& info = mActivationCount.valueFor(list[i].handle); 81 result.appendFormat("handle=0x%08x, active-count=%d, batch_period(ms)={ ", list[i].handle, 82 info.batchParams.size()); 83 for (size_t j = 0; j < info.batchParams.size(); j++) { 84 BatchParams params = info.batchParams.valueAt(j); 85 result.appendFormat("%4.1f%s", params.batchDelay / 1e6f, 86 j < info.batchParams.size() - 1 ? ", " : ""); 87 } 88 result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchDelay / 1e6f); 89 90 result.appendFormat("handle=0x%08x, active-count=%d, batch_timeout(ms)={ ", list[i].handle, 91 info.batchParams.size()); 92 for (size_t j = 0; j < info.batchParams.size(); j++) { 93 BatchParams params = info.batchParams.valueAt(j); 94 result.appendFormat("%4.1f%s", params.batchTimeout / 1e6f, 95 j < info.batchParams.size() - 1 ? ", " : ""); 96 } 97 result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f); 98 } 99 } 100 101 ssize_t SensorDevice::getSensorList(sensor_t const** list) { 102 if (!mSensorModule) return NO_INIT; 103 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list); 104 return count; 105 } 106 107 status_t SensorDevice::initCheck() const { 108 return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT; 109 } 110 111 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) { 112 if (!mSensorDevice) return NO_INIT; 113 ssize_t c; 114 do { 115 c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), 116 buffer, count); 117 } while (c == -EINTR); 118 return c; 119 } 120 121 void SensorDevice::autoDisable(void *ident, int handle) { 122 Info& info( mActivationCount.editValueFor(handle) ); 123 Mutex::Autolock _l(mLock); 124 info.removeBatchParamsForIdent(ident); 125 } 126 127 status_t SensorDevice::activate(void* ident, int handle, int enabled) 128 { 129 if (!mSensorDevice) return NO_INIT; 130 status_t err(NO_ERROR); 131 bool actuateHardware = false; 132 133 Mutex::Autolock _l(mLock); 134 Info& info( mActivationCount.editValueFor(handle) ); 135 136 ALOGD_IF(DEBUG_CONNECTIONS, 137 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d", 138 ident, handle, enabled, info.batchParams.size()); 139 140 if (enabled) { 141 ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%d", info.batchParams.indexOfKey(ident)); 142 143 if (info.batchParams.indexOfKey(ident) >= 0) { 144 if (info.batchParams.size() == 1) { 145 // This is the first connection, we need to activate the underlying h/w sensor. 146 actuateHardware = true; 147 } 148 } else { 149 // Log error. Every activate call should be preceded by a batch() call. 150 ALOGE("\t >>>ERROR: activate called without batch"); 151 } 152 } else { 153 ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%d", info.batchParams.indexOfKey(ident)); 154 155 if (info.removeBatchParamsForIdent(ident) >= 0) { 156 if (info.batchParams.size() == 0) { 157 // This is the last connection, we need to de-activate the underlying h/w sensor. 158 actuateHardware = true; 159 } else { 160 const int halVersion = getHalDeviceVersion(); 161 if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { 162 // Call batch for this sensor with the previously calculated best effort 163 // batch_rate and timeout. One of the apps has unregistered for sensor 164 // events, and the best effort batch parameters might have changed. 165 ALOGD_IF(DEBUG_CONNECTIONS, 166 "\t>>> actuating h/w batch %d %d %lld %lld ", handle, 167 info.bestBatchParams.flags, info.bestBatchParams.batchDelay, 168 info.bestBatchParams.batchTimeout); 169 mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags, 170 info.bestBatchParams.batchDelay, 171 info.bestBatchParams.batchTimeout); 172 } 173 } 174 } else { 175 // sensor wasn't enabled for this ident 176 } 177 } 178 179 if (actuateHardware) { 180 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, enabled); 181 err = mSensorDevice->activate( 182 reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled); 183 ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle, 184 strerror(-err)); 185 186 if (err != NO_ERROR && enabled) { 187 // Failure when enabling the sensor. Clean up on failure. 188 info.removeBatchParamsForIdent(ident); 189 } 190 } 191 192 // On older devices which do not support batch, call setDelay(). 193 if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.batchParams.size() > 0) { 194 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %lld ", handle, 195 info.bestBatchParams.batchDelay); 196 mSensorDevice->setDelay( 197 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), 198 handle, info.bestBatchParams.batchDelay); 199 } 200 return err; 201 } 202 203 status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs, 204 int64_t maxBatchReportLatencyNs) { 205 if (!mSensorDevice) return NO_INIT; 206 207 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) { 208 samplingPeriodNs = MINIMUM_EVENTS_PERIOD; 209 } 210 211 const int halVersion = getHalDeviceVersion(); 212 if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { 213 if (flags & SENSORS_BATCH_DRY_RUN) { 214 return mSensorDevice->batch(mSensorDevice, handle, flags, samplingPeriodNs, 215 maxBatchReportLatencyNs); 216 } else { 217 // Call h/w with dry run to see if the given parameters are feasible or not. Return if 218 // there is an error. 219 status_t errDryRun(NO_ERROR); 220 errDryRun = mSensorDevice->batch(mSensorDevice, handle, flags | SENSORS_BATCH_DRY_RUN, 221 samplingPeriodNs, maxBatchReportLatencyNs); 222 if (errDryRun != NO_ERROR) { 223 ALOGD_IF(DEBUG_CONNECTIONS, "SensorDevice::batch dry run error %s", 224 strerror(-errDryRun)); 225 return errDryRun; 226 } 227 } 228 } else if (maxBatchReportLatencyNs != 0) { 229 // Batch is not supported on older devices. 230 return INVALID_OPERATION; 231 } 232 233 ALOGD_IF(DEBUG_CONNECTIONS, 234 "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%lld timeout=%lld", 235 ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs); 236 237 Mutex::Autolock _l(mLock); 238 Info& info(mActivationCount.editValueFor(handle)); 239 240 if (info.batchParams.indexOfKey(ident) < 0) { 241 BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs); 242 info.batchParams.add(ident, params); 243 } else { 244 // A batch has already been called with this ident. Update the batch parameters. 245 info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs); 246 } 247 248 BatchParams prevBestBatchParams = info.bestBatchParams; 249 // Find the minimum of all timeouts and batch_rates for this sensor. 250 info.selectBatchParams(); 251 252 ALOGD_IF(DEBUG_CONNECTIONS, 253 "\t>>> curr_period=%lld min_period=%lld curr_timeout=%lld min_timeout=%lld", 254 prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay, 255 prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout); 256 257 status_t err(NO_ERROR); 258 // If the min period or min timeout has changed since the last batch call, call batch. 259 if (prevBestBatchParams != info.bestBatchParams) { 260 if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { 261 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %lld %lld ", handle, 262 info.bestBatchParams.flags, info.bestBatchParams.batchDelay, 263 info.bestBatchParams.batchTimeout); 264 err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags, 265 info.bestBatchParams.batchDelay, 266 info.bestBatchParams.batchTimeout); 267 } else { 268 // For older devices which do not support batch, call setDelay() after activate() is 269 // called. Some older devices may not support calling setDelay before activate(), so 270 // call setDelay in SensorDevice::activate() method. 271 } 272 if (err != NO_ERROR) { 273 ALOGE("sensor batch failed %p %d %d %lld %lld err=%s", mSensorDevice, handle, 274 info.bestBatchParams.flags, info.bestBatchParams.batchDelay, 275 info.bestBatchParams.batchTimeout, strerror(-err)); 276 info.removeBatchParamsForIdent(ident); 277 } 278 } 279 return err; 280 } 281 282 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) 283 { 284 if (!mSensorDevice) return NO_INIT; 285 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) { 286 samplingPeriodNs = MINIMUM_EVENTS_PERIOD; 287 } 288 Mutex::Autolock _l(mLock); 289 Info& info( mActivationCount.editValueFor(handle) ); 290 // If the underlying sensor is NOT in continuous mode, setDelay() should return an error. 291 // Calling setDelay() in batch mode is an invalid operation. 292 if (info.bestBatchParams.batchTimeout != 0) { 293 return INVALID_OPERATION; 294 } 295 ssize_t index = info.batchParams.indexOfKey(ident); 296 if (index < 0) { 297 return BAD_INDEX; 298 } 299 BatchParams& params = info.batchParams.editValueAt(index); 300 params.batchDelay = samplingPeriodNs; 301 info.selectBatchParams(); 302 return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), 303 handle, info.bestBatchParams.batchDelay); 304 } 305 306 int SensorDevice::getHalDeviceVersion() const { 307 if (!mSensorDevice) return -1; 308 309 return mSensorDevice->common.version; 310 } 311 312 status_t SensorDevice::flush(void* ident, int handle) { 313 if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) { 314 return INVALID_OPERATION; 315 } 316 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle); 317 return mSensorDevice->flush(mSensorDevice, handle); 318 } 319 320 // --------------------------------------------------------------------------- 321 322 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags, 323 int64_t samplingPeriodNs, 324 int64_t maxBatchReportLatencyNs) { 325 ssize_t index = batchParams.indexOfKey(ident); 326 if (index < 0) { 327 ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%lld timeout=%lld) failed (%s)", 328 ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index)); 329 return BAD_INDEX; 330 } 331 BatchParams& params = batchParams.editValueAt(index); 332 params.flags = flags; 333 params.batchDelay = samplingPeriodNs; 334 params.batchTimeout = maxBatchReportLatencyNs; 335 return NO_ERROR; 336 } 337 338 void SensorDevice::Info::selectBatchParams() { 339 BatchParams bestParams(-1, -1, -1); 340 341 if (batchParams.size() > 0) { 342 BatchParams params = batchParams.valueAt(0); 343 bestParams = params; 344 } 345 346 for (size_t i = 1; i < batchParams.size(); ++i) { 347 BatchParams params = batchParams.valueAt(i); 348 if (params.batchDelay < bestParams.batchDelay) { 349 bestParams.batchDelay = params.batchDelay; 350 } 351 if (params.batchTimeout < bestParams.batchTimeout) { 352 bestParams.batchTimeout = params.batchTimeout; 353 } 354 } 355 bestBatchParams = bestParams; 356 } 357 358 ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) { 359 ssize_t idx = batchParams.removeItem(ident); 360 if (idx >= 0) { 361 selectBatchParams(); 362 } 363 return idx; 364 } 365 366 // --------------------------------------------------------------------------- 367 }; // namespace android 368 369