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 "Sensors.h" 18 19 #include <android/hardware/sensors/2.0/types.h> 20 #include <log/log.h> 21 22 namespace android { 23 namespace hardware { 24 namespace sensors { 25 namespace V2_0 { 26 namespace implementation { 27 28 using ::android::hardware::sensors::V1_0::Event; 29 using ::android::hardware::sensors::V1_0::OperationMode; 30 using ::android::hardware::sensors::V1_0::RateLevel; 31 using ::android::hardware::sensors::V1_0::Result; 32 using ::android::hardware::sensors::V1_0::SharedMemInfo; 33 using ::android::hardware::sensors::V2_0::SensorTimeout; 34 using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; 35 36 constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP"; 37 38 Sensors::Sensors() 39 : mEventQueueFlag(nullptr), 40 mNextHandle(1), 41 mOutstandingWakeUpEvents(0), 42 mReadWakeLockQueueRun(false), 43 mAutoReleaseWakeLockTime(0), 44 mHasWakeLock(false) { 45 AddSensor<AccelSensor>(); 46 AddSensor<GyroSensor>(); 47 AddSensor<AmbientTempSensor>(); 48 AddSensor<DeviceTempSensor>(); 49 AddSensor<PressureSensor>(); 50 AddSensor<MagnetometerSensor>(); 51 AddSensor<LightSensor>(); 52 AddSensor<ProximitySensor>(); 53 AddSensor<RelativeHumiditySensor>(); 54 } 55 56 Sensors::~Sensors() { 57 deleteEventFlag(); 58 mReadWakeLockQueueRun = false; 59 mWakeLockThread.join(); 60 } 61 62 // Methods from ::android::hardware::sensors::V2_0::ISensors follow. 63 Return<void> Sensors::getSensorsList(getSensorsList_cb _hidl_cb) { 64 std::vector<SensorInfo> sensors; 65 for (const auto& sensor : mSensors) { 66 sensors.push_back(sensor.second->getSensorInfo()); 67 } 68 69 // Call the HIDL callback with the SensorInfo 70 _hidl_cb(sensors); 71 72 return Void(); 73 } 74 75 Return<Result> Sensors::setOperationMode(OperationMode mode) { 76 for (auto sensor : mSensors) { 77 sensor.second->setOperationMode(mode); 78 } 79 return Result::OK; 80 } 81 82 Return<Result> Sensors::activate(int32_t sensorHandle, bool enabled) { 83 auto sensor = mSensors.find(sensorHandle); 84 if (sensor != mSensors.end()) { 85 sensor->second->activate(enabled); 86 return Result::OK; 87 } 88 return Result::BAD_VALUE; 89 } 90 91 Return<Result> Sensors::initialize( 92 const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor, 93 const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor, 94 const sp<ISensorsCallback>& sensorsCallback) { 95 Result result = Result::OK; 96 97 // Ensure that all sensors are disabled 98 for (auto sensor : mSensors) { 99 sensor.second->activate(false /* enable */); 100 } 101 102 // Stop the Wake Lock thread if it is currently running 103 if (mReadWakeLockQueueRun.load()) { 104 mReadWakeLockQueueRun = false; 105 mWakeLockThread.join(); 106 } 107 108 // Save a reference to the callback 109 mCallback = sensorsCallback; 110 111 // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions. 112 mEventQueue = 113 std::make_unique<EventMessageQueue>(eventQueueDescriptor, true /* resetPointers */); 114 115 // Ensure that any existing EventFlag is properly deleted 116 deleteEventFlag(); 117 118 // Create the EventFlag that is used to signal to the framework that sensor events have been 119 // written to the Event FMQ 120 if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) { 121 result = Result::BAD_VALUE; 122 } 123 124 // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP 125 // events have been successfully read and handled by the framework. 126 mWakeLockQueue = 127 std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */); 128 129 if (!mCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) { 130 result = Result::BAD_VALUE; 131 } 132 133 // Start the thread to read events from the Wake Lock FMQ 134 mReadWakeLockQueueRun = true; 135 mWakeLockThread = std::thread(startReadWakeLockThread, this); 136 137 return result; 138 } 139 140 Return<Result> Sensors::batch(int32_t sensorHandle, int64_t samplingPeriodNs, 141 int64_t /* maxReportLatencyNs */) { 142 auto sensor = mSensors.find(sensorHandle); 143 if (sensor != mSensors.end()) { 144 sensor->second->batch(samplingPeriodNs); 145 return Result::OK; 146 } 147 return Result::BAD_VALUE; 148 } 149 150 Return<Result> Sensors::flush(int32_t sensorHandle) { 151 auto sensor = mSensors.find(sensorHandle); 152 if (sensor != mSensors.end()) { 153 return sensor->second->flush(); 154 } 155 return Result::BAD_VALUE; 156 } 157 158 Return<Result> Sensors::injectSensorData(const Event& event) { 159 auto sensor = mSensors.find(event.sensorHandle); 160 if (sensor != mSensors.end()) { 161 return sensor->second->injectEvent(event); 162 } 163 164 return Result::BAD_VALUE; 165 } 166 167 Return<void> Sensors::registerDirectChannel(const SharedMemInfo& /* mem */, 168 registerDirectChannel_cb _hidl_cb) { 169 _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); 170 return Return<void>(); 171 } 172 173 Return<Result> Sensors::unregisterDirectChannel(int32_t /* channelHandle */) { 174 return Result::INVALID_OPERATION; 175 } 176 177 Return<void> Sensors::configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */, 178 RateLevel /* rate */, configDirectReport_cb _hidl_cb) { 179 _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */); 180 return Return<void>(); 181 } 182 183 void Sensors::postEvents(const std::vector<Event>& events, bool wakeup) { 184 std::lock_guard<std::mutex> lock(mWriteLock); 185 if (mEventQueue->write(events.data(), events.size())) { 186 mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS)); 187 188 if (wakeup) { 189 // Keep track of the number of outstanding WAKE_UP events in order to properly hold 190 // a wake lock until the framework has secured a wake lock 191 updateWakeLock(events.size(), 0 /* eventsHandled */); 192 } 193 } 194 } 195 196 void Sensors::updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) { 197 std::lock_guard<std::mutex> lock(mWakeLockLock); 198 int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled; 199 if (newVal < 0) { 200 mOutstandingWakeUpEvents = 0; 201 } else { 202 mOutstandingWakeUpEvents = newVal; 203 } 204 205 if (eventsWritten > 0) { 206 // Update the time at which the last WAKE_UP event was sent 207 mAutoReleaseWakeLockTime = ::android::uptimeMillis() + 208 static_cast<uint32_t>(SensorTimeout::WAKE_LOCK_SECONDS) * 1000; 209 } 210 211 if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 && 212 acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) { 213 mHasWakeLock = true; 214 } else if (mHasWakeLock) { 215 // Check if the wake lock should be released automatically if 216 // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written to 217 // the Wake Lock FMQ. 218 if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) { 219 ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock", 220 SensorTimeout::WAKE_LOCK_SECONDS); 221 mOutstandingWakeUpEvents = 0; 222 } 223 224 if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) { 225 mHasWakeLock = false; 226 } 227 } 228 } 229 230 void Sensors::readWakeLockFMQ() { 231 while (mReadWakeLockQueueRun.load()) { 232 constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000; // 500 ms 233 uint32_t eventsHandled = 0; 234 235 // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to ensure 236 // that any held wake lock is able to be released if it is held for too long. 237 mWakeLockQueue->readBlocking(&eventsHandled, 1 /* count */, 0 /* readNotification */, 238 static_cast<uint32_t>(WakeLockQueueFlagBits::DATA_WRITTEN), 239 kReadTimeoutNs); 240 updateWakeLock(0 /* eventsWritten */, eventsHandled); 241 } 242 } 243 244 void Sensors::startReadWakeLockThread(Sensors* sensors) { 245 sensors->readWakeLockFMQ(); 246 } 247 248 void Sensors::deleteEventFlag() { 249 status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag); 250 if (status != OK) { 251 ALOGI("Failed to delete event flag: %d", status); 252 } 253 } 254 255 } // namespace implementation 256 } // namespace V2_0 257 } // namespace sensors 258 } // namespace hardware 259 } // namespace android 260