• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Sensors()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 
~Sensors()56 Sensors::~Sensors() {
57     deleteEventFlag();
58     mReadWakeLockQueueRun = false;
59     mWakeLockThread.join();
60 }
61 
62 // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
getSensorsList(getSensorsList_cb _hidl_cb)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 
setOperationMode(OperationMode mode)75 Return<Result> Sensors::setOperationMode(OperationMode mode) {
76     for (auto sensor : mSensors) {
77         sensor.second->setOperationMode(mode);
78     }
79     return Result::OK;
80 }
81 
activate(int32_t sensorHandle,bool enabled)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 
initialize(const::android::hardware::MQDescriptorSync<Event> & eventQueueDescriptor,const::android::hardware::MQDescriptorSync<uint32_t> & wakeLockDescriptor,const sp<ISensorsCallback> & sensorsCallback)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 
batch(int32_t sensorHandle,int64_t samplingPeriodNs,int64_t)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 
flush(int32_t sensorHandle)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 
injectSensorData(const Event & event)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 
registerDirectChannel(const SharedMemInfo &,registerDirectChannel_cb _hidl_cb)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 
unregisterDirectChannel(int32_t)173 Return<Result> Sensors::unregisterDirectChannel(int32_t /* channelHandle */) {
174     return Result::INVALID_OPERATION;
175 }
176 
configDirectReport(int32_t,int32_t,RateLevel,configDirectReport_cb _hidl_cb)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 
postEvents(const std::vector<Event> & events,bool wakeup)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 
updateWakeLock(int32_t eventsWritten,int32_t eventsHandled)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 
readWakeLockFMQ()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 
startReadWakeLockThread(Sensors * sensors)244 void Sensors::startReadWakeLockThread(Sensors* sensors) {
245     sensors->readWakeLockFMQ();
246 }
247 
deleteEventFlag()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