• 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 #pragma once
18 #include <android-base/unique_fd.h>
19 #include <V2_1/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 ahs21 = ahs::V2_1;
30 namespace ahs10 = ahs::V1_0;
31 
32 using ahs21::implementation::IHalProxyCallback;
33 using ahs21::SensorInfo;
34 using ahs21::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 ahs21::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_2_1(getSensorsList_2_1_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_2_1(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         float lastHingeAngle0Value = kSensorNoValue;
85         float lastHingeAngle1Value = kSensorNoValue;
86         float lastHingeAngle2Value = kSensorNoValue;
87     };
88 
89     bool isSensorHandleValid(int sensorHandle) const;
isSensorActiveMultihalSensors90     bool isSensorActive(int sensorHandle) const {
91         return m_activeSensorsMask & (1u << sensorHandle);  // m_mtx required
92     }
93     static bool activateQemuSensorImpl(int pipe, int sensorHandle, bool enabled);
94     bool setAllQemuSensors(bool enabled);
95     void parseQemuSensorEvent(const int pipe, QemuSensorsProtocolState* state);
96     void postSensorEvent(const Event& event);
97     void doPostSensorEventLocked(const SensorInfo& sensor, const Event& event);
98 
99     void qemuSensorListenerThread();
100     void batchThread();
101 
102     static constexpr char kCMD_QUIT = 'q';
103     bool qemuSensorThreadSendCommand(char cmd) const;
104 
105     // set in ctor, never change
106     const unique_fd     m_qemuSensorsFd;
107     uint32_t            m_availableSensorsMask = 0;
108     // a pair of connected sockets to talk to the worker thread
109     unique_fd           m_callersFd;        // a caller writes here
110     unique_fd           m_sensorThreadFd;   // the worker thread listens from here
111     std::thread         m_sensorThread;
112 
113     // changed by API
114     uint32_t                m_activeSensorsMask = 0;
115     OperationMode           m_opMode = OperationMode::NORMAL;
116     sp<IHalProxyCallback>   m_halProxyCallback;
117 
118     // batching
119     struct BatchEventRef {
120         int64_t  timestamp = -1;
121         int      sensorHandle = -1;
122         int      generation = 0;
123 
124         bool operator<(const BatchEventRef &rhs) const {
125             // not a typo, we want m_batchQueue.top() to be the smallest timestamp
126             return timestamp > rhs.timestamp;
127         }
128     };
129 
130     struct BatchInfo {
131         Event       event;
132         int64_t     samplingPeriodNs = 0;
133         int         generation = 0;
134     };
135 
136     std::priority_queue<BatchEventRef>      m_batchQueue;
137     std::vector<BatchInfo>                  m_batchInfo;
138     std::condition_variable                 m_batchUpdated;
139     std::thread                             m_batchThread;
140     std::atomic<bool>                       m_batchRunning = true;
141 
142     mutable std::mutex                      m_mtx;
143 };
144 
145 }  // namespace goldfish
146