Generate events for default Sensors 2.0
Adds the ability for default Sensors 2.0 implementation to generate
sensor events.
Bug: 111070257
Test: Builds
Change-Id: I98f04dbac5370cc6fc3be43468ba43b6476b4515
diff --git a/sensors/2.0/default/Sensor.cpp b/sensors/2.0/default/Sensor.cpp
index f4c9b57..1691b3e 100644
--- a/sensors/2.0/default/Sensor.cpp
+++ b/sensors/2.0/default/Sensor.cpp
@@ -16,35 +16,98 @@
#include "Sensor.h"
+#include <utils/SystemClock.h>
+
namespace android {
namespace hardware {
namespace sensors {
namespace V2_0 {
namespace implementation {
-Sensor::Sensor() : mIsEnabled(false), mSamplingPeriodNs(0) {}
+using ::android::hardware::sensors::V1_0::SensorStatus;
+
+Sensor::Sensor(ISensorsEventCallback* callback)
+ : mIsEnabled(false), mSamplingPeriodNs(0), mLastSampleTimeNs(0), mCallback(callback) {
+ mRunThread = std::thread(startThread, this);
+}
+
+Sensor::~Sensor() {
+ mStopThread = true;
+ mIsEnabled = false;
+ mWaitCV.notify_all();
+ mRunThread.join();
+}
const SensorInfo& Sensor::getSensorInfo() const {
return mSensorInfo;
}
-bool Sensor::batch(int32_t samplingPeriodNs) {
- bool success = true;
- if (samplingPeriodNs >= mSensorInfo.minDelay * 1000 &&
- samplingPeriodNs <= mSensorInfo.maxDelay * 1000) {
- mSamplingPeriodNs = samplingPeriodNs;
- } else {
- success = false;
+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;
}
- return success;
+
+ 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) {
- mIsEnabled = enable;
+ if (mIsEnabled != enable) {
+ mIsEnabled = enable;
+ mWaitCV.notify_all();
+ }
+}
+
+void Sensor::startThread(Sensor* sensor) {
+ sensor->run();
+}
+
+void Sensor::run() {
+ std::mutex runMutex;
+ std::unique_lock<std::mutex> runLock(runMutex);
+ constexpr int64_t kNanosecondsInSeconds = 1000 * 1000 * 1000;
+
+ while (!mStopThread) {
+ if (!mIsEnabled) {
+ mWaitCV.wait(runLock, [&] { return mIsEnabled || 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());
+ }
+
+ mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now));
+ }
+ }
+}
+
+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 = 1;
+ event.u.vec3.y = 2;
+ event.u.vec3.z = 3;
+ event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
+ events.push_back(event);
+ return events;
}
} // namespace implementation
} // namespace V2_0
} // namespace sensors
} // namespace hardware
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/sensors/2.0/default/Sensor.h b/sensors/2.0/default/Sensor.h
index 46026a4..21ad10d 100644
--- a/sensors/2.0/default/Sensor.h
+++ b/sensors/2.0/default/Sensor.h
@@ -19,7 +19,14 @@
#include <android/hardware/sensors/1.0/types.h>
+#include <condition_variable>
+#include <memory>
+#include <thread>
+#include <vector>
+
+using ::android::hardware::sensors::V1_0::Event;
using ::android::hardware::sensors::V1_0::SensorInfo;
+using ::android::hardware::sensors::V1_0::SensorType;
namespace android {
namespace hardware {
@@ -27,18 +34,36 @@
namespace V2_0 {
namespace implementation {
+class ISensorsEventCallback {
+ public:
+ virtual ~ISensorsEventCallback(){};
+ virtual void postEvents(const std::vector<Event>& events) = 0;
+};
+
class Sensor {
public:
- Sensor();
+ Sensor(ISensorsEventCallback* callback);
+ virtual ~Sensor();
const SensorInfo& getSensorInfo() const;
- bool batch(int32_t samplingPeriodNs);
+ void batch(int32_t samplingPeriodNs);
void activate(bool enable);
protected:
+ void run();
+ virtual std::vector<Event> readEvents();
+ static void startThread(Sensor* sensor);
+
bool mIsEnabled;
int64_t mSamplingPeriodNs;
+ int64_t mLastSampleTimeNs;
SensorInfo mSensorInfo;
+
+ std::atomic_bool mStopThread;
+ std::condition_variable mWaitCV;
+ std::thread mRunThread;
+
+ ISensorsEventCallback* mCallback;
};
} // namespace implementation
@@ -47,4 +72,4 @@
} // namespace hardware
} // namespace android
-#endif // ANDROID_HARDWARE_SENSORS_V2_0_SENSOR_H
\ No newline at end of file
+#endif // ANDROID_HARDWARE_SENSORS_V2_0_SENSOR_H
diff --git a/sensors/2.0/default/Sensors.cpp b/sensors/2.0/default/Sensors.cpp
index 29721fa..f0b02c3 100644
--- a/sensors/2.0/default/Sensors.cpp
+++ b/sensors/2.0/default/Sensors.cpp
@@ -100,12 +100,12 @@
Return<Result> Sensors::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
int64_t /* maxReportLatencyNs */) {
- Result result = Result::BAD_VALUE;
auto sensor = mSensors.find(sensorHandle);
- if (sensor != mSensors.end() && sensor->second->batch(samplingPeriodNs)) {
- result = Result::OK;
+ if (sensor != mSensors.end()) {
+ sensor->second->batch(samplingPeriodNs);
+ return Result::OK;
}
- return result;
+ return Result::BAD_VALUE;
}
Return<Result> Sensors::flush(int32_t /* sensorHandle */) {
@@ -134,6 +134,17 @@
return Return<void>();
}
+void Sensors::postEvents(const std::vector<Event>& events) {
+ std::lock_guard<std::mutex> l(mLock);
+
+ // TODO: read events from the Wake Lock FMQ in the right place
+ std::vector<uint32_t> tmp(mWakeLockQueue->availableToRead());
+ mWakeLockQueue->read(tmp.data(), mWakeLockQueue->availableToRead());
+
+ mEventQueue->write(events.data(), events.size());
+ mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
+}
+
void Sensors::deleteEventFlag() {
status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag);
if (status != OK) {
diff --git a/sensors/2.0/default/Sensors.h b/sensors/2.0/default/Sensors.h
index 64ee5c5..f543935 100644
--- a/sensors/2.0/default/Sensors.h
+++ b/sensors/2.0/default/Sensors.h
@@ -43,7 +43,7 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
-struct Sensors : public ISensors {
+struct Sensors : public ISensors, public ISensorsEventCallback {
using Event = ::android::hardware::sensors::V1_0::Event;
using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
@@ -80,6 +80,8 @@
Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
configDirectReport_cb _hidl_cb) override;
+ void postEvents(const std::vector<Event>& events) override;
+
private:
/**
* Utility function to delete the Event Flag
@@ -113,6 +115,11 @@
* A map of the available sensors
*/
std::map<int32_t, std::shared_ptr<Sensor>> mSensors;
+
+ /**
+ * Lock to protect writes and reads to the FMQs
+ */
+ std::mutex mLock;
};
} // namespace implementation