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