1 /*
2  * Copyright (C) 2019 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 
19 #include "ScopedWakelock.h"
20 #include "SubHal.h"
21 
22 #include <android/hardware/sensors/2.0/ISensors.h>
23 #include <android/hardware/sensors/2.0/types.h>
24 #include <fmq/MessageQueue.h>
25 #include <hardware_legacy/power.h>
26 #include <hidl/MQDescriptor.h>
27 #include <hidl/Status.h>
28 
29 #include <atomic>
30 #include <condition_variable>
31 #include <map>
32 #include <mutex>
33 #include <queue>
34 #include <thread>
35 #include <utility>
36 
37 namespace android {
38 namespace hardware {
39 namespace sensors {
40 namespace V2_0 {
41 namespace implementation {
42 
43 using ::android::sp;
44 using ::android::hardware::EventFlag;
45 using ::android::hardware::hidl_string;
46 using ::android::hardware::hidl_vec;
47 using ::android::hardware::MessageQueue;
48 using ::android::hardware::MQDescriptor;
49 using ::android::hardware::Return;
50 using ::android::hardware::Void;
51 
52 class HalProxy : public ISensors, public IScopedWakelockRefCounter {
53   public:
54     using Event = ::android::hardware::sensors::V1_0::Event;
55     using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
56     using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
57     using Result = ::android::hardware::sensors::V1_0::Result;
58     using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
59     using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
60     using ISensorsSubHal = ::android::hardware::sensors::V2_0::implementation::ISensorsSubHal;
61 
62     explicit HalProxy();
63     // Test only constructor.
64     explicit HalProxy(std::vector<ISensorsSubHal*>& subHalList);
65     ~HalProxy();
66 
67     // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
68     Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
69 
70     Return<Result> setOperationMode(OperationMode mode) override;
71 
72     Return<Result> activate(int32_t sensorHandle, bool enabled) override;
73 
74     Return<Result> initialize(
75             const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
76             const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
77             const sp<ISensorsCallback>& sensorsCallback) override;
78 
79     Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
80                          int64_t maxReportLatencyNs) override;
81 
82     Return<Result> flush(int32_t sensorHandle) override;
83 
84     Return<Result> injectSensorData(const Event& event) override;
85 
86     Return<void> registerDirectChannel(const SharedMemInfo& mem,
87                                        registerDirectChannel_cb _hidl_cb) override;
88 
89     Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
90 
91     Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
92                                     configDirectReport_cb _hidl_cb) override;
93 
94     Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
95 
96     // Below methods from ::android::hardware::sensors::V2_0::ISensorsCallback with a minor change
97     // to pass in the sub-HAL index. While the above methods are invoked from the sensors framework
98     // via the binder, these methods are invoked from a callback provided to sub-HALs inside the
99     // same process as the HalProxy, but potentially running on different threads.
100     Return<void> onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dynamicSensorsAdded,
101                                            int32_t subHalIndex);
102 
103     Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& dynamicSensorHandlesRemoved,
104                                               int32_t subHalIndex);
105 
106     // Below methods are for HalProxyCallback
107 
108     /**
109      * Post events to the event message queue if there is room to write them. Otherwise post the
110      * remaining events to a background thread for a blocking write with a kPendingWriteTimeoutNs
111      * timeout.
112      *
113      * @param events The list of events to post to the message queue.
114      * @param numWakeupEvents The number of wakeup events in events.
115      * @param wakelock The wakelock associated with this post of events.
116      */
117     void postEventsToMessageQueue(const std::vector<Event>& events, size_t numWakeupEvents,
118                                   ScopedWakelock wakelock);
119 
120     /**
121      * Get the sensor info associated with that sensorHandle.
122      *
123      * @param sensorHandle The sensor handle.
124      *
125      * @return The sensor info object in the mapping.
126      */
getSensorInfo(int32_t sensorHandle)127     const SensorInfo& getSensorInfo(int32_t sensorHandle) { return mSensors[sensorHandle]; }
128 
areThreadsRunning()129     bool areThreadsRunning() { return mThreadsRun.load(); }
130 
131     // Below methods are from IScopedWakelockRefCounter interface
132     bool incrementRefCountAndMaybeAcquireWakelock(size_t delta,
133                                                   int64_t* timeoutStart = nullptr) override;
134 
135     void decrementRefCountAndMaybeReleaseWakelock(size_t delta, int64_t timeoutStart = -1) override;
136 
137   private:
138     using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
139     using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
140 
141     /**
142      * The Event FMQ where sensor events are written
143      */
144     std::unique_ptr<EventMessageQueue> mEventQueue;
145 
146     /**
147      * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events
148      */
149     std::unique_ptr<WakeLockMessageQueue> mWakeLockQueue;
150 
151     /**
152      * Event Flag to signal to the framework when sensor events are available to be read and to
153      * interrupt event queue blocking write.
154      */
155     EventFlag* mEventQueueFlag = nullptr;
156 
157     //! Event Flag to signal internally that the wakelock queue should stop its blocking read.
158     EventFlag* mWakelockQueueFlag = nullptr;
159 
160     /**
161      * Callback to the sensors framework to inform it that new sensors have been added or removed.
162      */
163     sp<ISensorsCallback> mDynamicSensorsCallback;
164 
165     /**
166      * SubHal object pointers that have been saved from vendor dynamic libraries.
167      */
168     std::vector<ISensorsSubHal*> mSubHalList;
169 
170     //! The list of subhal callbacks for each subhal where the indices correlate with mSubHalList
171     std::vector<const sp<IHalProxyCallback>> mSubHalCallbacks;
172 
173     /**
174      * Map of sensor handles to SensorInfo objects that contains the sensor info from subhals as
175      * well as the modified sensor handle for the framework.
176      *
177      * The subhal index is encoded in the first byte of the sensor handle and the remaining
178      * bytes are generated by the subhal to identify the sensor.
179      */
180     std::map<int32_t, SensorInfo> mSensors;
181 
182     //! Map of the dynamic sensors that have been added to halproxy.
183     std::map<int32_t, SensorInfo> mDynamicSensors;
184 
185     //! The current operation mode for all subhals.
186     OperationMode mCurrentOperationMode = OperationMode::NORMAL;
187 
188     //! The single subHal that supports directChannel reporting.
189     ISensorsSubHal* mDirectChannelSubHal = nullptr;
190 
191     //! The timeout for each pending write on background thread for events.
192     static const int64_t kPendingWriteTimeoutNs = 5 * INT64_C(1000000000) /* 5 seconds */;
193 
194     //! The bit mask used to get the subhal index from a sensor handle.
195     static constexpr int32_t kSensorHandleSubHalIndexMask = 0xFF000000;
196 
197     /**
198      * A FIFO queue of pairs of vector of events and the number of wakeup events in that vector
199      * which are waiting to be written to the events fmq in the background thread.
200      */
201     std::queue<std::pair<std::vector<Event>, size_t>> mPendingWriteEventsQueue;
202 
203     //! The most events observed on the pending write events queue for debug purposes.
204     size_t mMostEventsObservedPendingWriteEventsQueue = 0;
205 
206     //! The max number of events allowed in the pending write events queue
207     static constexpr size_t kMaxSizePendingWriteEventsQueue = 100000;
208 
209     //! The number of events in the pending write events queue
210     size_t mSizePendingWriteEventsQueue = 0;
211 
212     //! The mutex protecting writing to the fmq and the pending events queue
213     std::mutex mEventQueueWriteMutex;
214 
215     //! The condition variable waiting on pending write events to stack up
216     std::condition_variable mEventQueueWriteCV;
217 
218     //! The thread object ptr that handles pending writes
219     std::thread mPendingWritesThread;
220 
221     //! The thread object that handles wakelocks
222     std::thread mWakelockThread;
223 
224     //! The bool indicating whether to end the threads started in initialize
225     std::atomic_bool mThreadsRun = true;
226 
227     //! The mutex protecting access to the dynamic sensors added and removed methods.
228     std::mutex mDynamicSensorsMutex;
229 
230     // WakelockRefCount membar vars below
231 
232     //! The mutex protecting the wakelock refcount and subsequent wakelock releases and
233     //! acquisitions
234     std::recursive_mutex mWakelockMutex;
235 
236     std::condition_variable_any mWakelockCV;
237 
238     //! The refcount of how many ScopedWakelocks and pending wakeup events are active
239     size_t mWakelockRefCount = 0;
240 
241     int64_t mWakelockTimeoutStartTime = getTimeNow();
242 
243     int64_t mWakelockTimeoutResetTime = getTimeNow();
244 
245     const char* kWakelockName = "SensorsHAL_WAKEUP";
246 
247     /**
248      * Initialize the list of SubHal objects in mSubHalList by reading from dynamic libraries
249      * listed in a config file.
250      */
251     void initializeSubHalListFromConfigFile(const char* configFileName);
252 
253     /**
254      * Initialize the HalProxyCallback vector using the list of subhals.
255      */
256     void initializeSubHalCallbacks();
257 
258     /**
259      * Initialize the list of SensorInfo objects in mSensorList by getting sensors from each
260      * subhal.
261      */
262     void initializeSensorList();
263 
264     /**
265      * Try using the default include directories as well as the directories defined in
266      * kSubHalShareObjectLocations to get a handle for dlsym for a subhal.
267      *
268      * @param filename The file name to search for.
269      *
270      * @return The handle or nullptr if search failed.
271      */
272     void* getHandleForSubHalSharedObject(const std::string& filename);
273 
274     /**
275      * Calls the helper methods that all ctors use.
276      */
277     void init();
278 
279     /**
280      * Stops all threads by setting the threads running flag to false and joining to them.
281      */
282     void stopThreads();
283 
284     /**
285      * Disable all the sensors observed by the HalProxy.
286      */
287     void disableAllSensors();
288 
289     /**
290      * Starts the thread that handles pending writes to event fmq.
291      *
292      * @param halProxy The HalProxy object pointer.
293      */
294     static void startPendingWritesThread(HalProxy* halProxy);
295 
296     //! Handles the pending writes on events to eventqueue.
297     void handlePendingWrites();
298 
299     /**
300      * Starts the thread that handles decrementing the ref count on wakeup events processed by the
301      * framework and timing out wakelocks.
302      *
303      * @param halProxy The HalProxy object pointer.
304      */
305     static void startWakelockThread(HalProxy* halProxy);
306 
307     //! Handles the wakelocks.
308     void handleWakelocks();
309 
310     /**
311      * @param timeLeft The variable that should be set to the timeleft before timeout will occur or
312      * unmodified if timeout occurred.
313      *
314      * @return true if the shared wakelock has been held passed the timeout and should be released
315      */
316     bool sharedWakelockDidTimeout(int64_t* timeLeft);
317 
318     /**
319      * Reset all the member variables associated with the wakelock ref count and maybe release
320      * the shared wakelock.
321      */
322     void resetSharedWakelock();
323 
324     /**
325      * Clear direct channel flags if the HalProxy has already chosen a subhal as its direct channel
326      * subhal. Set the directChannelSubHal pointer to the subHal passed in if this is the first
327      * direct channel enabled sensor seen.
328      *
329      * @param sensorInfo The SensorInfo object that may be altered to have direct channel support
330      *    disabled.
331      * @param subHal The subhal pointer that the current sensorInfo object came from.
332      */
333     void setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal);
334 
335     /*
336      * Get the subhal pointer which can be found by indexing into the mSubHalList vector
337      * using the index from the first byte of sensorHandle.
338      *
339      * @param sensorHandle The handle used to identify a sensor in one of the subhals.
340      */
341     ISensorsSubHal* getSubHalForSensorHandle(int32_t sensorHandle);
342 
343     /**
344      * Checks that sensorHandle's subhal index byte is within bounds of mSubHalList.
345      *
346      * @param sensorHandle The sensor handle to check.
347      *
348      * @return true if sensorHandles's subhal index byte is valid.
349      */
350     bool isSubHalIndexValid(int32_t sensorHandle);
351 
352     /**
353      * Count the number of wakeup events in the first n events of the vector.
354      *
355      * @param events The vector of Event objects.
356      * @param n The end index not inclusive of events to consider.
357      *
358      * @return The number of wakeup events of the considered events.
359      */
360     size_t countNumWakeupEvents(const std::vector<Event>& events, size_t n);
361 
362     /*
363      * Clear out the subhal index bytes from a sensorHandle.
364      *
365      * @param sensorHandle The sensor handle to modify.
366      *
367      * @return The modified version of the sensor handle.
368      */
369     static int32_t clearSubHalIndex(int32_t sensorHandle);
370 
371     /**
372      * @param sensorHandle The sensor handle to modify.
373      *
374      * @return true if subHalIndex byte of sensorHandle is zeroed.
375      */
376     static bool subHalIndexIsClear(int32_t sensorHandle);
377 };
378 
379 /**
380  * Callback class used to provide the HalProxy with the index of which subHal is invoking
381  */
382 class HalProxyCallback : public IHalProxyCallback {
383     using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
384 
385   public:
HalProxyCallback(HalProxy * halProxy,int32_t subHalIndex)386     HalProxyCallback(HalProxy* halProxy, int32_t subHalIndex)
387         : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {}
388 
onDynamicSensorsConnected(const hidl_vec<SensorInfo> & dynamicSensorsAdded)389     Return<void> onDynamicSensorsConnected(
390             const hidl_vec<SensorInfo>& dynamicSensorsAdded) override {
391         return mHalProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex);
392     }
393 
onDynamicSensorsDisconnected(const hidl_vec<int32_t> & dynamicSensorHandlesRemoved)394     Return<void> onDynamicSensorsDisconnected(
395             const hidl_vec<int32_t>& dynamicSensorHandlesRemoved) override {
396         return mHalProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, mSubHalIndex);
397     }
398 
399     void postEvents(const std::vector<Event>& events, ScopedWakelock wakelock);
400 
401     ScopedWakelock createScopedWakelock(bool lock);
402 
403   private:
404     HalProxy* mHalProxy;
405     int32_t mSubHalIndex;
406 
407     std::vector<Event> processEvents(const std::vector<Event>& events,
408                                      size_t* numWakeupEvents) const;
409 };
410 
411 }  // namespace implementation
412 }  // namespace V2_0
413 }  // namespace sensors
414 }  // namespace hardware
415 }  // namespace android
416