blob: 1fbc787157bd700e28c8294f5351af3d4c19e7d1 [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 Rokitad0cd57d2019-09-17 15:52:51 -070023#include "hardware_legacy/power.h"
24
Stan Rokita28790672019-08-20 14:32:15 -070025#include <dlfcn.h>
26
27#include <fstream>
28#include <functional>
Stan Rokita537c0272019-09-13 10:36:07 -070029#include <thread>
Stan Rokita28790672019-08-20 14:32:15 -070030
Anthony Stangea689f8a2019-07-30 11:35:48 -040031namespace android {
32namespace hardware {
33namespace sensors {
34namespace V2_0 {
35namespace implementation {
36
Stan Rokita537c0272019-09-13 10:36:07 -070037using ::android::hardware::sensors::V2_0::EventQueueFlagBits;
38
Stan Rokita28790672019-08-20 14:32:15 -070039typedef ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*);
40
Anthony Stangea689f8a2019-07-30 11:35:48 -040041HalProxy::HalProxy() {
Stan Rokita7a723542019-08-29 15:47:50 -070042 const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf";
43 initializeSubHalListFromConfigFile(kMultiHalConfigFile);
Stan Rokita537c0272019-09-13 10:36:07 -070044 initializeSubHalCallbacksAndSensorList();
Anthony Stangea689f8a2019-07-30 11:35:48 -040045}
46
Anthony Stangeaacbf942019-08-30 15:21:34 -040047HalProxy::HalProxy(std::vector<ISensorsSubHal*>& subHalList) : mSubHalList(subHalList) {
Stan Rokita537c0272019-09-13 10:36:07 -070048 initializeSubHalCallbacksAndSensorList();
Anthony Stangeaacbf942019-08-30 15:21:34 -040049}
50
Anthony Stangea689f8a2019-07-30 11:35:48 -040051HalProxy::~HalProxy() {
Stan Rokita59714262019-09-20 10:55:30 -070052 {
53 std::lock_guard<std::mutex> lockGuard(mEventQueueWriteMutex);
54 mPendingWritesRun = false;
55 mEventQueueWriteCV.notify_one();
56 }
57 if (mPendingWritesThread.joinable()) {
58 mPendingWritesThread.join();
59 }
60 // TODO: Cleanup wakeup thread once it is implemented
Anthony Stangea689f8a2019-07-30 11:35:48 -040061}
62
Stan Rokitadc7a8e72019-08-23 12:35:40 -070063Return<void> HalProxy::getSensorsList(getSensorsList_cb _hidl_cb) {
Stan Rokita537c0272019-09-13 10:36:07 -070064 std::vector<SensorInfo> sensors;
65 for (const auto& iter : mSensors) {
66 sensors.push_back(iter.second);
67 }
68 _hidl_cb(sensors);
Anthony Stangea689f8a2019-07-30 11:35:48 -040069 return Void();
70}
71
Stan Rokita7a723542019-08-29 15:47:50 -070072Return<Result> HalProxy::setOperationMode(OperationMode mode) {
73 Result result = Result::OK;
74 size_t subHalIndex;
75 for (subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
76 ISensorsSubHal* subHal = mSubHalList[subHalIndex];
77 result = subHal->setOperationMode(mode);
78 if (result != Result::OK) {
79 ALOGE("setOperationMode failed for SubHal: %s", subHal->getName().c_str());
80 break;
81 }
82 }
83 if (result != Result::OK) {
84 // Reset the subhal operation modes that have been flipped
85 for (size_t i = 0; i < subHalIndex; i++) {
86 ISensorsSubHal* subHal = mSubHalList[i];
87 subHal->setOperationMode(mCurrentOperationMode);
88 }
89 } else {
90 mCurrentOperationMode = mode;
91 }
92 return result;
Anthony Stangea689f8a2019-07-30 11:35:48 -040093}
94
Stan Rokita4b4c7b72019-09-10 15:07:59 -070095Return<Result> HalProxy::activate(int32_t sensorHandle, bool enabled) {
96 return getSubHalForSensorHandle(sensorHandle)
Stan Rokitaf97a3f32019-09-13 09:58:47 -070097 ->activate(clearSubHalIndex(sensorHandle), enabled);
Anthony Stangea689f8a2019-07-30 11:35:48 -040098}
99
100Return<Result> HalProxy::initialize(
101 const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
102 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
103 const sp<ISensorsCallback>& sensorsCallback) {
104 Result result = Result::OK;
105
106 // TODO: clean up sensor requests, if not already done elsewhere through a death recipient, and
107 // clean up any other resources that exist (FMQs, flags, threads, etc.)
108
109 mDynamicSensorsCallback = sensorsCallback;
110
111 // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
112 mEventQueue =
113 std::make_unique<EventMessageQueue>(eventQueueDescriptor, true /* resetPointers */);
114
115 // Create the EventFlag that is used to signal to the framework that sensor events have been
116 // written to the Event FMQ
117 if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
118 result = Result::BAD_VALUE;
119 }
120
121 // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
122 // events have been successfully read and handled by the framework.
123 mWakeLockQueue =
124 std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
125
126 if (!mDynamicSensorsCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
127 result = Result::BAD_VALUE;
128 }
129
Stan Rokita59714262019-09-20 10:55:30 -0700130 mPendingWritesThread = std::thread(startPendingWritesThread, this);
131 // TODO: start threads to read wake locks.
Anthony Stangea689f8a2019-07-30 11:35:48 -0400132
Stan Rokita537c0272019-09-13 10:36:07 -0700133 for (size_t i = 0; i < mSubHalList.size(); i++) {
134 auto subHal = mSubHalList[i];
135 const auto& subHalCallback = mSubHalCallbacks[i];
136 Result currRes = subHal->initialize(subHalCallback);
137 if (currRes != Result::OK) {
138 result = currRes;
139 ALOGE("Subhal '%s' failed to initialize.", subHal->getName().c_str());
140 break;
141 }
142 }
143
Anthony Stangea689f8a2019-07-30 11:35:48 -0400144 return result;
145}
146
Stan Rokita4b4c7b72019-09-10 15:07:59 -0700147Return<Result> HalProxy::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
148 int64_t maxReportLatencyNs) {
149 return getSubHalForSensorHandle(sensorHandle)
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700150 ->batch(clearSubHalIndex(sensorHandle), samplingPeriodNs, maxReportLatencyNs);
Anthony Stangea689f8a2019-07-30 11:35:48 -0400151}
152
Stan Rokita4b4c7b72019-09-10 15:07:59 -0700153Return<Result> HalProxy::flush(int32_t sensorHandle) {
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700154 return getSubHalForSensorHandle(sensorHandle)->flush(clearSubHalIndex(sensorHandle));
Anthony Stangea689f8a2019-07-30 11:35:48 -0400155}
156
Stan Rokita83e43702019-09-24 10:16:08 -0700157Return<Result> HalProxy::injectSensorData(const Event& event) {
158 Result result = Result::OK;
159 if (mCurrentOperationMode == OperationMode::NORMAL &&
160 event.sensorType != V1_0::SensorType::ADDITIONAL_INFO) {
161 ALOGE("An event with type != ADDITIONAL_INFO passed to injectSensorData while operation"
162 " mode was NORMAL.");
163 result = Result::BAD_VALUE;
164 }
165 if (result == Result::OK) {
166 Event subHalEvent = event;
167 subHalEvent.sensorHandle = clearSubHalIndex(event.sensorHandle);
168 result = getSubHalForSensorHandle(event.sensorHandle)->injectSensorData(subHalEvent);
169 }
170 return result;
Anthony Stangea689f8a2019-07-30 11:35:48 -0400171}
172
Stan Rokitadb23aa82019-09-24 11:08:27 -0700173Return<void> HalProxy::registerDirectChannel(const SharedMemInfo& mem,
Anthony Stangea689f8a2019-07-30 11:35:48 -0400174 registerDirectChannel_cb _hidl_cb) {
Stan Rokitadb23aa82019-09-24 11:08:27 -0700175 if (mDirectChannelSubHal == nullptr) {
176 _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
177 } else {
178 mDirectChannelSubHal->registerDirectChannel(mem, _hidl_cb);
179 }
Anthony Stangea689f8a2019-07-30 11:35:48 -0400180 return Return<void>();
181}
182
Stan Rokitadb23aa82019-09-24 11:08:27 -0700183Return<Result> HalProxy::unregisterDirectChannel(int32_t channelHandle) {
184 Result result;
185 if (mDirectChannelSubHal == nullptr) {
186 result = Result::INVALID_OPERATION;
187 } else {
188 result = mDirectChannelSubHal->unregisterDirectChannel(channelHandle);
189 }
190 return result;
Anthony Stangea689f8a2019-07-30 11:35:48 -0400191}
192
Stan Rokitadb23aa82019-09-24 11:08:27 -0700193Return<void> HalProxy::configDirectReport(int32_t sensorHandle, int32_t channelHandle,
194 RateLevel rate, configDirectReport_cb _hidl_cb) {
195 if (mDirectChannelSubHal == nullptr) {
196 _hidl_cb(Result::INVALID_OPERATION, -1 /* reportToken */);
197 } else {
198 mDirectChannelSubHal->configDirectReport(clearSubHalIndex(sensorHandle), channelHandle,
199 rate, _hidl_cb);
200 }
Anthony Stangea689f8a2019-07-30 11:35:48 -0400201 return Return<void>();
202}
203
204Return<void> HalProxy::debug(const hidl_handle& /* fd */, const hidl_vec<hidl_string>& /* args */) {
205 // TODO: output debug information
206 return Return<void>();
207}
208
209Return<void> HalProxy::onDynamicSensorsConnected(
210 const hidl_vec<SensorInfo>& /* dynamicSensorsAdded */, int32_t /* subHalIndex */) {
211 // TODO: Map the SensorInfo to the global list and then invoke the framework's callback.
212 return Return<void>();
213}
214
215Return<void> HalProxy::onDynamicSensorsDisconnected(
216 const hidl_vec<int32_t>& /* dynamicSensorHandlesRemoved */, int32_t /* subHalIndex */) {
217 // TODO: Unmap the SensorInfo from the global list and then invoke the framework's callback.
218 return Return<void>();
219}
220
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700221void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
222 std::ifstream subHalConfigStream(configFileName);
223 if (!subHalConfigStream) {
Stan Rokita7a723542019-08-29 15:47:50 -0700224 ALOGE("Failed to load subHal config file: %s", configFileName);
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700225 } else {
226 std::string subHalLibraryFile;
227 while (subHalConfigStream >> subHalLibraryFile) {
228 void* handle = dlopen(subHalLibraryFile.c_str(), RTLD_NOW);
229 if (handle == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700230 ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700231 } else {
232 SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
233 (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
234 if (sensorsHalGetSubHalPtr == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700235 ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s",
236 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700237 } else {
238 std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
239 *sensorsHalGetSubHalPtr;
240 uint32_t version;
241 ISensorsSubHal* subHal = sensorsHalGetSubHal(&version);
242 if (version != SUB_HAL_2_0_VERSION) {
Stan Rokita7a723542019-08-29 15:47:50 -0700243 ALOGE("SubHal version was not 2.0 for library: %s",
244 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700245 } else {
246 ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
247 mSubHalList.push_back(subHal);
248 }
249 }
250 }
251 }
252 }
253}
254
Stan Rokita537c0272019-09-13 10:36:07 -0700255void HalProxy::initializeSubHalCallbacks() {
256 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
257 sp<IHalProxyCallback> callback = new HalProxyCallback(this, subHalIndex);
258 mSubHalCallbacks.push_back(callback);
259 }
260}
261
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700262void HalProxy::initializeSensorList() {
263 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
264 ISensorsSubHal* subHal = mSubHalList[subHalIndex];
265 auto result = subHal->getSensorsList([&](const auto& list) {
266 for (SensorInfo sensor : list) {
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700267 if ((sensor.sensorHandle & kSensorHandleSubHalIndexMask) != 0) {
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700268 ALOGE("SubHal sensorHandle's first byte was not 0");
269 } else {
270 ALOGV("Loaded sensor: %s", sensor.name.c_str());
271 sensor.sensorHandle |= (subHalIndex << 24);
Stan Rokita7a723542019-08-29 15:47:50 -0700272 setDirectChannelFlags(&sensor, subHal);
Stan Rokita537c0272019-09-13 10:36:07 -0700273 mSensors[sensor.sensorHandle] = sensor;
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700274 }
275 }
276 });
277 if (!result.isOk()) {
278 ALOGE("getSensorsList call failed for SubHal: %s", subHal->getName().c_str());
279 }
280 }
281}
282
Stan Rokita537c0272019-09-13 10:36:07 -0700283void HalProxy::initializeSubHalCallbacksAndSensorList() {
284 initializeSubHalCallbacks();
285 initializeSensorList();
286}
287
Stan Rokita59714262019-09-20 10:55:30 -0700288void HalProxy::startPendingWritesThread(HalProxy* halProxy) {
289 halProxy->handlePendingWrites();
290}
291
292void HalProxy::handlePendingWrites() {
293 // TODO: Find a way to optimize locking strategy maybe using two mutexes instead of one.
294 std::unique_lock<std::mutex> lock(mEventQueueWriteMutex);
295 while (mPendingWritesRun) {
296 mEventQueueWriteCV.wait(
297 lock, [&] { return !mPendingWriteEventsQueue.empty() || !mPendingWritesRun; });
298 if (!mPendingWriteEventsQueue.empty() && mPendingWritesRun) {
299 std::vector<Event>& pendingWriteEvents = mPendingWriteEventsQueue.front();
300 size_t eventQueueSize = mEventQueue->getQuantumCount();
301 size_t numToWrite = std::min(pendingWriteEvents.size(), eventQueueSize);
302 lock.unlock();
303 // TODO: Find a way to interrup writeBlocking if the thread should exit
304 // so we don't have to wait for timeout on framework restarts.
305 if (!mEventQueue->writeBlocking(
306 pendingWriteEvents.data(), numToWrite,
307 static_cast<uint32_t>(EventQueueFlagBits::EVENTS_READ),
308 static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS),
309 kWakelockTimeoutNs, mEventQueueFlag)) {
310 ALOGE("Dropping %zu events after blockingWrite failed.", numToWrite);
311 } else {
312 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
313 }
314 lock.lock();
315 if (pendingWriteEvents.size() > eventQueueSize) {
316 // TODO: Check if this erase operation is too inefficient. It will copy all the
317 // events ahead of it down to fill gap off array at front after the erase.
318 pendingWriteEvents.erase(pendingWriteEvents.begin(),
319 pendingWriteEvents.begin() + eventQueueSize);
320 } else {
321 mPendingWriteEventsQueue.pop();
322 }
323 }
324 }
325}
326
Stan Rokita537c0272019-09-13 10:36:07 -0700327void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events) {
Stan Rokita59714262019-09-20 10:55:30 -0700328 size_t numToWrite = 0;
329 std::lock_guard<std::mutex> lock(mEventQueueWriteMutex);
330 if (mPendingWriteEventsQueue.empty()) {
331 numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
332 if (numToWrite > 0) {
333 if (mEventQueue->write(events.data(), numToWrite)) {
334 // TODO: While loop if mEventQueue->avaiableToWrite > 0 to possibly fit in more
335 // writes immediately
336 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
337 } else {
338 numToWrite = 0;
339 }
Stan Rokita537c0272019-09-13 10:36:07 -0700340 }
341 }
342 if (numToWrite < events.size()) {
Stan Rokita59714262019-09-20 10:55:30 -0700343 // TODO: Bound the mPendingWriteEventsQueue so that we do not trigger OOMs if framework
344 // stalls
345 mPendingWriteEventsQueue.push(
346 std::vector<Event>(events.begin() + numToWrite, events.end()));
347 mEventQueueWriteCV.notify_one();
Stan Rokita537c0272019-09-13 10:36:07 -0700348 }
349}
350
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700351// TODO: Implement the wakelock timeout in these next two methods. Also pass in the subhal
352// index for better tracking.
353
354void HalProxy::incrementRefCountAndMaybeAcquireWakelock() {
355 std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
356 if (mWakelockRefCount == 0) {
357 acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName);
358 }
359 mWakelockRefCount++;
360}
361
362void HalProxy::decrementRefCountAndMaybeReleaseWakelock() {
363 std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
364 mWakelockRefCount--;
365 if (mWakelockRefCount == 0) {
366 release_wake_lock(kWakeLockName);
367 }
368}
369
Stan Rokita7a723542019-08-29 15:47:50 -0700370void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal) {
371 bool sensorSupportsDirectChannel =
372 (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
373 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0;
374 if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) {
375 mDirectChannelSubHal = subHal;
376 } else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) {
377 // disable direct channel capability for sensors in subHals that are not
378 // the only one we will enable
379 sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
380 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
381 }
382}
383
Stan Rokita16385312019-09-10 14:54:36 -0700384ISensorsSubHal* HalProxy::getSubHalForSensorHandle(uint32_t sensorHandle) {
385 return mSubHalList[static_cast<size_t>(sensorHandle >> 24)];
386}
387
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700388uint32_t HalProxy::clearSubHalIndex(uint32_t sensorHandle) {
389 return sensorHandle & (~kSensorHandleSubHalIndexMask);
Stan Rokita16385312019-09-10 14:54:36 -0700390}
391
Stan Rokita537c0272019-09-13 10:36:07 -0700392void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) {
393 (void)wakelock;
394 size_t numWakeupEvents;
395 std::vector<Event> processedEvents = processEvents(events, &numWakeupEvents);
396 if (numWakeupEvents > 0) {
397 ALOG_ASSERT(wakelock.isLocked(),
398 "Wakeup events posted while wakelock unlocked for subhal"
399 " w/ index %zu.",
400 mSubHalIndex);
401 } else {
402 ALOG_ASSERT(!wakelock.isLocked(),
403 "No Wakeup events posted but wakelock locked for subhal"
404 " w/ index %zu.",
405 mSubHalIndex);
406 }
407
408 mHalProxy->postEventsToMessageQueue(processedEvents);
409}
410
411ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) {
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700412 ScopedWakelock wakelock(mHalProxy, lock);
Stan Rokita537c0272019-09-13 10:36:07 -0700413 return wakelock;
414}
415
416std::vector<Event> HalProxyCallback::processEvents(const std::vector<Event>& events,
417 size_t* numWakeupEvents) const {
418 std::vector<Event> eventsOut;
419 *numWakeupEvents = 0;
420 for (Event event : events) {
421 event.sensorHandle = setSubHalIndex(event.sensorHandle);
422 eventsOut.push_back(event);
423 if ((mHalProxy->getSensorInfo(event.sensorHandle).flags & V1_0::SensorFlagBits::WAKE_UP) !=
424 0) {
425 (*numWakeupEvents)++;
426 }
427 }
428 return eventsOut;
429}
430
431uint32_t HalProxyCallback::setSubHalIndex(uint32_t sensorHandle) const {
432 return sensorHandle | mSubHalIndex << 24;
433}
434
Anthony Stangea689f8a2019-07-30 11:35:48 -0400435} // namespace implementation
436} // namespace V2_0
437} // namespace sensors
438} // namespace hardware
439} // namespace android