blob: 5a45a44ad565421ebf62dd2dcbba4210ee818740 [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#include "HalProxy.h"
18
Stan Rokita537c0272019-09-13 10:36:07 -070019#include "SubHal.h"
20
Anthony Stangea689f8a2019-07-30 11:35:48 -040021#include <android/hardware/sensors/2.0/types.h>
22
Stan Rokita28790672019-08-20 14:32:15 -070023#include <dlfcn.h>
24
25#include <fstream>
26#include <functional>
Stan Rokita537c0272019-09-13 10:36:07 -070027#include <thread>
Stan Rokita28790672019-08-20 14:32:15 -070028
Anthony Stangea689f8a2019-07-30 11:35:48 -040029namespace android {
30namespace hardware {
31namespace sensors {
32namespace V2_0 {
33namespace implementation {
34
Stan Rokita537c0272019-09-13 10:36:07 -070035using ::android::hardware::sensors::V2_0::EventQueueFlagBits;
36
Stan Rokita28790672019-08-20 14:32:15 -070037typedef ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*);
38
Stan Rokita537c0272019-09-13 10:36:07 -070039ScopedWakelock::ScopedWakelock() {
40 // TODO: Implement
41}
Anthony Stangea689f8a2019-07-30 11:35:48 -040042
43HalProxy::HalProxy() {
Stan Rokita7a723542019-08-29 15:47:50 -070044 const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf";
45 initializeSubHalListFromConfigFile(kMultiHalConfigFile);
Stan Rokita537c0272019-09-13 10:36:07 -070046 initializeSubHalCallbacksAndSensorList();
Anthony Stangea689f8a2019-07-30 11:35:48 -040047}
48
Anthony Stangeaacbf942019-08-30 15:21:34 -040049HalProxy::HalProxy(std::vector<ISensorsSubHal*>& subHalList) : mSubHalList(subHalList) {
Stan Rokita537c0272019-09-13 10:36:07 -070050 initializeSubHalCallbacksAndSensorList();
Anthony Stangeaacbf942019-08-30 15:21:34 -040051}
52
Anthony Stangea689f8a2019-07-30 11:35:48 -040053HalProxy::~HalProxy() {
54 // TODO: Join any running threads and clean up FMQs and any other allocated
55 // state.
56}
57
Stan Rokitadc7a8e72019-08-23 12:35:40 -070058Return<void> HalProxy::getSensorsList(getSensorsList_cb _hidl_cb) {
Stan Rokita537c0272019-09-13 10:36:07 -070059 std::vector<SensorInfo> sensors;
60 for (const auto& iter : mSensors) {
61 sensors.push_back(iter.second);
62 }
63 _hidl_cb(sensors);
Anthony Stangea689f8a2019-07-30 11:35:48 -040064 return Void();
65}
66
Stan Rokita7a723542019-08-29 15:47:50 -070067Return<Result> HalProxy::setOperationMode(OperationMode mode) {
68 Result result = Result::OK;
69 size_t subHalIndex;
70 for (subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
71 ISensorsSubHal* subHal = mSubHalList[subHalIndex];
72 result = subHal->setOperationMode(mode);
73 if (result != Result::OK) {
74 ALOGE("setOperationMode failed for SubHal: %s", subHal->getName().c_str());
75 break;
76 }
77 }
78 if (result != Result::OK) {
79 // Reset the subhal operation modes that have been flipped
80 for (size_t i = 0; i < subHalIndex; i++) {
81 ISensorsSubHal* subHal = mSubHalList[i];
82 subHal->setOperationMode(mCurrentOperationMode);
83 }
84 } else {
85 mCurrentOperationMode = mode;
86 }
87 return result;
Anthony Stangea689f8a2019-07-30 11:35:48 -040088}
89
Stan Rokita4b4c7b72019-09-10 15:07:59 -070090Return<Result> HalProxy::activate(int32_t sensorHandle, bool enabled) {
91 return getSubHalForSensorHandle(sensorHandle)
Stan Rokitaf97a3f32019-09-13 09:58:47 -070092 ->activate(clearSubHalIndex(sensorHandle), enabled);
Anthony Stangea689f8a2019-07-30 11:35:48 -040093}
94
95Return<Result> HalProxy::initialize(
96 const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
97 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
98 const sp<ISensorsCallback>& sensorsCallback) {
99 Result result = Result::OK;
100
101 // TODO: clean up sensor requests, if not already done elsewhere through a death recipient, and
102 // clean up any other resources that exist (FMQs, flags, threads, etc.)
103
104 mDynamicSensorsCallback = sensorsCallback;
105
106 // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
107 mEventQueue =
108 std::make_unique<EventMessageQueue>(eventQueueDescriptor, true /* resetPointers */);
109
110 // Create the EventFlag that is used to signal to the framework that sensor events have been
111 // written to the Event FMQ
112 if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
113 result = Result::BAD_VALUE;
114 }
115
116 // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
117 // events have been successfully read and handled by the framework.
118 mWakeLockQueue =
119 std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
120
121 if (!mDynamicSensorsCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
122 result = Result::BAD_VALUE;
123 }
124
125 // TODO: start threads to read wake locks and process events from sub HALs.
126
Stan Rokita537c0272019-09-13 10:36:07 -0700127 for (size_t i = 0; i < mSubHalList.size(); i++) {
128 auto subHal = mSubHalList[i];
129 const auto& subHalCallback = mSubHalCallbacks[i];
130 Result currRes = subHal->initialize(subHalCallback);
131 if (currRes != Result::OK) {
132 result = currRes;
133 ALOGE("Subhal '%s' failed to initialize.", subHal->getName().c_str());
134 break;
135 }
136 }
137
Anthony Stangea689f8a2019-07-30 11:35:48 -0400138 return result;
139}
140
Stan Rokita4b4c7b72019-09-10 15:07:59 -0700141Return<Result> HalProxy::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
142 int64_t maxReportLatencyNs) {
143 return getSubHalForSensorHandle(sensorHandle)
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700144 ->batch(clearSubHalIndex(sensorHandle), samplingPeriodNs, maxReportLatencyNs);
Anthony Stangea689f8a2019-07-30 11:35:48 -0400145}
146
Stan Rokita4b4c7b72019-09-10 15:07:59 -0700147Return<Result> HalProxy::flush(int32_t sensorHandle) {
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700148 return getSubHalForSensorHandle(sensorHandle)->flush(clearSubHalIndex(sensorHandle));
Anthony Stangea689f8a2019-07-30 11:35:48 -0400149}
150
151Return<Result> HalProxy::injectSensorData(const Event& /* event */) {
152 // TODO: Proxy API call to appropriate sub-HAL.
153 return Result::INVALID_OPERATION;
154}
155
156Return<void> HalProxy::registerDirectChannel(const SharedMemInfo& /* mem */,
157 registerDirectChannel_cb _hidl_cb) {
158 // TODO: During init, discover the first sub-HAL in the config that has sensors with direct
159 // channel support, if any, and proxy the API call there.
160 _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
161 return Return<void>();
162}
163
164Return<Result> HalProxy::unregisterDirectChannel(int32_t /* channelHandle */) {
165 // TODO: During init, discover the first sub-HAL in the config that has sensors with direct
166 // channel support, if any, and proxy the API call there.
167 return Result::INVALID_OPERATION;
168}
169
170Return<void> HalProxy::configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */,
171 RateLevel /* rate */, configDirectReport_cb _hidl_cb) {
172 // TODO: During init, discover the first sub-HAL in the config that has sensors with direct
173 // channel support, if any, and proxy the API call there.
174 _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */);
175 return Return<void>();
176}
177
178Return<void> HalProxy::debug(const hidl_handle& /* fd */, const hidl_vec<hidl_string>& /* args */) {
179 // TODO: output debug information
180 return Return<void>();
181}
182
183Return<void> HalProxy::onDynamicSensorsConnected(
184 const hidl_vec<SensorInfo>& /* dynamicSensorsAdded */, int32_t /* subHalIndex */) {
185 // TODO: Map the SensorInfo to the global list and then invoke the framework's callback.
186 return Return<void>();
187}
188
189Return<void> HalProxy::onDynamicSensorsDisconnected(
190 const hidl_vec<int32_t>& /* dynamicSensorHandlesRemoved */, int32_t /* subHalIndex */) {
191 // TODO: Unmap the SensorInfo from the global list and then invoke the framework's callback.
192 return Return<void>();
193}
194
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700195void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
196 std::ifstream subHalConfigStream(configFileName);
197 if (!subHalConfigStream) {
Stan Rokita7a723542019-08-29 15:47:50 -0700198 ALOGE("Failed to load subHal config file: %s", configFileName);
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700199 } else {
200 std::string subHalLibraryFile;
201 while (subHalConfigStream >> subHalLibraryFile) {
202 void* handle = dlopen(subHalLibraryFile.c_str(), RTLD_NOW);
203 if (handle == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700204 ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700205 } else {
206 SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
207 (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
208 if (sensorsHalGetSubHalPtr == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700209 ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s",
210 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700211 } else {
212 std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
213 *sensorsHalGetSubHalPtr;
214 uint32_t version;
215 ISensorsSubHal* subHal = sensorsHalGetSubHal(&version);
216 if (version != SUB_HAL_2_0_VERSION) {
Stan Rokita7a723542019-08-29 15:47:50 -0700217 ALOGE("SubHal version was not 2.0 for library: %s",
218 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700219 } else {
220 ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
221 mSubHalList.push_back(subHal);
222 }
223 }
224 }
225 }
226 }
227}
228
Stan Rokita537c0272019-09-13 10:36:07 -0700229void HalProxy::initializeSubHalCallbacks() {
230 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
231 sp<IHalProxyCallback> callback = new HalProxyCallback(this, subHalIndex);
232 mSubHalCallbacks.push_back(callback);
233 }
234}
235
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700236void HalProxy::initializeSensorList() {
237 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
238 ISensorsSubHal* subHal = mSubHalList[subHalIndex];
239 auto result = subHal->getSensorsList([&](const auto& list) {
240 for (SensorInfo sensor : list) {
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700241 if ((sensor.sensorHandle & kSensorHandleSubHalIndexMask) != 0) {
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700242 ALOGE("SubHal sensorHandle's first byte was not 0");
243 } else {
244 ALOGV("Loaded sensor: %s", sensor.name.c_str());
245 sensor.sensorHandle |= (subHalIndex << 24);
Stan Rokita7a723542019-08-29 15:47:50 -0700246 setDirectChannelFlags(&sensor, subHal);
Stan Rokita537c0272019-09-13 10:36:07 -0700247 mSensors[sensor.sensorHandle] = sensor;
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700248 }
249 }
250 });
251 if (!result.isOk()) {
252 ALOGE("getSensorsList call failed for SubHal: %s", subHal->getName().c_str());
253 }
254 }
255}
256
Stan Rokita537c0272019-09-13 10:36:07 -0700257void HalProxy::initializeSubHalCallbacksAndSensorList() {
258 initializeSubHalCallbacks();
259 initializeSensorList();
260}
261
262void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events) {
263 std::lock_guard<std::mutex> lock(mEventQueueMutex);
264 size_t numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
265 if (numToWrite > 0) {
266 if (mEventQueue->write(events.data(), numToWrite)) {
267 // TODO: While loop if mEventQueue->avaiableToWrite > 0 to possibly fit in more writes
268 // immediately
269 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
270 } else {
271 numToWrite = 0;
272 }
273 }
274 if (numToWrite < events.size()) {
275 // TODO: Post from events[numToWrite -> end] to background events queue
276 // Signal background thread
277 }
278}
279
Stan Rokita7a723542019-08-29 15:47:50 -0700280void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal) {
281 bool sensorSupportsDirectChannel =
282 (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
283 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0;
284 if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) {
285 mDirectChannelSubHal = subHal;
286 } else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) {
287 // disable direct channel capability for sensors in subHals that are not
288 // the only one we will enable
289 sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
290 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
291 }
292}
293
Stan Rokita16385312019-09-10 14:54:36 -0700294ISensorsSubHal* HalProxy::getSubHalForSensorHandle(uint32_t sensorHandle) {
295 return mSubHalList[static_cast<size_t>(sensorHandle >> 24)];
296}
297
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700298uint32_t HalProxy::clearSubHalIndex(uint32_t sensorHandle) {
299 return sensorHandle & (~kSensorHandleSubHalIndexMask);
Stan Rokita16385312019-09-10 14:54:36 -0700300}
301
Stan Rokita537c0272019-09-13 10:36:07 -0700302void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) {
303 (void)wakelock;
304 size_t numWakeupEvents;
305 std::vector<Event> processedEvents = processEvents(events, &numWakeupEvents);
306 if (numWakeupEvents > 0) {
307 ALOG_ASSERT(wakelock.isLocked(),
308 "Wakeup events posted while wakelock unlocked for subhal"
309 " w/ index %zu.",
310 mSubHalIndex);
311 } else {
312 ALOG_ASSERT(!wakelock.isLocked(),
313 "No Wakeup events posted but wakelock locked for subhal"
314 " w/ index %zu.",
315 mSubHalIndex);
316 }
317
318 mHalProxy->postEventsToMessageQueue(processedEvents);
319}
320
321ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) {
322 ScopedWakelock wakelock;
323 wakelock.mLocked = lock;
324 return wakelock;
325}
326
327std::vector<Event> HalProxyCallback::processEvents(const std::vector<Event>& events,
328 size_t* numWakeupEvents) const {
329 std::vector<Event> eventsOut;
330 *numWakeupEvents = 0;
331 for (Event event : events) {
332 event.sensorHandle = setSubHalIndex(event.sensorHandle);
333 eventsOut.push_back(event);
334 if ((mHalProxy->getSensorInfo(event.sensorHandle).flags & V1_0::SensorFlagBits::WAKE_UP) !=
335 0) {
336 (*numWakeupEvents)++;
337 }
338 }
339 return eventsOut;
340}
341
342uint32_t HalProxyCallback::setSubHalIndex(uint32_t sensorHandle) const {
343 return sensorHandle | mSubHalIndex << 24;
344}
345
Anthony Stangea689f8a2019-07-30 11:35:48 -0400346} // namespace implementation
347} // namespace V2_0
348} // namespace sensors
349} // namespace hardware
350} // namespace android