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 Original line Diff line number Diff line
@@ -43,6 +43,8 @@ enum {
    CREATE_SENSOR_DIRECT_CONNECTION,
    CREATE_SENSOR_DIRECT_CONNECTION,
    SET_OPERATION_PARAMETER,
    SET_OPERATION_PARAMETER,
    GET_RUNTIME_SENSOR_LIST,
    GET_RUNTIME_SENSOR_LIST,
    ENABLE_REPLAY_DATA_INJECTION,
    ENABLE_HAL_BYPASS_REPLAY_DATA_INJECTION,
};
};


class BpSensorServer : public BpInterface<ISensorServer>
class BpSensorServer : public BpInterface<ISensorServer>
@@ -162,6 +164,20 @@ public:
        return reply.readInt32();
        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,
    virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
            int deviceId, uint32_t size, int32_t type, int32_t format,
            int deviceId, uint32_t size, int32_t type, int32_t format,
            const native_handle_t *resource) {
            const native_handle_t *resource) {
@@ -237,6 +253,18 @@ status_t BnSensorServer::onTransact(
            reply->writeInt32(static_cast<int32_t>(ret));
            reply->writeInt32(static_cast<int32_t>(ret));
            return NO_ERROR;
            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: {
        case GET_DYNAMIC_SENSOR_LIST: {
            CHECK_INTERFACE(ISensorServer, data, reply);
            CHECK_INTERFACE(ISensorServer, data, reply);
            const String16& opPackageName = data.readString16();
            const String16& opPackageName = data.readString16();
+16 −0
Original line number Original line Diff line number Diff line
@@ -310,6 +310,22 @@ bool SensorManager::isDataInjectionEnabled() {
    return false;
    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(
int SensorManager::createDirectChannel(
        size_t size, int channelType, const native_handle_t *resourceHandle) {
        size_t size, int channelType, const native_handle_t *resourceHandle) {
    static constexpr int DEFAULT_DEVICE_ID = 0;
    static constexpr int DEFAULT_DEVICE_ID = 0;
+2 −0
Original line number Original line Diff line number Diff line
@@ -48,6 +48,8 @@ public:
    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
    virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
             int mode, const String16& opPackageName, const String16& attributionTag) = 0;
             int mode, const String16& opPackageName, const String16& attributionTag) = 0;
    virtual int32_t isDataInjectionEnabled() = 0;
    virtual int32_t isDataInjectionEnabled() = 0;
    virtual int32_t isReplayDataInjectionEnabled() = 0;
    virtual int32_t isHalBypassReplayDataInjectionEnabled() = 0;


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


using namespace android::hardware::sensors;
using namespace android::hardware::sensors;
using android::util::ProtoOutputStream;
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;
    if (mHalWrapper == nullptr) return NO_INIT;


    ssize_t eventsRead = 0;
    ssize_t eventsRead = 0;
    if (mInHalBypassMode) [[unlikely]] {
        eventsRead = getHalBypassInjectedEvents(buffer, count);
    } else {
        if (mHalWrapper->supportsMessageQueues()) {
        if (mHalWrapper->supportsMessageQueues()) {
            eventsRead = mHalWrapper->pollFmq(buffer, count);
            eventsRead = mHalWrapper->pollFmq(buffer, count);
        } else if (mHalWrapper->supportsPolling()) {
        } 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");
            ALOGE("Must support polling or FMQ");
            eventsRead = -1;
            eventsRead = -1;
        }
        }
    }


    if (eventsRead > 0) {
    if (eventsRead > 0) {
        for (ssize_t i = 0; i < eventsRead; i++) {
        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[2], injected_sensor_event->data[3],
             injected_sensor_event->data[4], injected_sensor_event->data[5]);
             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);
    return mHalWrapper->injectSensorData(injected_sensor_event);
}
}


status_t SensorDevice::setMode(uint32_t mode) {
status_t SensorDevice::setMode(uint32_t mode) {
    if (mHalWrapper == nullptr) return NO_INIT;
    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));
    return mHalWrapper->setOperationMode(static_cast<SensorService::Mode>(mode));
}
}


@@ -872,5 +905,24 @@ float SensorDevice::getResolutionForSensor(int sensorHandle) {
    return 0;
    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
}; // namespace android
Loading