diff options
author | Anthony Stange <stange@google.com> | 2020-02-05 19:27:16 -0500 |
---|---|---|
committer | Anthony Stange <stange@google.com> | 2020-02-18 15:24:35 -0500 |
commit | 1d71acc129331cca3bedbfd6c1b350682f0d2fae (patch) | |
tree | 09a8a67ea06d43401c2c9a671b0ba599ecda9571 /sensors/common/default/2.X/Sensor.cpp | |
parent | c002dd9ecaa5f2dc29e1f488ed6d0b14adbdedb7 (diff) |
Add default impl of Sensors HAL 2.1
Create a default implementation of HAL 2.1 that shares 90% of the
underlying code with HAL 2.0 since the interfaces are very similar.
Bug: 144139857
Test: compile
Change-Id: Ic6b139df98ddb1f92833b1f2d65e1cecc297fd41
Diffstat (limited to 'sensors/common/default/2.X/Sensor.cpp')
-rw-r--r-- | sensors/common/default/2.X/Sensor.cpp | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/sensors/common/default/2.X/Sensor.cpp b/sensors/common/default/2.X/Sensor.cpp new file mode 100644 index 0000000000..4c40d1f33b --- /dev/null +++ b/sensors/common/default/2.X/Sensor.cpp @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Sensor.h" + +#include <utils/SystemClock.h> + +#include <cmath> + +namespace android { +namespace hardware { +namespace sensors { +namespace V2_X { +namespace implementation { + +using ::android::hardware::sensors::V1_0::Event; +using ::android::hardware::sensors::V1_0::MetaDataEventType; +using ::android::hardware::sensors::V1_0::OperationMode; +using ::android::hardware::sensors::V1_0::Result; +using ::android::hardware::sensors::V1_0::SensorFlagBits; +using ::android::hardware::sensors::V1_0::SensorInfo; +using ::android::hardware::sensors::V1_0::SensorStatus; +using ::android::hardware::sensors::V1_0::SensorType; + +static constexpr float kDefaultMaxDelayUs = 10 * 1000 * 1000; + +Sensor::Sensor(ISensorsEventCallback* callback) + : mIsEnabled(false), + mSamplingPeriodNs(0), + mLastSampleTimeNs(0), + mCallback(callback), + mMode(OperationMode::NORMAL) { + mRunThread = std::thread(startThread, this); +} + +Sensor::~Sensor() { + std::unique_lock<std::mutex> lock(mRunMutex); + mStopThread = true; + mIsEnabled = false; + mWaitCV.notify_all(); + lock.release(); + mRunThread.join(); +} + +const SensorInfo& Sensor::getSensorInfo() const { + return mSensorInfo; +} + +void Sensor::batch(int32_t samplingPeriodNs) { + if (samplingPeriodNs < mSensorInfo.minDelay * 1000) { + samplingPeriodNs = mSensorInfo.minDelay * 1000; + } else if (samplingPeriodNs > mSensorInfo.maxDelay * 1000) { + samplingPeriodNs = mSensorInfo.maxDelay * 1000; + } + + if (mSamplingPeriodNs != samplingPeriodNs) { + mSamplingPeriodNs = samplingPeriodNs; + // Wake up the 'run' thread to check if a new event should be generated now + mWaitCV.notify_all(); + } +} + +void Sensor::activate(bool enable) { + if (mIsEnabled != enable) { + std::unique_lock<std::mutex> lock(mRunMutex); + mIsEnabled = enable; + mWaitCV.notify_all(); + } +} + +Result Sensor::flush() { + // Only generate a flush complete event if the sensor is enabled and if the sensor is not a + // one-shot sensor. + if (!mIsEnabled || (mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::ONE_SHOT_MODE))) { + return Result::BAD_VALUE; + } + + // Note: If a sensor supports batching, write all of the currently batched events for the sensor + // to the Event FMQ prior to writing the flush complete event. + Event ev; + ev.sensorHandle = mSensorInfo.sensorHandle; + ev.sensorType = SensorType::META_DATA; + ev.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE; + std::vector<Event> evs{ev}; + mCallback->postEvents(evs, isWakeUpSensor()); + + return Result::OK; +} + +void Sensor::startThread(Sensor* sensor) { + sensor->run(); +} + +void Sensor::run() { + std::unique_lock<std::mutex> runLock(mRunMutex); + constexpr int64_t kNanosecondsInSeconds = 1000 * 1000 * 1000; + + while (!mStopThread) { + if (!mIsEnabled || mMode == OperationMode::DATA_INJECTION) { + mWaitCV.wait(runLock, [&] { + return ((mIsEnabled && mMode == OperationMode::NORMAL) || mStopThread); + }); + } else { + timespec curTime; + clock_gettime(CLOCK_REALTIME, &curTime); + int64_t now = (curTime.tv_sec * kNanosecondsInSeconds) + curTime.tv_nsec; + int64_t nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs; + + if (now >= nextSampleTime) { + mLastSampleTimeNs = now; + nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs; + mCallback->postEvents(readEvents(), isWakeUpSensor()); + } + + mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now)); + } + } +} + +bool Sensor::isWakeUpSensor() { + return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP); +} + +std::vector<Event> Sensor::readEvents() { + std::vector<Event> events; + Event event; + event.sensorHandle = mSensorInfo.sensorHandle; + event.sensorType = mSensorInfo.type; + event.timestamp = ::android::elapsedRealtimeNano(); + event.u.vec3.x = 0; + event.u.vec3.y = 0; + event.u.vec3.z = 0; + event.u.vec3.status = SensorStatus::ACCURACY_HIGH; + events.push_back(event); + return events; +} + +void Sensor::setOperationMode(OperationMode mode) { + if (mMode != mode) { + std::unique_lock<std::mutex> lock(mRunMutex); + mMode = mode; + mWaitCV.notify_all(); + } +} + +bool Sensor::supportsDataInjection() const { + return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION); +} + +Result Sensor::injectEvent(const Event& event) { + Result result = Result::OK; + if (event.sensorType == SensorType::ADDITIONAL_INFO) { + // When in OperationMode::NORMAL, SensorType::ADDITIONAL_INFO is used to push operation + // environment data into the device. + } else if (!supportsDataInjection()) { + result = Result::INVALID_OPERATION; + } else if (mMode == OperationMode::DATA_INJECTION) { + mCallback->postEvents(std::vector<Event>{event}, isWakeUpSensor()); + } else { + result = Result::BAD_VALUE; + } + return result; +} + +OnChangeSensor::OnChangeSensor(ISensorsEventCallback* callback) + : Sensor(callback), mPreviousEventSet(false) {} + +void OnChangeSensor::activate(bool enable) { + Sensor::activate(enable); + if (!enable) { + mPreviousEventSet = false; + } +} + +std::vector<Event> OnChangeSensor::readEvents() { + std::vector<Event> events = Sensor::readEvents(); + std::vector<Event> outputEvents; + + for (auto iter = events.begin(); iter != events.end(); ++iter) { + Event ev = *iter; + if (ev.u.vec3 != mPreviousEvent.u.vec3 || !mPreviousEventSet) { + outputEvents.push_back(ev); + mPreviousEvent = ev; + mPreviousEventSet = true; + } + } + return outputEvents; +} + +AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) { + mSensorInfo.sensorHandle = sensorHandle; + mSensorInfo.name = "Accel Sensor"; + mSensorInfo.vendor = "Vendor String"; + mSensorInfo.version = 1; + mSensorInfo.type = SensorType::ACCELEROMETER; + mSensorInfo.typeAsString = ""; + mSensorInfo.maxRange = 78.4f; // +/- 8g + mSensorInfo.resolution = 1.52e-5; + mSensorInfo.power = 0.001f; // mA + mSensorInfo.minDelay = 20 * 1000; // microseconds + mSensorInfo.maxDelay = kDefaultMaxDelayUs; + mSensorInfo.fifoReservedEventCount = 0; + mSensorInfo.fifoMaxEventCount = 0; + mSensorInfo.requiredPermission = ""; + mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION); +}; + +PressureSensor::PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback) + : Sensor(callback) { + mSensorInfo.sensorHandle = sensorHandle; + mSensorInfo.name = "Pressure Sensor"; + mSensorInfo.vendor = "Vendor String"; + mSensorInfo.version = 1; + mSensorInfo.type = SensorType::PRESSURE; + mSensorInfo.typeAsString = ""; + mSensorInfo.maxRange = 1100.0f; // hPa + mSensorInfo.resolution = 0.005f; // hPa + mSensorInfo.power = 0.001f; // mA + mSensorInfo.minDelay = 100 * 1000; // microseconds + mSensorInfo.maxDelay = kDefaultMaxDelayUs; + mSensorInfo.fifoReservedEventCount = 0; + mSensorInfo.fifoMaxEventCount = 0; + mSensorInfo.requiredPermission = ""; + mSensorInfo.flags = 0; +}; + +MagnetometerSensor::MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback) + : Sensor(callback) { + mSensorInfo.sensorHandle = sensorHandle; + mSensorInfo.name = "Magnetic Field Sensor"; + mSensorInfo.vendor = "Vendor String"; + mSensorInfo.version = 1; + mSensorInfo.type = SensorType::MAGNETIC_FIELD; + mSensorInfo.typeAsString = ""; + mSensorInfo.maxRange = 1300.0f; + mSensorInfo.resolution = 0.01f; + mSensorInfo.power = 0.001f; // mA + mSensorInfo.minDelay = 20 * 1000; // microseconds + mSensorInfo.maxDelay = kDefaultMaxDelayUs; + mSensorInfo.fifoReservedEventCount = 0; + mSensorInfo.fifoMaxEventCount = 0; + mSensorInfo.requiredPermission = ""; + mSensorInfo.flags = 0; +}; + +LightSensor::LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback) + : OnChangeSensor(callback) { + mSensorInfo.sensorHandle = sensorHandle; + mSensorInfo.name = "Light Sensor"; + mSensorInfo.vendor = "Vendor String"; + mSensorInfo.version = 1; + mSensorInfo.type = SensorType::LIGHT; + mSensorInfo.typeAsString = ""; + mSensorInfo.maxRange = 43000.0f; + mSensorInfo.resolution = 10.0f; + mSensorInfo.power = 0.001f; // mA + mSensorInfo.minDelay = 200 * 1000; // microseconds + mSensorInfo.maxDelay = kDefaultMaxDelayUs; + mSensorInfo.fifoReservedEventCount = 0; + mSensorInfo.fifoMaxEventCount = 0; + mSensorInfo.requiredPermission = ""; + mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE); +}; + +ProximitySensor::ProximitySensor(int32_t sensorHandle, ISensorsEventCallback* callback) + : OnChangeSensor(callback) { + mSensorInfo.sensorHandle = sensorHandle; + mSensorInfo.name = "Proximity Sensor"; + mSensorInfo.vendor = "Vendor String"; + mSensorInfo.version = 1; + mSensorInfo.type = SensorType::PROXIMITY; + mSensorInfo.typeAsString = ""; + mSensorInfo.maxRange = 5.0f; + mSensorInfo.resolution = 1.0f; + mSensorInfo.power = 0.012f; // mA + mSensorInfo.minDelay = 200 * 1000; // microseconds + mSensorInfo.maxDelay = kDefaultMaxDelayUs; + mSensorInfo.fifoReservedEventCount = 0; + mSensorInfo.fifoMaxEventCount = 0; + mSensorInfo.requiredPermission = ""; + mSensorInfo.flags = + static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE | SensorFlagBits::WAKE_UP); +}; + +GyroSensor::GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) { + mSensorInfo.sensorHandle = sensorHandle; + mSensorInfo.name = "Gyro Sensor"; + mSensorInfo.vendor = "Vendor String"; + mSensorInfo.version = 1; + mSensorInfo.type = SensorType::GYROSCOPE; + mSensorInfo.typeAsString = ""; + mSensorInfo.maxRange = 1000.0f * M_PI / 180.0f; + mSensorInfo.resolution = 1000.0f * M_PI / (180.0f * 32768.0f); + mSensorInfo.power = 0.001f; + mSensorInfo.minDelay = 2.5f * 1000; // microseconds + mSensorInfo.maxDelay = kDefaultMaxDelayUs; + mSensorInfo.fifoReservedEventCount = 0; + mSensorInfo.fifoMaxEventCount = 0; + mSensorInfo.requiredPermission = ""; + mSensorInfo.flags = 0; +}; + +AmbientTempSensor::AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback) + : OnChangeSensor(callback) { + mSensorInfo.sensorHandle = sensorHandle; + mSensorInfo.name = "Ambient Temp Sensor"; + mSensorInfo.vendor = "Vendor String"; + mSensorInfo.version = 1; + mSensorInfo.type = SensorType::AMBIENT_TEMPERATURE; + mSensorInfo.typeAsString = ""; + mSensorInfo.maxRange = 80.0f; + mSensorInfo.resolution = 0.01f; + mSensorInfo.power = 0.001f; + mSensorInfo.minDelay = 40 * 1000; // microseconds + mSensorInfo.maxDelay = kDefaultMaxDelayUs; + mSensorInfo.fifoReservedEventCount = 0; + mSensorInfo.fifoMaxEventCount = 0; + mSensorInfo.requiredPermission = ""; + mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE); +}; + +DeviceTempSensor::DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback) + : OnChangeSensor(callback) { + mSensorInfo.sensorHandle = sensorHandle; + mSensorInfo.name = "Device Temp Sensor"; + mSensorInfo.vendor = "Vendor String"; + mSensorInfo.version = 1; + mSensorInfo.type = SensorType::TEMPERATURE; + mSensorInfo.typeAsString = ""; + mSensorInfo.maxRange = 80.0f; + mSensorInfo.resolution = 0.01f; + mSensorInfo.power = 0.001f; + mSensorInfo.minDelay = 40 * 1000; // microseconds + mSensorInfo.maxDelay = kDefaultMaxDelayUs; + mSensorInfo.fifoReservedEventCount = 0; + mSensorInfo.fifoMaxEventCount = 0; + mSensorInfo.requiredPermission = ""; + mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE); +} + +RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle, + ISensorsEventCallback* callback) + : OnChangeSensor(callback) { + mSensorInfo.sensorHandle = sensorHandle; + mSensorInfo.name = "Relative Humidity Sensor"; + mSensorInfo.vendor = "Vendor String"; + mSensorInfo.version = 1; + mSensorInfo.type = SensorType::RELATIVE_HUMIDITY; + mSensorInfo.typeAsString = ""; + mSensorInfo.maxRange = 100.0f; + mSensorInfo.resolution = 0.1f; + mSensorInfo.power = 0.001f; + mSensorInfo.minDelay = 40 * 1000; // microseconds + mSensorInfo.maxDelay = kDefaultMaxDelayUs; + mSensorInfo.fifoReservedEventCount = 0; + mSensorInfo.fifoMaxEventCount = 0; + mSensorInfo.requiredPermission = ""; + mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE); +} + +} // namespace implementation +} // namespace V2_X +} // namespace sensors +} // namespace hardware +} // namespace android |