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

Commit a28e921d authored by Brian Stack's avatar Brian Stack
Browse files

Read Sensor Events from Event FMQ

Read sensor events from the Event FMQ whenever the READ_AND_PROCESS
bitmask is set from the Sensors HAL on the Event FMQ.

Bug: 111070257
Test: Compile, configured system to use sensors@2.0 and ensured that
      a_sns_test received events

Change-Id: Iad6b9ef2dc691b8d4f8ba4ae294c1371273be0ba
parent 979887bc
Loading
Loading
Loading
Loading
+67 −2
Original line number Diff line number Diff line
@@ -13,11 +13,13 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "SensorDevice.h"

#include "android/hardware/sensors/2.0/types.h"
#include "SensorService.h"

#include <android-base/logging.h>
#include <sensor/SensorEventQueue.h>
#include <sensors/convert.h>
#include <cutils/atomic.h>
#include <utils/Errors.h>
@@ -30,6 +32,7 @@
using namespace android::hardware::sensors;
using namespace android::hardware::sensors::V1_0;
using namespace android::hardware::sensors::V1_0::implementation;
using android::hardware::sensors::V2_0::EventQueueFlagBits;
using android::hardware::hidl_vec;
using android::SensorDeviceUtils::HidlServiceRegistrationWaiter;

@@ -88,6 +91,13 @@ SensorDevice::SensorDevice()
           (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
}

SensorDevice::~SensorDevice() {
    if (mEventQueueFlag != nullptr) {
        hardware::EventFlag::deleteEventFlag(&mEventQueueFlag);
        mEventQueueFlag = nullptr;
    }
}

bool SensorDevice::connectHidlService() {
    HalConnectionStatus status = connectHidlServiceV2_0();
    if (status == HalConnectionStatus::DOES_NOT_EXIST) {
@@ -147,8 +157,10 @@ SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV2_0() {
                SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
                true /* configureEventFlagWord */);

        hardware::EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);

        CHECK(mSensors != nullptr && mEventQueue != nullptr &&
              mWakeLockQueue != nullptr);
                mWakeLockQueue != nullptr && mEventQueueFlag != nullptr);

        status_t status = StatusFromResult(checkReturn(mSensors->initializeMessageQueues(
                *mEventQueue->getDesc(),
@@ -222,6 +234,19 @@ status_t SensorDevice::initCheck() const {
}

ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
    ssize_t eventsRead = 0;
    if (mSensors->supportsMessageQueues()) {
        eventsRead = pollFmq(buffer, count);
    } else if (mSensors->supportsPolling()) {
        eventsRead = pollHal(buffer, count);
    } else {
        ALOGE("Must support polling or FMQ");
        eventsRead = -1;
    }
    return eventsRead;
}

ssize_t SensorDevice::pollHal(sensors_event_t* buffer, size_t count) {
    if (mSensors == nullptr) return NO_INIT;

    ssize_t err;
@@ -267,6 +292,46 @@ ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
    return err;
}

ssize_t SensorDevice::pollFmq(sensors_event_t* buffer, size_t maxNumEventsToRead) {
    if (mSensors == nullptr) {
        return NO_INIT;
    }

    ssize_t eventsRead = 0;
    size_t availableEvents = mEventQueue->availableToRead();

    if (availableEvents == 0) {
        uint32_t eventFlagState = 0;

        // Wait for events to become available. This is necessary so that the Event FMQ's read() is
        // able to be called with the correct number of events to read. If the specified number of
        // events is not available, then read() would return no events, possibly introducing
        // additional latency in delivering events to applications.
        mEventQueueFlag->wait(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS),
                              &eventFlagState);
        availableEvents = mEventQueue->availableToRead();

        if (availableEvents == 0) {
            ALOGW("Event FMQ wake without any events");
        }
    }

    size_t eventsToRead = std::min({availableEvents, maxNumEventsToRead, mEventBuffer.size()});
    if (eventsToRead > 0) {
        if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
            for (size_t i = 0; i < eventsToRead; i++) {
                convertToSensorEvent(mEventBuffer[i], &buffer[i]);
            }
            eventsRead = eventsToRead;
        } else {
            ALOGW("Failed to read %zu events, currently %zu events available",
                    eventsToRead, availableEvents);
        }
    }

    return eventsRead;
}

void SensorDevice::autoDisable(void *ident, int handle) {
    Mutex::Autolock _l(mLock);
    ssize_t activationIndex = mActivationCount.indexOfKey(handle);
+11 −0
Original line number Diff line number Diff line
@@ -22,12 +22,14 @@
#include "SensorsWrapper.h"

#include <fmq/MessageQueue.h>
#include <sensor/SensorEventQueue.h>
#include <sensor/Sensor.h>
#include <stdint.h>
#include <sys/types.h>
#include <utils/KeyedVector.h>
#include <utils/Singleton.h>
#include <utils/String8.h>
#include <utils/Timers.h>

#include <string>
#include <unordered_map>
@@ -69,6 +71,8 @@ public:
        int mCount;   // number of transport errors observed
    };

    ~SensorDevice();

    ssize_t getSensorList(sensor_t const** list);

    void handleDynamicSensorConnection(int handle, bool connected);
@@ -173,6 +177,9 @@ private:
    HalConnectionStatus connectHidlServiceV1_0();
    HalConnectionStatus connectHidlServiceV2_0();

    ssize_t pollHal(sensors_event_t* buffer, size_t count);
    ssize_t pollFmq(sensors_event_t* buffer, size_t count);

    static void handleHidlDeath(const std::string &detail);
    template<typename T>
    static Return<T> checkReturn(Return<T> &&ret) {
@@ -203,6 +210,10 @@ private:
    typedef hardware::MessageQueue<uint32_t, hardware::kSynchronizedReadWrite> WakeLockQueue;
    std::unique_ptr<EventMessageQueue> mEventQueue;
    std::unique_ptr<WakeLockQueue> mWakeLockQueue;

    hardware::EventFlag* mEventQueueFlag;

    std::array<Event, SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT> mEventBuffer;
};

// ---------------------------------------------------------------------------