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