1/*
2 * Copyright (C) 2015 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#define LOG_TAG "sensors"
18#define LOG_NDEBUG  1
19#include <utils/Log.h>
20
21#include "hubconnection.h"
22#include "sensorlist.h"
23#include "sensors.h"
24
25#include <cutils/ashmem.h>
26#include <errno.h>
27#include <math.h>
28#include <media/stagefright/foundation/ADebug.h>
29#include <string.h>
30#include <sys/mman.h>
31#include <stdlib.h>
32
33#ifdef DYNAMIC_SENSOR_EXT_ENABLED
34#include <DynamicSensorManager.h>
35#include <SensorEventCallback.h>
36#endif
37
38using namespace android;
39
40////////////////////////////////////////////////////////////////////////////////
41
42SensorContext::SensorContext(const struct hw_module_t *module)
43        : mSensorList(kSensorList, kSensorList + kSensorCount),
44          mHubConnection(HubConnection::getInstance()) {
45    memset(&device, 0, sizeof(device));
46
47    device.common.tag = HARDWARE_DEVICE_TAG;
48    device.common.version = SENSORS_DEVICE_API_VERSION_1_4;
49    device.common.module = const_cast<hw_module_t *>(module);
50    device.common.close = CloseWrapper;
51    device.activate = ActivateWrapper;
52    device.setDelay = SetDelayWrapper;
53    device.poll = PollWrapper;
54    device.batch = BatchWrapper;
55    device.flush = FlushWrapper;
56    device.inject_sensor_data = InjectSensorDataWrapper;
57    mHubConnection->setRawScale(kScaleAccel, kScaleMag);
58    if (mHubConnection->isDirectReportSupported()) {
59        device.register_direct_channel = RegisterDirectChannelWrapper;
60        device.config_direct_report = ConfigDirectReportWrapper;
61    }
62
63    mOperationHandler.emplace_back(new HubConnectionOperation(mHubConnection));
64
65    initializeHalExtension();
66}
67
68int SensorContext::close() {
69    ALOGV("close");
70
71    delete this;
72
73    return 0;
74}
75
76int SensorContext::activate(int handle, int enabled) {
77    ALOGV("activate");
78
79    for (auto &h : mOperationHandler) {
80        if (h->owns(handle)) {
81            return h->activate(handle, enabled);
82        }
83    }
84    return INVALID_OPERATION;
85}
86
87int SensorContext::setDelay(int handle, int64_t delayNs) {
88    ALOGV("setDelay");
89
90    for (auto &h: mOperationHandler) {
91        if (h->owns(handle)) {
92            return h->setDelay(handle, delayNs);
93        }
94    }
95    return INVALID_OPERATION;
96}
97
98int SensorContext::poll(sensors_event_t *data, int count) {
99    ALOGV("poll");
100
101    // Release wakelock if held and no more events in ring buffer
102    mHubConnection->releaseWakeLockIfAppropriate();
103
104    ssize_t n = mHubConnection->read(data, count);
105
106    if (n < 0) {
107        return -1;
108    }
109
110    // If we have wake events in the queue, determine how many we're sending
111    // up this round and decrement that count now so that when we get called back,
112    // we'll have an accurate count of how many wake events are STILL in the HAL queue
113    // to be able to determine whether we can release our wakelock if held.
114    if (mHubConnection->getWakeEventCount() != 0) {
115        for (ssize_t i = 0; i < n; i++) {
116            if (mHubConnection->isWakeEvent(data[i].sensor)) {
117                ssize_t count = mHubConnection->decrementWakeEventCount();
118                if (count == 0) {
119                    break;
120                }
121            }
122        }
123    }
124
125    return n;
126}
127
128int SensorContext::batch(
129        int handle,
130        int64_t sampling_period_ns,
131        int64_t max_report_latency_ns) {
132    ALOGV("batch");
133
134    for (auto &h : mOperationHandler) {
135        if (h->owns(handle)) {
136            return h->batch(handle, sampling_period_ns, max_report_latency_ns);
137        }
138    }
139    return INVALID_OPERATION;
140}
141
142int SensorContext::flush(int handle) {
143    ALOGV("flush");
144
145    for (auto &h : mOperationHandler) {
146        if (h->owns(handle)) {
147            return h->flush(handle);
148        }
149    }
150    return INVALID_OPERATION;
151}
152
153int SensorContext::register_direct_channel(
154        const struct sensors_direct_mem_t *mem, int32_t channel_handle) {
155    if (mem) {
156        //add
157        return mHubConnection->addDirectChannel(mem);
158    } else {
159        //remove
160        mHubConnection->removeDirectChannel(channel_handle);
161        return NO_ERROR;
162    }
163}
164
165int SensorContext::config_direct_report(
166        int32_t sensor_handle, int32_t channel_handle, const struct sensors_direct_cfg_t * config) {
167    int rate_level = config->rate_level;
168    return mHubConnection->configDirectReport(sensor_handle, channel_handle, rate_level);
169}
170
171// static
172int SensorContext::CloseWrapper(struct hw_device_t *dev) {
173    return reinterpret_cast<SensorContext *>(dev)->close();
174}
175
176// static
177int SensorContext::ActivateWrapper(
178        struct sensors_poll_device_t *dev, int handle, int enabled) {
179    return reinterpret_cast<SensorContext *>(dev)->activate(handle, enabled);
180}
181
182// static
183int SensorContext::SetDelayWrapper(
184        struct sensors_poll_device_t *dev, int handle, int64_t delayNs) {
185    return reinterpret_cast<SensorContext *>(dev)->setDelay(handle, delayNs);
186}
187
188// static
189int SensorContext::PollWrapper(
190        struct sensors_poll_device_t *dev, sensors_event_t *data, int count) {
191    return reinterpret_cast<SensorContext *>(dev)->poll(data, count);
192}
193
194// static
195int SensorContext::BatchWrapper(
196        struct sensors_poll_device_1 *dev,
197        int handle,
198        int flags,
199        int64_t sampling_period_ns,
200        int64_t max_report_latency_ns) {
201    (void) flags;
202    return reinterpret_cast<SensorContext *>(dev)->batch(
203            handle, sampling_period_ns, max_report_latency_ns);
204}
205
206// static
207int SensorContext::FlushWrapper(struct sensors_poll_device_1 *dev, int handle) {
208    return reinterpret_cast<SensorContext *>(dev)->flush(handle);
209}
210
211// static
212int SensorContext::RegisterDirectChannelWrapper(struct sensors_poll_device_1 *dev,
213        const struct sensors_direct_mem_t* mem, int channel_handle) {
214    return reinterpret_cast<SensorContext *>(dev)->register_direct_channel(
215            mem, channel_handle);
216}
217
218// static
219int SensorContext::ConfigDirectReportWrapper(struct sensors_poll_device_1 *dev,
220        int sensor_handle, int channel_handle, const sensors_direct_cfg_t * config) {
221    return reinterpret_cast<SensorContext *>(dev)->config_direct_report(
222            sensor_handle, channel_handle, config);
223}
224
225int SensorContext::inject_sensor_data(const sensors_event_t *event) {
226    ALOGV("inject_sensor_data");
227
228    // only support set operation parameter, which will have handle == 0
229    if (event == nullptr || event->type != SENSOR_TYPE_ADDITIONAL_INFO) {
230        return -EINVAL;
231    }
232
233    if (event->sensor != SENSORS_HANDLE_BASE - 1) {
234        return -ENOSYS;
235    }
236
237    if (event->additional_info.type == AINFO_BEGIN
238            || event->additional_info.type == AINFO_END) {
239        return 0;
240    }
241
242    mHubConnection->setOperationParameter(event->additional_info);
243    return 0;
244}
245
246// static
247int SensorContext::InjectSensorDataWrapper(struct sensors_poll_device_1 *dev,
248        const struct sensors_event_t *event) {
249    return reinterpret_cast<SensorContext *>(dev)->inject_sensor_data(event);
250}
251
252bool SensorContext::getHubAlive() {
253    return (mHubConnection->initCheck() == OK && mHubConnection->getAliveCheck() == OK);
254}
255
256size_t SensorContext::getSensorList(sensor_t const **list) {
257    ALOGE("sensor p = %p, n = %zu", mSensorList.data(), mSensorList.size());
258    *list = mSensorList.data();
259    return mSensorList.size();
260}
261
262// HubConnectionOperation functions
263SensorContext::HubConnectionOperation::HubConnectionOperation(sp<HubConnection> hubConnection)
264        : mHubConnection(hubConnection) {
265    for (size_t i = 0; i < kSensorCount; i++) {
266        mHandles.emplace(kSensorList[i].handle);
267    }
268}
269
270bool SensorContext::HubConnectionOperation::owns(int handle) {
271    return mHandles.find(handle) != mHandles.end();
272}
273
274int SensorContext::HubConnectionOperation::activate(int handle, int enabled) {
275    mHubConnection->queueActivate(handle, enabled);
276    return 0;
277}
278
279int SensorContext::HubConnectionOperation::setDelay(int handle, int64_t delayNs) {
280    // clamp sample rate based on minDelay and maxDelay defined in kSensorList
281    int64_t delayNsClamped = delayNs;
282    for (size_t i = 0; i < kSensorCount; i++) {
283        sensor_t sensor = kSensorList[i];
284        if (sensor.handle != handle) {
285            continue;
286        }
287
288        if ((sensor.flags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) {
289            if ((delayNs/1000) < sensor.minDelay) {
290                delayNsClamped = sensor.minDelay * 1000;
291            } else if ((delayNs/1000) > sensor.maxDelay) {
292                delayNsClamped = sensor.maxDelay * 1000;
293            }
294        }
295
296        break;
297    }
298
299    mHubConnection->queueSetDelay(handle, delayNsClamped);
300    return 0;
301}
302
303int SensorContext::HubConnectionOperation::batch(
304        int handle, int64_t sampling_period_ns,
305        int64_t max_report_latency_ns) {
306    // clamp sample rate based on minDelay and maxDelay defined in kSensorList
307    int64_t sampling_period_ns_clamped = sampling_period_ns;
308    for (size_t i = 0; i < kSensorCount; i++) {
309        sensor_t sensor = kSensorList[i];
310        if (sensor.handle != handle) {
311            continue;
312        }
313
314        if ((sensor.flags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) {
315            if ((sampling_period_ns/1000) < sensor.minDelay) {
316                sampling_period_ns_clamped = sensor.minDelay * 1000;
317            } else if ((sampling_period_ns/1000) > sensor.maxDelay) {
318                sampling_period_ns_clamped = sensor.maxDelay * 1000;
319            }
320        }
321
322        break;
323    }
324
325    mHubConnection->queueBatch(handle, sampling_period_ns_clamped,
326                               max_report_latency_ns);
327    return 0;
328}
329
330int SensorContext::HubConnectionOperation::flush(int handle) {
331    mHubConnection->queueFlush(handle);
332    return 0;
333}
334
335#ifdef DYNAMIC_SENSOR_EXT_ENABLED
336namespace {
337// adaptor class
338class Callback : public SensorEventCallback {
339public:
340    Callback(sp<HubConnection> hubConnection) : mHubConnection(hubConnection) {}
341    virtual int submitEvent(sp<BaseSensorObject> source, const sensors_event_t &e) override;
342private:
343    sp<HubConnection> mHubConnection;
344};
345
346int Callback::submitEvent(sp<BaseSensorObject> source, const sensors_event_t &e) {
347    (void) source; // irrelavent in this context
348    return (mHubConnection->write(&e, 1) == 1) ? 0 : -ENOSPC;
349}
350} // anonymous namespace
351
352SensorContext::DynamicSensorManagerOperation::DynamicSensorManagerOperation(DynamicSensorManager* manager)
353        : mDynamicSensorManager(manager) {
354}
355
356bool SensorContext::DynamicSensorManagerOperation::owns(int handle) {
357    return mDynamicSensorManager->owns(handle);
358}
359
360int SensorContext::DynamicSensorManagerOperation::activate(int handle, int enabled) {
361    return mDynamicSensorManager->activate(handle, enabled);
362}
363
364int SensorContext::DynamicSensorManagerOperation::setDelay(int handle, int64_t delayNs) {
365    return mDynamicSensorManager->setDelay(handle, delayNs);
366}
367
368int SensorContext::DynamicSensorManagerOperation::batch(int handle, int64_t sampling_period_ns,
369        int64_t max_report_latency_ns) {
370    return mDynamicSensorManager->batch(handle, sampling_period_ns, max_report_latency_ns);
371}
372
373int SensorContext::DynamicSensorManagerOperation::flush(int handle) {
374    return mDynamicSensorManager->flush(handle);
375}
376#endif
377
378void SensorContext::initializeHalExtension() {
379#ifdef DYNAMIC_SENSOR_EXT_ENABLED
380    // initialize callback and dynamic sensor manager
381    mEventCallback.reset(new Callback(mHubConnection));
382    DynamicSensorManager* manager = DynamicSensorManager::createInstance(
383        kDynamicHandleBase, kMaxDynamicHandleCount, mEventCallback.get());
384
385    // add meta sensor to list
386    mSensorList.push_back(manager->getDynamicMetaSensor());
387
388    // register operation
389    mOperationHandler.emplace_back(new DynamicSensorManagerOperation(manager));
390#endif
391}
392
393////////////////////////////////////////////////////////////////////////////////
394
395static bool gHubAlive;
396static sensor_t const *sensor_list;
397static int n_sensor;
398
399static int open_sensors(
400        const struct hw_module_t *module,
401        const char *,
402        struct hw_device_t **dev) {
403    ALOGV("open_sensors");
404
405    SensorContext *ctx = new SensorContext(module);
406    n_sensor = ctx->getSensorList(&sensor_list);
407    gHubAlive = ctx->getHubAlive();
408    *dev = &ctx->device.common;
409
410    return 0;
411}
412
413static struct hw_module_methods_t sensors_module_methods = {
414    .open = open_sensors
415};
416
417static int get_sensors_list(
418        struct sensors_module_t *,
419        struct sensor_t const **list) {
420    ALOGV("get_sensors_list");
421    if (gHubAlive && sensor_list != nullptr) {
422        *list = sensor_list;
423        return n_sensor;
424    } else {
425        *list = {};
426        return 0;
427    }
428}
429
430static int set_operation_mode(unsigned int mode) {
431    ALOGV("set_operation_mode");
432
433    // This is no-op because there is no sensor in the hal that system can
434    // inject events. Only operation parameter injection is implemented, which
435    // works in both data injection and normal mode.
436    (void) mode;
437    return 0;
438}
439
440struct sensors_module_t HAL_MODULE_INFO_SYM = {
441        .common = {
442                .tag = HARDWARE_MODULE_TAG,
443                .version_major = 1,
444                .version_minor = 0,
445                .id = SENSORS_HARDWARE_MODULE_ID,
446                .name = "Google Sensor module",
447                .author = "Google",
448                .methods = &sensors_module_methods,
449                .dso  = NULL,
450                .reserved = {0},
451        },
452        .get_sensors_list = get_sensors_list,
453        .set_operation_mode = set_operation_mode,
454};
455