blob: ae4b2c53c680e2cc6771b29cea3fcc6cc3a49aca [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
19#include "SubHal.h"
20
21#include <android/hardware/sensors/2.0/ISensors.h>
22#include <fmq/MessageQueue.h>
23#include <hardware_legacy/power.h>
24#include <hidl/MQDescriptor.h>
25#include <hidl/Status.h>
26
Stan Rokita59714262019-09-20 10:55:30 -070027#include <atomic>
28#include <condition_variable>
Stan Rokita537c0272019-09-13 10:36:07 -070029#include <map>
Stan Rokita59714262019-09-20 10:55:30 -070030#include <mutex>
31#include <queue>
32#include <thread>
Stan Rokita537c0272019-09-13 10:36:07 -070033
Anthony Stangea689f8a2019-07-30 11:35:48 -040034namespace android {
35namespace hardware {
36namespace sensors {
37namespace V2_0 {
38namespace implementation {
39
40using ::android::sp;
41using ::android::hardware::EventFlag;
42using ::android::hardware::hidl_string;
43using ::android::hardware::hidl_vec;
44using ::android::hardware::MessageQueue;
45using ::android::hardware::MQDescriptor;
46using ::android::hardware::Return;
47using ::android::hardware::Void;
48
Stan Rokitad0cd57d2019-09-17 15:52:51 -070049class HalProxy : public ISensors, public IScopedWakelockRefCounter {
Stan Rokitadc7a8e72019-08-23 12:35:40 -070050 public:
Anthony Stangea689f8a2019-07-30 11:35:48 -040051 using Event = ::android::hardware::sensors::V1_0::Event;
52 using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
53 using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
54 using Result = ::android::hardware::sensors::V1_0::Result;
Stan Rokita537c0272019-09-13 10:36:07 -070055 using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
Anthony Stangea689f8a2019-07-30 11:35:48 -040056 using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
Stan Rokita537c0272019-09-13 10:36:07 -070057 using ISensorsSubHal = ::android::hardware::sensors::V2_0::implementation::ISensorsSubHal;
Anthony Stangea689f8a2019-07-30 11:35:48 -040058
Anthony Stangeaacbf942019-08-30 15:21:34 -040059 explicit HalProxy();
60 // Test only constructor.
61 explicit HalProxy(std::vector<ISensorsSubHal*>& subHalList);
Anthony Stangea689f8a2019-07-30 11:35:48 -040062 ~HalProxy();
63
64 // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
65 Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
66
67 Return<Result> setOperationMode(OperationMode mode) override;
68
69 Return<Result> activate(int32_t sensorHandle, bool enabled) override;
70
71 Return<Result> initialize(
72 const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
73 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
74 const sp<ISensorsCallback>& sensorsCallback) override;
75
76 Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
77 int64_t maxReportLatencyNs) override;
78
79 Return<Result> flush(int32_t sensorHandle) override;
80
81 Return<Result> injectSensorData(const Event& event) override;
82
83 Return<void> registerDirectChannel(const SharedMemInfo& mem,
84 registerDirectChannel_cb _hidl_cb) override;
85
86 Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
87
88 Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
89 configDirectReport_cb _hidl_cb) override;
90
91 Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
92
Anthony Stangeaacbf942019-08-30 15:21:34 -040093 // Below methods from ::android::hardware::sensors::V2_0::ISensorsCallback with a minor change
Anthony Stangea689f8a2019-07-30 11:35:48 -040094 // to pass in the sub-HAL index. While the above methods are invoked from the sensors framework
95 // via the binder, these methods are invoked from a callback provided to sub-HALs inside the
96 // same process as the HalProxy, but potentially running on different threads.
97 Return<void> onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dynamicSensorsAdded,
98 int32_t subHalIndex);
99
100 Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& dynamicSensorHandlesRemoved,
101 int32_t subHalIndex);
102
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700103 // Below methods follow IScopedWakelockRefCounter
104
105 /**
106 * Increment ref count and maybe acquire wakelock.
107 */
108 void incrementRefCountAndMaybeAcquireWakelock() override;
109
110 /**
111 * Decrement ref count and maybe release wakelock.
112 */
113 void decrementRefCountAndMaybeReleaseWakelock() override;
114
Stan Rokita537c0272019-09-13 10:36:07 -0700115 // Below methods are for HalProxyCallback
116
117 /**
118 * Post events to the event message queue if there is room to write them. Otherwise post the
119 * remaining events to a background thread for a blocking write with a 5 second timeout.
120 *
121 * @param events The list of events to post to the message queue.
122 */
123 void postEventsToMessageQueue(const std::vector<Event>& events);
124
125 /**
126 * Get the SensorInfo object associated with the sensorHandle.
127 *
128 * @param sensorHandle The sensorHandle for the sensor.
129 *
130 * @return The sensor info for the sensor.
131 */
132 const SensorInfo& getSensorInfo(uint32_t sensorHandle) const {
133 return mSensors.at(sensorHandle);
134 }
135
Anthony Stangea689f8a2019-07-30 11:35:48 -0400136 private:
137 using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
138 using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
139
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700140 const char* kWakeLockName = "SensorsHAL_WAKEUP";
141
Anthony Stangea689f8a2019-07-30 11:35:48 -0400142 /**
143 * The Event FMQ where sensor events are written
144 */
145 std::unique_ptr<EventMessageQueue> mEventQueue;
146
147 /**
148 * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events
149 */
150 std::unique_ptr<WakeLockMessageQueue> mWakeLockQueue;
151
152 /**
153 * Event Flag to signal to the framework when sensor events are available to be read
154 */
155 EventFlag* mEventQueueFlag;
156
157 /**
158 * Callback to the sensors framework to inform it that new sensors have been added or removed.
159 */
160 sp<ISensorsCallback> mDynamicSensorsCallback;
Stan Rokita28790672019-08-20 14:32:15 -0700161
162 /**
163 * SubHal object pointers that have been saved from vendor dynamic libraries.
164 */
165 std::vector<ISensorsSubHal*> mSubHalList;
Stan Rokita16385312019-09-10 14:54:36 -0700166
Stan Rokita59714262019-09-20 10:55:30 -0700167 //! The list of subhal callbacks for each subhal where the indices correlate with mSubHalList
Stan Rokita537c0272019-09-13 10:36:07 -0700168 std::vector<const sp<IHalProxyCallback>> mSubHalCallbacks;
169
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700170 /**
Stan Rokita537c0272019-09-13 10:36:07 -0700171 * Map of sensor handles to SensorInfo objects that contains the sensor info from subhals as
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700172 * well as the modified sensor handle for the framework.
173 *
Stan Rokita537c0272019-09-13 10:36:07 -0700174 * The subhal index is encoded in the first byte of the sensor handle and the remaining
175 * bytes are generated by the subhal to identify the sensor.
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700176 */
Stan Rokita537c0272019-09-13 10:36:07 -0700177 std::map<uint32_t, SensorInfo> mSensors;
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700178
Stan Rokita7a723542019-08-29 15:47:50 -0700179 //! The current operation mode for all subhals.
180 OperationMode mCurrentOperationMode = OperationMode::NORMAL;
181
182 //! The single subHal that supports directChannel reporting.
183 ISensorsSubHal* mDirectChannelSubHal = nullptr;
184
Stan Rokita537c0272019-09-13 10:36:07 -0700185 //! The mutex for the event queue.
186 std::mutex mEventQueueMutex;
187
Stan Rokita59714262019-09-20 10:55:30 -0700188 //! The timeout for each pending write on background thread for events.
189 static const int64_t kWakelockTimeoutNs = 5 * INT64_C(1000000000) /* 5 seconds */;
190
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700191 //! The scoped wakelock ref count.
192 size_t mWakelockRefCount = 0;
193
194 //! The mutex guarding the mWakelockRefCount variable
195 std::mutex mWakelockRefCountMutex;
196
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700197 //! The bit mask used to get the subhal index from a sensor handle.
198 static constexpr uint32_t kSensorHandleSubHalIndexMask = 0xFF000000;
199
Stan Rokita59714262019-09-20 10:55:30 -0700200 //! The events that were not able to be written to fmq right away
201 std::queue<std::vector<Event>> mPendingWriteEventsQueue;
202
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
212 //! The bool indicating whether to end the pending writes background thread or not
213 bool mPendingWritesRun = true;
214
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700215 /**
216 * Initialize the list of SubHal objects in mSubHalList by reading from dynamic libraries
217 * listed in a config file.
218 */
219 void initializeSubHalListFromConfigFile(const char* configFileName);
220
221 /**
Stan Rokita537c0272019-09-13 10:36:07 -0700222 * Initialize the HalProxyCallback vector using the list of subhals.
223 */
224 void initializeSubHalCallbacks();
225
226 /**
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700227 * Initialize the list of SensorInfo objects in mSensorList by getting sensors from each
228 * subhal.
229 */
230 void initializeSensorList();
231
Stan Rokita7a723542019-08-29 15:47:50 -0700232 /**
Stan Rokita537c0272019-09-13 10:36:07 -0700233 * Calls the above two helper methods which are shared in both ctors.
234 */
235 void initializeSubHalCallbacksAndSensorList();
236
237 /**
Stan Rokita59714262019-09-20 10:55:30 -0700238 * Starts the thread that handles pending writes to event fmq.
239 *
240 * @param halProxy The HalProxy object pointer.
241 */
242 static void startPendingWritesThread(HalProxy* halProxy);
243
244 //! Handles the pending writes on events to eventqueue.
245 void handlePendingWrites();
246
247 /**
Stan Rokita7a723542019-08-29 15:47:50 -0700248 * Clear direct channel flags if the HalProxy has already chosen a subhal as its direct channel
249 * subhal. Set the directChannelSubHal pointer to the subHal passed in if this is the first
250 * direct channel enabled sensor seen.
251 *
252 * @param sensorInfo The SensorInfo object that may be altered to have direct channel support
253 * disabled.
254 * @param subHal The subhal pointer that the current sensorInfo object came from.
255 */
256 void setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal);
257
Stan Rokita16385312019-09-10 14:54:36 -0700258 /*
259 * Get the subhal pointer which can be found by indexing into the mSubHalList vector
260 * using the index from the first byte of sensorHandle.
261 *
262 * @param sensorHandle The handle used to identify a sensor in one of the subhals.
263 */
264 ISensorsSubHal* getSubHalForSensorHandle(uint32_t sensorHandle);
265
266 /*
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700267 * Clear out the subhal index bytes from a sensorHandle.
Stan Rokita16385312019-09-10 14:54:36 -0700268 *
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700269 * @param sensorHandle The sensor handle to modify.
Stan Rokita16385312019-09-10 14:54:36 -0700270 *
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700271 * @return The modified version of the sensor handle.
Stan Rokita16385312019-09-10 14:54:36 -0700272 */
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700273 static uint32_t clearSubHalIndex(uint32_t sensorHandle);
Anthony Stangea689f8a2019-07-30 11:35:48 -0400274};
275
Stan Rokita537c0272019-09-13 10:36:07 -0700276/**
277 * Callback class used to provide the HalProxy with the index of which subHal is invoking
278 */
279class HalProxyCallback : public IHalProxyCallback {
280 using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
281
282 public:
283 HalProxyCallback(HalProxy* halProxy, int32_t subHalIndex)
284 : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {}
285
286 Return<void> onDynamicSensorsConnected(
287 const hidl_vec<SensorInfo>& dynamicSensorsAdded) override {
288 return mHalProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex);
289 }
290
291 Return<void> onDynamicSensorsDisconnected(
292 const hidl_vec<int32_t>& dynamicSensorHandlesRemoved) override {
293 return mHalProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, mSubHalIndex);
294 }
295
296 void postEvents(const std::vector<Event>& events, ScopedWakelock wakelock);
297
298 ScopedWakelock createScopedWakelock(bool lock);
299
300 private:
301 HalProxy* mHalProxy;
302 int32_t mSubHalIndex;
303
304 std::vector<Event> processEvents(const std::vector<Event>& events,
305 size_t* numWakeupEvents) const;
306
307 uint32_t setSubHalIndex(uint32_t sensorHandle) const;
308};
309
Anthony Stangea689f8a2019-07-30 11:35:48 -0400310} // namespace implementation
311} // namespace V2_0
312} // namespace sensors
313} // namespace hardware
314} // namespace android