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