1 /*
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
19 #include <android/hardware/sensors/2.0/types.h>
20
21 #include <android-base/file.h>
22 #include "hardware_legacy/power.h"
23
24 #include <dlfcn.h>
25
26 #include <cinttypes>
27 #include <cmath>
28 #include <fstream>
29 #include <functional>
30 #include <thread>
31
32 namespace android {
33 namespace hardware {
34 namespace sensors {
35 namespace V2_1 {
36 namespace implementation {
37
38 using ::android::hardware::sensors::V1_0::Result;
39 using ::android::hardware::sensors::V2_0::EventQueueFlagBits;
40 using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits;
41 using ::android::hardware::sensors::V2_0::implementation::getTimeNow;
42 using ::android::hardware::sensors::V2_0::implementation::kWakelockTimeoutNs;
43
44 typedef V2_0::implementation::ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*);
45 typedef V2_1::implementation::ISensorsSubHal*(SensorsHalGetSubHalV2_1Func)(uint32_t*);
46
47 static constexpr int32_t kBitsAfterSubHalIndex = 24;
48
49 /**
50 * Set the subhal index as first byte of sensor handle and return this modified version.
51 *
52 * @param sensorHandle The sensor handle to modify.
53 * @param subHalIndex The index in the hal proxy of the sub hal this sensor belongs to.
54 *
55 * @return The modified sensor handle.
56 */
setSubHalIndex(int32_t sensorHandle,size_t subHalIndex)57 int32_t setSubHalIndex(int32_t sensorHandle, size_t subHalIndex) {
58 return sensorHandle | (static_cast<int32_t>(subHalIndex) << kBitsAfterSubHalIndex);
59 }
60
61 /**
62 * Extract the subHalIndex from sensorHandle.
63 *
64 * @param sensorHandle The sensorHandle to extract from.
65 *
66 * @return The subhal index.
67 */
extractSubHalIndex(int32_t sensorHandle)68 size_t extractSubHalIndex(int32_t sensorHandle) {
69 return static_cast<size_t>(sensorHandle >> kBitsAfterSubHalIndex);
70 }
71
72 /**
73 * Convert nanoseconds to milliseconds.
74 *
75 * @param nanos The nanoseconds input.
76 *
77 * @return The milliseconds count.
78 */
msFromNs(int64_t nanos)79 int64_t msFromNs(int64_t nanos) {
80 constexpr int64_t nanosecondsInAMillsecond = 1000000;
81 return nanos / nanosecondsInAMillsecond;
82 }
83
HalProxy()84 HalProxy::HalProxy() {
85 static const std::string kMultiHalConfigFiles[] = {"/vendor/etc/sensors/hals.conf",
86 "/odm/etc/sensors/hals.conf"};
87 for (const std::string& configFile : kMultiHalConfigFiles) {
88 initializeSubHalListFromConfigFile(configFile.c_str());
89 }
90 init();
91 }
92
HalProxy(std::vector<ISensorsSubHalV2_0 * > & subHalList)93 HalProxy::HalProxy(std::vector<ISensorsSubHalV2_0*>& subHalList) {
94 for (ISensorsSubHalV2_0* subHal : subHalList) {
95 mSubHalList.push_back(std::make_unique<SubHalWrapperV2_0>(subHal));
96 }
97
98 init();
99 }
100
HalProxy(std::vector<ISensorsSubHalV2_0 * > & subHalList,std::vector<ISensorsSubHalV2_1 * > & subHalListV2_1)101 HalProxy::HalProxy(std::vector<ISensorsSubHalV2_0*>& subHalList,
102 std::vector<ISensorsSubHalV2_1*>& subHalListV2_1) {
103 for (ISensorsSubHalV2_0* subHal : subHalList) {
104 mSubHalList.push_back(std::make_unique<SubHalWrapperV2_0>(subHal));
105 }
106
107 for (ISensorsSubHalV2_1* subHal : subHalListV2_1) {
108 mSubHalList.push_back(std::make_unique<SubHalWrapperV2_1>(subHal));
109 }
110
111 init();
112 }
113
~HalProxy()114 HalProxy::~HalProxy() {
115 stopThreads();
116 }
117
getSensorsList_2_1(ISensorsV2_1::getSensorsList_2_1_cb _hidl_cb)118 Return<void> HalProxy::getSensorsList_2_1(ISensorsV2_1::getSensorsList_2_1_cb _hidl_cb) {
119 std::vector<V2_1::SensorInfo> sensors;
120 for (const auto& iter : mSensors) {
121 sensors.push_back(iter.second);
122 }
123 _hidl_cb(sensors);
124 return Void();
125 }
126
getSensorsList(ISensorsV2_0::getSensorsList_cb _hidl_cb)127 Return<void> HalProxy::getSensorsList(ISensorsV2_0::getSensorsList_cb _hidl_cb) {
128 std::vector<V1_0::SensorInfo> sensors;
129 for (const auto& iter : mSensors) {
130 if (iter.second.type != SensorType::HINGE_ANGLE) {
131 sensors.push_back(convertToOldSensorInfo(iter.second));
132 }
133 }
134 _hidl_cb(sensors);
135 return Void();
136 }
137
setOperationMode(OperationMode mode)138 Return<Result> HalProxy::setOperationMode(OperationMode mode) {
139 Result result = Result::OK;
140 size_t subHalIndex;
141 for (subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
142 result = mSubHalList[subHalIndex]->setOperationMode(mode);
143 if (result != Result::OK) {
144 ALOGE("setOperationMode failed for SubHal: %s",
145 mSubHalList[subHalIndex]->getName().c_str());
146 break;
147 }
148 }
149
150 if (result != Result::OK) {
151 // Reset the subhal operation modes that have been flipped
152 for (size_t i = 0; i < subHalIndex; i++) {
153 mSubHalList[i]->setOperationMode(mCurrentOperationMode);
154 }
155 } else {
156 mCurrentOperationMode = mode;
157 }
158 return result;
159 }
160
activate(int32_t sensorHandle,bool enabled)161 Return<Result> HalProxy::activate(int32_t sensorHandle, bool enabled) {
162 if (!isSubHalIndexValid(sensorHandle)) {
163 return Result::BAD_VALUE;
164 }
165 return getSubHalForSensorHandle(sensorHandle)
166 ->activate(clearSubHalIndex(sensorHandle), enabled);
167 }
168
initialize_2_1(const::android::hardware::MQDescriptorSync<V2_1::Event> & eventQueueDescriptor,const::android::hardware::MQDescriptorSync<uint32_t> & wakeLockDescriptor,const sp<V2_1::ISensorsCallback> & sensorsCallback)169 Return<Result> HalProxy::initialize_2_1(
170 const ::android::hardware::MQDescriptorSync<V2_1::Event>& eventQueueDescriptor,
171 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
172 const sp<V2_1::ISensorsCallback>& sensorsCallback) {
173 sp<ISensorsCallbackWrapperBase> dynamicCallback =
174 new ISensorsCallbackWrapperV2_1(sensorsCallback);
175
176 // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
177 auto eventQueue =
178 std::make_unique<EventMessageQueueV2_1>(eventQueueDescriptor, true /* resetPointers */);
179 std::unique_ptr<EventMessageQueueWrapperBase> queue =
180 std::make_unique<EventMessageQueueWrapperV2_1>(eventQueue);
181
182 // Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions.
183 auto hidlWakeLockQueue =
184 std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
185 std::unique_ptr<WakeLockMessageQueueWrapperBase> wakeLockQueue =
186 std::make_unique<WakeLockMessageQueueWrapperHidl>(hidlWakeLockQueue);
187
188 return initializeCommon(queue, wakeLockQueue, dynamicCallback);
189 }
190
initialize(const::android::hardware::MQDescriptorSync<V1_0::Event> & eventQueueDescriptor,const::android::hardware::MQDescriptorSync<uint32_t> & wakeLockDescriptor,const sp<V2_0::ISensorsCallback> & sensorsCallback)191 Return<Result> HalProxy::initialize(
192 const ::android::hardware::MQDescriptorSync<V1_0::Event>& eventQueueDescriptor,
193 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
194 const sp<V2_0::ISensorsCallback>& sensorsCallback) {
195 sp<ISensorsCallbackWrapperBase> dynamicCallback =
196 new ISensorsCallbackWrapperV2_0(sensorsCallback);
197
198 // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
199 auto eventQueue =
200 std::make_unique<EventMessageQueueV2_0>(eventQueueDescriptor, true /* resetPointers */);
201 std::unique_ptr<EventMessageQueueWrapperBase> queue =
202 std::make_unique<EventMessageQueueWrapperV1_0>(eventQueue);
203
204 // Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions.
205 auto hidlWakeLockQueue =
206 std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
207 std::unique_ptr<WakeLockMessageQueueWrapperBase> wakeLockQueue =
208 std::make_unique<WakeLockMessageQueueWrapperHidl>(hidlWakeLockQueue);
209
210 return initializeCommon(queue, wakeLockQueue, dynamicCallback);
211 }
212
initializeCommon(std::unique_ptr<EventMessageQueueWrapperBase> & eventQueue,std::unique_ptr<WakeLockMessageQueueWrapperBase> & wakeLockQueue,const sp<ISensorsCallbackWrapperBase> & sensorsCallback)213 Return<Result> HalProxy::initializeCommon(
214 std::unique_ptr<EventMessageQueueWrapperBase>& eventQueue,
215 std::unique_ptr<WakeLockMessageQueueWrapperBase>& wakeLockQueue,
216 const sp<ISensorsCallbackWrapperBase>& sensorsCallback) {
217 Result result = Result::OK;
218
219 stopThreads();
220 resetSharedWakelock();
221
222 // So that the pending write events queue can be cleared safely and when we start threads
223 // again we do not get new events until after initialize resets the subhals.
224 disableAllSensors();
225
226 // Clears the queue if any events were pending write before.
227 mPendingWriteEventsQueue = std::queue<std::pair<std::vector<V2_1::Event>, size_t>>();
228 mSizePendingWriteEventsQueue = 0;
229
230 // Clears previously connected dynamic sensors
231 mDynamicSensors.clear();
232
233 mDynamicSensorsCallback = sensorsCallback;
234
235 // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
236 mEventQueue = std::move(eventQueue);
237
238 // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
239 // events have been successfully read and handled by the framework.
240 mWakeLockQueue = std::move(wakeLockQueue);
241
242 if (mEventQueueFlag != nullptr) {
243 EventFlag::deleteEventFlag(&mEventQueueFlag);
244 }
245 if (mWakelockQueueFlag != nullptr) {
246 EventFlag::deleteEventFlag(&mWakelockQueueFlag);
247 }
248 if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
249 result = Result::BAD_VALUE;
250 }
251 if (EventFlag::createEventFlag(mWakeLockQueue->getEventFlagWord(), &mWakelockQueueFlag) != OK) {
252 result = Result::BAD_VALUE;
253 }
254 if (!mDynamicSensorsCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
255 result = Result::BAD_VALUE;
256 }
257
258 mThreadsRun.store(true);
259
260 mPendingWritesThread = std::thread(startPendingWritesThread, this);
261 mWakelockThread = std::thread(startWakelockThread, this);
262
263 for (size_t i = 0; i < mSubHalList.size(); i++) {
264 Result currRes = mSubHalList[i]->initialize(this, this, i);
265 if (currRes != Result::OK) {
266 result = currRes;
267 ALOGE("Subhal '%s' failed to initialize with reason %" PRId32 ".",
268 mSubHalList[i]->getName().c_str(), static_cast<int32_t>(currRes));
269 }
270 }
271
272 mCurrentOperationMode = OperationMode::NORMAL;
273
274 return result;
275 }
276
batch(int32_t sensorHandle,int64_t samplingPeriodNs,int64_t maxReportLatencyNs)277 Return<Result> HalProxy::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
278 int64_t maxReportLatencyNs) {
279 if (!isSubHalIndexValid(sensorHandle)) {
280 return Result::BAD_VALUE;
281 }
282 return getSubHalForSensorHandle(sensorHandle)
283 ->batch(clearSubHalIndex(sensorHandle), samplingPeriodNs, maxReportLatencyNs);
284 }
285
flush(int32_t sensorHandle)286 Return<Result> HalProxy::flush(int32_t sensorHandle) {
287 if (!isSubHalIndexValid(sensorHandle)) {
288 return Result::BAD_VALUE;
289 }
290 return getSubHalForSensorHandle(sensorHandle)->flush(clearSubHalIndex(sensorHandle));
291 }
292
injectSensorData_2_1(const V2_1::Event & event)293 Return<Result> HalProxy::injectSensorData_2_1(const V2_1::Event& event) {
294 return injectSensorData(convertToOldEvent(event));
295 }
296
injectSensorData(const V1_0::Event & event)297 Return<Result> HalProxy::injectSensorData(const V1_0::Event& event) {
298 Result result = Result::OK;
299 if (mCurrentOperationMode == OperationMode::NORMAL &&
300 event.sensorType != V1_0::SensorType::ADDITIONAL_INFO) {
301 ALOGE("An event with type != ADDITIONAL_INFO passed to injectSensorData while operation"
302 " mode was NORMAL.");
303 result = Result::BAD_VALUE;
304 }
305 if (result == Result::OK) {
306 V1_0::Event subHalEvent = event;
307 if (!isSubHalIndexValid(event.sensorHandle)) {
308 return Result::BAD_VALUE;
309 }
310 subHalEvent.sensorHandle = clearSubHalIndex(event.sensorHandle);
311 result = getSubHalForSensorHandle(event.sensorHandle)
312 ->injectSensorData(convertToNewEvent(subHalEvent));
313 }
314 return result;
315 }
316
registerDirectChannel(const SharedMemInfo & mem,ISensorsV2_0::registerDirectChannel_cb _hidl_cb)317 Return<void> HalProxy::registerDirectChannel(const SharedMemInfo& mem,
318 ISensorsV2_0::registerDirectChannel_cb _hidl_cb) {
319 if (mDirectChannelSubHal == nullptr) {
320 _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
321 } else {
322 mDirectChannelSubHal->registerDirectChannel(mem, _hidl_cb);
323 }
324 return Return<void>();
325 }
326
unregisterDirectChannel(int32_t channelHandle)327 Return<Result> HalProxy::unregisterDirectChannel(int32_t channelHandle) {
328 Result result;
329 if (mDirectChannelSubHal == nullptr) {
330 result = Result::INVALID_OPERATION;
331 } else {
332 result = mDirectChannelSubHal->unregisterDirectChannel(channelHandle);
333 }
334 return result;
335 }
336
configDirectReport(int32_t sensorHandle,int32_t channelHandle,RateLevel rate,ISensorsV2_0::configDirectReport_cb _hidl_cb)337 Return<void> HalProxy::configDirectReport(int32_t sensorHandle, int32_t channelHandle,
338 RateLevel rate,
339 ISensorsV2_0::configDirectReport_cb _hidl_cb) {
340 if (mDirectChannelSubHal == nullptr) {
341 _hidl_cb(Result::INVALID_OPERATION, -1 /* reportToken */);
342 } else if (sensorHandle == -1 && rate != RateLevel::STOP) {
343 _hidl_cb(Result::BAD_VALUE, -1 /* reportToken */);
344 } else {
345 // -1 denotes all sensors should be disabled
346 if (sensorHandle != -1) {
347 sensorHandle = clearSubHalIndex(sensorHandle);
348 }
349 mDirectChannelSubHal->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb);
350 }
351 return Return<void>();
352 }
353
debug(const hidl_handle & fd,const hidl_vec<hidl_string> & args)354 Return<void> HalProxy::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
355 if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
356 ALOGE("%s: missing fd for writing", __FUNCTION__);
357 return Void();
358 }
359
360 int writeFd = fd->data[0];
361
362 std::ostringstream stream;
363 stream << "===HalProxy===" << std::endl;
364 stream << "Internal values:" << std::endl;
365 stream << " Threads are running: " << (mThreadsRun.load() ? "true" : "false") << std::endl;
366 int64_t now = getTimeNow();
367 stream << " Wakelock timeout start time: " << msFromNs(now - mWakelockTimeoutStartTime)
368 << " ms ago" << std::endl;
369 stream << " Wakelock timeout reset time: " << msFromNs(now - mWakelockTimeoutResetTime)
370 << " ms ago" << std::endl;
371 // TODO(b/142969448): Add logging for history of wakelock acquisition per subhal.
372 stream << " Wakelock ref count: " << mWakelockRefCount << std::endl;
373 stream << " # of events on pending write writes queue: " << mSizePendingWriteEventsQueue
374 << std::endl;
375 stream << " Most events seen on pending write events queue: "
376 << mMostEventsObservedPendingWriteEventsQueue << std::endl;
377 if (!mPendingWriteEventsQueue.empty()) {
378 stream << " Size of events list on front of pending writes queue: "
379 << mPendingWriteEventsQueue.front().first.size() << std::endl;
380 }
381 stream << " # of non-dynamic sensors across all subhals: " << mSensors.size() << std::endl;
382 stream << " # of dynamic sensors across all subhals: " << mDynamicSensors.size() << std::endl;
383 stream << "SubHals (" << mSubHalList.size() << "):" << std::endl;
384 for (auto& subHal : mSubHalList) {
385 stream << " Name: " << subHal->getName() << std::endl;
386 stream << " Debug dump: " << std::endl;
387 android::base::WriteStringToFd(stream.str(), writeFd);
388 subHal->debug(fd, args);
389 stream.str("");
390 stream << std::endl;
391 }
392 android::base::WriteStringToFd(stream.str(), writeFd);
393 return Return<void>();
394 }
395
onDynamicSensorsConnected(const hidl_vec<SensorInfo> & dynamicSensorsAdded,int32_t subHalIndex)396 Return<void> HalProxy::onDynamicSensorsConnected(const hidl_vec<SensorInfo>& dynamicSensorsAdded,
397 int32_t subHalIndex) {
398 std::vector<SensorInfo> sensors;
399 {
400 std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
401 for (SensorInfo sensor : dynamicSensorsAdded) {
402 if (!subHalIndexIsClear(sensor.sensorHandle)) {
403 ALOGE("Dynamic sensor added %s had sensorHandle with first byte not 0.",
404 sensor.name.c_str());
405 } else {
406 sensor.sensorHandle = setSubHalIndex(sensor.sensorHandle, subHalIndex);
407 mDynamicSensors[sensor.sensorHandle] = sensor;
408 sensors.push_back(sensor);
409 }
410 }
411 }
412 mDynamicSensorsCallback->onDynamicSensorsConnected(sensors);
413 return Return<void>();
414 }
415
onDynamicSensorsDisconnected(const hidl_vec<int32_t> & dynamicSensorHandlesRemoved,int32_t subHalIndex)416 Return<void> HalProxy::onDynamicSensorsDisconnected(
417 const hidl_vec<int32_t>& dynamicSensorHandlesRemoved, int32_t subHalIndex) {
418 // TODO(b/143302327): Block this call until all pending events are flushed from queue
419 std::vector<int32_t> sensorHandles;
420 {
421 std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
422 for (int32_t sensorHandle : dynamicSensorHandlesRemoved) {
423 if (!subHalIndexIsClear(sensorHandle)) {
424 ALOGE("Dynamic sensorHandle removed had first byte not 0.");
425 } else {
426 sensorHandle = setSubHalIndex(sensorHandle, subHalIndex);
427 if (mDynamicSensors.find(sensorHandle) != mDynamicSensors.end()) {
428 mDynamicSensors.erase(sensorHandle);
429 sensorHandles.push_back(sensorHandle);
430 }
431 }
432 }
433 }
434 mDynamicSensorsCallback->onDynamicSensorsDisconnected(sensorHandles);
435 return Return<void>();
436 }
437
initializeSubHalListFromConfigFile(const char * configFileName)438 void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
439 std::ifstream subHalConfigStream(configFileName);
440 if (!subHalConfigStream) {
441 ALOGE("Failed to load subHal config file: %s", configFileName);
442 } else {
443 std::string subHalLibraryFile;
444 while (subHalConfigStream >> subHalLibraryFile) {
445 void* handle = getHandleForSubHalSharedObject(subHalLibraryFile);
446 if (handle == nullptr) {
447 ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str());
448 } else {
449 SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
450 (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
451 if (sensorsHalGetSubHalPtr != nullptr) {
452 std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
453 *sensorsHalGetSubHalPtr;
454 uint32_t version;
455 ISensorsSubHalV2_0* subHal = sensorsHalGetSubHal(&version);
456 if (version != SUB_HAL_2_0_VERSION) {
457 ALOGE("SubHal version was not 2.0 for library: %s",
458 subHalLibraryFile.c_str());
459 } else {
460 ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
461 mSubHalList.push_back(std::make_unique<SubHalWrapperV2_0>(subHal));
462 }
463 } else {
464 SensorsHalGetSubHalV2_1Func* getSubHalV2_1Ptr =
465 (SensorsHalGetSubHalV2_1Func*)dlsym(handle, "sensorsHalGetSubHal_2_1");
466
467 if (getSubHalV2_1Ptr == nullptr) {
468 ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s",
469 subHalLibraryFile.c_str());
470 } else {
471 std::function<SensorsHalGetSubHalV2_1Func> sensorsHalGetSubHal_2_1 =
472 *getSubHalV2_1Ptr;
473 uint32_t version;
474 ISensorsSubHalV2_1* subHal = sensorsHalGetSubHal_2_1(&version);
475 if (version != SUB_HAL_2_1_VERSION) {
476 ALOGE("SubHal version was not 2.1 for library: %s",
477 subHalLibraryFile.c_str());
478 } else {
479 ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
480 mSubHalList.push_back(std::make_unique<SubHalWrapperV2_1>(subHal));
481 }
482 }
483 }
484 }
485 }
486 }
487 }
488
initializeSensorList()489 void HalProxy::initializeSensorList() {
490 for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
491 auto result = mSubHalList[subHalIndex]->getSensorsList([&](const auto& list) {
492 for (SensorInfo sensor : list) {
493 if (!subHalIndexIsClear(sensor.sensorHandle)) {
494 ALOGE("SubHal sensorHandle's first byte was not 0");
495 } else {
496 ALOGV("Loaded sensor: %s", sensor.name.c_str());
497 sensor.sensorHandle = setSubHalIndex(sensor.sensorHandle, subHalIndex);
498 setDirectChannelFlags(&sensor, mSubHalList[subHalIndex]);
499 mSensors[sensor.sensorHandle] = sensor;
500 }
501 }
502 });
503 if (!result.isOk()) {
504 ALOGE("getSensorsList call failed for SubHal: %s",
505 mSubHalList[subHalIndex]->getName().c_str());
506 }
507 }
508 }
509
getHandleForSubHalSharedObject(const std::string & filename)510 void* HalProxy::getHandleForSubHalSharedObject(const std::string& filename) {
511 static const std::string kSubHalShareObjectLocations[] = {
512 "", // Default locations will be searched
513 #ifdef __LP64__
514 "/vendor/lib64/hw/", "/odm/lib64/hw/"
515 #else
516 "/vendor/lib/hw/", "/odm/lib/hw/"
517 #endif
518 };
519
520 for (const std::string& dir : kSubHalShareObjectLocations) {
521 void* handle = dlopen((dir + filename).c_str(), RTLD_NOW);
522 if (handle != nullptr) {
523 return handle;
524 }
525 }
526 return nullptr;
527 }
528
init()529 void HalProxy::init() {
530 initializeSensorList();
531 }
532
stopThreads()533 void HalProxy::stopThreads() {
534 mThreadsRun.store(false);
535 if (mEventQueueFlag != nullptr && mEventQueue != nullptr) {
536 size_t numToRead = mEventQueue->availableToRead();
537 std::vector<Event> events(numToRead);
538 mEventQueue->read(events.data(), numToRead);
539 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::EVENTS_READ));
540 }
541 if (mWakelockQueueFlag != nullptr && mWakeLockQueue != nullptr) {
542 uint32_t kZero = 0;
543 mWakeLockQueue->write(&kZero);
544 mWakelockQueueFlag->wake(static_cast<uint32_t>(WakeLockQueueFlagBits::DATA_WRITTEN));
545 }
546 mWakelockCV.notify_one();
547 mEventQueueWriteCV.notify_one();
548 if (mPendingWritesThread.joinable()) {
549 mPendingWritesThread.join();
550 }
551 if (mWakelockThread.joinable()) {
552 mWakelockThread.join();
553 }
554 }
555
disableAllSensors()556 void HalProxy::disableAllSensors() {
557 for (const auto& sensorEntry : mSensors) {
558 int32_t sensorHandle = sensorEntry.first;
559 activate(sensorHandle, false /* enabled */);
560 }
561 std::lock_guard<std::mutex> dynamicSensorsLock(mDynamicSensorsMutex);
562 for (const auto& sensorEntry : mDynamicSensors) {
563 int32_t sensorHandle = sensorEntry.first;
564 activate(sensorHandle, false /* enabled */);
565 }
566 }
567
startPendingWritesThread(HalProxy * halProxy)568 void HalProxy::startPendingWritesThread(HalProxy* halProxy) {
569 halProxy->handlePendingWrites();
570 }
571
handlePendingWrites()572 void HalProxy::handlePendingWrites() {
573 // TODO(b/143302327): Find a way to optimize locking strategy maybe using two mutexes instead of
574 // one.
575 std::unique_lock<std::mutex> lock(mEventQueueWriteMutex);
576 while (mThreadsRun.load()) {
577 mEventQueueWriteCV.wait(
578 lock, [&] { return !mPendingWriteEventsQueue.empty() || !mThreadsRun.load(); });
579 if (mThreadsRun.load()) {
580 std::vector<Event>& pendingWriteEvents = mPendingWriteEventsQueue.front().first;
581 size_t numWakeupEvents = mPendingWriteEventsQueue.front().second;
582 size_t eventQueueSize = mEventQueue->getQuantumCount();
583 size_t numToWrite = std::min(pendingWriteEvents.size(), eventQueueSize);
584 lock.unlock();
585 if (!mEventQueue->writeBlocking(
586 pendingWriteEvents.data(), numToWrite,
587 static_cast<uint32_t>(EventQueueFlagBits::EVENTS_READ),
588 static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS),
589 kPendingWriteTimeoutNs, mEventQueueFlag)) {
590 ALOGE("Dropping %zu events after blockingWrite failed.", numToWrite);
591 if (numWakeupEvents > 0) {
592 if (pendingWriteEvents.size() > eventQueueSize) {
593 decrementRefCountAndMaybeReleaseWakelock(
594 countNumWakeupEvents(pendingWriteEvents, eventQueueSize));
595 } else {
596 decrementRefCountAndMaybeReleaseWakelock(numWakeupEvents);
597 }
598 }
599 }
600 lock.lock();
601 mSizePendingWriteEventsQueue -= numToWrite;
602 if (pendingWriteEvents.size() > eventQueueSize) {
603 // TODO(b/143302327): Check if this erase operation is too inefficient. It will copy
604 // all the events ahead of it down to fill gap off array at front after the erase.
605 pendingWriteEvents.erase(pendingWriteEvents.begin(),
606 pendingWriteEvents.begin() + eventQueueSize);
607 } else {
608 mPendingWriteEventsQueue.pop();
609 }
610 }
611 }
612 }
613
startWakelockThread(HalProxy * halProxy)614 void HalProxy::startWakelockThread(HalProxy* halProxy) {
615 halProxy->handleWakelocks();
616 }
617
handleWakelocks()618 void HalProxy::handleWakelocks() {
619 std::unique_lock<std::recursive_mutex> lock(mWakelockMutex);
620 while (mThreadsRun.load()) {
621 mWakelockCV.wait(lock, [&] { return mWakelockRefCount > 0 || !mThreadsRun.load(); });
622 if (mThreadsRun.load()) {
623 int64_t timeLeft;
624 if (sharedWakelockDidTimeout(&timeLeft)) {
625 resetSharedWakelock();
626 } else {
627 uint32_t numWakeLocksProcessed;
628 lock.unlock();
629 bool success = mWakeLockQueue->readBlocking(
630 &numWakeLocksProcessed, 1, 0,
631 static_cast<uint32_t>(WakeLockQueueFlagBits::DATA_WRITTEN), timeLeft);
632 lock.lock();
633 if (success) {
634 decrementRefCountAndMaybeReleaseWakelock(
635 static_cast<size_t>(numWakeLocksProcessed));
636 }
637 }
638 }
639 }
640 resetSharedWakelock();
641 }
642
sharedWakelockDidTimeout(int64_t * timeLeft)643 bool HalProxy::sharedWakelockDidTimeout(int64_t* timeLeft) {
644 bool didTimeout;
645 int64_t duration = getTimeNow() - mWakelockTimeoutStartTime;
646 if (duration > kWakelockTimeoutNs) {
647 didTimeout = true;
648 } else {
649 didTimeout = false;
650 *timeLeft = kWakelockTimeoutNs - duration;
651 }
652 return didTimeout;
653 }
654
resetSharedWakelock()655 void HalProxy::resetSharedWakelock() {
656 std::lock_guard<std::recursive_mutex> lockGuard(mWakelockMutex);
657 decrementRefCountAndMaybeReleaseWakelock(mWakelockRefCount);
658 mWakelockTimeoutResetTime = getTimeNow();
659 }
660
postEventsToMessageQueue(const std::vector<Event> & events,size_t numWakeupEvents,V2_0::implementation::ScopedWakelock wakelock)661 void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events, size_t numWakeupEvents,
662 V2_0::implementation::ScopedWakelock wakelock) {
663 size_t numToWrite = 0;
664 std::lock_guard<std::mutex> lock(mEventQueueWriteMutex);
665 if (wakelock.isLocked()) {
666 incrementRefCountAndMaybeAcquireWakelock(numWakeupEvents);
667 }
668 if (mPendingWriteEventsQueue.empty()) {
669 numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
670 if (numToWrite > 0) {
671 if (mEventQueue->write(events.data(), numToWrite)) {
672 // TODO(b/143302327): While loop if mEventQueue->avaiableToWrite > 0 to possibly fit
673 // in more writes immediately
674 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
675 } else {
676 numToWrite = 0;
677 }
678 }
679 }
680 size_t numLeft = events.size() - numToWrite;
681 if (numToWrite < events.size() &&
682 mSizePendingWriteEventsQueue + numLeft <= kMaxSizePendingWriteEventsQueue) {
683 std::vector<Event> eventsLeft(events.begin() + numToWrite, events.end());
684 mPendingWriteEventsQueue.push({eventsLeft, numWakeupEvents});
685 mSizePendingWriteEventsQueue += numLeft;
686 mMostEventsObservedPendingWriteEventsQueue =
687 std::max(mMostEventsObservedPendingWriteEventsQueue, mSizePendingWriteEventsQueue);
688 mEventQueueWriteCV.notify_one();
689 }
690 }
691
incrementRefCountAndMaybeAcquireWakelock(size_t delta,int64_t * timeoutStart)692 bool HalProxy::incrementRefCountAndMaybeAcquireWakelock(size_t delta,
693 int64_t* timeoutStart /* = nullptr */) {
694 if (!mThreadsRun.load()) return false;
695 std::lock_guard<std::recursive_mutex> lockGuard(mWakelockMutex);
696 if (mWakelockRefCount == 0) {
697 acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakelockName);
698 mWakelockCV.notify_one();
699 }
700 mWakelockTimeoutStartTime = getTimeNow();
701 mWakelockRefCount += delta;
702 if (timeoutStart != nullptr) {
703 *timeoutStart = mWakelockTimeoutStartTime;
704 }
705 return true;
706 }
707
decrementRefCountAndMaybeReleaseWakelock(size_t delta,int64_t timeoutStart)708 void HalProxy::decrementRefCountAndMaybeReleaseWakelock(size_t delta,
709 int64_t timeoutStart /* = -1 */) {
710 if (!mThreadsRun.load()) return;
711 std::lock_guard<std::recursive_mutex> lockGuard(mWakelockMutex);
712 if (delta > mWakelockRefCount) {
713 ALOGE("Decrementing wakelock ref count by %zu when count is %zu",
714 delta, mWakelockRefCount);
715 }
716 if (timeoutStart == -1) timeoutStart = mWakelockTimeoutResetTime;
717 if (mWakelockRefCount == 0 || timeoutStart < mWakelockTimeoutResetTime) return;
718 mWakelockRefCount -= std::min(mWakelockRefCount, delta);
719 if (mWakelockRefCount == 0) {
720 release_wake_lock(kWakelockName);
721 }
722 }
723
setDirectChannelFlags(SensorInfo * sensorInfo,std::shared_ptr<ISubHalWrapperBase> subHal)724 void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo,
725 std::shared_ptr<ISubHalWrapperBase> subHal) {
726 bool sensorSupportsDirectChannel =
727 (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
728 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0;
729 if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) {
730 mDirectChannelSubHal = subHal;
731 } else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) {
732 // disable direct channel capability for sensors in subHals that are not
733 // the only one we will enable
734 sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
735 V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
736 }
737 }
738
getSubHalForSensorHandle(int32_t sensorHandle)739 std::shared_ptr<ISubHalWrapperBase> HalProxy::getSubHalForSensorHandle(int32_t sensorHandle) {
740 return mSubHalList[extractSubHalIndex(sensorHandle)];
741 }
742
isSubHalIndexValid(int32_t sensorHandle)743 bool HalProxy::isSubHalIndexValid(int32_t sensorHandle) {
744 return extractSubHalIndex(sensorHandle) < mSubHalList.size();
745 }
746
countNumWakeupEvents(const std::vector<Event> & events,size_t n)747 size_t HalProxy::countNumWakeupEvents(const std::vector<Event>& events, size_t n) {
748 size_t numWakeupEvents = 0;
749 for (size_t i = 0; i < n; i++) {
750 int32_t sensorHandle = events[i].sensorHandle;
751 if (mSensors[sensorHandle].flags & static_cast<uint32_t>(V1_0::SensorFlagBits::WAKE_UP)) {
752 numWakeupEvents++;
753 }
754 }
755 return numWakeupEvents;
756 }
757
clearSubHalIndex(int32_t sensorHandle)758 int32_t HalProxy::clearSubHalIndex(int32_t sensorHandle) {
759 return sensorHandle & (~kSensorHandleSubHalIndexMask);
760 }
761
subHalIndexIsClear(int32_t sensorHandle)762 bool HalProxy::subHalIndexIsClear(int32_t sensorHandle) {
763 return (sensorHandle & kSensorHandleSubHalIndexMask) == 0;
764 }
765
766 } // namespace implementation
767 } // namespace V2_1
768 } // namespace sensors
769 } // namespace hardware
770 } // namespace android
771