• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)38 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
39 
40 SensorDevice::SensorDevice()
41     :  mSensorDevice(0),
42        mSensorModule(0) {
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             if (mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_1 ||
57                 mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_2) {
58                 ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3");
59             }
60 
61             sensor_t const* list;
62             ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
63             mActivationCount.setCapacity(count);
64             Info model;
65             for (size_t i=0 ; i<size_t(count) ; i++) {
66                 mActivationCount.add(list[i].handle, model);
67                 mSensorDevice->activate(
68                         reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
69                         list[i].handle, 0);
70             }
71         }
72     }
73 }
74 
handleDynamicSensorConnection(int handle,bool connected)75 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
76     if (connected) {
77         Info model;
78         mActivationCount.add(handle, model);
79         mSensorDevice->activate(
80                 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, 0);
81     } else {
82         mActivationCount.removeItem(handle);
83     }
84 }
85 
dump() const86 std::string SensorDevice::dump() const {
87     if (!mSensorModule) return "HAL not initialized\n";
88 
89     String8 result;
90     sensor_t const* list;
91     int count = mSensorModule->get_sensors_list(mSensorModule, &list);
92 
93     result.appendFormat("HAL: %s (%s), version %#010x\n",
94                         mSensorModule->common.name,
95                         mSensorModule->common.author,
96                         getHalDeviceVersion());
97     result.appendFormat("Total %d h/w sensors, %zu running:\n", count, mActivationCount.size());
98 
99     Mutex::Autolock _l(mLock);
100     for (int i = 0 ; i < count ; i++) {
101         const Info& info = mActivationCount.valueFor(list[i].handle);
102         if (info.batchParams.isEmpty()) continue;
103         result.appendFormat("0x%08x) active-count = %zu; ", list[i].handle,
104                             info.batchParams.size());
105 
106         result.append("sampling_period(ms) = {");
107         for (size_t j = 0; j < info.batchParams.size(); j++) {
108             const BatchParams& params = info.batchParams.valueAt(j);
109             result.appendFormat("%.1f%s", params.batchDelay / 1e6f,
110                                 j < info.batchParams.size() - 1 ? ", " : "");
111         }
112         result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f);
113 
114         result.append("batching_period(ms) = {");
115         for (size_t j = 0; j < info.batchParams.size(); j++) {
116             BatchParams params = info.batchParams.valueAt(j);
117             result.appendFormat("%.1f%s", params.batchTimeout / 1e6f,
118                                 j < info.batchParams.size() - 1 ? ", " : "");
119         }
120         result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
121     }
122     return result.string();
123 }
124 
getSensorList(sensor_t const ** list)125 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
126     if (!mSensorModule) return NO_INIT;
127     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
128     return count;
129 }
130 
initCheck() const131 status_t SensorDevice::initCheck() const {
132     return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
133 }
134 
poll(sensors_event_t * buffer,size_t count)135 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
136     if (!mSensorDevice) return NO_INIT;
137     ssize_t c;
138     do {
139         c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
140                                 buffer, count);
141     } while (c == -EINTR);
142     return c;
143 }
144 
autoDisable(void * ident,int handle)145 void SensorDevice::autoDisable(void *ident, int handle) {
146     Info& info( mActivationCount.editValueFor(handle) );
147     Mutex::Autolock _l(mLock);
148     info.removeBatchParamsForIdent(ident);
149 }
150 
activate(void * ident,int handle,int enabled)151 status_t SensorDevice::activate(void* ident, int handle, int enabled) {
152     if (!mSensorDevice) return NO_INIT;
153     status_t err(NO_ERROR);
154     bool actuateHardware = false;
155 
156     Mutex::Autolock _l(mLock);
157     Info& info( mActivationCount.editValueFor(handle) );
158 
159     ALOGD_IF(DEBUG_CONNECTIONS,
160              "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
161              ident, handle, enabled, info.batchParams.size());
162 
163     if (enabled) {
164         ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
165 
166         if (isClientDisabledLocked(ident)) {
167             return INVALID_OPERATION;
168         }
169 
170         if (info.batchParams.indexOfKey(ident) >= 0) {
171           if (info.numActiveClients() == 1) {
172               // This is the first connection, we need to activate the underlying h/w sensor.
173               actuateHardware = true;
174           }
175         } else {
176             // Log error. Every activate call should be preceded by a batch() call.
177             ALOGE("\t >>>ERROR: activate called without batch");
178         }
179     } else {
180         ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
181 
182         if (info.removeBatchParamsForIdent(ident) >= 0) {
183             if (info.numActiveClients() == 0) {
184                 // This is the last connection, we need to de-activate the underlying h/w sensor.
185                 actuateHardware = true;
186             } else {
187                 const int halVersion = getHalDeviceVersion();
188                 if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
189                     // Call batch for this sensor with the previously calculated best effort
190                     // batch_rate and timeout. One of the apps has unregistered for sensor
191                     // events, and the best effort batch parameters might have changed.
192                     ALOGD_IF(DEBUG_CONNECTIONS,
193                              "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
194                              info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
195                              info.bestBatchParams.batchTimeout);
196                     mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
197                                          info.bestBatchParams.batchDelay,
198                                          info.bestBatchParams.batchTimeout);
199                 }
200             }
201         } else {
202             // sensor wasn't enabled for this ident
203         }
204 
205         if (isClientDisabledLocked(ident)) {
206             return NO_ERROR;
207         }
208     }
209 
210     if (actuateHardware) {
211         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
212                  enabled);
213         err = mSensorDevice->activate(
214                 reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
215         ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
216                  strerror(-err));
217 
218         if (err != NO_ERROR && enabled) {
219             // Failure when enabling the sensor. Clean up on failure.
220             info.removeBatchParamsForIdent(ident);
221         }
222     }
223 
224     // On older devices which do not support batch, call setDelay().
225     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.numActiveClients() > 0) {
226         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
227                  info.bestBatchParams.batchDelay);
228         mSensorDevice->setDelay(
229                 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
230                 handle, info.bestBatchParams.batchDelay);
231     }
232     return err;
233 }
234 
batch(void * ident,int handle,int flags,int64_t samplingPeriodNs,int64_t maxBatchReportLatencyNs)235 status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
236                              int64_t maxBatchReportLatencyNs) {
237     if (!mSensorDevice) return NO_INIT;
238 
239     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
240         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
241     }
242 
243     const int halVersion = getHalDeviceVersion();
244     if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 && maxBatchReportLatencyNs != 0) {
245         // Batch is not supported on older devices return invalid operation.
246         return INVALID_OPERATION;
247     }
248 
249     ALOGD_IF(DEBUG_CONNECTIONS,
250              "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
251              ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
252 
253     Mutex::Autolock _l(mLock);
254     Info& info(mActivationCount.editValueFor(handle));
255 
256     if (info.batchParams.indexOfKey(ident) < 0) {
257         BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
258         info.batchParams.add(ident, params);
259     } else {
260         // A batch has already been called with this ident. Update the batch parameters.
261         info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
262     }
263 
264     BatchParams prevBestBatchParams = info.bestBatchParams;
265     // Find the minimum of all timeouts and batch_rates for this sensor.
266     info.selectBatchParams();
267 
268     ALOGD_IF(DEBUG_CONNECTIONS,
269              "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
270              " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
271              prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
272              prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
273 
274     status_t err(NO_ERROR);
275     // If the min period or min timeout has changed since the last batch call, call batch.
276     if (prevBestBatchParams != info.bestBatchParams) {
277         if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
278             ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
279                      info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
280                      info.bestBatchParams.batchTimeout);
281             err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
282                                        info.bestBatchParams.batchDelay,
283                                        info.bestBatchParams.batchTimeout);
284         } else {
285             // For older devices which do not support batch, call setDelay() after activate() is
286             // called. Some older devices may not support calling setDelay before activate(), so
287             // call setDelay in SensorDevice::activate() method.
288         }
289         if (err != NO_ERROR) {
290             ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
291                   mSensorDevice, handle,
292                   info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
293                   info.bestBatchParams.batchTimeout, strerror(-err));
294             info.removeBatchParamsForIdent(ident);
295         }
296     }
297     return err;
298 }
299 
setDelay(void * ident,int handle,int64_t samplingPeriodNs)300 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
301     if (!mSensorDevice) return NO_INIT;
302     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
303         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
304     }
305     Mutex::Autolock _l(mLock);
306     if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
307     Info& info( mActivationCount.editValueFor(handle) );
308     // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
309     // Calling setDelay() in batch mode is an invalid operation.
310     if (info.bestBatchParams.batchTimeout != 0) {
311       return INVALID_OPERATION;
312     }
313     ssize_t index = info.batchParams.indexOfKey(ident);
314     if (index < 0) {
315         return BAD_INDEX;
316     }
317     BatchParams& params = info.batchParams.editValueAt(index);
318     params.batchDelay = samplingPeriodNs;
319     info.selectBatchParams();
320     return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
321                                    handle, info.bestBatchParams.batchDelay);
322 }
323 
getHalDeviceVersion() const324 int SensorDevice::getHalDeviceVersion() const {
325     if (!mSensorDevice) return -1;
326     return mSensorDevice->common.version;
327 }
328 
flush(void * ident,int handle)329 status_t SensorDevice::flush(void* ident, int handle) {
330     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
331         return INVALID_OPERATION;
332     }
333     if (isClientDisabled(ident)) return INVALID_OPERATION;
334     ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
335     return mSensorDevice->flush(mSensorDevice, handle);
336 }
337 
isClientDisabled(void * ident)338 bool SensorDevice::isClientDisabled(void* ident) {
339     Mutex::Autolock _l(mLock);
340     return isClientDisabledLocked(ident);
341 }
342 
isClientDisabledLocked(void * ident)343 bool SensorDevice::isClientDisabledLocked(void* ident) {
344     return mDisabledClients.indexOf(ident) >= 0;
345 }
346 
enableAllSensors()347 void SensorDevice::enableAllSensors() {
348     Mutex::Autolock _l(mLock);
349     mDisabledClients.clear();
350     const int halVersion = getHalDeviceVersion();
351     for (size_t i = 0; i< mActivationCount.size(); ++i) {
352         Info& info = mActivationCount.editValueAt(i);
353         if (info.batchParams.isEmpty()) continue;
354         info.selectBatchParams();
355         const int sensor_handle = mActivationCount.keyAt(i);
356         ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
357                    sensor_handle);
358         status_t err(NO_ERROR);
359         if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) {
360             err = mSensorDevice->batch(mSensorDevice, sensor_handle,
361                  info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
362                  info.bestBatchParams.batchTimeout);
363             ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
364         }
365 
366         if (err == NO_ERROR) {
367             err = mSensorDevice->activate(
368                     reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
369                     sensor_handle, 1);
370             ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
371         }
372 
373         if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0) {
374              err = mSensorDevice->setDelay(
375                     reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
376                     sensor_handle, info.bestBatchParams.batchDelay);
377              ALOGE_IF(err, "Error calling setDelay sensor %d (%s)", sensor_handle, strerror(-err));
378         }
379     }
380 }
381 
disableAllSensors()382 void SensorDevice::disableAllSensors() {
383     Mutex::Autolock _l(mLock);
384    for (size_t i = 0; i< mActivationCount.size(); ++i) {
385         const Info& info = mActivationCount.valueAt(i);
386         // Check if this sensor has been activated previously and disable it.
387         if (info.batchParams.size() > 0) {
388            const int sensor_handle = mActivationCount.keyAt(i);
389            ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
390                    sensor_handle);
391            mSensorDevice->activate(
392                    reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
393                    sensor_handle, 0);
394            // Add all the connections that were registered for this sensor to the disabled
395            // clients list.
396            for (size_t j = 0; j < info.batchParams.size(); ++j) {
397                mDisabledClients.add(info.batchParams.keyAt(j));
398            }
399         }
400     }
401 }
402 
injectSensorData(const sensors_event_t * injected_sensor_event)403 status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) {
404       ALOGD_IF(DEBUG_CONNECTIONS,
405               "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
406                injected_sensor_event->sensor,
407                injected_sensor_event->timestamp, injected_sensor_event->data[0],
408                injected_sensor_event->data[1], injected_sensor_event->data[2],
409                injected_sensor_event->data[3], injected_sensor_event->data[4],
410                injected_sensor_event->data[5]);
411       if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
412           return INVALID_OPERATION;
413       }
414       return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event);
415 }
416 
setMode(uint32_t mode)417 status_t SensorDevice::setMode(uint32_t mode) {
418      if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
419           return INVALID_OPERATION;
420      }
421      return mSensorModule->set_operation_mode(mode);
422 }
423 
424 // ---------------------------------------------------------------------------
425 
numActiveClients()426 int SensorDevice::Info::numActiveClients() {
427     SensorDevice& device(SensorDevice::getInstance());
428     int num = 0;
429     for (size_t i = 0; i < batchParams.size(); ++i) {
430         if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
431             ++num;
432         }
433     }
434     return num;
435 }
436 
setBatchParamsForIdent(void * ident,int flags,int64_t samplingPeriodNs,int64_t maxBatchReportLatencyNs)437 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
438                                                     int64_t samplingPeriodNs,
439                                                     int64_t maxBatchReportLatencyNs) {
440     ssize_t index = batchParams.indexOfKey(ident);
441     if (index < 0) {
442         ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
443               ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
444         return BAD_INDEX;
445     }
446     BatchParams& params = batchParams.editValueAt(index);
447     params.flags = flags;
448     params.batchDelay = samplingPeriodNs;
449     params.batchTimeout = maxBatchReportLatencyNs;
450     return NO_ERROR;
451 }
452 
selectBatchParams()453 void SensorDevice::Info::selectBatchParams() {
454     BatchParams bestParams(0, -1, -1);
455     SensorDevice& device(SensorDevice::getInstance());
456 
457     for (size_t i = 0; i < batchParams.size(); ++i) {
458         if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
459         BatchParams params = batchParams.valueAt(i);
460         if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
461             bestParams.batchDelay = params.batchDelay;
462         }
463         if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
464             bestParams.batchTimeout = params.batchTimeout;
465         }
466     }
467     bestBatchParams = bestParams;
468 }
469 
removeBatchParamsForIdent(void * ident)470 ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
471     ssize_t idx = batchParams.removeItem(ident);
472     if (idx >= 0) {
473         selectBatchParams();
474     }
475     return idx;
476 }
477 
478 // ---------------------------------------------------------------------------
479 }; // namespace android
480 
481