~aleteoryx/muditaos

bc737e93f697de2dda221f8f97f0ce0ff05edd0b — Przemyslaw Brudny 4 years ago 97760f7
[EGD-5885] Added SimLockHandler

Refactored LockWindow TitleBar handling. Added Sim pin request
block on lockedPhone. Added Sim info popup added when pin
changed. Updated assets. Removed old PinLock structures.
Cleared LockBox structures. Removed old settings sim setters.
New CellularMessage adaptation. Cleared Lock structure.
82 files changed, 1641 insertions(+), 1890 deletions(-)

A art/phone/common/info_icon_W_G.png
A art/phone/common/unlock_icon_W_G.png
D image/assets/images/pin_lock_info.vpi
A image/assets/images/unlock_icon_W_G.vpi
M image/assets/lang/English.json
M image/assets/lang/Svenska.json
M module-apps/Application.cpp
M module-apps/Application.hpp
M module-apps/application-desktop/ApplicationDesktop.cpp
M module-apps/application-desktop/ApplicationDesktop.hpp
M module-apps/application-desktop/windows/DesktopMainWindow.cpp
M module-apps/application-desktop/windows/PostUpdateWindow.cpp
M module-apps/application-desktop/windows/PostUpdateWindow.hpp
M module-apps/application-onboarding/windows/OnBoardingSimSelectWindow.cpp
M module-apps/application-settings-new/ApplicationSettings.cpp
M module-apps/application-settings-new/windows/PINSettingsWindow.cpp
M module-apps/application-settings-new/windows/SecurityMainWindow.cpp
M module-apps/application-settings/ApplicationSettings.cpp
M module-apps/application-settings/ApplicationSettings.hpp
M module-apps/application-settings/CMakeLists.txt
M module-apps/application-settings/windows/SettingsMainWindow.cpp
D module-apps/application-settings/windows/SimSelectWindow.cpp
D module-apps/application-settings/windows/SimSelectWindow.hpp
M module-apps/locks/CMakeLists.txt
M module-apps/locks/data/LockData.hpp
M module-apps/locks/data/LockStyle.hpp
A module-apps/locks/data/SimLockMessages.hpp
M module-apps/locks/handlers/PhoneLockHandler.cpp
M module-apps/locks/handlers/PhoneLockHandler.hpp
M module-apps/locks/handlers/PhoneLockSubject.cpp
M module-apps/locks/handlers/PhoneLockSubject.hpp
D module-apps/locks/handlers/PinLockHandler.cpp
D module-apps/locks/handlers/PinLockHandler.hpp
A module-apps/locks/handlers/SimLockHandler.cpp
A module-apps/locks/handlers/SimLockHandler.hpp
A module-apps/locks/handlers/SimLockSubject.cpp
A module-apps/locks/handlers/SimLockSubject.hpp
M module-apps/locks/widgets/Lock.cpp
M module-apps/locks/widgets/Lock.hpp
M module-apps/locks/widgets/LockBox.hpp
A module-apps/locks/widgets/LockBoxAlternatingSize.cpp
R module-apps/locks/widgets/{PukLockBox => LockBoxAlternatingSize}.hpp
R module-apps/locks/widgets/{PhoneLockBaseBox => LockBoxConstantSize}.cpp
R module-apps/locks/widgets/{PhoneLockBaseBox => LockBoxConstantSize}.hpp
M module-apps/locks/widgets/LockHash.hpp
M module-apps/locks/widgets/PhoneLockBox.cpp
M module-apps/locks/widgets/PhoneLockBox.hpp
D module-apps/locks/widgets/PukLockBox.cpp
M module-apps/locks/widgets/SimLockBox.cpp
M module-apps/locks/widgets/SimLockBox.hpp
A module-apps/locks/windows/LockInputWindow.cpp
R module-apps/locks/windows/{LockWindow => LockInputWindow}.hpp
D module-apps/locks/windows/LockWindow.cpp
D module-apps/locks/windows/PinLockBaseWindow.cpp
D module-apps/locks/windows/PinLockBaseWindow.hpp
D module-apps/locks/windows/PinLockWindow.cpp
D module-apps/locks/windows/PinLockWindow.hpp
M module-apps/popups/CMakeLists.txt
M module-apps/popups/Popups.cpp
M module-apps/popups/Popups.hpp
M module-apps/popups/data/PopupRequestParams.hpp
M module-apps/popups/lock-popups/PhoneLockChangeInfoWindow.cpp
M module-apps/popups/lock-popups/PhoneLockChangeInfoWindow.hpp
M module-apps/popups/lock-popups/PhoneLockInputWindow.cpp
M module-apps/popups/lock-popups/PhoneLockInputWindow.hpp
M module-apps/popups/lock-popups/PhoneLockedInfoWindow.cpp
M module-apps/popups/lock-popups/PhoneLockedInfoWindow.hpp
A module-apps/popups/lock-popups/SimInfoWindow.cpp
A module-apps/popups/lock-popups/SimInfoWindow.hpp
A module-apps/popups/lock-popups/SimLockInputWindow.cpp
A module-apps/popups/lock-popups/SimLockInputWindow.hpp
M module-gui/gui/widgets/Icon.cpp
M module-gui/gui/widgets/ImageBox.cpp
M module-gui/gui/widgets/ImageBox.hpp
M module-services/service-appmgr/CMakeLists.txt
D module-services/service-appmgr/data/SimActionsParams.cpp
M module-services/service-appmgr/model/ApplicationManager.cpp
M module-services/service-appmgr/service-appmgr/Actions.hpp
D module-services/service-appmgr/service-appmgr/data/SimActionsParams.hpp
M module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp
M module-services/service-cellular/service-cellular/CellularMessage.hpp
M module-services/service-desktop/service-desktop/DesktopMessages.hpp
A art/phone/common/info_icon_W_G.png => art/phone/common/info_icon_W_G.png +0 -0
A art/phone/common/unlock_icon_W_G.png => art/phone/common/unlock_icon_W_G.png +0 -0
D image/assets/images/pin_lock_info.vpi => image/assets/images/pin_lock_info.vpi +0 -0
A image/assets/images/unlock_icon_W_G.vpi => image/assets/images/unlock_icon_W_G.vpi +0 -0
M image/assets/lang/English.json => image/assets/lang/English.json +18 -17
@@ 228,23 228,24 @@
  "app_desktop_info_mmi_imei": "IMEI (MEID)",
  "app_desktop_info_mmi_result_success": "Success",
  "app_desktop_info_mmi_result_failed": "Failed",
  "app_desktop_header_sim_setup": "<text><token>$SIM</token> setup</text>",
  "app_desktop_sim_enter_pin_unlock": "<text>Type current <token>$PINTYPE</token> code:</text>",
  "app_desktop_sim_change_pin": "Change PIN code",
  "app_desktop_sim_enter_new_pin": "Enter new PIN code:",
  "app_desktop_sim_confirm_new_pin": "Confirm new PIN code:",
  "app_desktop_sim_setup_wrong_pin_last_attempt": "<text>Wrong PIN code. You have<br></br>1 attempt left.</text>",
  "app_desktop_sim_setup_wrong_pin": "<text>Wrong PIN code. You have<br></br><token>$ATTEMPTS</token> attempts left.</text>",
  "app_desktop_sim_wrong_pin_confirmation": "Wrong PIN code.",
  "app_desktop_sim_pin_changed_successfully": "PIN code changed successfully",
  "app_desktop_sim_cme_error": "<text>SIM card<br></br>CME error:<token>$CMECODE</token></text>",
  "app_desktop_sim_puk_blocked": "<text>The SIM card is blocked.<br></br>Please, contact the operator.</text>",
  "app_desktop_sim_setup_enter_puk": "<text>The SIM card is blocked.<br></br>To unblock it, type the PUK code:</text>",
  "app_desktop_sim_setup_wrong_puk": "<text>Wrong PUK code.<br></br>You have <token>$ATTEMPTS</token> attempts left</text>",
  "app_desktop_sim_setup_wrong_puk_last_attempt": "<text>Wrong PUK code.<br></br>You have 1 attempt left</text>",
  "app_desktop_sim_setup_wrong_puk_last_attempt_warning": "<text>If the code is wrong this time, the<br></br>SIM card will be blocked and you'll<br></br>have to contact the operator.</text>",
  "app_desktop_sim_card_unlocked": "SIM card unlocked",
  "app_desktop_sim_card_locked": "SIM card locked",
  "sim_header_setup": "<text><token>$SIM</token> setup</text>",
  "sim_enter_pin_unlock": "<text>Enter the PIN code to set up <br></br> the <token>$PINTYPE</token> card:</text>",
  "sim_enter_enter_current": "<text>Type current Pin Code:</text>",
  "sim_change_pin": "Change PIN code",
  "sim_enter_new_pin": "Enter new PIN code:",
  "sim_confirm_new_pin": "Confirm new PIN code:",
  "sim_setup_wrong_pin": "<text>Wrong PIN code. You have<br></br><token>$ATTEMPTS</token> attempts left.</text>",
  "sim_setup_wrong_pin_last_attempt": "<text>Wrong PIN code. You have<br></br>1 attempt left.</text>",
  "sim_wrong_pin_confirmation": "Wrong PIN code.",
  "sim_pin_changed_successfully": "PIN code changed successfully",
  "sim_cme_error": "<text>SIM card<br></br>CME error:<token>$CMECODE</token></text>",
  "sim_puk_blocked": "<text>The SIM card is blocked.<br></br>Please, contact the operator.</text>",
  "sim_setup_enter_puk": "<text>The SIM card is blocked.<br></br>To unblock it, type the PUK code:</text>",
  "sim_setup_wrong_puk": "<text>Wrong PUK code.<br></br>You have <token>$ATTEMPTS</token> attempts left</text>",
  "sim_setup_wrong_puk_last_attempt": "<text>Wrong PUK code.<br></br>You have 1 attempt left</text>",
  "sim_setup_wrong_puk_last_attempt_warning": "<text>If the code is wrong this time, the<br></br>SIM card will be blocked and you'll<br></br>have to contact the operator.</text>",
  "sim_card_pin_disabled": "SIM card pin disabled",
  "sim_card_pin_enabled": "SIM card pin enabled",
  "app_desktop_press_to_unlock": "<text font='gt_pressura' size='27'>Press <b>Unlock</b> and then <b>#</b></text>",
  "app_desktop_unread_messages": "<text>Unread <b>messages</b></text>",
  "app_desktop_missed_calls": "<text>Missed <b>calls</b></text>",

M image/assets/lang/Svenska.json => image/assets/lang/Svenska.json +13 -13
@@ 216,19 216,19 @@
  "app_desktop_info_mmi_imei": "IMEI-nummer (MEID)",
  "app_desktop_info_mmi_result_success": "Lyckades",
  "app_desktop_info_mmi_result_failed": "Misslyckades",
  "app_desktop_header_sim_setup": "<text><token>$SIM</token>-inställningar</text>",
  "app_desktop_sim_enter_pin_unlock": "Den förra PIN-koden:",
  "app_desktop_sim_enter_new_pin": "Den nya PIN-koden:",
  "app_desktop_sim_confirm_new_pin": "Bekräfta ny PIN-kod:",
  "app_desktop_sim_setup_wrong_pin_last_attempt": "<text>Fel PIN-kod. Du har<br></br>1 försök kvar.</text>",
  "app_desktop_sim_setup_wrong_pin": "<text>Fel PIN-kod. Du har<br></br><token>$ATTEMPTS</token> försök kvar.</text>",
  "app_desktop_sim_wrong_pin_confirmation": "Fel PIN-kod.",
  "app_desktop_sim_cme_error": "<text>SIM-kort<br></br>CME error:<token>$CMECODE</token></text>",
  "app_desktop_sim_puk_blocked": "<text>SIM-kortet är låst.<br></br>Var god kontakta operatör.</text>",
  "app_desktop_sim_setup_enter_puk": "<text>SIM-kortet är låst.<br></br>För att låsa upp det, skriv in PUK-koden:</text>",
  "app_desktop_sim_setup_wrong_puk": "<text>Fel PUK-kod.<br></br>Du har <token>$ATTEMPTS</token> försök kvar.</text>",
  "app_desktop_sim_setup_wrong_puk_last_attempt": "<text>Fel PUK-kod.<br></br>Du har 1 försök kvar.</text>",
  "app_desktop_sim_setup_wrong_puk_last_attempt_warning": "<text>Om koden är fel den här gången<br></br>kommer SIM-kortet låsas och du kommer<br></br>behöva kontakta operatören.</text>",
  "sim_header_setup": "<text><token>$SIM</token>-inställningar</text>",
  "sim_enter_pin_unlock": "Den förra PIN-koden:",
  "sim_enter_new_pin": "Den nya PIN-koden:",
  "sim_confirm_new_pin": "Bekräfta ny PIN-kod:",
  "sim_setup_wrong_pin_last_attempt": "<text>Fel PIN-kod. Du har<br></br>1 försök kvar.</text>",
  "sim_setup_wrong_pin": "<text>Fel PIN-kod. Du har<br></br><token>$ATTEMPTS</token> försök kvar.</text>",
  "sim_wrong_pin_confirmation": "Fel PIN-kod.",
  "sim_cme_error": "<text>SIM-kort<br></br>CME error:<token>$CMECODE</token></text>",
  "sim_puk_blocked": "<text>SIM-kortet är låst.<br></br>Var god kontakta operatör.</text>",
  "sim_setup_enter_puk": "<text>SIM-kortet är låst.<br></br>För att låsa upp det, skriv in PUK-koden:</text>",
  "sim_setup_wrong_puk": "<text>Fel PUK-kod.<br></br>Du har <token>$ATTEMPTS</token> försök kvar.</text>",
  "sim_setup_wrong_puk_last_attempt": "<text>Fel PUK-kod.<br></br>Du har 1 försök kvar.</text>",
  "sim_setup_wrong_puk_last_attempt_warning": "<text>Om koden är fel den här gången<br></br>kommer SIM-kortet låsas och du kommer<br></br>behöva kontakta operatören.</text>",
  "app_desktop_press_to_unlock": "<text font='gt_pressura' size='27'>Tryck <b>Lås upp</b> följt av <b>#</b></text>",
  "app_desktop_unread_messages": "<text>Olästa <b>meddelanden</b></text>",
  "app_desktop_missed_calls": "<text>Missade <b>samtal</b></text>",

M module-apps/Application.cpp => module-apps/Application.cpp +25 -1
@@ 49,6 49,8 @@
#include <popups/lock-popups/PhoneLockedInfoWindow.hpp>
#include <popups/lock-popups/PhoneLockInputWindow.hpp>
#include <popups/lock-popups/PhoneLockChangeInfoWindow.hpp>
#include <popups/lock-popups/SimLockInputWindow.hpp>
#include <popups/lock-popups/SimInfoWindow.hpp>
#include <popups/data/PopupData.hpp>
#include <popups/data/PopupRequestParams.hpp>
#include <popups/data/PhoneModeParams.hpp>


@@ 104,7 106,7 @@ namespace app
          keyTranslator{std::make_unique<gui::KeyInputSimpleTranslation>()}, startInBackground{startInBackground},
          callbackStorage{std::make_unique<CallbackStorage>()}, topBarManager{std::make_unique<TopBarManager>()},
          settings(std::make_unique<settings::Settings>()), phoneMode{mode}, phoneLockSubject(this),
          lockPolicyHandler(this)
          lockPolicyHandler(this), simLockSubject(this)
    {
        topBarManager->enableIndicators({gui::top_bar::Indicator::Time});
        using TimeMode = gui::top_bar::TimeConfiguration::TimeMode;


@@ 792,6 794,15 @@ namespace app
                    return std::make_unique<gui::PowerOffWindow>(app, std::move(presenter));
                });
                break;
            case ID::SimLock:
            case ID::SimInfo:
                windowsFactory.attach(window::sim_unlock_window, [](Application *app, const std::string &name) {
                    return std::make_unique<gui::SimLockInputWindow>(app, window::sim_unlock_window);
                });
                windowsFactory.attach(window::sim_info_window, [](Application *app, const std::string &name) {
                    return std::make_unique<gui::SimInfoWindow>(app, window::sim_info_window);
                });
                break;
            }
        }
    }


@@ 817,6 828,14 @@ namespace app
                gui::popup::resolveWindowName(id),
                std::make_unique<locks::LockData>(popupParams->getLock(), popupParams->getPhoneLockInputTypeAction()));
        }
        else if (id == ID::SimLock || id == ID::SimInfo) {
            auto popupParams = static_cast<const gui::SimUnlockInputRequestParams *>(params);

            switchWindow(gui::popup::resolveWindowName(id),
                         std::make_unique<locks::SimLockData>(popupParams->getLock(),
                                                              popupParams->getSimInputTypeAction(),
                                                              popupParams->getErrorCode()));
        }
        else {
            switchWindow(gui::popup::resolveWindowName(id));
        }


@@ 952,4 971,9 @@ namespace app
    {
        return lockPolicyHandler;
    }

    auto Application::getSimLockSubject() noexcept -> locks::SimLockSubject &
    {
        return simLockSubject;
    }
} /* namespace app */

M module-apps/Application.hpp => module-apps/Application.hpp +3 -0
@@ 30,6 30,7 @@
#include <TopBarManager.hpp>
#include <popups/Popups.hpp>
#include <locks/handlers/PhoneLockSubject.hpp>
#include <locks/handlers/SimLockSubject.hpp>
#include <locks/handlers/LockPolicyHandler.hpp>
#include "WindowsFactory.hpp"
#include "WindowsStack.hpp"


@@ 402,9 403,11 @@ namespace app

        locks::PhoneLockSubject phoneLockSubject;
        locks::LockPolicyHandler lockPolicyHandler;
        locks::SimLockSubject simLockSubject;

      public:
        [[nodiscard]] auto getPhoneLockSubject() noexcept -> locks::PhoneLockSubject &;
        [[nodiscard]] auto getSimLockSubject() noexcept -> locks::SimLockSubject &;

        [[nodiscard]] bool isPhoneLockEnabled() const noexcept;


M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +6 -150
@@ 6,7 6,6 @@
#include "MessageType.hpp"
#include "windows/DesktopMainWindow.hpp"
#include "windows/MenuWindow.hpp"
#include "locks/windows/PinLockWindow.hpp"
#include "windows/DeadBatteryWindow.hpp"
#include "windows/LogoWindow.hpp"
#include "windows/ChargingBatteryWindow.hpp"


@@ 28,7 27,6 @@
#include <service-appmgr/Controller.hpp>
#include <service-cellular/ServiceCellular.hpp>
#include <service-cellular/CellularMessage.hpp>
#include <service-cellular-api>
#include <service-db/QueryMessage.hpp>
#include <module-services/service-db/agents/settings/SystemSettings.hpp>
#include <magic_enum.hpp>


@@ 46,7 44,7 @@ namespace app
                                           sys::phone_modes::PhoneMode mode,
                                           StartInBackground startInBackground)
        : Application(std::move(name), std::move(parent), mode, startInBackground), AsyncCallbackReceiver(this),
          lockHandler(this), dbNotificationHandler(this)
          dbNotificationHandler(this)
    {
        using namespace gui::top_bar;
        topBarManager->enableIndicators({Indicator::Signal, Indicator::Time, Indicator::Battery, Indicator::SimCard});


@@ 54,48 52,6 @@ namespace app
                           std::make_shared<SIMConfiguration>(SIMConfiguration::DisplayMode::OnlyInactiveState));
        bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);

        addActionReceiver(app::manager::actions::RequestPin, [this](auto &&data) {
            lockHandler.handlePasscodeRequest(locks::Lock::LockType::SimPin, std::move(data));
            return actionHandled();
        });

        addActionReceiver(app::manager::actions::RequestPuk, [this](auto &&data) {
            lockHandler.handlePasscodeRequest(locks::Lock::LockType::SimPuk, std::move(data));
            return actionHandled();
        });

        addActionReceiver(app::manager::actions::RequestPinChange, [this](auto &&data) {
            lockHandler.handlePinChangeRequest(std::move(data));
            return actionHandled();
        });

        addActionReceiver(app::manager::actions::RequestPinDisable, [this](auto &&data) {
            lockHandler.handlePinEnableRequest(std::forward<decltype(data)>(data),
                                               cellular::api::SimLockState::Disabled);
            return actionHandled();
        });

        addActionReceiver(app::manager::actions::RequestPinEnable, [this](auto &&data) {
            lockHandler.handlePinEnableRequest(std::forward<decltype(data)>(data),
                                               cellular::api::SimLockState::Enabled);
            return actionHandled();
        });

        addActionReceiver(app::manager::actions::BlockSim, [this](auto &&data) {
            lockHandler.handleSimBlocked(std::move(data));
            return actionHandled();
        });

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

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

        addActionReceiver(app::manager::actions::ShowMMIResponse, [this](auto &&data) {
            switchWindow(app::window::name::desktop_mmi_pull, std::move(data));
            return actionHandled();


@@ 192,15 148,6 @@ namespace app
    auto ApplicationDesktop::handle(cellular::StateChange *msg) -> bool
    {
        assert(msg);
        if (msg->request == cellular::service::State::ST::URCReady) {
            if (need_sim_select && !lockHandler.isScreenLocked()) {
                manager::Controller::sendAction(this, manager::actions::SelectSimCard);
                return true;
            }
            else if (need_sim_select == false) {
                bus.sendUnicast(std::make_shared<CellularSimProcedureMessage>(), ServiceCellular::serviceName);
            }
        }
        if (msg->request == cellular::service::State::ST::ModemFatalFailure) {
            switchWindow(app::window::name::desktop_reboot);
        }


@@ 242,68 189,6 @@ namespace app
            return sys::msgHandled();
        });

        auto createPinChangedSuccessfullyDialog =
            [](app::ApplicationDesktop *app) -> std::unique_ptr<gui::DialogMetadataMessage> {
            return std::make_unique<gui::DialogMetadataMessage>(
                gui::DialogMetadata{utils::translate("app_desktop_sim_change_pin"),
                                    "success_icon_W_G",
                                    utils::translate("app_desktop_sim_pin_changed_successfully"),
                                    "",
                                    [app]() {
                                        app->switchWindow(app::window::name::desktop_main_window);
                                        return true;
                                    }});
        };

        connect(typeid(cellular::msg::request::sim::ChangePin::Response),
                [&](sys::Message *request) -> sys::MessagePointer {
                    auto response = dynamic_cast<cellular::msg::request::sim::ChangePin::Response *>(request);
                    if (response->retCode) {
                        auto metaData = createPinChangedSuccessfullyDialog(this);
                        switchWindow(
                            gui::window::name::dialog_confirm, gui::ShowMode::GUI_SHOW_INIT, std::move(metaData));
                    }
                    else {
                        lockHandler.handlePinChangeRequestFailed();
                    }
                    return sys::MessageNone{};
                });

        connect(typeid(cellular::msg::request::sim::UnblockWithPuk::Response),
                [&](sys::Message *request) -> sys::MessagePointer {
                    auto response = dynamic_cast<cellular::msg::request::sim::UnblockWithPuk::Response *>(request);
                    if (response->retCode) {
                        auto metaData = createPinChangedSuccessfullyDialog(this);
                        switchWindow(
                            gui::window::name::dialog_confirm, gui::ShowMode::GUI_SHOW_INIT, std::move(metaData));
                    }
                    return sys::MessageNone{};
                });

        connect(typeid(cellular::msg::request::sim::SetPinLock::Response),
                [&](sys::Message *request) -> sys::MessagePointer {
                    auto response = dynamic_cast<cellular::msg::request::sim::SetPinLock::Response *>(request);
                    if (response->retCode) {
                        auto metaData = std::make_unique<gui::DialogMetadataMessage>(
                            gui::DialogMetadata{"",
                                                "success_icon_W_G",
                                                response->lock == cellular::api::SimLockState::Disabled
                                                    ? utils::translate("app_desktop_sim_card_unlocked")
                                                    : utils::translate("app_desktop_sim_card_locked"),
                                                "",
                                                [this]() {
                                                    switchWindow(app::window::name::desktop_main_window);
                                                    return true;
                                                }});
                        switchWindow(
                            gui::window::name::dialog_confirm, gui::ShowMode::GUI_SHOW_INIT, std::move(metaData));
                    }
                    else {
                        lockHandler.handlePinEnableRequestFailed(response->lock);
                    }
                    return sys::MessageNone{};
                });

        connect(typeid(db::NotificationMessage), [&](sys::Message *request) {
            auto notificationMessage = static_cast<db::NotificationMessage *>(request);
            dbNotificationHandler.handle(notificationMessage);


@@ 314,20 199,6 @@ namespace app
            std::make_shared<sdesktop::UpdateOsMessage>(updateos::UpdateMessageType::UpdateCheckForUpdateOnce);
        bus.sendUnicast(msgToSend, service::name::service_desktop);

        auto selectedSim = magic_enum::enum_cast<Store::GSM::SIM>(
            settings->getValue(settings::SystemProperties::activeSim, settings::SettingsScope::Global));
        if (selectedSim.has_value()) {
            Store::GSM::get()->selected = selectedSim.value();
        }
        else {
            Store::GSM::get()->selected = Store::GSM::SIM::NONE;
        }

        settings->registerValueChange(
            settings::SystemProperties::activeSim,
            [this](const std::string &value) { activeSimChanged(value); },
            settings::SettingsScope::Global);

        settings->registerValueChange(
            settings::SystemProperties::osCurrentVersion,
            [this](const std::string &value) { osCurrentVersionChanged(value); },


@@ 354,9 225,6 @@ namespace app
        windowsFactory.attach(desktop_main_window, [](Application *app, const std::string &name) {
            return std::make_unique<gui::DesktopMainWindow>(app);
        });
        windowsFactory.attach(desktop_pin_lock, [&](Application *app, const std::string newname) {
            return std::make_unique<gui::PinLockWindow>(app, desktop_pin_lock);
        });
        windowsFactory.attach(desktop_menu, [this](Application *app, const std::string newname) {
            return std::make_unique<gui::MenuWindow>(app, dbNotificationHandler);
        });


@@ 395,8 263,11 @@ namespace app
            return std::make_unique<gui::DialogConfirm>(app, name);
        });

        attachPopups(
            {gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes, gui::popup::ID::PhoneLock});
        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::SimLock});
    }

    void ApplicationDesktop::destroyUserInterface()


@@ 412,21 283,6 @@ namespace app
        return false;
    }

    void ApplicationDesktop::activeSimChanged(std::string value)
    {
        auto sim = magic_enum::enum_cast<Store::GSM::SIM>(value);
        if (sim.has_value()) {
            Store::GSM::get()->selected = sim.value();
        }
        else {
            Store::GSM::get()->selected = Store::GSM::SIM::NONE;
        }

        if (Store::GSM::SIM::NONE == sim) {
            need_sim_select = true;
        }
    }

    void ApplicationDesktop::handleLowBatteryNotification(manager::actions::ActionParamsPtr &&data)
    {
        auto lowBatteryState = static_cast<manager::actions::LowBatteryNotificationParams *>(data.get());

M module-apps/application-desktop/ApplicationDesktop.hpp => module-apps/application-desktop/ApplicationDesktop.hpp +0 -14
@@ 4,7 4,6 @@
#pragma once

#include "windows/Names.hpp"
#include "locks/handlers/PinLockHandler.hpp"
#include "widgets/DBNotificationsHandler.hpp"
#include "Constants.hpp"
#include <Application.hpp>


@@ 26,10 25,6 @@ namespace app
    class ApplicationDesktop : public Application, public AsyncCallbackReceiver
    {
      public:
        bool need_sim_select = false;

        gui::PinLockHandler lockHandler;

        explicit ApplicationDesktop(std::string name                    = name_desktop,
                                    std::string parent                  = {},
                                    sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,


@@ 63,7 58,6 @@ namespace app

      private:
        bool refreshMenuWindow();
        void activeSimChanged(std::string value);
        void handleLowBatteryNotification(manager::actions::ActionParamsPtr &&data);
        void osUpdateVersionChanged(const std::string &value);
        void osCurrentVersionChanged(const std::string &value);


@@ 78,17 72,9 @@ namespace app
        {
            return {{manager::actions::Launch,
                     manager::actions::AutoLock,
                     manager::actions::RequestPin,
                     manager::actions::RequestPuk,
                     manager::actions::RequestPinChange,
                     manager::actions::RequestPinDisable,
                     manager::actions::RequestPinEnable,
                     manager::actions::UnlockSim,
                     manager::actions::BlockSim,
                     manager::actions::ShowMMIResponse,
                     manager::actions::ShowMMIPush,
                     manager::actions::ShowMMIResult,
                     manager::actions::DisplayCMEError,
                     manager::actions::DisplayLowBatteryScreen,
                     manager::actions::SystemBrownout,
                     manager::actions::DisplayLogoAtExit,

M module-apps/application-desktop/windows/DesktopMainWindow.cpp => module-apps/application-desktop/windows/DesktopMainWindow.cpp +0 -8
@@ 92,10 92,6 @@ namespace gui

    void DesktopMainWindow::setVisibleState()
    {
        auto app = getAppDesktop();

        app->lockHandler.unlockScreen();

        setActiveState();

        if (osUpdateVer == osCurrentVer && osUpdateVer != updateos::initSysVer &&


@@ 106,10 102,6 @@ namespace gui
            getAppDesktop()->setOsUpdateVersion(updateos::initSysVer);
        }

        if (app->need_sim_select && Store::GSM::get()->sim == Store::GSM::SIM::SIM_UNKNOWN) {
            app::manager::Controller::sendAction(application, app::manager::actions::SelectSimCard);
        }

        application->bus.sendUnicast(std::make_shared<TimersProcessingStartMessage>(), service::name::service_time);
    }


M module-apps/application-desktop/windows/PostUpdateWindow.cpp => module-apps/application-desktop/windows/PostUpdateWindow.cpp +9 -18
@@ 28,7 28,7 @@ void PostUpdateWindow::onBeforeShow(ShowMode mode, SwitchData *data)
            currentOsVersion = item->getCurrentOsVersion();
            auto info        = utils::translate("app_desktop_update_success");
            utils::findAndReplaceAll(info, "$VERSION", currentOsVersion);
            infoText->setText(info);
            infoIcon->text->setText(info);
        }
    }
    setVisibleState();


@@ 36,7 36,6 @@ void PostUpdateWindow::onBeforeShow(ShowMode mode, SwitchData *data)

void PostUpdateWindow::setVisibleState()
{
    successImage->setVisible(true);
    bottomBar->setActive(BottomBar::Side::CENTER, true);
}



@@ 67,31 66,23 @@ top_bar::Configuration PostUpdateWindow::configureTopBar(top_bar::Configuration 

void PostUpdateWindow::buildInterface()
{
    namespace post_update_style = style::window::pin_lock;
    AppWindow::buildInterface();

    setTitle(utils::translate("app_desktop_update_muditaos"));

    bottomBar->setText(BottomBar::Side::CENTER, utils::translate("common_ok"));

    successImage =
        new gui::Image(this, post_update_style::image::x, post_update_style::image::y, 0, 0, "circle_success");
    infoText = new Text(this,
                        post_update_style::primary_text::x,
                        post_update_style::primary_text::y,
                        post_update_style::primary_text::w,
                        post_update_style::primary_text::h);
    infoText->setAlignment(Alignment::Horizontal::Center);
    infoIcon = new gui::Icon(this,
                             style::window::default_left_margin,
                             style::header::height,
                             style::window::default_body_width,
                             style::window::default_body_height,
                             "circle_success",
                             "");
    infoIcon->setAlignment(Alignment::Horizontal::Center);
}

void PostUpdateWindow::destroyInterface()
{
    erase();
    invalidate();
}

void PostUpdateWindow::invalidate() noexcept
{
    successImage = nullptr;
    infoText     = nullptr;
}

M module-apps/application-desktop/windows/PostUpdateWindow.hpp => module-apps/application-desktop/windows/PostUpdateWindow.hpp +2 -5
@@ 5,18 5,15 @@

#include <module-apps/windows/AppWindow.hpp>
#include <module-gui/gui/widgets/Text.hpp>
#include <module-gui/gui/widgets/Image.hpp>
#include <module-gui/gui/widgets/Icon.hpp>

namespace gui
{
    class PostUpdateWindow : public AppWindow
    {
        gui::Image *successImage = nullptr;
        gui::Text *infoText      = nullptr;
        Icon *infoIcon = nullptr;

        void setVisibleState();
        void invalidate() noexcept;

        std::string currentOsVersion;

      public:

M module-apps/application-onboarding/windows/OnBoardingSimSelectWindow.cpp => module-apps/application-onboarding/windows/OnBoardingSimSelectWindow.cpp +2 -2
@@ 51,7 51,7 @@ namespace gui
        options.emplace_back(std::make_unique<gui::option::OptionSettings>(
            "SIM1",
            [=](const gui::Item &item) {
                application->getPhoneLockSubject().setPhoneLock();
                application->getSimLockSubject().setSim(cellular::api::SimSlot::SIM1);
                return true;
            },
            nullptr,


@@ 61,7 61,7 @@ namespace gui
        options.emplace_back(std::make_unique<gui::option::OptionSettings>(
            "SIM2",
            [=](const gui::Item &item) {
                application->getPhoneLockSubject().setPhoneLock();
                application->getSimLockSubject().setSim(cellular::api::SimSlot::SIM2);
                return true;
            },
            nullptr,

M module-apps/application-settings-new/ApplicationSettings.cpp => module-apps/application-settings-new/ApplicationSettings.cpp +7 -9
@@ 59,8 59,6 @@
#include <application-settings-new/data/AutoLockData.hpp>

#include <service-evtmgr/EventManagerServiceAPI.hpp>
#include <service-cellular/CellularServiceAPI.hpp>
#include <service-cellular-api>
#include <service-bluetooth/BluetoothMessage.hpp>
#include <service-bluetooth/Constants.hpp>
#include <service-bluetooth/messages/Status.hpp>


@@ 82,7 80,6 @@
#include <module-apps/application-desktop/windows/Names.hpp>
#include <module-apps/messages/DialogMetadataMessage.hpp>
#include <module-apps/windows/Dialog.hpp>
#include <locks/windows/PinLockWindow.hpp>

#include <i18n/i18n.hpp>



@@ 433,9 430,6 @@ namespace app
        windowsFactory.attach(gui::window::name::security, [](Application *app, const std::string &name) {
            return std::make_unique<gui::SecurityMainWindow>(app, static_cast<ApplicationSettingsNew *>(app));
        });
        windowsFactory.attach(app::window::name::desktop_pin_lock, [&](Application *app, const std::string newname) {
            return std::make_unique<gui::PinLockWindow>(app, app::window::name::desktop_pin_lock);
        });
        windowsFactory.attach(gui::window::name::dialog_confirm, [](Application *app, const std::string &name) {
            return std::make_unique<gui::DialogConfirm>(app, gui::window::name::dialog_confirm);
        });


@@ 514,8 508,12 @@ namespace app
                              [](Application *app, const std::string &name) {
                                  return std::make_unique<gui::BluetoothCheckPasskeyWindow>(app);
                              });
        attachPopups(
            {gui::popup::ID::Volume, gui::popup::ID::Tethering, gui::popup::ID::PhoneModes, gui::popup::ID::PhoneLock});

        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::PhoneModes,
                      gui::popup::ID::PhoneLock,
                      gui::popup::ID::SimLock});
    }

    void ApplicationSettingsNew::destroyUserInterface()


@@ 529,7 527,7 @@ namespace app
    void ApplicationSettingsNew::setSim(Store::GSM::SIM sim)
    {
        auto arg = (sim == Store::GSM::SIM::SIM2) ? cellular::api::SimSlot::SIM2 : cellular::api::SimSlot::SIM1;
        bus.sendUnicast<cellular::msg::request::sim::SetActiveSim>(arg);
        getSimLockSubject().setSim(arg);
    }

    Store::GSM::SIM ApplicationSettingsNew::getSim()

M module-apps/application-settings-new/windows/PINSettingsWindow.cpp => module-apps/application-settings-new/windows/PINSettingsWindow.cpp +4 -11
@@ 8,7 8,7 @@
#include "OptionSetting.hpp"

#include <service-appmgr/Controller.hpp>
#include <service-appmgr/service-appmgr/data/SimActionsParams.hpp>
#include <locks/data/SimLockMessages.hpp>
#include <service-cellular-api>

namespace gui


@@ 56,11 56,7 @@ namespace gui
            optionList.emplace_back(std::make_unique<option::OptionSettings>(
                utils::translate("app_settings_network_pin_change_code"),
                [=](Item & /*item*/) {
                    using namespace app::manager::actions;
                    auto params = std::make_unique<PasscodeParams>(Store::GSM::get()->selected,
                                                                   PasscodeParams::numOfAttemptsForEnteringPIN,
                                                                   PasscodeParams::pinName);
                    app::manager::Controller::sendAction(application, RequestPinChange, std::move(params));
                    application->getSimLockSubject().changeSimPin();
                    return true;
                },
                nullptr,


@@ 75,14 71,11 @@ namespace gui
    {
        currentState = !currentState;
        refreshOptionsList();
        using namespace app::manager::actions;
        auto params = std::make_unique<PasscodeParams>(
            Store::GSM::get()->selected, PasscodeParams::numOfAttemptsForEnteringPIN, PasscodeParams::pinName);
        if (!currentState) {
            app::manager::Controller::sendAction(application, RequestPinDisable, std::move(params));
            application->getSimLockSubject().disableSimPin();
        }
        else {
            app::manager::Controller::sendAction(application, RequestPinEnable, std::move(params));
            application->getSimLockSubject().enableSimPin();
        }
    }
} // namespace gui

M module-apps/application-settings-new/windows/SecurityMainWindow.cpp => module-apps/application-settings-new/windows/SecurityMainWindow.cpp +0 -27
@@ 44,33 44,6 @@ namespace gui
            nullptr,
            isPhoneLockEnabled ? option::SettingRightItem::On : option::SettingRightItem::Off));

        optionList.emplace_back(std::make_unique<option::OptionSettings>(
            utils::translate("app_settings_security_usb_passcode"),
            [=](Item &item) {
                auto lock = std::make_unique<locks::Lock>(
                    Store::GSM::SIM::NONE, locks::Lock::LockState::InputRequired, locks::Lock::LockType::Screen);
                lock->onActivatedCallback = [this](locks::Lock::LockType type, const std::vector<unsigned int> &data) {
                    securitySettings->setUSBSecurity(!securitySettings->isUSBSecured());
                    application->returnToPreviousWindow();
                };
                application->switchWindow(
                    app::window::name::desktop_pin_lock,
                    gui::ShowMode::GUI_SHOW_INIT,
                    std::make_unique<locks::LockData>(*lock, locks::PhoneLockInputTypeAction::Change));
                return true;
            },
            [=](Item &item) {
                if (item.focus) {
                    this->setBottomBarText(utils::translate(style::strings::common::Switch), BottomBar::Side::CENTER);
                }
                else {
                    this->setBottomBarText(utils::translate(style::strings::common::select), BottomBar::Side::CENTER);
                }
                return true;
            },
            nullptr,
            securitySettings->isUSBSecured() ? option::SettingRightItem::On : option::SettingRightItem::Off));

        if (isPhoneLockEnabled) {
            optionList.emplace_back(std::make_unique<option::OptionSettings>(
                utils::translate("app_settings_security_change_phone_lock"),

M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +1 -20
@@ 20,10 20,7 @@

#include "ApplicationSettings.hpp"

#include "service-cellular/ServiceCellular.hpp"
#include <service-cellular-api>
#include "windows/SettingsMainWindow.hpp"
#include "windows/SimSelectWindow.hpp"
#include "windows/CellularPassthroughWindow.hpp"

#include <i18n/i18n.hpp>


@@ 45,13 42,7 @@ namespace app
                                             sys::phone_modes::PhoneMode mode,
                                             StartInBackground startInBackground)
        : Application(name, parent, mode, startInBackground)
    {
        bus.channels.push_back(sys::BusChannel::AntennaNotifications);
        addActionReceiver(manager::actions::SelectSimCard, [this](auto &&data) {
            switchWindow(app::sim_select);
            return actionHandled();
        });
    }
    {}

    ApplicationSettings::~ApplicationSettings()
    {}


@@ 116,10 107,6 @@ namespace app
            return std::make_unique<gui::OptionWindow>(
                app, utils::translate("app_settings_title_main"), mainWindowOptions(app));
        });

        windowsFactory.attach(app::sim_select, [this](Application *app, const std::string &name) {
            return std::make_unique<gui::OptionWindow>(app, name, simSelectWindow(app, this));
        });
        windowsFactory.attach("Languages", [](Application *app, const std::string &name) {
            return std::make_unique<gui::LanguageWindow>(app);
        });


@@ 162,12 149,6 @@ namespace app
    void ApplicationSettings::destroyUserInterface()
    {}

    void ApplicationSettings::setSim(Store::GSM::SIM sim)
    {
        auto arg = (sim == Store::GSM::SIM::SIM2) ? cellular::api::SimSlot::SIM2 : cellular::api::SimSlot::SIM1;
        bus.sendUnicast<cellular::msg::request::sim::SetActiveSim>(arg);
    }

    void ApplicationSettings::timeDateChanged(std::string value)
    {
        auto newTimeDateFormat = utils::getNumericValue<bool>(value);

M module-apps/application-settings/ApplicationSettings.hpp => module-apps/application-settings/ApplicationSettings.hpp +2 -13
@@ 10,18 10,9 @@

namespace app
{

    inline constexpr auto name_settings  = "ApplicationSettings";
    inline constexpr auto sim_select     = "SimSelect";

    class SimSetter
    {
      public:
        virtual ~SimSetter()                     = default;
        virtual void setSim(Store::GSM::SIM sim) = 0;
    };

    class ApplicationSettings : public app::Application, public SimSetter
    class ApplicationSettings : public app::Application
    {
      public:
        ApplicationSettings(std::string name                    = name_settings,


@@ 41,11 32,9 @@ namespace app
        void createUserInterface() override;
        void destroyUserInterface() override;
        bsp::Board board = bsp::Board::none;
        void setSim(Store::GSM::SIM sim) override;
        void timeDateChanged(std::string value);

      private:
        unsigned int lockPassHash;
        bool europeanDateTimeFormat = false; // true europe format, false american format
    };



@@ 53,7 42,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch, manager::actions::SelectSimCard, manager::actions::PhoneModeChanged}};
            return {{manager::actions::Launch, manager::actions::PhoneModeChanged}};
        }
    };
} /* namespace app */

M module-apps/application-settings/CMakeLists.txt => module-apps/application-settings/CMakeLists.txt +0 -1
@@ 21,7 21,6 @@ target_sources( ${PROJECT_NAME}
        windows/BtScanWindow.cpp
        windows/UITestWindow.cpp
        windows/Info.cpp
        windows/SimSelectWindow.cpp
        windows/DateTimeWindow.cpp
        windows/CellularPassthroughWindow.cpp
        windows/FotaWindow.cpp

M module-apps/application-settings/windows/SettingsMainWindow.cpp => module-apps/application-settings/windows/SettingsMainWindow.cpp +0 -1
@@ 33,7 33,6 @@ std::list<gui::Option> mainWindowOptions(app::Application *app)
    addMenu("UI TEST", "TEST_UI");
    addMenu(i18("app_settings_bt"), "Bluetooth");
    addMenu(i18("app_settings_language"), "Languages");
    addMenu("SIM SELECT", app::sim_select);
    addMenu(i18("app_settings_date_and_time"), "DateTime");
    if (dynamic_cast<app::ApplicationSettings *>(app)->board == bsp::Board::T4) {
        addMenu(i18("app_settings_cellular_passthrough"), gui::window::cellular_passthrough::window_name);

D module-apps/application-settings/windows/SimSelectWindow.cpp => module-apps/application-settings/windows/SimSelectWindow.cpp +0 -32
@@ 1,32 0,0 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SimSelectWindow.hpp"
#include "Info.hpp"
#include "SettingsMainWindow.hpp"
#include <i18n/i18n.hpp>
#include "log/log.hpp"
#include <common_data/EventStore.hpp>
#include <service-db/DBServiceAPI.hpp>
#include <service-db/Settings.hpp>
#include <module-utils/Utils.hpp>
#include <module-services/service-db/agents/settings/SystemSettings.hpp>
#include <module-apps/application-settings/ApplicationSettings.hpp>

std::list<gui::Option> simSelectWindow(app::Application *app, app::SimSetter *setter)
{
    std::list<gui::Option> l;
    l.emplace_back(gui::Option{"SIM 1",
                               [=](gui::Item &item) {
                                   setter->setSim(Store::GSM::SIM::SIM1);
                                   return true;
                               },
                               gui::option::Arrow::Disabled});
    l.emplace_back(gui::Option{"SIM 2",
                               [=](gui::Item &item) {
                                   setter->setSim(Store::GSM::SIM::SIM2);
                                   return true;
                               },
                               gui::option::Arrow::Disabled});
    return l;
}

D module-apps/application-settings/windows/SimSelectWindow.hpp => module-apps/application-settings/windows/SimSelectWindow.hpp +0 -13
@@ 1,13 0,0 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <OptionWindow.hpp>
namespace app
{
    class Application;
    class SimSetter;
} // namespace app

std::list<gui::Option> simSelectWindow(app::Application *app, app::SimSetter *setter);
\ No newline at end of file

M module-apps/locks/CMakeLists.txt => module-apps/locks/CMakeLists.txt +11 -12
@@ 14,16 14,15 @@ include_directories( ${PROJECT_NAME}
target_sources( ${PROJECT_NAME}

	PRIVATE
		"${CMAKE_CURRENT_LIST_DIR}/handlers/PinLockHandler.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/PhoneLockHandler.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/PhoneLockSubject.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/SimLockHandler.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/SimLockSubject.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/LockPolicyHandler.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/LockWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/PinLockBaseWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/PinLockWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/LockInputWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/Lock.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/PukLockBox.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/PhoneLockBaseBox.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/LockBoxConstantSize.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/LockBoxAlternatingSize.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/PhoneLockBox.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/SimLockBox.cpp"



@@ 31,18 30,18 @@ target_sources( ${PROJECT_NAME}
		"${CMAKE_CURRENT_LIST_DIR}/data/LockData.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/data/LockStyle.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/data/PhoneLockMessages.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/PinLockHandler.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/data/SimLockMessages.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/PhoneLockHandler.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/PhoneLockSubject.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/LockPolicyHandler.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/LockWindow.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/PinLockBaseWindow.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/PinLockWindow.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/SimLockHandler.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/handlers/SimLockSubject.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/windows/LockInputWindow.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/LockHash.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/Lock.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/LockBox.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/PukLockBox.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/PhoneLockBaseBox.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/LockBoxConstantSize.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/LockBoxAlternatingSize.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/PhoneLockBox.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/widgets/SimLockBox.hpp"
)

M module-apps/locks/data/LockData.hpp => module-apps/locks/data/LockData.hpp +35 -1
@@ 4,12 4,13 @@
#pragma once

#include <memory>
#include <utility>
#include "gui/SwitchData.hpp"
#include "locks/widgets/Lock.hpp"

namespace locks
{
    using LockInput = const std::vector<unsigned int> &;

    enum class PhoneLockInputTypeAction
    {
        Unlock,


@@ 20,6 21,17 @@ namespace locks
        Set
    };

    enum class SimInputTypeAction
    {
        UnlockWithPin,
        UnlockWithPuk,
        ChangePin,
        EnablePin,
        DisablePin,
        Blocked,
        Error,
    };

    // class template that stores information that was sent along with switch message
    class LockData : public gui::SwitchData
    {


@@ 45,4 57,26 @@ namespace locks
        }
    };

    class SimLockData : public LockData
    {
        SimInputTypeAction simInputTypeAction;
        unsigned int errorCode;

      public:
        explicit SimLockData(Lock lock, SimInputTypeAction simInputTypeAction, unsigned int errorCode)
            : LockData(std::move(lock)), simInputTypeAction(simInputTypeAction), errorCode(errorCode)
        {
            description = "SimLockPhoneData";
        }

        [[nodiscard]] auto getSimInputTypeAction() const noexcept
        {
            return simInputTypeAction;
        }

        [[nodiscard]] auto getErrorCode() const noexcept
        {
            return errorCode;
        }
    };
} // namespace locks

M module-apps/locks/data/LockStyle.hpp => module-apps/locks/data/LockStyle.hpp +15 -42
@@ 1,42 1,33 @@
// 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

#include "gui/widgets/Style.hpp"

namespace style::window::pin_lock
namespace style::window::lock_input
{
    namespace image
    {
        constexpr inline auto x = 177;
        constexpr inline auto y = 132;
        constexpr inline auto wh                  = 128;
        constexpr inline auto image_top_margin    = 30;
        constexpr inline auto image_bottom_margin = 33;
    } // namespace image

    namespace pin_label
    namespace input_box
    {
        constexpr inline auto x = 85;
        constexpr inline auto y = 400;
        constexpr inline auto w = style::window_width - 2 * x;

        constexpr inline auto size   = 60;
        constexpr inline auto margin = 10;
        constexpr inline auto w            = style::window::default_body_width;
        constexpr inline auto h            = 60;
        constexpr inline auto label_margin = 10;
        constexpr inline auto top_margin   = 30;
    } // namespace pin_label

    namespace title
    {
        constexpr inline auto x = 0;
        constexpr inline auto y = 60;
        constexpr inline auto w = style::window_width;
        constexpr inline auto h = 50;
    } // namespace title

    namespace ice
    {
        constexpr inline auto x = style::window::default_left_margin;
        constexpr inline auto y = title::y;
        constexpr inline auto y = 60;
        constexpr inline auto w = 60;
        constexpr inline auto h = title::h;
        constexpr inline auto h = 50;

        constexpr inline auto margin = 3;



@@ 49,31 40,13 @@ namespace style::window::pin_lock

    namespace primary_text
    {
        constexpr inline auto x = style::window::default_left_margin;
        constexpr inline auto y = 294;
        constexpr inline auto w = style::window_width - 2 * x;
        constexpr inline auto h = 60;
    } // namespace primary_text

    namespace secondary_text
    {
        constexpr inline auto x = style::window::default_left_margin;
        constexpr inline auto y = primary_text::y + primary_text::h + 30;
        constexpr inline auto w = style::window_width - 2 * x;
        constexpr inline auto h = 90;
        constexpr inline auto top_margin = 30;
        constexpr inline auto h          = 90;
    } // namespace secondary_text

} // namespace style::window::pin_lock

namespace style::window::screen_pin_lock
{
    namespace pin_label
    {
        constexpr inline auto y = 248;
    } // namespace pin_label

    namespace primary_text
    {
        constexpr inline auto y = 160;
    } // namespace primary_text
} // namespace style::window::screen_pin_lock
} // namespace style::window::lock_input

A module-apps/locks/data/SimLockMessages.hpp => module-apps/locks/data/SimLockMessages.hpp +50 -0
@@ 0,0 1,50 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Service/Message.hpp>
#include <service-cellular-api>

namespace locks
{
    class UnLockSimInput : public sys::DataMessage
    {
      private:
        std::vector<unsigned int> inputData;

      public:
        explicit UnLockSimInput(std::vector<unsigned int> inputData) : DataMessage{}, inputData(std::move(inputData))
        {}

        [[nodiscard]] auto getInputData() const noexcept
        {
            return inputData;
        }
    };

    class SetSim : public sys::DataMessage
    {
      private:
        cellular::api::SimSlot simSlot;

      public:
        explicit SetSim(cellular::api::SimSlot simSlot) : DataMessage{}, simSlot(simSlot)
        {}

        [[nodiscard]] auto getSimSlot() const noexcept
        {
            return simSlot;
        }
    };

    class ChangeSimPin : public sys::DataMessage
    {};

    class EnableSimPin : public sys::DataMessage
    {};

    class DisableSimPin : public sys::DataMessage
    {};

} // namespace locks

M module-apps/locks/handlers/PhoneLockHandler.cpp => module-apps/locks/handlers/PhoneLockHandler.cpp +5 -5
@@ 1,5 1,5 @@
//// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
//// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PhoneLockHandler.hpp"



@@ 234,7 234,7 @@ namespace locks
        phoneInputRequiredAction();
    }

    sys::MessagePointer PhoneLockHandler::verifyPhoneLockInput(const std::vector<unsigned int> &inputData)
    sys::MessagePointer PhoneLockHandler::verifyPhoneLockInput(LockInput inputData)
    {
        if (checkPhoneLockInputTypeAction(PhoneLockInputTypeAction::Enable) ||
            checkPhoneLockInputTypeAction(PhoneLockInputTypeAction::Change) ||


@@ 246,7 246,7 @@ namespace locks
        }
    }

    sys::MessagePointer PhoneLockHandler::verifyPhoneUnlockInput(const std::vector<unsigned int> &inputData)
    sys::MessagePointer PhoneLockHandler::verifyPhoneUnlockInput(LockInput inputData)
    {
        const uint32_t hash = getHash(inputData);
        lock.attemptsLeft--;


@@ 269,7 269,7 @@ namespace locks
        return sys::msgHandled();
    }

    sys::MessagePointer PhoneLockHandler::verifyPhoneLockChangeInput(const std::vector<unsigned int> &inputData)
    sys::MessagePointer PhoneLockHandler::verifyPhoneLockChangeInput(LockInput inputData)
    {
        if (lock.isState(Lock::LockState::NewInputRequired) || lock.isState(Lock::LockState::NewInputInvalid)) {
            storedInputData = inputData;

M module-apps/locks/handlers/PhoneLockHandler.hpp => module-apps/locks/handlers/PhoneLockHandler.hpp +3 -3
@@ 49,8 49,8 @@ namespace locks
        void checkNewPhoneLock();
        void resolvePhoneLockAction();

        sys::MessagePointer verifyPhoneUnlockInput(const std::vector<unsigned int> &inputData);
        sys::MessagePointer verifyPhoneLockChangeInput(const std::vector<unsigned int> &inputData);
        sys::MessagePointer verifyPhoneUnlockInput(LockInput inputData);
        sys::MessagePointer verifyPhoneLockChangeInput(LockInput inputData);

      public:
        explicit PhoneLockHandler(sys::Service *owner, std::shared_ptr<settings::Settings> settings);


@@ 63,7 63,7 @@ namespace locks
        sys::MessagePointer handleChangePhoneLock();
        sys::MessagePointer handleSetPhoneLock();
        sys::MessagePointer handleSkipSetPhoneLock();
        sys::MessagePointer verifyPhoneLockInput(const std::vector<unsigned int> &inputData);
        sys::MessagePointer verifyPhoneLockInput(LockInput inputData);

        void enablePhoneLock(bool _phoneLockEnabled);
        void setPhoneLockHash(const std::string &value);

M module-apps/locks/handlers/PhoneLockSubject.cpp => module-apps/locks/handlers/PhoneLockSubject.cpp +3 -3
@@ 1,5 1,5 @@
//// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
//// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PhoneLockSubject.hpp"



@@ 50,7 50,7 @@ namespace locks
        owner->bus.sendUnicast(std::make_shared<SkipSetPhoneLock>(), app::manager::ApplicationManager::ServiceName);
    }

    void PhoneLockSubject::verifyInput(const std::vector<unsigned int> &inputData)
    void PhoneLockSubject::verifyInput(LockInput inputData)
    {
        owner->bus.sendUnicast(std::make_shared<UnLockPhoneInput>(inputData),
                               app::manager::ApplicationManager::ServiceName);

M module-apps/locks/handlers/PhoneLockSubject.hpp => module-apps/locks/handlers/PhoneLockSubject.hpp +2 -1
@@ 3,6 3,7 @@

#pragma once

#include <locks/data/LockData.hpp>
#include <module-sys/Service/Service.hpp>

namespace locks


@@ 22,7 23,7 @@ namespace locks
        void changePhoneLock();
        void setPhoneLock();
        void skipSetPhoneLock();
        void verifyInput(const std::vector<unsigned int> &inputData);
        void verifyInput(LockInput inputData);
    };

} // namespace locks

D module-apps/locks/handlers/PinLockHandler.cpp => module-apps/locks/handlers/PinLockHandler.cpp +0 -314
@@ 1,314 0,0 @@
//// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
//// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "locks/data/LockData.hpp"
#include "PinLockHandler.hpp"
#include "locks/widgets/LockHash.hpp"
#include "application-desktop/ApplicationDesktop.hpp"
#include "application-desktop/windows/Names.hpp"
#include <module-utils/common_data/EventStore.hpp>
#include <service-appmgr/service-appmgr/data/SimActionsParams.hpp>
#include <service-desktop/Constants.hpp>

#include <service-cellular/CellularMessage.hpp>
#include <service-cellular-api>

namespace gui
{
    namespace
    {
        constexpr unsigned int default_screen_pin_size = 4;
        constexpr unsigned int screen_nopin_size       = 0;
        constexpr unsigned int default_attempts        = 4;
        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)
        : app(app),
          screenLock(Store::GSM::SIM::NONE, Lock::LockState::InputRequired, Lock::LockType::Screen, default_attempts),
          simLock(Store::GSM::SIM::NONE, Lock::LockState::Unlocked, Lock::LockType::SimPin, default_attempts)
    {
        simLock.setInputSizeBounds(sim_min_passcode_size, sim_max_passcode_size);
        screenLock.setInputSizeBounds(default_screen_pin_size, default_screen_pin_size);
        screenLock.setAutoActivate(true);
    }

    void PinLockHandler::handlePasscodeParams(Lock::LockType type,
                                              Lock::LockState state,
                                              app::manager::actions::ActionParamsPtr &&data)
    {
        auto passcodeData = static_cast<app::manager::actions::PasscodeParams *>(data.get());
        if (simLock.isSim(passcodeData->getSim()) && simLock.isType(type) && simLock.isState(state) &&
            simLock.getAttemptsLeft() > passcodeData->getAttempts()) {
            simLock.lockState = Lock::LockState::InputInvalid;
        }
        else {
            simLock.lockState = state;
            simLock.sim       = passcodeData->getSim();
            simLock.lockType  = type;
        }
        simLock.lockName     = passcodeData->getPasscodeName();
        simLock.attemptsLeft = passcodeData->getAttempts();
    }

    void PinLockHandler::handlePasscodeRequest(Lock::LockType type, app::manager::actions::ActionParamsPtr &&data)
    {
        LOG_DEBUG("Handling on of PasscodeRequest actions");
        promptSimLockWindow = true;
        handlePasscodeParams(type, Lock::LockState::InputRequired, std::move(data));
        if (!getStrongestLock().isType(Lock::LockType::Screen)) {
            unlock();
        }
    }

    void PinLockHandler::handlePinChangeRequest(app::manager::actions::ActionParamsPtr &&data)
    {
        LOG_DEBUG("Handling RequestPinChange action");
        handlePasscodeParams(Lock::LockType::SimPin, Lock::LockState::InputRequired, std::move(data));
        promptSimLockWindow      = true;
        auto onActivatedCallback = [this](Lock::LockType type, const cellular::api::SimCode &data) {
            handlePasscodeChange(data);
        };
        switchToPinLockWindow(onActivatedCallback);
    }

    void PinLockHandler::handlePinEnableRequest(app::manager::actions::ActionParamsPtr &&data,
                                                cellular::api::SimLockState simCardLock)
    {
        using namespace cellular::msg;
        using namespace cellular::api;
        LOG_DEBUG("Handling PinEnableRequest action, simCardLock = %d", static_cast<int>(simCardLock));
        handlePasscodeParams(Lock::LockType::SimPin, Lock::LockState::InputRequired, std::move(data));
        promptSimLockWindow      = true;
        auto onActivatedCallback = [this, simCardLock](Lock::LockType, const cellular::api::SimCode &data) {
            app->bus.sendUnicast<request::sim::SetPinLock>(simCardLock, data);
        };
        switchToPinLockWindow(onActivatedCallback);
    }

    void PinLockHandler::handlePinEnableRequestFailed(cellular::api::SimLockState simCardLock)
    {
        LOG_DEBUG("Handling PinEnableRequestFailed action, simCardLock = %d, simLock.value = %u",
                  static_cast<int>(simCardLock),
                  simLock.attemptsLeft);
        using namespace app::manager::actions;
        if (simLock.attemptsLeft > 0) {
            --simLock.attemptsLeft;
        }
        else {
            LOG_ERROR("Number of attempts left is equal to zero before decrementation!");
        }
        if (simLock.attemptsLeft > 0) {
            simLock.lockState        = Lock::LockState::InputInvalid;
            auto onActivatedCallback = [this, simCardLock](Lock::LockType type, const cellular::api::SimCode &data) {
                auto params = std::make_unique<PasscodeParams>(
                    Store::GSM::get()->selected, simLock.attemptsLeft, PasscodeParams::pinName);
                handlePinEnableRequest(std::move(params), simCardLock);
            };
            switchToPinLockWindow(Lock::LockState::InputInvalid, onActivatedCallback);
        }
        else {
            auto params = std::make_unique<PasscodeParams>(
                Store::GSM::get()->selected, PasscodeParams::numOfAttemptsForEnteringPUK, PasscodeParams::pukName);
            handlePasscodeRequest(gui::Lock::LockType::SimPuk, std::move(params));
        }
    }

    void PinLockHandler::handlePinChangeRequestFailed()
    {
        LOG_DEBUG("Handling PinChangeRequestFailed action, simLock.value = %u", simLock.attemptsLeft);
        using namespace app::manager::actions;
        if (simLock.attemptsLeft > 0) {
            --simLock.attemptsLeft;
        }
        else {
            LOG_ERROR("Number of attempts left is equal to zero before decrementation!");
        }
        if (simLock.attemptsLeft > 0) {
            simLock.lockState        = Lock::LockState::InputInvalid;
            auto onActivatedCallback = [this](Lock::LockType type, const cellular::api::SimCode &data) {
                auto params = std::make_unique<PasscodeParams>(
                    Store::GSM::get()->selected, simLock.attemptsLeft, PasscodeParams::pinName);
                handlePinChangeRequest(std::move(params));
            };
            switchToPinLockWindow(Lock::LockState::InputInvalid, onActivatedCallback);
        }
        else {
            auto params = std::make_unique<PasscodeParams>(
                Store::GSM::get()->selected, PasscodeParams::numOfAttemptsForEnteringPUK, PasscodeParams::pukName);
            handlePasscodeRequest(gui::Lock::LockType::SimPuk, std::move(params));
        }
    }

    void PinLockHandler::handleSimBlocked(app::manager::actions::ActionParamsPtr &&data)
    {
        LOG_DEBUG("Handling BlockSim action");
        auto params          = static_cast<app::manager::actions::SimStateParams *>(data.get());
        promptSimLockWindow  = true;
        simLock.sim          = params->getSim();
        simLock.lockState    = gui::Lock::LockState::Blocked;
        simLock.lockType     = gui::Lock::LockType::SimPin;
        simLock.attemptsLeft = blocked_sim_attempts;
        unlock();
    }

    void PinLockHandler::handleUnlockSim(app::manager::actions::ActionParamsPtr &&data)
    {
        LOG_DEBUG("Handling UnlockSim action");
        promptSimLockWindow = false;
        if (!simLock.isState(Lock::LockState::Unlocked)) {
            simLock.lockState = Lock::LockState::Unlocked;
            unlock();
        }
    }

    void PinLockHandler::handleCMEError(app::manager::actions::ActionParamsPtr &&data) const
    {
        LOG_DEBUG("Handling DisplayCMEError action");
        auto params = static_cast<app::manager::actions::UnhandledCMEParams *>(data.get());
        auto lock   = std::make_unique<gui::Lock>(
            params->getSim(), Lock::LockState::ErrorOccurred, Lock::LockType::SimPin, params->getCMECode());
        lock->onActivatedCallback = [this](Lock::LockType type, const cellular::api::SimCode &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::LockData>(*lock));
    }

    void PinLockHandler::switchToPinLockWindow(
        std::function<void(Lock::LockType, const cellular::api::SimCode &)> onLockActivatedCallback)
    {
        auto lock = std::make_unique<gui::Lock>(getStrongestLock());
        if (lock->isState(Lock::LockState::InputInvalid)) {
            getStrongestLock().consumeState();
            lock->onActivatedCallback = [this, onLockActivatedCallback](Lock::LockType,
                                                                        const cellular::api::SimCode &) {
                switchToPinLockWindow(onLockActivatedCallback);
            };
        }
        else if (lock->isState(gui::Lock::LockState::Blocked)) {
            lock->onActivatedCallback = [this](Lock::LockType type, const cellular::api::SimCode &data) {
                setSimLockHandled();
                app->switchWindow(app::window::name::desktop_main_window);
            };
        }
        else if (lock->isState(gui::Lock::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::LockData>(*lock));
    }

    void PinLockHandler::switchToPinLockWindow(
        Lock::LockState state,
        std::function<void(Lock::LockType, const cellular::api::SimCode &)> onLockActivatedCallback)
    {
        auto lock                 = std::make_unique<gui::Lock>(getStrongestLock());
        lock->lockState           = state;
        lock->onActivatedCallback = onLockActivatedCallback;
        app->switchWindow(
            app::window::name::desktop_pin_lock, gui::ShowMode::GUI_SHOW_INIT, std::make_unique<gui::LockData>(*lock));
    }

    void PinLockHandler::handlePasscode(Lock::LockType type, const cellular::api::SimCode &passcode)
    {
        if (type == Lock::LockType::SimPin) {
            setSimLockHandled();
            app->bus.sendUnicast<cellular::msg::request::sim::PinUnlock>(passcode);
        }
        else if (type == Lock::LockType::SimPuk) {
            handlePasscodeChange(passcode);
        }
    }

    void PinLockHandler::handlePasscodeChange(const cellular::api::SimCode &passcode)
    {
        auto onActivatedCallback = [this, passcode](Lock::LockType, const cellular::api::SimCode &pin) {
            handleNewPasscodeUnconfirmed(passcode, pin);
        };
        switchToPinLockWindow(Lock::LockState::NewInputRequired, onActivatedCallback);
    }

    void PinLockHandler::handleNewPasscodeUnconfirmed(const cellular::api::SimCode &passcode,
                                                      const cellular::api::SimCode &pin)
    {
        auto onActivatedCallback = [this, passcode, pin](Lock::LockType type,
                                                         const cellular::api::SimCode &pinConfirmed) {
            if (pin == pinConfirmed) {
                handleNewPasscodeConfirmed(type, passcode, pin);
            }
            else {
                handleNewPasscodeInvalid(passcode);
            }
        };
        switchToPinLockWindow(Lock::LockState::NewInputConfirmRequired, onActivatedCallback);
    }

    void PinLockHandler::handleNewPasscodeConfirmed(Lock::LockType type,
                                                    const cellular::api::SimCode &passcode,
                                                    const cellular::api::SimCode &pin)
    {
        using namespace cellular::msg;
        if (type == Lock::LockType::SimPin) {
            app->bus.sendUnicast<request::sim::ChangePin>(passcode, pin);
        }
        else if (type == Lock::LockType::SimPuk) {
            app->bus.sendUnicast<request::sim::UnblockWithPuk>(passcode, pin);
        }
    }

    void PinLockHandler::handleNewPasscodeInvalid(const cellular::api::SimCode &passcode)
    {
        auto onActivatedCallback = [this, passcode](Lock::LockType type, const cellular::api::SimCode &pin) {
            handlePasscodeChange(passcode);
        };
        switchToPinLockWindow(Lock::LockState::NewInputInvalid, onActivatedCallback);
    }
    void PinLockHandler::unlock()
    {
        auto onActivatedCallback = [this](Lock::LockType type, const cellular::api::SimCode &data) {
            handlePasscode(type, data);
        };
        switchToPinLockWindow(onActivatedCallback);
    }

    auto PinLockHandler::getStrongestLock() noexcept -> gui::Lock &
    {
        if (!screenLock.isState(Lock::LockState::Unlocked)) {
            return screenLock;
        }
        else if (promptSimLockWindow && !simLock.isState(Lock::LockState::Unlocked)) {
            return simLock;
        }
        return screenLock;
    }

    void PinLockHandler::lockScreen()
    {
        screenLock.lockState = Lock::LockState::InputRequired;
    }

    void PinLockHandler::unlockScreen()
    {
        if (getStrongestLock().isType(Lock::LockType::Screen)) {
            screenLock.lockState = gui::Lock::LockState::Unlocked;
        }
    }

    void PinLockHandler::setSimLockHandled() noexcept
    {
        if (!getStrongestLock().isType(Lock::LockType::Screen)) {
            promptSimLockWindow = false;
        }
    }

} // namespace gui

D module-apps/locks/handlers/PinLockHandler.hpp => module-apps/locks/handlers/PinLockHandler.hpp +0 -72
@@ 1,72 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "locks/widgets/Lock.hpp"

#include <module-services/service-appmgr/service-appmgr/messages/ActionRequest.hpp>
#include <module-services/service-appmgr/service-appmgr/Actions.hpp>
#include <service-cellular/api/common.hpp>

namespace app
{
    class ApplicationDesktop;
}

namespace gui
{
    using namespace locks;

    class PinLockHandler
    {
        app::ApplicationDesktop *app = nullptr;
        Lock screenLock;
        Lock simLock;
        bool promptSimLockWindow = true;

        void handlePasscode(Lock::LockType type, const cellular::api::SimCode &passcode);
        void handlePasscodeChange(const cellular::api::SimCode &passcode);
        void handleNewPasscodeUnconfirmed(const cellular::api::SimCode &passcode, const cellular::api::SimCode &pin);
        void handleNewPasscodeConfirmed(Lock::LockType type,
                                        const cellular::api::SimCode &passcode,
                                        const cellular::api::SimCode &pin);
        void handleNewPasscodeInvalid(const cellular::api::SimCode &passcode);
        void handlePasscodeParams(Lock::LockType type,
                                  Lock::LockState state,
                                  app::manager::actions::ActionParamsPtr &&data);
        void switchToPinLockWindow(
            std::function<void(Lock::LockType, const cellular::api::SimCode &)> onLockActivatedCallback);
        void switchToPinLockWindow(
            Lock::LockState type,
            std::function<void(Lock::LockType, const cellular::api::SimCode &)> onLockActivatedCallback);

        auto getStrongestLock() noexcept -> gui::Lock &;
        void unlock();
        void setSimLockHandled() noexcept;

      public:
        PinLockHandler(app::ApplicationDesktop *app);

        void handlePasscodeRequest(Lock::LockType type, app::manager::actions::ActionParamsPtr &&data);
        void handlePinChangeRequest(app::manager::actions::ActionParamsPtr &&data);
        void handlePinEnableRequest(app::manager::actions::ActionParamsPtr &&data,
                                    cellular::api::SimLockState simCardLock);
        void handlePinEnableRequestFailed(cellular::api::SimLockState simCardLock);
        void handleSimBlocked(app::manager::actions::ActionParamsPtr &&data);
        void handleUnlockSim(app::manager::actions::ActionParamsPtr &&data);
        void handleCMEError(app::manager::actions::ActionParamsPtr &&data) const;
        void handlePinChangeRequestFailed();

        [[nodiscard]] auto isScreenLocked() const noexcept -> bool
        {
            return !screenLock.isState(Lock::LockState::Unlocked);
        }
        [[nodiscard]] auto isScreenBlocked() const noexcept -> bool
        {
            return screenLock.isState(Lock::LockState::Blocked);
        }
        void lockScreen();
        void unlockScreen();
    };
} // namespace gui

A module-apps/locks/handlers/SimLockHandler.cpp => module-apps/locks/handlers/SimLockHandler.cpp +354 -0
@@ 0,0 1,354 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SimLockHandler.hpp"

#include <service-appmgr/service-appmgr/Controller.hpp>
#include <locks/widgets/LockHash.hpp>
#include <Utils.hpp>
#include <memory>

#include <module-apps/popups/data/PopupRequestParams.hpp>
#include <service-cellular-api>
#include <module-utils/common_data/EventStore.hpp>

namespace locks
{
    constexpr unsigned int default_attempts = 4;
    constexpr unsigned int max_input_size   = 8;
    constexpr unsigned int min_input_size   = 4;

    SimLockHandler::SimLockHandler(sys::Service *owner)
        : owner(owner), lock(Lock::LockState::Unlocked, default_attempts)
    {
        lock.setInputSizeBounds(min_input_size, max_input_size);
    }

    void SimLockHandler::clearStoredInputs()
    {
        storedFirstInput.clear();
        storedSecondInput.clear();
    }

    void SimLockHandler::setSimInputTypeAction(SimInputTypeAction _simInputTypeAction)
    {
        if (simInputTypeAction != _simInputTypeAction) {
            simInputTypeAction = _simInputTypeAction;
            lock.lockState     = Lock::LockState::Unlocked;
        }
    }

    void SimLockHandler::simInputRequiredAction()
    {
        app::manager::Controller::sendAction(
            owner,
            app::manager::actions::ShowPopup,
            std::make_unique<gui::SimUnlockInputRequestParams>(gui::popup::ID::SimLock, lock, simInputTypeAction));
    }

    void SimLockHandler::simErrorAction(unsigned int errorCode)
    {
        app::manager::Controller::sendAction(owner,
                                             app::manager::actions::ShowPopup,
                                             std::make_unique<gui::SimUnlockInputRequestParams>(
                                                 gui::popup::ID::SimLock, lock, simInputTypeAction, errorCode));
    }

    void SimLockHandler::simUnlockAction()
    {
        app::manager::Controller::sendAction(owner,
                                             app::manager::actions::AbortPopup,
                                             std::make_unique<gui::PopupRequestParams>(gui::popup::ID::SimLock));
    }

    void SimLockHandler::simInfoAction()
    {
        app::manager::Controller::sendAction(
            owner,
            app::manager::actions::ShowPopup,
            std::make_unique<gui::SimUnlockInputRequestParams>(gui::popup::ID::SimInfo, lock, simInputTypeAction));
    }

    void SimLockHandler::getSettingsSimSelect(const std::string &settingsSim)
    {
        auto selectedSim            = magic_enum::enum_cast<Store::GSM::SIM>(settingsSim);
        Store::GSM::get()->selected = selectedSim.value();

        if ((selectedSim.value() == Store::GSM::SIM::SIM1 || selectedSim.value() == Store::GSM::SIM::SIM2)) {
            setSim(static_cast<cellular::api::SimSlot>(selectedSim.value()));
        }
        else {
            Store::GSM::get()->selected = Store::GSM::SIM::NONE;
        }
    }

    void SimLockHandler::setSim(cellular::api::SimSlot simSlot)
    {
        owner->bus.sendUnicast<cellular::msg::request::sim::SetActiveSim>(simSlot);
    }

    sys::MessagePointer SimLockHandler::handleSimPinRequest(unsigned int attempts)
    {
        setSimInputTypeAction(SimInputTypeAction::UnlockWithPin);
        lock.attemptsLeft = attempts;
        lock.lockName     = utils::enumToString(Store::GSM::get()->selected);

        if (simUnlockBlockOnLockedPhone) {
            return sys::msgNotHandled();
        }

        if (lock.isState(Lock::LockState::Unlocked)) {
            lock.lockState = Lock::LockState::InputRequired;
        }
        else if (lock.isState(Lock::LockState::InputRequired)) {
            lock.lockState = Lock::LockState::InputInvalid;
        }

        simInputRequiredAction();
        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::handleSimPukRequest(unsigned int attempts)
    {
        setSimInputTypeAction(SimInputTypeAction::UnlockWithPuk);
        lock.attemptsLeft = attempts;
        lock.lockName     = utils::enumToString(Store::GSM::get()->selected);

        if (simUnlockBlockOnLockedPhone) {
            return sys::msgNotHandled();
        }

        clearStoredInputs();

        if (lock.isState(Lock::LockState::Unlocked)) {
            lock.lockState = Lock::LockState::InputRequired;
        }
        else if (lock.isState(Lock::LockState::InputRequired) ||
                 lock.isState(Lock::LockState::NewInputConfirmRequired)) {
            lock.lockState = Lock::LockState::InputInvalid;
        }

        simInputRequiredAction();

        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::handleSimUnlockedMessage()
    {
        lock.lockState = Lock::LockState::Unlocked;

        if (simInputTypeAction == SimInputTypeAction::UnlockWithPuk ||
            simInputTypeAction == SimInputTypeAction::ChangePin) {
            simInfoAction();
        }

        simUnlockAction();

        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::handleSimChangedMessage()
    {
        lock.lockState = Lock::LockState::Unlocked;
        simInfoAction();
        simUnlockAction();

        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::handleSimAvailabilityMessage()
    {
        lock.lockState = Lock::LockState::Unlocked;
        simInfoAction();
        simUnlockAction();

        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::handleSimPinChangeRequest()
    {
        setSimInputTypeAction(SimInputTypeAction::ChangePin);

        lock.lockName  = utils::enumToString(Store::GSM::get()->selected);
        lock.lockState = Lock::LockState::InputRequired;
        simInputRequiredAction();

        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::handleSimPinChangeFailedRequest()
    {
        clearStoredInputs();

        lock.lockName  = utils::enumToString(Store::GSM::get()->selected);
        lock.lockState = Lock::LockState::InputInvalid;
        simInputRequiredAction();

        return sys::MessagePointer();
    }

    sys::MessagePointer SimLockHandler::handleSimEnableRequest()
    {
        setSimInputTypeAction(SimInputTypeAction::EnablePin);

        lock.lockName  = utils::enumToString(Store::GSM::get()->selected);
        lock.lockState = Lock::LockState::InputRequired;
        simInputRequiredAction();

        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::handleSimDisableRequest()
    {
        setSimInputTypeAction(SimInputTypeAction::DisablePin);

        lock.lockName  = utils::enumToString(Store::GSM::get()->selected);
        lock.lockState = Lock::LockState::InputRequired;
        simInputRequiredAction();

        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::handleSimBlockedRequest()
    {
        setSimInputTypeAction(SimInputTypeAction::Blocked);

        if (simUnlockBlockOnLockedPhone) {
            return sys::msgNotHandled();
        }

        lock.lockName  = utils::enumToString(Store::GSM::get()->selected);
        lock.lockState = Lock::LockState::Blocked;
        simInputRequiredAction();

        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::handleCMEErrorRequest(unsigned int errorCode)
    {
        setSimInputTypeAction(SimInputTypeAction::Error);

        if (simUnlockBlockOnLockedPhone) {
            storedErrorCode = errorCode;
            return sys::msgNotHandled();
        }

        lock.lockName  = utils::enumToString(Store::GSM::get()->selected);
        lock.lockState = Lock::LockState::ErrorOccurred;
        simErrorAction(errorCode);

        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::processLockWithNewInput(LockInput inputData)
    {
        if (lock.isState(Lock::LockState::InputRequired) || (lock.isState(Lock::LockState::InputInvalid))) {

            storedFirstInput = inputData;
            lock.lockState   = Lock::LockState::NewInputRequired;
            simInputRequiredAction();
        }
        else if (lock.isState(Lock::LockState::NewInputRequired) || lock.isState(Lock::LockState::NewInputInvalid)) {

            storedSecondInput = inputData;
            lock.lockState    = Lock::LockState::NewInputConfirmRequired;
            simInputRequiredAction();
        }
        else if (lock.isState(Lock::LockState::NewInputConfirmRequired)) {

            if (storedSecondInput == inputData) {
                return resolveNewInputAction(storedFirstInput, inputData);
            }

            lock.lockState = Lock::LockState::NewInputInvalid;
            simInputRequiredAction();
        }
        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::verifySimLockInput(LockInput inputData)
    {
        switch (simInputTypeAction) {
        case SimInputTypeAction::UnlockWithPin:
            return unlockSimWithPin(inputData);
        case SimInputTypeAction::UnlockWithPuk:
            return processLockWithNewInput(inputData);
        case SimInputTypeAction::ChangePin:
            return processLockWithNewInput(inputData);
        case SimInputTypeAction::EnablePin:
            return enableSimPin(inputData);
        case SimInputTypeAction::DisablePin:
            return disableSimPin(inputData);
        default:
            return sys::msgNotHandled();
        }
    }

    void SimLockHandler::setSimUnlockBlockOnLockedPhone()
    {
        simUnlockBlockOnLockedPhone = true;
    }

    sys::MessagePointer SimLockHandler::releaseSimUnlockBlockOnLockedPhone()
    {
        if (simUnlockBlockOnLockedPhone) {
            simUnlockBlockOnLockedPhone = false;
            if (simInputTypeAction == SimInputTypeAction::UnlockWithPin) {
                return handleSimPinRequest(lock.getAttemptsLeft());
            }
            else if (simInputTypeAction == SimInputTypeAction::UnlockWithPuk) {
                return handleSimPukRequest(lock.getAttemptsLeft());
            }
            else if (simInputTypeAction == SimInputTypeAction::Blocked) {
                return handleSimBlockedRequest();
            }
            else if (simInputTypeAction == SimInputTypeAction::Error) {
                return handleCMEErrorRequest(storedErrorCode);
            }
        }
        return sys::msgNotHandled();
    }

    sys::MessagePointer SimLockHandler::resolveNewInputAction(LockInput firstInputData, LockInput secondInputData)
    {
        if (simInputTypeAction == SimInputTypeAction::UnlockWithPuk) {
            return unlockSimWithPuk(firstInputData, secondInputData);
        }
        else if (simInputTypeAction == SimInputTypeAction::ChangePin) {
            return changeSimPin(firstInputData, secondInputData);
        }
        return sys::msgNotHandled();
    }

    sys::MessagePointer SimLockHandler::unlockSimWithPin(LockInput pinInputData)
    {
        owner->bus.sendUnicast<cellular::msg::request::sim::PinUnlock>(pinInputData);
        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::unlockSimWithPuk(LockInput pukInputData, LockInput newPinInputData)
    {
        owner->bus.sendUnicast<cellular::msg::request::sim::UnblockWithPuk>(pukInputData, newPinInputData);
        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::changeSimPin(LockInput oldPinInputData, LockInput newPinInputData)
    {
        owner->bus.sendUnicast<cellular::msg::request::sim::ChangePin>(oldPinInputData, newPinInputData);
        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::enableSimPin(LockInput pinInputData)
    {
        owner->bus.sendUnicast<cellular::msg::request::sim::SetPinLock>(cellular::api::SimLockState::Enabled,
                                                                        pinInputData);
        return sys::msgHandled();
    }

    sys::MessagePointer SimLockHandler::disableSimPin(LockInput pinInputData)
    {
        owner->bus.sendUnicast<cellular::msg::request::sim::SetPinLock>(cellular::api::SimLockState::Disabled,
                                                                        pinInputData);
        return sys::msgHandled();
    }
} // namespace locks

A module-apps/locks/handlers/SimLockHandler.hpp => module-apps/locks/handlers/SimLockHandler.hpp +68 -0
@@ 0,0 1,68 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <locks/widgets/Lock.hpp>
#include <locks/data/SimLockMessages.hpp>
#include <locks/data/LockData.hpp>

#include <module-sys/Service/Service.hpp>

namespace locks
{
    using StoredLockInput = std::vector<unsigned int>;

    class SimLockHandler
    {
      private:
        sys::Service *owner;
        Lock lock;

        SimInputTypeAction simInputTypeAction = SimInputTypeAction::UnlockWithPin;
        unsigned int storedErrorCode          = 0;
        bool simUnlockBlockOnLockedPhone      = false;
        StoredLockInput storedFirstInput;
        StoredLockInput storedSecondInput;

        void clearStoredInputs();
        void setSimInputTypeAction(SimInputTypeAction _simInputTypeAction);

        void simInputRequiredAction();
        void simErrorAction(unsigned int errorCode);
        void simUnlockAction();
        void simInfoAction();

        sys::MessagePointer unlockSimWithPin(LockInput pinInputData);
        sys::MessagePointer processLockWithNewInput(LockInput inputData);
        sys::MessagePointer resolveNewInputAction(LockInput firstInputData, LockInput secondInputData);
        sys::MessagePointer unlockSimWithPuk(LockInput pukInputData, LockInput newPinInputData);
        sys::MessagePointer changeSimPin(LockInput oldPinInputData, LockInput newPinInputData);
        sys::MessagePointer enableSimPin(LockInput pinInputData);
        sys::MessagePointer disableSimPin(LockInput pinInputData);

      public:
        explicit SimLockHandler(sys::Service *owner);

        void setSimUnlockBlockOnLockedPhone();
        sys::MessagePointer releaseSimUnlockBlockOnLockedPhone();

        sys::MessagePointer verifySimLockInput(LockInput inputData);

        sys::MessagePointer handleSimPinRequest(unsigned int attempts);
        sys::MessagePointer handleSimPukRequest(unsigned int attempts);
        sys::MessagePointer handleSimPinChangeRequest();
        sys::MessagePointer handleSimPinChangeFailedRequest();
        sys::MessagePointer handleSimEnableRequest();
        sys::MessagePointer handleSimDisableRequest();
        sys::MessagePointer handleSimBlockedRequest();
        sys::MessagePointer handleCMEErrorRequest(unsigned int errorCode);
        sys::MessagePointer handleSimUnlockedMessage();
        sys::MessagePointer handleSimChangedMessage();
        sys::MessagePointer handleSimAvailabilityMessage();

        void getSettingsSimSelect(const std::string &settingsSim);
        void setSim(cellular::api::SimSlot simSlot);
    };

} // namespace locks

A module-apps/locks/handlers/SimLockSubject.cpp => module-apps/locks/handlers/SimLockSubject.cpp +43 -0
@@ 0,0 1,43 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SimLockSubject.hpp"

#include <locks/data/PhoneLockMessages.hpp>
#include <service-appmgr/service-appmgr/model/ApplicationManager.hpp>

namespace locks
{
    SimLockSubject::SimLockSubject(sys::Service *owner) : owner{owner}
    {
        if (owner == nullptr) {
            throw std::invalid_argument{"Subject's owner is invalid"};
        }
    }

    void SimLockSubject::setSim(cellular::api::SimSlot simSlot)
    {
        owner->bus.sendUnicast(std::make_shared<locks::SetSim>(simSlot), app::manager::ApplicationManager::ServiceName);
    }

    void SimLockSubject::changeSimPin()
    {
        owner->bus.sendUnicast(std::make_shared<locks::ChangeSimPin>(), app::manager::ApplicationManager::ServiceName);
    }

    void SimLockSubject::enableSimPin()
    {
        owner->bus.sendUnicast(std::make_shared<locks::EnableSimPin>(), app::manager::ApplicationManager::ServiceName);
    }

    void SimLockSubject::disableSimPin()
    {
        owner->bus.sendUnicast(std::make_shared<locks::DisableSimPin>(), app::manager::ApplicationManager::ServiceName);
    }

    void SimLockSubject::verifyInput(LockInput inputData)
    {
        owner->bus.sendUnicast(std::make_shared<UnLockSimInput>(inputData),
                               app::manager::ApplicationManager::ServiceName);
    }
} // namespace locks

A module-apps/locks/handlers/SimLockSubject.hpp => module-apps/locks/handlers/SimLockSubject.hpp +28 -0
@@ 0,0 1,28 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <locks/data/LockData.hpp>

#include <module-sys/Service/Service.hpp>
#include <service-cellular-api>

namespace locks
{
    class SimLockSubject
    {
      private:
        sys::Service *owner;

      public:
        explicit SimLockSubject(sys::Service *owner);

        void setSim(cellular::api::SimSlot simSlot);
        void changeSimPin();
        void enableSimPin();
        void disableSimPin();
        void verifyInput(LockInput inputData);
    };

} // namespace locks

M module-apps/locks/widgets/Lock.cpp => module-apps/locks/widgets/Lock.cpp +0 -12
@@ 24,9 24,6 @@ namespace locks
        if (maxInputSize > inputValue.size()) {
            inputValue.push_back(c);
        }
        if (canVerify() && autoActivate && onActivatedCallback != nullptr) {
            onActivatedCallback(lockType, inputValue);
        }
    }

    void Lock::popChar()


@@ 41,13 38,4 @@ namespace locks
        inputValue.clear();
    }

    void Lock::activate()
    {
        if (!onActivatedCallback) {
            LOG_ERROR("Passcode verification callback null");
            return;
        }
        onActivatedCallback(lockType, inputValue);
        clearAttempt();
    }
} // namespace locks

M module-apps/locks/widgets/Lock.hpp => module-apps/locks/widgets/Lock.hpp +3 -45
@@ 7,26 7,14 @@
#include <functional>
#include <limits>

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

namespace gui
{
    class PinLockHandler;
} // namespace gui

namespace locks
{
    class PhoneLockHandler;
    class SimLockHandler;

    class Lock
    {
      public:
        enum class LockType
        {
            SimPin,
            SimPuk,
            Screen
        };

        enum class LockState
        {


@@ 44,10 32,6 @@ namespace locks
        {
            return lockState;
        }
        [[nodiscard]] LockType getLockType() const noexcept
        {
            return lockType;
        }
        [[nodiscard]] unsigned int getMaxInputSize() const noexcept
        {
            return maxInputSize;


@@ 73,26 57,14 @@ namespace locks
        {
            return attemptsLeft;
        }
        [[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;
        }
        [[nodiscard]] const std::string &getLockName() const noexcept
        {
            return lockName;
        }
        [[nodiscard]] Store::GSM::SIM getSim() const noexcept
        {
            return sim;
        }

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


@@ 102,37 74,23 @@ namespace locks
        /// consumes LockState::InputInvalid state and LockState::NewInputInvalid
        void consumeState() noexcept;
        /// calls
        void activate();

        Lock(Store::GSM::SIM sim, LockState state, LockType type, unsigned int attemptsLeft = unlimitedNumOfAttempts)
            : sim{sim}, lockState{state}, lockType{type}, attemptsLeft{attemptsLeft}
        {}

        Lock(LockState state, unsigned int attemptsLeft = unlimitedNumOfAttempts)
        explicit Lock(LockState state, unsigned int attemptsLeft = unlimitedNumOfAttempts)
            : lockState{state}, attemptsLeft{attemptsLeft}
        {}

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

      private:
        std::string lockName;
        Store::GSM::SIM sim       = Store::GSM::SIM::NONE;
        LockState lockState       = LockState::Unlocked;
        LockType lockType         = LockType::Screen;
        unsigned int attemptsLeft = 0;

        std::vector<unsigned int> inputValue;
        unsigned int maxInputSize = defaultInputSize;
        unsigned int minInputSize = defaultInputSize;
        bool autoActivate         = false;

        static constexpr unsigned int defaultInputSize       = 4;
        static constexpr unsigned int unlimitedNumOfAttempts = std::numeric_limits<unsigned int>::max();

        void setAutoActivate(bool _autoActivate)
        {
            autoActivate = _autoActivate;
        }
        void setInputSizeBounds(unsigned int _minInputSize, unsigned int _maxInputSize)
        {
            minInputSize = _minInputSize;


@@ 140,7 98,7 @@ namespace locks
        }

        friend class PhoneLockHandler;
        friend class gui::PinLockHandler;
        friend class SimLockHandler;
    };

} // namespace lock

M module-apps/locks/widgets/LockBox.hpp => module-apps/locks/widgets/LockBox.hpp +1 -1
@@ 21,7 21,6 @@ namespace gui
        {
            InvalidInput,
            NewInputConfirmFailed,
            UnhandledError
        };

        virtual void popChar(unsigned int charNum) = 0;


@@ 31,6 30,7 @@ namespace gui
        virtual void setVisibleStateInputRequired(InputActionType type)                   = 0;
        virtual void setVisibleStateInputInvalid(InputErrorType type, unsigned int value) = 0;
        virtual void setVisibleStateBlocked()                                             = 0;
        virtual void setVisibleStateError(unsigned int errorCode)                         = 0;

        virtual void buildLockBox(unsigned int inputSize) = 0;
        virtual ~LockBox()                                = default;

A module-apps/locks/widgets/LockBoxAlternatingSize.cpp => module-apps/locks/widgets/LockBoxAlternatingSize.cpp +47 -0
@@ 0,0 1,47 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "Lock.hpp"
#include "LockBoxAlternatingSize.hpp"

#include <locks/data/LockStyle.hpp>
#include <locks/windows/LockInputWindow.hpp>

namespace gui
{
    void LockBoxAlternatingSize::buildLockBox(unsigned int pinSize)
    {
        buildPinLabels(0);
    }

    void LockBoxAlternatingSize::clear()
    {
        lockWindow->pinLabelsBox->erase();
        buildPinLabels(0);
    }

    void LockBoxAlternatingSize::popChar(unsigned int charNum)
    {
        buildPinLabels(charNum);
    }

    void LockBoxAlternatingSize::putChar(unsigned int charNum)
    {
        buildPinLabels(charNum + 1);
    }

    void LockBoxAlternatingSize::buildPinLabels(unsigned int pinSize)
    {
        if (lockWindow->pinLabelsBox) {
            lockWindow->pinLabelsBox->erase();
        }

        auto itemBuilder = []() {
            auto label = new gui::Image("dot_12px_hard_alpha_W_G");
            return label;
        };

        lockWindow->buildPinLabels(itemBuilder, pinSize);
        lockWindow->pinLabelsBox->setEdges(RectangleEdge::Bottom);
    }
} // namespace gui

R module-apps/locks/widgets/PukLockBox.hpp => module-apps/locks/widgets/LockBoxAlternatingSize.hpp +12 -17
@@ 5,31 5,26 @@

#include "LockBox.hpp"

namespace gui
{
    class PinLockBaseWindow;
}
#include <locks/windows/LockInputWindow.hpp>
#include <Image.hpp>

namespace gui
{
    class PukLockBox : public LockBox
    class LockBoxAlternatingSize : public LockBox
    {
      public:
        explicit PukLockBox(PinLockBaseWindow *LockBaseWindow) : LockWindow(LockBaseWindow)
        {}

      private:
        PinLockBaseWindow *LockWindow;
        void buildLockBox(unsigned int pinSize) override;
        void clear() final;
        void popChar(unsigned int charNum) final;
        void putChar(unsigned int charNum) final;
        void clear() final;

        void setVisibleStateInputRequired(InputActionType type) final;
        void setVisibleStateInputInvalid(InputErrorType type, unsigned int value) final;
        void setVisibleStateBlocked() final;
      protected:
        explicit LockBoxAlternatingSize(LockInputWindow *lockBaseWindow) : lockWindow(lockBaseWindow)
        {}

        void buildLockBox(unsigned int inputSize) final;
        void buildInputLabels(unsigned int inputSize);
        void rebuildInputLabels(unsigned int inputSize);
        void buildPinLabels(unsigned int pinSize);

      private:
        LockInputWindow *lockWindow;
    };
} // namespace gui

R module-apps/locks/widgets/PhoneLockBaseBox.cpp => module-apps/locks/widgets/LockBoxConstantSize.cpp +17 -19
@@ 1,74 1,72 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "locks/data/LockStyle.hpp"
#include "locks/windows/PinLockBaseWindow.hpp"
#include "Lock.hpp"
#include "PhoneLockBaseBox.hpp"
#include "LockBoxConstantSize.hpp"

namespace label_style = style::window::pin_lock::pin_label;
#include <locks/data/LockStyle.hpp>
#include <locks/windows/LockInputWindow.hpp>

namespace gui
{
    void PhoneLockBaseBox::buildLockBox(unsigned int pinSize)
    void LockBoxConstantSize::buildLockBox(unsigned int pinSize)
    {
        buildPinLabels(pinSize);
    }

    void PhoneLockBaseBox::clear()
    void LockBoxConstantSize::clear()
    {
        for (unsigned i = 0; i < inputLabels.size(); i++) {
            popChar(i);
        }
    }

    void PhoneLockBaseBox::popChar(unsigned int charNum)
    void LockBoxConstantSize::popChar(unsigned int charNum)
    {
        if (charNum < inputLabels.size()) {
            inputLabels[charNum]->setVisibleState(false);
        }
    }

    void PhoneLockBaseBox::putChar(unsigned int charNum)
    void LockBoxConstantSize::putChar(unsigned int charNum)
    {
        if (charNum < inputLabels.size()) {
            inputLabels[charNum]->setVisibleState(true);
        }
    }

    void PhoneLockBaseBox::buildPinLabels(unsigned int pinSize)
    void LockBoxConstantSize::buildPinLabels(unsigned int pinSize)
    {
        constexpr auto pinLabelWidth = style::window::default_body_width;
        using namespace style::window::lock_input;

        inputLabels.clear();

        if (pinSize == 0) {
            return;
        }

        unsigned int singleLabelWidth        = label_style::size;
        unsigned int maxNoMarginsLabelsWidth = pinLabelWidth - pinSize * 2 * label_style::margin;
        unsigned int singleLabelWidth        = input_box::h;
        unsigned int maxNoMarginsLabelsWidth = input_box::w - pinSize * 2 * input_box::label_margin;

        if (pinSize * singleLabelWidth > maxNoMarginsLabelsWidth) {
            singleLabelWidth = maxNoMarginsLabelsWidth / pinSize;
        }

        auto itemBuilder = [this, singleLabelWidth]() {
            auto label = new InputLabel(nullptr, singleLabelWidth, label_style::size);
            auto label = new InputLabel(nullptr, singleLabelWidth, input_box::h);
            label->setEdges(RectangleEdge::Bottom);
            label->setMargins(Margins(label_style::margin, 0, label_style::margin, 0));
            label->setMargins(Margins(input_box::label_margin, 0, input_box::label_margin, 0));
            inputLabels.push_back(label);
            return label;
        };

        lockWindow->buildPinLabels(
            itemBuilder, pinSize, style::window::default_left_margin, label_style::y, pinLabelWidth);
        lockWindow->pinLabelsBox->setEdges(RectangleEdge::None);
        lockWindow->buildPinLabels(itemBuilder, pinSize);
    }

    PhoneLockBaseBox::InputLabel::InputLabel(Item *parent, uint32_t w, uint32_t h) : HBox(parent, 0, 0, w, h)
    LockBoxConstantSize::InputLabel::InputLabel(Item *parent, uint32_t w, uint32_t h) : HBox(parent, 0, 0, w, h)
    {}

    void PhoneLockBaseBox::InputLabel::setVisibleState(bool isImageVisible)
    void LockBoxConstantSize::InputLabel::setVisibleState(bool isImageVisible)
    {
        if (isImageVisible && image == nullptr) {
            image = new gui::Image("dot_12px_hard_alpha_W_G");

R module-apps/locks/widgets/PhoneLockBaseBox.hpp => module-apps/locks/widgets/LockBoxConstantSize.hpp +10 -14
@@ 3,32 3,28 @@

#pragma once

#include "Image.hpp"
#include "LockBox.hpp"
#include "locks/windows/LockWindow.hpp"

#include <locks/windows/LockInputWindow.hpp>
#include <Image.hpp>

namespace gui
{
    class PhoneLockBaseBox : public LockBox
    class LockBoxConstantSize : public LockBox
    {
      public:
        explicit PhoneLockBaseBox(LockWindow *lockBaseWindow) : lockWindow(lockBaseWindow)
        {}

        void buildLockBox(unsigned int pinSize) override;
        void clear() final;
        void popChar(unsigned int charNum) final;
        void putChar(unsigned int charNum) final;

      private:
        void buildPinLabels(unsigned int pinSize);
        void setVisibleStateBlocked() override
        {}
        void setVisibleStateInputRequired(InputActionType type) override
        {}
        void setVisibleStateInputInvalid(InputErrorType type, unsigned int value) override
      protected:
        explicit LockBoxConstantSize(LockInputWindow *lockBaseWindow) : lockWindow(lockBaseWindow)
        {}

        void buildPinLabels(unsigned int pinSize);

      private:
        struct InputLabel : public HBox
        {
            InputLabel(Item *parent, uint32_t w, uint32_t h);


@@ 37,7 33,7 @@ namespace gui
            gui::Image *image = nullptr;
        };

        LockWindow *lockWindow;
        LockInputWindow *lockWindow;
        std::vector<InputLabel *> inputLabels;
    };
} // namespace gui

M module-apps/locks/widgets/LockHash.hpp => module-apps/locks/widgets/LockHash.hpp +3 -1
@@ 3,6 3,8 @@

#pragma once

#include <locks/data/LockData.hpp>

#include <cstdint>
#include <vector>
#include <functional>


@@ 20,7 22,7 @@ template <> struct std::hash<std::vector<unsigned int>>
    }
};

static inline uint32_t getHash(const std::vector<unsigned int> &input)
static inline uint32_t getHash(locks::LockInput input)
{
    static std::hash<std::vector<unsigned int>> hashEngine;
    return hashEngine(input);

M module-apps/locks/widgets/PhoneLockBox.cpp => module-apps/locks/widgets/PhoneLockBox.cpp +24 -43
@@ 10,26 10,7 @@ namespace gui

    void PhoneLockBox::buildLockBox(unsigned int pinSize)
    {
        LockWindow->buildImages("pin_lock", "pin_lock_info");
        PhoneLockBaseBox::buildLockBox(pinSize);
    }

    top_bar::Configuration PhoneLockBox::configureTopBarLocked()
    {
        top_bar::Configuration appConfiguration;
        appConfiguration.disable(top_bar::Indicator::Time);
        appConfiguration.enable(top_bar::Indicator::Lock);

        return appConfiguration;
    }

    top_bar::Configuration PhoneLockBox::configureTopBarUnLocked()
    {
        top_bar::Configuration appConfiguration;
        appConfiguration.enable(top_bar::Indicator::Time);
        appConfiguration.disable(top_bar::Indicator::Lock);

        return appConfiguration;
        LockBoxConstantSize::buildLockBox(pinSize);
    }

    void PhoneLockBox::applyLockActionText(locks::PhoneLockInputTypeAction phoneLockInputTypeAction)


@@ 37,7 18,6 @@ namespace gui
        switch (phoneLockInputTypeAction) {
        case locks::PhoneLockInputTypeAction::Unlock:
            LockWindow->setTitleBar(false, false);
            LockWindow->configureTopBar(configureTopBarLocked());
            textForInputRequired = "phone_lock_unlock";
            textForInvalidInput  = "phone_lock_unlock_invalid";
            leftBottomBarState   = false;


@@ 47,8 27,7 @@ namespace gui
        case locks::PhoneLockInputTypeAction::ConfirmCurrent:
        case locks::PhoneLockInputTypeAction::Change:
            LockWindow->setTitleBar(true, false);
            LockWindow->setText("phone_lock_configure", LockWindow::TextType::Title);
            LockWindow->configureTopBar(configureTopBarUnLocked());
            LockWindow->setText("phone_lock_configure", LockInputWindow::TextType::Title);

            textForInputRequired   = "phone_lock_current";
            textForInvalidInput    = "phone_lock_invalid";


@@ 58,8 37,7 @@ namespace gui
            break;
        case locks::PhoneLockInputTypeAction::Set:
            LockWindow->setTitleBar(true, false);
            LockWindow->setText("phone_lock_configure", LockWindow::TextType::Title);
            LockWindow->configureTopBar(configureTopBarUnLocked());
            LockWindow->setText("phone_lock_configure", LockInputWindow::TextType::Title);

            textForInputRequired   = "phone_lock_current";
            textForInvalidInput    = "phone_lock_invalid_retry";


@@ 74,30 52,35 @@ namespace gui

    void PhoneLockBox::setVisibleStateBlocked()
    {
        LockWindow->setText("phone_lock_blocked", LockWindow::TextType::Primary);
        LockWindow->setImagesVisible(false, true);
        LockWindow->setText("phone_lock_blocked", LockInputWindow::TextType::Primary);
        LockWindow->setImage("info_icon_W_G");
        LockWindow->setBottomBarWidgetsActive(false, true, false);
    }

    void PhoneLockBox::setVisibleStateError(unsigned int errorCode)
    {
        LOG_ERROR("No use case for UnhandledError");
    }

    void PhoneLockBox::setVisibleStateInputRequired(InputActionType type)
    {
        LockWindow->pinLabelsBox->setVisible(true);

        switch (type) {
        case LockBox::InputActionType::ProvideInput: {
            LockWindow->setText(textForInputRequired, PinLockBaseWindow::TextType::Primary);
            LockWindow->setText(textForInputRequired, LockInputWindow::TextType::Primary);
            break;
        }
        case LockBox::InputActionType::ProvideNewInput: {
            LockWindow->setText(textForProvideNewInput, PinLockBaseWindow::TextType::Primary);
            LockWindow->setText(textForProvideNewInput, LockInputWindow::TextType::Primary);
            break;
        }
        case LockBox::InputActionType::ConfirmNewInput:
            LockWindow->setText(textForConfirmNewInput, PinLockBaseWindow::TextType::Primary);
            LockWindow->setText(textForConfirmNewInput, LockInputWindow::TextType::Primary);
            break;
        }

        LockWindow->setImagesVisible(true, false);
        LockWindow->setImage("unlock_icon_W_G");
        LockWindow->setBottomBarWidgetsActive(leftBottomBarState, false, true);
    }



@@ 106,28 89,26 @@ namespace gui
        switch (type) {
        case LockBox::InputErrorType::InvalidInput:
            if (value == 1) {
                LockWindow->setText("phone_lock_unlock_last_attempt", LockWindow::TextType::Primary);
                LockWindow->setText("phone_lock_unlock_last_attempt", LockInputWindow::TextType::Primary);
                LockWindow->setText("phone_lock_unlock_last_attempt_warning",
                                    LockWindow::TextType::Secondary,
                                    {{LockWindow->getToken(LockWindow::Token::Mins), timeToUnlock}});
                                    LockInputWindow::TextType::Secondary,
                                    {{LockWindow->getToken(LockInputWindow::Token::Mins), timeToUnlock}});
            }
            else {
                LockWindow->setText(textForInvalidInput,
                                    LockWindow::TextType::Primary,
                                    {{LockWindow->getToken(LockWindow::Token::Attempts), static_cast<int>(value)}});
                LockWindow->setText(
                    textForInvalidInput,
                    LockInputWindow::TextType::Primary,
                    {{LockWindow->getToken(LockInputWindow::Token::Attempts), static_cast<int>(value)}});
            }
            break;

        case LockBox::InputErrorType::NewInputConfirmFailed:
            LockWindow->setText(textForInvalidInput,
                                LockWindow::TextType::Primary,
                                {{LockWindow->getToken(LockWindow::Token::Attempts), static_cast<int>(value)}});
            break;
        case LockBox::InputErrorType::UnhandledError:
            LOG_ERROR("No use case for UnhandledError");
                                LockInputWindow::TextType::Primary,
                                {{LockWindow->getToken(LockInputWindow::Token::Attempts), static_cast<int>(value)}});
            break;
        }
        LockWindow->setImagesVisible(false, true);
        LockWindow->setImage("info_icon_W_G");
        LockWindow->setBottomBarWidgetsActive(false, true, true);
    }
} // namespace gui

M module-apps/locks/widgets/PhoneLockBox.hpp => module-apps/locks/widgets/PhoneLockBox.hpp +7 -9
@@ 4,18 4,18 @@
#pragma once

#include "locks/data/LockData.hpp"
#include "locks/windows/PinLockBaseWindow.hpp"
#include "PhoneLockBaseBox.hpp"
#include "locks/windows/LockInputWindow.hpp"
#include "LockBoxConstantSize.hpp"

namespace gui
{
    class PhoneLockBox : public PhoneLockBaseBox
    class PhoneLockBox : public LockBoxConstantSize
    {
      public:
        explicit PhoneLockBox(
            PinLockBaseWindow *LockBaseWindow,
            LockInputWindow *LockBaseWindow,
            locks::PhoneLockInputTypeAction phoneLockInputTypeAction = locks::PhoneLockInputTypeAction::Unlock)
            : PhoneLockBaseBox(LockBaseWindow), LockWindow(LockBaseWindow)
            : LockBoxConstantSize(LockBaseWindow), LockWindow(LockBaseWindow)
        {
            applyLockActionText(phoneLockInputTypeAction);
        }


@@ 23,14 23,12 @@ namespace gui
      private:
        void buildLockBox(unsigned int pinSize) final;
        void setVisibleStateBlocked() final;
        void setVisibleStateError(unsigned int errorCode) final;
        void setVisibleStateInputRequired(InputActionType type) final;
        void setVisibleStateInputInvalid(InputErrorType type, unsigned int value) final;
        void applyLockActionText(locks::PhoneLockInputTypeAction phoneLockInputTypeAction);

        [[nodiscard]] top_bar::Configuration configureTopBarLocked();
        [[nodiscard]] top_bar::Configuration configureTopBarUnLocked();

        PinLockBaseWindow *LockWindow;
        LockInputWindow *LockWindow;
        std::string textForInputRequired;
        std::string textForInvalidInput;
        std::string textForProvideNewInput;

D module-apps/locks/widgets/PukLockBox.cpp => module-apps/locks/widgets/PukLockBox.cpp +0 -105
@@ 1,105 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PukLockBox.hpp"

#include "locks/data/LockStyle.hpp"
#include "locks/windows/PinLockBaseWindow.hpp"
#include "Lock.hpp"
#include "gui/widgets/Image.hpp"
#include <i18n/i18n.hpp>
#include <Style.hpp>

namespace label_style = style::window::pin_lock::pin_label;
namespace gui
{
    void PukLockBox::popChar(unsigned int charNum)
    {
        rebuildInputLabels(charNum);
    }
    void PukLockBox::putChar(unsigned int charNum)
    {
        rebuildInputLabels(++charNum);
    }
    void PukLockBox::buildLockBox(unsigned int inputSize)
    {
        LockWindow->buildImages("pin_lock", "pin_lock_info");
        buildInputLabels(0);
    }
    void PukLockBox::buildInputLabels(unsigned int inputSize)
    {
        auto itemBuilder = []() {
            auto label = new gui::Image("dot_12px_hard_alpha_W_G");
            return label;
        };

        LockWindow->buildPinLabels(itemBuilder, inputSize, label_style::x, label_style::y, label_style::w);
        LockWindow->pinLabelsBox->setEdges(RectangleEdge::Bottom);
    }

    void PukLockBox::rebuildInputLabels(unsigned int inputSize)
    {
        LockWindow->pinLabelsBox->erase();
        buildInputLabels(inputSize);
    }

    void PukLockBox::setVisibleStateInputRequired(InputActionType type)
    {
        LockWindow->pinLabelsBox->setVisible(true);
        switch (type) {
        case LockBox::InputActionType::ProvideInput: {
            LockWindow->setText("app_desktop_sim_setup_enter_puk", PinLockBaseWindow::TextType::Primary);
            break;
        }
        case LockBox::InputActionType::ProvideNewInput: {
            LockWindow->setText("app_desktop_sim_enter_new_pin", PinLockBaseWindow::TextType::Primary);
            break;
        }
        case LockBox::InputActionType::ConfirmNewInput:
            LockWindow->setText("app_desktop_sim_confirm_new_pin", PinLockBaseWindow::TextType::Primary);
            break;
        }

        LockWindow->setImagesVisible(true, false);
        LockWindow->setBottomBarWidgetsActive(false, false, true);
    }
    void PukLockBox::setVisibleStateInputInvalid(InputErrorType type, unsigned int value)
    {
        switch (type) {
        case LockBox::InputErrorType::InvalidInput:
            if (value > 1) {
                LockWindow->setText(
                    "app_desktop_sim_setup_wrong_puk",
                    PinLockBaseWindow::TextType::Primary,
                    {{LockWindow->getToken(PinLockBaseWindow::Token::Attempts), static_cast<int>(value)}});
            }
            else {
                LockWindow->setText("app_desktop_sim_setup_wrong_puk_last_attempt",
                                    PinLockBaseWindow::TextType::Primary);
                LockWindow->setText("app_desktop_sim_setup_wrong_puk_last_attempt_warning",
                                    PinLockBaseWindow::TextType::Secondary);
            }
            break;
        case LockBox::InputErrorType::NewInputConfirmFailed: {
            LockWindow->setText("app_desktop_sim_wrong_pin_confirmation", PinLockBaseWindow::TextType::Primary);
            break;
        }
        case LockBox::InputErrorType::UnhandledError:
            LOG_ERROR("No use case for UnhandledError in PukLockBox");
            break;
        }
        LockWindow->setImagesVisible(false, true);
        LockWindow->setBottomBarWidgetsActive(false, true, false);
    }
    void PukLockBox::setVisibleStateBlocked()
    {
        LockWindow->setText("app_desktop_sim_puk_blocked", PinLockBaseWindow::TextType::Primary);
        LockWindow->setImagesVisible(false, true);
        LockWindow->setBottomBarWidgetsActive(true, false, false);
    }

    void PukLockBox::clear()
    {
        rebuildInputLabels(0);
    }
} // namespace gui

M module-apps/locks/widgets/SimLockBox.cpp => module-apps/locks/widgets/SimLockBox.cpp +56 -57
@@ 2,47 2,46 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SimLockBox.hpp"

#include "locks/data/LockStyle.hpp"
#include "locks/windows/PinLockBaseWindow.hpp"
#include "Lock.hpp"
#include <Style.hpp>
#include <Image.hpp>

namespace label_style = style::window::pin_lock::pin_label;
#include "locks/windows/LockInputWindow.hpp"

namespace gui
{

    void SimLockBox::popChar(unsigned int charNum)
    void SimLockBox::buildLockBox(unsigned int pinSize)
    {
        rebuildInputLabels(charNum);
    }
    void SimLockBox::putChar(unsigned int charNum)
    {
        rebuildInputLabels(++charNum);
        LockBoxAlternatingSize::buildLockBox(pinSize);
    }

    void SimLockBox::buildLockBox(unsigned int inputSize)
    void SimLockBox::applyLockActionText(locks::SimInputTypeAction simInputTypeAction)
    {
        LockWindow->buildImages("pin_lock", "pin_lock_info");
        buildInputLabels(0);
    }
    void SimLockBox::buildInputLabels(unsigned int inputSize)
    {
        auto itemBuilder = []() {
            auto label = new gui::Image("dot_12px_hard_alpha_W_G");
            return label;
        };

        LockWindow->buildPinLabels(itemBuilder, inputSize, label_style::x, label_style::y, label_style::w);
        LockWindow->pinLabelsBox->setEdges(RectangleEdge::Bottom);
    }
        LockWindow->setText("sim_header_setup",
                            LockInputWindow::TextType::Title,
                            {{LockWindow->getToken(LockInputWindow::Token::Sim), LockWindow->lock->getLockName()}});
        LockWindow->setTitleBar(true, true);

    void SimLockBox::rebuildInputLabels(unsigned int inputSize)
    {
        LockWindow->pinLabelsBox->erase();
        buildInputLabels(inputSize);
        switch (simInputTypeAction) {
        case locks::SimInputTypeAction::UnlockWithPin:
            textForInputRequired                  = "sim_enter_pin_unlock";
            textForInvalidInput                   = "sim_setup_wrong_pin";
            textForInvalidInputLastAttempt        = "sim_setup_wrong_pin_last_attempt";
            textForInvalidInputLastAttemptWarning = "";
            break;
        case locks::SimInputTypeAction::UnlockWithPuk:
            textForInputRequired                  = "sim_setup_enter_puk";
            textForInvalidInput                   = "sim_setup_wrong_puk";
            textForInvalidInputLastAttempt        = "sim_setup_wrong_puk_last_attempt";
            textForInvalidInputLastAttemptWarning = "sim_setup_wrong_puk_last_attempt_warning";
            break;
        case locks::SimInputTypeAction::ChangePin:
        case locks::SimInputTypeAction::EnablePin:
        case locks::SimInputTypeAction::DisablePin:
            textForInputRequired                  = "sim_enter_enter_current";
            textForInvalidInput                   = "sim_wrong_pin_confirmation";
            textForInvalidInputLastAttempt        = "";
            textForInvalidInputLastAttemptWarning = "";
            break;
        default:
            break;
        }
    }

    void SimLockBox::setVisibleStateInputRequired(InputActionType type)


@@ 51,59 50,59 @@ namespace gui
        switch (type) {
        case LockBox::InputActionType::ProvideInput: {
            LockWindow->setText(
                "app_desktop_sim_enter_pin_unlock",
                PinLockBaseWindow::TextType::Primary,
                {{LockWindow->getToken(PinLockBaseWindow::Token::PinType), LockWindow->lock->getLockName()}});
                textForInputRequired,
                LockInputWindow::TextType::Primary,
                {{LockWindow->getToken(LockInputWindow::Token::PinType), LockWindow->lock->getLockName()}});
            break;
        }
        case LockBox::InputActionType::ProvideNewInput:
            LockWindow->setText("app_desktop_sim_enter_new_pin", PinLockBaseWindow::TextType::Primary);
            LockWindow->setText("sim_enter_new_pin", LockInputWindow::TextType::Primary);
            break;
        case LockBox::InputActionType::ConfirmNewInput:
            LockWindow->setText("app_desktop_sim_confirm_new_pin", PinLockBaseWindow::TextType::Primary);
            LockWindow->setText("sim_confirm_new_pin", LockInputWindow::TextType::Primary);
            break;
        }

        LockWindow->setImagesVisible(true, false);
        LockWindow->setImage("sim_card_W_G");
        LockWindow->setBottomBarWidgetsActive(false, false, true);
    }

    void SimLockBox::setVisibleStateInputInvalid(InputErrorType type, unsigned int value)
    {
        switch (type) {
        case LockBox::InputErrorType::InvalidInput:
            if (value == 1) {
                LockWindow->setText("app_desktop_sim_setup_wrong_pin_last_attempt",
                                    PinLockBaseWindow::TextType::Primary);
                LockWindow->setText(textForInvalidInputLastAttempt, LockInputWindow::TextType::Primary);
                LockWindow->setText(textForInvalidInputLastAttemptWarning, LockInputWindow::TextType::Secondary);
            }
            else {
                LockWindow->setText(
                    "app_desktop_sim_setup_wrong_pin",
                    PinLockBaseWindow::TextType::Primary,
                    {{LockWindow->getToken(PinLockBaseWindow::Token::Attempts), static_cast<int>(value)}});
                    textForInvalidInput,
                    LockInputWindow::TextType::Primary,
                    {{LockWindow->getToken(LockInputWindow::Token::Attempts), static_cast<int>(value)}});
            }
            break;
        case LockBox::InputErrorType::NewInputConfirmFailed:
            LockWindow->setText("app_desktop_sim_wrong_pin_confirmation", PinLockBaseWindow::TextType::Primary);
            break;
        case LockBox::InputErrorType::UnhandledError: {
            LockWindow->setText("app_desktop_sim_cme_error",
                                PinLockBaseWindow::TextType::Primary,
                                {{LockWindow->getToken(PinLockBaseWindow::Token::CmeCode), static_cast<int>(value)}});
            LockWindow->setText("sim_wrong_pin_confirmation", LockInputWindow::TextType::Primary);
            break;
        }
        }
        LockWindow->setImagesVisible(false, true);
        LockWindow->setImage("info_icon_W_G");
        LockWindow->setBottomBarWidgetsActive(false, true, true);
    }

    void SimLockBox::setVisibleStateBlocked()
    {
        LockWindow->setText("app_desktop_sim_puk_blocked", PinLockBaseWindow::TextType::Primary);
        LockWindow->setImagesVisible(false, true);
        LockWindow->setBottomBarWidgetsActive(false, true, true);
        LockWindow->setText("sim_puk_blocked", LockInputWindow::TextType::Primary);
        LockWindow->setImage("sim_card_W_G");
        LockWindow->setBottomBarWidgetsActive(false, false, true);
    }

    void SimLockBox::clear()
    void SimLockBox::setVisibleStateError(unsigned int errorCode)
    {
        rebuildInputLabels(0);
        LockWindow->setText("sim_cme_error",
                            LockInputWindow::TextType::Primary,
                            {{LockWindow->getToken(LockInputWindow::Token::CmeCode), static_cast<int>(errorCode)}});
        LockWindow->setImage("info_icon_W_G");
        LockWindow->setBottomBarWidgetsActive(false, false, true);
    }
} // namespace gui

M module-apps/locks/widgets/SimLockBox.hpp => module-apps/locks/widgets/SimLockBox.hpp +18 -13
@@ 3,33 3,38 @@

#pragma once

#include "LockBox.hpp"
#include "LockBoxAlternatingSize.hpp"
#include <locks/data/LockData.hpp>

namespace gui
{
    class PinLockBaseWindow;
    class LockInputWindow;
}

namespace gui
{
    class SimLockBox : public LockBox
    class SimLockBox : public LockBoxAlternatingSize
    {
      public:
        SimLockBox(PinLockBaseWindow *LockBaseWindow) : LockWindow(LockBaseWindow)
        {}
        explicit SimLockBox(LockInputWindow *LockBaseWindow,
                            locks::SimInputTypeAction simLockInputTypeAction = locks::SimInputTypeAction::UnlockWithPin)
            : LockBoxAlternatingSize(LockBaseWindow), LockWindow(LockBaseWindow)
        {
            applyLockActionText(simLockInputTypeAction);
        }

      private:
        PinLockBaseWindow *LockWindow;
        void popChar(unsigned int charNum) final;
        void putChar(unsigned int charNum) final;
        void clear() final;

        void buildLockBox(unsigned int pinSize) final;
        void setVisibleStateInputRequired(InputActionType type) final;
        void setVisibleStateInputInvalid(InputErrorType type, unsigned int value) final;
        void setVisibleStateBlocked() final;
        void setVisibleStateError(unsigned int errorCode) final;
        void applyLockActionText(locks::SimInputTypeAction simLockInputTypeAction);

        void buildLockBox(unsigned int inputSize) final;
        void buildInputLabels(unsigned int inputSize);
        void rebuildInputLabels(unsigned int inputSize);
        LockInputWindow *LockWindow;
        std::string textForInputRequired;
        std::string textForInvalidInput;
        std::string textForInvalidInputLastAttempt;
        std::string textForInvalidInputLastAttemptWarning;
    };
} // namespace gui

A module-apps/locks/windows/LockInputWindow.cpp => module-apps/locks/windows/LockInputWindow.cpp +247 -0
@@ 0,0 1,247 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "LockInputWindow.hpp"

#include <locks/data/LockStyle.hpp>
#include <locks/widgets/Lock.hpp>

#include <service-appmgr/Controller.hpp>
#include <FontManager.hpp>
#include <i18n/i18n.hpp>

namespace lock_style = style::window::lock_input;

namespace gui
{
    void LockInputWindow::build()
    {
        buildBody();
        buildImage();
        buildInfoTexts();
        buildPinBody();
        buildIceBox();
        buildBottomBar();

        body->resizeItems();
    }

    void LockInputWindow::buildBody()
    {
        body = new VBox(this,
                        style::window::default_left_margin,
                        style::header::height,
                        style::window::default_body_width,
                        style::window::default_body_height);
        body->setEdges(RectangleEdge::None);
    }

    void LockInputWindow::buildImage()
    {
        using namespace style::window::lock_input;

        infoImage = new gui::ImageBox(body, 0, 0, 0, 0, new gui::Image(""));
        infoImage->setMinimumSize(image::wh, image::wh);
        infoImage->setMargins(Margins(0, image::image_top_margin, 0, image::image_bottom_margin));
        infoImage->showImage(false);
    }

    void LockInputWindow::buildInfoTexts()
    {
        using namespace style::window::lock_input;

        primaryText = new Text(body, 0, 0, 0, 0);
        primaryText->setMinimumSize(style::window::default_body_width, primary_text::h);
        primaryText->setFont(style::window::font::medium);
        primaryText->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));

        secondaryText = new Text(body, 0, 0, 0, secondary_text::h);
        secondaryText->setMinimumSize(style::window::default_body_width, secondary_text::h);
        secondaryText->setMargins(Margins(0, secondary_text::top_margin, 0, 0));
        secondaryText->setFont(style::window::font::medium);
        secondaryText->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
    }

    void LockInputWindow::buildBottomBar()
    {
        bottomBar->setText(BottomBar::Side::LEFT, utils::translate(style::strings::common::skip));
        bottomBar->setText(BottomBar::Side::CENTER, utils::translate(style::strings::common::confirm));
        bottomBar->setText(BottomBar::Side::RIGHT, utils::translate(style::strings::common::back));
        setBottomBarWidgetsActive(false, false, false);
    }

    void LockInputWindow::buildIceBox()
    {
        using namespace style::window::lock_input;

        iceBox = new gui::HBox(this, ice::x, ice::y, ice::w, ice::h);
        iceBox->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        iceBox->setEdges(RectangleEdge::None);
        iceBox->setVisible(false);

        auto arrow        = new gui::Image("left_label_arrow");
        arrow->activeItem = false;
        arrow->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        arrow->setMargins(Margins(0, 0, ice::margin, 0));
        iceBox->addWidget(arrow);

        auto iceText        = new gui::Text(nullptr, 0, 0, ice::text::w, ice::h);
        iceText->activeItem = false;
        iceText->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        iceText->setFont(style::window::font::verysmall);
        iceText->setText(utils::translate("app_desktop_emergency"));
        iceBox->addWidget(iceText);
    }

    void LockInputWindow::buildPinBody()
    {
        pinLabelsBox = new gui::HBox(body, 0, 0, 0, 0);
        pinLabelsBox->setMinimumSize(lock_style::input_box::w, lock_style::input_box::h);
        pinLabelsBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
        pinLabelsBox->setMargins(Margins(0, lock_style::input_box::top_margin, 0, 0));
        pinLabelsBox->setEdges(RectangleEdge::None);
    }

    void LockInputWindow::buildPinLabels(const std::function<Rect *()> &itemBuilder, unsigned int pinSize)
    {
        if (pinSize == 0) {
            return;
        }

        for (uint32_t i = 0; i < pinSize; i++) {
            auto label = itemBuilder();
            label->setFilled(false);
            label->setBorderColor(gui::ColorFullBlack);
            label->setPenWidth(2);
            label->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
            label->setVisible(true);
            label->activeItem = false;
            pinLabelsBox->addWidget(label);
        }
    }

    top_bar::Configuration LockInputWindow::configureTopBar(top_bar::Configuration appConfiguration)
    {
        appConfiguration.disable(top_bar::Indicator::NetworkAccessTechnology);
        appConfiguration.enable(top_bar::Indicator::Time);
        appConfiguration.enable(top_bar::Indicator::PhoneMode);
        appConfiguration.enable(top_bar::Indicator::Battery);
        appConfiguration.enable(top_bar::Indicator::Signal);
        appConfiguration.enable(top_bar::Indicator::SimCard);
        return appConfiguration;
    }

    void LockInputWindow::restore() noexcept
    {
        infoImage->showImage(false);
        primaryText->setVisible(false);
        secondaryText->setVisible(false);
        pinLabelsBox->setVisible(false);
    }

    void LockInputWindow::setImage(const UTF8 &imageName)
    {
        infoImage->setImage(imageName);
        infoImage->showImage(true);
    }

    void LockInputWindow::setBottomBarWidgetsActive(bool left, bool center, bool right)
    {
        bottomBar->setActive(BottomBar::Side::LEFT, left);
        bottomBar->setActive(BottomBar::Side::CENTER, center);
        bottomBar->setActive(BottomBar::Side::RIGHT, right);
    }

    void LockInputWindow::setText(const std::string &value, TextType type, text::RichTextParser::TokenMap tokens)
    {
        switch (type) {
        case TextType::Title: {
            title->setVisible(true);
            if (!tokens.empty()) {
                TextFormat format(FontManager::getInstance().getFont(style::window::font::medium));
                title->setText(
                    text::RichTextParser().parse(utils::translate(value), &format, std::move(tokens))->getText());
            }
            else {
                title->setText(utils::translate(value));
            }
            break;
        }
        case TextType::Primary:
            primaryText->setVisible(true);
            primaryText->setRichText(utils::translate(value), std::move(tokens));
            break;
        case TextType::Secondary:
            secondaryText->setVisible(true);
            secondaryText->setRichText(utils::translate(value), std::move(tokens));
            break;
        }
    }

    void LockInputWindow::setTitleBar(bool titleVisible, bool iceVisible)
    {
        title->setVisible(titleVisible);
        iceBox->setVisible(iceVisible);
    }

    auto LockInputWindow::getToken(LockInputWindow::Token token) const -> std::string
    {
        if (token == Token::PinType) {
            return "$PINTYPE";
        }
        else if (token == Token::Sim) {
            return "$SIM";
        }
        else if (token == Token::Attempts) {
            return "$ATTEMPTS";
        }
        else if (token == Token::Mins) {
            return "$MINUTES";
        }
        else if (token == Token::CmeCode) {
            return "$CMECODE";
        }
        return std::string{};
    }

    void LockInputWindow::setVisibleState()
    {
        restore();
        switch (lock->getState()) {
        case locks::Lock::LockState::InputRequired:
            lockBox->setVisibleStateInputRequired(LockBox::InputActionType::ProvideInput);
            break;
        case locks::Lock::LockState::InputInvalid:
            lockBox->setVisibleStateInputInvalid(LockBox::InputErrorType::InvalidInput, lock->getAttemptsLeft());
            break;
        case locks::Lock::LockState::Blocked:
            lockBox->setVisibleStateBlocked();
            break;
        case locks::Lock::LockState::NewInputRequired:
            lockBox->setVisibleStateInputRequired(LockBox::InputActionType::ProvideNewInput);
            break;
        case locks::Lock::LockState::NewInputConfirmRequired:
            lockBox->setVisibleStateInputRequired(LockBox::InputActionType::ConfirmNewInput);
            break;
        case locks::Lock::LockState::NewInputInvalid:
            lockBox->setVisibleStateInputInvalid(LockBox::InputErrorType::NewInputConfirmFailed,
                                                 lock->getAttemptsLeft());
            break;
        default:
            break;
        }
    }

    auto LockInputWindow::isInInputState() const noexcept -> bool
    {
        return lock && (lock->isState(locks::Lock::LockState::InputRequired) ||
                        lock->isState(locks::Lock::LockState::NewInputRequired) ||
                        lock->isState(locks::Lock::LockState::NewInputConfirmRequired));
    }

    auto LockInputWindow::isInInvalidInputState() const noexcept -> bool
    {
        return lock && (lock->isState(locks::Lock::LockState::InputInvalid) ||
                        lock->isState(locks::Lock::LockState::NewInputInvalid));
    }
} // namespace gui

R module-apps/locks/windows/LockWindow.hpp => module-apps/locks/windows/LockInputWindow.hpp +40 -21
@@ 3,9 3,12 @@

#pragma once

#include "AppWindow.hpp"
#include "RichTextParser.hpp"
#include "Text.hpp"
#include <locks/widgets/LockBox.hpp>

#include <AppWindow.hpp>
#include <RichTextParser.hpp>
#include <Text.hpp>
#include <ImageBox.hpp>

namespace locks
{


@@ 14,7 17,7 @@ namespace locks

namespace gui
{
    class LockWindow : public AppWindow
    class LockInputWindow : public AppWindow
    {
      public:
        enum class TextType


@@ 33,29 36,45 @@ namespace gui
            PinType
        };

        LockWindow(app::Application *app, std::string name) : AppWindow(app, std::move(name))
        {}
        void build();
        void buildInfoTexts();
        void buildPinLabels(const std::function<Rect *()> &itemBuilder,
                            unsigned int pinSize,
                            unsigned int offsetX,
                            unsigned int offsetY,
                            unsigned int boxWidth);
        virtual void restore() noexcept;
        void setBottomBarWidgetsActive(bool left, bool center, bool right);
        void buildPinLabels(const std::function<Rect *()> &itemBuilder, unsigned int pinSize);
        void setText(const std::string &value,
                     TextType type,
                     text::RichTextParser::TokenMap tokens = text::RichTextParser::TokenMap{});
        void setTitleBar(bool isVisible);
        void setTitleBar(bool titleVisible, bool iceVisible);
        void setImage(const UTF8 &imageName);
        void setBottomBarWidgetsActive(bool left, bool center, bool right);

        [[nodiscard]] auto getToken(Token token) const -> std::string;
        top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration) override;

        std::unique_ptr<locks::Lock> lock = nullptr;
        gui::HBox *pinLabelsBox          = nullptr;
        gui::Text *primaryText           = nullptr;
        gui::Text *secondaryText         = nullptr;
        gui::HBox *pinLabelsBox           = nullptr;

      protected:
        virtual void buildBottomBar();
        virtual void buildTitleBar() = 0;
        LockInputWindow(app::Application *app, std::string name) : AppWindow(app, std::move(name))
        {}

        void build();
        void restore() noexcept;

        virtual void setVisibleState();
        std::unique_ptr<LockBox> lockBox = nullptr;

        [[nodiscard]] auto isInInputState() const noexcept -> bool;
        [[nodiscard]] auto isInInvalidInputState() const noexcept -> bool;

      private:
        gui::VBox *body          = nullptr;
        gui::HBox *iceBox        = nullptr;
        gui::ImageBox *infoImage = nullptr;
        gui::Text *primaryText   = nullptr;
        gui::Text *secondaryText = nullptr;

        void buildBody();
        void buildImage();
        void buildInfoTexts();
        void buildPinBody();
        void buildBottomBar();
        void buildIceBox();
    };
} // namespace gui

D module-apps/locks/windows/LockWindow.cpp => module-apps/locks/windows/LockWindow.cpp +0 -111
@@ 1,111 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "locks/data/LockStyle.hpp"
#include "locks/widgets/Lock.hpp"
#include "FontManager.hpp"
#include <i18n/i18n.hpp>
#include "LockWindow.hpp"

namespace lock_style = style::window::pin_lock;

namespace gui
{
    void LockWindow::build()
    {
        buildBottomBar();
        buildTitleBar();
        buildInfoTexts();
    }

    void LockWindow::buildInfoTexts()
    {
        using namespace style::window::pin_lock;

        primaryText = new Text(this, primary_text::x, primary_text::y, primary_text::w, primary_text::h);
        primaryText->setFont(style::window::font::medium);
        primaryText->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));

        secondaryText = new Text(this, secondary_text::x, secondary_text::y, secondary_text::w, secondary_text::h);
        secondaryText->setFont(style::window::font::medium);
        secondaryText->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Top));
    }

    void LockWindow::buildPinLabels(const std::function<Rect *()> &itemBuilder,
                                    unsigned int pinSize,
                                    unsigned int offsetX,
                                    unsigned int offsetY,
                                    unsigned int boxWidth)
    {
        pinLabelsBox = new gui::HBox(this, offsetX, offsetY, boxWidth, lock_style::pin_label::size);
        pinLabelsBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));

        if (pinSize == 0) {
            return;
        }

        for (uint32_t i = 0; i < pinSize; i++) {
            auto label = itemBuilder();
            label->setFilled(false);
            label->setBorderColor(gui::ColorFullBlack);
            label->setPenWidth(2);
            label->setAlignment(gui::Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center));
            label->setVisible(true);
            label->activeItem = false;
            pinLabelsBox->addWidget(label);
        }
    }

    void LockWindow::restore() noexcept
    {
        primaryText->setVisible(false);
        secondaryText->setVisible(false);
        pinLabelsBox->setVisible(false);
    }

    void LockWindow::setBottomBarWidgetsActive(bool left, bool center, bool right)
    {
        bottomBar->setActive(BottomBar::Side::LEFT, left);
        bottomBar->setActive(BottomBar::Side::CENTER, center);
        bottomBar->setActive(BottomBar::Side::RIGHT, right);
    }

    void LockWindow::setText(const std::string &value, TextType type, text::RichTextParser::TokenMap tokens)
    {
        switch (type) {
        case TextType::Title: {
            title->setVisible(true);
            if (!tokens.empty()) {
                TextFormat format(FontManager::getInstance().getFont(style::window::font::medium));
                title->setText(
                    text::RichTextParser().parse(utils::translate(value), &format, std::move(tokens))->getText());
            }
            else {
                title->setText(utils::translate(value));
            }
            break;
        }
        case TextType::Primary:
            primaryText->setVisible(true);
            primaryText->setRichText(utils::translate(value), std::move(tokens));
            break;
        case TextType::Secondary:
            secondaryText->setVisible(true);
            secondaryText->setRichText(utils::translate(value), std::move(tokens));
            break;
        }
    }

    void LockWindow::setTitleBar(bool isVisible)
    {
        title->setVisible(isVisible);
    }

    void LockWindow::buildBottomBar()
    {
        bottomBar->setText(BottomBar::Side::LEFT, utils::translate(style::strings::common::skip));
        bottomBar->setText(BottomBar::Side::CENTER, utils::translate(style::strings::common::confirm));
        bottomBar->setText(BottomBar::Side::RIGHT, utils::translate(style::strings::common::back));
    }

} // namespace gui

D module-apps/locks/windows/PinLockBaseWindow.cpp => module-apps/locks/windows/PinLockBaseWindow.cpp +0 -98
@@ 1,98 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "locks/data/LockStyle.hpp"
#include "locks/widgets/Lock.hpp"
#include <i18n/i18n.hpp>
#include "PinLockBaseWindow.hpp"
#include <Image.hpp>

namespace lock_style = style::window::pin_lock;

namespace gui
{
    void PinLockBaseWindow::buildImages(const std::string &lockImg, const std::string &infoImg)
    {
        lockImage = new gui::Image(this, lock_style::image::x, lock_style::image::y, 0, 0, lockImg);
        infoImage = new gui::Image(this, lock_style::image::x, lock_style::image::y, 0, 0, infoImg);
    }

    auto PinLockBaseWindow::getToken(Token token) const -> std::string
    {
        if (token == Token::PinType) {
            return "$PINTYPE";
        }
        else if (token == Token::Sim) {
            return "$SIM";
        }
        else if (token == Token::Attempts) {
            return "$ATTEMPTS";
        }
        else if (token == Token::Mins) {
            return "$MINUTES";
        }
        else if (token == Token::CmeCode) {
            return "$CMECODE";
        }
        return std::string{};
    }

    top_bar::Configuration PinLockBaseWindow::configureTopBar(top_bar::Configuration appConfiguration)
    {
        appConfiguration.disable(top_bar::Indicator::NetworkAccessTechnology);
        appConfiguration.enable(top_bar::Indicator::PhoneMode);
        appConfiguration.enable(top_bar::Indicator::Battery);
        appConfiguration.enable(top_bar::Indicator::Signal);
        appConfiguration.enable(top_bar::Indicator::SimCard);
        return appConfiguration;
    }

    void PinLockBaseWindow::restore() noexcept
    {
        LockWindow::restore();
        lockImage->setVisible(false);
        infoImage->setVisible(false);
    }

    void PinLockBaseWindow::setImagesVisible(bool lockImg, bool infoImg)
    {
        lockImage->setVisible(lockImg);
        infoImage->setVisible(infoImg);
    }

    void PinLockBaseWindow::setTitleBar(bool isVisible, bool isIceActive)
    {
        iceBox->setVisible(isIceActive);
        LockWindow::setTitleBar(isVisible);
    }

    void PinLockBaseWindow::buildBottomBar()
    {
        LockWindow::buildBottomBar();
        setBottomBarWidgetsActive(false, false, false);
    }

    void PinLockBaseWindow::buildTitleBar()
    {
        using namespace style::window::pin_lock;

        iceBox = new gui::HBox(this, ice::x, ice::y, ice::w, ice::h);
        iceBox->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        iceBox->setEdges(RectangleEdge::None);
        iceBox->setVisible(false);

        auto arrow        = new gui::Image("left_label_arrow");
        arrow->activeItem = false;
        arrow->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        arrow->setMargins(Margins(0, 0, ice::margin, 0));
        iceBox->addWidget(arrow);

        auto iceText        = new gui::Text(nullptr, 0, 0, ice::text::w, ice::h);
        iceText->activeItem = false;
        iceText->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center));
        iceText->setFont(style::window::font::verysmall);
        iceText->setText(utils::translate("app_desktop_emergency"));
        iceBox->addWidget(iceText);
    }

} // namespace gui

D module-apps/locks/windows/PinLockBaseWindow.hpp => module-apps/locks/windows/PinLockBaseWindow.hpp +0 -33
@@ 1,33 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "LockWindow.hpp"

namespace gui
{
    class Image;
    class PinLockBaseWindow : public LockWindow
    {
      public:
        PinLockBaseWindow(app::Application *app, std::string name) : LockWindow(app, name)
        {}

        top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration) override;

        void buildImages(const std::string &lockImg, const std::string &infoImg);
        [[nodiscard]] auto getToken(Token token) const -> std::string;
        void restore() noexcept override;
        void setImagesVisible(bool lockImg, bool infoImg);
        void setTitleBar(bool isVisible, bool isIceActive);

        gui::HBox *iceBox     = nullptr;
        gui::Image *infoImage = nullptr;
        gui::Image *lockImage = nullptr;

      private:
        void buildBottomBar() override;
        void buildTitleBar() override;
    };
} // namespace gui

D module-apps/locks/windows/PinLockWindow.cpp => module-apps/locks/windows/PinLockWindow.cpp +0 -168
@@ 1,168 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

// application manager
#include "InputEvent.hpp"
#include "service-appmgr/Controller.hpp"

// module-gui
#include "gui/widgets/BottomBar.hpp"
#include "PinLockWindow.hpp"

#include "application-desktop/ApplicationDesktop.hpp"
#include "locks/data/LockData.hpp"
#include "locks/widgets/PhoneLockBox.hpp"
#include "locks/widgets/SimLockBox.hpp"
#include "locks/widgets/PukLockBox.hpp"
#include <application-phonebook/ApplicationPhonebook.hpp>

namespace gui
{

    PinLockWindow::PinLockWindow(app::Application *app, const std::string &window_name)
        : PinLockBaseWindow(app, window_name), this_window_name(window_name)
    {
        buildInterface();
    }

    void PinLockWindow::rebuild()
    {
        // find which widget has focus
        destroyInterface();
        buildInterface();
        // set state
        focusItem = nullptr;
    }
    void PinLockWindow::buildInterface()
    {
        AppWindow::buildInterface();
        PinLockBaseWindow::build();
    }

    void PinLockWindow::destroyInterface()
    {
        erase();
    }

    void PinLockWindow::setVisibleState()
    {
        restore();
        if (lock->isState(Lock::LockState::InputRequired)) {
            lockBox->setVisibleStateInputRequired(LockBox::InputActionType::ProvideInput);
        }
        else if (lock->isState(Lock::LockState::InputInvalid)) {
            lockBox->setVisibleStateInputInvalid(LockBox::InputErrorType::InvalidInput, lock->getAttemptsLeft());
        }
        else if (lock->isState(Lock::LockState::Blocked)) {
            lockBox->setVisibleStateBlocked();
        }
        else if (lock->isState(Lock::LockState::NewInputRequired)) {
            lockBox->setVisibleStateInputRequired(LockBox::InputActionType::ProvideNewInput);
        }
        else if (lock->isState(Lock::LockState::NewInputConfirmRequired)) {
            lockBox->setVisibleStateInputRequired(LockBox::InputActionType::ConfirmNewInput);
        }
        else if (lock->isState(Lock::LockState::NewInputInvalid)) {
            lockBox->setVisibleStateInputInvalid(LockBox::InputErrorType::NewInputConfirmFailed,
                                                 lock->getAttemptsLeft());
        }
        else if (lock->isState(Lock::LockState::ErrorOccurred)) {
            lockBox->setVisibleStateInputInvalid(LockBox::InputErrorType::UnhandledError, lock->getAttemptsLeft());
        }
        application->refreshWindow(RefreshModes::GUI_REFRESH_FAST);
    }

    void PinLockWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        if (auto lockData = dynamic_cast<LockData *>(data)) {
            rebuild();
            lock = std::make_unique<locks::Lock>(lockData->getLock());

            buildPinLockBox();
            lockBox->buildLockBox(lock->getMaxInputSize());

            if (lock->isState(Lock::LockState::InputRequired)) {
                currentPasscodeType = LockBox::InputActionType::ProvideInput;
            }
            else if (lock->isState(Lock::LockState::NewInputRequired)) {
                currentPasscodeType = LockBox::InputActionType::ProvideNewInput;
            }
            setVisibleState();
        }
    }

    bool PinLockWindow::onInput(const InputEvent &inputEvent)
    {
        if (!inputEvent.isShortRelease()) {
            return AppWindow::onInput(inputEvent);
        }
        // accept only LF, enter, RF, #, and numeric values;
        if (inputEvent.is(KeyCode::KEY_LEFT) && iceBox->visible) {
            app::manager::Controller::sendAction(application, app::manager::actions::EmergencyDial);
            return true;
        }
        else if (inputEvent.is(KeyCode::KEY_RF) && bottomBar->isActive(BottomBar::Side::RIGHT)) {
            if (usesNumericKeys()) {
                lock->clearAttempt();
            }
            else if (lock->isState(Lock::LockState::InputInvalid)) {
                lock->consumeState();
            }
            application->returnToPreviousWindow();
            return true;
        }
        else if (inputEvent.is(KeyCode::KEY_PND)) {
            if (usesNumericKeys()) {
                lock->popChar();
                lockBox->popChar(lock->getCharCount());
                bottomBar->setActive(BottomBar::Side::CENTER, lock->canVerify());
                return true;
            }
        }
        else if (inputEvent.isDigit()) {
            if (usesNumericKeys() && lock->canPut()) {
                lockBox->putChar(lock->getCharCount());
                lock->putNextChar(inputEvent.numericValue());
                bottomBar->setActive(BottomBar::Side::CENTER, lock->canVerify());
                return true;
            }
        }
        else if (inputEvent.is(KeyCode::KEY_ENTER) && bottomBar->isActive(BottomBar::Side::CENTER)) {
            lock->activate();
            bottomBar->setActive(BottomBar::Side::CENTER, false);
            return true;
        }
        // check if any of the lower inheritance onInput methods catch the event
        return AppWindow::onInput(inputEvent);
    }

    void PinLockWindow::buildPinLockBox()
    {
        auto lockType = lock->getLockType();
        if (lockType == Lock::LockType::Screen) {
            lockBox = std::make_unique<PhoneLockBox>(this);
        }
        else if (lockType == Lock::LockType::SimPuk) {
            lockBox = std::make_unique<PukLockBox>(this);
            setTitleBar(true, true);
            setText("app_desktop_header_sim_setup",
                    TextType::Title,
                    {{getToken(Token::Sim), utils::enumToString(lock->getSim())}});
        }
        else if (lockType == Lock::LockType::SimPin) {
            lockBox = std::make_unique<SimLockBox>(this);
            setTitleBar(true, false);
            setText("app_desktop_header_sim_setup",
                    TextType::Title,
                    {{getToken(Token::Sim), utils::enumToString(lock->getSim())}});
        }
        assert(lockBox != nullptr);
    }

    auto PinLockWindow::usesNumericKeys() const noexcept -> bool
    {
        return lock &&
               (lock->isState(Lock::LockState::InputRequired) || lock->isState(Lock::LockState::NewInputRequired) ||
                lock->isState(Lock::LockState::NewInputConfirmRequired));
    }
} /* namespace gui */

D module-apps/locks/windows/PinLockWindow.hpp => module-apps/locks/windows/PinLockWindow.hpp +0 -38
@@ 1,38 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "AppWindow.hpp"
#include "gui/widgets/Label.hpp"
#include "gui/widgets/Image.hpp"
#include "gui/widgets/BottomBar.hpp"
#include "locks/widgets/Lock.hpp"
#include "locks/widgets/LockBox.hpp"
#include "PinLockBaseWindow.hpp"

namespace gui
{
    class PinLockWindow : public PinLockBaseWindow
    {
        const std::string this_window_name;
        std::string lockTimeoutApplication           = "";
        std::unique_ptr<LockBox> lockBox             = nullptr;
        LockBox::InputActionType currentPasscodeType = LockBox::InputActionType::ProvideInput;

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

      public:
        PinLockWindow(app::Application *app, const std::string &window_name);
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        bool onInput(const InputEvent &inputEvent) override;

        void rebuild() override;
        void buildInterface() override;
        void destroyInterface() override;
    };

} /* namespace gui */

M module-apps/popups/CMakeLists.txt => module-apps/popups/CMakeLists.txt +4 -0
@@ 27,6 27,8 @@ target_sources( ${PROJECT_NAME}
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/PhoneLockedWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/PhoneLockInputWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/PhoneLockChangeInfoWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/SimLockInputWindow.cpp"
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/SimInfoWindow.cpp"

	PRIVATE
		"${CMAKE_CURRENT_LIST_DIR}/Popups.hpp"


@@ 43,4 45,6 @@ target_sources( ${PROJECT_NAME}
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/PhoneLockedWindow.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/PhoneLockInputWindow.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/PhoneLockChangeInfoWindow.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/SimLockInputWindow.hpp"
		"${CMAKE_CURRENT_LIST_DIR}/lock-popups/SimInfoWindow.hpp"
)

M module-apps/popups/Popups.cpp => module-apps/popups/Popups.cpp +5 -0
@@ 24,7 24,12 @@ namespace gui::popup
            return gui::popup::window::phone_lock_input_window;
        case ID::PhoneLockChangeInfo:
            return gui::popup::window::phone_lock_change_info_window;
        case ID::SimLock:
            return gui::popup::window::sim_unlock_window;
        case ID::SimInfo:
            return gui::popup::window::sim_info_window;
        }

        return {};
    }
} // namespace gui::popup

M module-apps/popups/Popups.hpp => module-apps/popups/Popups.hpp +4 -0
@@ 19,6 19,8 @@ namespace gui
            PhoneLock,
            PhoneLockInput,
            PhoneLockChangeInfo,
            SimLock,
            SimInfo,
        };

        namespace window


@@ 33,6 35,8 @@ namespace gui
            inline constexpr auto phone_lock_input_window           = "PhoneLockInputPopup";
            inline constexpr auto phone_lock_change_info_window     = "PhoneLockChangeInfoPopup";
            inline constexpr auto power_off_window                  = "PowerOffPopup";
            inline constexpr auto sim_unlock_window                 = "SimUnlockPopup";
            inline constexpr auto sim_info_window                   = "SimInfoPopup";

        } // namespace window


M module-apps/popups/data/PopupRequestParams.hpp => module-apps/popups/data/PopupRequestParams.hpp +32 -0
@@ 53,6 53,38 @@ namespace gui
        locks::PhoneLockInputTypeAction phoneLockInputTypeAction;
    };

    class SimUnlockInputRequestParams : public PopupRequestParams
    {
      public:
        SimUnlockInputRequestParams(gui::popup::ID popupId,
                                    locks::Lock lock,
                                    locks::SimInputTypeAction simInputTypeAction,
                                    unsigned int errorCode = 0)
            : PopupRequestParams{popupId}, lock{std::move(lock)}, simInputTypeAction(simInputTypeAction),
              errorCode(errorCode)
        {}

        [[nodiscard]] auto getLock() const noexcept
        {
            return lock;
        }

        [[nodiscard]] auto getSimInputTypeAction() const noexcept
        {
            return simInputTypeAction;
        }

        [[nodiscard]] auto getErrorCode() const noexcept
        {
            return errorCode;
        }

      private:
        locks::Lock lock;
        locks::SimInputTypeAction simInputTypeAction;
        unsigned int errorCode;
    };

    class PhoneModePopupRequestParams : public PopupRequestParams
    {
      public:

M module-apps/popups/lock-popups/PhoneLockChangeInfoWindow.cpp => module-apps/popups/lock-popups/PhoneLockChangeInfoWindow.cpp +10 -11
@@ 33,11 33,11 @@ void PhoneLockChangeInfoWindow::onBeforeShow(ShowMode mode, SwitchData *data)

        switch (infoData->getPhoneLockInputTypeAction()) {
        case locks::PhoneLockInputTypeAction::Disable:
            infoText->setRichText(utils::translate("phone_lock_disabled"));
            infoIcon->text->setRichText(utils::translate("phone_lock_disabled"));
            break;
        case locks::PhoneLockInputTypeAction::Enable:
        case locks::PhoneLockInputTypeAction::Change:
            infoText->setRichText(utils::translate("phone_lock_changed_successfully"));
            infoIcon->text->setRichText(utils::translate("phone_lock_changed_successfully"));
            break;
        default:
            break;


@@ 47,17 47,16 @@ void PhoneLockChangeInfoWindow::onBeforeShow(ShowMode mode, SwitchData *data)

void PhoneLockChangeInfoWindow::buildInterface()
{
    namespace lock_style = style::window::pin_lock;
    AppWindow::buildInterface();

    setTitle(utils::translate("phone_lock_configure"));

    infoImage = new gui::Image(this, lock_style::image::x, lock_style::image::y, 0, 0, "success_icon_W_G");
    infoText  = new Text(this,
                        lock_style::primary_text::x,
                        lock_style::primary_text::y,
                        lock_style::primary_text::w,
                        lock_style::primary_text::h);

    infoText->setAlignment(Alignment::Horizontal::Center);
    infoIcon = new gui::Icon(this,
                             style::window::default_left_margin,
                             style::header::height,
                             style::window::default_body_width,
                             style::window::default_body_height,
                             "success_icon_W_G",
                             "");
    infoIcon->setAlignment(Alignment::Horizontal::Center);
}

M module-apps/popups/lock-popups/PhoneLockChangeInfoWindow.hpp => module-apps/popups/lock-popups/PhoneLockChangeInfoWindow.hpp +2 -3
@@ 5,14 5,13 @@

#include <popups/WindowWithTimer.hpp>
#include <Text.hpp>
#include <gui/widgets/Image.hpp>
#include <gui/widgets/Icon.hpp>

namespace gui
{
    class PhoneLockChangeInfoWindow : public WindowWithTimer
    {
        gui::Image *infoImage = nullptr;
        gui::Text *infoText   = nullptr;
        Icon *infoIcon = nullptr;

      public:
        PhoneLockChangeInfoWindow(app::Application *app, const std::string &name);

M module-apps/popups/lock-popups/PhoneLockInputWindow.cpp => module-apps/popups/lock-popups/PhoneLockInputWindow.cpp +10 -29
@@ 11,7 11,7 @@
namespace gui
{
    PhoneLockInputWindow::PhoneLockInputWindow(app::Application *app, const std::string &window_name)
        : PinLockBaseWindow(app, window_name)
        : LockInputWindow(app, window_name)
    {
        buildInterface();
    }


@@ 24,7 24,7 @@ namespace gui
    void PhoneLockInputWindow::buildInterface()
    {
        AppWindow::buildInterface();
        LockWindow::build();
        LockInputWindow::build();
    }

    void PhoneLockInputWindow::destroyInterface()


@@ 32,28 32,17 @@ namespace gui
        erase();
    }

    void PhoneLockInputWindow::setVisibleState()
    top_bar::Configuration PhoneLockInputWindow::configureTopBar(top_bar::Configuration appConfiguration)
    {
        restore();
        if (lock->isState(locks::Lock::LockState::InputRequired)) {
            lockBox->setVisibleStateInputRequired(LockBox::InputActionType::ProvideInput);
        if (phoneLockInputTypeAction == locks::PhoneLockInputTypeAction::Unlock) {
            appConfiguration.enable(top_bar::Indicator::Lock);
            appConfiguration.disable(top_bar::Indicator::Time);
        }
        else if (lock->isState(locks::Lock::LockState::InputInvalid)) {
            lockBox->setVisibleStateInputInvalid(LockBox::InputErrorType::InvalidInput, lock->getAttemptsLeft());
        }
        else if (lock->isState(locks::Lock::LockState::Blocked)) {
            lockBox->setVisibleStateBlocked();
        }
        else if (lock->isState(locks::Lock::LockState::NewInputRequired)) {
            lockBox->setVisibleStateInputRequired(LockBox::InputActionType::ProvideNewInput);
        }
        else if (lock->isState(locks::Lock::LockState::NewInputConfirmRequired)) {
            lockBox->setVisibleStateInputRequired(LockBox::InputActionType::ConfirmNewInput);
        }
        else if (lock->isState(locks::Lock::LockState::NewInputInvalid)) {
            lockBox->setVisibleStateInputInvalid(LockBox::InputErrorType::NewInputConfirmFailed,
                                                 lock->getAttemptsLeft());
        else {
            appConfiguration.enable(top_bar::Indicator::Time);
            appConfiguration.disable(top_bar::Indicator::Lock);
        }
        return appConfiguration;
    }

    void PhoneLockInputWindow::onBeforeShow(ShowMode mode, SwitchData *data)


@@ 134,12 123,4 @@ namespace gui
        // check if any of the lower inheritance onInput methods catch the event
        return AppWindow::onInput(inputEvent);
    }

    auto PhoneLockInputWindow::isInInputState() const noexcept -> bool
    {
        return lock && (lock->isState(locks::Lock::LockState::InputRequired) ||
                        lock->isState(locks::Lock::LockState::NewInputRequired) ||
                        lock->isState(locks::Lock::LockState::NewInputConfirmRequired));
    }

} /* namespace gui */

M module-apps/popups/lock-popups/PhoneLockInputWindow.hpp => module-apps/popups/lock-popups/PhoneLockInputWindow.hpp +3 -6
@@ 6,18 6,14 @@
#include <locks/data/LockData.hpp>
#include <locks/widgets/Lock.hpp>
#include <locks/widgets/LockBox.hpp>
#include <locks/windows/PinLockBaseWindow.hpp>
#include <locks/windows/LockInputWindow.hpp>

namespace gui
{
    class PhoneLockInputWindow : public PinLockBaseWindow
    class PhoneLockInputWindow : public LockInputWindow
    {
        std::unique_ptr<LockBox> lockBox                         = nullptr;
        locks::PhoneLockInputTypeAction phoneLockInputTypeAction = locks::PhoneLockInputTypeAction::Unlock;

        void setVisibleState();
        [[nodiscard]] auto isInInputState() const noexcept -> bool;

      public:
        PhoneLockInputWindow(app::Application *app, const std::string &window_name);
        void onBeforeShow(ShowMode mode, SwitchData *data) override;


@@ 26,6 22,7 @@ namespace gui
        void rebuild() override;
        void buildInterface() override;
        void destroyInterface() override;
        top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration) override;
    };

} /* namespace gui */

M module-apps/popups/lock-popups/PhoneLockedInfoWindow.cpp => module-apps/popups/lock-popups/PhoneLockedInfoWindow.cpp +9 -17
@@ 18,13 18,6 @@ PhoneLockedInfoWindow::PhoneLockedInfoWindow(app::Application *app, const std::s

void PhoneLockedInfoWindow::onBeforeShow(ShowMode mode, SwitchData *data)
{
    setVisibleState();
}

void PhoneLockedInfoWindow::setVisibleState()
{
    lockImage->setVisible(true);

    bottomBar->setActive(BottomBar::Side::LEFT, true);
    bottomBar->setActive(BottomBar::Side::CENTER, false);
    bottomBar->setActive(BottomBar::Side::RIGHT, true);


@@ 56,19 49,18 @@ top_bar::Configuration PhoneLockedInfoWindow::configureTopBar(top_bar::Configura

void PhoneLockedInfoWindow::buildInterface()
{
    namespace lock_style = style::window::pin_lock;
    namespace lock_style = style::window::lock_input;
    AppWindow::buildInterface();

    bottomBar->setText(BottomBar::Side::LEFT, utils::translate("app_desktop_emergency"));
    bottomBar->setText(BottomBar::Side::RIGHT, utils::translate("common_back"));

    lockImage = new gui::Image(this, lock_style::image::x, lock_style::image::y, 0, 0, "pin_lock");
    infoText  = new Text(this,
                        lock_style::primary_text::x,
                        lock_style::primary_text::y,
                        lock_style::primary_text::w,
                        lock_style::primary_text::h);

    infoText->setRichText(utils::translate("app_desktop_press_to_unlock"));
    infoText->setAlignment(Alignment::Horizontal::Center);
    infoIcon = new gui::Icon(this,
                             style::window::default_left_margin,
                             style::header::height,
                             style::window::default_body_width,
                             style::window::default_body_height,
                             "unlock_icon_W_G",
                             utils::translate("app_desktop_press_to_unlock"));
    infoIcon->setAlignment(Alignment::Horizontal::Center);
}

M module-apps/popups/lock-popups/PhoneLockedInfoWindow.hpp => module-apps/popups/lock-popups/PhoneLockedInfoWindow.hpp +2 -5
@@ 5,16 5,13 @@

#include <AppWindow.hpp>
#include <Text.hpp>
#include <gui/widgets/Image.hpp>
#include <gui/widgets/Icon.hpp>

namespace gui
{
    class PhoneLockedInfoWindow : public AppWindow
    {
        gui::Image *lockImage = nullptr;
        gui::Text *infoText   = nullptr;

        void setVisibleState();
        Icon *infoIcon = nullptr;

      public:
        PhoneLockedInfoWindow(app::Application *app, const std::string &name);

A module-apps/popups/lock-popups/SimInfoWindow.cpp => module-apps/popups/lock-popups/SimInfoWindow.cpp +67 -0
@@ 0,0 1,67 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SimInfoWindow.hpp"
#include <locks/data/LockStyle.hpp>
#include <locks/data/LockData.hpp>
#include <i18n/i18n.hpp>

using namespace gui;

SimInfoWindow::SimInfoWindow(app::Application *app, const std::string &name) : WindowWithTimer(app, name)
{
    buildInterface();
}

top_bar::Configuration SimInfoWindow::configureTopBar(top_bar::Configuration appConfiguration)
{
    appConfiguration.enable(top_bar::Indicator::NetworkAccessTechnology);
    appConfiguration.enable(top_bar::Indicator::Time);
    appConfiguration.enable(top_bar::Indicator::PhoneMode);
    appConfiguration.enable(top_bar::Indicator::Battery);
    appConfiguration.enable(top_bar::Indicator::Signal);
    appConfiguration.enable(top_bar::Indicator::SimCard);
    return appConfiguration;
}

void SimInfoWindow::onBeforeShow(ShowMode mode, SwitchData *data)
{
    WindowWithTimer::onBeforeShow(mode, data);

    if (auto infoData = dynamic_cast<locks::SimLockData *>(data)) {

        switch (infoData->getSimInputTypeAction()) {
        case locks::SimInputTypeAction::UnlockWithPuk:
        case locks::SimInputTypeAction::ChangePin:
            setTitle(utils::translate("sim_change_pin"));
            infoIcon->text->setRichText(utils::translate("sim_pin_changed_successfully"));
            break;
        case locks::SimInputTypeAction::EnablePin:
            setTitle("");
            infoIcon->text->setRichText(utils::translate("sim_card_pin_enabled"));
            break;
        case locks::SimInputTypeAction::DisablePin:
            setTitle("");
            infoIcon->text->setRichText(utils::translate("sim_card_pin_disabled"));
            break;
        default:
            break;
        }
    }
}

void SimInfoWindow::buildInterface()
{
    AppWindow::buildInterface();

    setTitle(utils::translate("sim_change_pin"));

    infoIcon = new gui::Icon(this,
                             style::window::default_left_margin,
                             style::header::height,
                             style::window::default_body_width,
                             style::window::default_body_height,
                             "success_icon_W_G",
                             utils::translate("sim_pin_changed_successfully"));
    infoIcon->setAlignment(Alignment::Horizontal::Center);
}

A module-apps/popups/lock-popups/SimInfoWindow.hpp => module-apps/popups/lock-popups/SimInfoWindow.hpp +23 -0
@@ 0,0 1,23 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <popups/WindowWithTimer.hpp>
#include <Text.hpp>
#include <gui/widgets/Icon.hpp>

namespace gui
{
    class SimInfoWindow : public WindowWithTimer
    {
        Icon *infoIcon = nullptr;

      public:
        SimInfoWindow(app::Application *app, const std::string &name);

        void buildInterface() override;
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration) override;
    };
} /* namespace gui */

A module-apps/popups/lock-popups/SimLockInputWindow.cpp => module-apps/popups/lock-popups/SimLockInputWindow.cpp +123 -0
@@ 0,0 1,123 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SimLockInputWindow.hpp"

#include <locks/data/LockData.hpp>
#include <locks/widgets/SimLockBox.hpp>
#include <locks/widgets/LockHash.hpp>

#include <service-appmgr/Controller.hpp>
#include <popups/data/PopupRequestParams.hpp>

namespace gui
{
    SimLockInputWindow::SimLockInputWindow(app::Application *app, const std::string &window_name)
        : LockInputWindow(app, window_name)
    {
        buildInterface();
    }

    void SimLockInputWindow::rebuild()
    {
        destroyInterface();
        buildInterface();
    }
    void SimLockInputWindow::buildInterface()
    {
        AppWindow::buildInterface();
        LockInputWindow::build();
    }

    void SimLockInputWindow::destroyInterface()
    {
        erase();
    }

    void SimLockInputWindow::setVisibleState()
    {
        LockInputWindow::setVisibleState();

        if (lock->isState(locks::Lock::LockState::ErrorOccurred)) {
            lockBox->setVisibleStateError(errorCode);
        }
    }

    top_bar::Configuration SimLockInputWindow::configureTopBar(top_bar::Configuration appConfiguration)
    {
        appConfiguration.disable(top_bar::Indicator::NetworkAccessTechnology);
        appConfiguration.enable(top_bar::Indicator::Time);
        appConfiguration.enable(top_bar::Indicator::PhoneMode);
        appConfiguration.enable(top_bar::Indicator::Battery);
        appConfiguration.enable(top_bar::Indicator::Signal);
        appConfiguration.enable(top_bar::Indicator::SimCard);
        return appConfiguration;
    }

    void SimLockInputWindow::onBeforeShow(ShowMode mode, SwitchData *data)
    {
        if (auto SimLockData = dynamic_cast<locks::SimLockData *>(data)) {
            lock                   = std::make_unique<locks::Lock>(SimLockData->getLock());
            simLockInputTypeAction = SimLockData->getSimInputTypeAction();
            errorCode              = SimLockData->getErrorCode();
        }

        // Lock need to exist in that window flow
        assert(lock);

        rebuild();
        lockBox = std::make_unique<SimLockBox>(this, simLockInputTypeAction);
        lockBox->buildLockBox(lock->getMaxInputSize());

        setVisibleState();
    }

    bool SimLockInputWindow::onInput(const InputEvent &inputEvent)
    {
        if (!inputEvent.isShortRelease()) {
            return AppWindow::onInput(inputEvent);
        }
        else if (inputEvent.is(KeyCode::KEY_RF) && bottomBar->isActive(BottomBar::Side::RIGHT)) {
            if (isInInputState()) {
                lock->clearAttempt();
            }
            else if (lock->isState(locks::Lock::LockState::InputInvalid)) {
                lock->consumeState();
            }
            application->returnToPreviousWindow();
            return true;
        }
        else if (inputEvent.is(KeyCode::KEY_PND)) {
            if (isInInputState()) {
                lock->popChar();
                lockBox->popChar(lock->getCharCount());
                bottomBar->setActive(BottomBar::Side::CENTER, lock->canVerify());
                return true;
            }
        }
        else if (inputEvent.isDigit()) {
            if (isInInputState() && lock->canPut()) {
                lockBox->putChar(lock->getCharCount());
                lock->putNextChar(inputEvent.numericValue());

                bottomBar->setActive(BottomBar::Side::CENTER, lock->canVerify());
                return true;
            }
        }
        else if (inputEvent.is(KeyCode::KEY_ENTER) && bottomBar->isActive(BottomBar::Side::CENTER)) {
            if (isInInputState()) {
                application->getSimLockSubject().verifyInput(lock->getInput());
            }
            else if (isInInvalidInputState()) {
                lock->consumeState();
                lock->clearAttempt();
                setVisibleState();
            }
            return true;
        }

        // check if any of the lower inheritance onInput methods catch the event
        return AppWindow::onInput(inputEvent);
    }

} /* namespace gui */

A module-apps/popups/lock-popups/SimLockInputWindow.hpp => module-apps/popups/lock-popups/SimLockInputWindow.hpp +32 -0
@@ 0,0 1,32 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <locks/data/LockData.hpp>
#include <locks/widgets/Lock.hpp>
#include <locks/widgets/LockBox.hpp>
#include <locks/windows/LockInputWindow.hpp>

namespace gui
{
    class SimLockInputWindow : public LockInputWindow
    {
      private:
        locks::SimInputTypeAction simLockInputTypeAction = locks::SimInputTypeAction::UnlockWithPin;
        unsigned int errorCode                           = 0;

        void setVisibleState() override;

      public:
        SimLockInputWindow(app::Application *app, const std::string &window_name);
        void onBeforeShow(ShowMode mode, SwitchData *data) override;
        bool onInput(const InputEvent &inputEvent) override;

        void rebuild() override;
        void buildInterface() override;
        void destroyInterface() override;
        top_bar::Configuration configureTopBar(top_bar::Configuration appConfiguration) override;
    };

} /* namespace gui */

M module-gui/gui/widgets/Icon.cpp => module-gui/gui/widgets/Icon.cpp +1 -1
@@ 22,7 22,7 @@ Icon::Icon(Item *parent,
    setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

    image = new Image(this, imageName);
    image->setMargins(Margins(0, 0, 0, icon::image_bottom_margin));
    image->setMargins(Margins(0, icon::image_top_margin, 0, icon::image_bottom_margin));

    text = new Text(this, 0, 0, 0, 0);
    text->setMaximumSize(w, h);

M module-gui/gui/widgets/ImageBox.cpp => module-gui/gui/widgets/ImageBox.cpp +5 -0
@@ 18,3 18,8 @@ void ImageBox::showImage(bool show)
{
    image->setVisible(show);
}

void ImageBox::setImage(const UTF8 &name)
{
    image->set(name);
}

M module-gui/gui/widgets/ImageBox.hpp => module-gui/gui/widgets/ImageBox.hpp +1 -0
@@ 17,6 17,7 @@ namespace gui
        ~ImageBox() override = default;

        void showImage(bool show);
        void setImage(const UTF8 &name);

      private:
        Image *image;

M module-services/service-appmgr/CMakeLists.txt => module-services/service-appmgr/CMakeLists.txt +0 -1
@@ 4,7 4,6 @@ message( "${PROJECT_NAME}  ${CMAKE_CURRENT_LIST_DIR}" )
set(SOURCES
    ApplicationManifest.cpp
    Controller.cpp
    data/SimActionsParams.cpp
    data/MmiActionsParams.cpp
    data/NotificationsChangedActionsParams.cpp
    model/ApplicationManager.cpp

D module-services/service-appmgr/data/SimActionsParams.cpp => module-services/service-appmgr/data/SimActionsParams.cpp +0 -43
@@ 1,43 0,0 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

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

using namespace app::manager::actions;

PasscodeParams::PasscodeParams(Store::GSM::SIM _sim, unsigned int _attempts, std::string _passcodeName)
    : sim{_sim}, attempts{_attempts}, passcodeName{std::move(_passcodeName)}
{}

Store::GSM::SIM PasscodeParams::getSim() const noexcept
{
    return sim;
}
unsigned int PasscodeParams::getAttempts() const noexcept
{
    return attempts;
}
const std::string &PasscodeParams::getPasscodeName() const noexcept
{
    return passcodeName;
}

SimStateParams::SimStateParams(Store::GSM::SIM _sim) : sim{_sim}
{}

Store::GSM::SIM SimStateParams::getSim() const noexcept
{
    return sim;
}

UnhandledCMEParams::UnhandledCMEParams(Store::GSM::SIM _sim, unsigned int _cmeCode) : sim{_sim}, cmeCode{_cmeCode}
{}

Store::GSM::SIM UnhandledCMEParams::getSim() const noexcept
{
    return sim;
}
unsigned int UnhandledCMEParams::getCMECode() const noexcept
{
    return cmeCode;
}

M module-services/service-appmgr/model/ApplicationManager.cpp => module-services/service-appmgr/model/ApplicationManager.cpp +112 -79
@@ 40,6 40,7 @@
#include <service-appmgr/messages/AutoLockRequests.hpp>
#include <service-db/DBNotificationMessage.hpp>
#include <module-db/queries/notifications/QueryNotificationsGetAll.hpp>
#include <service-cellular-api>

#include "module-services/service-appmgr/service-appmgr/messages/ApplicationStatus.hpp"



@@ 138,7 139,7 @@ namespace app::manager
          actionsRegistry{[this](ActionEntry &action) { return handleAction(action); }}, notificationProvider(this),
          settings(std::make_unique<settings::Settings>()),
          phoneModeObserver(std::make_unique<sys::phone_modes::Observer>()),
          phoneLockHandler(locks::PhoneLockHandler(this, settings))
          phoneLockHandler(locks::PhoneLockHandler(this, settings)), simLockHandler(this)
    {
        autoLockTimer = sys::TimerFactory::createSingleShotTimer(
            this, autoLockTimerName, sys::timer::InfiniteTimeout, [this](sys::Timer &) { onPhoneLocked(); });


@@ 425,6 426,8 @@ namespace app::manager
            handleDBResponse(response);
            return sys::msgHandled();
        });

        // PhoneLock connects
        connect(typeid(locks::LockPhone),
                [&](sys::Message *request) -> sys::MessagePointer { return phoneLockHandler.handleLockRequest(); });
        connect(typeid(locks::UnlockPhone),


@@ 433,7 436,7 @@ namespace app::manager
            return phoneLockHandler.handleUnlockCancelRequest();
        });
        connect(typeid(locks::UnLockPhoneInput), [&](sys::Message *request) -> sys::MessagePointer {
            auto data = dynamic_cast<locks::UnLockPhoneInput *>(request);
            auto data = static_cast<locks::UnLockPhoneInput *>(request);
            return phoneLockHandler.verifyPhoneLockInput(data->getInputData());
        });
        connect(typeid(locks::EnablePhoneLock),


@@ 443,7 446,7 @@ namespace app::manager
        });
        connect(typeid(locks::UnlockedPhone), [&](sys::Message *request) -> sys::MessagePointer {
            autoLockTimer.start();
            return sys::msgHandled();
            return simLockHandler.releaseSimUnlockBlockOnLockedPhone();
        });
        connect(typeid(locks::ChangePhoneLock),
                [&](sys::Message *request) -> sys::MessagePointer { return phoneLockHandler.handleChangePhoneLock(); });


@@ 461,6 464,112 @@ namespace app::manager
            return handleAutoLockSetRequest(req);
        });

        // SimLock connects
        connect(typeid(cellular::msg::notification::SimNeedPin), [&](sys::Message *request) -> sys::MessagePointer {
            auto data = static_cast<cellular::msg::notification::SimNeedPin *>(request);
            if (phoneLockHandler.isPhoneLocked()) {
                simLockHandler.setSimUnlockBlockOnLockedPhone();
            }
            return simLockHandler.handleSimPinRequest(data->attempts);
        });
        connect(typeid(cellular::msg::request::sim::PinUnlock::Response),
                [&](sys::Message *request) -> sys::MessagePointer {
                    auto data = static_cast<cellular::msg::request::sim::PinUnlock::Response *>(request);
                    if (data->retCode) {
                        return simLockHandler.handleSimUnlockedMessage();
                    }
                    return sys::msgNotHandled();
                });
        connect(typeid(locks::UnLockSimInput), [&](sys::Message *request) -> sys::MessagePointer {
            auto msg = static_cast<locks::UnLockSimInput *>(request);
            return simLockHandler.verifySimLockInput(msg->getInputData());
        });
        connect(typeid(cellular::msg::notification::SimNeedPuk), [&](sys::Message *request) -> sys::MessagePointer {
            auto data = static_cast<cellular::msg::notification::SimNeedPuk *>(request);
            if (phoneLockHandler.isPhoneLocked()) {
                simLockHandler.setSimUnlockBlockOnLockedPhone();
            }
            return simLockHandler.handleSimPukRequest(data->attempts);
        });
        connect(typeid(cellular::msg::request::sim::UnblockWithPuk::Response),
                [&](sys::Message *request) -> sys::MessagePointer {
                    auto data = static_cast<cellular::msg::request::sim::UnblockWithPuk::Response *>(request);
                    if (data->retCode) {
                        return simLockHandler.handleSimUnlockedMessage();
                    }
                    return sys::msgNotHandled();
                });
        connect(typeid(locks::ChangeSimPin), [&](sys::Message *request) -> sys::MessagePointer {
            return simLockHandler.handleSimPinChangeRequest();
        });
        connect(typeid(cellular::msg::request::sim::ChangePin::Response),
                [&](sys::Message *request) -> sys::MessagePointer {
                    auto data = static_cast<cellular::msg::request::sim::ChangePin::Response *>(request);
                    if (data->retCode) {
                        return simLockHandler.handleSimChangedMessage();
                    }
                    else {
                        return simLockHandler.handleSimPinChangeFailedRequest();
                    }
                });
        connect(typeid(locks::EnableSimPin),
                [&](sys::Message *request) -> sys::MessagePointer { return simLockHandler.handleSimEnableRequest(); });
        connect(typeid(locks::DisableSimPin),
                [&](sys::Message *request) -> sys::MessagePointer { return simLockHandler.handleSimDisableRequest(); });
        connect(typeid(cellular::msg::request::sim::SetPinLock::Response),
                [&](sys::Message *request) -> sys::MessagePointer {
                    auto data = static_cast<cellular::msg::request::sim::SetPinLock::Response *>(request);
                    if (data->retCode) {
                        return simLockHandler.handleSimAvailabilityMessage();
                    }
                    else {
                        if (data->lock == cellular::api::SimLockState::Enabled) {
                            return simLockHandler.handleSimEnableRequest();
                        }
                        else {
                            return simLockHandler.handleSimDisableRequest();
                        }
                    }
                });
        connect(typeid(cellular::msg::notification::SimBlocked), [&](sys::Message *request) -> sys::MessagePointer {
            if (phoneLockHandler.isPhoneLocked()) {
                simLockHandler.setSimUnlockBlockOnLockedPhone();
            }
            return simLockHandler.handleSimBlockedRequest();
        });
        connect(typeid(cellular::msg::notification::UnhandledCME), [&](sys::Message *request) -> sys::MessagePointer {
            auto data = static_cast<cellular::msg::notification::UnhandledCME *>(request);
            if (phoneLockHandler.isPhoneLocked()) {
                simLockHandler.setSimUnlockBlockOnLockedPhone();
            }
            return simLockHandler.handleCMEErrorRequest(data->code);
        });
        connect(typeid(locks::SetSim), [&](sys::Message *request) -> sys::MessagePointer {
            auto data = static_cast<locks::SetSim *>(request);
            simLockHandler.setSim(data->getSimSlot());
            return sys::msgHandled();
        });
        connect(typeid(cellular::msg::request::sim::SetActiveSim::Response),
                [&](sys::Message *request) -> sys::MessagePointer {
                    auto data = static_cast<cellular::msg::request::sim::SetActiveSim::Response *>(request);
                    if (data->retCode) {
                        settings->setValue(::settings::SystemProperties::activeSim,
                                           utils::enumToString(Store::GSM::get()->selected),
                                           ::settings::SettingsScope::Global);
                        return sys::msgHandled();
                    }
                    return sys::msgNotHandled();
                });
        connect(typeid(cellular::StateChange), [&](sys::Message *request) -> sys::MessagePointer {
            auto data = static_cast<cellular::StateChange *>(request);
            if (data->request == cellular::service::State::ST::URCReady) {
                simLockHandler.getSettingsSimSelect(
                    settings->getValue(settings::SystemProperties::activeSim, settings::SettingsScope::Global));
                return sys::msgHandled();
            }
            return sys::msgNotHandled();
        });

        connect(typeid(sdesktop::developerMode::DeveloperModeRequest),
                [&](sys::Message *request) -> sys::MessagePointer { return handleDeveloperModeRequest(request); });



@@ 480,33 589,6 @@ namespace app::manager
        connect(typeid(sys::TetheringQuestionAbort), convertibleToActionHandler);
        connect(typeid(sys::TetheringPhoneModeChangeProhibitedMessage), convertibleToActionHandler);
        connect(typeid(VolumeChanged), convertibleToActionHandler);

        /* Notifications from sys::BusChannel::ServiceCellularNotifications */
        connect(typeid(cellular::msg::notification::SimReady), [&](sys::Message *request) {
            auto msg = static_cast<cellular::msg::notification::SimReady *>(request);
            handleSimReady(msg);
            return sys::MessageNone{};
        });
        connect(typeid(cellular::msg::notification::SimNeedPin), [&](sys::Message *request) {
            auto msg = static_cast<cellular::msg::notification::SimNeedPin *>(request);
            handleSimNeedPin(msg);
            return sys::MessageNone{};
        });
        connect(typeid(cellular::msg::notification::SimNeedPuk), [&](sys::Message *request) {
            auto msg = static_cast<cellular::msg::notification::SimNeedPuk *>(request);
            handleSimNeedPuk(msg);
            return sys::MessageNone{};
        });
        connect(typeid(cellular::msg::notification::SimBlocked), [&](sys::Message *request) {
            auto msg = static_cast<cellular::msg::notification::SimBlocked *>(request);
            handleSimBlocked(msg);
            return sys::MessageNone{};
        });
        connect(typeid(cellular::msg::notification::UnhandledCME), [&](sys::Message *request) {
            auto msg = static_cast<cellular::msg::notification::UnhandledCME *>(request);
            handleUnhandledCME(msg);
            return sys::MessageNone{};
        });
    }

    sys::ReturnCodes ApplicationManager::SwitchPowerModeHandler(const sys::ServicePowerMode mode)


@@ 654,55 736,6 @@ namespace app::manager
        actionsRegistry.enqueue(std::move(entry));
    }

    void ApplicationManager::handleSimReady(cellular::msg::notification::SimReady *msg)
    {
        if (msg->ready) {
            auto action = std::make_unique<app::manager::ActionRequest>(
                msg->sender,
                app::manager::actions::UnlockSim,
                std::make_unique<app::manager::actions::SimStateParams>(Store::GSM::get()->selected));
            handleActionRequest(action.get());
        }
    }

    void ApplicationManager::handleSimNeedPin(cellular::msg::notification::SimNeedPin *msg)
    {
        auto action = std::make_unique<app::manager::ActionRequest>(
            msg->sender,
            app::manager::actions::RequestPin,
            std::make_unique<app::manager::actions::PasscodeParams>(
                Store::GSM::get()->selected, msg->attempts, std::string()));
        handleActionRequest(action.get());
    }

    void ApplicationManager::handleSimNeedPuk(cellular::msg::notification::SimNeedPuk *msg)
    {
        auto action = std::make_unique<app::manager::ActionRequest>(
            msg->sender,
            app::manager::actions::RequestPuk,
            std::make_unique<app::manager::actions::PasscodeParams>(
                Store::GSM::get()->selected, msg->attempts, std::string()));
        handleActionRequest(action.get());
    }

    void ApplicationManager::handleSimBlocked(cellular::msg::notification::SimBlocked *msg)
    {
        auto action = std::make_unique<app::manager::ActionRequest>(
            msg->sender,
            app::manager::actions::BlockSim,
            std::make_unique<app::manager::actions::SimStateParams>(Store::GSM::get()->selected));
        handleActionRequest(action.get());
    }

    void ApplicationManager::handleUnhandledCME(cellular::msg::notification::UnhandledCME *msg)
    {
        auto action = std::make_unique<app::manager::ActionRequest>(
            msg->sender,
            app::manager::actions::DisplayCMEError,
            std::make_unique<app::manager::actions::UnhandledCMEParams>(Store::GSM::get()->selected, msg->code));
        handleActionRequest(action.get());
    }

    void ApplicationManager::handlePhoneModeChanged(sys::phone_modes::PhoneMode phoneMode)
    {
        for (const auto app : getRunningApplications()) {

M module-services/service-appmgr/service-appmgr/Actions.hpp => module-services/service-appmgr/service-appmgr/Actions.hpp +0 -9
@@ 39,21 39,12 @@ namespace app::manager
            EditContact,
            ShowContactDetails,
            ShowSpecialInput,
            SelectSimCard,
            ShowAlarm,
            ShowReminder,
            RequestPin,
            RequestPuk,
            RequestPinChange,
            RequestPinDisable,
            RequestPinEnable,
            UnlockSim,
            BlockSim,
            ShowMMIResult,
            ShowMMIResponse,
            ShowMMIPush,
            SmsRejectNoSim,
            DisplayCMEError,
            DisplayLowBatteryScreen,
            SystemBrownout,
            DisplayLogoAtExit,

D module-services/service-appmgr/service-appmgr/data/SimActionsParams.hpp => module-services/service-appmgr/service-appmgr/data/SimActionsParams.hpp +0 -65
@@ 1,65 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

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

namespace app::manager::actions
{
    /** Action parameters for
     * RequestPinAction
     * RequestPukAction
     * ChangePinAction
     */
    class PasscodeParams : public ActionParams
    {
        Store::GSM::SIM sim;
        unsigned int attempts;
        /// passcodeName stands for PIN1/PIN2 or PUK1/PUK2 type
        std::string passcodeName;

      public:
        PasscodeParams(Store::GSM::SIM _sim, unsigned int _attempts, std::string _passcodeName);

        [[nodiscard]] Store::GSM::SIM getSim() const noexcept;
        [[nodiscard]] unsigned int getAttempts() const noexcept;
        [[nodiscard]] const std::string &getPasscodeName() const noexcept;

        static constexpr auto numOfAttemptsForEnteringPIN = 3u;
        static constexpr auto numOfAttemptsForEnteringPUK = 10u;

        static constexpr auto pinName = "PIN";
        static constexpr auto pukName = "PUK";
    };

    /** Action parameters for
     * SimUnlockedAction
     * SimBlockedAction
     */
    class SimStateParams : public ActionParams
    {
        Store::GSM::SIM sim;

      public:
        explicit SimStateParams(Store::GSM::SIM _sim);

        [[nodiscard]] Store::GSM::SIM getSim() const noexcept;
    };

    /** Action parameters for
     * UnhandledCMEError
     */
    class UnhandledCMEParams : public ActionParams
    {
        Store::GSM::SIM sim;
        unsigned int cmeCode;

      public:
        UnhandledCMEParams(Store::GSM::SIM _sim, unsigned int _cmeCode);

        [[nodiscard]] Store::GSM::SIM getSim() const noexcept;
        [[nodiscard]] unsigned int getCMECode() const noexcept;
    };
} // namespace app::manager::actions

M module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp => module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp +2 -6
@@ 32,7 32,7 @@

#include <notifications/NotificationProvider.hpp>
#include <locks/handlers/PhoneLockHandler.hpp>
#include <service-cellular-api>
#include <locks/handlers/SimLockHandler.hpp>

namespace app
{


@@ 151,11 151,6 @@ namespace app::manager
        auto handleDBResponse(db::QueryResponse *msg) -> bool;
        auto handlePowerSavingModeInit() -> bool;
        auto handleMessageAsAction(sys::Message *request) -> std::shared_ptr<sys::ResponseMessage>;
        void handleSimReady(cellular::msg::notification::SimReady *msg);
        void handleSimNeedPin(cellular::msg::notification::SimNeedPin *msg);
        void handleSimNeedPuk(cellular::msg::notification::SimNeedPuk *msg);
        void handleSimBlocked(cellular::msg::notification::SimBlocked *msg);
        void handleUnhandledCME(cellular::msg::notification::UnhandledCME *msg);
        auto handleDeveloperModeRequest(sys::Message *request) -> sys::MessagePointer;
        /// handles dom request by passing this request to application which should provide the dom
        auto handleDOMRequest(sys::Message *request) -> std::shared_ptr<sys::ResponseMessage>;


@@ 192,6 187,7 @@ namespace app::manager
        std::unique_ptr<sys::phone_modes::Observer> phoneModeObserver;

        locks::PhoneLockHandler phoneLockHandler;
        locks::SimLockHandler simLockHandler;

        void displayLanguageChanged(std::string value);
        void lockTimeChanged(std::string value);

M module-services/service-cellular/service-cellular/CellularMessage.hpp => module-services/service-cellular/service-cellular/CellularMessage.hpp +0 -1
@@ 20,7 20,6 @@

#include <service-appmgr/service-appmgr/messages/ActionRequest.hpp>
#include <service-appmgr/service-appmgr/Actions.hpp>
#include <service-appmgr/service-appmgr/data/SimActionsParams.hpp>
#include <service-appmgr/service-appmgr/data/MmiActionsParams.hpp>

#include <service-cellular/api/common.hpp>

M module-services/service-desktop/service-desktop/DesktopMessages.hpp => module-services/service-desktop/service-desktop/DesktopMessages.hpp +0 -1
@@ 7,7 7,6 @@
#include <endpoints/update/UpdateOSTypes.hpp>
#include <service-appmgr/Actions.hpp>
#include <service-appmgr/messages/ActionRequest.hpp>
#include <service-appmgr/data/SimActionsParams.hpp>
#include <Service/Message.hpp>
#include <MessageType.hpp>
#include <service-desktop/DeveloperModeMessage.hpp>