blob: b1dd737025cacf975e0c67c74ff9fee128734ece [file] [log] [blame]
Anthony Stangea689f8a2019-07-30 11:35:48 -04001/*
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
Stan Rokita75cc7bf2019-09-26 13:17:01 -070019#include "ScopedWakelock.h"
Anthony Stangea689f8a2019-07-30 11:35:48 -040020#include "SubHal.h"
21
22#include <android/hardware/sensors/2.0/ISensors.h>
Stan Rokita75cc7bf2019-09-26 13:17:01 -070023#include <android/hardware/sensors/2.0/types.h>
Anthony Stangea689f8a2019-07-30 11:35:48 -040024#include <fmq/MessageQueue.h>
25#include <hardware_legacy/power.h>
26#include <hidl/MQDescriptor.h>
27#include <hidl/Status.h>
28
Stan Rokita59714262019-09-20 10:55:30 -070029#include <atomic>
30#include <condition_variable>
Stan Rokita537c0272019-09-13 10:36:07 -070031#include <map>
Stan Rokita59714262019-09-20 10:55:30 -070032#include <mutex>
33#include <queue>
34#include <thread>
Stan Rokita75cc7bf2019-09-26 13:17:01 -070035#include <utility>
Stan Rokita537c0272019-09-13 10:36:07 -070036
Anthony Stangea689f8a2019-07-30 11:35:48 -040037namespace android {
38namespace hardware {
39namespace sensors {
40namespace V2_0 {
41namespace implementation {
42
43using ::android::sp;
44using ::android::hardware::EventFlag;
45using ::android::hardware::hidl_string;
46using ::android::hardware::hidl_vec;
47using ::android::hardware::MessageQueue;
48using ::android::hardware::MQDescriptor;
49using ::android::hardware::Return;
50using ::android::hardware::Void;
51
Stan Rokitad0cd57d2019-09-17 15:52:51 -070052class HalProxy : public ISensors, public IScopedWakelockRefCounter {
Stan Rokitadc7a8e72019-08-23 12:35:40 -070053 public:
Anthony Stangea689f8a2019-07-30 11:35:48 -040054 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;
Stan Rokita537c0272019-09-13 10:36:07 -070058 using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
Anthony Stangea689f8a2019-07-30 11:35:48 -040059 using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
Stan Rokita537c0272019-09-13 10:36:07 -070060 using ISensorsSubHal = ::android::hardware::sensors::V2_0::implementation::ISensorsSubHal;
Anthony Stangea689f8a2019-07-30 11:35:48 -040061
Anthony Stangeaacbf942019-08-30 15:21:34 -040062 explicit HalProxy();
63 // Test only constructor.
64 explicit HalProxy(std::vector<ISensorsSubHal*>& subHalList);
Anthony Stangea689f8a2019-07-30 11:35:48 -040065 ~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
Anthony Stangeaacbf942019-08-30 15:21:34 -040096 // Below methods from ::android::hardware::sensors::V2_0::ISensorsCallback with a minor change
Anthony Stangea689f8a2019-07-30 11:35:48 -040097 // 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
Stan Rokita537c0272019-09-13 10:36:07 -0700106 // 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
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700110 * remaining events to a background thread for a blocking write with a kPendingWriteTimeoutNs
111 * timeout.
Stan Rokita537c0272019-09-13 10:36:07 -0700112 *
113 * @param events The list of events to post to the message queue.
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700114 * @param numWakeupEvents The number of wakeup events in events.
115 * @param wakelock The wakelock associated with this post of events.
Stan Rokita537c0272019-09-13 10:36:07 -0700116 */
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700117 void postEventsToMessageQueue(const std::vector<Event>& events, size_t numWakeupEvents,
118 ScopedWakelock wakelock);
Stan Rokita537c0272019-09-13 10:36:07 -0700119
120 /**
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700121 * Get the sensor info associated with that sensorHandle.
Stan Rokita537c0272019-09-13 10:36:07 -0700122 *
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700123 * @param sensorHandle The sensor handle.
Stan Rokita537c0272019-09-13 10:36:07 -0700124 *
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700125 * @return The sensor info object in the mapping.
Stan Rokita537c0272019-09-13 10:36:07 -0700126 */
Stan Rokitae0721532019-10-17 11:58:02 -0700127 const SensorInfo& getSensorInfo(int32_t sensorHandle) { return mSensors[sensorHandle]; }
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700128
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;
Stan Rokita537c0272019-09-13 10:36:07 -0700136
Anthony Stangea689f8a2019-07-30 11:35:48 -0400137 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 /**
Stan Rokita336c1c72019-10-14 15:30:57 -0700152 * Event Flag to signal to the framework when sensor events are available to be read and to
153 * interrupt event queue blocking write.
Anthony Stangea689f8a2019-07-30 11:35:48 -0400154 */
Stan Rokita336c1c72019-10-14 15:30:57 -0700155 EventFlag* mEventQueueFlag = nullptr;
156
157 //! Event Flag to signal internally that the wakelock queue should stop its blocking read.
158 EventFlag* mWakelockQueueFlag = nullptr;
Anthony Stangea689f8a2019-07-30 11:35:48 -0400159
160 /**
161 * Callback to the sensors framework to inform it that new sensors have been added or removed.
162 */
163 sp<ISensorsCallback> mDynamicSensorsCallback;
Stan Rokita28790672019-08-20 14:32:15 -0700164
165 /**
166 * SubHal object pointers that have been saved from vendor dynamic libraries.
167 */
168 std::vector<ISensorsSubHal*> mSubHalList;
Stan Rokita16385312019-09-10 14:54:36 -0700169
Stan Rokita59714262019-09-20 10:55:30 -0700170 //! The list of subhal callbacks for each subhal where the indices correlate with mSubHalList
Stan Rokita537c0272019-09-13 10:36:07 -0700171 std::vector<const sp<IHalProxyCallback>> mSubHalCallbacks;
172
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700173 /**
Stan Rokita537c0272019-09-13 10:36:07 -0700174 * Map of sensor handles to SensorInfo objects that contains the sensor info from subhals as
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700175 * well as the modified sensor handle for the framework.
176 *
Stan Rokita537c0272019-09-13 10:36:07 -0700177 * 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.
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700179 */
Stan Rokitae0721532019-10-17 11:58:02 -0700180 std::map<int32_t, SensorInfo> mSensors;
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700181
Stan Rokitae93fdf92019-09-24 11:58:51 -0700182 //! Map of the dynamic sensors that have been added to halproxy.
Stan Rokitae0721532019-10-17 11:58:02 -0700183 std::map<int32_t, SensorInfo> mDynamicSensors;
Stan Rokitae93fdf92019-09-24 11:58:51 -0700184
Stan Rokita7a723542019-08-29 15:47:50 -0700185 //! 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
Stan Rokita59714262019-09-20 10:55:30 -0700191 //! The timeout for each pending write on background thread for events.
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700192 static const int64_t kPendingWriteTimeoutNs = 5 * INT64_C(1000000000) /* 5 seconds */;
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700193
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700194 //! The bit mask used to get the subhal index from a sensor handle.
Stan Rokitae0721532019-10-17 11:58:02 -0700195 static constexpr int32_t kSensorHandleSubHalIndexMask = 0xFF000000;
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700196
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700197 /**
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;
Stan Rokita59714262019-09-20 10:55:30 -0700202
203 //! The mutex protecting writing to the fmq and the pending events queue
204 std::mutex mEventQueueWriteMutex;
205
206 //! The condition variable waiting on pending write events to stack up
207 std::condition_variable mEventQueueWriteCV;
208
209 //! The thread object ptr that handles pending writes
210 std::thread mPendingWritesThread;
211
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700212 //! The thread object that handles wakelocks
213 std::thread mWakelockThread;
214
215 //! The bool indicating whether to end the threads started in initialize
216 std::atomic_bool mThreadsRun = true;
Stan Rokita59714262019-09-20 10:55:30 -0700217
Stan Rokitae93fdf92019-09-24 11:58:51 -0700218 //! The mutex protecting access to the dynamic sensors added and removed methods.
219 std::mutex mDynamicSensorsMutex;
220
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700221 // WakelockRefCount membar vars below
222
223 //! The mutex protecting the wakelock refcount and subsequent wakelock releases and
224 //! acquisitions
225 std::recursive_mutex mWakelockMutex;
226
227 std::condition_variable_any mWakelockCV;
228
229 //! The refcount of how many ScopedWakelocks and pending wakeup events are active
230 size_t mWakelockRefCount = 0;
231
232 int64_t mWakelockTimeoutStartTime = getTimeNow();
233
234 int64_t mWakelockTimeoutResetTime = getTimeNow();
235
Stan Rokita1de5bb32019-10-18 14:21:58 -0700236 const char* kWakelockName = "SensorsHAL_WAKEUP";
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700237
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700238 /**
239 * Initialize the list of SubHal objects in mSubHalList by reading from dynamic libraries
240 * listed in a config file.
241 */
242 void initializeSubHalListFromConfigFile(const char* configFileName);
243
244 /**
Stan Rokita537c0272019-09-13 10:36:07 -0700245 * Initialize the HalProxyCallback vector using the list of subhals.
246 */
247 void initializeSubHalCallbacks();
248
249 /**
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700250 * Initialize the list of SensorInfo objects in mSensorList by getting sensors from each
251 * subhal.
252 */
253 void initializeSensorList();
254
Stan Rokita7a723542019-08-29 15:47:50 -0700255 /**
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700256 * Calls the helper methods that all ctors use.
Stan Rokita537c0272019-09-13 10:36:07 -0700257 */
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700258 void init();
Stan Rokita537c0272019-09-13 10:36:07 -0700259
260 /**
Stan Rokita336c1c72019-10-14 15:30:57 -0700261 * Stops all threads by setting the threads running flag to false and joining to them.
262 */
263 void stopThreads();
264
265 /**
266 * Disable all the sensors observed by the HalProxy.
267 */
268 void disableAllSensors();
269
270 /**
Stan Rokita59714262019-09-20 10:55:30 -0700271 * Starts the thread that handles pending writes to event fmq.
272 *
273 * @param halProxy The HalProxy object pointer.
274 */
275 static void startPendingWritesThread(HalProxy* halProxy);
276
277 //! Handles the pending writes on events to eventqueue.
278 void handlePendingWrites();
279
280 /**
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700281 * Starts the thread that handles decrementing the ref count on wakeup events processed by the
282 * framework and timing out wakelocks.
283 *
284 * @param halProxy The HalProxy object pointer.
285 */
286 static void startWakelockThread(HalProxy* halProxy);
287
288 //! Handles the wakelocks.
289 void handleWakelocks();
290
291 /**
292 * @param timeLeft The variable that should be set to the timeleft before timeout will occur or
293 * unmodified if timeout occurred.
294 *
295 * @return true if the shared wakelock has been held passed the timeout and should be released
296 */
297 bool sharedWakelockDidTimeout(int64_t* timeLeft);
298
299 /**
300 * Reset all the member variables associated with the wakelock ref count and maybe release
301 * the shared wakelock.
302 */
303 void resetSharedWakelock();
304
305 /**
Stan Rokita7a723542019-08-29 15:47:50 -0700306 * Clear direct channel flags if the HalProxy has already chosen a subhal as its direct channel
307 * subhal. Set the directChannelSubHal pointer to the subHal passed in if this is the first
308 * direct channel enabled sensor seen.
309 *
310 * @param sensorInfo The SensorInfo object that may be altered to have direct channel support
311 * disabled.
312 * @param subHal The subhal pointer that the current sensorInfo object came from.
313 */
314 void setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal);
315
Stan Rokita16385312019-09-10 14:54:36 -0700316 /*
317 * Get the subhal pointer which can be found by indexing into the mSubHalList vector
318 * using the index from the first byte of sensorHandle.
319 *
320 * @param sensorHandle The handle used to identify a sensor in one of the subhals.
321 */
Stan Rokitae0721532019-10-17 11:58:02 -0700322 ISensorsSubHal* getSubHalForSensorHandle(int32_t sensorHandle);
323
324 /**
325 * Checks that sensorHandle's subhal index byte is within bounds of mSubHalList.
326 *
327 * @param sensorHandle The sensor handle to check.
328 *
329 * @return true if sensorHandles's subhal index byte is valid.
330 */
331 bool isSubHalIndexValid(int32_t sensorHandle);
Stan Rokita16385312019-09-10 14:54:36 -0700332
Stan Rokita75cc7bf2019-09-26 13:17:01 -0700333 /**
334 * Count the number of wakeup events in the first n events of the vector.
335 *
336 * @param events The vector of Event objects.
337 * @param n The end index not inclusive of events to consider.
338 *
339 * @return The number of wakeup events of the considered events.
340 */
341 size_t countNumWakeupEvents(const std::vector<Event>& events, size_t n);
342
Stan Rokita16385312019-09-10 14:54:36 -0700343 /*
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700344 * Clear out the subhal index bytes from a sensorHandle.
Stan Rokita16385312019-09-10 14:54:36 -0700345 *
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700346 * @param sensorHandle The sensor handle to modify.
Stan Rokita16385312019-09-10 14:54:36 -0700347 *
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700348 * @return The modified version of the sensor handle.
Stan Rokita16385312019-09-10 14:54:36 -0700349 */
Stan Rokitae0721532019-10-17 11:58:02 -0700350 static int32_t clearSubHalIndex(int32_t sensorHandle);
Stan Rokitae93fdf92019-09-24 11:58:51 -0700351
352 /**
353 * @param sensorHandle The sensor handle to modify.
354 *
355 * @return true if subHalIndex byte of sensorHandle is zeroed.
356 */
Stan Rokitae0721532019-10-17 11:58:02 -0700357 static bool subHalIndexIsClear(int32_t sensorHandle);
Anthony Stangea689f8a2019-07-30 11:35:48 -0400358};
359
Stan Rokita537c0272019-09-13 10:36:07 -0700360/**
361 * Callback class used to provide the HalProxy with the index of which subHal is invoking
362 */
363class HalProxyCallback : public IHalProxyCallback {
364 using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
365
366 public:
367 HalProxyCallback(HalProxy* halProxy, int32_t subHalIndex)
368 : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {}
369
370 Return<void> onDynamicSensorsConnected(
371 const hidl_vec<SensorInfo>& dynamicSensorsAdded) override {
372 return mHalProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex);
373 }
374
375 Return<void> onDynamicSensorsDisconnected(
376 const hidl_vec<int32_t>& dynamicSensorHandlesRemoved) override {
377 return mHalProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, mSubHalIndex);
378 }
379
380 void postEvents(const std::vector<Event>& events, ScopedWakelock wakelock);
381
382 ScopedWakelock createScopedWakelock(bool lock);
383
384 private:
385 HalProxy* mHalProxy;
386 int32_t mSubHalIndex;
387
388 std::vector<Event> processEvents(const std::vector<Event>& events,
389 size_t* numWakeupEvents) const;
Stan Rokita537c0272019-09-13 10:36:07 -0700390};
391
Anthony Stangea689f8a2019-07-30 11:35:48 -0400392} // namespace implementation
393} // namespace V2_0
394} // namespace sensors
395} // namespace hardware
396} // namespace android