1 /*
2 * Copyright (C) 2015 Intel Corporation
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 <string.h>
18 #include <cutils/log.h>
19 #include <stdexcept>
20 #include <errno.h>
21 #include <sys/epoll.h>
22 #include "SensorsHAL.hpp"
23
24 Sensor * (*SensorContext::sensorFactoryFuncs[MAX_DEVICES])(int);
25 struct sensor_t SensorContext::sensorDescs[MAX_DEVICES];
26 int SensorContext::sensorsNum = 0;
27 android::Mutex SensorContext::mutex;
28
SensorContext(const hw_module_t * module)29 SensorContext::SensorContext(const hw_module_t *module) {
30 /* create the epoll fd used to register the incoming fds */
31 pollFd = epoll_create(MAX_DEVICES);
32 if (pollFd == -1) {
33 throw std::runtime_error("Failed to create poll file descriptor");
34 }
35
36 memset(&device, 0, sizeof(device));
37
38 device.common.tag = HARDWARE_DEVICE_TAG;
39 device.common.version = SENSORS_DEVICE_API_VERSION_1_0;
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 = PollEventsWrapper;
45 device.batch = BatchWrapper;
46 device.flush = FlushWrapper;
47
48 memset(sensors, 0, sizeof(Sensor *) * MAX_DEVICES);
49 }
50
~SensorContext()51 SensorContext::~SensorContext() {
52 int rc;
53
54 for (int i = 0; i < sensorsNum; i++) {
55 if (sensors[i]) {
56 delete sensors[i];
57 sensors[i] = nullptr;
58 }
59 }
60
61 rc = close(pollFd);
62 if (rc != 0) {
63 ALOGE("Cannot close poll file descriptor");
64 }
65 }
66
addSensorModule(struct sensor_t * sensorDesc,Sensor * (* sensorFactoryFunc)(int))67 int SensorContext::addSensorModule(struct sensor_t *sensorDesc,
68 Sensor * (*sensorFactoryFunc)(int)) {
69 android::Mutex::Autolock autolock(mutex);
70
71 if ((sensorDesc == nullptr) || (sensorFactoryFunc == nullptr)) {
72 ALOGE("%s: cannot add a null sensor", __func__);
73 return -EINVAL;
74 }
75
76 if (sensorsNum >= MAX_DEVICES) {
77 ALOGE("%s: Cannot add more than %d sensors.", __func__, MAX_DEVICES);
78 return -E2BIG;
79 }
80
81 sensorDesc->handle = sensorsNum;
82 sensorDescs[sensorsNum] = *sensorDesc;
83 sensorFactoryFuncs[sensorsNum] = sensorFactoryFunc;
84 sensorsNum++;
85
86 return 0;
87 }
88
OpenWrapper(const struct hw_module_t * module,const char * id,struct hw_device_t ** device)89 int SensorContext::OpenWrapper(const struct hw_module_t *module,
90 const char* id, struct hw_device_t **device) {
91 SensorContext *ctx;
92
93 try {
94 ctx = new SensorContext(module);
95 } catch (const std::runtime_error& e) {
96 ALOGE("%s: Failed to open sensors hal. Error message: %s",
97 __func__, e.what());
98 return -1;
99 }
100
101 *device = &ctx->device.common;
102
103 return 0;
104 }
105
GetSensorsListWrapper(struct sensors_module_t * module,struct sensor_t const ** list)106 int SensorContext::GetSensorsListWrapper(struct sensors_module_t *module,
107 struct sensor_t const **list) {
108 android::Mutex::Autolock autolock(mutex);
109
110 if (!list || (sensorsNum == 0)) {
111 return 0;
112 }
113
114 *list = sensorDescs;
115 return sensorsNum;
116 }
117
activate(int handle,int enabled)118 int SensorContext::activate(int handle, int enabled) {
119 int rc = 0;
120
121 if (enabled != 0 && enabled != 1) {
122 ALOGE("%s: Invalid parameter", __func__);
123 return -EINVAL;
124 }
125
126 if (handle < 0 || handle >= sensorsNum) {
127 return -EINVAL;
128 }
129
130 try {
131 if (enabled) {
132 if (sensors[handle] == nullptr) {
133 sensors[handle] = sensorFactoryFuncs[handle](pollFd);
134 if (sensors[handle] == nullptr) {
135 return -1;
136 }
137 rc = sensors[handle]->activate(handle, enabled);
138 if (rc != 0) {
139 goto delete_sensor;
140 }
141 } else {
142 return 0;
143 }
144 } else {
145 if (sensors[handle] != nullptr) {
146 rc = sensors[handle]->activate(handle, enabled);
147 delete sensors[handle];
148 sensors[handle] = nullptr;
149 } else {
150 return 0;
151 }
152 }
153
154 return rc;
155 } catch (const std::exception& e) {
156 /* The upper layer doesn't expect exceptions. Catch them all. */
157 ALOGE("%s: Failed to %s sensor %d. Error message: %s.",
158 __func__, enabled ? "activate" : "deactivate", handle, e.what());
159 }
160
161 delete_sensor:
162 if (sensors[handle] != nullptr) {
163 delete sensors[handle];
164 sensors[handle] = nullptr;
165 }
166
167 return -1;
168 }
169
setDelay(int handle,int64_t ns)170 int SensorContext::setDelay(int handle, int64_t ns) {
171 if (handle < 0 || handle >= sensorsNum) {
172 return -EINVAL;
173 }
174
175 if (sensors[handle] == nullptr) {
176 ALOGE("%s: cannot set delay. sensor %d is not activated", __func__, handle);
177 return -EINVAL;
178 }
179
180 return sensors[handle]->setDelay(handle, ns);
181 }
182
pollEvents(sensors_event_t * data,int count)183 int SensorContext::pollEvents(sensors_event_t *data, int count) {
184 int nfds, i;
185 struct epoll_event ev[MAX_DEVICES];
186 int returnedEvents = 0, sensorIndex = -1;
187
188 /* return only when at least one event is available */
189 while(true) {
190 nfds = epoll_wait(pollFd, ev, MAX_DEVICES, -1);
191 if (nfds < 0) {
192 ALOGE("%s: epoll_wait returned an error: %d", __func__, errno);
193 return nfds;
194 }
195
196 { // Autolock scope
197 android::Mutex::Autolock autolock(mutex);
198 for(i = 0; i < nfds && returnedEvents < count; i++) {
199 if (ev[i].events == EPOLLIN) {
200 sensorIndex = ev[i].data.u32;
201 if ((sensorIndex < 0) || (sensorIndex > sensorsNum)) {
202 ALOGE("%s: Invalid sensor index", __func__);
203 return -1;
204 }
205
206 if (sensors[sensorIndex] == nullptr) {
207 /* The sensor might have been deactivated by another thread */
208 continue;
209 }
210
211 /*
212 * The read operation might fail if the data is read by another
213 * pollEvents call executed by another thread.
214 */
215 if (sensors[sensorIndex]->readOneEvent(data + returnedEvents)) {
216 returnedEvents++;
217 }
218 }
219 }
220 } // Autolock scope
221
222 if (returnedEvents > 0) {
223 return returnedEvents;
224 }
225 }
226 }
227
batch(int handle,int flags,int64_t period_ns,int64_t timeout)228 int SensorContext::batch(int handle, int flags,
229 int64_t period_ns, int64_t timeout) {
230 if (handle < 0 || handle >= sensorsNum) {
231 return -EINVAL;
232 }
233
234 if (sensors[handle] == nullptr) {
235 ALOGE("%s: cannot set delay. sensor %d is not activated", __func__, handle);
236 return -EINVAL;
237 }
238
239 return sensors[handle]->batch(handle, flags, period_ns, timeout);
240 }
241
flush(int handle)242 int SensorContext::flush(int handle) {
243 if (handle < 0 || handle >= sensorsNum) {
244 return -EINVAL;
245 }
246
247 if (sensors[handle] == nullptr) {
248 ALOGE("%s: cannot set delay. sensor %d is not activated", __func__, handle);
249 return -EINVAL;
250 }
251
252 /* flush doesn't apply to one-shot sensors */
253 if (sensorDescs[handle].flags & SENSOR_FLAG_ONE_SHOT_MODE)
254 return -EINVAL;
255
256 return sensors[handle]->flush(handle);
257 }
258
CloseWrapper(hw_device_t * dev)259 int SensorContext::CloseWrapper(hw_device_t *dev) {
260 SensorContext *sensorContext = reinterpret_cast<SensorContext *>(dev);
261 android::Mutex::Autolock autolock(mutex);
262
263 if (sensorContext != nullptr) {
264 delete sensorContext;
265 }
266
267 return 0;
268 }
269
ActivateWrapper(sensors_poll_device_t * dev,int handle,int enabled)270 int SensorContext::ActivateWrapper(sensors_poll_device_t *dev,
271 int handle, int enabled) {
272 android::Mutex::Autolock autolock(mutex);
273
274 return reinterpret_cast<SensorContext *>(dev)->activate(handle, enabled);
275 }
276
SetDelayWrapper(sensors_poll_device_t * dev,int handle,int64_t ns)277 int SensorContext::SetDelayWrapper(sensors_poll_device_t *dev,
278 int handle, int64_t ns) {
279 android::Mutex::Autolock autolock(mutex);
280
281 return reinterpret_cast<SensorContext *>(dev)->setDelay(handle, ns);
282 }
283
PollEventsWrapper(sensors_poll_device_t * dev,sensors_event_t * data,int count)284 int SensorContext::PollEventsWrapper(sensors_poll_device_t *dev,
285 sensors_event_t *data, int count) {
286 return reinterpret_cast<SensorContext *>(dev)->pollEvents(data, count);
287 }
288
BatchWrapper(sensors_poll_device_1_t * dev,int handle,int flags,int64_t period_ns,int64_t timeout)289 int SensorContext::BatchWrapper(sensors_poll_device_1_t *dev, int handle,
290 int flags, int64_t period_ns, int64_t timeout) {
291 android::Mutex::Autolock autolock(mutex);
292
293 return reinterpret_cast<SensorContext *>(dev)->batch(handle, flags, period_ns,
294 timeout);
295 }
296
FlushWrapper(sensors_poll_device_1_t * dev,int handle)297 int SensorContext::FlushWrapper(sensors_poll_device_1_t *dev,
298 int handle) {
299 android::Mutex::Autolock autolock(mutex);
300
301 return reinterpret_cast<SensorContext *>(dev)->flush(handle);
302 }
303
304 static struct hw_module_methods_t sensors_module_methods = {
305 .open = SensorContext::OpenWrapper,
306 };
307
308 struct sensors_module_t HAL_MODULE_INFO_SYM = {
309 .common = {
310 .tag = HARDWARE_MODULE_TAG,
311 .version_major = 1,
312 .version_minor = 0,
313 .id = SENSORS_HARDWARE_MODULE_ID,
314 .name = "Edison Sensor HAL",
315 .author = "Intel",
316 .methods = &sensors_module_methods,
317 .dso = nullptr,
318 .reserved = {0},
319 },
320 .get_sensors_list = SensorContext::GetSensorsListWrapper,
321 .set_operation_mode = nullptr
322 };
323