Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c7aa5023 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Generate events for default Sensors 2.0"

parents cad11764 237abc6c
Loading
Loading
Loading
Loading
+73 −10
Original line number Diff line number Diff line
@@ -16,31 +16,94 @@

#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) {
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;
    } else {
        success = false;
        // Wake up the 'run' thread to check if a new event should be generated now
        mWaitCV.notify_all();
    }
    return success;
}

void Sensor::activate(bool 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
+28 −3
Original line number Diff line number Diff line
@@ -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 sensors {
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
+15 −4
Original line number Diff line number Diff line
@@ -100,12 +100,12 @@ Return<Result> Sensors::initialize(

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<void> Sensors::configDirectReport(int32_t /* sensorHandle */, int32_t /*
    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) {
+8 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ using ::android::hardware::MQDescriptor;
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 @@ struct Sensors : public ISensors {
    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 @@ struct Sensors : public ISensors {
     * 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