1 /*
2  * Copyright (C) 2019 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 "Sensor.h"
18 
19 #include <hardware/sensors.h>
20 #include <utils/SystemClock.h>
21 
22 #include <cmath>
23 
24 namespace android {
25 namespace hardware {
26 namespace sensors {
27 namespace V2_1 {
28 namespace subhal {
29 namespace implementation {
30 
31 using ::android::hardware::sensors::V1_0::MetaDataEventType;
32 using ::android::hardware::sensors::V1_0::OperationMode;
33 using ::android::hardware::sensors::V1_0::Result;
34 using ::android::hardware::sensors::V1_0::SensorFlagBits;
35 using ::android::hardware::sensors::V1_0::SensorStatus;
36 using ::android::hardware::sensors::V2_1::Event;
37 using ::android::hardware::sensors::V2_1::SensorInfo;
38 using ::android::hardware::sensors::V2_1::SensorType;
39 
Sensor(int32_t sensorHandle,ISensorsEventCallback * callback)40 Sensor::Sensor(int32_t sensorHandle, ISensorsEventCallback* callback)
41     : mIsEnabled(false),
42       mSamplingPeriodNs(0),
43       mLastSampleTimeNs(0),
44       mCallback(callback),
45       mMode(OperationMode::NORMAL) {
46     mSensorInfo.sensorHandle = sensorHandle;
47     mSensorInfo.vendor = "Vendor String";
48     mSensorInfo.version = 1;
49     constexpr float kDefaultMaxDelayUs = 1000 * 1000;
50     mSensorInfo.maxDelay = kDefaultMaxDelayUs;
51     mSensorInfo.fifoReservedEventCount = 0;
52     mSensorInfo.fifoMaxEventCount = 0;
53     mSensorInfo.requiredPermission = "";
54     mSensorInfo.flags = 0;
55     mRunThread = std::thread(startThread, this);
56 }
57 
~Sensor()58 Sensor::~Sensor() {
59     // Ensure that lock is unlocked before calling mRunThread.join() or a
60     // deadlock will occur.
61     {
62         std::unique_lock<std::mutex> lock(mRunMutex);
63         mStopThread = true;
64         mIsEnabled = false;
65         mWaitCV.notify_all();
66     }
67     mRunThread.join();
68 }
69 
getSensorInfo() const70 const SensorInfo& Sensor::getSensorInfo() const {
71     return mSensorInfo;
72 }
73 
batch(int32_t samplingPeriodNs)74 void Sensor::batch(int32_t samplingPeriodNs) {
75     samplingPeriodNs =
76             std::clamp(samplingPeriodNs, mSensorInfo.minDelay * 1000, mSensorInfo.maxDelay * 1000);
77 
78     if (mSamplingPeriodNs != samplingPeriodNs) {
79         mSamplingPeriodNs = samplingPeriodNs;
80         // Wake up the 'run' thread to check if a new event should be generated now
81         mWaitCV.notify_all();
82     }
83 }
84 
activate(bool enable)85 void Sensor::activate(bool enable) {
86     if (mIsEnabled != enable) {
87         std::unique_lock<std::mutex> lock(mRunMutex);
88         mIsEnabled = enable;
89         mWaitCV.notify_all();
90     }
91 }
92 
flush()93 Result Sensor::flush() {
94     // Only generate a flush complete event if the sensor is enabled and if the sensor is not a
95     // one-shot sensor.
96     if (!mIsEnabled || (mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::ONE_SHOT_MODE))) {
97         return Result::BAD_VALUE;
98     }
99 
100     // Note: If a sensor supports batching, write all of the currently batched events for the sensor
101     // to the Event FMQ prior to writing the flush complete event.
102     Event ev;
103     ev.sensorHandle = mSensorInfo.sensorHandle;
104     ev.sensorType = SensorType::META_DATA;
105     ev.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE;
106     std::vector<Event> evs{ev};
107     mCallback->postEvents(evs, isWakeUpSensor());
108 
109     return Result::OK;
110 }
111 
startThread(Sensor * sensor)112 void Sensor::startThread(Sensor* sensor) {
113     sensor->run();
114 }
115 
run()116 void Sensor::run() {
117     std::unique_lock<std::mutex> runLock(mRunMutex);
118     constexpr int64_t kNanosecondsInSeconds = 1000 * 1000 * 1000;
119 
120     while (!mStopThread) {
121         if (!mIsEnabled || mMode == OperationMode::DATA_INJECTION) {
122             mWaitCV.wait(runLock, [&] {
123                 return ((mIsEnabled && mMode == OperationMode::NORMAL) || mStopThread);
124             });
125         } else {
126             timespec curTime;
127             clock_gettime(CLOCK_REALTIME, &curTime);
128             int64_t now = (curTime.tv_sec * kNanosecondsInSeconds) + curTime.tv_nsec;
129             int64_t nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
130 
131             if (now >= nextSampleTime) {
132                 mLastSampleTimeNs = now;
133                 nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
134                 mCallback->postEvents(readEvents(), isWakeUpSensor());
135             }
136 
137             mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now));
138         }
139     }
140 }
141 
isWakeUpSensor()142 bool Sensor::isWakeUpSensor() {
143     return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
144 }
145 
readEvents()146 std::vector<Event> Sensor::readEvents() {
147     std::vector<Event> events;
148     Event event;
149     event.sensorHandle = mSensorInfo.sensorHandle;
150     event.sensorType = mSensorInfo.type;
151     event.timestamp = ::android::elapsedRealtimeNano();
152     event.u.vec3.x = 0;
153     event.u.vec3.y = 0;
154     event.u.vec3.z = 0;
155     event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
156     events.push_back(event);
157     return events;
158 }
159 
setOperationMode(OperationMode mode)160 void Sensor::setOperationMode(OperationMode mode) {
161     if (mMode != mode) {
162         std::unique_lock<std::mutex> lock(mRunMutex);
163         mMode = mode;
164         mWaitCV.notify_all();
165     }
166 }
167 
supportsDataInjection() const168 bool Sensor::supportsDataInjection() const {
169     return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION);
170 }
171 
injectEvent(const Event & event)172 Result Sensor::injectEvent(const Event& event) {
173     Result result = Result::OK;
174     if (event.sensorType == SensorType::ADDITIONAL_INFO) {
175         // When in OperationMode::NORMAL, SensorType::ADDITIONAL_INFO is used to push operation
176         // environment data into the device.
177     } else if (!supportsDataInjection()) {
178         result = Result::INVALID_OPERATION;
179     } else if (mMode == OperationMode::DATA_INJECTION) {
180         mCallback->postEvents(std::vector<Event>{event}, isWakeUpSensor());
181     } else {
182         result = Result::BAD_VALUE;
183     }
184     return result;
185 }
186 
OnChangeSensor(int32_t sensorHandle,ISensorsEventCallback * callback)187 OnChangeSensor::OnChangeSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
188     : Sensor(sensorHandle, callback), mPreviousEventSet(false) {
189     mSensorInfo.flags |= SensorFlagBits::ON_CHANGE_MODE;
190 }
191 
activate(bool enable)192 void OnChangeSensor::activate(bool enable) {
193     Sensor::activate(enable);
194     if (!enable) {
195         mPreviousEventSet = false;
196     }
197 }
198 
readEvents()199 std::vector<Event> OnChangeSensor::readEvents() {
200     std::vector<Event> events = Sensor::readEvents();
201     std::vector<Event> outputEvents;
202 
203     for (auto iter = events.begin(); iter != events.end(); ++iter) {
204         Event ev = *iter;
205         if (ev.u.vec3 != mPreviousEvent.u.vec3 || !mPreviousEventSet) {
206             outputEvents.push_back(ev);
207             mPreviousEvent = ev;
208             mPreviousEventSet = true;
209         }
210     }
211     return outputEvents;
212 }
213 
ContinuousSensor(int32_t sensorHandle,ISensorsEventCallback * callback)214 ContinuousSensor::ContinuousSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
215     : Sensor(sensorHandle, callback) {
216     mSensorInfo.flags |= SensorFlagBits::CONTINUOUS_MODE;
217 }
218 
AccelSensor(int32_t sensorHandle,ISensorsEventCallback * callback)219 AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
220     : ContinuousSensor(sensorHandle, callback) {
221     mSensorInfo.name = "Accel Sensor";
222     mSensorInfo.type = SensorType::ACCELEROMETER;
223     mSensorInfo.typeAsString = SENSOR_STRING_TYPE_ACCELEROMETER;
224     mSensorInfo.maxRange = 78.4f;  // +/- 8g
225     mSensorInfo.resolution = 1.52e-5;
226     mSensorInfo.power = 0.001f;        // mA
227     mSensorInfo.minDelay = 20 * 1000;  // microseconds
228     mSensorInfo.flags |= SensorFlagBits::DATA_INJECTION;
229 }
230 
readEvents()231 std::vector<Event> AccelSensor::readEvents() {
232     std::vector<Event> events;
233     Event event;
234     event.sensorHandle = mSensorInfo.sensorHandle;
235     event.sensorType = mSensorInfo.type;
236     event.timestamp = ::android::elapsedRealtimeNano();
237     event.u.vec3.x = 0;
238     event.u.vec3.y = 0;
239     event.u.vec3.z = -9.815;
240     event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
241     events.push_back(event);
242     return events;
243 }
244 
PressureSensor(int32_t sensorHandle,ISensorsEventCallback * callback)245 PressureSensor::PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
246     : ContinuousSensor(sensorHandle, callback) {
247     mSensorInfo.name = "Pressure Sensor";
248     mSensorInfo.type = SensorType::PRESSURE;
249     mSensorInfo.typeAsString = SENSOR_STRING_TYPE_PRESSURE;
250     mSensorInfo.maxRange = 1100.0f;     // hPa
251     mSensorInfo.resolution = 0.005f;    // hPa
252     mSensorInfo.power = 0.001f;         // mA
253     mSensorInfo.minDelay = 100 * 1000;  // microseconds
254 }
255 
MagnetometerSensor(int32_t sensorHandle,ISensorsEventCallback * callback)256 MagnetometerSensor::MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
257     : ContinuousSensor(sensorHandle, callback) {
258     mSensorInfo.name = "Magnetic Field Sensor";
259     mSensorInfo.type = SensorType::MAGNETIC_FIELD;
260     mSensorInfo.typeAsString = SENSOR_STRING_TYPE_MAGNETIC_FIELD;
261     mSensorInfo.maxRange = 1300.0f;
262     mSensorInfo.resolution = 0.01f;
263     mSensorInfo.power = 0.001f;        // mA
264     mSensorInfo.minDelay = 20 * 1000;  // microseconds
265 }
266 
LightSensor(int32_t sensorHandle,ISensorsEventCallback * callback)267 LightSensor::LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
268     : OnChangeSensor(sensorHandle, callback) {
269     mSensorInfo.name = "Light Sensor";
270     mSensorInfo.type = SensorType::LIGHT;
271     mSensorInfo.typeAsString = SENSOR_STRING_TYPE_LIGHT;
272     mSensorInfo.maxRange = 43000.0f;
273     mSensorInfo.resolution = 10.0f;
274     mSensorInfo.power = 0.001f;         // mA
275     mSensorInfo.minDelay = 200 * 1000;  // microseconds
276 }
277 
ProximitySensor(int32_t sensorHandle,ISensorsEventCallback * callback)278 ProximitySensor::ProximitySensor(int32_t sensorHandle, ISensorsEventCallback* callback)
279     : OnChangeSensor(sensorHandle, callback) {
280     mSensorInfo.name = "Proximity Sensor";
281     mSensorInfo.type = SensorType::PROXIMITY;
282     mSensorInfo.typeAsString = SENSOR_STRING_TYPE_PROXIMITY;
283     mSensorInfo.maxRange = 5.0f;
284     mSensorInfo.resolution = 1.0f;
285     mSensorInfo.power = 0.012f;         // mA
286     mSensorInfo.minDelay = 200 * 1000;  // microseconds
287     mSensorInfo.flags |= SensorFlagBits::WAKE_UP;
288 }
289 
GyroSensor(int32_t sensorHandle,ISensorsEventCallback * callback)290 GyroSensor::GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
291     : ContinuousSensor(sensorHandle, callback) {
292     mSensorInfo.name = "Gyro Sensor";
293     mSensorInfo.type = SensorType::GYROSCOPE;
294     mSensorInfo.typeAsString = SENSOR_STRING_TYPE_GYROSCOPE;
295     mSensorInfo.maxRange = 1000.0f * M_PI / 180.0f;
296     mSensorInfo.resolution = 1000.0f * M_PI / (180.0f * 32768.0f);
297     mSensorInfo.power = 0.001f;
298     mSensorInfo.minDelay = 2.5f * 1000;  // microseconds
299 }
300 
readEvents()301 std::vector<Event> GyroSensor::readEvents() {
302     std::vector<Event> events;
303     Event event;
304     event.sensorHandle = mSensorInfo.sensorHandle;
305     event.sensorType = mSensorInfo.type;
306     event.timestamp = ::android::elapsedRealtimeNano();
307     event.u.vec3.x = 0;
308     event.u.vec3.y = 0;
309     event.u.vec3.z = 0;
310     event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
311     events.push_back(event);
312     return events;
313 }
314 
AmbientTempSensor(int32_t sensorHandle,ISensorsEventCallback * callback)315 AmbientTempSensor::AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
316     : OnChangeSensor(sensorHandle, callback) {
317     mSensorInfo.name = "Ambient Temp Sensor";
318     mSensorInfo.type = SensorType::AMBIENT_TEMPERATURE;
319     mSensorInfo.typeAsString = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
320     mSensorInfo.maxRange = 80.0f;
321     mSensorInfo.resolution = 0.01f;
322     mSensorInfo.power = 0.001f;
323     mSensorInfo.minDelay = 40 * 1000;  // microseconds
324 }
325 
DeviceTempSensor(int32_t sensorHandle,ISensorsEventCallback * callback)326 DeviceTempSensor::DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
327     : ContinuousSensor(sensorHandle, callback) {
328     mSensorInfo.name = "Device Temp Sensor";
329     mSensorInfo.type = SensorType::TEMPERATURE;
330     mSensorInfo.typeAsString = SENSOR_STRING_TYPE_TEMPERATURE;
331     mSensorInfo.maxRange = 80.0f;
332     mSensorInfo.resolution = 0.01f;
333     mSensorInfo.power = 0.001f;
334     mSensorInfo.minDelay = 40 * 1000;  // microseconds
335 }
336 
RelativeHumiditySensor(int32_t sensorHandle,ISensorsEventCallback * callback)337 RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle,
338                                                ISensorsEventCallback* callback)
339     : OnChangeSensor(sensorHandle, callback) {
340     mSensorInfo.name = "Relative Humidity Sensor";
341     mSensorInfo.type = SensorType::RELATIVE_HUMIDITY;
342     mSensorInfo.typeAsString = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
343     mSensorInfo.maxRange = 100.0f;
344     mSensorInfo.resolution = 0.1f;
345     mSensorInfo.power = 0.001f;
346     mSensorInfo.minDelay = 40 * 1000;  // microseconds
347 }
348 
349 }  // namespace implementation
350 }  // namespace subhal
351 }  // namespace V2_1
352 }  // namespace sensors
353 }  // namespace hardware
354 }  // namespace android
355