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 #ifndef ANDROID_HARDWARE_SENSORS_V2_X_SENSORS_H 18 #define ANDROID_HARDWARE_SENSORS_V2_X_SENSORS_H 19 20 #include "EventMessageQueueWrapper.h" 21 #include "Sensor.h" 22 23 #include <android/hardware/sensors/2.0/ISensors.h> 24 #include <android/hardware/sensors/2.0/types.h> 25 #include <fmq/MessageQueue.h> 26 #include <hardware_legacy/power.h> 27 #include <hidl/MQDescriptor.h> 28 #include <hidl/Status.h> 29 #include <log/log.h> 30 31 #include <atomic> 32 #include <memory> 33 #include <thread> 34 35 namespace android { 36 namespace hardware { 37 namespace sensors { 38 namespace V2_X { 39 namespace implementation { 40 41 template <class ISensorsInterface> 42 struct Sensors : public ISensorsInterface, public ISensorsEventCallback { 43 using Event = ::android::hardware::sensors::V1_0::Event; 44 using OperationMode = ::android::hardware::sensors::V1_0::OperationMode; 45 using RateLevel = ::android::hardware::sensors::V1_0::RateLevel; 46 using Result = ::android::hardware::sensors::V1_0::Result; 47 using SharedMemInfo = ::android::hardware::sensors::V1_0::SharedMemInfo; 48 using EventQueueFlagBits = ::android::hardware::sensors::V2_0::EventQueueFlagBits; 49 using SensorTimeout = ::android::hardware::sensors::V2_0::SensorTimeout; 50 using WakeLockQueueFlagBits = ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; 51 using ISensorsCallback = ::android::hardware::sensors::V2_0::ISensorsCallback; 52 using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>; 53 using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>; 54 55 static constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP"; 56 SensorsSensors57 Sensors() 58 : mEventQueueFlag(nullptr), 59 mNextHandle(1), 60 mOutstandingWakeUpEvents(0), 61 mReadWakeLockQueueRun(false), 62 mAutoReleaseWakeLockTime(0), 63 mHasWakeLock(false) { 64 AddSensor<AccelSensor>(); 65 AddSensor<GyroSensor>(); 66 AddSensor<AmbientTempSensor>(); 67 AddSensor<PressureSensor>(); 68 AddSensor<MagnetometerSensor>(); 69 AddSensor<LightSensor>(); 70 AddSensor<ProximitySensor>(); 71 AddSensor<RelativeHumiditySensor>(); 72 } 73 ~SensorsSensors74 virtual ~Sensors() { 75 deleteEventFlag(); 76 mReadWakeLockQueueRun = false; 77 mWakeLockThread.join(); 78 } 79 80 // Methods from ::android::hardware::sensors::V2_0::ISensors follow. setOperationModeSensors81 Return<Result> setOperationMode(OperationMode mode) override { 82 for (auto sensor : mSensors) { 83 sensor.second->setOperationMode(mode); 84 } 85 return Result::OK; 86 } 87 activateSensors88 Return<Result> activate(int32_t sensorHandle, bool enabled) override { 89 auto sensor = mSensors.find(sensorHandle); 90 if (sensor != mSensors.end()) { 91 sensor->second->activate(enabled); 92 return Result::OK; 93 } 94 return Result::BAD_VALUE; 95 } 96 initializeSensors97 Return<Result> initialize( 98 const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor, 99 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, 100 const sp<ISensorsCallback>& sensorsCallback) override { 101 auto eventQueue = 102 std::make_unique<EventMessageQueue>(eventQueueDescriptor, true /* resetPointers */); 103 std::unique_ptr<V2_1::implementation::EventMessageQueueWrapperBase> wrapper = 104 std::make_unique<V2_1::implementation::EventMessageQueueWrapperV1_0>(eventQueue); 105 return initializeBase(wrapper, wakeLockDescriptor, sensorsCallback); 106 } 107 initializeBaseSensors108 Return<Result> initializeBase( 109 std::unique_ptr<V2_1::implementation::EventMessageQueueWrapperBase>& eventQueue, 110 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, 111 const sp<ISensorsCallback>& sensorsCallback) { 112 Result result = Result::OK; 113 114 // Ensure that all sensors are disabled 115 for (auto sensor : mSensors) { 116 sensor.second->activate(false /* enable */); 117 } 118 119 // Stop the Wake Lock thread if it is currently running 120 if (mReadWakeLockQueueRun.load()) { 121 mReadWakeLockQueueRun = false; 122 mWakeLockThread.join(); 123 } 124 125 // Save a reference to the callback 126 mCallback = sensorsCallback; 127 128 // Save the event queue. 129 mEventQueue = std::move(eventQueue); 130 131 // Ensure that any existing EventFlag is properly deleted 132 deleteEventFlag(); 133 134 // Create the EventFlag that is used to signal to the framework that sensor events have been 135 // written to the Event FMQ 136 if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) { 137 result = Result::BAD_VALUE; 138 } 139 140 // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP 141 // events have been successfully read and handled by the framework. 142 mWakeLockQueue = std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, 143 true /* resetPointers */); 144 145 if (!mCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) { 146 result = Result::BAD_VALUE; 147 } 148 149 // Start the thread to read events from the Wake Lock FMQ 150 mReadWakeLockQueueRun = true; 151 mWakeLockThread = std::thread(startReadWakeLockThread, this); 152 153 return result; 154 } 155 batchSensors156 Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs, 157 int64_t /* maxReportLatencyNs */) override { 158 auto sensor = mSensors.find(sensorHandle); 159 if (sensor != mSensors.end()) { 160 sensor->second->batch(samplingPeriodNs); 161 return Result::OK; 162 } 163 return Result::BAD_VALUE; 164 } 165 flushSensors166 Return<Result> flush(int32_t sensorHandle) override { 167 auto sensor = mSensors.find(sensorHandle); 168 if (sensor != mSensors.end()) { 169 return sensor->second->flush(); 170 } 171 return Result::BAD_VALUE; 172 } 173 injectSensorDataSensors174 Return<Result> injectSensorData(const Event& event) override { 175 auto sensor = mSensors.find(event.sensorHandle); 176 if (sensor != mSensors.end()) { 177 return sensor->second->injectEvent(V2_1::implementation::convertToNewEvent(event)); 178 } 179 180 return Result::BAD_VALUE; 181 } 182 registerDirectChannelSensors183 Return<void> registerDirectChannel(const SharedMemInfo& /* mem */, 184 V2_0::ISensors::registerDirectChannel_cb _hidl_cb) override { 185 _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); 186 return Return<void>(); 187 } 188 unregisterDirectChannelSensors189 Return<Result> unregisterDirectChannel(int32_t /* channelHandle */) override { 190 return Result::INVALID_OPERATION; 191 } 192 configDirectReportSensors193 Return<void> configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */, 194 RateLevel /* rate */, 195 V2_0::ISensors::configDirectReport_cb _hidl_cb) override { 196 _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */); 197 return Return<void>(); 198 } 199 postEventsSensors200 void postEvents(const std::vector<V2_1::Event>& events, bool wakeup) override { 201 std::lock_guard<std::mutex> lock(mWriteLock); 202 if (mEventQueue->write(events)) { 203 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS)); 204 205 if (wakeup) { 206 // Keep track of the number of outstanding WAKE_UP events in order to properly hold 207 // a wake lock until the framework has secured a wake lock 208 updateWakeLock(events.size(), 0 /* eventsHandled */); 209 } 210 } 211 } 212 213 protected: 214 /** 215 * Add a new sensor 216 */ 217 template <class SensorType> AddSensorSensors218 void AddSensor() { 219 std::shared_ptr<SensorType> sensor = 220 std::make_shared<SensorType>(mNextHandle++ /* sensorHandle */, this /* callback */); 221 mSensors[sensor->getSensorInfo().sensorHandle] = sensor; 222 } 223 224 /** 225 * Utility function to delete the Event Flag 226 */ deleteEventFlagSensors227 void deleteEventFlag() { 228 status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag); 229 if (status != OK) { 230 ALOGI("Failed to delete event flag: %d", status); 231 } 232 } 233 startReadWakeLockThreadSensors234 static void startReadWakeLockThread(Sensors* sensors) { sensors->readWakeLockFMQ(); } 235 236 /** 237 * Function to read the Wake Lock FMQ and release the wake lock when appropriate 238 */ readWakeLockFMQSensors239 void readWakeLockFMQ() { 240 while (mReadWakeLockQueueRun.load()) { 241 constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000; // 500 ms 242 uint32_t eventsHandled = 0; 243 244 // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to 245 // ensure that any held wake lock is able to be released if it is held for too long. 246 mWakeLockQueue->readBlocking(&eventsHandled, 1 /* count */, 0 /* readNotification */, 247 static_cast<uint32_t>(WakeLockQueueFlagBits::DATA_WRITTEN), 248 kReadTimeoutNs); 249 updateWakeLock(0 /* eventsWritten */, eventsHandled); 250 } 251 } 252 253 /** 254 * Responsible for acquiring and releasing a wake lock when there are unhandled WAKE_UP events 255 */ updateWakeLockSensors256 void updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) { 257 std::lock_guard<std::mutex> lock(mWakeLockLock); 258 int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled; 259 if (newVal < 0) { 260 mOutstandingWakeUpEvents = 0; 261 } else { 262 mOutstandingWakeUpEvents = newVal; 263 } 264 265 if (eventsWritten > 0) { 266 // Update the time at which the last WAKE_UP event was sent 267 mAutoReleaseWakeLockTime = 268 ::android::uptimeMillis() + 269 static_cast<uint32_t>(SensorTimeout::WAKE_LOCK_SECONDS) * 1000; 270 } 271 272 if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 && 273 acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) { 274 mHasWakeLock = true; 275 } else if (mHasWakeLock) { 276 // Check if the wake lock should be released automatically if 277 // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written 278 // to the Wake Lock FMQ. 279 if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) { 280 ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock", 281 SensorTimeout::WAKE_LOCK_SECONDS); 282 mOutstandingWakeUpEvents = 0; 283 } 284 285 if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) { 286 mHasWakeLock = false; 287 } 288 } 289 } 290 291 /** 292 * The Event FMQ where sensor events are written 293 */ 294 std::unique_ptr<V2_1::implementation::EventMessageQueueWrapperBase> mEventQueue; 295 296 /** 297 * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events 298 */ 299 std::unique_ptr<WakeLockMessageQueue> mWakeLockQueue; 300 301 /** 302 * Event Flag to signal to the framework when sensor events are available to be read 303 */ 304 EventFlag* mEventQueueFlag; 305 306 /** 307 * Callback for asynchronous events, such as dynamic sensor connections. 308 */ 309 sp<ISensorsCallback> mCallback; 310 311 /** 312 * A map of the available sensors 313 */ 314 std::map<int32_t, std::shared_ptr<Sensor>> mSensors; 315 316 /** 317 * The next available sensor handle 318 */ 319 int32_t mNextHandle; 320 321 /** 322 * Lock to protect writes to the FMQs 323 */ 324 std::mutex mWriteLock; 325 326 /** 327 * Lock to protect acquiring and releasing the wake lock 328 */ 329 std::mutex mWakeLockLock; 330 331 /** 332 * Track the number of WAKE_UP events that have not been handled by the framework 333 */ 334 uint32_t mOutstandingWakeUpEvents; 335 336 /** 337 * A thread to read the Wake Lock FMQ 338 */ 339 std::thread mWakeLockThread; 340 341 /** 342 * Flag to indicate that the Wake Lock Thread should continue to run 343 */ 344 std::atomic_bool mReadWakeLockQueueRun; 345 346 /** 347 * Track the time when the wake lock should automatically be released 348 */ 349 int64_t mAutoReleaseWakeLockTime; 350 351 /** 352 * Flag to indicate if a wake lock has been acquired 353 */ 354 bool mHasWakeLock; 355 }; 356 357 } // namespace implementation 358 } // namespace V2_X 359 } // namespace sensors 360 } // namespace hardware 361 } // namespace android 362 363 #endif // ANDROID_HARDWARE_SENSORS_V2_X_SENSORS_H 364