blob: 81d1b64af8c5be7b07401f4e33b28b0b3e0d11fc [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
149Return<Result> HalProxy::injectSensorData(const Event& /* event */) {
150 // TODO: Proxy API call to appropriate sub-HAL.
151 return Result::INVALID_OPERATION;
152}
153
154Return<void> HalProxy::registerDirectChannel(const SharedMemInfo& /* mem */,
155 registerDirectChannel_cb _hidl_cb) {
156 // TODO: During init, discover the first sub-HAL in the config that has sensors with direct
157 // channel support, if any, and proxy the API call there.
158 _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
159 return Return<void>();
160}
161
162Return<Result> HalProxy::unregisterDirectChannel(int32_t /* channelHandle */) {
163 // TODO: During init, discover the first sub-HAL in the config that has sensors with direct
164 // channel support, if any, and proxy the API call there.
165 return Result::INVALID_OPERATION;
166}
167
168Return<void> HalProxy::configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */,
169 RateLevel /* rate */, configDirectReport_cb _hidl_cb) {
170 // TODO: During init, discover the first sub-HAL in the config that has sensors with direct
171 // channel support, if any, and proxy the API call there.
172 _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */);
173 return Return<void>();
174}
175
176Return<void> HalProxy::debug(const hidl_handle& /* fd */, const hidl_vec<hidl_string>& /* args */) {
177 // TODO: output debug information
178 return Return<void>();
179}
180
181Return<void> HalProxy::onDynamicSensorsConnected(
182 const hidl_vec<SensorInfo>& /* dynamicSensorsAdded */, int32_t /* subHalIndex */) {
183 // TODO: Map the SensorInfo to the global list and then invoke the framework's callback.
184 return Return<void>();
185}
186
187Return<void> HalProxy::onDynamicSensorsDisconnected(
188 const hidl_vec<int32_t>& /* dynamicSensorHandlesRemoved */, int32_t /* subHalIndex */) {
189 // TODO: Unmap the SensorInfo from the global list and then invoke the framework's callback.
190 return Return<void>();
191}
192
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700193void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
194 std::ifstream subHalConfigStream(configFileName);
195 if (!subHalConfigStream) {
Stan Rokita7a723542019-08-29 15:47:50 -0700196 ALOGE("Failed to load subHal config file: %s", configFileName);
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700197 } else {
198 std::string subHalLibraryFile;
199 while (subHalConfigStream >> subHalLibraryFile) {
200 void* handle = dlopen(subHalLibraryFile.c_str(), RTLD_NOW);
201 if (handle == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700202 ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700203 } else {
204 SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
205 (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
206 if (sensorsHalGetSubHalPtr == nullptr) {
Stan Rokita7a723542019-08-29 15:47:50 -0700207 ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s",
208 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700209 } else {
210 std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
211 *sensorsHalGetSubHalPtr;
212 uint32_t version;
213 ISensorsSubHal* subHal = sensorsHalGetSubHal(&version);
214 if (version != SUB_HAL_2_0_VERSION) {
Stan Rokita7a723542019-08-29 15:47:50 -0700215 ALOGE("SubHal version was not 2.0 for library: %s",
216 subHalLibraryFile.c_str());
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700217 } else {
218 ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
219 mSubHalList.push_back(subHal);
220 }
221 }
222 }
223 }
224 }
225}
226
Stan Rokita537c0272019-09-13 10:36:07 -0700227void HalProxy::initializeSubHalCallbacks() {
228 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
229 sp<IHalProxyCallback> callback = new HalProxyCallback(this, subHalIndex);
230 mSubHalCallbacks.push_back(callback);
231 }
232}
233
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700234void HalProxy::initializeSensorList() {
235 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
236 ISensorsSubHal* subHal = mSubHalList[subHalIndex];
237 auto result = subHal->getSensorsList([&](const auto& list) {
238 for (SensorInfo sensor : list) {
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700239 if ((sensor.sensorHandle & kSensorHandleSubHalIndexMask) != 0) {
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700240 ALOGE("SubHal sensorHandle's first byte was not 0");
241 } else {
242 ALOGV("Loaded sensor: %s", sensor.name.c_str());
243 sensor.sensorHandle |= (subHalIndex << 24);
Stan Rokita7a723542019-08-29 15:47:50 -0700244 setDirectChannelFlags(&sensor, subHal);
Stan Rokita537c0272019-09-13 10:36:07 -0700245 mSensors[sensor.sensorHandle] = sensor;
Stan Rokitadc7a8e72019-08-23 12:35:40 -0700246 }
247 }
248 });
249 if (!result.isOk()) {
250 ALOGE("getSensorsList call failed for SubHal: %s", subHal->getName().c_str());
251 }
252 }
253}
254
Stan Rokita537c0272019-09-13 10:36:07 -0700255void HalProxy::initializeSubHalCallbacksAndSensorList() {
256 initializeSubHalCallbacks();
257 initializeSensorList();
258}
259
260void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events) {
261 std::lock_guard<std::mutex> lock(mEventQueueMutex);
262 size_t numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
263 if (numToWrite > 0) {
264 if (mEventQueue->write(events.data(), numToWrite)) {
265 // TODO: While loop if mEventQueue->avaiableToWrite > 0 to possibly fit in more writes
266 // immediately
267 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
268 } else {
269 numToWrite = 0;
270 }
271 }
272 if (numToWrite < events.size()) {
273 // TODO: Post from events[numToWrite -> end] to background events queue
274 // Signal background thread
275 }
276}
277
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700278// TODO: Implement the wakelock timeout in these next two methods. Also pass in the subhal
279// index for better tracking.
280
281void HalProxy::incrementRefCountAndMaybeAcquireWakelock() {
282 std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
283 if (mWakelockRefCount == 0) {
284 acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName);
285 }
286 mWakelockRefCount++;
287}
288
289void HalProxy::decrementRefCountAndMaybeReleaseWakelock() {
290 std::lock_guard<std::mutex> lockGuard(mWakelockRefCountMutex);
291 mWakelockRefCount--;
292 if (mWakelockRefCount == 0) {
293 release_wake_lock(kWakeLockName);
294 }
295}
296
Stan Rokita7a723542019-08-29 15:47:50 -0700297void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal) {
298 bool sensorSupportsDirectChannel =
299 (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
300 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0;
301 if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) {
302 mDirectChannelSubHal = subHal;
303 } else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) {
304 // disable direct channel capability for sensors in subHals that are not
305 // the only one we will enable
306 sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
307 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
308 }
309}
310
Stan Rokita16385312019-09-10 14:54:36 -0700311ISensorsSubHal* HalProxy::getSubHalForSensorHandle(uint32_t sensorHandle) {
312 return mSubHalList[static_cast<size_t>(sensorHandle >> 24)];
313}
314
Stan Rokitaf97a3f32019-09-13 09:58:47 -0700315uint32_t HalProxy::clearSubHalIndex(uint32_t sensorHandle) {
316 return sensorHandle & (~kSensorHandleSubHalIndexMask);
Stan Rokita16385312019-09-10 14:54:36 -0700317}
318
Stan Rokita537c0272019-09-13 10:36:07 -0700319void HalProxyCallback::postEvents(const std::vector<Event>& events, ScopedWakelock wakelock) {
320 (void)wakelock;
321 size_t numWakeupEvents;
322 std::vector<Event> processedEvents = processEvents(events, &numWakeupEvents);
323 if (numWakeupEvents > 0) {
324 ALOG_ASSERT(wakelock.isLocked(),
325 "Wakeup events posted while wakelock unlocked for subhal"
326 " w/ index %zu.",
327 mSubHalIndex);
328 } else {
329 ALOG_ASSERT(!wakelock.isLocked(),
330 "No Wakeup events posted but wakelock locked for subhal"
331 " w/ index %zu.",
332 mSubHalIndex);
333 }
334
335 mHalProxy->postEventsToMessageQueue(processedEvents);
336}
337
338ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) {
Stan Rokitad0cd57d2019-09-17 15:52:51 -0700339 ScopedWakelock wakelock(mHalProxy, lock);
Stan Rokita537c0272019-09-13 10:36:07 -0700340 return wakelock;
341}
342
343std::vector<Event> HalProxyCallback::processEvents(const std::vector<Event>& events,
344 size_t* numWakeupEvents) const {
345 std::vector<Event> eventsOut;
346 *numWakeupEvents = 0;
347 for (Event event : events) {
348 event.sensorHandle = setSubHalIndex(event.sensorHandle);
349 eventsOut.push_back(event);
350 if ((mHalProxy->getSensorInfo(event.sensorHandle).flags & V1_0::SensorFlagBits::WAKE_UP) !=
351 0) {
352 (*numWakeupEvents)++;
353 }
354 }
355 return eventsOut;
356}
357
358uint32_t HalProxyCallback::setSubHalIndex(uint32_t sensorHandle) const {
359 return sensorHandle | mSubHalIndex << 24;
360}
361
Anthony Stangea689f8a2019-07-30 11:35:48 -0400362} // namespace implementation
363} // namespace V2_0
364} // namespace sensors
365} // namespace hardware
366} // namespace android