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 #pragma once
18 #include <android-base/unique_fd.h>
19 #include <SubHal.h>
20 #include <atomic>
21 #include <condition_variable>
22 #include <cstdint>
23 #include <queue>
24 #include <thread>
25 #include <vector>
26 
27 namespace goldfish {
28 namespace ahs = ::android::hardware::sensors;
29 namespace ahs20 = ahs::V2_0;
30 namespace ahs10 = ahs::V1_0;
31 
32 using ahs20::implementation::IHalProxyCallback;
33 using ahs10::SensorInfo;
34 using ahs10::Event;
35 using ahs10::OperationMode;
36 using ahs10::RateLevel;
37 using ahs10::Result;
38 using ahs10::SharedMemInfo;
39 
40 using ::android::base::unique_fd;
41 using ::android::hardware::hidl_handle;
42 using ::android::hardware::hidl_string;
43 using ::android::hardware::hidl_vec;
44 using ::android::hardware::Return;
45 using ::android::sp;
46 
47 struct MultihalSensors : public ahs20::implementation::ISensorsSubHal {
48     MultihalSensors();
49     ~MultihalSensors();
50 
51     Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
52     Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
53     Return<Result> setOperationMode(OperationMode mode) override;
54     Return<Result> activate(int32_t sensorHandle, bool enabled) override;
55     Return<Result> batch(int32_t sensorHandle,
56                            int64_t samplingPeriodNs,
57                            int64_t maxReportLatencyNs) override;
58     Return<Result> flush(int32_t sensorHandle) override;
59     Return<Result> injectSensorData(const Event& event) override;
60 
61 
62     Return<void> registerDirectChannel(const SharedMemInfo& mem,
63                                        registerDirectChannel_cb _hidl_cb) override;
64     Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
65     Return<void> configDirectReport(int32_t sensorHandle,
66                                     int32_t channelHandle,
67                                     RateLevel rate,
68                                     configDirectReport_cb _hidl_cb) override;
69 
70     const std::string getName() override;
71     Return<Result> initialize(const sp<IHalProxyCallback>& halProxyCallback) override;
72 
73 private:
74     struct QemuSensorsProtocolState {
75         int64_t timeBiasNs = -500000000;
76 
77         static constexpr float kSensorNoValue = -1e+30;
78 
79         // on change sensors (host does not support them)
80         float lastAmbientTemperatureValue = kSensorNoValue;
81         float lastProximityValue = kSensorNoValue;
82         float lastLightValue = kSensorNoValue;
83         float lastRelativeHumidityValue = kSensorNoValue;
84     };
85 
86     bool isSensorHandleValid(int sensorHandle) const;
isSensorActiveMultihalSensors87     bool isSensorActive(int sensorHandle) const {
88         return m_activeSensorsMask & (1u << sensorHandle);  // m_mtx required
89     }
90     static bool activateQemuSensorImpl(int pipe, int sensorHandle, bool enabled);
91     bool setAllQemuSensors(bool enabled);
92     void parseQemuSensorEvent(const int pipe, QemuSensorsProtocolState* state);
93     void postSensorEvent(const Event& event);
94     void doPostSensorEventLocked(const SensorInfo& sensor, const Event& event);
95 
96     void qemuSensorListenerThread();
97     void batchThread();
98 
99     static constexpr char kCMD_QUIT = 'q';
100     bool qemuSensorThreadSendCommand(char cmd) const;
101 
102     // set in ctor, never change
103     const unique_fd     m_qemuSensorsFd;
104     uint32_t            m_availableSensorsMask = 0;
105     // a pair of connected sockets to talk to the worker thread
106     unique_fd           m_callersFd;        // a caller writes here
107     unique_fd           m_sensorThreadFd;   // the worker thread listens from here
108     std::thread         m_sensorThread;
109 
110     // changed by API
111     uint32_t                m_activeSensorsMask = 0;
112     OperationMode           m_opMode = OperationMode::NORMAL;
113     sp<IHalProxyCallback>   m_halProxyCallback;
114 
115     // batching
116     struct BatchEventRef {
117         int64_t  timestamp = -1;
118         int      sensorHandle = -1;
119         int      generation = 0;
120 
121         bool operator<(const BatchEventRef &rhs) const {
122             // not a typo, we want m_batchQueue.top() to be the smallest timestamp
123             return timestamp > rhs.timestamp;
124         }
125     };
126 
127     struct BatchInfo {
128         Event       event;
129         int64_t     samplingPeriodNs = 0;
130         int         generation = 0;
131     };
132 
133     std::priority_queue<BatchEventRef>      m_batchQueue;
134     std::vector<BatchInfo>                  m_batchInfo;
135     std::condition_variable                 m_batchUpdated;
136     std::thread                             m_batchThread;
137     std::atomic<bool>                       m_batchRunning = true;
138 
139     mutable std::mutex                      m_mtx;
140 };
141 
142 }  // namespace goldfish
143