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 <cstdint>
18 #include <log/log.h>
19 #include <utils/SystemClock.h>
20 #include <multihal_sensors.h>
21 #include "sensor_list.h"
22
23 namespace goldfish {
24 using ahs21::SensorType;
25 using ahs10::EventPayload;
26 using ahs10::SensorFlagBits;
27 using ahs10::SensorStatus;
28 using ahs10::MetaDataEventType;
29 using ahs10::AdditionalInfoType;
30
31 namespace {
32 constexpr int64_t kMaxSamplingPeriodNs = 1000000000;
33
34 struct SensorsTransportStub : public SensorsTransport {
Sendgoldfish::__anon077a7bc70111::SensorsTransportStub35 int Send(const void*, int) override { return -1; }
Receivegoldfish::__anon077a7bc70111::SensorsTransportStub36 int Receive(void*, int) override { return -1; }
Okgoldfish::__anon077a7bc70111::SensorsTransportStub37 bool Ok() const override { return false; }
Fdgoldfish::__anon077a7bc70111::SensorsTransportStub38 int Fd() const override { return -1; }
Namegoldfish::__anon077a7bc70111::SensorsTransportStub39 const char* Name() const override { return "stub"; }
40 };
41
42 const SensorsTransportStub g_sensorsTransportStub;
43 }
44
MultihalSensors(SensorsTransportFactory stf)45 MultihalSensors::MultihalSensors(SensorsTransportFactory stf)
46 : m_sensorsTransportFactory(std::move(stf))
47 , m_sensorsTransport(const_cast<SensorsTransportStub*>(&g_sensorsTransportStub))
48 , m_batchInfo(getSensorNumber()) {
49 {
50 const auto st = m_sensorsTransportFactory();
51
52 LOG_ALWAYS_FATAL_IF(!st->Ok(), "%s:%d: sensors transport is not opened",
53 __func__, __LINE__);
54
55 using namespace std::literals;
56 const std::string_view kListSensorsCmd = "list-sensors"sv;
57
58 LOG_ALWAYS_FATAL_IF(st->Send(kListSensorsCmd.data(), kListSensorsCmd.size()) < 0,
59 "%s:%d: send for %s failed", __func__, __LINE__, st->Name());
60
61 char buffer[64];
62 const int len = st->Receive(buffer, sizeof(buffer) - 1);
63 LOG_ALWAYS_FATAL_IF(len < 0, "%s:%d: receive for %s failed", __func__, __LINE__,
64 st->Name());
65
66 buffer[len] = 0;
67 uint32_t hostSensorsMask = 0;
68 LOG_ALWAYS_FATAL_IF(sscanf(buffer, "%u", &hostSensorsMask) != 1,
69 "%s:%d: Can't parse qemud response", __func__, __LINE__);
70
71 m_availableSensorsMask = hostSensorsMask & ((1u << getSensorNumber()) - 1);
72
73 ALOGI("%s:%d: host sensors mask=%x, available sensors mask=%x",
74 __func__, __LINE__, hostSensorsMask, m_availableSensorsMask);
75 }
76
77 LOG_ALWAYS_FATAL_IF(!::android::base::Socketpair(AF_LOCAL, SOCK_STREAM, 0,
78 &m_callersFd, &m_sensorThreadFd),
79 "%s:%d: Socketpair failed", __func__, __LINE__);
80
81 setAdditionalInfoFrames();
82
83 m_sensorThread = std::thread(&MultihalSensors::qemuSensorListenerThread, this);
84 m_batchThread = std::thread(&MultihalSensors::batchThread, this);
85 }
86
~MultihalSensors()87 MultihalSensors::~MultihalSensors() {
88 m_batchRunning = false;
89 m_batchUpdated.notify_one();
90 m_batchThread.join();
91
92 qemuSensorThreadSendCommand(kCMD_QUIT);
93 m_sensorThread.join();
94 }
95
getName()96 const std::string MultihalSensors::getName() {
97 return "hal_sensors_2_1_impl_ranchu";
98 }
99
debug(const hidl_handle & fd,const hidl_vec<hidl_string> & args)100 Return<void> MultihalSensors::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
101 (void)fd;
102 (void)args;
103 return {};
104 }
105
getSensorsList_2_1(getSensorsList_2_1_cb _hidl_cb)106 Return<void> MultihalSensors::getSensorsList_2_1(getSensorsList_2_1_cb _hidl_cb) {
107 std::vector<SensorInfo> sensors;
108
109 uint32_t mask = m_availableSensorsMask;
110 for (int i = 0; mask; ++i, mask >>= 1) {
111 if (mask & 1) {
112 sensors.push_back(*getSensorInfoByHandle(i));
113 }
114 }
115
116 _hidl_cb(sensors);
117 return {};
118 }
119
setOperationMode(const OperationMode mode)120 Return<Result> MultihalSensors::setOperationMode(const OperationMode mode) {
121 std::unique_lock<std::mutex> lock(m_mtx);
122
123 if (m_activeSensorsMask) {
124 return Result::INVALID_OPERATION;
125 } else {
126 m_opMode = mode;
127 return Result::OK;
128 }
129 }
130
activate(const int32_t sensorHandle,const bool enabled)131 Return<Result> MultihalSensors::activate(const int32_t sensorHandle,
132 const bool enabled) {
133 if (!isSensorHandleValid(sensorHandle)) {
134 return Result::BAD_VALUE;
135 }
136
137 std::unique_lock<std::mutex> lock(m_mtx);
138 BatchInfo& batchInfo = m_batchInfo[sensorHandle];
139
140 if (enabled) {
141 const SensorInfo* sensor = getSensorInfoByHandle(sensorHandle);
142 LOG_ALWAYS_FATAL_IF(!sensor);
143 if (sensor->flags & static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE)) {
144 doPostSensorEventLocked(*sensor,
145 activationOnChangeSensorEvent(sensorHandle, *sensor));
146 } else {
147 if (batchInfo.samplingPeriodNs <= 0) {
148 return Result::BAD_VALUE;
149 }
150
151 BatchEventRef batchEventRef;
152 batchEventRef.timestamp =
153 ::android::elapsedRealtimeNano() + batchInfo.samplingPeriodNs;
154 batchEventRef.sensorHandle = sensorHandle;
155 batchEventRef.generation = ++batchInfo.generation;
156
157 m_batchQueue.push(batchEventRef);
158 m_batchUpdated.notify_one();
159 }
160 sendAdditionalInfoReport(sensorHandle);
161 m_activeSensorsMask = m_activeSensorsMask | (1u << sensorHandle);
162 } else {
163 m_activeSensorsMask = m_activeSensorsMask & ~(1u << sensorHandle);
164 }
165 return Result::OK;
166 }
167
activationOnChangeSensorEvent(const int32_t sensorHandle,const SensorInfo & sensor) const168 Event MultihalSensors::activationOnChangeSensorEvent(const int32_t sensorHandle,
169 const SensorInfo& sensor) const {
170 Event event;
171 EventPayload* payload = &event.u;
172
173 switch (sensor.type) {
174 case SensorType::LIGHT:
175 payload->scalar = m_protocolState.lastLightValue;
176 break;
177
178 case SensorType::PROXIMITY:
179 payload->scalar = m_protocolState.lastProximityValue;
180 break;
181
182 case SensorType::RELATIVE_HUMIDITY:
183 payload->scalar = m_protocolState.lastRelativeHumidityValue;
184 break;
185
186 case SensorType::AMBIENT_TEMPERATURE:
187 payload->scalar = m_protocolState.kSensorNoValue;
188 break;
189
190 case SensorType::HEART_RATE:
191 // Heart rate sensor's first data after activation should be
192 // SENSOR_STATUS_UNRELIABLE.
193 payload->heartRate.status = SensorStatus::UNRELIABLE;
194 payload->heartRate.bpm = 0;
195 break;
196
197 case SensorType::HINGE_ANGLE:
198 switch (sensorHandle) {
199 case kSensorHandleHingeAngle0:
200 payload->scalar = m_protocolState.lastHingeAngle0Value;
201 break;
202
203 case kSensorHandleHingeAngle1:
204 payload->scalar = m_protocolState.lastHingeAngle1Value;
205 break;
206
207 case kSensorHandleHingeAngle2:
208 payload->scalar = m_protocolState.lastHingeAngle2Value;
209 break;
210
211 default:
212 LOG_ALWAYS_FATAL("%s:%d: unexpected hinge sensor: %d",
213 __func__, __LINE__, sensorHandle);
214 break;
215 }
216 break;
217
218 default:
219 LOG_ALWAYS_FATAL("%s:%d: unexpected sensor type: %u",
220 __func__, __LINE__, static_cast<unsigned>(sensor.type));
221 break;
222 }
223
224 event.sensorHandle = sensorHandle;
225 event.sensorType = sensor.type;
226 event.timestamp = ::android::elapsedRealtimeNano();
227
228 return event;
229 }
230
batch(const int32_t sensorHandle,const int64_t samplingPeriodNs,const int64_t maxReportLatencyNs)231 Return<Result> MultihalSensors::batch(const int32_t sensorHandle,
232 const int64_t samplingPeriodNs,
233 const int64_t maxReportLatencyNs) {
234 (void)maxReportLatencyNs;
235
236 if (!isSensorHandleValid(sensorHandle)) {
237 return Result::BAD_VALUE;
238 }
239
240 const SensorInfo* sensor = getSensorInfoByHandle(sensorHandle);
241 LOG_ALWAYS_FATAL_IF(!sensor);
242
243 if (samplingPeriodNs < sensor->minDelay) {
244 return Result::BAD_VALUE;
245 }
246
247 std::unique_lock<std::mutex> lock(m_mtx);
248 if (m_opMode == OperationMode::NORMAL) {
249 m_batchInfo[sensorHandle].samplingPeriodNs = samplingPeriodNs;
250
251 auto minSamplingPeriodNs = kMaxSamplingPeriodNs;
252 auto activeSensorsMask = m_activeSensorsMask;
253 for (const auto& b : m_batchInfo) {
254 if (activeSensorsMask & 1) {
255 const auto periodNs = b.samplingPeriodNs;
256 if ((periodNs > 0) && (periodNs < minSamplingPeriodNs)) {
257 minSamplingPeriodNs = periodNs;
258 }
259 }
260
261 activeSensorsMask >>= 1;
262 }
263
264 const uint32_t sensorsUpdateIntervalMs = std::max(1, int(minSamplingPeriodNs / 1000000));
265 m_protocolState.sensorsUpdateIntervalMs = sensorsUpdateIntervalMs;
266 if (!setSensorsUpdateIntervalMs(*m_sensorsTransport, sensorsUpdateIntervalMs)) {
267 qemuSensorThreadSendCommand(kCMD_RESTART);
268 }
269 }
270
271 return Result::OK;
272 }
273
flush(const int32_t sensorHandle)274 Return<Result> MultihalSensors::flush(const int32_t sensorHandle) {
275 if (!isSensorHandleValid(sensorHandle)) {
276 return Result::BAD_VALUE;
277 }
278
279 const SensorInfo* sensor = getSensorInfoByHandle(sensorHandle);
280 LOG_ALWAYS_FATAL_IF(!sensor);
281
282 std::unique_lock<std::mutex> lock(m_mtx);
283 if (!isSensorActive(sensorHandle)) {
284 return Result::BAD_VALUE;
285 }
286
287 Event event;
288 event.sensorHandle = sensorHandle;
289 event.sensorType = SensorType::META_DATA;
290 event.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE;
291
292 doPostSensorEventLocked(*sensor, event);
293 sendAdditionalInfoReport(sensorHandle);
294
295 return Result::OK;
296 }
297
injectSensorData_2_1(const Event & event)298 Return<Result> MultihalSensors::injectSensorData_2_1(const Event& event) {
299 if (!isSensorHandleValid(event.sensorHandle)) {
300 return Result::BAD_VALUE;
301 }
302 if (event.sensorType == SensorType::ADDITIONAL_INFO) {
303 return Result::OK;
304 }
305
306 std::unique_lock<std::mutex> lock(m_mtx);
307 if (m_opMode != OperationMode::DATA_INJECTION) {
308 return Result::INVALID_OPERATION;
309 }
310 const SensorInfo* sensor = getSensorInfoByHandle(event.sensorHandle);
311 LOG_ALWAYS_FATAL_IF(!sensor);
312 if (sensor->type != event.sensorType) {
313 return Result::BAD_VALUE;
314 }
315
316 doPostSensorEventLocked(*sensor, event);
317 return Result::OK;
318 }
319
initialize(const sp<IHalProxyCallback> & halProxyCallback)320 Return<Result> MultihalSensors::initialize(const sp<IHalProxyCallback>& halProxyCallback) {
321 std::unique_lock<std::mutex> lock(m_mtx);
322 m_opMode = OperationMode::NORMAL;
323 m_halProxyCallback = halProxyCallback;
324 return Result::OK;
325 }
326
postSensorEventLocked(const Event & event)327 void MultihalSensors::postSensorEventLocked(const Event& event) {
328 const SensorInfo* sensor = getSensorInfoByHandle(event.sensorHandle);
329 LOG_ALWAYS_FATAL_IF(!sensor);
330
331 if (sensor->flags & static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE)) {
332 if (isSensorActive(event.sensorHandle)) {
333 doPostSensorEventLocked(*sensor, event);
334 }
335 } else { // CONTINUOUS_MODE
336 m_batchInfo[event.sensorHandle].event = event;
337 }
338 }
339
doPostSensorEventLocked(const SensorInfo & sensor,const Event & event)340 void MultihalSensors::doPostSensorEventLocked(const SensorInfo& sensor,
341 const Event& event) {
342 const bool isWakeupEvent =
343 sensor.flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
344
345 m_halProxyCallback->postEvents(
346 {event},
347 m_halProxyCallback->createScopedWakelock(isWakeupEvent));
348 }
349
setAdditionalInfoFrames()350 void MultihalSensors::setAdditionalInfoFrames() {
351 // https://developer.android.com/reference/android/hardware/SensorAdditionalInfo#TYPE_SENSOR_PLACEMENT
352 AdditionalInfo additionalInfoSensorPlacement = {
353 .type = AdditionalInfoType::AINFO_SENSOR_PLACEMENT,
354 .serial = 0,
355 .u.data_float{ {0, 1, 0, 0, -1, 0, 0, 10, 0, 0, 1, -2.5} },
356 };
357 const AdditionalInfo additionalInfoBegin = {
358 .type = AdditionalInfoType::AINFO_BEGIN,
359 .serial = 0,
360 };
361 const AdditionalInfo additionalInfoEnd = {
362 .type = AdditionalInfoType::AINFO_END,
363 .serial = 0,
364 };
365
366 mAdditionalInfoFrames.insert(
367 mAdditionalInfoFrames.end(),
368 {additionalInfoBegin, additionalInfoSensorPlacement, additionalInfoEnd});
369 }
370
sendAdditionalInfoReport(int sensorHandle)371 void MultihalSensors::sendAdditionalInfoReport(int sensorHandle) {
372 const SensorInfo* sensor = getSensorInfoByHandle(sensorHandle);
373 const bool isWakeupEvent =
374 sensor->flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
375 std::vector<Event> events;
376
377 for (const auto& frame : mAdditionalInfoFrames) {
378 events.emplace_back(Event{
379 .timestamp = android::elapsedRealtimeNano(),
380 .sensorHandle = sensorHandle,
381 .sensorType = SensorType::ADDITIONAL_INFO,
382 .u.additional = frame,
383 });
384 }
385
386 if (!events.empty()) {
387 m_halProxyCallback->postEvents(
388 events,
389 m_halProxyCallback->createScopedWakelock(isWakeupEvent));
390 }
391 }
392
qemuSensorThreadSendCommand(const char cmd) const393 bool MultihalSensors::qemuSensorThreadSendCommand(const char cmd) const {
394 return TEMP_FAILURE_RETRY(write(m_callersFd.get(), &cmd, 1)) == 1;
395 }
396
isSensorHandleValid(int sensorHandle) const397 bool MultihalSensors::isSensorHandleValid(int sensorHandle) const {
398 if (!goldfish::isSensorHandleValid(sensorHandle)) {
399 return false;
400 }
401
402 if (!(m_availableSensorsMask & (1u << sensorHandle))) {
403 return false;
404 }
405
406 return true;
407 }
408
qemuSensorListenerThread()409 void MultihalSensors::qemuSensorListenerThread() {
410 while (true) {
411 const auto st = m_sensorsTransportFactory();
412
413 LOG_ALWAYS_FATAL_IF(!setSensorsGuestTime(
414 *st, ::android::elapsedRealtimeNano()));
415 LOG_ALWAYS_FATAL_IF(!setSensorsUpdateIntervalMs(
416 *st, m_protocolState.sensorsUpdateIntervalMs));
417 LOG_ALWAYS_FATAL_IF(!setAllSensorsReporting(
418 *st, m_availableSensorsMask, true));
419
420 {
421 std::unique_lock<std::mutex> lock(m_mtx);
422 m_sensorsTransport = st.get();
423 }
424
425 const bool cont = qemuSensorListenerThreadImpl(st->Fd());
426
427 {
428 std::unique_lock<std::mutex> lock(m_mtx);
429 m_sensorsTransport = const_cast<SensorsTransportStub*>(&g_sensorsTransportStub);
430 }
431
432 if (!cont) {
433 break;
434 }
435 }
436 }
437
batchThread()438 void MultihalSensors::batchThread() {
439 while (m_batchRunning) {
440 std::unique_lock<std::mutex> lock(m_mtx);
441 if (m_batchQueue.empty()) {
442 m_batchUpdated.wait(lock);
443 } else {
444 const int64_t d =
445 m_batchQueue.top().timestamp - ::android::elapsedRealtimeNano();
446 m_batchUpdated.wait_for(lock, std::chrono::nanoseconds(d));
447 }
448
449 const int64_t nowNs = ::android::elapsedRealtimeNano();
450 while (!m_batchQueue.empty() && (nowNs >= m_batchQueue.top().timestamp)) {
451 BatchEventRef evRef = m_batchQueue.top();
452 m_batchQueue.pop();
453
454 const int sensorHandle = evRef.sensorHandle;
455 LOG_ALWAYS_FATAL_IF(!goldfish::isSensorHandleValid(sensorHandle));
456 if (!isSensorActive(sensorHandle)) {
457 continue;
458 }
459
460 BatchInfo &batchInfo = m_batchInfo[sensorHandle];
461 if (batchInfo.event.sensorType == SensorType::META_DATA) {
462 ALOGW("%s:%d the host has not provided value yet for sensorHandle=%d",
463 __func__, __LINE__, sensorHandle);
464 } else {
465 batchInfo.event.timestamp = evRef.timestamp;
466 const SensorInfo* sensor = getSensorInfoByHandle(sensorHandle);
467 LOG_ALWAYS_FATAL_IF(!sensor);
468 doPostSensorEventLocked(*sensor, batchInfo.event);
469 }
470
471 if (evRef.generation == batchInfo.generation) {
472 const int64_t samplingPeriodNs = batchInfo.samplingPeriodNs;
473 LOG_ALWAYS_FATAL_IF(samplingPeriodNs <= 0);
474
475 evRef.timestamp += samplingPeriodNs;
476 m_batchQueue.push(evRef);
477 }
478 }
479 }
480 }
481
482 /// not supported //////////////////////////////////////////////////////////////
registerDirectChannel(const SharedMemInfo & mem,registerDirectChannel_cb _hidl_cb)483 Return<void> MultihalSensors::registerDirectChannel(const SharedMemInfo& mem,
484 registerDirectChannel_cb _hidl_cb) {
485 (void)mem;
486 _hidl_cb(Result::INVALID_OPERATION, -1);
487 return {};
488 }
489
unregisterDirectChannel(int32_t channelHandle)490 Return<Result> MultihalSensors::unregisterDirectChannel(int32_t channelHandle) {
491 (void)channelHandle;
492 return Result::INVALID_OPERATION;
493 }
494
configDirectReport(int32_t sensorHandle,int32_t channelHandle,RateLevel rate,configDirectReport_cb _hidl_cb)495 Return<void> MultihalSensors::configDirectReport(int32_t sensorHandle,
496 int32_t channelHandle,
497 RateLevel rate,
498 configDirectReport_cb _hidl_cb) {
499 (void)sensorHandle;
500 (void)channelHandle;
501 (void)rate;
502 _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */);
503 return {};
504 }
505
506 } // namespace goldfish
507