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