blob: 6c50eef8f479ed12525e7b0724d5e256b086e149 [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 Rokita537c0272019-09-13 10:36:07 -070027#include <map>
28
Anthony Stangea689f8a2019-07-30 11:35:48 -040029namespace android {
30namespace hardware {
31namespace sensors {
32namespace V2_0 {
33namespace implementation {
34
35using ::android::sp;
36using ::android::hardware::EventFlag;
37using ::android::hardware::hidl_string;
38using ::android::hardware::hidl_vec;
39using ::android::hardware::MessageQueue;
40using ::android::hardware::MQDescriptor;
41using ::android::hardware::Return;
42using ::android::hardware::Void;
43
Stan Rokitadc7a8e72019-08-23 12:35:40 -070044class HalProxy : public ISensors {
45 public:
Anthony Stangea689f8a2019-07-30 11:35:48 -040046 using Event = ::android::hardware::sensors::V1_0::Event;
47 using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
48 using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
49 using Result = ::android::hardware::sensors::V1_0::Result;
Stan Rokita537c0272019-09-13 10:36:07 -070050 using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
Anthony Stangea689f8a2019-07-30 11:35:48 -040051 using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo;
Stan Rokita537c0272019-09-13 10:36:07 -070052 using ISensorsSubHal = ::android::hardware::sensors::V2_0::implementation::ISensorsSubHal;
Anthony Stangea689f8a2019-07-30 11:35:48 -040053
Anthony Stangeaacbf942019-08-30 15:21:34 -040054 explicit HalProxy();
55 // Test only constructor.
56 explicit HalProxy(std::vector<ISensorsSubHal*>& subHalList);
Anthony Stangea689f8a2019-07-30 11:35:48 -040057 ~HalProxy();
58
59 // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
60 Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
61
62 Return<Result> setOperationMode(OperationMode mode) override;
63
64 Return<Result> activate(int32_t sensorHandle, bool enabled) override;
65
66 Return<Result> initialize(
67 const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
68 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
69 const sp<ISensorsCallback>& sensorsCallback) override;
70
71 Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
72 int64_t maxReportLatencyNs) override;
73
74 Return<Result> flush(int32_t sensorHandle) override;
75
76 Return<Result> injectSensorData(const Event& event) override;
77
78 Return<void> registerDirectChannel(const SharedMemInfo& mem,
79 registerDirectChannel_cb _hidl_cb) override;
80
81 Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
82
83 Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
84 configDirectReport_cb _hidl_cb) override;
85
86 Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
87
Anthony Stangeaacbf942019-08-30 15:21:34 -040088 // Below methods from ::android::hardware::sensors::V2_0::ISensorsCallback with a minor change
Anthony Stangea689f8a2019-07-30 11:35:48 -040089 // to pass in the sub-HAL index. While the above methods are invoked from the sensors framework
90 // via the binder, these methods are invoked from a callback provided to sub-HALs inside the
91 // same process as the HalProxy, but potentially running on different threads.
92 Return<void> onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dynamicSensorsAdded,
93 int32_t subHalIndex);
94
95 Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& dynamicSensorHandlesRemoved,
96 int32_t subHalIndex);
97
Stan Rokita537c0272019-09-13 10:36:07 -070098 // Below methods are for HalProxyCallback
99
100 /**
101 * Post events to the event message queue if there is room to write them. Otherwise post the
102 * remaining events to a background thread for a blocking write with a 5 second timeout.
103 *
104 * @param events The list of events to post to the message queue.
105 */
106 void postEventsToMessageQueue(const std::vector<Event>& events);
107
108 /**
109 * Get the SensorInfo object associated with the sensorHandle.
110 *
111 * @param sensorHandle The sensorHandle for the sensor.
112 *
113 * @return The sensor info for the sensor.
114 */
115 const SensorInfo& getSensorInfo(uint32_t sensorHandle) const {
116 return mSensors.at(sensorHandle);
117 }
118
Anthony Stangea689f8a2019-07-30 11:35:48 -0400119 private:
120 using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
121 using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;
122
123 /**
124 * The Event FMQ where sensor events are written
125 */
126 std::unique_ptr<EventMessageQueue> mEventQueue;
127
128 /**
129 * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events
130 */
131 std::unique_ptr<WakeLockMessageQueue> mWakeLockQueue;
132
133 /**
134 * Event Flag to signal to the framework when sensor events are available to be read
135 */
136 EventFlag* mEventQueueFlag;
137
138 /**
139 * Callback to the sensors framework to inform it that new sensors have been added or removed.
140 */
141 sp<ISensorsCallback> mDynamicSensorsCallback;
Stan Rokita28790672019-08-20 14:32:15 -0700142
143 /**
144 * SubHal object pointers that have been saved from vendor dynamic libraries.
145 */
146 std::vector<ISensorsSubHal*> mSubHalList;
Stan Rokita16385312019-09-10 14:54:36 -0700147
Stan Rokita537c0272019-09-13 10:36:07 -0700148 std::vector<const sp<IHalProxyCallback>> mSubHalCallbacks;
149
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700150 /**
Stan Rokita537c0272019-09-13 10:36:07 -0700151 * Map of sensor handles to SensorInfo objects that contains the sensor info from subhals as
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700152 * well as the modified sensor handle for the framework.
153 *
Stan Rokita537c0272019-09-13 10:36:07 -0700154 * The subhal index is encoded in the first byte of the sensor handle and the remaining
155 * bytes are generated by the subhal to identify the sensor.
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700156 */
Stan Rokita537c0272019-09-13 10:36:07 -0700157 std::map<uint32_t, SensorInfo> mSensors;
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700158
Stan Rokita7a723542019-08-29 15:47:50 -0700159 //! The current operation mode for all subhals.
160 OperationMode mCurrentOperationMode = OperationMode::NORMAL;
161
162 //! The single subHal that supports directChannel reporting.
163 ISensorsSubHal* mDirectChannelSubHal = nullptr;
164
Stan Rokita537c0272019-09-13 10:36:07 -0700165 //! The mutex for the event queue.
166 std::mutex mEventQueueMutex;
167
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700168 //! The bit mask used to get the subhal index from a sensor handle.
169 static constexpr uint32_t kSensorHandleSubHalIndexMask = 0xFF000000;
170
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700171 /**
172 * Initialize the list of SubHal objects in mSubHalList by reading from dynamic libraries
173 * listed in a config file.
174 */
175 void initializeSubHalListFromConfigFile(const char* configFileName);
176
177 /**
Stan Rokita537c0272019-09-13 10:36:07 -0700178 * Initialize the HalProxyCallback vector using the list of subhals.
179 */
180 void initializeSubHalCallbacks();
181
182 /**
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700183 * Initialize the list of SensorInfo objects in mSensorList by getting sensors from each
184 * subhal.
185 */
186 void initializeSensorList();
187
Stan Rokita7a723542019-08-29 15:47:50 -0700188 /**
Stan Rokita537c0272019-09-13 10:36:07 -0700189 * Calls the above two helper methods which are shared in both ctors.
190 */
191 void initializeSubHalCallbacksAndSensorList();
192
193 /**
Stan Rokita7a723542019-08-29 15:47:50 -0700194 * Clear direct channel flags if the HalProxy has already chosen a subhal as its direct channel
195 * subhal. Set the directChannelSubHal pointer to the subHal passed in if this is the first
196 * direct channel enabled sensor seen.
197 *
198 * @param sensorInfo The SensorInfo object that may be altered to have direct channel support
199 * disabled.
200 * @param subHal The subhal pointer that the current sensorInfo object came from.
201 */
202 void setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal);
203
Stan Rokita16385312019-09-10 14:54:36 -0700204 /*
205 * Get the subhal pointer which can be found by indexing into the mSubHalList vector
206 * using the index from the first byte of sensorHandle.
207 *
208 * @param sensorHandle The handle used to identify a sensor in one of the subhals.
209 */
210 ISensorsSubHal* getSubHalForSensorHandle(uint32_t sensorHandle);
211
212 /*
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700213 * Clear out the subhal index bytes from a sensorHandle.
Stan Rokita16385312019-09-10 14:54:36 -0700214 *
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700215 * @param sensorHandle The sensor handle to modify.
Stan Rokita16385312019-09-10 14:54:36 -0700216 *
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700217 * @return The modified version of the sensor handle.
Stan Rokita16385312019-09-10 14:54:36 -0700218 */
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700219 static uint32_t clearSubHalIndex(uint32_t sensorHandle);
Anthony Stangea689f8a2019-07-30 11:35:48 -0400220};
221
Stan Rokita537c0272019-09-13 10:36:07 -0700222// TODO: Use this wake lock name as the prefix to all sensors HAL wake locks acquired.
223// constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP";
224
225// TODO: Use the following class as a starting point for implementing the full HalProxyCallback
226// along with being inspiration for how to implement the ScopedWakelock class.
227/**
228 * Callback class used to provide the HalProxy with the index of which subHal is invoking
229 */
230class HalProxyCallback : public IHalProxyCallback {
231 using SensorInfo = ::android::hardware::sensors::V1_0::SensorInfo;
232
233 public:
234 HalProxyCallback(HalProxy* halProxy, int32_t subHalIndex)
235 : mHalProxy(halProxy), mSubHalIndex(subHalIndex) {}
236
237 Return<void> onDynamicSensorsConnected(
238 const hidl_vec<SensorInfo>& dynamicSensorsAdded) override {
239 return mHalProxy->onDynamicSensorsConnected(dynamicSensorsAdded, mSubHalIndex);
240 }
241
242 Return<void> onDynamicSensorsDisconnected(
243 const hidl_vec<int32_t>& dynamicSensorHandlesRemoved) override {
244 return mHalProxy->onDynamicSensorsDisconnected(dynamicSensorHandlesRemoved, mSubHalIndex);
245 }
246
247 void postEvents(const std::vector<Event>& events, ScopedWakelock wakelock);
248
249 ScopedWakelock createScopedWakelock(bool lock);
250
251 private:
252 HalProxy* mHalProxy;
253 int32_t mSubHalIndex;
254
255 std::vector<Event> processEvents(const std::vector<Event>& events,
256 size_t* numWakeupEvents) const;
257
258 uint32_t setSubHalIndex(uint32_t sensorHandle) const;
259};
260
Anthony Stangea689f8a2019-07-30 11:35:48 -0400261} // namespace implementation
262} // namespace V2_0
263} // namespace sensors
264} // namespace hardware
265} // namespace android