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