blob: f051a11a2c4ec21ad262a28c60fdaca1d26ce7f5 [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
165Return<void> HalProxy::registerDirectChannel(const SharedMemInfo& /* mem */,
166 registerDirectChannel_cb _hidl_cb) {
167 // TODO: During init, discover the first sub-HAL in the config that has sensors with direct
168 // channel support, if any, and proxy the API call there.
169 _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
170 return Return<void>();
171}
172
173Return<Result> HalProxy::unregisterDirectChannel(int32_t /* channelHandle */) {
174 // TODO: During init, discover the first sub-HAL in the config that has sensors with direct
175 // channel support, if any, and proxy the API call there.
176 return Result::INVALID_OPERATION;
177}
178
179Return<void> HalProxy::configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */,
180 RateLevel /* rate */, configDirectReport_cb _hidl_cb) {
181 // TODO: During init, discover the first sub-HAL in the config that has sensors with direct
182 // channel support, if any, and proxy the API call there.
183 _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */);
184 return Return<void>();
185}
186
187Return<void> HalProxy::debug(const hidl_handle& /* fd */, const hidl_vec<hidl_string>& /* args */) {
188 // TODO: output debug information
189 return Return<void>();
190}
191
192Return<void> HalProxy::onDynamicSensorsConnected(
193 const hidl_vec<SensorInfo>& /* dynamicSensorsAdded */, int32_t /* subHalIndex */) {
194 // TODO: Map the SensorInfo to the global list and then invoke the framework's callback.
195 return Return<void>();
196}
197
198Return<void> HalProxy::onDynamicSensorsDisconnected(
199 const hidl_vec<int32_t>& /* dynamicSensorHandlesRemoved */, int32_t /* subHalIndex */) {
200 // TODO: Unmap the SensorInfo from the global list and then invoke the framework's callback.
201 return Return<void>();
202}
203
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700204void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
205 std::ifstream subHalConfigStream(configFileName);
206 if (!subHalConfigStream) {
Stan Rokita7a723542019-08-29 15:47:50 -0700207 ALOGE("Failed to load subHal config file: %s", configFileName);
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700208 } else {
209 std::string subHalLibraryFile;
210 while (subHalConfigStream >> subHalLibraryFile) {
211 void* handle = dlopen(subHalLibraryFile.c_str(), RTLD_NOW);
212 if (handle == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700213 ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700214 } else {
215 SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
216 (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
217 if (sensorsHalGetSubHalPtr == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700218 ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s",
219 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700220 } else {
221 std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
222 *sensorsHalGetSubHalPtr;
223 uint32_t version;
224 ISensorsSubHal* subHal = sensorsHalGetSubHal(&version);
225 if (version != SUB_HAL_2_0_VERSION) {
Stan Rokita7a723542019-08-29 15:47:50 -0700226 ALOGE("SubHal version was not 2.0 for library: %s",
227 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700228 } else {
229 ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
230 mSubHalList.push_back(subHal);
231 }
232 }
233 }
234 }
235 }
236}
237
Stan Rokita537c0272019-09-13 10:36:07 -0700238void HalProxy::initializeSubHalCallbacks() {
239 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
240 sp<IHalProxyCallback> callback = new HalProxyCallback(this, subHalIndex);
241 mSubHalCallbacks.push_back(callback);
242 }
243}
244
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700245void HalProxy::initializeSensorList() {
246 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
247 ISensorsSubHal* subHal = mSubHalList[subHalIndex];
248 auto result = subHal->getSensorsList([&](const auto& list) {
249 for (SensorInfo sensor : list) {
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700250 if ((sensor.sensorHandle & kSensorHandleSubHalIndexMask) != 0) {
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700251 ALOGE("SubHal sensorHandle's first byte was not 0");
252 } else {
253 ALOGV("Loaded sensor: %s", sensor.name.c_str());
254 sensor.sensorHandle |= (subHalIndex << 24);
Stan Rokita7a723542019-08-29 15:47:50 -0700255 setDirectChannelFlags(&sensor, subHal);
Stan Rokita537c0272019-09-13 10:36:07 -0700256 mSensors[sensor.sensorHandle] = sensor;
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700257 }
258 }
259 });
260 if (!result.isOk()) {
261 ALOGE("getSensorsList call failed for SubHal: %s", subHal->getName().c_str());
262 }
263 }
264}
265
Stan Rokita537c0272019-09-13 10:36:07 -0700266void HalProxy::initializeSubHalCallbacksAndSensorList() {
267 initializeSubHalCallbacks();
268 initializeSensorList();
269}
270
271void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events) {
272 std::lock_guard<std::mutex> lock(mEventQueueMutex);
273 size_t numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
274 if (numToWrite > 0) {
275 if (mEventQueue->write(events.data(), numToWrite)) {
276 // TODO: While loop if mEventQueue->avaiableToWrite > 0 to possibly fit in more writes
277 // immediately
278 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
279 } else {
280 numToWrite = 0;
281 }
282 }
283 if (numToWrite < events.size()) {
284 // TODO: Post from events[numToWrite -> end] to background events queue
285 // Signal background thread
286 }
287}
288
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700289// TODO: Implement the wakelock timeout in these next two methods. Also pass in the subhal
290// index for better tracking.
291
292void HalProxy::incrementRefCountAndMaybeAcquireWakelock() {
293 std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
294 if (mWakelockRefCount == 0) {
295 acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName);
296 }
297 mWakelockRefCount++;
298}
299
300void HalProxy::decrementRefCountAndMaybeReleaseWakelock() {
301 std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
302 mWakelockRefCount--;
303 if (mWakelockRefCount == 0) {
304 release_wake_lock(kWakeLockName);
305 }
306}
307
Stan Rokita7a723542019-08-29 15:47:50 -0700308void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal) {
309 bool sensorSupportsDirectChannel =
310 (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
311 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0;
312 if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) {
313 mDirectChannelSubHal = subHal;
314 } else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) {
315 // disable direct channel capability for sensors in subHals that are not
316 // the only one we will enable
317 sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
318 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
319 }
320}
321
Stan Rokita16385312019-09-10 14:54:36 -0700322ISensorsSubHal* HalProxy::getSubHalForSensorHandle(uint32_t sensorHandle) {
323 return mSubHalList[static_cast<size_t>(sensorHandle >> 24)];
324}
325
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700326uint32_t HalProxy::clearSubHalIndex(uint32_t sensorHandle) {
327 return sensorHandle & (~kSensorHandleSubHalIndexMask);
Stan Rokita16385312019-09-10 14:54:36 -0700328}
329
Stan Rokita537c0272019-09-13 10:36:07 -0700330void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) {
331 (void)wakelock;
332 size_t numWakeupEvents;
333 std::vector<Event> processedEvents = processEvents(events, &numWakeupEvents);
334 if (numWakeupEvents > 0) {
335 ALOG_ASSERT(wakelock.isLocked(),
336 "Wakeup events posted while wakelock unlocked for subhal"
337 " w/ index %zu.",
338 mSubHalIndex);
339 } else {
340 ALOG_ASSERT(!wakelock.isLocked(),
341 "No Wakeup events posted but wakelock locked for subhal"
342 " w/ index %zu.",
343 mSubHalIndex);
344 }
345
346 mHalProxy->postEventsToMessageQueue(processedEvents);
347}
348
349ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) {
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700350 ScopedWakelock wakelock(mHalProxy, lock);
Stan Rokita537c0272019-09-13 10:36:07 -0700351 return wakelock;
352}
353
354std::vector<Event> HalProxyCallback::processEvents(const std::vector<Event>& events,
355 size_t* numWakeupEvents) const {
356 std::vector<Event> eventsOut;
357 *numWakeupEvents = 0;
358 for (Event event : events) {
359 event.sensorHandle = setSubHalIndex(event.sensorHandle);
360 eventsOut.push_back(event);
361 if ((mHalProxy->getSensorInfo(event.sensorHandle).flags & V1_0::SensorFlagBits::WAKE_UP) !=
362 0) {
363 (*numWakeupEvents)++;
364 }
365 }
366 return eventsOut;
367}
368
369uint32_t HalProxyCallback::setSubHalIndex(uint32_t sensorHandle) const {
370 return sensorHandle | mSubHalIndex << 24;
371}
372
Anthony Stangea689f8a2019-07-30 11:35:48 -0400373} // namespace implementation
374} // namespace V2_0
375} // namespace sensors
376} // namespace hardware
377} // namespace android