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

Commit fb4e33ac authored by Anthony Stange's avatar Anthony Stange
Browse files

Block dynamic connection event if sensor not found

A bug in the Sensors HIDL spec marks onDynamicSensorsConnected as oneway
which means that HALs are not blocked on the framework processing that
event. This means the onDynamicSensorsConnected invocation and dynamic
meta event can be received out of order. Blocking processing of the
event gives time for onDynamicSensorsConnected to be invoked so that the
event can be correctly processed.

Bug: 201529167
Test: Connect dynamic sensor and validate that the HAL can deliver the
event and method invocation without any sleeps on the HAL side.

Change-Id: Ie1cad22f26de60a7cecb3c6048280c4919165dbb
parent 979587e1
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -614,6 +614,8 @@ ssize_t SensorDevice::pollFmq(sensors_event_t* buffer, size_t maxNumEventsToRead

Return<void> SensorDevice::onDynamicSensorsConnected(
        const hidl_vec<SensorInfo> &dynamicSensorsAdded) {
    std::unique_lock<std::mutex> lock(mDynamicSensorsMutex);

    // Allocate a sensor_t structure for each dynamic sensor added and insert
    // it into the dictionary of connected dynamic sensors keyed by handle.
    for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
@@ -629,6 +631,8 @@ Return<void> SensorDevice::onDynamicSensorsConnected(
                std::make_pair(sensor->handle, sensor));
    }

    mDynamicSensorsCv.notify_all();

    return Return<void>();
}

@@ -1174,8 +1178,20 @@ void SensorDevice::convertToSensorEvent(
        dst->dynamic_sensor_meta.connected = dyn.connected;
        dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
        if (dyn.connected) {
            std::unique_lock<std::mutex> lock(mDynamicSensorsMutex);
            // Give MAX_DYN_SENSOR_WAIT_SEC for onDynamicSensorsConnected to be invoked since it
            // can be received out of order from this event due to a bug in the HIDL spec that
            // marks it as oneway.
            auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
            if (it == mConnectedDynamicSensors.end()) {
                mDynamicSensorsCv.wait_for(lock, MAX_DYN_SENSOR_WAIT,
                        [&, dyn]{
                            return mConnectedDynamicSensors.find(dyn.sensorHandle)
                                    != mConnectedDynamicSensors.end();
                });
                it = mConnectedDynamicSensors.find(dyn.sensorHandle);
                CHECK(it != mConnectedDynamicSensors.end());
            }

            dst->dynamic_sensor_meta.sensor = it->second;

+8 −0
Original line number Diff line number Diff line
@@ -139,6 +139,14 @@ private:
    Vector<sensor_t> mSensorList;
    std::unordered_map<int32_t, sensor_t*> mConnectedDynamicSensors;

    // A bug in the Sensors HIDL spec which marks onDynamicSensorsConnected as oneway causes dynamic
    // meta events and onDynamicSensorsConnected to be received out of order. This mutex + CV are
    // used to block meta event processing until onDynamicSensorsConnected is received to simplify
    // HAL implementations.
    std::mutex mDynamicSensorsMutex;
    std::condition_variable mDynamicSensorsCv;
    static constexpr std::chrono::seconds MAX_DYN_SENSOR_WAIT{5};

    static const nsecs_t MINIMUM_EVENTS_PERIOD =   1000000; // 1000 Hz
    mutable Mutex mLock; // protect mActivationCount[].batchParams
    // fixed-size array after construction