blob: 3b64f0a8bc66cacfe707ee27d745746758e52253 [file] [log] [blame]
Mathias Agopianf001c922010-11-11 17:58:51 -08001/*
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"
Mathias Agopiana1b7db92011-05-27 16:23:58 -070032#include "SensorService.h"
Mathias Agopianf001c922010-11-11 17:58:51 -080033
34namespace android {
35// ---------------------------------------------------------------------------
Mathias Agopianf001c922010-11-11 17:58:51 -080036
37ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
38
39SensorDevice::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
Steve Blockf5a12302012-01-06 19:20:56 +000046 ALOGE_IF(err, "couldn't load %s module (%s)",
Mathias Agopianf001c922010-11-11 17:58:51 -080047 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
48
49 if (mSensorModule) {
Aravind Akella724d91d2013-06-27 12:04:23 -070050 err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
Mathias Agopianf001c922010-11-11 17:58:51 -080051
Steve Blockf5a12302012-01-06 19:20:56 +000052 ALOGE_IF(err, "couldn't open device for module %s (%s)",
Mathias Agopianf001c922010-11-11 17:58:51 -080053 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);
Aravind Akella724d91d2013-06-27 12:04:23 -070062 mSensorDevice->activate(
63 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
64 list[i].handle, 0);
Mathias Agopianf001c922010-11-11 17:58:51 -080065 }
66 }
67 }
68}
69
Mathias Agopianba02cd22013-07-03 16:20:57 -070070void SensorDevice::dump(String8& result)
Mathias Agopianf001c922010-11-11 17:58:51 -080071{
72 if (!mSensorModule) return;
73 sensor_t const* list;
74 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
75
Mathias Agopianba02cd22013-07-03 16:20:57 -070076 result.appendFormat("%d h/w sensors:\n", int(count));
Mathias Agopianf001c922010-11-11 17:58:51 -080077
78 Mutex::Autolock _l(mLock);
79 for (size_t i=0 ; i<size_t(count) ; i++) {
Mathias Agopian667102f2011-09-14 16:43:34 -070080 const Info& info = mActivationCount.valueFor(list[i].handle);
Mark Salyzyn92dc3fc2014-03-12 13:12:44 -070081 result.appendFormat("handle=0x%08x, active-count=%zu, batch_period(ms)={ ", list[i].handle,
Aravind Akella724d91d2013-06-27 12:04:23 -070082 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 ? ", " : "");
Mathias Agopian667102f2011-09-14 16:43:34 -070087 }
Aravind Akella724d91d2013-06-27 12:04:23 -070088 result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchDelay / 1e6f);
89
Mark Salyzyn92dc3fc2014-03-12 13:12:44 -070090 result.appendFormat("handle=0x%08x, active-count=%zu, batch_timeout(ms)={ ", list[i].handle,
Aravind Akella724d91d2013-06-27 12:04:23 -070091 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);
Mathias Agopianf001c922010-11-11 17:58:51 -080098 }
99}
100
101ssize_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
107status_t SensorDevice::initCheck() const {
108 return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
109}
110
111ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
112 if (!mSensorDevice) return NO_INIT;
Mathias Agopian1a623012011-11-09 17:50:15 -0800113 ssize_t c;
114 do {
Aravind Akella724d91d2013-06-27 12:04:23 -0700115 c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
116 buffer, count);
Mathias Agopian1a623012011-11-09 17:50:15 -0800117 } while (c == -EINTR);
118 return c;
Mathias Agopianf001c922010-11-11 17:58:51 -0800119}
120
Mathias Agopianac9a96d2013-07-12 02:01:16 -0700121void SensorDevice::autoDisable(void *ident, int handle) {
122 Info& info( mActivationCount.editValueFor(handle) );
Jaikumar Ganesh4c01b1a2013-04-16 15:52:23 -0700123 Mutex::Autolock _l(mLock);
Aravind Akella724d91d2013-06-27 12:04:23 -0700124 info.removeBatchParamsForIdent(ident);
Jaikumar Ganesh4c01b1a2013-04-16 15:52:23 -0700125}
126
Mathias Agopianf001c922010-11-11 17:58:51 -0800127status_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
Aravind Akella724d91d2013-06-27 12:04:23 -0700133 Mutex::Autolock _l(mLock);
Mathias Agopianf001c922010-11-11 17:58:51 -0800134 Info& info( mActivationCount.editValueFor(handle) );
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700135
Steve Blocka5512372011-12-20 16:23:08 +0000136 ALOGD_IF(DEBUG_CONNECTIONS,
Aravind Akella724d91d2013-06-27 12:04:23 -0700137 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
138 ident, handle, enabled, info.batchParams.size());
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700139
Mathias Agopianf001c922010-11-11 17:58:51 -0800140 if (enabled) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700141 ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%d", info.batchParams.indexOfKey(ident));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700142
Aravind Akella724d91d2013-06-27 12:04:23 -0700143 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 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800148 } else {
Aravind Akella724d91d2013-06-27 12:04:23 -0700149 // Log error. Every activate call should be preceded by a batch() call.
150 ALOGE("\t >>>ERROR: activate called without batch");
Mathias Agopianf001c922010-11-11 17:58:51 -0800151 }
152 } else {
Aravind Akella724d91d2013-06-27 12:04:23 -0700153 ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%d", info.batchParams.indexOfKey(ident));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700154
Aravind Akella724d91d2013-06-27 12:04:23 -0700155 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.
Mathias Agopian50b66762010-11-29 17:26:51 -0800158 actuateHardware = true;
Aravind Akella724d91d2013-06-27 12:04:23 -0700159 } 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 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800173 }
174 } else {
175 // sensor wasn't enabled for this ident
176 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800177 }
Mathias Agopian50b66762010-11-29 17:26:51 -0800178
Mathias Agopianf001c922010-11-11 17:58:51 -0800179 if (actuateHardware) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700180 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));
Mathias Agopiana1b7db92011-05-27 16:23:58 -0700185
Aravind Akella724d91d2013-06-27 12:04:23 -0700186 if (err != NO_ERROR && enabled) {
187 // Failure when enabling the sensor. Clean up on failure.
188 info.removeBatchParamsForIdent(ident);
Mathias Agopianac9a96d2013-07-12 02:01:16 -0700189 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800190 }
191
Aravind Akella724d91d2013-06-27 12:04:23 -0700192 // 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);
Mathias Agopianf001c922010-11-11 17:58:51 -0800199 }
Mathias Agopianf001c922010-11-11 17:58:51 -0800200 return err;
201}
202
Aravind Akella724d91d2013-06-27 12:04:23 -0700203status_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
282status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs)
Mathias Agopianf001c922010-11-11 17:58:51 -0800283{
284 if (!mSensorDevice) return NO_INIT;
Aravind Akella724d91d2013-06-27 12:04:23 -0700285 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
286 samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
287 }
Mathias Agopian667102f2011-09-14 16:43:34 -0700288 Mutex::Autolock _l(mLock);
Mathias Agopianf001c922010-11-11 17:58:51 -0800289 Info& info( mActivationCount.editValueFor(handle) );
Aravind Akella724d91d2013-06-27 12:04:23 -0700290 // 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);
Mathias Agopian667102f2011-09-14 16:43:34 -0700304}
305
Jaikumar Ganesh4342fdf2013-04-08 16:43:12 -0700306int SensorDevice::getHalDeviceVersion() const {
307 if (!mSensorDevice) return -1;
308
309 return mSensorDevice->common.version;
310}
311
Mark Salyzyn92dc3fc2014-03-12 13:12:44 -0700312status_t SensorDevice::flush(void* /*ident*/, int handle) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700313 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
Mathias Agopian667102f2011-09-14 16:43:34 -0700320// ---------------------------------------------------------------------------
321
Aravind Akella724d91d2013-06-27 12:04:23 -0700322status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
323 int64_t samplingPeriodNs,
324 int64_t maxBatchReportLatencyNs) {
325 ssize_t index = batchParams.indexOfKey(ident);
Mathias Agopian667102f2011-09-14 16:43:34 -0700326 if (index < 0) {
Aravind Akella724d91d2013-06-27 12:04:23 -0700327 ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%lld timeout=%lld) failed (%s)",
328 ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
Mathias Agopian667102f2011-09-14 16:43:34 -0700329 return BAD_INDEX;
330 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700331 BatchParams& params = batchParams.editValueAt(index);
332 params.flags = flags;
333 params.batchDelay = samplingPeriodNs;
334 params.batchTimeout = maxBatchReportLatencyNs;
Mathias Agopian667102f2011-09-14 16:43:34 -0700335 return NO_ERROR;
336}
337
Aravind Akella724d91d2013-06-27 12:04:23 -0700338void 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;
Mathias Agopianf001c922010-11-11 17:58:51 -0800353 }
354 }
Aravind Akella724d91d2013-06-27 12:04:23 -0700355 bestBatchParams = bestParams;
356}
357
358ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
359 ssize_t idx = batchParams.removeItem(ident);
360 if (idx >= 0) {
361 selectBatchParams();
362 }
363 return idx;
Mathias Agopianf001c922010-11-11 17:58:51 -0800364}
365
366// ---------------------------------------------------------------------------
367}; // namespace android
368