1 /* 2 * Copyright (C) 2021 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 #pragma once 18 19 #include <aidl/android/hardware/common/fmq/SynchronizedReadWrite.h> 20 #include <aidl/android/hardware/sensors/BnSensors.h> 21 #include <fmq/AidlMessageQueue.h> 22 #include <hardware_legacy/power.h> 23 #include <map> 24 #include "Sensor.h" 25 26 namespace aidl { 27 namespace android { 28 namespace hardware { 29 namespace sensors { 30 31 using aidl::android::hardware::common::fmq::SynchronizedReadWrite; 32 using ::android::AidlMessageQueue; 33 using ::android::OK; 34 using ::android::status_t; 35 using ::android::hardware::EventFlag; 36 37 class Sensors : public BnSensors, public ISensorsEventCallback { 38 static constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP"; 39 40 public: Sensors()41 Sensors() 42 : mEventQueueFlag(nullptr), 43 mNextHandle(1), 44 mOutstandingWakeUpEvents(0), 45 mReadWakeLockQueueRun(false), 46 mAutoReleaseWakeLockTime(0), 47 mHasWakeLock(false) { 48 AddSensor<AccelSensor>(); 49 AddSensor<GyroSensor>(); 50 AddSensor<AmbientTempSensor>(); 51 AddSensor<PressureSensor>(); 52 AddSensor<MagnetometerSensor>(); 53 AddSensor<LightSensor>(); 54 AddSensor<ProximitySensor>(); 55 AddSensor<RelativeHumiditySensor>(); 56 AddSensor<HingeAngleSensor>(); 57 } 58 ~Sensors()59 virtual ~Sensors() { 60 deleteEventFlag(); 61 mReadWakeLockQueueRun = false; 62 mWakeLockThread.join(); 63 } 64 65 ::ndk::ScopedAStatus activate(int32_t in_sensorHandle, bool in_enabled) override; 66 ::ndk::ScopedAStatus batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs, 67 int64_t in_maxReportLatencyNs) override; 68 ::ndk::ScopedAStatus configDirectReport( 69 int32_t in_sensorHandle, int32_t in_channelHandle, 70 ::aidl::android::hardware::sensors::ISensors::RateLevel in_rate, 71 int32_t* _aidl_return) override; 72 ::ndk::ScopedAStatus flush(int32_t in_sensorHandle) override; 73 ::ndk::ScopedAStatus getSensorsList( 74 std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) override; 75 ::ndk::ScopedAStatus initialize( 76 const ::aidl::android::hardware::common::fmq::MQDescriptor< 77 ::aidl::android::hardware::sensors::Event, 78 ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& 79 in_eventQueueDescriptor, 80 const ::aidl::android::hardware::common::fmq::MQDescriptor< 81 int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& 82 in_wakeLockDescriptor, 83 const std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback>& 84 in_sensorsCallback) override; 85 ::ndk::ScopedAStatus injectSensorData( 86 const ::aidl::android::hardware::sensors::Event& in_event) override; 87 ::ndk::ScopedAStatus registerDirectChannel( 88 const ::aidl::android::hardware::sensors::ISensors::SharedMemInfo& in_mem, 89 int32_t* _aidl_return) override; 90 ::ndk::ScopedAStatus setOperationMode( 91 ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) override; 92 ::ndk::ScopedAStatus unregisterDirectChannel(int32_t in_channelHandle) override; 93 postEvents(const std::vector<Event> & events,bool wakeup)94 void postEvents(const std::vector<Event>& events, bool wakeup) override { 95 std::lock_guard<std::mutex> lock(mWriteLock); 96 if (mEventQueue == nullptr) { 97 return; 98 } 99 if (mEventQueue->write(&events.front(), events.size())) { 100 mEventQueueFlag->wake( 101 static_cast<uint32_t>(BnSensors::EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS)); 102 103 if (wakeup) { 104 // Keep track of the number of outstanding WAKE_UP events in order to properly hold 105 // a wake lock until the framework has secured a wake lock 106 updateWakeLock(events.size(), 0 /* eventsHandled */); 107 } 108 } 109 } 110 111 protected: 112 // Add a new sensor 113 template <class SensorType> AddSensor()114 void AddSensor() { 115 std::shared_ptr<SensorType> sensor = 116 std::make_shared<SensorType>(mNextHandle++ /* sensorHandle */, this /* callback */); 117 mSensors[sensor->getSensorInfo().sensorHandle] = sensor; 118 } 119 120 // Utility function to delete the Event Flag deleteEventFlag()121 void deleteEventFlag() { 122 if (mEventQueueFlag != nullptr) { 123 status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag); 124 if (status != OK) { 125 ALOGI("Failed to delete event flag: %d", status); 126 } 127 } 128 } 129 startReadWakeLockThread(Sensors * sensors)130 static void startReadWakeLockThread(Sensors* sensors) { sensors->readWakeLockFMQ(); } 131 132 // Function to read the Wake Lock FMQ and release the wake lock when appropriate readWakeLockFMQ()133 void readWakeLockFMQ() { 134 while (mReadWakeLockQueueRun.load()) { 135 constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000; // 500 ms 136 int32_t eventsHandled = 0; 137 138 // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to 139 // ensure that any held wake lock is able to be released if it is held for too long. 140 mWakeLockQueue->readBlocking( 141 &eventsHandled, 1 /* count */, 0 /* readNotification */, 142 static_cast<uint32_t>(WAKE_LOCK_QUEUE_FLAG_BITS_DATA_WRITTEN), kReadTimeoutNs); 143 updateWakeLock(0 /* eventsWritten */, eventsHandled); 144 } 145 } 146 147 /** 148 * Responsible for acquiring and releasing a wake lock when there are unhandled WAKE_UP events 149 */ updateWakeLock(int32_t eventsWritten,int32_t eventsHandled)150 void updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) { 151 std::lock_guard<std::mutex> lock(mWakeLockLock); 152 int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled; 153 if (newVal < 0) { 154 mOutstandingWakeUpEvents = 0; 155 } else { 156 mOutstandingWakeUpEvents = newVal; 157 } 158 159 if (eventsWritten > 0) { 160 // Update the time at which the last WAKE_UP event was sent 161 mAutoReleaseWakeLockTime = ::android::uptimeMillis() + 162 static_cast<uint32_t>(WAKE_LOCK_TIMEOUT_SECONDS) * 1000; 163 } 164 165 if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 && 166 acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) { 167 mHasWakeLock = true; 168 } else if (mHasWakeLock) { 169 // Check if the wake lock should be released automatically if 170 // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written 171 // to the Wake Lock FMQ. 172 if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) { 173 ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock", 174 WAKE_LOCK_TIMEOUT_SECONDS); 175 mOutstandingWakeUpEvents = 0; 176 } 177 178 if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) { 179 mHasWakeLock = false; 180 } 181 } 182 } 183 184 private: 185 // The Event FMQ where sensor events are written 186 std::unique_ptr<AidlMessageQueue<Event, SynchronizedReadWrite>> mEventQueue; 187 // The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events 188 std::unique_ptr<AidlMessageQueue<int32_t, SynchronizedReadWrite>> mWakeLockQueue; 189 // Event Flag to signal to the framework when sensor events are available to be read 190 EventFlag* mEventQueueFlag; 191 // Callback for asynchronous events, such as dynamic sensor connections. 192 std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> mCallback; 193 // A map of the available sensors. 194 std::map<int32_t, std::shared_ptr<Sensor>> mSensors; 195 // The next available sensor handle. 196 int32_t mNextHandle; 197 // Lock to protect writes to the FMQs. 198 std::mutex mWriteLock; 199 // Lock to protect acquiring and releasing the wake lock 200 std::mutex mWakeLockLock; 201 // Track the number of WAKE_UP events that have not been handled by the framework 202 uint32_t mOutstandingWakeUpEvents; 203 // A thread to read the Wake Lock FMQ 204 std::thread mWakeLockThread; 205 // Flag to indicate that the Wake Lock Thread should continue to run 206 std::atomic_bool mReadWakeLockQueueRun; 207 // Track the time when the wake lock should automatically be released 208 int64_t mAutoReleaseWakeLockTime; 209 // Flag to indicate if a wake lock has been acquired 210 bool mHasWakeLock; 211 }; 212 213 } // namespace sensors 214 } // namespace hardware 215 } // namespace android 216 } // namespace aidl 217