• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()) {
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,int64_t sampling_period_ns,int64_t max_report_latency_ns)107 int SensorContext::batch(
108         int handle,
109         int64_t sampling_period_ns,
110         int64_t max_report_latency_ns) {
111     ALOGI("batch");
112 
113     // clamp sample rate based on minDelay and maxDelay defined in kSensorList
114     int64_t sampling_period_ns_clamped = sampling_period_ns;
115     for (size_t i = 0; i < kSensorCount; i++) {
116         sensor_t sensor = kSensorList[i];
117         if (sensor.handle != handle) {
118             continue;
119         }
120 
121         if ((sensor.flags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) {
122             if ((sampling_period_ns/1000) < sensor.minDelay) {
123                 sampling_period_ns_clamped = sensor.minDelay * 1000;
124             } else if ((sampling_period_ns/1000) > sensor.maxDelay) {
125                 sampling_period_ns_clamped = sensor.maxDelay * 1000;
126             }
127         }
128 
129         break;
130     }
131 
132     mHubConnection->queueBatch(handle, sampling_period_ns_clamped,
133                                max_report_latency_ns);
134     return 0;
135 }
136 
flush(int handle)137 int SensorContext::flush(int handle) {
138     ALOGI("flush");
139 
140     mHubConnection->queueFlush(handle);
141     return 0;
142 }
143 
144 // static
CloseWrapper(struct hw_device_t * dev)145 int SensorContext::CloseWrapper(struct hw_device_t *dev) {
146     return reinterpret_cast<SensorContext *>(dev)->close();
147 }
148 
149 // static
ActivateWrapper(struct sensors_poll_device_t * dev,int handle,int enabled)150 int SensorContext::ActivateWrapper(
151         struct sensors_poll_device_t *dev, int handle, int enabled) {
152     return reinterpret_cast<SensorContext *>(dev)->activate(handle, enabled);
153 }
154 
155 // static
SetDelayWrapper(struct sensors_poll_device_t * dev,int handle,int64_t delayNs)156 int SensorContext::SetDelayWrapper(
157         struct sensors_poll_device_t *dev, int handle, int64_t delayNs) {
158     return reinterpret_cast<SensorContext *>(dev)->setDelay(handle, delayNs);
159 }
160 
161 // static
PollWrapper(struct sensors_poll_device_t * dev,sensors_event_t * data,int count)162 int SensorContext::PollWrapper(
163         struct sensors_poll_device_t *dev, sensors_event_t *data, int count) {
164     return reinterpret_cast<SensorContext *>(dev)->poll(data, count);
165 }
166 
167 // static
BatchWrapper(struct sensors_poll_device_1 * dev,int handle,int flags,int64_t sampling_period_ns,int64_t max_report_latency_ns)168 int SensorContext::BatchWrapper(
169         struct sensors_poll_device_1 *dev,
170         int handle,
171         int flags,
172         int64_t sampling_period_ns,
173         int64_t max_report_latency_ns) {
174     (void) flags;
175     return reinterpret_cast<SensorContext *>(dev)->batch(
176             handle, sampling_period_ns, max_report_latency_ns);
177 }
178 
179 // static
FlushWrapper(struct sensors_poll_device_1 * dev,int handle)180 int SensorContext::FlushWrapper(struct sensors_poll_device_1 *dev, int handle) {
181     return reinterpret_cast<SensorContext *>(dev)->flush(handle);
182 }
183 
getHubAlive()184 bool SensorContext::getHubAlive() {
185     return mHubAlive;
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 
190 static bool gHubAlive;
191 
open_sensors(const struct hw_module_t * module,const char *,struct hw_device_t ** dev)192 static int open_sensors(
193         const struct hw_module_t *module,
194         const char *,
195         struct hw_device_t **dev) {
196     ALOGI("open_sensors");
197 
198     SensorContext *ctx = new SensorContext(module);
199 
200     gHubAlive = ctx->getHubAlive();
201     *dev = &ctx->device.common;
202 
203     return 0;
204 }
205 
206 static struct hw_module_methods_t sensors_module_methods = {
207     .open = open_sensors
208 };
209 
get_sensors_list(struct sensors_module_t *,struct sensor_t const ** list)210 static int get_sensors_list(
211         struct sensors_module_t *,
212         struct sensor_t const **list) {
213     ALOGI("get_sensors_list");
214 
215     if (gHubAlive) {
216         *list = kSensorList;
217         return kSensorCount;
218     } else {
219         *list = {};
220         return 0;
221     }
222 }
223 
set_operation_mode(unsigned int mode)224 static int set_operation_mode(unsigned int mode) {
225     ALOGI("set_operation_mode");
226     return (mode) ? -EINVAL : 0;
227 }
228 
229 struct sensors_module_t HAL_MODULE_INFO_SYM = {
230         .common = {
231                 .tag = HARDWARE_MODULE_TAG,
232                 .version_major = 1,
233                 .version_minor = 0,
234                 .id = SENSORS_HARDWARE_MODULE_ID,
235                 .name = "Google Sensor module",
236                 .author = "Google",
237                 .methods = &sensors_module_methods,
238                 .dso  = NULL,
239                 .reserved = {0},
240         },
241         .get_sensors_list = get_sensors_list,
242         .set_operation_mode = set_operation_mode,
243 };
244