• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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