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

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

Merge "Process runtime sensor events in a separate thread." into main

parents b01174f0 60ed8366
Loading
Loading
Loading
Loading
+65 −30
Original line number Diff line number Diff line
@@ -63,8 +63,10 @@
#include <sys/types.h>
#include <unistd.h>

#include <condition_variable>
#include <ctime>
#include <future>
#include <mutex>
#include <string>

#include <private/android_filesystem_config.h>
@@ -196,6 +198,16 @@ int SensorService::registerRuntimeSensor(
    if (mRuntimeSensorCallbacks.find(deviceId) == mRuntimeSensorCallbacks.end()) {
        mRuntimeSensorCallbacks.emplace(deviceId, callback);
    }

    if (mRuntimeSensorHandler == nullptr) {
        mRuntimeSensorEventBuffer =
                new sensors_event_t[SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT];
        mRuntimeSensorHandler = new RuntimeSensorHandler(this);
        // Use PRIORITY_URGENT_DISPLAY as the injected sensor events should be dispatched as soon as
        // possible, and also for consistency within the SensorService.
        mRuntimeSensorHandler->run("RuntimeSensorHandler", PRIORITY_URGENT_DISPLAY);
    }

    return handle;
}

@@ -232,8 +244,9 @@ status_t SensorService::unregisterRuntimeSensor(int handle) {
}

status_t SensorService::sendRuntimeSensorEvent(const sensors_event_t& event) {
    Mutex::Autolock _l(mLock);
    std::unique_lock<std::mutex> lock(mRutimeSensorThreadMutex);
    mRuntimeSensorEventQueue.push(event);
    mRuntimeSensorsCv.notify_all();
    return OK;
}

@@ -458,6 +471,7 @@ void SensorService::onFirstRef() {
            const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
            mSensorEventBuffer = new sensors_event_t[minBufferSize];
            mSensorEventScratch = new sensors_event_t[minBufferSize];
            mRuntimeSensorEventBuffer = nullptr;
            mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize];
            mCurrentOperatingMode = NORMAL;

@@ -1089,7 +1103,6 @@ bool SensorService::threadLoop() {
        recordLastValueLocked(mSensorEventBuffer, count);

        // handle virtual sensors
        bool bufferNeedsSorting = false;
        if (count && vcount) {
            sensors_event_t const * const event = mSensorEventBuffer;
            if (!mActiveVirtualSensors.empty()) {
@@ -1125,35 +1138,9 @@ bool SensorService::threadLoop() {
                    // record the last synthesized values
                    recordLastValueLocked(&mSensorEventBuffer[count], k);
                    count += k;
                    bufferNeedsSorting = true;
                }
            }
        }

        // handle runtime sensors
        {
            size_t k = 0;
            while (!mRuntimeSensorEventQueue.empty()) {
                if (count + k >= minBufferSize) {
                    ALOGE("buffer too small to hold all events: count=%zd, k=%zu, size=%zu",
                          count, k, minBufferSize);
                    break;
                }
                mSensorEventBuffer[count + k] = mRuntimeSensorEventQueue.front();
                mRuntimeSensorEventQueue.pop();
                k++;
            }
            if (k) {
                // record the last synthesized values
                recordLastValueLocked(&mSensorEventBuffer[count], k);
                count += k;
                bufferNeedsSorting = true;
                    sortEventBuffer(mSensorEventBuffer, count);
                }
            }

        if (bufferNeedsSorting) {
            // sort the buffer by time-stamps
            sortEventBuffer(mSensorEventBuffer, count);
        }

        // handle backward compatibility for RotationVector sensor
@@ -1253,6 +1240,46 @@ bool SensorService::threadLoop() {
    return false;
}

void SensorService::processRuntimeSensorEvents() {
    size_t count = 0;
    const size_t maxBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;

    {
        std::unique_lock<std::mutex> lock(mRutimeSensorThreadMutex);

        if (mRuntimeSensorEventQueue.empty()) {
            mRuntimeSensorsCv.wait(lock, [this] { return !mRuntimeSensorEventQueue.empty(); });
        }

        // Pop the events from the queue into the buffer until it's empty or the buffer is full.
        while (!mRuntimeSensorEventQueue.empty()) {
            if (count >= maxBufferSize) {
                ALOGE("buffer too small to hold all events: count=%zd, size=%zu", count,
                      maxBufferSize);
                break;
            }
            mRuntimeSensorEventBuffer[count] = mRuntimeSensorEventQueue.front();
            mRuntimeSensorEventQueue.pop();
            count++;
        }
    }

    if (count) {
        ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);

        recordLastValueLocked(mRuntimeSensorEventBuffer, count);
        sortEventBuffer(mRuntimeSensorEventBuffer, count);

        for (const sp<SensorEventConnection>& connection : connLock.getActiveConnections()) {
            connection->sendEvents(mRuntimeSensorEventBuffer, count, /* scratch= */ nullptr,
                                   /* mapFlushEventsToConnections= */ nullptr);
            if (connection->hasOneShotSensors()) {
                cleanupAutoDisabledSensorLocked(connection, mRuntimeSensorEventBuffer, count);
            }
        }
    }
}

sp<Looper> SensorService::getLooper() const {
    return mLooper;
}
@@ -1300,6 +1327,14 @@ bool SensorService::SensorEventAckReceiver::threadLoop() {
    return false;
}

bool SensorService::RuntimeSensorHandler::threadLoop() {
    ALOGD("new thread RuntimeSensorHandler");
    do {
        mService->processRuntimeSensorEvents();
    } while (!Thread::exitPending());
    return false;
}

void SensorService::recordLastValueLocked(
        const sensors_event_t* buffer, size_t count) {
    for (size_t i = 0; i < count; i++) {
+18 −1
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@

#include <stdint.h>
#include <sys/types.h>
#include <condition_variable>
#include <mutex>
#include <queue>
#include <unordered_map>
#include <unordered_set>
@@ -208,6 +210,7 @@ private:
    class SensorEventAckReceiver;
    class SensorRecord;
    class SensorRegistrationInfo;
    class RuntimeSensorHandler;

    // Promoting a SensorEventConnection or SensorDirectConnection from wp to sp must be done with
    // mLock held, but destroying that sp must be done unlocked to avoid a race condition that
@@ -264,6 +267,14 @@ private:
        SortedVector< wp<SensorDirectConnection> > mDirectConnections;
    };

    class RuntimeSensorHandler : public Thread {
        sp<SensorService> const mService;
    public:
        virtual bool threadLoop();
        explicit RuntimeSensorHandler(const sp<SensorService>& service) : mService(service) {
        }
    };

    // If accessing a sensor we need to make sure the UID has access to it. If
    // the app UID is idle then it cannot access sensors and gets no trigger
    // events, no on-change events, flush event behavior does not change, and
@@ -368,6 +379,8 @@ private:
    // Thread interface
    virtual bool threadLoop();

    void processRuntimeSensorEvents();

    // ISensorServer interface
    virtual Vector<Sensor> getSensorList(const String16& opPackageName);
    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName);
@@ -512,6 +525,10 @@ private:
    uint32_t mSocketBufferSize;
    sp<Looper> mLooper;
    sp<SensorEventAckReceiver> mAckReceiver;
    sp<RuntimeSensorHandler> mRuntimeSensorHandler;
    // Mutex and CV used to notify the mRuntimeSensorHandler thread that there are new events.
    std::mutex mRutimeSensorThreadMutex;
    std::condition_variable mRuntimeSensorsCv;

    // protected by mLock
    mutable Mutex mLock;
@@ -519,7 +536,7 @@ private:
    std::unordered_set<int> mActiveVirtualSensors;
    SensorConnectionHolder mConnectionHolder;
    bool mWakeLockAcquired;
    sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
    sensors_event_t *mSensorEventBuffer, *mSensorEventScratch, *mRuntimeSensorEventBuffer;
    // WARNING: these SensorEventConnection instances must not be promoted to sp, except via
    // modification to add support for them in ConnectionSafeAutolock
    wp<const SensorEventConnection> * mMapFlushEventsToConnections;