1 /*
2 * Copyright (C) 2020 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 #include <cinttypes>
18 #include <log/log.h>
19 #include <qemud.h>
20 #include <utils/SystemClock.h>
21 #include "multihal_sensors.h"
22 #include "sensor_list.h"
23
24 namespace goldfish {
25 using ahs10::SensorType;
26 using ahs10::SensorFlagBits;
27 using ahs10::MetaDataEventType;
28
MultihalSensors()29 MultihalSensors::MultihalSensors()
30 : m_qemuSensorsFd(qemud_channel_open("sensors"))
31 , m_batchInfo(getSensorNumber()) {
32 if (!m_qemuSensorsFd.ok()) {
33 ALOGE("%s:%d: m_qemuSensorsFd is not opened", __func__, __LINE__);
34 ::abort();
35 }
36
37 char buffer[64];
38 int len = snprintf(buffer, sizeof(buffer),
39 "time:%" PRId64, ::android::elapsedRealtimeNano());
40 if (qemud_channel_send(m_qemuSensorsFd.get(), buffer, len) < 0) {
41 ALOGE("%s:%d: qemud_channel_send failed", __func__, __LINE__);
42 ::abort();
43 }
44
45 using namespace std::literals;
46 const std::string_view kListSensorsCmd = "list-sensors"sv;
47
48 if (qemud_channel_send(m_qemuSensorsFd.get(),
49 kListSensorsCmd.data(),
50 kListSensorsCmd.size()) < 0) {
51 ALOGE("%s:%d: qemud_channel_send failed", __func__, __LINE__);
52 ::abort();
53 }
54
55 len = qemud_channel_recv(m_qemuSensorsFd.get(), buffer, sizeof(buffer) - 1);
56 if (len < 0) {
57 ALOGE("%s:%d: qemud_channel_recv failed", __func__, __LINE__);
58 ::abort();
59 }
60 buffer[len] = 0;
61 uint32_t hostSensorsMask = 0;
62 if (sscanf(buffer, "%u", &hostSensorsMask) != 1) {
63 ALOGE("%s:%d: Can't parse qemud response", __func__, __LINE__);
64 ::abort();
65 }
66 m_availableSensorsMask =
67 hostSensorsMask & ((1u << getSensorNumber()) - 1);
68
69 ALOGI("%s:%d: host sensors mask=%x, available sensors mask=%x",
70 __func__, __LINE__, hostSensorsMask, m_availableSensorsMask);
71
72 if (!::android::base::Socketpair(AF_LOCAL, SOCK_STREAM, 0,
73 &m_callersFd, &m_sensorThreadFd)) {
74 ALOGE("%s:%d: Socketpair failed", __func__, __LINE__);
75 ::abort();
76 }
77
78 m_sensorThread = std::thread(&MultihalSensors::qemuSensorListenerThread, this);
79 m_batchThread = std::thread(&MultihalSensors::batchThread, this);
80 }
81
~MultihalSensors()82 MultihalSensors::~MultihalSensors() {
83 setAllQemuSensors(false);
84
85 m_batchRunning = false;
86 m_batchUpdated.notify_one();
87 m_batchThread.join();
88
89 qemuSensorThreadSendCommand(kCMD_QUIT);
90 m_sensorThread.join();
91 }
92
getName()93 const std::string MultihalSensors::getName() {
94 return "hal_sensors_2_0_impl_ranchu";
95 }
96
debug(const hidl_handle & fd,const hidl_vec<hidl_string> & args)97 Return<void> MultihalSensors::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
98 (void)fd;
99 (void)args;
100 return {};
101 }
102
getSensorsList(getSensorsList_cb _hidl_cb)103 Return<void> MultihalSensors::getSensorsList(getSensorsList_cb _hidl_cb) {
104 std::vector<SensorInfo> sensors;
105
106 uint32_t mask = m_availableSensorsMask;
107 for (int i = 0; mask; ++i, mask >>= 1) {
108 if (mask & 1) {
109 sensors.push_back(*getSensorInfoByHandle(i));
110 }
111 }
112
113 _hidl_cb(sensors);
114 return {};
115 }
116
setOperationMode(const OperationMode mode)117 Return<Result> MultihalSensors::setOperationMode(const OperationMode mode) {
118 std::unique_lock<std::mutex> lock(m_mtx);
119
120 if (m_activeSensorsMask) {
121 return Result::INVALID_OPERATION;
122 } else {
123 m_opMode = mode;
124 return Result::OK;
125 }
126 }
127
activate(const int32_t sensorHandle,const bool enabled)128 Return<Result> MultihalSensors::activate(const int32_t sensorHandle,
129 const bool enabled) {
130 if (!isSensorHandleValid(sensorHandle)) {
131 return Result::BAD_VALUE;
132 }
133
134 std::unique_lock<std::mutex> lock(m_mtx);
135 BatchInfo& batchInfo = m_batchInfo[sensorHandle];
136
137 if (enabled) {
138 const SensorInfo* sensor = getSensorInfoByHandle(sensorHandle);
139 LOG_ALWAYS_FATAL_IF(!sensor);
140 if (!(sensor->flags & static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE))) {
141 if (batchInfo.samplingPeriodNs <= 0) {
142 return Result::BAD_VALUE;
143 }
144
145 BatchEventRef batchEventRef;
146 batchEventRef.timestamp =
147 ::android::elapsedRealtimeNano() + batchInfo.samplingPeriodNs;
148 batchEventRef.sensorHandle = sensorHandle;
149 batchEventRef.generation = ++batchInfo.generation;
150
151 m_batchQueue.push(batchEventRef);
152 m_batchUpdated.notify_one();
153 }
154
155 m_activeSensorsMask = m_activeSensorsMask | (1u << sensorHandle);
156 } else {
157 m_activeSensorsMask = m_activeSensorsMask & ~(1u << sensorHandle);
158 }
159 return Result::OK;
160 }
161
batch(const int32_t sensorHandle,const int64_t samplingPeriodNs,const int64_t maxReportLatencyNs)162 Return<Result> MultihalSensors::batch(const int32_t sensorHandle,
163 const int64_t samplingPeriodNs,
164 const int64_t maxReportLatencyNs) {
165 (void)maxReportLatencyNs;
166
167 if (!isSensorHandleValid(sensorHandle)) {
168 return Result::BAD_VALUE;
169 }
170
171 const SensorInfo* sensor = getSensorInfoByHandle(sensorHandle);
172 LOG_ALWAYS_FATAL_IF(!sensor);
173
174 if (samplingPeriodNs < sensor->minDelay) {
175 return Result::BAD_VALUE;
176 }
177
178 std::unique_lock<std::mutex> lock(m_mtx);
179 if (m_opMode == OperationMode::NORMAL) {
180 m_batchInfo[sensorHandle].samplingPeriodNs = samplingPeriodNs;
181 }
182
183 return Result::OK;
184 }
185
flush(const int32_t sensorHandle)186 Return<Result> MultihalSensors::flush(const int32_t sensorHandle) {
187 if (!isSensorHandleValid(sensorHandle)) {
188 return Result::BAD_VALUE;
189 }
190
191 const SensorInfo* sensor = getSensorInfoByHandle(sensorHandle);
192 LOG_ALWAYS_FATAL_IF(!sensor);
193
194 std::unique_lock<std::mutex> lock(m_mtx);
195 if (!isSensorActive(sensorHandle)) {
196 return Result::BAD_VALUE;
197 }
198
199 Event event;
200 event.sensorHandle = sensorHandle;
201 event.sensorType = SensorType::META_DATA;
202 event.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE;
203
204 doPostSensorEventLocked(*sensor, event);
205 return Result::OK;
206 }
207
injectSensorData(const Event & event)208 Return<Result> MultihalSensors::injectSensorData(const Event& event) {
209 if (!isSensorHandleValid(event.sensorHandle)) {
210 return Result::BAD_VALUE;
211 }
212 if (event.sensorType == SensorType::ADDITIONAL_INFO) {
213 return Result::OK;
214 }
215
216 std::unique_lock<std::mutex> lock(m_mtx);
217 if (m_opMode != OperationMode::DATA_INJECTION) {
218 return Result::INVALID_OPERATION;
219 }
220 const SensorInfo* sensor = getSensorInfoByHandle(event.sensorHandle);
221 LOG_ALWAYS_FATAL_IF(!sensor);
222 if (sensor->type != event.sensorType) {
223 return Result::BAD_VALUE;
224 }
225
226 doPostSensorEventLocked(*sensor, event);
227 return Result::OK;
228 }
229
initialize(const sp<IHalProxyCallback> & halProxyCallback)230 Return<Result> MultihalSensors::initialize(const sp<IHalProxyCallback>& halProxyCallback) {
231 std::unique_lock<std::mutex> lock(m_mtx);
232 setAllQemuSensors(true); // we need to start sampling sensors for batching
233 m_opMode = OperationMode::NORMAL;
234 m_halProxyCallback = halProxyCallback;
235 return Result::OK;
236 }
237
postSensorEvent(const Event & event)238 void MultihalSensors::postSensorEvent(const Event& event) {
239 const SensorInfo* sensor = getSensorInfoByHandle(event.sensorHandle);
240 LOG_ALWAYS_FATAL_IF(!sensor);
241
242 std::unique_lock<std::mutex> lock(m_mtx);
243 if (sensor->flags & static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE)) {
244 if (isSensorActive(event.sensorHandle)) {
245 doPostSensorEventLocked(*sensor, event);
246 }
247 } else { // CONTINUOUS_MODE
248 m_batchInfo[event.sensorHandle].event = event;
249 }
250 }
251
doPostSensorEventLocked(const SensorInfo & sensor,const Event & event)252 void MultihalSensors::doPostSensorEventLocked(const SensorInfo& sensor,
253 const Event& event) {
254 const bool isWakeupEvent =
255 sensor.flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
256
257 m_halProxyCallback->postEvents(
258 {event},
259 m_halProxyCallback->createScopedWakelock(isWakeupEvent));
260 }
261
qemuSensorThreadSendCommand(const char cmd) const262 bool MultihalSensors::qemuSensorThreadSendCommand(const char cmd) const {
263 return TEMP_FAILURE_RETRY(write(m_callersFd.get(), &cmd, 1)) == 1;
264 }
265
isSensorHandleValid(int sensorHandle) const266 bool MultihalSensors::isSensorHandleValid(int sensorHandle) const {
267 if (!goldfish::isSensorHandleValid(sensorHandle)) {
268 return false;
269 }
270
271 if (!(m_availableSensorsMask & (1u << sensorHandle))) {
272 return false;
273 }
274
275 return true;
276 }
277
batchThread()278 void MultihalSensors::batchThread() {
279 using high_resolution_clock = std::chrono::high_resolution_clock;
280
281 while (m_batchRunning) {
282 std::unique_lock<std::mutex> lock(m_mtx);
283 if (m_batchQueue.empty()) {
284 m_batchUpdated.wait(lock);
285 } else {
286 const int64_t t = m_batchQueue.top().timestamp;
287 const auto d = std::chrono::nanoseconds(t);
288 high_resolution_clock::time_point waitUntil(d);
289 m_batchUpdated.wait_until(lock, waitUntil);
290 }
291
292 const int64_t nowNs = ::android::elapsedRealtimeNano();
293 while (!m_batchQueue.empty() && (nowNs >= m_batchQueue.top().timestamp)) {
294 BatchEventRef evRef = m_batchQueue.top();
295 m_batchQueue.pop();
296
297 const int sensorHandle = evRef.sensorHandle;
298 LOG_ALWAYS_FATAL_IF(!goldfish::isSensorHandleValid(sensorHandle));
299 if (!isSensorActive(sensorHandle)) {
300 continue;
301 }
302
303 BatchInfo &batchInfo = m_batchInfo[sensorHandle];
304 if (batchInfo.event.sensorType == SensorType::META_DATA) {
305 ALOGW("%s:%d the host has not provided value yet for sensorHandle=%d",
306 __func__, __LINE__, sensorHandle);
307 } else {
308 batchInfo.event.timestamp = evRef.timestamp;
309 const SensorInfo* sensor = getSensorInfoByHandle(sensorHandle);
310 LOG_ALWAYS_FATAL_IF(!sensor);
311 doPostSensorEventLocked(*sensor, batchInfo.event);
312 }
313
314 if (evRef.generation == batchInfo.generation) {
315 const int64_t samplingPeriodNs = batchInfo.samplingPeriodNs;
316 LOG_ALWAYS_FATAL_IF(samplingPeriodNs <= 0);
317
318 evRef.timestamp += samplingPeriodNs;
319 m_batchQueue.push(evRef);
320 }
321 }
322 }
323 }
324
325 /// not supported //////////////////////////////////////////////////////////////
registerDirectChannel(const SharedMemInfo & mem,registerDirectChannel_cb _hidl_cb)326 Return<void> MultihalSensors::registerDirectChannel(const SharedMemInfo& mem,
327 registerDirectChannel_cb _hidl_cb) {
328 (void)mem;
329 _hidl_cb(Result::INVALID_OPERATION, -1);
330 return {};
331 }
332
unregisterDirectChannel(int32_t channelHandle)333 Return<Result> MultihalSensors::unregisterDirectChannel(int32_t channelHandle) {
334 (void)channelHandle;
335 return Result::INVALID_OPERATION;
336 }
337
configDirectReport(int32_t sensorHandle,int32_t channelHandle,RateLevel rate,configDirectReport_cb _hidl_cb)338 Return<void> MultihalSensors::configDirectReport(int32_t sensorHandle,
339 int32_t channelHandle,
340 RateLevel rate,
341 configDirectReport_cb _hidl_cb) {
342 (void)sensorHandle;
343 (void)channelHandle;
344 (void)rate;
345 _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */);
346 return {};
347 }
348
349 } // namespace goldfish
350