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