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
35namespace android {
36// ---------------------------------------------------------------------------
37
38ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
39
40SensorDevice::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
75void 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
86std::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
125ssize_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
131status_t SensorDevice::initCheck() const {
132    return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
133}
134
135ssize_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
145void SensorDevice::autoDisable(void *ident, int handle) {
146    Info& info( mActivationCount.editValueFor(handle) );
147    Mutex::Autolock _l(mLock);
148    info.removeBatchParamsForIdent(ident);
149}
150
151status_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
235status_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
300status_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
324int SensorDevice::getHalDeviceVersion() const {
325    if (!mSensorDevice) return -1;
326    return mSensorDevice->common.version;
327}
328
329status_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
338bool SensorDevice::isClientDisabled(void* ident) {
339    Mutex::Autolock _l(mLock);
340    return isClientDisabledLocked(ident);
341}
342
343bool SensorDevice::isClientDisabledLocked(void* ident) {
344    return mDisabledClients.indexOf(ident) >= 0;
345}
346
347void 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
382void 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
403status_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
417status_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
426int 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
437status_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
453void 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
470ssize_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