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 // #defined LOG_NDEBUG  1
19 #include <utils/Log.h>
20 
21 #include "hubconnection.h"
22 #include "sensorlist.h"
23 #include "sensors.h"
24 
25 #include <errno.h>
26 #include <math.h>
27 #include <media/stagefright/foundation/ADebug.h>
28 #include <string.h>
29 
30 using namespace android;
31 
32 ////////////////////////////////////////////////////////////////////////////////
33 
SensorContext(const struct hw_module_t * module)34 SensorContext::SensorContext(const struct hw_module_t *module)
35     : mHubConnection(HubConnection::getInstance()), mHubAlive(true) {
36     memset(&device, 0, sizeof(device));
37 
38     device.common.tag = HARDWARE_DEVICE_TAG;
39     device.common.version = SENSORS_DEVICE_API_VERSION_1_3;
40     device.common.module = const_cast<hw_module_t *>(module);
41     device.common.close = CloseWrapper;
42     device.activate = ActivateWrapper;
43     device.setDelay = SetDelayWrapper;
44     device.poll = PollWrapper;
45     device.batch = BatchWrapper;
46     device.flush = FlushWrapper;
47 
48     mHubAlive = (mHubConnection->initCheck() == OK
49         && mHubConnection->getAliveCheck() == OK);
50 }
51 
close()52 int SensorContext::close() {
53     ALOGI("close");
54 
55     delete this;
56 
57     return 0;
58 }
59 
activate(int handle,int enabled)60 int SensorContext::activate(int handle, int enabled) {
61     ALOGI("activate");
62 
63     mHubConnection->queueActivate(handle, enabled);
64 
65     return 0;
66 }
67 
setDelay(int handle,int64_t delayNs)68 int SensorContext::setDelay(int handle, int64_t delayNs) {
69     ALOGI("setDelay");
70 
71     // clamp sample rate based on minDelay and maxDelay defined in kSensorList
72     int64_t delayNsClamped = delayNs;
73     for (size_t i = 0; i < kSensorCount; i++) {
74         sensor_t sensor = kSensorList[i];
75         if (sensor.handle != handle) {
76             continue;
77         }
78 
79         if ((sensor.flags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) {
80             if ((delayNs/1000) < sensor.minDelay) {
81                 delayNsClamped = sensor.minDelay * 1000;
82             } else if ((delayNs/1000) > sensor.maxDelay) {
83                 delayNsClamped = sensor.maxDelay * 1000;
84             }
85         }
86 
87         break;
88     }
89 
90     mHubConnection->queueSetDelay(handle, delayNsClamped);
91 
92     return 0;
93 }
94 
poll(sensors_event_t * data,int count)95 int SensorContext::poll(sensors_event_t *data, int count) {
96     ALOGV("poll");
97 
98     ssize_t n = mHubConnection->read(data, count);
99 
100     if (n < 0) {
101         return -1;
102     }
103 
104     return n;
105 }
106 
batch(int handle,int flags,int64_t sampling_period_ns,int64_t max_report_latency_ns)107 int SensorContext::batch(
108         int handle,
109         int flags,
110         int64_t sampling_period_ns,
111         int64_t max_report_latency_ns) {
112     ALOGI("batch");
113 
114     // clamp sample rate based on minDelay and maxDelay defined in kSensorList
115     int64_t sampling_period_ns_clamped = sampling_period_ns;
116     for (size_t i = 0; i < kSensorCount; i++) {
117         sensor_t sensor = kSensorList[i];
118         if (sensor.handle != handle) {
119             continue;
120         }
121 
122         if ((sensor.flags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) {
123             if ((sampling_period_ns/1000) < sensor.minDelay) {
124                 sampling_period_ns_clamped = sensor.minDelay * 1000;
125             } else if ((sampling_period_ns/1000) > sensor.maxDelay) {
126                 sampling_period_ns_clamped = sensor.maxDelay * 1000;
127             }
128         }
129 
130         break;
131     }
132 
133     mHubConnection->queueBatch(
134             handle, flags, sampling_period_ns_clamped, max_report_latency_ns);
135 
136     return 0;
137 }
138 
flush(int handle)139 int SensorContext::flush(int handle) {
140     ALOGI("flush");
141 
142     mHubConnection->queueFlush(handle);
143     return 0;
144 }
145 
146 // static
CloseWrapper(struct hw_device_t * dev)147 int SensorContext::CloseWrapper(struct hw_device_t *dev) {
148     return reinterpret_cast<SensorContext *>(dev)->close();
149 }
150 
151 // static
ActivateWrapper(struct sensors_poll_device_t * dev,int handle,int enabled)152 int SensorContext::ActivateWrapper(
153         struct sensors_poll_device_t *dev, int handle, int enabled) {
154     return reinterpret_cast<SensorContext *>(dev)->activate(handle, enabled);
155 }
156 
157 // static
SetDelayWrapper(struct sensors_poll_device_t * dev,int handle,int64_t delayNs)158 int SensorContext::SetDelayWrapper(
159         struct sensors_poll_device_t *dev, int handle, int64_t delayNs) {
160     return reinterpret_cast<SensorContext *>(dev)->setDelay(handle, delayNs);
161 }
162 
163 // static
PollWrapper(struct sensors_poll_device_t * dev,sensors_event_t * data,int count)164 int SensorContext::PollWrapper(
165         struct sensors_poll_device_t *dev, sensors_event_t *data, int count) {
166     return reinterpret_cast<SensorContext *>(dev)->poll(data, count);
167 }
168 
169 // static
BatchWrapper(struct sensors_poll_device_1 * dev,int handle,int flags,int64_t sampling_period_ns,int64_t max_report_latency_ns)170 int SensorContext::BatchWrapper(
171         struct sensors_poll_device_1 *dev,
172         int handle,
173         int flags,
174         int64_t sampling_period_ns,
175         int64_t max_report_latency_ns) {
176     return reinterpret_cast<SensorContext *>(dev)->batch(
177             handle, flags, sampling_period_ns, max_report_latency_ns);
178 }
179 
180 // static
FlushWrapper(struct sensors_poll_device_1 * dev,int handle)181 int SensorContext::FlushWrapper(struct sensors_poll_device_1 *dev, int handle) {
182     return reinterpret_cast<SensorContext *>(dev)->flush(handle);
183 }
184 
getHubAlive()185 bool SensorContext::getHubAlive() {
186     return mHubAlive;
187 }
188 
189 ////////////////////////////////////////////////////////////////////////////////
190 
191 static bool gHubAlive;
192 
open_sensors(const struct hw_module_t * module,const char *,struct hw_device_t ** dev)193 static int open_sensors(
194         const struct hw_module_t *module,
195         const char *,
196         struct hw_device_t **dev) {
197     ALOGI("open_sensors");
198 
199     SensorContext *ctx = new SensorContext(module);
200 
201     gHubAlive = ctx->getHubAlive();
202     *dev = &ctx->device.common;
203 
204     return 0;
205 }
206 
207 static struct hw_module_methods_t sensors_module_methods = {
208     .open = open_sensors
209 };
210 
get_sensors_list(struct sensors_module_t *,struct sensor_t const ** list)211 static int get_sensors_list(
212         struct sensors_module_t *,
213         struct sensor_t const **list) {
214     ALOGI("get_sensors_list");
215 
216     if (gHubAlive) {
217         *list = kSensorList;
218         return kSensorCount;
219     } else {
220         *list = {};
221         return 0;
222     }
223 }
224 
set_operation_mode(unsigned int mode)225 static int set_operation_mode(unsigned int mode) {
226     ALOGI("set_operation_mode");
227     return (mode) ? -EINVAL : 0;
228 }
229 
230 struct sensors_module_t HAL_MODULE_INFO_SYM = {
231         .common = {
232                 .tag = HARDWARE_MODULE_TAG,
233                 .version_major = 1,
234                 .version_minor = 0,
235                 .id = SENSORS_HARDWARE_MODULE_ID,
236                 .name = "Google Sensor module",
237                 .author = "Google",
238                 .methods = &sensors_module_methods,
239                 .dso  = NULL,
240                 .reserved = {0},
241         },
242         .get_sensors_list = get_sensors_list,
243         .set_operation_mode = set_operation_mode,
244 };
245