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