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

Commit 8f285d98 authored by Mark Wheatley's avatar Mark Wheatley
Browse files

Add HAL Bypass Data Injection mode to Sensor Service

Add a new mode, HAL_BYPASS_REPLAY_DATA_INJECTION, which behaves similar
to Replay Data Injection with the difference that injected sensor data
is not injected into the HAL but simply passed back up to clients in
the platform.

Also, while I was in there, hook up the remaining bits and bobs to get
Replay Data Injection working and accessible from APIs in
SystemSensorManager in the platform.

Bug: 287257057
Test: manual
Change-Id: I9fc33a8bf5b67c02483089f849ba7ff0346d8097
(cherry picked from commit b0df44e2a6a40fb70a6e98a1e4e629945995a5f6)
parent ca7ea7b9
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ enum {
    CREATE_SENSOR_DIRECT_CONNECTION,
    SET_OPERATION_PARAMETER,
    GET_RUNTIME_SENSOR_LIST,
    ENABLE_REPLAY_DATA_INJECTION,
    ENABLE_HAL_BYPASS_REPLAY_DATA_INJECTION,
};

class BpSensorServer : public BpInterface<ISensorServer>
@@ -162,6 +164,20 @@ public:
        return reply.readInt32();
    }

    virtual int isReplayDataInjectionEnabled() {
        Parcel data, reply;
        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
        remote()->transact(ENABLE_REPLAY_DATA_INJECTION, data, &reply);
        return reply.readInt32();
    }

    virtual int isHalBypassReplayDataInjectionEnabled() {
        Parcel data, reply;
        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
        remote()->transact(ENABLE_HAL_BYPASS_REPLAY_DATA_INJECTION, data, &reply);
        return reply.readInt32();
    }

    virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
            int deviceId, uint32_t size, int32_t type, int32_t format,
            const native_handle_t *resource) {
@@ -237,6 +253,18 @@ status_t BnSensorServer::onTransact(
            reply->writeInt32(static_cast<int32_t>(ret));
            return NO_ERROR;
        }
        case ENABLE_REPLAY_DATA_INJECTION: {
            CHECK_INTERFACE(ISensorServer, data, reply);
            int32_t ret = isReplayDataInjectionEnabled();
            reply->writeInt32(static_cast<int32_t>(ret));
            return NO_ERROR;
        }
        case ENABLE_HAL_BYPASS_REPLAY_DATA_INJECTION: {
            CHECK_INTERFACE(ISensorServer, data, reply);
            int32_t ret = isHalBypassReplayDataInjectionEnabled();
            reply->writeInt32(static_cast<int32_t>(ret));
            return NO_ERROR;
        }
        case GET_DYNAMIC_SENSOR_LIST: {
            CHECK_INTERFACE(ISensorServer, data, reply);
            const String16& opPackageName = data.readString16();
+16 −0
Original line number Diff line number Diff line
@@ -310,6 +310,22 @@ bool SensorManager::isDataInjectionEnabled() {
    return false;
}

bool SensorManager::isReplayDataInjectionEnabled() {
    Mutex::Autolock _l(mLock);
    if (assertStateLocked() == NO_ERROR) {
        return mSensorServer->isReplayDataInjectionEnabled();
    }
    return false;
}

bool SensorManager::isHalBypassReplayDataInjectionEnabled() {
    Mutex::Autolock _l(mLock);
    if (assertStateLocked() == NO_ERROR) {
        return mSensorServer->isHalBypassReplayDataInjectionEnabled();
    }
    return false;
}

int SensorManager::createDirectChannel(
        size_t size, int channelType, const native_handle_t *resourceHandle) {
    static constexpr int DEFAULT_DEVICE_ID = 0;
+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ public:
    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
             int mode, const String16& opPackageName, const String16& attributionTag) = 0;
    virtual int32_t isDataInjectionEnabled() = 0;
    virtual int32_t isReplayDataInjectionEnabled() = 0;
    virtual int32_t isHalBypassReplayDataInjectionEnabled() = 0;

    virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
            int deviceId, uint32_t size, int32_t type, int32_t format,
+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ public:
    sp<SensorEventQueue> createEventQueue(
        String8 packageName = String8(""), int mode = 0, String16 attributionTag = String16(""));
    bool isDataInjectionEnabled();
    bool isReplayDataInjectionEnabled();
    bool isHalBypassReplayDataInjectionEnabled();
    int createDirectChannel(size_t size, int channelType, const native_handle_t *channelData);
    int createDirectChannel(
        int deviceId, size_t size, int channelType, const native_handle_t *channelData);
+58 −6
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
#include <cinttypes>
#include <cstddef>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace android::hardware::sensors;
using android::util::ProtoOutputStream;
@@ -352,6 +354,9 @@ ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
    if (mHalWrapper == nullptr) return NO_INIT;

    ssize_t eventsRead = 0;
    if (mInHalBypassMode) [[unlikely]] {
        eventsRead = getHalBypassInjectedEvents(buffer, count);
    } else {
        if (mHalWrapper->supportsMessageQueues()) {
            eventsRead = mHalWrapper->pollFmq(buffer, count);
        } else if (mHalWrapper->supportsPolling()) {
@@ -360,6 +365,7 @@ ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
            ALOGE("Must support polling or FMQ");
            eventsRead = -1;
        }
    }

    if (eventsRead > 0) {
        for (ssize_t i = 0; i < eventsRead; i++) {
@@ -762,11 +768,38 @@ status_t SensorDevice::injectSensorData(const sensors_event_t* injected_sensor_e
             injected_sensor_event->data[2], injected_sensor_event->data[3],
             injected_sensor_event->data[4], injected_sensor_event->data[5]);

    if (mInHalBypassMode) {
        std::lock_guard _l(mHalBypassLock);
        mHalBypassInjectedEventQueue.push(*injected_sensor_event);
        mHalBypassCV.notify_one();
        return OK;
    }
    return mHalWrapper->injectSensorData(injected_sensor_event);
}

status_t SensorDevice::setMode(uint32_t mode) {
    if (mHalWrapper == nullptr) return NO_INIT;
    if (mode == SensorService::Mode::HAL_BYPASS_REPLAY_DATA_INJECTION) {
        if (!mInHalBypassMode) {
            std::lock_guard _l(mHalBypassLock);
            while (!mHalBypassInjectedEventQueue.empty()) {
                // flush any stale events from the injected event queue
                mHalBypassInjectedEventQueue.pop();
            }
            mInHalBypassMode = true;
        }
        return OK;
    } else {
        if (mInHalBypassMode) {
            // We are transitioning out of HAL Bypass mode. We need to notify the reader thread
            // (specifically getHalBypassInjectedEvents()) of this change in state so that it is not
            // stuck waiting on more injected events to come and therefore preventing events coming
            // from the HAL from being read.
            std::lock_guard _l(mHalBypassLock);
            mInHalBypassMode = false;
            mHalBypassCV.notify_one();
        }
    }
    return mHalWrapper->setOperationMode(static_cast<SensorService::Mode>(mode));
}

@@ -872,5 +905,24 @@ float SensorDevice::getResolutionForSensor(int sensorHandle) {
    return 0;
}

ssize_t SensorDevice::getHalBypassInjectedEvents(sensors_event_t* buffer,
                                                 size_t maxNumEventsToRead) {
    std::unique_lock _l(mHalBypassLock);
    if (mHalBypassInjectedEventQueue.empty()) {
        // if the injected event queue is empty, block and wait till there are events to process
        // or if we are no longer in HAL Bypass mode so that this method is not called in a tight
        // loop. Otherwise, continue copying the injected events into the supplied buffer.
        mHalBypassCV.wait(_l, [this] {
            return (!mHalBypassInjectedEventQueue.empty() || !mInHalBypassMode);
        });
    }
    size_t eventsToRead = std::min(mHalBypassInjectedEventQueue.size(), maxNumEventsToRead);
    for (size_t i = 0; i < eventsToRead; i++) {
        buffer[i] = mHalBypassInjectedEventQueue.front();
        mHalBypassInjectedEventQueue.pop();
    }
    return eventsToRead;
}

// ---------------------------------------------------------------------------
}; // namespace android
Loading