~aleteoryx/muditaos

399acf823cf11d720c149ccdfdcbbd95e087a6b1 — Wojtek Rzepecki 4 years ago c2e45b0
[EGD-6672] Fix missing key after slider

Fix of not working key press right after
slider movement or disconnecting tethtering
M module-bsp/board/linux/keyboard/keyboard.cpp => module-bsp/board/linux/keyboard/keyboard.cpp +54 -32
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

/*


@@ 27,52 27,74 @@

namespace bsp
{
    namespace
    {
        TaskHandle_t linux_keyboard_worker_handle = nullptr;

    static TaskHandle_t linux_keyboard_worker_handle = NULL;
        uint8_t kcode  = 0;
        uint8_t kevent = 0;

    static uint8_t kcode  = 0;
    static uint8_t kevent = 0;
        int fd;

    static int fd;
        bool handleSliderKey()
        {
            bool breakIfSliderReleased = false;
            if (kcode == static_cast<uint8_t>(bsp::KeyCodes::SSwitchUp) ||
                kcode == static_cast<uint8_t>(bsp::KeyCodes::SSwitchMid) ||
                kcode == static_cast<uint8_t>(bsp::KeyCodes::SSwitchDown)) {
                if (kevent == static_cast<uint8_t>(bsp::KeyEvents::Pressed)) {
                    kevent = static_cast<uint8_t>(bsp::KeyEvents::Moved);
                }
                else {
                    breakIfSliderReleased = true;
                }
            }
            return breakIfSliderReleased;
        }

    static void linux_keyboard_worker(void *pvp)
    {
        void linux_keyboard_worker(void *pvp)
        {

        const char *myfifo = "/tmp/myfifo3";
            const char *myfifo = "/tmp/myfifo3";

        // Creating the named file(FIFO)
        // mkfifo(<pathname>, <permission>)
        mkfifo(myfifo, 0666);
            // Creating the named file(FIFO)
            // mkfifo(<pathname>, <permission>)
            mkfifo(myfifo, 0666);

        // Open FIFO for write only
        fd = open(myfifo, O_RDONLY | O_NONBLOCK);
            // Open FIFO for write only
            fd = open(myfifo, O_RDONLY | O_NONBLOCK);

        while (1) {
            uint8_t buff[10];
            int32_t readedBytes = read(fd, buff, 10);
            while (1) {
                uint8_t buff[10];
                int32_t readedBytes = read(fd, buff, 10);

            if (readedBytes > 1) {
                kevent = buff[0];
                kcode  = buff[1];
                if (readedBytes > 1) {
                    kevent = buff[0];
                    kcode  = buff[1];

                xQueueHandle qhandle = reinterpret_cast<xQueueHandle>(pvp);
                    xQueueHandle qhandle = reinterpret_cast<xQueueHandle>(pvp);

                uint8_t notification = 0;
                if (kcode == static_cast<uint8_t>(bsp::KeyCodes::FnRight)) {
                    if (kevent == static_cast<uint8_t>(bsp::KeyEvents::Pressed))
                        notification = 0x02;
                    uint8_t notification = 0;
                    if (kcode == static_cast<uint8_t>(bsp::KeyCodes::FnRight)) {
                        if (kevent == static_cast<uint8_t>(bsp::KeyEvents::Pressed))
                            notification = 0x02;
                        else
                            notification = 0x04;
                    }
                    else
                        notification = 0x04;
                        notification = 0x01;

                    if (handleSliderKey()) {
                        break;
                    }
                    xQueueSend(qhandle, &notification, 100);
                }
                else
                    notification = 0x01;
                xQueueSend(qhandle, &notification, 100);
                vTaskDelay(50);
            }
            vTaskDelay(50);
        }

        close(fd);
    }
            close(fd);
        }
    } // namespace

    void keyboard_get_data(const uint8_t &notification, uint8_t &event, uint8_t &code)
    {

M module-bsp/bsp/common.hpp => module-bsp/bsp/common.hpp +1 -1
@@ 15,7 15,7 @@ namespace bsp
    enum class KeyEvents{
        Released,
        Pressed,

        Moved,
    };

    /// CPU frequency is dependent on the clock settings.

M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +48 -31
@@ 19,12 19,11 @@
#include <SystemManager/Constants.hpp>
#include <SystemManager/SystemManager.hpp>
#include <bsp/common.hpp>
#include <bsp/keyboard/key_codes.hpp>
#include <bsp/magnetometer/magnetometer.hpp>
#include <bsp/rtc/rtc.hpp>
#include <bsp/torch/torch.hpp>
#include <bsp/battery-charger/battery_charger.hpp>
#include <common_data/RawKey.hpp>
#include <bsp/keyboard/key_codes.hpp>
#include <log.hpp>
#include <Logger.hpp>
#include <service-appmgr/Controller.hpp>


@@ 51,6 50,14 @@ namespace
{
    constexpr auto loggerDelayMs   = 1000 * 60 * 5;
    constexpr auto loggerTimerName = "Logger";
    constexpr std::array sliderKeyCodes = {
        bsp::KeyCodes::SSwitchUp, bsp::KeyCodes::SSwitchMid, bsp::KeyCodes::SSwitchDown};

    [[nodiscard]] bool isSliderKeyCode(bsp::KeyCodes code)
    {
        return std::find(std::begin(sliderKeyCodes), std::end(sliderKeyCodes), code) != std::end(sliderKeyCodes);
    }

} // namespace

EventManager::EventManager(const std::string &name)


@@ 95,35 102,6 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy
    else if (msgl->messageType == MessageType::EVM_GPIO) {
        LOG_DEBUG("EVM_GPIO msg");
    }
    else if (msgl->messageType == MessageType::KBDKeyEvent &&
             (msgl->sender == this->GetName() || msgl->sender == service::name::service_desktop)) {

        auto *msg = dynamic_cast<sevm::KbdMessage *>(msgl);
        assert(msg);
        auto message = std::make_shared<sevm::KbdMessage>();
        message->key = msg->key;

        if (message->key.state == RawKey::State::Pressed) {
            const auto code = message->key.key_code;
            if (code == bsp::KeyCodes::FnRight) {
                bus.sendUnicast(message, service::name::system_manager);
            }
            else if (code == bsp::KeyCodes::SSwitchUp || code == bsp::KeyCodes::SSwitchMid ||
                     code == bsp::KeyCodes::SSwitchDown) {
                const auto mode = sys::SystemManager::translateSliderState(message->key);
                bus.sendUnicast(std::make_shared<sys::PhoneModeRequest>(mode), service::name::system_manager);
            }
            backlightHandler.handleKeyPressed();
        }

        // send key to focused application
        if (!targetApplication.empty()) {
            bus.sendUnicast(message, targetApplication);
        }
        // notify application manager to prevent screen locking
        app::manager::Controller::preventBlockingDevice(this);
        handled = true;
    }
    else if (msgl->messageType == MessageType::EVMFocusApplication) {
        auto *msg = static_cast<sevm::EVMFocusApplication *>(msgl);
        if (msg->sender == "ApplicationManager") {


@@ 190,6 168,11 @@ sys::ReturnCodes EventManager::InitHandler()
        return std::make_shared<sys::ResponseMessage>();
    });

    connect(sevm::KbdMessage(), [&](sys::Message *msg) {
        handleKeyEvent(msg);
        return std::make_shared<sys::ResponseMessage>();
    });

    connect(app::AppInputEventMessage(gui::InputEvent(RawKey())), [&](sys::Message *msgl) {
        auto msg = static_cast<app::AppInputEventMessage *>(msgl);
        assert(msg);


@@ 359,6 342,40 @@ bool EventManager::messageSetApplication(sys::Service *sender, const std::string
    return sender->bus.sendUnicast(msg, service::name::evt_manager);
}

void EventManager::handleKeyEvent(sys::Message *msg)
{
    auto kbdMessage = dynamic_cast<sevm::KbdMessage *>(msg);
    auto message    = std::make_shared<sevm::KbdMessage>();
    message->key    = kbdMessage->key;

    if (message->key.state == RawKey::State::Pressed) {
        const auto code = message->key.key_code;
        if (code == bsp::KeyCodes::FnRight) {
            bus.sendUnicast(message, service::name::system_manager);
        }
        backlightHandler.handleKeyPressed();
    }
    else if (message->key.state == RawKey::State::Moved) {
        handleKeyMoveEvent(message->key);
        backlightHandler.handleKeyPressed();
    }

    // send key to focused application
    if (!targetApplication.empty()) {
        bus.sendUnicast(message, targetApplication);
    }
    // notify application manager to prevent screen locking
    app::manager::Controller::preventBlockingDevice(this);
}

void EventManager::handleKeyMoveEvent(RawKey key)
{
    if (isSliderKeyCode(key.key_code)) {
        const auto mode = sys::SystemManager::translateSliderState(key);
        bus.sendUnicast(std::make_shared<sys::PhoneModeRequest>(mode), service::name::system_manager);
    }
}

void EventManager::dumpLogsToFile()
{
    const auto logPath = purefs::dir::getUserDiskPath() / LOG_FILE_NAME;

M module-services/service-evtmgr/WorkerEvent.cpp => module-services/service-evtmgr/WorkerEvent.cpp +11 -13
@@ 264,34 264,32 @@ void WorkerEvent::processKeyEvent(bsp::KeyEvents event, bsp::KeyCodes code)

    message->key.key_code = code;

    if (event == bsp::KeyEvents::Pressed) {
    switch (event) {
    case bsp::KeyEvents::Pressed:
        if (lastState == bsp::KeyEvents::Pressed) {
            return;
        }

        message->key.state      = RawKey::State::Pressed;
        message->key.time_press = xTaskGetTickCount();

        // Slider sends only press, not release state so it would block the entire keyboard
        if ((code != bsp::KeyCodes::SSwitchUp) && (code != bsp::KeyCodes::SSwitchMid) &&
            (code != bsp::KeyCodes::SSwitchDown)) {
            lastPressed = code;
            lastState   = event;
        }
    }
    else {
        lastPressed             = code;
        lastState               = event;
        break;
    case bsp::KeyEvents::Released:
        if (lastState != bsp::KeyEvents::Pressed) {
            return;
        }
        if (lastPressed != code) {
            return;
        }

        lastState = bsp::KeyEvents::Released;
        {
            message->key.state        = RawKey::State::Released;
            message->key.time_release = xTaskGetTickCount();
        }
        break;
    case bsp::KeyEvents::Moved:
        message->key.state = RawKey::State::Moved;
        break;
    }
    service->bus.sendUnicast(message, service::name::evt_manager);
}


@@ 306,7 304,7 @@ void WorkerEvent::handleMagnetometerEvent()
{
    if (const auto &key = bsp::magnetometer::WorkerEventHandler(); key.has_value()) {
        LOG_DEBUG("magneto IRQ handler: %s", c_str(*key));
        processKeyEvent(bsp::KeyEvents::Pressed, *key);
        processKeyEvent(bsp::KeyEvents::Moved, *key);
    }
}


M module-services/service-evtmgr/service-evtmgr/EventManager.hpp => module-services/service-evtmgr/service-evtmgr/EventManager.hpp +3 -0
@@ 14,6 14,7 @@
#include <Timers/TimerHandle.hpp>
#include <Service/Worker.hpp>
#include <service-db/DBServiceName.hpp>
#include <common_data/RawKey.hpp>

#include <cstdint>
#include <memory>


@@ 31,6 32,8 @@ class EventManager : public sys::Service
{
  private:
    static constexpr auto stackDepth = 4096;
    void handleKeyEvent(sys::Message *msg);
    void handleKeyMoveEvent(RawKey key);
    void handleMinuteUpdate(time_t timestamp);
    bool processVibraRequest(bsp::vibrator::Action act,
                             std::chrono::milliseconds RepetitionTime = std::chrono::milliseconds{1000});

M module-utils/common_data/RawKey.hpp => module-utils/common_data/RawKey.hpp +3 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 20,7 20,8 @@ struct RawKey
        Undefined,
        Pressed,
        Released,
    } state                = State::Undefined;
        Moved,
    } state                   = State::Undefined;
    bsp::KeyCodes key_code = bsp::KeyCodes::Undefined;
    unsigned int time_press   = 0;
    unsigned int time_release = 0;