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