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

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

Merge "Acquire and Release Wake Lock"

parents b0a219ae f2aca3b4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ cc_binary {
        "libhidlbase",
        "libhidltransport",
        "liblog",
        "libpower",
        "libutils",
    ],
}
+7 −3
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ Result Sensor::flush() {
    ev.sensorType = SensorType::ADDITIONAL_INFO;
    ev.u.meta.what = MetaDataEventType::META_DATA_FLUSH_COMPLETE;
    std::vector<Event> evs{ev};
    mCallback->postEvents(evs);
    mCallback->postEvents(evs, isWakeUpSensor());

    return Result::OK;
}
@@ -113,7 +113,7 @@ void Sensor::run() {
            if (now >= nextSampleTime) {
                mLastSampleTimeNs = now;
                nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
                mCallback->postEvents(readEvents());
                mCallback->postEvents(readEvents(), isWakeUpSensor());
            }

            mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now));
@@ -121,6 +121,10 @@ void Sensor::run() {
    }
}

bool Sensor::isWakeUpSensor() {
    return mSensorInfo.flags & static_cast<uint32_t>(SensorFlagBits::WAKE_UP);
}

std::vector<Event> Sensor::readEvents() {
    std::vector<Event> events;
    Event event;
@@ -155,7 +159,7 @@ Result Sensor::injectEvent(const Event& event) {
    } else if (!supportsDataInjection()) {
        result = Result::INVALID_OPERATION;
    } else if (mMode == OperationMode::DATA_INJECTION) {
        mCallback->postEvents(std::vector<Event>{event});
        mCallback->postEvents(std::vector<Event>{event}, isWakeUpSensor());
    } else {
        result = Result::BAD_VALUE;
    }
+3 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ namespace implementation {
class ISensorsEventCallback {
   public:
    virtual ~ISensorsEventCallback(){};
    virtual void postEvents(const std::vector<Event>& events) = 0;
    virtual void postEvents(const std::vector<Event>& events, bool wakeup) = 0;
};

class Sensor {
@@ -62,6 +62,8 @@ class Sensor {
    virtual std::vector<Event> readEvents();
    static void startThread(Sensor* sensor);

    bool isWakeUpSensor();

    bool mIsEnabled;
    int64_t mSamplingPeriodNs;
    int64_t mLastSampleTimeNs;
+74 −8
Original line number Diff line number Diff line
@@ -30,8 +30,16 @@ using ::android::hardware::sensors::V1_0::OperationMode;
using ::android::hardware::sensors::V1_0::RateLevel;
using ::android::hardware::sensors::V1_0::Result;
using ::android::hardware::sensors::V1_0::SharedMemInfo;
using ::android::hardware::sensors::V2_0::SensorTimeout;

Sensors::Sensors() : mEventQueueFlag(nullptr) {
constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP";

Sensors::Sensors()
    : mEventQueueFlag(nullptr),
      mOutstandingWakeUpEvents(0),
      mReadWakeLockQueueRun(false),
      mAutoReleaseWakeLockTime(0),
      mHasWakeLock(false) {
    std::shared_ptr<AccelSensor> accel =
        std::make_shared<AccelSensor>(1 /* sensorHandle */, this /* callback */);
    mSensors[accel->getSensorInfo().sensorHandle] = accel;
@@ -39,6 +47,8 @@ Sensors::Sensors() : mEventQueueFlag(nullptr) {

Sensors::~Sensors() {
    deleteEventFlag();
    mReadWakeLockQueueRun = false;
    mWakeLockThread.join();
}

// Methods from ::android::hardware::sensors::V2_0::ISensors follow.
@@ -101,6 +111,10 @@ Return<Result> Sensors::initialize(
        result = Result::BAD_VALUE;
    }

    // Start the thread to read events from the Wake Lock FMQ
    mReadWakeLockQueueRun = true;
    mWakeLockThread = std::thread(startReadWakeLockThread, this);

    return result;
}

@@ -147,15 +161,67 @@ 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);
void Sensors::postEvents(const std::vector<Event>& events, bool wakeup) {
    std::lock_guard<std::mutex> lock(mWriteLock);
    if (mEventQueue->write(events.data(), events.size())) {
        mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));

    // 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());
        if (wakeup) {
            // Keep track of the number of outstanding WAKE_UP events in order to properly hold
            // a wake lock until the framework has secured a wake lock
            updateWakeLock(events.size(), 0 /* eventsHandled */);
        }
    }
}

    mEventQueue->write(events.data(), events.size());
    mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
void Sensors::updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) {
    std::lock_guard<std::mutex> lock(mWakeLockLock);
    int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled;
    if (newVal < 0) {
        mOutstandingWakeUpEvents = 0;
    } else {
        mOutstandingWakeUpEvents = newVal;
    }

    if (eventsWritten > 0) {
        // Update the time at which the last WAKE_UP event was sent
        mAutoReleaseWakeLockTime = ::android::uptimeMillis() +
                                   static_cast<uint32_t>(SensorTimeout::WAKE_LOCK_SECONDS) * 1000;
    }

    if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 &&
        acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) {
        mHasWakeLock = true;
    } else if (mHasWakeLock) {
        // Check if the wake lock should be released automatically if
        // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written to
        // the Wake Lock FMQ.
        if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) {
            ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock",
                  SensorTimeout::WAKE_LOCK_SECONDS);
            mOutstandingWakeUpEvents = 0;
        }

        if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) {
            mHasWakeLock = false;
        }
    }
}

void Sensors::readWakeLockFMQ() {
    while (mReadWakeLockQueueRun.load()) {
        constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000;  // 500 ms
        uint32_t eventsHandled = 0;

        // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to ensure
        // that any held wake lock is able to be released if it is held for too long.
        mWakeLockQueue->readBlocking(&eventsHandled, 1 /* count */, kReadTimeoutNs);
        updateWakeLock(0 /* eventsWritten */, eventsHandled);
    }
}

void Sensors::startReadWakeLockThread(Sensors* sensors) {
    sensors->readWakeLockFMQ();
}

void Sensors::deleteEventFlag() {
+48 −3
Original line number Diff line number Diff line
@@ -21,10 +21,13 @@

#include <android/hardware/sensors/2.0/ISensors.h>
#include <fmq/MessageQueue.h>
#include <hardware_legacy/power.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>

#include <atomic>
#include <memory>
#include <thread>

namespace android {
namespace hardware {
@@ -80,7 +83,7 @@ struct Sensors : public ISensors, public ISensorsEventCallback {
    Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
                                    configDirectReport_cb _hidl_cb) override;

    void postEvents(const std::vector<Event>& events) override;
    void postEvents(const std::vector<Event>& events, bool wakeup) override;

   private:
    /**
@@ -88,6 +91,18 @@ struct Sensors : public ISensors, public ISensorsEventCallback {
     */
    void deleteEventFlag();

    /**
     * Function to read the Wake Lock FMQ and release the wake lock when appropriate
     */
    void readWakeLockFMQ();

    static void startReadWakeLockThread(Sensors* sensors);

    /**
     * Responsible for acquiring and releasing a wake lock when there are unhandled WAKE_UP events
     */
    void updateWakeLock(int32_t eventsWritten, int32_t eventsHandled);

    using EventMessageQueue = MessageQueue<Event, kSynchronizedReadWrite>;
    using WakeLockMessageQueue = MessageQueue<uint32_t, kSynchronizedReadWrite>;

@@ -117,9 +132,39 @@ struct Sensors : public ISensors, public ISensorsEventCallback {
    std::map<int32_t, std::shared_ptr<Sensor>> mSensors;

    /**
     * Lock to protect writes and reads to the FMQs
     * Lock to protect writes to the FMQs
     */
    std::mutex mWriteLock;

    /**
     * Lock to protect acquiring and releasing the wake lock
     */
    std::mutex mWakeLockLock;

    /**
     * Track the number of WAKE_UP events that have not been handled by the framework
     */
    uint32_t mOutstandingWakeUpEvents;

    /**
     * A thread to read the Wake Lock FMQ
     */
    std::thread mWakeLockThread;

    /**
     * Flag to indicate that the Wake Lock Thread should continue to run
     */
    std::atomic_bool mReadWakeLockQueueRun;

    /**
     * Track the time when the wake lock should automatically be released
     */
    int64_t mAutoReleaseWakeLockTime;

    /**
     * Flag to indicate if a wake lock has been acquired
     */
    std::mutex mLock;
    bool mHasWakeLock;
};

}  // namespace implementation