blob: 3bdd8b6f1b57fce5624e730b79fd21d977abc300 [file] [log] [blame]
Grace Chengbc2a1b72021-11-09 14:26:23 +00001/*
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#include "sensors-impl/Sensor.h"
18
19#include "utils/SystemClock.h"
20
21#include <cmath>
22
23using ::ndk::ScopedAStatus;
24
25namespace aidl {
26namespace android {
27namespace hardware {
28namespace sensors {
29
30static constexpr int32_t kDefaultMaxDelayUs = 10 * 1000 * 1000;
31
32Sensor::Sensor(ISensorsEventCallback* callback)
33 : mIsEnabled(false),
34 mSamplingPeriodNs(0),
35 mLastSampleTimeNs(0),
36 mCallback(callback),
37 mMode(OperationMode::NORMAL) {
38 mRunThread = std::thread(startThread, this);
39}
40
41Sensor::~Sensor() {
42 std::unique_lock<std::mutex> lock(mRunMutex);
43 mStopThread = true;
44 mIsEnabled = false;
45 mWaitCV.notify_all();
46 lock.release();
47 mRunThread.join();
48}
49
50const SensorInfo& Sensor::getSensorInfo() const {
51 return mSensorInfo;
52}
53
54void Sensor::batch(int64_t samplingPeriodNs) {
Chih-Hung Hsieh91b48352022-02-09 15:47:54 -080055 if (samplingPeriodNs < mSensorInfo.minDelayUs * 1000LL) {
56 samplingPeriodNs = mSensorInfo.minDelayUs * 1000LL;
57 } else if (samplingPeriodNs > mSensorInfo.maxDelayUs * 1000LL) {
58 samplingPeriodNs = mSensorInfo.maxDelayUs * 1000LL;
Grace Chengbc2a1b72021-11-09 14:26:23 +000059 }
60
61 if (mSamplingPeriodNs != samplingPeriodNs) {
62 mSamplingPeriodNs = samplingPeriodNs;
63 // Wake up the 'run' thread to check if a new event should be generated now
64 mWaitCV.notify_all();
65 }
66}
67
68void Sensor::activate(bool enable) {
69 if (mIsEnabled != enable) {
70 std::unique_lock<std::mutex> lock(mRunMutex);
71 mIsEnabled = enable;
72 mWaitCV.notify_all();
73 }
74}
75
76ScopedAStatus Sensor::flush() {
77 // Only generate a flush complete event if the sensor is enabled and if the sensor is not a
78 // one-shot sensor.
79 if (!mIsEnabled ||
80 (mSensorInfo.flags & static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE))) {
81 return ScopedAStatus::fromServiceSpecificError(
82 static_cast<int32_t>(BnSensors::ERROR_BAD_VALUE));
83 }
84
85 // Note: If a sensor supports batching, write all of the currently batched events for the sensor
86 // to the Event FMQ prior to writing the flush complete event.
87 Event ev;
88 ev.sensorHandle = mSensorInfo.sensorHandle;
89 ev.sensorType = SensorType::META_DATA;
90 EventPayload::MetaData meta = {
91 .what = MetaDataEventType::META_DATA_FLUSH_COMPLETE,
92 };
93 ev.payload.set<EventPayload::Tag::meta>(meta);
94 std::vector<Event> evs{ev};
95 mCallback->postEvents(evs, isWakeUpSensor());
96
97 return ScopedAStatus::ok();
98}
99
100void Sensor::startThread(Sensor* sensor) {
101 sensor->run();
102}
103
104void Sensor::run() {
105 std::unique_lock<std::mutex> runLock(mRunMutex);
106 constexpr int64_t kNanosecondsInSeconds = 1000 * 1000 * 1000;
107
108 while (!mStopThread) {
109 if (!mIsEnabled || mMode == OperationMode::DATA_INJECTION) {
110 mWaitCV.wait(runLock, [&] {
111 return ((mIsEnabled && mMode == OperationMode::NORMAL) || mStopThread);
112 });
113 } else {
114 timespec curTime;
115 clock_gettime(CLOCK_BOOTTIME, &curTime);
116 int64_t now = (curTime.tv_sec * kNanosecondsInSeconds) + curTime.tv_nsec;
117 int64_t nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
118
119 if (now >= nextSampleTime) {
120 mLastSampleTimeNs = now;
121 nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
122 mCallback->postEvents(readEvents(), isWakeUpSensor());
123 }
124
125 mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now));
126 }
127 }
128}
129
130bool Sensor::isWakeUpSensor() {
131 return mSensorInfo.flags & static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_WAKE_UP);
132}
133
134std::vector<Event> Sensor::readEvents() {
135 std::vector<Event> events;
136 Event event;
137 event.sensorHandle = mSensorInfo.sensorHandle;
138 event.sensorType = mSensorInfo.type;
139 event.timestamp = ::android::elapsedRealtimeNano();
140 memset(&event.payload, 0, sizeof(event.payload));
141 readEventPayload(event.payload);
142 events.push_back(event);
143 return events;
144}
145
146void Sensor::setOperationMode(OperationMode mode) {
147 if (mMode != mode) {
148 std::unique_lock<std::mutex> lock(mRunMutex);
149 mMode = mode;
150 mWaitCV.notify_all();
151 }
152}
153
154bool Sensor::supportsDataInjection() const {
155 return mSensorInfo.flags & static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_DATA_INJECTION);
156}
157
158ScopedAStatus Sensor::injectEvent(const Event& event) {
159 if (event.sensorType == SensorType::ADDITIONAL_INFO) {
160 return ScopedAStatus::ok();
161 // When in OperationMode::NORMAL, SensorType::ADDITIONAL_INFO is used to push operation
162 // environment data into the device.
163 }
164
165 if (!supportsDataInjection()) {
166 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
167 }
168
169 if (mMode == OperationMode::DATA_INJECTION) {
170 mCallback->postEvents(std::vector<Event>{event}, isWakeUpSensor());
171 return ScopedAStatus::ok();
172 }
173
174 return ScopedAStatus::fromServiceSpecificError(
175 static_cast<int32_t>(BnSensors::ERROR_BAD_VALUE));
176}
177
178OnChangeSensor::OnChangeSensor(ISensorsEventCallback* callback)
179 : Sensor(callback), mPreviousEventSet(false) {}
180
181void OnChangeSensor::activate(bool enable) {
182 Sensor::activate(enable);
183 if (!enable) {
184 mPreviousEventSet = false;
185 }
186}
187
188std::vector<Event> OnChangeSensor::readEvents() {
189 std::vector<Event> events = Sensor::readEvents();
190 std::vector<Event> outputEvents;
191
192 for (auto iter = events.begin(); iter != events.end(); ++iter) {
193 Event ev = *iter;
194 if (!mPreviousEventSet ||
195 memcmp(&mPreviousEvent.payload, &ev.payload, sizeof(ev.payload)) != 0) {
196 outputEvents.push_back(ev);
197 mPreviousEvent = ev;
198 mPreviousEventSet = true;
199 }
200 }
201 return outputEvents;
202}
203
204AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
205 mSensorInfo.sensorHandle = sensorHandle;
206 mSensorInfo.name = "Accel Sensor";
207 mSensorInfo.vendor = "Vendor String";
208 mSensorInfo.version = 1;
209 mSensorInfo.type = SensorType::ACCELEROMETER;
210 mSensorInfo.typeAsString = "";
211 mSensorInfo.maxRange = 78.4f; // +/- 8g
212 mSensorInfo.resolution = 1.52e-5;
213 mSensorInfo.power = 0.001f; // mA
214 mSensorInfo.minDelayUs = 10 * 1000; // microseconds
215 mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
216 mSensorInfo.fifoReservedEventCount = 0;
217 mSensorInfo.fifoMaxEventCount = 0;
218 mSensorInfo.requiredPermission = "";
219 mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_DATA_INJECTION);
220};
221
222void AccelSensor::readEventPayload(EventPayload& payload) {
223 EventPayload::Vec3 vec3 = {
224 .x = 0,
225 .y = 0,
Karthik Bharadwaj4cea5292022-11-21 18:28:44 +0000226 .z = 9.8,
Grace Chengbc2a1b72021-11-09 14:26:23 +0000227 .status = SensorStatus::ACCURACY_HIGH,
228 };
229 payload.set<EventPayload::Tag::vec3>(vec3);
230}
231
232PressureSensor::PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
233 : Sensor(callback) {
234 mSensorInfo.sensorHandle = sensorHandle;
235 mSensorInfo.name = "Pressure Sensor";
236 mSensorInfo.vendor = "Vendor String";
237 mSensorInfo.version = 1;
238 mSensorInfo.type = SensorType::PRESSURE;
239 mSensorInfo.typeAsString = "";
240 mSensorInfo.maxRange = 1100.0f; // hPa
241 mSensorInfo.resolution = 0.005f; // hPa
242 mSensorInfo.power = 0.001f; // mA
243 mSensorInfo.minDelayUs = 100 * 1000; // microseconds
244 mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
245 mSensorInfo.fifoReservedEventCount = 0;
246 mSensorInfo.fifoMaxEventCount = 0;
247 mSensorInfo.requiredPermission = "";
248 mSensorInfo.flags = 0;
249};
250
251void PressureSensor::readEventPayload(EventPayload& payload) {
252 payload.set<EventPayload::Tag::scalar>(1013.25f);
253}
254
255MagnetometerSensor::MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
256 : Sensor(callback) {
257 mSensorInfo.sensorHandle = sensorHandle;
258 mSensorInfo.name = "Magnetic Field Sensor";
259 mSensorInfo.vendor = "Vendor String";
260 mSensorInfo.version = 1;
261 mSensorInfo.type = SensorType::MAGNETIC_FIELD;
262 mSensorInfo.typeAsString = "";
263 mSensorInfo.maxRange = 1300.0f;
264 mSensorInfo.resolution = 0.01f;
265 mSensorInfo.power = 0.001f; // mA
266 mSensorInfo.minDelayUs = 20 * 1000; // microseconds
267 mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
268 mSensorInfo.fifoReservedEventCount = 0;
269 mSensorInfo.fifoMaxEventCount = 0;
270 mSensorInfo.requiredPermission = "";
271 mSensorInfo.flags = 0;
272};
273
274void MagnetometerSensor::readEventPayload(EventPayload& payload) {
275 EventPayload::Vec3 vec3 = {
276 .x = 100.0,
277 .y = 0,
278 .z = 50.0,
279 .status = SensorStatus::ACCURACY_HIGH,
280 };
281 payload.set<EventPayload::Tag::vec3>(vec3);
282}
283
284LightSensor::LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
285 : OnChangeSensor(callback) {
286 mSensorInfo.sensorHandle = sensorHandle;
287 mSensorInfo.name = "Light Sensor";
288 mSensorInfo.vendor = "Vendor String";
289 mSensorInfo.version = 1;
290 mSensorInfo.type = SensorType::LIGHT;
291 mSensorInfo.typeAsString = "";
292 mSensorInfo.maxRange = 43000.0f;
293 mSensorInfo.resolution = 10.0f;
294 mSensorInfo.power = 0.001f; // mA
295 mSensorInfo.minDelayUs = 200 * 1000; // microseconds
296 mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
297 mSensorInfo.fifoReservedEventCount = 0;
298 mSensorInfo.fifoMaxEventCount = 0;
299 mSensorInfo.requiredPermission = "";
300 mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE);
301};
302
303void LightSensor::readEventPayload(EventPayload& payload) {
304 payload.set<EventPayload::Tag::scalar>(80.0f);
305}
306
307ProximitySensor::ProximitySensor(int32_t sensorHandle, ISensorsEventCallback* callback)
308 : OnChangeSensor(callback) {
309 mSensorInfo.sensorHandle = sensorHandle;
310 mSensorInfo.name = "Proximity Sensor";
311 mSensorInfo.vendor = "Vendor String";
312 mSensorInfo.version = 1;
313 mSensorInfo.type = SensorType::PROXIMITY;
314 mSensorInfo.typeAsString = "";
315 mSensorInfo.maxRange = 5.0f;
316 mSensorInfo.resolution = 1.0f;
317 mSensorInfo.power = 0.012f; // mA
318 mSensorInfo.minDelayUs = 200 * 1000; // microseconds
319 mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
320 mSensorInfo.fifoReservedEventCount = 0;
321 mSensorInfo.fifoMaxEventCount = 0;
322 mSensorInfo.requiredPermission = "";
323 mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE |
324 SensorInfo::SENSOR_FLAG_BITS_WAKE_UP);
325};
326
327void ProximitySensor::readEventPayload(EventPayload& payload) {
328 payload.set<EventPayload::Tag::scalar>(2.5f);
329}
330
331GyroSensor::GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
332 mSensorInfo.sensorHandle = sensorHandle;
333 mSensorInfo.name = "Gyro Sensor";
334 mSensorInfo.vendor = "Vendor String";
335 mSensorInfo.version = 1;
336 mSensorInfo.type = SensorType::GYROSCOPE;
337 mSensorInfo.typeAsString = "";
338 mSensorInfo.maxRange = 1000.0f * M_PI / 180.0f;
339 mSensorInfo.resolution = 1000.0f * M_PI / (180.0f * 32768.0f);
340 mSensorInfo.power = 0.001f;
341 mSensorInfo.minDelayUs = 10 * 1000; // microseconds
342 mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
343 mSensorInfo.fifoReservedEventCount = 0;
344 mSensorInfo.fifoMaxEventCount = 0;
345 mSensorInfo.requiredPermission = "";
346 mSensorInfo.flags = 0;
347};
348
349void GyroSensor::readEventPayload(EventPayload& payload) {
350 EventPayload::Vec3 vec3 = {
351 .x = 0,
352 .y = 0,
353 .z = 0,
354 .status = SensorStatus::ACCURACY_HIGH,
355 };
356 payload.set<EventPayload::Tag::vec3>(vec3);
357}
358
359AmbientTempSensor::AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
360 : OnChangeSensor(callback) {
361 mSensorInfo.sensorHandle = sensorHandle;
362 mSensorInfo.name = "Ambient Temp Sensor";
363 mSensorInfo.vendor = "Vendor String";
364 mSensorInfo.version = 1;
365 mSensorInfo.type = SensorType::AMBIENT_TEMPERATURE;
366 mSensorInfo.typeAsString = "";
367 mSensorInfo.maxRange = 80.0f;
368 mSensorInfo.resolution = 0.01f;
369 mSensorInfo.power = 0.001f;
370 mSensorInfo.minDelayUs = 40 * 1000; // microseconds
371 mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
372 mSensorInfo.fifoReservedEventCount = 0;
373 mSensorInfo.fifoMaxEventCount = 0;
374 mSensorInfo.requiredPermission = "";
375 mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE);
376};
377
378void AmbientTempSensor::readEventPayload(EventPayload& payload) {
379 payload.set<EventPayload::Tag::scalar>(40.0f);
380}
381
382RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle,
383 ISensorsEventCallback* callback)
384 : OnChangeSensor(callback) {
385 mSensorInfo.sensorHandle = sensorHandle;
386 mSensorInfo.name = "Relative Humidity Sensor";
387 mSensorInfo.vendor = "Vendor String";
388 mSensorInfo.version = 1;
389 mSensorInfo.type = SensorType::RELATIVE_HUMIDITY;
390 mSensorInfo.typeAsString = "";
391 mSensorInfo.maxRange = 100.0f;
392 mSensorInfo.resolution = 0.1f;
393 mSensorInfo.power = 0.001f;
394 mSensorInfo.minDelayUs = 40 * 1000; // microseconds
395 mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
396 mSensorInfo.fifoReservedEventCount = 0;
397 mSensorInfo.fifoMaxEventCount = 0;
398 mSensorInfo.requiredPermission = "";
399 mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE);
400}
401
402void RelativeHumiditySensor::readEventPayload(EventPayload& payload) {
403 payload.set<EventPayload::Tag::scalar>(50.0f);
404}
405
406HingeAngleSensor::HingeAngleSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
407 : OnChangeSensor(callback) {
408 mSensorInfo.sensorHandle = sensorHandle;
409 mSensorInfo.name = "Hinge Angle Sensor";
410 mSensorInfo.vendor = "Vendor String";
411 mSensorInfo.version = 1;
412 mSensorInfo.type = SensorType::HINGE_ANGLE;
413 mSensorInfo.typeAsString = "";
414 mSensorInfo.maxRange = 360.0f;
415 mSensorInfo.resolution = 1.0f;
416 mSensorInfo.power = 0.001f;
417 mSensorInfo.minDelayUs = 40 * 1000; // microseconds
418 mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
419 mSensorInfo.fifoReservedEventCount = 0;
420 mSensorInfo.fifoMaxEventCount = 0;
421 mSensorInfo.requiredPermission = "";
422 mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE |
423 SensorInfo::SENSOR_FLAG_BITS_WAKE_UP |
424 SensorInfo::SENSOR_FLAG_BITS_DATA_INJECTION);
425}
426
427void HingeAngleSensor::readEventPayload(EventPayload& payload) {
428 payload.set<EventPayload::Tag::scalar>(180.0f);
429}
430
431} // namespace sensors
432} // namespace hardware
433} // namespace android
434} // namespace aidl