blob: 7264e15c9f77c33797a5ca27fc274ba549b19417 [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() {
52 // TODO: Join any running threads and clean up FMQs and any other allocated
53 // state.
54}
55
Stan Rokitadc7a8e72019-08-23 12:35:40 -070056Return<void> HalProxy::getSensorsList(getSensorsList_cb _hidl_cb) {
Stan Rokita537c0272019-09-13 10:36:07 -070057 std::vector<SensorInfo> sensors;
58 for (const auto& iter : mSensors) {
59 sensors.push_back(iter.second);
60 }
61 _hidl_cb(sensors);
Anthony Stangea689f8a2019-07-30 11:35:48 -040062 return Void();
63}
64
Stan Rokita7a723542019-08-29 15:47:50 -070065Return<Result> HalProxy::setOperationMode(OperationMode mode) {
66 Result result = Result::OK;
67 size_t subHalIndex;
68 for (subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
69 ISensorsSubHal* subHal = mSubHalList[subHalIndex];
70 result = subHal->setOperationMode(mode);
71 if (result != Result::OK) {
72 ALOGE("setOperationMode failed for SubHal: %s", subHal->getName().c_str());
73 break;
74 }
75 }
76 if (result != Result::OK) {
77 // Reset the subhal operation modes that have been flipped
78 for (size_t i = 0; i < subHalIndex; i++) {
79 ISensorsSubHal* subHal = mSubHalList[i];
80 subHal->setOperationMode(mCurrentOperationMode);
81 }
82 } else {
83 mCurrentOperationMode = mode;
84 }
85 return result;
Anthony Stangea689f8a2019-07-30 11:35:48 -040086}
87
Stan Rokita4b4c7b72019-09-10 15:07:59 -070088Return<Result> HalProxy::activate(int32_t sensorHandle, bool enabled) {
89 return getSubHalForSensorHandle(sensorHandle)
Stan Rokitaf97a3f32019-09-13 09:58:47 -070090 ->activate(clearSubHalIndex(sensorHandle), enabled);
Anthony Stangea689f8a2019-07-30 11:35:48 -040091}
92
93Return<Result> HalProxy::initialize(
94 const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
95 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
96 const sp<ISensorsCallback>& sensorsCallback) {
97 Result result = Result::OK;
98
99 // TODO: clean up sensor requests, if not already done elsewhere through a death recipient, and
100 // clean up any other resources that exist (FMQs, flags, threads, etc.)
101
102 mDynamicSensorsCallback = sensorsCallback;
103
104 // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
105 mEventQueue =
106 std::make_unique<EventMessageQueue>(eventQueueDescriptor, true /* resetPointers */);
107
108 // Create the EventFlag that is used to signal to the framework that sensor events have been
109 // written to the Event FMQ
110 if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
111 result = Result::BAD_VALUE;
112 }
113
114 // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
115 // events have been successfully read and handled by the framework.
116 mWakeLockQueue =
117 std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
118
119 if (!mDynamicSensorsCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
120 result = Result::BAD_VALUE;
121 }
122
123 // TODO: start threads to read wake locks and process events from sub HALs.
124
Stan Rokita537c0272019-09-13 10:36:07 -0700125 for (size_t i = 0; i < mSubHalList.size(); i++) {
126 auto subHal = mSubHalList[i];
127 const auto& subHalCallback = mSubHalCallbacks[i];
128 Result currRes = subHal->initialize(subHalCallback);
129 if (currRes != Result::OK) {
130 result = currRes;
131 ALOGE("Subhal '%s' failed to initialize.", subHal->getName().c_str());
132 break;
133 }
134 }
135
Anthony Stangea689f8a2019-07-30 11:35:48 -0400136 return result;
137}
138
Stan Rokita4b4c7b72019-09-10 15:07:59 -0700139Return<Result> HalProxy::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
140 int64_t maxReportLatencyNs) {
141 return getSubHalForSensorHandle(sensorHandle)
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700142 ->batch(clearSubHalIndex(sensorHandle), samplingPeriodNs, maxReportLatencyNs);
Anthony Stangea689f8a2019-07-30 11:35:48 -0400143}
144
Stan Rokita4b4c7b72019-09-10 15:07:59 -0700145Return<Result> HalProxy::flush(int32_t sensorHandle) {
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700146 return getSubHalForSensorHandle(sensorHandle)->flush(clearSubHalIndex(sensorHandle));
Anthony Stangea689f8a2019-07-30 11:35:48 -0400147}
148
Stan Rokita83e43702019-09-24 10:16:08 -0700149Return<Result> HalProxy::injectSensorData(const Event& event) {
150 Result result = Result::OK;
151 if (mCurrentOperationMode == OperationMode::NORMAL &&
152 event.sensorType != V1_0::SensorType::ADDITIONAL_INFO) {
153 ALOGE("An event with type != ADDITIONAL_INFO passed to injectSensorData while operation"
154 " mode was NORMAL.");
155 result = Result::BAD_VALUE;
156 }
157 if (result == Result::OK) {
158 Event subHalEvent = event;
159 subHalEvent.sensorHandle = clearSubHalIndex(event.sensorHandle);
160 result = getSubHalForSensorHandle(event.sensorHandle)->injectSensorData(subHalEvent);
161 }
162 return result;
Anthony Stangea689f8a2019-07-30 11:35:48 -0400163}
164
Stan Rokitadb23aa82019-09-24 11:08:27 -0700165Return<void> HalProxy::registerDirectChannel(const SharedMemInfo& mem,
Anthony Stangea689f8a2019-07-30 11:35:48 -0400166 registerDirectChannel_cb _hidl_cb) {
Stan Rokitadb23aa82019-09-24 11:08:27 -0700167 if (mDirectChannelSubHal == nullptr) {
168 _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
169 } else {
170 mDirectChannelSubHal->registerDirectChannel(mem, _hidl_cb);
171 }
Anthony Stangea689f8a2019-07-30 11:35:48 -0400172 return Return<void>();
173}
174
Stan Rokitadb23aa82019-09-24 11:08:27 -0700175Return<Result> HalProxy::unregisterDirectChannel(int32_t channelHandle) {
176 Result result;
177 if (mDirectChannelSubHal == nullptr) {
178 result = Result::INVALID_OPERATION;
179 } else {
180 result = mDirectChannelSubHal->unregisterDirectChannel(channelHandle);
181 }
182 return result;
Anthony Stangea689f8a2019-07-30 11:35:48 -0400183}
184
Stan Rokitadb23aa82019-09-24 11:08:27 -0700185Return<void> HalProxy::configDirectReport(int32_t sensorHandle, int32_t channelHandle,
186 RateLevel rate, configDirectReport_cb _hidl_cb) {
187 if (mDirectChannelSubHal == nullptr) {
188 _hidl_cb(Result::INVALID_OPERATION, -1 /* reportToken */);
189 } else {
190 mDirectChannelSubHal->configDirectReport(clearSubHalIndex(sensorHandle), channelHandle,
191 rate, _hidl_cb);
192 }
Anthony Stangea689f8a2019-07-30 11:35:48 -0400193 return Return<void>();
194}
195
196Return<void> HalProxy::debug(const hidl_handle& /* fd */, const hidl_vec<hidl_string>& /* args */) {
197 // TODO: output debug information
198 return Return<void>();
199}
200
201Return<void> HalProxy::onDynamicSensorsConnected(
202 const hidl_vec<SensorInfo>& /* dynamicSensorsAdded */, int32_t /* subHalIndex */) {
203 // TODO: Map the SensorInfo to the global list and then invoke the framework's callback.
204 return Return<void>();
205}
206
207Return<void> HalProxy::onDynamicSensorsDisconnected(
208 const hidl_vec<int32_t>& /* dynamicSensorHandlesRemoved */, int32_t /* subHalIndex */) {
209 // TODO: Unmap the SensorInfo from the global list and then invoke the framework's callback.
210 return Return<void>();
211}
212
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700213void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
214 std::ifstream subHalConfigStream(configFileName);
215 if (!subHalConfigStream) {
Stan Rokita7a723542019-08-29 15:47:50 -0700216 ALOGE("Failed to load subHal config file: %s", configFileName);
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700217 } else {
218 std::string subHalLibraryFile;
219 while (subHalConfigStream >> subHalLibraryFile) {
220 void* handle = dlopen(subHalLibraryFile.c_str(), RTLD_NOW);
221 if (handle == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700222 ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700223 } else {
224 SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
225 (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
226 if (sensorsHalGetSubHalPtr == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700227 ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s",
228 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700229 } else {
230 std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
231 *sensorsHalGetSubHalPtr;
232 uint32_t version;
233 ISensorsSubHal* subHal = sensorsHalGetSubHal(&version);
234 if (version != SUB_HAL_2_0_VERSION) {
Stan Rokita7a723542019-08-29 15:47:50 -0700235 ALOGE("SubHal version was not 2.0 for library: %s",
236 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700237 } else {
238 ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
239 mSubHalList.push_back(subHal);
240 }
241 }
242 }
243 }
244 }
245}
246
Stan Rokita537c0272019-09-13 10:36:07 -0700247void HalProxy::initializeSubHalCallbacks() {
248 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
249 sp<IHalProxyCallback> callback = new HalProxyCallback(this, subHalIndex);
250 mSubHalCallbacks.push_back(callback);
251 }
252}
253
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700254void HalProxy::initializeSensorList() {
255 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
256 ISensorsSubHal* subHal = mSubHalList[subHalIndex];
257 auto result = subHal->getSensorsList([&](const auto& list) {
258 for (SensorInfo sensor : list) {
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700259 if ((sensor.sensorHandle & kSensorHandleSubHalIndexMask) != 0) {
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700260 ALOGE("SubHal sensorHandle's first byte was not 0");
261 } else {
262 ALOGV("Loaded sensor: %s", sensor.name.c_str());
263 sensor.sensorHandle |= (subHalIndex << 24);
Stan Rokita7a723542019-08-29 15:47:50 -0700264 setDirectChannelFlags(&sensor, subHal);
Stan Rokita537c0272019-09-13 10:36:07 -0700265 mSensors[sensor.sensorHandle] = sensor;
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700266 }
267 }
268 });
269 if (!result.isOk()) {
270 ALOGE("getSensorsList call failed for SubHal: %s", subHal->getName().c_str());
271 }
272 }
273}
274
Stan Rokita537c0272019-09-13 10:36:07 -0700275void HalProxy::initializeSubHalCallbacksAndSensorList() {
276 initializeSubHalCallbacks();
277 initializeSensorList();
278}
279
280void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events) {
281 std::lock_guard<std::mutex> lock(mEventQueueMutex);
282 size_t numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
283 if (numToWrite > 0) {
284 if (mEventQueue->write(events.data(), numToWrite)) {
285 // TODO: While loop if mEventQueue->avaiableToWrite > 0 to possibly fit in more writes
286 // immediately
287 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
288 } else {
289 numToWrite = 0;
290 }
291 }
292 if (numToWrite < events.size()) {
293 // TODO: Post from events[numToWrite -> end] to background events queue
294 // Signal background thread
295 }
296}
297
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700298// TODO: Implement the wakelock timeout in these next two methods. Also pass in the subhal
299// index for better tracking.
300
301void HalProxy::incrementRefCountAndMaybeAcquireWakelock() {
302 std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
303 if (mWakelockRefCount == 0) {
304 acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName);
305 }
306 mWakelockRefCount++;
307}
308
309void HalProxy::decrementRefCountAndMaybeReleaseWakelock() {
310 std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
311 mWakelockRefCount--;
312 if (mWakelockRefCount == 0) {
313 release_wake_lock(kWakeLockName);
314 }
315}
316
Stan Rokita7a723542019-08-29 15:47:50 -0700317void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal) {
318 bool sensorSupportsDirectChannel =
319 (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
320 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0;
321 if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) {
322 mDirectChannelSubHal = subHal;
323 } else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) {
324 // disable direct channel capability for sensors in subHals that are not
325 // the only one we will enable
326 sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
327 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
328 }
329}
330
Stan Rokita16385312019-09-10 14:54:36 -0700331ISensorsSubHal* HalProxy::getSubHalForSensorHandle(uint32_t sensorHandle) {
332 return mSubHalList[static_cast<size_t>(sensorHandle >> 24)];
333}
334
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700335uint32_t HalProxy::clearSubHalIndex(uint32_t sensorHandle) {
336 return sensorHandle & (~kSensorHandleSubHalIndexMask);
Stan Rokita16385312019-09-10 14:54:36 -0700337}
338
Stan Rokita537c0272019-09-13 10:36:07 -0700339void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) {
340 (void)wakelock;
341 size_t numWakeupEvents;
342 std::vector<Event> processedEvents = processEvents(events, &numWakeupEvents);
343 if (numWakeupEvents > 0) {
344 ALOG_ASSERT(wakelock.isLocked(),
345 "Wakeup events posted while wakelock unlocked for subhal"
346 " w/ index %zu.",
347 mSubHalIndex);
348 } else {
349 ALOG_ASSERT(!wakelock.isLocked(),
350 "No Wakeup events posted but wakelock locked for subhal"
351 " w/ index %zu.",
352 mSubHalIndex);
353 }
354
355 mHalProxy->postEventsToMessageQueue(processedEvents);
356}
357
358ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) {
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700359 ScopedWakelock wakelock(mHalProxy, lock);
Stan Rokita537c0272019-09-13 10:36:07 -0700360 return wakelock;
361}
362
363std::vector<Event> HalProxyCallback::processEvents(const std::vector<Event>& events,
364 size_t* numWakeupEvents) const {
365 std::vector<Event> eventsOut;
366 *numWakeupEvents = 0;
367 for (Event event : events) {
368 event.sensorHandle = setSubHalIndex(event.sensorHandle);
369 eventsOut.push_back(event);
370 if ((mHalProxy->getSensorInfo(event.sensorHandle).flags & V1_0::SensorFlagBits::WAKE_UP) !=
371 0) {
372 (*numWakeupEvents)++;
373 }
374 }
375 return eventsOut;
376}
377
378uint32_t HalProxyCallback::setSubHalIndex(uint32_t sensorHandle) const {
379 return sensorHandle | mSubHalIndex << 24;
380}
381
Anthony Stangea689f8a2019-07-30 11:35:48 -0400382} // namespace implementation
383} // namespace V2_0
384} // namespace sensors
385} // namespace hardware
386} // namespace android