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