~aleteoryx/muditaos

38ee9a224c38f022d8ff932f348a6a4acd13c5f7 — Michał Kamoń 5 years ago 84e08c2
[EGD-4452] unify desktop locks (#1071)

* [EGD-4452] Desktop locks refactored
M changelog.md => changelog.md +1 -0
@@ 20,6 20,7 @@

### Changed

* `[gui][desktop]` ScreenLock logic unified with simLock's
* `[messages]` Changed fonts of message snippet and its prefix.

## [0.47.1 2020-11-20]

M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +7 -3
@@ 33,12 33,12 @@ namespace app
        busChannels.push_back(sys::BusChannels::ServiceDBNotifications);

        addActionReceiver(app::manager::actions::RequestPin, [this](auto &&data) {
            lockHandler.handlePinRequest(std::move(data));
            lockHandler.handlePasscodeRequest(gui::PinLock::LockType::SimPin, std::move(data));
            return msgHandled();
        });

        addActionReceiver(app::manager::actions::RequestPuk, [this](auto &&data) {
            lockHandler.handlePukRequest(std::move(data));
            lockHandler.handlePasscodeRequest(gui::PinLock::LockType::SimPuk, std::move(data));
            return msgHandled();
        });



@@ 52,6 52,11 @@ namespace app
            return msgHandled();
        });

        addActionReceiver(app::manager::actions::UnlockSim, [this](auto &&data) {
            lockHandler.handleUnlockSim(std::move(data));
            return msgHandled();
        });

        addActionReceiver(app::manager::actions::DisplayCMEError, [this](auto &&data) {
            lockHandler.handleCMEError(std::move(data));
            return msgHandled();


@@ 257,7 262,6 @@ namespace app
        reloadSettings();
        requestNotReadNotifications();
        requestNotSeenNotifications();
        lockHandler.reloadScreenLock();

        createUserInterface();
        setActiveWindow(gui::name::window::main_window);

M module-apps/application-desktop/widgets/PinLock.cpp => module-apps/application-desktop/widgets/PinLock.cpp +4 -4
@@ 2,7 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PinLock.hpp"
#include "PinLockHandler.hpp"
#include <module-utils/log/log.hpp>

namespace gui
{


@@ 29,7 29,7 @@ namespace gui
            pinValue.push_back(c);
        }
        if (canVerify() && autoActivate && onActivatedCallback != nullptr) {
            onActivatedCallback(pinValue);
            onActivatedCallback(lockType, pinValue);
        }
    }



@@ 45,7 45,7 @@ namespace gui
        pinValue.clear();
    }

    void PinLock::verify()
    void PinLock::activate()
    {
        auto pinCopy = std::move(pinValue);
        clearAttempt();


@@ 53,6 53,6 @@ namespace gui
            LOG_ERROR("Passcode verification callback null");
            return;
        }
        onActivatedCallback(pinCopy);
        onActivatedCallback(lockType, pinCopy);
    }
} // namespace gui

M module-apps/application-desktop/widgets/PinLock.hpp => module-apps/application-desktop/widgets/PinLock.hpp +20 -11
@@ 6,6 6,8 @@
#include <string>
#include <functional>

#include <module-utils/common_data/EventStore.hpp>

namespace gui
{
    class PinLockHandler;


@@ 26,15 28,10 @@ namespace gui
            PasscodeInvalidRetryRequired,
            Blocked,
            NewPasscodeRequired,
            NewPasscodeConfirmRequired,
            NewPasscodeInvalid,
            ErrorOccurred
        };
        enum class SimCard
        {
            SIM1,
            SIM2,
            NoCard
        };

        [[nodiscard]] LockState getState() const noexcept
        {


@@ 69,6 66,18 @@ namespace gui
        {
            return value;
        }
        [[nodiscard]] bool isSim(Store::GSM::SIM _sim) const noexcept
        {
            return sim == _sim;
        }
        [[nodiscard]] bool isState(LockState state) const noexcept
        {
            return lockState == state;
        }
        [[nodiscard]] bool isType(LockType type) const noexcept
        {
            return lockType == type;
        }

        void putNextChar(unsigned int c);
        /// removes a last character passed to Lock via putNextChar. The last character can not be popped


@@ 78,18 87,18 @@ namespace gui
        /// consumes LockState::PasscodeInvalidRetryRequired state and LockState::NewPasscodeInvalid)
        void consumeState() noexcept;
        void setNewPasscodeInvalidState() noexcept;
        /// calls
        void activate();

        void verify();

        PinLock(SimCard sim, LockState state, LockType type, unsigned int value)
        PinLock(Store::GSM::SIM sim, LockState state, LockType type, unsigned int value)
            : sim{sim}, lockState{state}, lockType{type}, value{value}
        {}
        PinLock(const PinLock &other) = default;

        std::function<void(const std::vector<unsigned int> &)> onActivatedCallback = nullptr;
        std::function<void(LockType type, const std::vector<unsigned int> &)> onActivatedCallback = nullptr;

      private:
        SimCard sim         = SimCard::NoCard;
        Store::GSM::SIM sim = Store::GSM::SIM::NONE;
        LockState lockState = LockState::Unlocked;
        LockType lockType   = LockType::Screen;
        unsigned int value  = 0;

M module-apps/application-desktop/widgets/PinLockHandler.cpp => module-apps/application-desktop/widgets/PinLockHandler.cpp +176 -122
@@ 8,7 8,6 @@
#include "application-desktop/windows/Names.hpp"

#include <module-utils/common_data/EventStore.hpp>

#include <service-appmgr/service-appmgr/data/SimActionsParams.hpp>
#include <service-cellular/CellularMessage.hpp>



@@ 22,197 21,252 @@ namespace gui
        constexpr unsigned int blocked_sim_attempts    = 0;
        constexpr unsigned int sim_max_passcode_size   = 8;
        constexpr unsigned int sim_min_passcode_size   = 4;

        constexpr inline auto serviceCellular = "ServiceCellular";
    } // namespace

    PinLockHandler::PinLockHandler(app::ApplicationDesktop *app, SettingsRecord &settings)
        : app(app), appSettings(settings), screenLock(PinLock::SimCard::NoCard,
                                                      PinLock::LockState::PasscodeRequired,
                                                      PinLock::LockType::Screen,
                                                      default_attempts),
          simLock(PinLock::SimCard::NoCard, PinLock::LockState::Unlocked, PinLock::LockType::SimPin, default_attempts)
        : app(app), appSettings(settings),
          screenLock(
              Store::GSM::SIM::NONE, PinLock::LockState::PasscodeRequired, PinLock::LockType::Screen, default_attempts),
          simLock(Store::GSM::SIM::NONE, PinLock::LockState::Unlocked, PinLock::LockType::SimPin, default_attempts)
    {
        reloadScreenLock();
        screenLock.setAutoActivate(true);

        simLock.setPinSizeBounds(sim_min_passcode_size, sim_max_passcode_size);
        screenLock.setAutoActivate(true);
    }

    void PinLockHandler::handleScreenPin(const std::vector<unsigned int> &pin)
    {
        if (screenLock.getMaxPinSize() == screen_nopin_size) {
        std::hash<std::vector<unsigned int>> hashEngine;
        uint32_t hash = hashEngine(pin);
        screenLock.value--;
        if (hash == appSettings.lockPassHash) {
            screenLock.lockState = gui::PinLock::LockState::Unlocked;
            screenLock.value     = default_attempts;
        }
        else if (screenLock.value > 0) {
            std::hash<std::vector<unsigned int>> hashEngine;
            uint32_t hash = hashEngine(pin);
            screenLock.value--;
            if (hash == appSettings.lockPassHash) {
                screenLock.lockState = gui::PinLock::LockState::Unlocked;
                screenLock.value     = default_attempts;
            }
            else if (screenLock.value > 0) {
                screenLock.lockState = gui::PinLock::LockState::PasscodeInvalidRetryRequired;
            }
            else {
                screenLock.lockState = gui::PinLock::LockState::Blocked;
            }
            screenLock.lockState = gui::PinLock::LockState::PasscodeInvalidRetryRequired;
        }
        else {
            screenLock.lockState = gui::PinLock::LockState::Blocked;
        }
        unlock();
    }

    void PinLockHandler::handleScreenConfirm()
    void PinLockHandler::handlePasscodeParams(PinLock::LockType type,
                                              PinLock::LockState state,
                                              app::manager::actions::ActionParamsPtr &&data)
    {
        simLock.consumeState();
        auto passcodeData = static_cast<app::manager::actions::PasscodeParams *>(data.get());
        if (simLock.isSim(passcodeData->getSim()) && simLock.isType(type) && simLock.isState(state) &&
            simLock.getValue() > passcodeData->getAttempts()) {
            simLock.lockState = PinLock::LockState::PasscodeInvalidRetryRequired;
        }
        else {
            simLock.lockState = state;
            simLock.sim       = passcodeData->getSim();
            simLock.lockType  = type;
        }
        simLock.value = passcodeData->getAttempts();
    }

    void PinLockHandler::reloadScreenLock()
    void PinLockHandler::handlePasscodeRequest(PinLock::LockType type, app::manager::actions::ActionParamsPtr &&data)
    {
        screenLock.lockState = gui::PinLock::LockState::PasscodeRequired;
        unsigned int pinSize = appSettings.lockPassHash == 0 ? screen_nopin_size : default_screen_pin_size;
        screenLock.setPinSizeBounds(pinSize, pinSize);
        screenLock.value = default_attempts;
        LOG_DEBUG("Handling on of PasscodeRequest actions");
        handlePasscodeParams(type, PinLock::LockState::PasscodeRequired, std::move(data));
        if (!getStrongestLock().isType(PinLock::LockType::Screen)) {
            unlock();
        }
    }

    auto PinLockHandler::handlePasscodeParams(app::manager::actions::ActionParamsPtr &&data) const -> gui::PinLock
    void PinLockHandler::handlePinChangeRequest(app::manager::actions::ActionParamsPtr &&data)
    {
        auto passcodeData = static_cast<app::manager::actions::PasscodeParams *>(data.get());

        gui::PinLock lock(parseSimCard(passcodeData->getSim()),
                          gui::PinLock::LockState::PasscodeRequired,
                          simLock.getLockType(),
                          passcodeData->getAttempts());

        if (simLock.getLockType() == lock.getLockType() && simLock.getState() == lock.getState() &&
            simLock.getValue() > lock.getValue()) {
            lock.lockState = PinLock::LockState::PasscodeInvalidRetryRequired;
        }
        lock.setPinSizeBounds(sim_min_passcode_size, sim_max_passcode_size);

        return lock;
        LOG_DEBUG("Handling RequestPinChange action");
        handlePasscodeParams(PinLock::LockType::SimPin, PinLock::LockState::PasscodeRequired, std::move(data));
        promptSimLockWindow      = true;
        auto onActivatedCallback = [this](PinLock::LockType type, const std::vector<unsigned int> &data) {
            handlePasscodeChange(data);
        };
        switchToPinLockWindow(onActivatedCallback);
    }

    void PinLockHandler::handlePinRequest(app::manager::actions::ActionParamsPtr &&data)
    void PinLockHandler::handleSimBlocked(app::manager::actions::ActionParamsPtr &&data)
    {
        simLock          = handlePasscodeParams(std::move(data));
        simLock.lockType = gui::PinLock::LockType::SimPin;

        auto onActivatedCallback = [this](const std::vector<unsigned int> &data) { handlePasscode(data); };
        switchToPinlockWindow(onActivatedCallback);
        LOG_DEBUG("Handling BlockSim action");
        auto params         = static_cast<app::manager::actions::SimStateParams *>(data.get());
        promptSimLockWindow = true;
        simLock.sim         = params->getSim();
        simLock.lockState   = gui::PinLock::LockState::Blocked;
        simLock.lockType    = gui::PinLock::LockType::SimPin;
        simLock.value       = blocked_sim_attempts;
        unlock();
    }

    void PinLockHandler::handlePukRequest(app::manager::actions::ActionParamsPtr &&data)
    void PinLockHandler::handleUnlockSim(app::manager::actions::ActionParamsPtr &&data)
    {
        simLock          = handlePasscodeParams(std::move(data));
        simLock.lockType = gui::PinLock::LockType::SimPuk;

        auto onActivatedCallback = [this](const std::vector<unsigned int> &data) { handlePasscodeChange(data); };
        switchToPinlockWindow(onActivatedCallback);
        LOG_DEBUG("Handling UnlockSim action");
        simLock.lockState   = PinLock::LockState::Unlocked;
        promptSimLockWindow = false;
        unlock();
    }

    void PinLockHandler::switchToPinlockWindow(
        std::function<void(const std::vector<unsigned int> &)> onLockActivatedCallback)
    void PinLockHandler::handleCMEError(app::manager::actions::ActionParamsPtr &&data) const
    {
        auto lock = std::make_unique<gui::PinLock>(simLock);
        LOG_DEBUG("Handling DisplayCMEError action");
        auto params = static_cast<app::manager::actions::UnhandledCMEParams *>(data.get());
        auto lock   = std::make_unique<gui::PinLock>(
            params->getSim(), PinLock::LockState::ErrorOccurred, PinLock::LockType::SimPin, params->getCMECode());
        lock->onActivatedCallback = [this](PinLock::LockType type, const std::vector<unsigned int> &data) {
            app->switchWindow(app::window::name::desktop_main_window);
        };
        app->switchWindow(app::window::name::desktop_pin_lock,
                          gui::ShowMode::GUI_SHOW_INIT,
                          std::make_unique<gui::LockPhoneData>(std::move(lock)));
    }

        if (lock->getState() == PinLock::LockState::PasscodeInvalidRetryRequired) {
            lock->onActivatedCallback = [this, onLockActivatedCallback](const std::vector<unsigned int> &) {
                simLock.consumeState();
                switchToPinlockWindow(onLockActivatedCallback);
    void PinLockHandler::switchToPinLockWindow(
        std::function<void(PinLock::LockType, const std::vector<unsigned int> &)> onLockActivatedCallback)
    {
        auto lock = std::make_unique<gui::PinLock>(getStrongestLock());
        if (lock->isState(PinLock::LockState::PasscodeInvalidRetryRequired)) {
            lock->onActivatedCallback = [this, onLockActivatedCallback](PinLock::LockType,
                                                                        const std::vector<unsigned int> &) {
                getStrongestLock().consumeState();
                switchToPinLockWindow(onLockActivatedCallback);
            };
        }
        else if (lock->isState(gui::PinLock::LockState::Blocked)) {
            lock->onActivatedCallback = [this](PinLock::LockType type, const std::vector<unsigned int> &data) {
                setSimLockHandled();
                app->switchWindow(app::window::name::desktop_main_window);
            };
        }
        else if (lock->isState(gui::PinLock::LockState::Unlocked)) {
            setSimLockHandled();
            app->switchWindow(app::window::name::desktop_main_window);
            return;
        }
        else {
            lock->onActivatedCallback = onLockActivatedCallback;
        }

        app->switchWindow(app::window::name::desktop_pin_lock,
                          gui::ShowMode::GUI_SHOW_INIT,
                          std::make_unique<gui::LockPhoneData>(std::move(lock)));
    }

    void PinLockHandler::handlePinChangeRequest(app::manager::actions::ActionParamsPtr &&data)
    void PinLockHandler::switchToPinLockWindow(
        PinLock::LockState state,
        std::function<void(PinLock::LockType, const std::vector<unsigned int> &)> onLockActivatedCallback)
    {
        simLock          = handlePasscodeParams(std::move(data));
        simLock.lockType = gui::PinLock::LockType::SimPin;

        auto onActivatedCallback = [this](const std::vector<unsigned int> &data) { handlePasscodeChange(data); };
        switchToPinlockWindow(onActivatedCallback);
    }

    void PinLockHandler::handleSimBlocked(app::manager::actions::ActionParamsPtr &&data)
    {
        auto params = static_cast<app::manager::actions::SimStateParams *>(data.get());
        simLock     = PinLock(parseSimCard(params->getSim()),
                          gui::PinLock::LockState::Blocked,
                          gui::PinLock::LockType::SimPin,
                          blocked_sim_attempts);

        auto lock = std::make_unique<gui::PinLock>(simLock);
        auto lock                 = std::make_unique<gui::PinLock>(getStrongestLock());
        lock->lockState           = state;
        lock->onActivatedCallback = onLockActivatedCallback;
        app->switchWindow(app::window::name::desktop_pin_lock,
                          gui::ShowMode::GUI_SHOW_INIT,
                          std::make_unique<gui::LockPhoneData>(std::move(lock)));
    }

    void PinLockHandler::handleCMEError(app::manager::actions::ActionParamsPtr &&data) const
    void PinLockHandler::handlePasscode(PinLock::LockType type, const std::vector<unsigned int> passcode)
    {
        auto params = static_cast<app::manager::actions::UnhandledCMEParams *>(data.get());
        if (type == PinLock::LockType::SimPin) {
            setSimLockHandled();
            sys::Bus::SendUnicast(
                std::make_shared<CellularSimPinDataMessage>(simLock.sim, passcode), serviceCellular, app);
        }
        else if (type == PinLock::LockType::SimPuk) {
            handlePasscodeChange(passcode);
        }
        else if (type == PinLock::LockType::Screen) {
            handleScreenPin(passcode);
        }
    }

        auto lock = std::make_unique<gui::PinLock>(parseSimCard(params->getSim()),
                                                   PinLock::LockState::ErrorOccurred,
                                                   PinLock::LockType::SimPin,
                                                   params->getCMECode());
    void PinLockHandler::handlePasscodeChange(const std::vector<unsigned int> passcode)
    {
        auto onActivatedCallback = [this, passcode](PinLock::LockType, const std::vector<unsigned int> &pin) {
            handleNewPasscodeUnconfirmed(passcode, pin);
        };
        switchToPinLockWindow(PinLock::LockState::NewPasscodeRequired, onActivatedCallback);
    }

        app->switchWindow(app::window::name::desktop_pin_lock,
                          gui::ShowMode::GUI_SHOW_INIT,
                          std::make_unique<gui::LockPhoneData>(std::move(lock)));
    void PinLockHandler::handleNewPasscodeUnconfirmed(const std::vector<unsigned int> &passcode,
                                                      const std::vector<unsigned int> &pin)
    {
        auto onActivatedCallback = [this, passcode, pin](PinLock::LockType type,
                                                         const std::vector<unsigned int> &pinConfirmed) {
            if (pin == pinConfirmed) {
                handleNewPasscodeConfirmed(type, passcode, pin);
            }
            else {
                handleNewPasscodeInvalid(passcode);
            }
        };
        switchToPinLockWindow(PinLock::LockState::NewPasscodeConfirmRequired, onActivatedCallback);
    }

    void PinLockHandler::handlePasscode(const std::vector<unsigned int> passcode) const
    void PinLockHandler::handleNewPasscodeConfirmed(PinLock::LockType type,
                                                    const std::vector<unsigned int> &passcode,
                                                    const std::vector<unsigned int> &pin)
    {
        if (simLock.getLockType() == PinLock::LockType::SimPin) {
        setSimLockHandled();
        if (type == PinLock::LockType::SimPin) {
            sys::Bus::SendUnicast(
                std::make_shared<CellularSimPinDataMessage>(Store::GSM::SIM::SIM1, passcode), "ServiceCellular", app);
                std::make_shared<CellularSimNewPinDataMessage>(simLock.sim, passcode, pin), serviceCellular, app);
        }
        else if (simLock.getLockType() == PinLock::LockType::SimPuk) {
            handlePasscodeChange(passcode);
        else if (type == PinLock::LockType::SimPuk) {
            sys::Bus::SendUnicast(
                std::make_shared<CellularSimPukDataMessage>(simLock.sim, passcode, pin), serviceCellular, app);
        }
    }
    void PinLockHandler::handlePasscodeChange(const std::vector<unsigned int> passcode) const
    {
        auto lock       = std::make_unique<gui::PinLock>(simLock);
        lock->lockState = PinLock::LockState::NewPasscodeRequired;

        lock->onActivatedCallback = [this, passcode](const std::vector<unsigned int> &pin) {
            handleNewPasscodeConfirmed(passcode, pin);
    void PinLockHandler::handleNewPasscodeInvalid(const std::vector<unsigned int> &passcode)
    {
        auto onActivatedCallback = [this, passcode](PinLock::LockType type, const std::vector<unsigned int> &pin) {
            handlePasscodeChange(passcode);
        };

        app->switchWindow(app::window::name::desktop_pin_lock,
                          gui::ShowMode::GUI_SHOW_INIT,
                          std::make_unique<gui::LockPhoneData>(std::move(lock)));
        switchToPinLockWindow(PinLock::LockState::NewPasscodeInvalid, onActivatedCallback);
    }
    void PinLockHandler::unlock()
    {
        auto onActivatedCallback = [this](PinLock::LockType type, const std::vector<unsigned int> &data) {
            handlePasscode(type, data);
        };
        switchToPinLockWindow(onActivatedCallback);
    }

    void PinLockHandler::handleNewPasscodeConfirmed(const std::vector<unsigned int> &passcode,
                                                    const std::vector<unsigned int> &pin) const
    auto PinLockHandler::getStrongestLock() noexcept -> gui::PinLock &
    {
        if (simLock.getLockType() == PinLock::LockType::SimPin) {
            sys::Bus::SendUnicast(std::make_shared<CellularSimNewPinDataMessage>(Store::GSM::SIM::SIM1, passcode, pin),
                                  "ServiceCellular",
                                  app);
        if (!screenLock.isState(PinLock::LockState::Unlocked)) {
            return screenLock;
        }
        else if (simLock.getLockType() == PinLock::LockType::SimPuk) {
            sys::Bus::SendUnicast(std::make_shared<CellularSimPukDataMessage>(Store::GSM::SIM::SIM1, passcode, pin),
                                  "ServiceCellular",
                                  app);
        else if (promptSimLockWindow && !simLock.isState(PinLock::LockState::Unlocked)) {
            return simLock;
        }
        return screenLock;
    }

    void PinLockHandler::lockScreen()
    {
        screenLock.lockState = PinLock::LockState::PasscodeRequired;
    }

    auto PinLockHandler::parseSimCard(Store::GSM::SIM sim) const noexcept -> PinLock::SimCard
    void PinLockHandler::unlockScreen()
    {
        if (sim == Store::GSM::SIM::SIM1) {
            return gui::PinLock::SimCard::SIM1;
        if (getStrongestLock().isType(PinLock::LockType::Screen)) {
            unsigned int pinSize = appSettings.lockPassHash == 0 ? screen_nopin_size : default_screen_pin_size;
            screenLock.setPinSizeBounds(pinSize, pinSize);
            if (screenLock.getMaxPinSize() == screen_nopin_size) {
                screenLock.lockState = gui::PinLock::LockState::Unlocked;
            }
        }
        else if (sim == Store::GSM::SIM::SIM2) {
            return gui::PinLock::SimCard::SIM2;
        unlock();
    }

    void PinLockHandler::setSimLockHandled() noexcept
    {
        if (!getStrongestLock().isType(PinLock::LockType::Screen)) {
            promptSimLockWindow = false;
        }
        return gui::PinLock::SimCard::NoCard;
    }

} // namespace gui

M module-apps/application-desktop/widgets/PinLockHandler.hpp => module-apps/application-desktop/widgets/PinLockHandler.hpp +29 -23
@@ 21,40 21,46 @@ namespace gui
    {
        app::ApplicationDesktop *app = nullptr;
        const SettingsRecord &appSettings;
        gui::PinLock screenLock;
        gui::PinLock simLock;
        bool promptSimLockWindow = true;

        auto parseSimCard(Store::GSM::SIM sim) const noexcept -> PinLock::SimCard;

        void handlePasscode(const std::vector<unsigned int> passcode) const;
        void handlePasscodeChange(const std::vector<unsigned int> passcode) const;
        void handleNewPasscodeConfirmed(const std::vector<unsigned int> &passcode,
                                        const std::vector<unsigned int> &pin) const;
        auto handlePasscodeParams(app::manager::actions::ActionParamsPtr &&data) const -> gui::PinLock;
        void handleScreenPin(const std::vector<unsigned int> &pin);
        void handlePasscode(PinLock::LockType type, const std::vector<unsigned int> passcode);
        void handlePasscodeChange(const std::vector<unsigned int> passcode);
        void handleNewPasscodeUnconfirmed(const std::vector<unsigned int> &passcode,
                                          const std::vector<unsigned int> &pin);
        void handleNewPasscodeConfirmed(PinLock::LockType type,
                                        const std::vector<unsigned int> &passcode,
                                        const std::vector<unsigned int> &pin);
        void handleNewPasscodeInvalid(const std::vector<unsigned int> &passcode);
        void handlePasscodeParams(PinLock::LockType type,
                                  PinLock::LockState state,
                                  app::manager::actions::ActionParamsPtr &&data);
        void switchToPinLockWindow(
            std::function<void(PinLock::LockType, const std::vector<unsigned int> &)> onLockActivatedCallback);
        void switchToPinLockWindow(
            PinLock::LockState type,
            std::function<void(PinLock::LockType, const std::vector<unsigned int> &)> onLockActivatedCallback);

        void switchToPinlockWindow(std::function<void(const std::vector<unsigned int> &)> onLockActivatedCallback);
        auto getStrongestLock() noexcept -> gui::PinLock &;
        void unlock();
        void setSimLockHandled() noexcept;

      public:
        PinLockHandler(app::ApplicationDesktop *app, SettingsRecord &settings);
        void reloadScreenLock();

        void handleScreenPin(const std::vector<unsigned int> &pin);
        void handleScreenConfirm();
        void handlePinRequest(app::manager::actions::ActionParamsPtr &&data);
        void handlePukRequest(app::manager::actions::ActionParamsPtr &&data);
        void handlePasscodeRequest(PinLock::LockType type, app::manager::actions::ActionParamsPtr &&data);
        void handlePinChangeRequest(app::manager::actions::ActionParamsPtr &&data);

        void handleSimBlocked(app::manager::actions::ActionParamsPtr &&data);
        void handleUnlockSim(app::manager::actions::ActionParamsPtr &&data);
        void handleCMEError(app::manager::actions::ActionParamsPtr &&data) const;

        [[nodiscard]] bool isScreenLocked() const noexcept
        [[nodiscard]] auto isScreenLocked() const noexcept -> bool
        {
            return screenLock.getState() != PinLock::LockState::Unlocked;
            return !screenLock.isState(PinLock::LockState::Unlocked);
        }
        void lockScreen() noexcept
        {
            screenLock.lockState = PinLock::LockState::PasscodeRequired;
        }

        gui::PinLock screenLock;
        gui::PinLock simLock;
        void lockScreen();
        void unlockScreen();
    };
} // namespace gui

M module-apps/application-desktop/windows/DesktopMainWindow.cpp => module-apps/application-desktop/windows/DesktopMainWindow.cpp +1 -53
@@ 133,16 133,6 @@ namespace gui
            lockTimeoutApplilcation = lockData->getPreviousApplication();
            application->setSuspendFlag(true);
        }

        if (mode == ShowMode::GUI_SHOW_RETURN) {
            auto lock = getScreenLock();
            if (lock->getState() == PinLock::LockState::Unlocked) {
                setVisibleState();
                return;
            }
            switchToPinLockWindow(std::move(lock));
        }

        setVisibleState();
    }



@@ 201,14 191,7 @@ namespace gui
            // if interval between enter and pnd keys is less than time defined for unlocking
            // display pin lock screen or simply refresh current window to update labels

            auto lock = getScreenLock();
            // if there is no pin,
            if (lock->getMaxPinSize() == 0) {
                lock->verify();
                return true;
            }

            switchToPinLockWindow(std::move(lock));
            getAppDesktop()->lockHandler.unlockScreen();
            return true;
        }
        else if (enter_cache.storeEnter(inputEvent)) {


@@ 348,39 331,4 @@ namespace gui
        assert(app);
        return app;
    }

    auto DesktopMainWindow::getScreenLock() -> std::unique_ptr<PinLock>
    {
        auto lock = std::make_unique<PinLock>(getAppDesktop()->lockHandler.screenLock);
        auto app  = getAppDesktop();
        if (lock->getState() == PinLock::LockState::PasscodeRequired) {
            lock->onActivatedCallback = [app](const std::vector<unsigned int> &data) {
                app->lockHandler.handleScreenPin(data);
                app->switchWindow(app::window::name::desktop_main_window, ShowMode::GUI_SHOW_RETURN);
            };
        }
        else if (lock->getState() == PinLock::LockState::PasscodeInvalidRetryRequired) {
            lock->onActivatedCallback = [app](const std::vector<unsigned int> &) {
                app->lockHandler.screenLock.consumeState();
                app->switchWindow(app::window::name::desktop_main_window, ShowMode::GUI_SHOW_RETURN);
            };
        }
        else if (lock->getState() == PinLock::LockState::Blocked) {
            lock->onActivatedCallback = [app](const std::vector<unsigned int> &) {
                app->switchWindow(app::window::name::desktop_main_window, ShowMode::GUI_SHOW_INIT);
            };
        }
        return lock;
    }

    void DesktopMainWindow::switchToPinLockWindow(std::unique_ptr<PinLock> &&lock)
    {
        auto data = std::make_unique<LockPhoneData>(std::move(lock));
        if (!lockTimeoutApplilcation.empty()) {
            // if there was no application on to before closing proceed normally to pin protection
            data->setPrevApplication(lockTimeoutApplilcation);
            lockTimeoutApplilcation.clear();
        }
        application->switchWindow(app::window::name::desktop_pin_lock, std::move(data));
    }
} /* namespace gui */

M module-apps/application-desktop/windows/DesktopMainWindow.hpp => module-apps/application-desktop/windows/DesktopMainWindow.hpp +0 -4
@@ 17,7 17,6 @@ namespace app
namespace gui
{
    class NotificationsBox;
    class PinLock;

    class DesktopMainWindow : public AppWindow
    {


@@ 70,9 69,6 @@ namespace gui
        bool processLongPressEvent(const InputEvent &inputEvent);
        bool processShortPressEventOnUnlocked(const InputEvent &inputEvent);
        bool processShortPressEventOnLocked(const InputEvent &inputEvent);

        auto getScreenLock() -> std::unique_ptr<PinLock>;
        void switchToPinLockWindow(std::unique_ptr<PinLock> &&data);
        app::ApplicationDesktop *getAppDesktop() const;

      public:

M module-apps/application-desktop/windows/PinLockWindow.cpp => module-apps/application-desktop/windows/PinLockWindow.cpp +27 -48
@@ 54,26 54,28 @@ namespace gui
        pinLabelsBox = nullptr;
    }

    void PinLockWindow::setVisibleState(const PinLock::LockState state)
    void PinLockWindow::setVisibleState()
    {
        if (state == PinLock::LockState::PasscodeRequired) {
            currentPasscodeType = PinLockBox::EnterPasscodeType::ProvidePasscode;
            LockBox->setVisibleStateEnterPin(currentPasscodeType);
        if (lock->isState(PinLock::LockState::PasscodeRequired)) {
            LockBox->setVisibleStateEnterPin(PinLockBox::EnterPasscodeType::ProvidePasscode);
        }
        else if (state == PinLock::LockState::PasscodeInvalidRetryRequired) {
        else if (lock->isState(PinLock::LockState::PasscodeInvalidRetryRequired)) {
            LockBox->setVisibleStateInvalidPin(PinLockBox::PasscodeErrorType::InvalidPasscode, lock->getValue());
        }
        else if (state == PinLock::LockState::Blocked) {
        else if (lock->isState(PinLock::LockState::Blocked)) {
            LockBox->setVisibleStateBlocked();
        }
        else if (state == PinLock::LockState::NewPasscodeRequired) {
            LockBox->setVisibleStateEnterPin(currentPasscodeType);
        else if (lock->isState(PinLock::LockState::NewPasscodeRequired)) {
            LockBox->setVisibleStateEnterPin(PinLockBox::EnterPasscodeType::ProvideNewPasscode);
        }
        else if (state == PinLock::LockState::NewPasscodeInvalid) {
        else if (lock->isState(PinLock::LockState::NewPasscodeConfirmRequired)) {
            LockBox->setVisibleStateEnterPin(PinLockBox::EnterPasscodeType::ConfirmNewPasscode);
        }
        else if (lock->isState(PinLock::LockState::NewPasscodeInvalid)) {
            LockBox->setVisibleStateInvalidPin(PinLockBox::PasscodeErrorType::NewPasscodeConfirmFailed,
                                               lock->getValue());
        }
        else if (state == PinLock::LockState::ErrorOccurred) {
        else if (lock->isState(PinLock::LockState::ErrorOccurred)) {
            LockBox->setVisibleStateInvalidPin(PinLockBox::PasscodeErrorType::UnhandledError, lock->getValue());
        }
        application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);


@@ 93,20 95,18 @@ namespace gui
            buildPinLockBox();
            LockBox->buildLockBox(lock->getMaxPinSize());

            auto state = lock->getState();
            if (state == PinLock::LockState::PasscodeRequired) {
            if (lock->isState(PinLock::LockState::PasscodeRequired)) {
                currentPasscodeType = PinLockBox::EnterPasscodeType::ProvidePasscode;
            }
            else if (state == PinLock::LockState::NewPasscodeRequired) {
            else if (lock->isState(PinLock::LockState::NewPasscodeRequired)) {
                currentPasscodeType = PinLockBox::EnterPasscodeType::ProvideNewPasscode;
            }
            setVisibleState(lock->getState());
            setVisibleState();
        }
    }

    bool PinLockWindow::onInput(const InputEvent &inputEvent)
    {
        auto state = lock->getState();
        if (!inputEvent.isShortPress()) {
            return AppWindow::onInput(inputEvent);
        }


@@ 116,17 116,17 @@ namespace gui
            return true;
        }
        else if (inputEvent.is(KeyCode::KEY_RF) && bottomBar->isActive(BottomBar::Side::RIGHT)) {
            if (state == PinLock::LockState::PasscodeRequired || state == PinLock::LockState::NewPasscodeRequired) {
            if (usesNumericKeys()) {
                lock->clearAttempt();
            }
            else if (state == PinLock::LockState::PasscodeInvalidRetryRequired) {
            else if (lock->isState(PinLock::LockState::PasscodeInvalidRetryRequired)) {
                lock->consumeState();
            }
            application->switchWindow(gui::name::window::main_window);
            return true;
        }
        else if (inputEvent.is(KeyCode::KEY_PND)) {
            if (state == PinLock::LockState::PasscodeRequired || state == PinLock::LockState::NewPasscodeRequired) {
            if (usesNumericKeys()) {
                lock->popChar();
                LockBox->popChar(lock->getCharCount());
                bottomBar->setActive(BottomBar::Side::CENTER, lock->canVerify());


@@ 134,8 134,7 @@ namespace gui
            }
        }
        else if (0 <= gui::toNumeric(inputEvent.keyCode) && gui::toNumeric(inputEvent.keyCode) <= 9) {
            if ((state == PinLock::LockState::PasscodeRequired || state == PinLock::LockState::NewPasscodeRequired) &&
                lock->canPut()) {
            if (usesNumericKeys() && lock->canPut()) {
                LockBox->putChar(lock->getCharCount());
                lock->putNextChar(gui::toNumeric(inputEvent.keyCode));
                bottomBar->setActive(BottomBar::Side::CENTER, lock->canVerify());


@@ 143,34 142,7 @@ namespace gui
            }
        }
        else if (inputEvent.is(KeyCode::KEY_ENTER) && bottomBar->isActive(BottomBar::Side::CENTER)) {
            if (state == PinLock::LockState::NewPasscodeInvalid) {
                lock->consumeState();
                setVisibleState(lock->getState());
                return true;
            }
            else if (currentPasscodeType == PinLockBox::EnterPasscodeType::ProvideNewPasscode) {
                buffer = lock->getPin();
                lock->clearAttempt();
                LockBox->clear();

                currentPasscodeType = PinLockBox::EnterPasscodeType::ConfirmNewPasscode;
                setVisibleState(lock->getState());
                return true;
            }
            else if (currentPasscodeType == PinLockBox::EnterPasscodeType::ConfirmNewPasscode) {
                if (buffer == lock->getPin()) {
                    lock->verify();
                }
                else {
                    currentPasscodeType = PinLockBox::EnterPasscodeType::ProvideNewPasscode;
                    lock->clearAttempt();
                    lock->setNewPasscodeInvalidState();
                    LockBox->clear();
                    setVisibleState(lock->getState());
                }
                return true;
            }
            lock->verify();
            lock->activate();
            return true;
        }
        // check if any of the lower inheritance onInput methods catch the event


@@ 191,4 163,11 @@ namespace gui
        }
        assert(LockBox != nullptr);
    }

    auto PinLockWindow::usesNumericKeys() const noexcept -> bool
    {
        return lock->isState(PinLock::LockState::PasscodeRequired) ||
               lock->isState(PinLock::LockState::NewPasscodeRequired) ||
               lock->isState(PinLock::LockState::NewPasscodeConfirmRequired);
    }
} /* namespace gui */

M module-apps/application-desktop/windows/PinLockWindow.hpp => module-apps/application-desktop/windows/PinLockWindow.hpp +2 -5
@@ 13,7 13,6 @@
#include "PinLockBaseWindow.hpp"
namespace gui
{

    class PinLockWindow : public PinLockBaseWindow
    {
        const std::string this_window_name;


@@ 21,13 20,11 @@ namespace gui
        std::unique_ptr<PinLockBox> LockBox = nullptr;
        PinLockBox::EnterPasscodeType currentPasscodeType = PinLockBox::EnterPasscodeType::ProvidePasscode;

        std::vector<unsigned int> buffer;
        std::function<void(const std::vector<unsigned int> &)> callbackBuffer = nullptr;

        // method hides or show widgets and sets bars according to provided state
        void setVisibleState(const PinLock::LockState state);
        void setVisibleState();
        void buildPinLockBox();
        void invalidate() noexcept;
        auto usesNumericKeys() const noexcept -> bool;

      public:
        PinLockWindow(app::Application *app, const std::string &window_name);