1 /* 2 * Copyright (C) 2018 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 "SensorsHidlEnvironmentV2_0.h" 18 19 #include <android/hardware/sensors/2.0/types.h> 20 #include <log/log.h> 21 22 #include <algorithm> 23 #include <vector> 24 25 using ::android::hardware::EventFlag; 26 using ::android::hardware::hidl_vec; 27 using ::android::hardware::Return; 28 using ::android::hardware::sensors::V1_0::Result; 29 using ::android::hardware::sensors::V1_0::SensorInfo; 30 using ::android::hardware::sensors::V2_0::EventQueueFlagBits; 31 using ::android::hardware::sensors::V2_0::ISensors; 32 using ::android::hardware::sensors::V2_0::ISensorsCallback; 33 34 template <typename EnumType> 35 constexpr typename std::underlying_type<EnumType>::type asBaseType(EnumType value) { 36 return static_cast<typename std::underlying_type<EnumType>::type>(value); 37 } 38 39 constexpr size_t SensorsHidlEnvironmentV2_0::MAX_RECEIVE_BUFFER_EVENT_COUNT; 40 41 struct SensorsCallback : ISensorsCallback { 42 Return<void> onDynamicSensorsConnected(const hidl_vec<SensorInfo>& /* sensorInfos */) { 43 return Return<void>(); 44 } 45 46 Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& /* sensorHandles */) { 47 return Return<void>(); 48 } 49 }; 50 51 bool SensorsHidlEnvironmentV2_0::resetHal() { 52 bool succeed = false; 53 do { 54 mSensors = ISensors::getService( 55 SensorsHidlEnvironmentV2_0::Instance()->getServiceName<ISensors>()); 56 if (mSensors == nullptr) { 57 break; 58 } 59 60 // Initialize FMQs 61 mEventQueue = std::make_unique<EventMessageQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT, 62 true /* configureEventFlagWord */); 63 64 mWakeLockQueue = std::make_unique<WakeLockQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT, 65 true /* configureEventFlagWord */); 66 67 if (mEventQueue == nullptr || mWakeLockQueue == nullptr) { 68 break; 69 } 70 71 EventFlag::deleteEventFlag(&mEventQueueFlag); 72 EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag); 73 if (mEventQueueFlag == nullptr) { 74 break; 75 } 76 77 mSensors->initialize(*mEventQueue->getDesc(), *mWakeLockQueue->getDesc(), 78 new SensorsCallback()); 79 80 std::vector<SensorInfo> sensorList; 81 if (!mSensors->getSensorsList([&](const hidl_vec<SensorInfo>& list) { sensorList = list; }) 82 .isOk()) { 83 break; 84 } 85 86 // stop each sensor individually 87 bool ok = true; 88 for (const auto& i : sensorList) { 89 if (!mSensors->activate(i.sensorHandle, false).isOk()) { 90 ok = false; 91 break; 92 } 93 } 94 if (!ok) { 95 break; 96 } 97 98 // mark it done 99 succeed = true; 100 } while (0); 101 102 if (!succeed) { 103 mSensors = nullptr; 104 } 105 106 return succeed; 107 } 108 109 void SensorsHidlEnvironmentV2_0::HidlTearDown() { 110 mStopThread = true; 111 112 if (mEventQueueFlag != nullptr) { 113 // Wake up the event queue so the poll thread can exit 114 mEventQueueFlag->wake(asBaseType(EventQueueFlagBits::READ_AND_PROCESS)); 115 if (mPollThread.joinable()) { 116 mPollThread.join(); 117 } 118 119 EventFlag::deleteEventFlag(&mEventQueueFlag); 120 } 121 } 122 123 void SensorsHidlEnvironmentV2_0::startPollingThread() { 124 mStopThread = false; 125 mPollThread = std::thread(pollingThread, this); 126 mEvents.reserve(MAX_RECEIVE_BUFFER_EVENT_COUNT); 127 } 128 129 void SensorsHidlEnvironmentV2_0::readEvents() { 130 size_t availableEvents = mEventQueue->availableToRead(); 131 132 if (availableEvents == 0) { 133 uint32_t eventFlagState = 0; 134 135 mEventQueueFlag->wait(asBaseType(EventQueueFlagBits::READ_AND_PROCESS), &eventFlagState); 136 availableEvents = mEventQueue->availableToRead(); 137 } 138 139 size_t eventsToRead = std::min(availableEvents, mEventBuffer.size()); 140 if (eventsToRead > 0) { 141 if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) { 142 mEventQueueFlag->wake(asBaseType(EventQueueFlagBits::EVENTS_READ)); 143 for (size_t i = 0; i < eventsToRead; i++) { 144 addEvent(mEventBuffer[i]); 145 } 146 } 147 } 148 } 149 150 void SensorsHidlEnvironmentV2_0::pollingThread(SensorsHidlEnvironmentV2_0* env) { 151 ALOGD("polling thread start"); 152 153 while (!env->mStopThread.load()) { 154 env->readEvents(); 155 } 156 157 ALOGD("polling thread end"); 158 } 159