~aleteoryx/muditaos

fe8671698432b6877da6b8e911b8df77fc439922 — Piotr Tanski 5 years ago 452135b
[EGD-4153] Use actions instead explicit applications switch. (#1032)

50 files changed, 440 insertions(+), 534 deletions(-)

M changelog.md
M module-apps/CMakeLists.txt
D module-apps/UiCommonActions.cpp
D module-apps/UiCommonActions.hpp
M module-apps/application-calendar/ApplicationCalendar.cpp
M module-apps/application-calendar/ApplicationCalendar.hpp
M module-apps/application-calendar/windows/EventReminderWindow.cpp
M module-apps/application-call/ApplicationCall.cpp
M module-apps/application-call/ApplicationCall.hpp
M module-apps/application-call/windows/CallWindow.cpp
M module-apps/application-call/windows/EnterNumberWindow.cpp
M module-apps/application-calllog/ApplicationCallLog.cpp
M module-apps/application-calllog/ApplicationCallLog.hpp
M module-apps/application-calllog/CalllogModel.cpp
M module-apps/application-calllog/windows/CallLogDetailsWindow.cpp
M module-apps/application-calllog/windows/CallLogMainWindow.cpp
M module-apps/application-calllog/windows/CallLogOptionsWindow.cpp
M module-apps/application-desktop/ApplicationDesktop.cpp
M module-apps/application-desktop/windows/DesktopMainWindow.cpp
M module-apps/application-desktop/windows/LockedInfoWindow.cpp
M module-apps/application-desktop/windows/MenuWindow.cpp
M module-apps/application-desktop/windows/PinLockWindow.cpp
M module-apps/application-messages/ApplicationMessages.cpp
M module-apps/application-messages/ApplicationMessages.hpp
M module-apps/application-messages/windows/NewMessage.cpp
M module-apps/application-messages/windows/NewMessage.hpp
M module-apps/application-messages/windows/OptionsMessages.cpp
M module-apps/application-messages/windows/ThreadWindowOptions.cpp
M module-apps/application-phonebook/ApplicationPhonebook.cpp
M module-apps/application-phonebook/ApplicationPhonebook.hpp
M module-apps/application-phonebook/models/PhonebookModel.cpp
M module-apps/application-phonebook/widgets/NumberWithIconsWidget.cpp
M module-apps/application-phonebook/windows/PhonebookNamecardOptions.cpp
M module-apps/application-settings-new/windows/SettingsMainWindow.cpp
M module-apps/application-settings/ApplicationSettings.cpp
M module-apps/application-settings/ApplicationSettings.hpp
M module-apps/application-special-input/ApplicationSpecialInput.cpp
M module-apps/application-special-input/ApplicationSpecialInput.hpp
M module-apps/application-special-input/widgets/SpecialInputTableWidget.cpp
M module-apps/windows/AppWindow.cpp
M module-apps/windows/Options.cpp
M module-apps/windows/Options.hpp
M module-services/service-appmgr/Controller.cpp
M module-services/service-appmgr/model/ApplicationManager.cpp
M module-services/service-appmgr/service-appmgr/Actions.hpp
M module-services/service-appmgr/service-appmgr/Controller.hpp
M module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp
M module-services/service-evtmgr/alarm/EventManagerAlarm.cpp
M module-services/service-time/timeEvents/CalendarTimeEvents.cpp
M source/MessageType.hpp
M changelog.md => changelog.md +1 -0
@@ 59,6 59,7 @@
* `[calendar]` Changed default option to 'all day' event.
* `[bus]` Refactored message handling.
* `[appmgr]` Translating messages to actions introduced. 
* `[appmgr]` Switching between applications replaced with actions.

### Fixed


M module-apps/CMakeLists.txt => module-apps/CMakeLists.txt +0 -1
@@ 14,7 14,6 @@ endif()
set( SOURCES 
    "Application.cpp"
    "GuiTimer.cpp"
    "UiCommonActions.cpp"
    "WindowsFactory.cpp"
    "windows/AppWindow.cpp" 
    "windows/OptionWindow.cpp"

D module-apps/UiCommonActions.cpp => module-apps/UiCommonActions.cpp +0 -172
@@ 1,172 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 "UiCommonActions.hpp"
#include "application-call/ApplicationCall.hpp"
#include "application-call/data/CallSwitchData.hpp"
#include "application-messages/ApplicationMessages.hpp"
#include "application-messages/data/SMSdata.hpp"
#include "application-messages/windows/SMSThreadViewWindow.hpp"
#include "application-phonebook/ApplicationPhonebook.hpp"
#include "application-phonebook/data/PhonebookItemData.hpp"
#include "application-special-input/ApplicationSpecialInput.hpp"

#include <service-appmgr/Controller.hpp>
#include <service-appmgr/messages/Message.hpp>

#include <i18/i18.hpp>
#include <log/log.hpp>
#include <PhoneNumber.hpp>

#include <cassert>
#include <string>
#include <utility>

namespace app
{
    auto call(Application *app, const ContactRecord &contact) -> bool
    {
        assert(app != nullptr);

        if (contact.numbers.size() != 0) {
            return call(app, contact.numbers[0].number);
        }
        else {
            LOG_ERROR("No contact numbers!");
            return false;
        }
    }

    auto call(Application *app, const utils::PhoneNumber::View &phoneNumber) -> bool
    {
        assert(app != nullptr);
        auto data = std::make_unique<ExecuteCallData>(phoneNumber);
        return app::manager::Controller::sendAction(app, manager::actions::Call, std::move(data));
    }

    auto prepareCall(Application *app, const std::string &number) -> bool
    {
        assert(app != nullptr);
        auto data = std::make_unique<EnterNumberData>(number);

        return app::manager::Controller::switchApplication(app, name_call, window::name_enterNumber, std::move(data));
    }

    auto sms(Application *app, SmsOperation smsOperation, const utils::PhoneNumber::View &number, const UTF8 textData)
        -> bool
    {
        assert(app != nullptr);

        switch (smsOperation) {
        case SmsOperation::New: {
            auto data                        = std::make_unique<SMSSendRequest>(number, textData);
            data->disableAppClose            = true;
            data->ignoreCurrentWindowOnStack = true;
            return app::manager::Controller::switchApplication(
                app, name_messages, gui::name::window::new_sms, std::move(data));
        }
        case SmsOperation::Template: {
            return app::manager::Controller::switchApplication(
                app, name_messages, gui::name::window::sms_templates, std::make_unique<SMSSendTemplateRequest>(number));
        }
        default: {
            LOG_ERROR("SmsOperation not supported %" PRIu32, static_cast<uint32_t>(smsOperation));
            return false;
        }
        }
    }

    auto contact(Application *app, ContactOperation contactOperation, const ContactRecord &contact) -> bool
    {
        auto data             = std::make_unique<PhonebookItemData>(std::make_shared<ContactRecord>(contact));
        data->disableAppClose = true;
        assert(app != nullptr);
        switch (contactOperation) {
        case ContactOperation::Add: {
            data->ignoreCurrentWindowOnStack = true;
            return app::manager::Controller::switchApplication(
                app, name_phonebook, gui::window::name::new_contact, std::move(data));
        }
        case ContactOperation::Details: {
            return app::manager::Controller::switchApplication(
                app, name_phonebook, gui::window::name::contact, std::move(data));
        }
        case ContactOperation::Edit: {
            return app::manager::Controller::switchApplication(
                app,
                name_phonebook,
                gui::window::name::new_contact, // TODO: need to be fixed when contact edition is working
                std::move(data));
        }
        default: {
            LOG_ERROR("ContactOperation not supported %" PRIu32, static_cast<uint32_t>(contactOperation));
            return false;
        }
        }
    }

    auto contact(Application *app, ContactOperation contactOperation, const std::string &number) -> bool
    {
        assert(app != nullptr);

        auto searchResults = DBServiceAPI::ContactSearch(app, "", "", number);
        ContactRecord contactRec;
        if (searchResults.get()->size() == 1) {
            contactRec = searchResults->front();
            LOG_INFO("Found contact matching search num %s : contact ID %" PRIu32 " - %s %s",
                     number.c_str(),
                     contactRec.ID,
                     contactRec.primaryName.c_str(),
                     contactRec.alternativeName.c_str());

            if (contactOperation == ContactOperation::Add) {
                return app::manager::Controller::switchApplication(
                    app,
                    name_phonebook,
                    gui::window::name::new_contact,
                    std::make_unique<PhonebookItemData>(std::make_shared<ContactRecord>(contactRec)));
            }
        }
        else if (searchResults.get()->size() > 1) {
            LOG_FATAL("Found more than one contact for number %s", number.c_str());
            for (auto i : *searchResults) {
                LOG_FATAL("ContactID = %" PRIu32, i.ID);
            }
            return false;
        }
        else if (contactOperation != ContactOperation::Add) {
            LOG_ERROR("Invalid operation for not existing contact for number %s", number.c_str());
            return false;
        }

        contactRec.numbers.emplace_back(ContactRecord::Number(utils::PhoneNumber(number).getView()));
        return contact(app, contactOperation, contactRec);
    }

    auto contact(Application *app, ContactOperation contactOperation, uint32_t contactId) -> bool
    {
        assert(app != nullptr);
        assert(contactOperation != ContactOperation::Add);

        auto searchResults = DBServiceAPI::ContactGetByID(app, contactId);
        if (searchResults.get()->size() == 1) {
            ContactRecord contactRec = searchResults->front();
            return contact(app, contactOperation, contactRec);
        }

        return false;
    }

    auto specialInput(Application *app, std::unique_ptr<gui::SwitchSpecialChar> &&switchData) -> bool
    {
        assert(app != nullptr);

        switchData->disableAppClose = true;
        if (gui::SwitchSpecialChar::Type::Request == switchData->type) {
            return app::manager::Controller::switchApplication(
                app, app::special_input, app::char_select, std::move(switchData));
        }
        return app::manager::Controller::switchBack(
            app, std::make_unique<app::manager::SwitchBackRequest>(switchData->requester, std::move(switchData)));
    }
} // namespace app

D module-apps/UiCommonActions.hpp => module-apps/UiCommonActions.hpp +0 -111
@@ 1,111 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 "Application.hpp"

#include <OptionWindow.hpp>
#include <PhoneNumber.hpp>
#include <service-db/DBServiceAPI.hpp>

namespace app
{
    enum class CallOperation
    {
        ExecuteCall,
        PrepareCall
    };

    /// @brief requests selected call operation
    ///
    /// @param app - requesting application
    /// @param CallOperation - selected call operation.
    ///
    /// @parem contact - contact record on which the operation is requested
    ///
    /// @return true if succeed
    auto call(Application *app, const ContactRecord &contact) -> bool;

    /// @brief requests selected call operation
    ///
    /// @param app - requesting application
    /// @param CallOperation - selected call operation.
    ///
    /// @param number - phone number (assigned to contact) on which the operation is requested
    ///
    /// @return true if succeed
    auto call(Application *app, const utils::PhoneNumber::View &number) -> bool;

    /// @brief prepares for a call (displays number to the user)
    ///
    /// @param app - requesting application
    /// @param number - phone number on which the operation is requested
    ///
    /// @return true if succeed
    auto prepareCall(Application *app, const std::string &number) -> bool;

    enum class SmsOperation
    {
        New,
        Template
    };

    /// @brief requests selected sms operation
    ///
    /// @param app - requesting application
    /// @param smsOperation - selected sms operation.
    ///
    /// @param number - phone number (assigned to contact) on which the operation is requested
    ///
    /// @param textData - text message which should be sent as sms
    ///
    /// @return true if succeed
    auto sms(Application *app,
             SmsOperation smsOperation,
             const utils::PhoneNumber::View &number,
             const UTF8 textData = "") -> bool;

    enum class ContactOperation
    {
        Add,
        Details,
        Edit
    };

    /// @brief requests selected contact operation
    ///
    /// @param app - requesting application
    /// @param contactOperation - selected contact operation.
    ///
    /// @parem contact - contact record on which the operation is requested
    ///
    /// @return true if succeed
    auto contact(Application *app, ContactOperation contactOperation, const ContactRecord &contact) -> bool;

    /// @brief requests selected contact operation
    ///
    /// @param app - requesting application
    /// @param contactOperation - selected contact operation.
    ///
    /// @parem number - phone number (assigned to contact) on which the operation is requested
    ///
    /// @return true if succeed
    auto contact(Application *app, ContactOperation contactOperation, const std::string &number) -> bool;

    /// @brief requests selected contact operation
    ///
    /// @param app - requesting application
    /// @param contactOperation - selected contact operation. @note ContactOperation::Add is no valid in this case
    ///
    /// @parem contactId - id of contact on which the operation is requested
    ///
    /// @return true if succeed
    auto contact(Application *app, ContactOperation contactOperation, uint32_t contactId) -> bool;

    /// @brief requests display special input window.
    /// @param app          Requesting application
    /// @param switchData   Application switch data.
    /// @return true if succeed.
    auto specialInput(Application *app, std::unique_ptr<gui::SwitchSpecialChar> &&switchData) -> bool;
} // namespace app

M module-apps/application-calendar/ApplicationCalendar.cpp => module-apps/application-calendar/ApplicationCalendar.cpp +4 -0
@@ 51,6 51,10 @@ namespace app
        : Application(name, parent, startInBackground, stackDepth, priority)
    {
        busChannels.push_back(sys::BusChannels::ServiceDBNotifications);
        addActionReceiver(manager::actions::ShowReminder, [this](auto &&data) {
            switchWindow(style::window::calendar::name::event_reminder_window, std::move(data));
            return msgHandled();
        });
    }

    sys::MessagePointer ApplicationCalendar::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)

M module-apps/application-calendar/ApplicationCalendar.hpp => module-apps/application-calendar/ApplicationCalendar.hpp +1 -1
@@ 65,7 65,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::Launch, manager::actions::ShowReminder}};
        }
    };
} /* namespace app */

M module-apps/application-calendar/windows/EventReminderWindow.cpp => module-apps/application-calendar/windows/EventReminderWindow.cpp +1 -1
@@ 156,7 156,7 @@ namespace gui
        LOG_DEBUG("Switch to previous window");
        destroyTimer();

        app::manager::Controller::switchApplication(application, "ApplicationDesktop", gui::name::window::main_window);
        app::manager::Controller::sendAction(application, app::manager::actions::Home);
    }

} /* namespace gui */

M module-apps/application-call/ApplicationCall.cpp => module-apps/application-call/ApplicationCall.cpp +42 -17
@@ 15,7 15,6 @@
#include <Application.hpp>
#include <MessageType.hpp>
#include <PhoneNumber.hpp>
#include <UiCommonActions.hpp>
#include <Dialog.hpp>
#include <log/log.hpp>
#include <memory>


@@ 27,13 26,19 @@
#include <ticks.hpp>

#include <cassert>
#include <module-apps/application-phonebook/data/PhonebookItemData.hpp>
#include <module-services/service-db/service-db/DBServiceAPI.hpp>

namespace app
{
    ApplicationCall::ApplicationCall(std::string name, std::string parent, StartInBackground startInBackground)
        : Application(name, parent, startInBackground, app::call_stack_size)
    {
        addActionReceiver(manager::actions::Call, [this](auto data) {
        addActionReceiver(manager::actions::Call, [this](auto &&data) {
            switchWindow(window::name_call, std::move(data));
            return msgHandled();
        });
        addActionReceiver(manager::actions::Dial, [this](auto data) {
            switchWindow(window::name_enterNumber, std::move(data));
            return msgHandled();
        });


@@ 42,34 47,26 @@ namespace app
    //  number of seconds after end call to switch back to previous application
    const inline utils::time::Duration delayToSwitchToPreviousApp = 3;

    void switchWindowOrApp(Application *app, std::unique_ptr<gui::SwitchData> &&data)
    {
        if (app->getState() == Application::State::ACTIVE_FORGROUND) {
            app->switchWindow(window::name_call, std::move(data));
        }
        else {
            app::manager::Controller::switchApplication(app, name_call, window::name_call, std::move(data));
        }
    }

    void ApplicationCall::CallAbortHandler()
    {
        switchWindowOrApp(this, std::make_unique<app::CallAbortData>());
        manager::Controller::sendAction(this, manager::actions::Call, std::make_unique<app::CallAbortData>());
    }

    void ApplicationCall::CallActiveHandler()
    {
        switchWindowOrApp(this, std::make_unique<app::CallActiveData>());
        manager::Controller::sendAction(this, manager::actions::Call, std::make_unique<app::CallActiveData>());
    }

    void ApplicationCall::IncomingCallHandler(const CellularCallMessage *const msg)
    {
        switchWindowOrApp(this, std::make_unique<app::IncomingCallData>(msg->number));
        manager::Controller::sendAction(
            this, manager::actions::Call, std::make_unique<app::IncomingCallData>(msg->number));
    }

    void ApplicationCall::RingingHandler(const CellularCallMessage *const msg)
    {
        switchWindowOrApp(this, std::make_unique<app::ExecuteCallData>(msg->number));
        manager::Controller::sendAction(
            this, manager::actions::Call, std::make_unique<app::ExecuteCallData>(msg->number));
    }

    // Invoked upon receiving data message


@@ 205,7 202,35 @@ namespace app
    void ApplicationCall::handleAddContactEvent(const std::string &number)
    {
        LOG_INFO("add contact information: %s", number.c_str());
        app::contact(this, app::ContactOperation::Add, number);

        auto searchResults = DBServiceAPI::ContactSearch(this, UTF8{}, UTF8{}, number);
        if (const auto resultsSize = searchResults->size(); resultsSize > 1) {
            LOG_FATAL("Found more than one contact for number %s", number.c_str());
            for (auto i : *searchResults) {
                LOG_FATAL("ContactID = %" PRIu32, i.ID);
            }
        }
        else if (resultsSize == 1) {
            const auto &contactRecord = searchResults->front();
            LOG_INFO("Found contact matching search num %s : contact ID %" PRIu32 " - %s %s",
                     number.c_str(),
                     contactRecord.ID,
                     contactRecord.primaryName.c_str(),
                     contactRecord.alternativeName.c_str());
            app::manager::Controller::sendAction(
                this,
                app::manager::actions::AddContact,
                std::make_unique<PhonebookItemData>(std::make_shared<ContactRecord>(contactRecord)));
        }
        else {
            ContactRecord contactRecord;
            contactRecord.numbers.emplace_back(ContactRecord::Number(utils::PhoneNumber(number).getView()));

            auto data = std::make_unique<PhonebookItemData>(std::make_shared<ContactRecord>(contactRecord));
            data->ignoreCurrentWindowOnStack = true;
            app::manager::Controller::sendAction(
                this, manager::actions::AddContact, std::move(data), manager::OnSwitchBehaviour::RunInBackground);
        }
    }

    void ApplicationCall::transmitDtmfTone(uint32_t digit)

M module-apps/application-call/ApplicationCall.hpp => module-apps/application-call/ApplicationCall.hpp +1 -1
@@ 74,7 74,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch, manager::actions::Call}};
            return {{manager::actions::Launch, manager::actions::Call, manager::actions::Dial}};
        }
    };
} /* namespace app */

M module-apps/application-call/windows/CallWindow.cpp => module-apps/application-call/windows/CallWindow.cpp +3 -3
@@ 24,7 24,6 @@
#include "application-call/data/CallAppStyle.hpp"
#include "time/time_conversion.hpp"

#include <UiCommonActions.hpp>
#include <application-messages/data/SMSdata.hpp>
#include <InputMode.hpp>



@@ 137,8 136,9 @@ namespace gui
        };
        sendSmsIcon->activatedCallback = [=](gui::Item &item) {
            LOG_INFO("Send messaage template and reject the call");
            app::sms(application, app::SmsOperation::Template, phoneNumber);
            return true;
            return app::manager::Controller::sendAction(application,
                                                        app::manager::actions::ShowSmsTemplates,
                                                        std::make_unique<SMSSendTemplateRequest>(phoneNumber));
        };

        // define navigation between icons

M module-apps/application-call/windows/EnterNumberWindow.cpp => module-apps/application-call/windows/EnterNumberWindow.cpp +0 -1
@@ 13,7 13,6 @@
#include <InputMode.hpp>
#include <service-appmgr/Controller.hpp>
#include <service-cellular/CellularServiceAPI.hpp>
#include <UiCommonActions.hpp>

#include <phonenumbers/phonenumberutil.h>
#include <phonenumbers/asyoutypeformatter.h>

M module-apps/application-calllog/ApplicationCallLog.cpp => module-apps/application-calllog/ApplicationCallLog.cpp +6 -1
@@ 25,7 25,12 @@ namespace app
{
    ApplicationCallLog::ApplicationCallLog(std::string name, std::string parent, StartInBackground startInBackground)
        : Application(name, parent, startInBackground, 4096)
    {}
    {
        addActionReceiver(manager::actions::ShowCallLog, [this](auto &&data) {
            switchWindow(gui::name::window::main_window, std::move(data));
            return msgHandled();
        });
    }

    ApplicationCallLog::~ApplicationCallLog()
    {

M module-apps/application-calllog/ApplicationCallLog.hpp => module-apps/application-calllog/ApplicationCallLog.hpp +1 -1
@@ 41,7 41,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::Launch, manager::actions::ShowCallLog}};
        }
    };
} /* namespace app */

M module-apps/application-calllog/CalllogModel.cpp => module-apps/application-calllog/CalllogModel.cpp +6 -2
@@ 4,12 4,13 @@
#include "CalllogModel.hpp"
#include "InputEvent.hpp"
#include "ListView.hpp"
#include "UiCommonActions.hpp"
#include "data/CallLogInternals.hpp"
#include "data/CallLogSwitchData.hpp"
#include "widgets/CalllogItem.hpp"

#include <service-db/DBServiceAPI.hpp>
#include <service-appmgr/Controller.hpp>
#include "application-call/data/CallSwitchData.hpp"

using namespace calllog;



@@ 75,7 76,10 @@ gui::ListItem *CalllogModel::getItem(gui::Order order)
        }
        if (event.keyCode == gui::KeyCode::KEY_LF) {
            LOG_DEBUG("calling");
            return app::call(application, item->getCall().phoneNumber);
            return app::manager::Controller::sendAction(
                application,
                app::manager::actions::Dial,
                std::make_unique<app::ExecuteCallData>(item->getCall().phoneNumber));
        }
        return false;
    };

M module-apps/application-calllog/windows/CallLogDetailsWindow.cpp => module-apps/application-calllog/windows/CallLogDetailsWindow.cpp +13 -3
@@ 7,6 7,7 @@

#include "OptionsWindow.hpp"
#include <service-appmgr/model/ApplicationManager.hpp>
#include <service-appmgr/Controller.hpp>

#include "bsp/rtc/rtc.hpp"



@@ 20,11 21,12 @@
#include "../windows/CallLogOptionsWindow.hpp"
#include "Label.hpp"
#include "Margins.hpp"
#include "UiCommonActions.hpp"
#include "application-call/ApplicationCall.hpp"
#include <application-call/data/CallSwitchData.hpp>
#include "time/time_conversion.hpp"
#include <Style.hpp>
#include <cassert>
#include <module-apps/application-messages/data/SMSdata.hpp>

using namespace calllog;
using namespace callLogStyle::detailsWindow;


@@ 141,12 143,20 @@ namespace gui
        // activated callbacks
        rects[FocusRects::Call]->activatedCallback = [=](gui::Item &item) {
            LOG_INFO("call %s", record.phoneNumber.getE164().c_str());
            return app::call(application, record.phoneNumber);
            return app::manager::Controller::sendAction(application,
                                                        app::manager::actions::Dial,
                                                        std::make_unique<app::ExecuteCallData>(record.phoneNumber),
                                                        app::manager::OnSwitchBehaviour::RunInBackground);
        };

        rects[FocusRects::Sms]->activatedCallback = [=](gui::Item &item) {
            LOG_INFO("sms %s", record.phoneNumber.getE164().c_str());
            return app::sms(application, app::SmsOperation::New, record.phoneNumber);
            auto data                        = std::make_unique<SMSSendRequest>(record.phoneNumber, std::string{});
            data->ignoreCurrentWindowOnStack = true;
            return app::manager::Controller::sendAction(application,
                                                        app::manager::actions::CreateSms,
                                                        std::move(data),
                                                        app::manager::OnSwitchBehaviour::RunInBackground);
        };

        // Type

M module-apps/application-calllog/windows/CallLogMainWindow.cpp => module-apps/application-calllog/windows/CallLogMainWindow.cpp +0 -1
@@ 12,7 12,6 @@
#include <i18/i18.hpp>
#include <Label.hpp>
#include <Margins.hpp>
#include <UiCommonActions.hpp>
#include <Style.hpp>

#include <cassert>

M module-apps/application-calllog/windows/CallLogOptionsWindow.cpp => module-apps/application-calllog/windows/CallLogOptionsWindow.cpp +3 -2
@@ 5,6 5,7 @@
#include "i18/i18.hpp"
#include "log/log.hpp"
#include <Options.hpp>
#include <module-services/service-db/service-db/DBServiceAPI.hpp>

/// below just for apps names...



@@ 16,11 17,11 @@ std::list<gui::Option> calllogWindowOptions(app::ApplicationCallLog *app, const 

    if (searchResults->empty() || !searchResults->front().isValid() || searchResults->front().isTemporary()) {
        // add option - add contact
        options.push_back(gui::options::contact(app, app::ContactOperation::Add, searchResults->front()));
        options.push_back(gui::options::contact(app, gui::options::ContactOperation::Add, searchResults->front()));
    }
    else {
        // add option - contact details
        options.push_back(gui::options::contact(app, app::ContactOperation::Details, searchResults->front()));
        options.push_back(gui::options::contact(app, gui::options::ContactOperation::Details, searchResults->front()));
    }

    // add option delete call option

M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +2 -3
@@ 191,7 191,7 @@ namespace app
        assert(msg);
        if (msg->request == cellular::State::ST::URCReady) {
            if (need_sim_select && !lockHandler.isScreenLocked()) {
                app::manager::Controller::switchApplication(this, app::name_settings, app::sim_select, nullptr);
                manager::Controller::sendAction(this, manager::actions::SelectSimCard);
                return true;
            }
            else if (need_sim_select == false) {


@@ 209,8 209,7 @@ namespace app
    bool ApplicationDesktop::showCalls()
    {
        LOG_DEBUG("show calls!");
        return app::manager::Controller::switchApplication(
            this, app::CallLogAppStr, gui::name::window::main_window, nullptr);
        return manager::Controller::sendAction(this, manager::actions::ShowCallLog);
    }

    bool ApplicationDesktop::clearCallsNotification()

M module-apps/application-desktop/windows/DesktopMainWindow.cpp => module-apps/application-desktop/windows/DesktopMainWindow.cpp +11 -7
@@ 17,7 17,6 @@
#include <service-appmgr/Controller.hpp>
#include <service-time/ServiceTime.hpp>
#include <service-time/TimeMessage.hpp>
#include <UiCommonActions.hpp>

#include "i18/i18.hpp"
#include "log/log.hpp"


@@ 26,6 25,7 @@
#include <application-settings/ApplicationSettings.hpp>
#include <cassert>
#include <time/time_conversion.hpp>
#include <module-apps/application-call/data/CallSwitchData.hpp>

namespace gui
{


@@ 110,8 110,7 @@ namespace gui
            setActiveState(app);

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

            sys::Bus::SendUnicast(


@@ 160,7 159,8 @@ namespace gui
            }
            // long press of '0' key is translated to '+'
            else if (inputEvent.is(KeyCode::KEY_0)) {
                return app::prepareCall(application, "+");
                return app::manager::Controller::sendAction(
                    application, app::manager::actions::Dial, std::make_unique<app::EnterNumberData>("+"));
            }
        }



@@ 177,7 177,9 @@ namespace gui
        auto code = translator.handle(inputEvent.key, InputMode({InputMode::phone}).get());
        // if numeric key was pressed record that key and send it to call application
        if (code != 0) {
            return app::prepareCall(application, std::string(1, static_cast<char>(code)));
            const auto &number = std::string(1, static_cast<char>(code));
            return app::manager::Controller::sendAction(
                application, app::manager::actions::Dial, std::make_unique<app::EnterNumberData>(number));
        }
        else if (inputEvent.is(KeyCode::KEY_UP) && focusItem == nullptr) {
            setFocusItem(notifications);


@@ 294,8 296,10 @@ namespace gui
                utils::localize.get("app_desktop_unread_messages"),
                std::to_string(app->notifications.notSeen.SMS),
                [this]() -> bool {
                    return app::manager::Controller::switchApplication(
                        application, app::name_messages, gui::name::window::main_window, nullptr);
                    return app::manager::Controller::sendAction(
                        application,
                        app::manager::actions::Launch,
                        std::make_unique<app::ApplicationLaunchData>(app::name_messages));
                },
                [app, this]() -> bool { return app->clearMessagesNotification(); },
                onNotificationFocus);

M module-apps/application-desktop/windows/LockedInfoWindow.cpp => module-apps/application-desktop/windows/LockedInfoWindow.cpp +1 -2
@@ 44,8 44,7 @@ bool LockedInfoWindow::onInput(const InputEvent &inputEvent)
{
    if (inputEvent.isShortPress()) {
        if (inputEvent.keyCode == KeyCode::KEY_LF && bottomBar->isActive(BottomBar::Side::LEFT)) {
            app::manager::Controller::switchApplication(
                application, app::name_phonebook, gui::window::name::ice_contacts);
            app::manager::Controller::sendAction(application, app::manager::actions::ShowEmergencyContacts);
            return true;
        }
        else if (inputEvent.keyCode == KeyCode::KEY_RF && bottomBar->isActive(BottomBar::Side::RIGHT)) {

M module-apps/application-desktop/windows/MenuWindow.cpp => module-apps/application-desktop/windows/MenuWindow.cpp +40 -36
@@ 129,61 129,62 @@ namespace gui
                new gui::Tile("menu_calendar_W_G",
                              "app_desktop_menu_calendar",
                              [=](gui::Item &item) {
                                  app::manager::Controller::switchApplication(
                                      application, "ApplicationCalendar", gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationCalendar"));
                              }),

                new gui::Tile{"menu_phone_W_G",
                              "app_desktop_menu_phone",
                              [=](gui::Item &item) {
                                  LOG_INFO("Call Log");
                                  app::manager::Controller::switchApplication(
                                      application, "ApplicationCallLog", gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationCallLog"));
                              },
                              app->notifications.notRead.Calls},
                new gui::Tile("menu_contacts_W_G",
                              "app_desktop_menu_contacts",
                              [=](gui::Item &item) {
                                  LOG_INFO("Phonebook");
                                  app::manager::Controller::switchApplication(
                                      application, "ApplicationPhonebook", gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationPhonebook"));
                              }),

                new gui::Tile{"menu_messages_W_G",
                              "app_desktop_menu_messages",
                              [=](gui::Item &item) {
                                  LOG_INFO("Messages");
                                  app::manager::Controller::switchApplication(
                                      application, "ApplicationMessages", gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationMessages"));
                              },
                              app->notifications.notRead.SMS},
                new gui::Tile{"menu_music_player_W_G",
                              "app_desktop_menu_music",
                              [=](gui::Item &item) {
                                  LOG_INFO("Music Player");
                                  app::manager::Controller::switchApplication(
                                      application, "ApplicationMusicPlayer", gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationMusicPlayer"));
                              }},
                new gui::Tile{"menu_meditation_W_G",
                              "app_desktop_menu_meditation",
                              [=](gui::Item &item) {
                                  LOG_INFO("Meditation");
                                  app::manager::Controller::switchApplication(
                                      application, "ApplicationMeditation", gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationMeditation"));
                              }},
                new gui::Tile{"menu_settings_W_G",
                              "app_desktop_menu_settings_new",
                              [=](gui::Item &item) {
                                  LOG_INFO("page 1 settings");
                                  app::manager::Controller::switchApplication(
                                      application, APP_SETTINGS_NEW, gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>(APP_SETTINGS_NEW));
                              }},
            });



@@ 194,23 195,26 @@ namespace gui
                new gui::Tile{"menu_tools_notes_W_G",
                              "app_desktop_tools_notes",
                              [=](gui::Item &item) {
                                  app::manager::Controller::switchApplication(
                                      application, "ApplicationNotes", gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationNotes"));
                              }},
                new gui::Tile{"menu_tools_calculator_W_G",
                              "app_desktop_tools_calculator",
                              [=](gui::Item &item) {
                                  app::manager::Controller::switchApplication(
                                      application, "ApplicationCalculator", gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationCalculator"));
                              }},
                new gui::Tile{"menu_tools_recorder_W_G",
                              "app_desktop_tools_antenna",
                              [=](gui::Item &item) {
                                  app::manager::Controller::switchApplication(
                                      application, "ApplicationAntenna", gui::name::window::main_window, nullptr);
                                  return true;
                                  return app::manager::Controller::sendAction(
                                      application,
                                      app::manager::actions::Launch,
                                      std::make_unique<app::ApplicationLaunchData>("ApplicationAntenna"));
                              }},
            });


M module-apps/application-desktop/windows/PinLockWindow.cpp => module-apps/application-desktop/windows/PinLockWindow.cpp +1 -2
@@ 112,8 112,7 @@ namespace gui
        }
        // accept only LF, enter, RF, #, and numeric values;
        if (inputEvent.is(KeyCode::KEY_LF) && bottomBar->isActive(BottomBar::Side::LEFT)) {
            app::manager::Controller::switchApplication(
                application, app::name_phonebook, gui::window::name::ice_contacts, nullptr);
            app::manager::Controller::sendAction(application, app::manager::actions::ShowEmergencyContacts);
            return true;
        }
        else if (inputEvent.is(KeyCode::KEY_RF) && bottomBar->isActive(BottomBar::Side::RIGHT)) {

M module-apps/application-messages/ApplicationMessages.cpp => module-apps/application-messages/ApplicationMessages.cpp +8 -0
@@ 41,6 41,14 @@ namespace app
        : Application(name, parent, startInBackground, 4096 * 2)
    {
        busChannels.push_back(sys::BusChannels::ServiceDBNotifications);
        addActionReceiver(manager::actions::CreateSms, [this](auto &&data) {
            switchWindow(gui::name::window::new_sms, std::move(data));
            return msgHandled();
        });
        addActionReceiver(manager::actions::ShowSmsTemplates, [this](auto &&data) {
            switchWindow(gui::name::window::sms_templates, std::move(data));
            return msgHandled();
        });
    }

    ApplicationMessages::~ApplicationMessages()

M module-apps/application-messages/ApplicationMessages.hpp => module-apps/application-messages/ApplicationMessages.hpp +1 -1
@@ 82,7 82,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::Launch, manager::actions::CreateSms, manager::actions::ShowSmsTemplates}};
        }
    };
} /* namespace app */

M module-apps/application-messages/windows/NewMessage.cpp => module-apps/application-messages/windows/NewMessage.cpp +27 -4
@@ 23,6 23,29 @@

namespace gui
{
    class NewMessageWindow::MessageMemento
    {
      public:
        void setState(const gui::Text *_state)
        {
            assert(_state);
            state = std::make_unique<TextBackup>(_state->backupText());
        }

        void getState(gui::Text *_state)
        {
            assert(_state);
            if (!state) {
                return;
            }
            _state->restoreFrom(*state);
            state = nullptr;
        }

      private:
        std::unique_ptr<gui::TextBackup> state;
    };

    std::unique_ptr<NewMessageWindow::MessageMemento> NewMessageWindow::memento =
        std::make_unique<NewMessageWindow::MessageMemento>();



@@ 82,11 105,11 @@ namespace gui
    {
        // select contact only if there is no entered number
        if (recipient->getText().empty()) {
            auto data             = std::make_unique<PhonebookSearchReuqest>();
            data->disableAppClose = true;
            memento->setState(message);
            return app::manager::Controller::switchApplication(
                application, app::name_phonebook, name::window::main_window, std::move(data));
            return app::manager::Controller::sendAction(application,
                                                        app::manager::actions::ShowContacts,
                                                        std::make_unique<PhonebookSearchReuqest>(),
                                                        app::manager::OnSwitchBehaviour::RunInBackground);
        }
        return true;
    }

M module-apps/application-messages/windows/NewMessage.hpp => module-apps/application-messages/windows/NewMessage.hpp +1 -30
@@ 47,36 47,7 @@ namespace gui
        /// MessageMemento class provides buffer-like functionality for message field of NewMessageWindow.
        /// MessageMemento shall be used whenever there is a need for temporary window switch in normal (uninterrupted)
        /// flow of new message preparation, such as using options or recipient selection.
        class MessageMemento : public Item
        {
            gui::Text *state = nullptr;

          public:
            /// sets memento and leaves the origin pointing to default-constructed object
            void setState(gui::Text *&_state)
            {
                assert(_state);
                LOG_DEBUG("setting memento for NewMessageWindow");
                if (state == nullptr) {
                    state         = new gui::Text();
                    state->parent = this;
                }
                std::swap(state->parent, _state->parent);
                std::swap(state, _state);
            }
            void getState(gui::Text *&_state)
            {
                if (state == nullptr) {
                    return;
                }
                assert(_state);
                LOG_DEBUG("getting memento for NewMessageWindow");
                std::swap(state->parent, _state->parent);
                std::swap(state, _state);
                delete state;
                state = nullptr;
            }
        };
        class MessageMemento;
        static std::unique_ptr<MessageMemento> memento;
    };
} /* namespace gui */

M module-apps/application-messages/windows/OptionsMessages.cpp => module-apps/application-messages/windows/OptionsMessages.cpp +4 -2
@@ 14,6 14,7 @@
#include <Text.hpp>
#include <BoxLayout.hpp>
#include <memory>
#include <module-services/service-db/service-db/DBServiceAPI.hpp>

using namespace style::window;



@@ 29,8 30,9 @@ std::list<gui::Option> smsWindowOptions(app::ApplicationMessages *app, const SMS
            return true;
        });
    }
    options.push_back(gui::options::call(app, app::CallOperation::ExecuteCall, contact));
    auto contactOperation = contact.isTemporary() ? app::ContactOperation::Add : app::ContactOperation::Details;
    options.push_back(gui::options::call(app, contact));
    auto contactOperation =
        contact.isTemporary() ? gui::options::ContactOperation::Add : gui::options::ContactOperation::Details;
    options.push_back(gui::options::contact(app, contactOperation, contact));
    options.emplace_back(UTF8(utils::localize.get("sms_forward_message")), [=](gui::Item &item) {
        std::unique_ptr<gui::SwitchData> data = std::make_unique<SMSTextData>(record.body);

M module-apps/application-messages/windows/ThreadWindowOptions.cpp => module-apps/application-messages/windows/ThreadWindowOptions.cpp +4 -2
@@ 6,6 6,7 @@
#include "log/log.hpp"
#include <Options.hpp>
#include <OptionWindow.hpp>
#include <module-services/service-db/service-db/DBServiceAPI.hpp>

/// below just for apps names...



@@ 16,8 17,9 @@ std::list<gui::Option> threadWindowOptions(app::ApplicationMessages *app, const 
        record ? DBServiceAPI::ContactGetByIDWithTemporary(app, record->contactID)->front() : ContactRecord();
    std::list<gui::Option> options;

    options.emplace_back(gui::options::call(app, app::CallOperation::ExecuteCall, contact));
    auto contactOperation = contact.isTemporary() ? app::ContactOperation::Add : app::ContactOperation::Details;
    options.emplace_back(gui::options::call(app, contact));
    auto contactOperation =
        contact.isTemporary() ? gui::options::ContactOperation::Add : gui::options::ContactOperation::Details;
    options.emplace_back(gui::options::contact(app, contactOperation, contact));

    if (record->isUnread()) {

M module-apps/application-phonebook/ApplicationPhonebook.cpp => module-apps/application-phonebook/ApplicationPhonebook.cpp +20 -0
@@ 25,6 25,26 @@ namespace app
        : Application(name, parent, startInBackground, phonebook_stack_size)
    {
        busChannels.push_back(sys::BusChannels::ServiceDBNotifications);
        addActionReceiver(manager::actions::ShowContacts, [this](auto &&data) {
            switchWindow(gui::name::window::main_window, std::move(data));
            return msgHandled();
        });
        addActionReceiver(manager::actions::AddContact, [this](auto &&data) {
            switchWindow(gui::window::name::new_contact, std::move(data));
            return msgHandled();
        });
        addActionReceiver(manager::actions::EditContact, [this](auto &&data) {
            switchWindow(gui::window::name::new_contact, std::move(data));
            return msgHandled();
        });
        addActionReceiver(manager::actions::ShowContactDetails, [this](auto &&data) {
            switchWindow(gui::window::name::contact, std::move(data));
            return msgHandled();
        });
        addActionReceiver(manager::actions::ShowEmergencyContacts, [this](auto &&data) {
            switchWindow(gui::window::name::ice_contacts, std::move(data));
            return msgHandled();
        });
    }

    // Invoked upon receiving data message

M module-apps/application-phonebook/ApplicationPhonebook.hpp => module-apps/application-phonebook/ApplicationPhonebook.hpp +6 -1
@@ 55,7 55,12 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::Launch,
                     manager::actions::ShowContacts,
                     manager::actions::AddContact,
                     manager::actions::EditContact,
                     manager::actions::ShowContactDetails,
                     manager::actions::ShowEmergencyContacts}};
        }
    };
} // namespace app

M module-apps/application-phonebook/models/PhonebookModel.cpp => module-apps/application-phonebook/models/PhonebookModel.cpp +7 -2
@@ 12,7 12,8 @@

#include <service-db/QueryMessage.hpp>
#include <service-db/DBServiceAPI.hpp>
#include "UiCommonActions.hpp"
#include <service-appmgr/Controller.hpp>
#include <application-call/data/CallSwitchData.hpp>

#include <string>
#include <utility>


@@ 145,7 146,11 @@ auto PhonebookModel::getItem(gui::Order order) -> gui::ListItem *
            return false;
        }
        if (event.keyCode == gui::KeyCode::KEY_LF) {
            return app::call(application, *item->contact);
            if (item->contact && !item->contact->numbers.empty()) {
                const auto phoneNumber = item->contact->numbers.front().number;
                return app::manager::Controller::sendAction(
                    application, app::manager::actions::Dial, std::make_unique<app::ExecuteCallData>(phoneNumber));
            }
        }
        return false;
    };

M module-apps/application-phonebook/widgets/NumberWithIconsWidget.cpp => module-apps/application-phonebook/widgets/NumberWithIconsWidget.cpp +14 -3
@@ 4,10 4,13 @@
#include "NumberWithIconsWidget.hpp"

#include "application-phonebook/data/PhonebookStyle.hpp"
#include "UiCommonActions.hpp"

#include <BottomBar.hpp>

#include <application-call/data/CallSwitchData.hpp>
#include <service-appmgr/Controller.hpp>
#include <module-apps/application-messages/data/SMSdata.hpp>

namespace gui
{
    NumberWithIconsWidget::NumberWithIconsWidget(app::Application *app,


@@ 29,8 32,13 @@ namespace gui
                                new Image("mail"));
        smsImage->inputCallback = [=](Item &item, const InputEvent &input) {
            if (input.keyCode == KeyCode::KEY_ENTER && input.state == InputEvent::State::keyReleasedShort) {
                return app::sms(app, app::SmsOperation::New, number);
                LOG_INFO("SMS operation started");
                auto data                        = std::make_unique<SMSSendRequest>(number, std::string{});
                data->ignoreCurrentWindowOnStack = true;
                return app::manager::Controller::sendAction(app,
                                                            app::manager::actions::CreateSms,
                                                            std::move(data),
                                                            app::manager::OnSwitchBehaviour::RunInBackground);
            }
            return false;
        };


@@ 47,7 55,10 @@ namespace gui
                                       0));
        phoneImage->inputCallback = [=](Item &item, const InputEvent &input) {
            if (input.keyCode == KeyCode::KEY_ENTER && input.state == InputEvent::State::keyReleasedShort) {
                return app::call(app, number);
                app::manager::Controller::sendAction(app,
                                                     app::manager::actions::Dial,
                                                     std::make_unique<app::ExecuteCallData>(number),
                                                     app::manager::OnSwitchBehaviour::RunInBackground);
                LOG_INFO("Call operation started");
            }
            return false;

M module-apps/application-phonebook/windows/PhonebookNamecardOptions.cpp => module-apps/application-phonebook/windows/PhonebookNamecardOptions.cpp +8 -4
@@ 1,11 1,12 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <module-services/service-appmgr/service-appmgr/Controller.hpp>
#include "PhonebookNamecardOptions.hpp"
#include "application-phonebook/ApplicationPhonebook.hpp"
#include "application-phonebook/data/PhonebookItemData.hpp"
#include "application-phonebook/data/PhonebookUtils.hpp"
#include "UiCommonActions.hpp"
#include "application-messages/data/SMSdata.hpp"

namespace gui
{


@@ 44,9 45,12 @@ namespace gui

    auto PhonebookNamecardOptions::sendViaSms() -> bool
    {
        const UTF8 contactData = contact->getAsString();
        const utils::PhoneNumber::View emptyNumber;
        return app::sms(application, app::SmsOperation::New, emptyNumber, contactData);
        auto data = std::make_unique<SMSSendRequest>(utils::PhoneNumber::View{}, contact->getAsString());
        data->ignoreCurrentWindowOnStack = true;
        return app::manager::Controller::sendAction(application,
                                                    app::manager::actions::CreateSms,
                                                    std::move(data),
                                                    app::manager::OnSwitchBehaviour::RunInBackground);
    }

    void PhonebookNamecardOptions::sendViaBluetooth()

M module-apps/application-settings-new/windows/SettingsMainWindow.cpp => module-apps/application-settings-new/windows/SettingsMainWindow.cpp +4 -2
@@ 32,8 32,10 @@ std::list<gui::Option> mainWindowOptionsNew(app::Application *app)
                                           return false;
                                       }
                                       LOG_INFO("switching to %s page", window.c_str());
                                       app::manager::Controller::switchApplication(
                                           app, "ApplicationSettings", gui::name::window::main_window, nullptr);
                                       app::manager::Controller::sendAction(
                                           app,
                                           app::manager::actions::Launch,
                                           std::make_unique<app::ApplicationLaunchData>("ApplicationSettings"));
                                       app->switchWindow(window, nullptr);
                                       return true;
                                   },

M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +4 -0
@@ 36,6 36,10 @@ namespace app
        : Application(name, parent, startInBackground)
    {
        busChannels.push_back(sys::BusChannels::AntennaNotifications);
        addActionReceiver(manager::actions::SelectSimCard, [this](auto &&data) {
            switchWindow(app::sim_select);
            return msgHandled();
        });
    }

    ApplicationSettings::~ApplicationSettings()

M module-apps/application-settings/ApplicationSettings.hpp => module-apps/application-settings/ApplicationSettings.hpp +1 -1
@@ 40,7 40,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::Launch, manager::actions::SelectSimCard}};
        }
    };
} /* namespace app */

M module-apps/application-special-input/ApplicationSpecialInput.cpp => module-apps/application-special-input/ApplicationSpecialInput.cpp +5 -0
@@ 12,6 12,11 @@ ApplicationSpecialInput::ApplicationSpecialInput(std::string name,
                                                 StartInBackground startInBackground)
    : Application(name, parent, startInBackground)
{
    addActionReceiver(manager::actions::ShowSpecialInput, [this](auto &&data) {
        switchWindow(app::char_select, std::move(data));
        return msgHandled();
    });

    windowsFactory.attach(app::char_select, [](Application *app, const std::string &name) {
        return std::make_unique<gui::SpecialInputMainWindow>(app);
    });

M module-apps/application-special-input/ApplicationSpecialInput.hpp => module-apps/application-special-input/ApplicationSpecialInput.hpp +1 -1
@@ 39,7 39,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::ShowSpecialInput}};
        }
    };
}; // namespace app

M module-apps/application-special-input/widgets/SpecialInputTableWidget.cpp => module-apps/application-special-input/widgets/SpecialInputTableWidget.cpp +4 -6
@@ 12,8 12,6 @@
#include "Style.hpp"
#include "messages/AppMessage.hpp"

#include "UiCommonActions.hpp"

namespace gui
{



@@ 81,10 79,10 @@ namespace gui
        it->activatedCallback = [=](Item &it) {
            setFocusItem(nullptr);
            LOG_INFO("handled special char for %s", application->getCurrentWindow()->getName().c_str());
            app::specialInput(
                application,
                std::make_unique<gui::SwitchSpecialChar>(gui::SwitchSpecialChar::Type::Response, app->requester, str));
            return true;
            auto switchData =
                std::make_unique<gui::SwitchSpecialChar>(gui::SwitchSpecialChar::Type::Response, app->requester, str);
            return app::manager::Controller::switchBack(
                application, std::make_unique<app::manager::SwitchBackRequest>(app->requester, std::move(switchData)));
        };
    }


M module-apps/windows/AppWindow.cpp => module-apps/windows/AppWindow.cpp +5 -5
@@ 4,7 4,6 @@
#include "AppWindow.hpp"
#include "Application.hpp"
#include "InputEvent.hpp"
#include "UiCommonActions.hpp"
#include <Style.hpp>
#include <application-desktop/ApplicationDesktop.hpp>
#include <i18/i18.hpp>


@@ 126,8 125,7 @@ namespace gui

        if (inputEvent.state == InputEvent::State::keyReleasedLong && inputEvent.keyCode == gui::KeyCode::KEY_RF) {
            LOG_INFO("exit to main menu");
            app::manager::Controller::switchApplication(
                application, app::name_desktop, gui::name::window::main_window, nullptr);
            app::manager::Controller::sendAction(application, app::manager::actions::Home);
        }
        // process only if key is released
        if ((inputEvent.state != InputEvent::State::keyReleasedShort))


@@ 212,9 210,11 @@ namespace gui

    bool AppWindow::selectSpecialCharacter()
    {
        return app::specialInput(
        return app::manager::Controller::sendAction(
            application,
            std::make_unique<gui::SwitchSpecialChar>(gui::SwitchSpecialChar::Type::Request, application->GetName()));
            app::manager::actions::ShowSpecialInput,
            std::make_unique<gui::SwitchSpecialChar>(gui::SwitchSpecialChar::Type::Request, application->GetName()),
            app::manager::OnSwitchBehaviour::RunInBackground);
    }

    BoundingBox AppWindow::bodySize()

M module-apps/windows/Options.cpp => module-apps/windows/Options.cpp +55 -16
@@ 4,12 4,15 @@
#include "Options.hpp"
#include "Text.hpp"
#include "tools/Common.hpp"
#include <UiCommonActions.hpp>
#include <cassert>
#include <i18/i18.hpp>
#include <utility>
#include <FontManager.hpp>

#include <service-appmgr/Controller.hpp>
#include <application-call/data/CallSwitchData.hpp>
#include <module-apps/application-phonebook/data/PhonebookItemData.hpp>

namespace style::option
{
    const inline gui::Length text_left_padding = 10;


@@ 46,52 49,88 @@ namespace gui::option
            style::window::decorate(rect);
            auto l_app              = app;
            auto l_contact          = contact;
            rect->activatedCallback = [l_app, l_contact](gui::Item &item) { return app::call(l_app, l_contact); };
            rect->activatedCallback = [l_app, l_contact](gui::Item &item) {
                if (!l_contact.numbers.empty()) {
                    const auto &phoneNumber = l_contact.numbers.front().number;
                    return app::manager::Controller::sendAction(
                        l_app, app::manager::actions::Dial, std::make_unique<app::ExecuteCallData>(phoneNumber));
                }
                return false;
            };
            rect->addWidget(text);
            center(rect, text, Axis::Y);
            return rect;
        }
    };

}; // namespace gui::option
} // namespace gui::option

namespace gui::options
{
    using namespace app;
    namespace
    {
        bool onContactOptionClick(app::Application *app,
                                  ContactOperation contactOperation,
                                  const ContactRecord &contactRecord)
        {
            auto data = std::make_unique<PhonebookItemData>(std::make_shared<ContactRecord>(contactRecord));

    Option call(Application *app, CallOperation callOperation, const ContactRecord &contact)
            switch (contactOperation) {
            case ContactOperation::Add: {
                data->ignoreCurrentWindowOnStack = true;
                return app::manager::Controller::sendAction(app,
                                                            app::manager::actions::AddContact,
                                                            std::move(data),
                                                            app::manager::OnSwitchBehaviour::RunInBackground);
            }
            case ContactOperation::Details: {
                return app::manager::Controller::sendAction(app,
                                                            app::manager::actions::ShowContactDetails,
                                                            std::move(data),
                                                            app::manager::OnSwitchBehaviour::RunInBackground);
            }
            case ContactOperation::Edit: {
                return app::manager::Controller::sendAction(app,
                                                            app::manager::actions::EditContact,
                                                            std::move(data),
                                                            app::manager::OnSwitchBehaviour::RunInBackground);
            }
            }
            LOG_ERROR("ContactOperation not supported %" PRIu32, static_cast<uint32_t>(contactOperation));
            return false;
        }
    } // namespace

    Option call(app::Application *app, const ContactRecord &contact)
    {
        assert(app != nullptr);
        return Option{std::make_unique<gui::option::Call>(app, contact)};
    }

    Option contact(Application *app,
    Option contact(app::Application *app,
                   ContactOperation contactOperation,
                   const ContactRecord &contactRec,
                   gui::Arrow arrow)
    {
        assert(app != nullptr);

        std::string str;
        std::string optionName;
        switch (contactOperation) {
        case ContactOperation::Details:
            str = utils::localize.get("app_options_contact_details");
            optionName = utils::localize.get("app_options_contact_details");
            break;

        case ContactOperation::Add:
            str = utils::localize.get("app_options_contact_add");
            optionName = utils::localize.get("app_options_contact_add");
            break;

        case ContactOperation::Edit:
            str = utils::localize.get("app_options_contact_edit");
            optionName = utils::localize.get("app_options_contact_edit");
            break;

        default:
            str = utils::localize.get("app_options_invalid_option");
            optionName = utils::localize.get("app_options_invalid_option");
            LOG_WARN("ContactOperation %d not supported", static_cast<int>(contactOperation));
            break;
        }

        return {str, [=](gui::Item &item) { return app::contact(app, contactOperation, contactRec); }, arrow};
        return Option{
            optionName, [=](gui::Item &) { return onContactOptionClick(app, contactOperation, contactRec); }, arrow};
    }
} // namespace gui::options

M module-apps/windows/Options.hpp => module-apps/windows/Options.hpp +10 -3
@@ 3,15 3,22 @@

#pragma once

#include <module-db/Interface/ContactRecord.hpp>
#include "Application.hpp"
#include "OptionWindow.hpp"
#include <UiCommonActions.hpp>

namespace gui::options
{
    Option call(app::Application *app, app::CallOperation callOperation, const ContactRecord &contact);
    enum class ContactOperation
    {
        Add,
        Details,
        Edit
    };

    Option call(app::Application *app, const ContactRecord &contact);
    Option contact(app::Application *app,
                   app::ContactOperation contactOperation,
                   ContactOperation contactOperation,
                   const ContactRecord &contactRec,
                   gui::Arrow arrow = gui::Arrow::Disabled);
} // namespace gui::options

M module-services/service-appmgr/Controller.cpp => module-services/service-appmgr/Controller.cpp +24 -27
@@ 9,14 9,18 @@
#include <Service/Service.hpp>

#include <utility> // for move

namespace app::manager
{
    auto Controller::sendAction(sys::Service *sender, actions::ActionId actionId, actions::ActionParamsPtr &&data)
        -> bool
    namespace
    {
        auto msg = std::make_shared<app::manager::ActionRequest>(sender->GetName(), actionId, std::move(data));
        return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
    }
        void setOnSwitchBehaviour(actions::ActionParamsPtr &data, OnSwitchBehaviour onSwitchBehaviour) noexcept
        {
            if (data) {
                data->disableAppClose = (onSwitchBehaviour == OnSwitchBehaviour::RunInBackground);
            }
        }
    } // namespace

    auto Controller::applicationInitialised(sys::Service *sender,
                                            StartupStatus status,


@@ 26,26 30,27 @@ namespace app::manager
        return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
    }

    auto Controller::switchApplication(sys::Service *sender,
                                       const ApplicationName &applicationName,
                                       const std::string &windowName,
                                       std::unique_ptr<gui::SwitchData> data) -> bool
    auto Controller::sendAction(sys::Service *sender,
                                actions::ActionId actionId,
                                actions::ActionParamsPtr &&data,
                                OnSwitchBehaviour onSwitchBehaviour) -> bool
    {
        auto msg = std::make_shared<app::manager::SwitchRequest>(
            sender->GetName(), applicationName, windowName, std::move(data));
        setOnSwitchBehaviour(data, onSwitchBehaviour);
        auto msg = std::make_shared<app::manager::ActionRequest>(sender->GetName(), actionId, std::move(data));
        return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
    }

    auto Controller::confirmSwitch(sys::Service *sender) -> bool
    auto Controller::switchBack(sys::Service *sender, std::unique_ptr<SwitchBackRequest> msg) -> bool
    {

        auto msg = std::make_shared<app::manager::SwitchConfirmation>(sender->GetName());
        return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
        std::shared_ptr<SwitchBackRequest> switchMsg =
            msg ? std::move(msg) : std::make_shared<app::manager::SwitchBackRequest>(sender->GetName());
        return sys::Bus::SendUnicast(switchMsg, ApplicationManager::ServiceName, sender);
    }

    auto Controller::confirmClose(sys::Service *sender) -> bool
    auto Controller::confirmSwitch(sys::Service *sender) -> bool
    {
        auto msg = std::make_shared<app::manager::CloseConfirmation>(sender->GetName());
        auto msg = std::make_shared<app::manager::SwitchConfirmation>(sender->GetName());
        return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
    }



@@ 55,12 60,10 @@ namespace app::manager
        return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
    }

    auto Controller::switchBack(sys::Service *sender, std::unique_ptr<SwitchBackRequest> msg) -> bool
    auto Controller::confirmClose(sys::Service *sender) -> bool
    {

        std::shared_ptr<SwitchBackRequest> switchMsg =
            msg ? std::move(msg) : std::make_shared<app::manager::SwitchBackRequest>(sender->GetName());
        return sys::Bus::SendUnicast(switchMsg, ApplicationManager::ServiceName, sender);
        auto msg = std::make_shared<app::manager::CloseConfirmation>(sender->GetName());
        return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
    }

    auto Controller::changeDisplayLanguage(sys::Service *sender, utils::Lang language) -> bool


@@ 75,12 78,6 @@ namespace app::manager
        return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
    }

    auto Controller::stopApplicationManager(sys::Service *sender) -> bool
    {
        auto msg = std::make_shared<app::manager::ShutdownRequest>(sender->GetName());
        return sys::Bus::SendUnicast(msg, ApplicationManager::ServiceName, sender);
    }

    auto Controller::preventBlockingDevice(sys::Service *sender) -> bool
    {
        auto msg = std::make_shared<app::manager::PreventBlockingRequest>(sender->GetName());

M module-services/service-appmgr/model/ApplicationManager.cpp => module-services/service-appmgr/model/ApplicationManager.cpp +45 -31
@@ 147,7 147,7 @@ namespace app::manager
        startSystemServices();
        startBackgroundApplications();
        if (auto app = getApplication(rootApplicationName); app != nullptr) {
            Controller::switchApplication(this, rootApplicationName, std::string{}, nullptr);
            Controller::sendAction(this, actions::Home);
        }

        return sys::ReturnCodes::Success;


@@ 349,7 349,7 @@ namespace app::manager
        return true;
    }

    auto ApplicationManager::handleSwitchApplication(SwitchRequest *msg) -> bool
    auto ApplicationManager::handleSwitchApplication(SwitchRequest *msg, bool closeCurrentlyFocusedApp) -> bool
    {
        auto app = getApplication(msg->getName());
        if (app == nullptr) {


@@ 371,8 371,8 @@ namespace app::manager
        }

        onApplicationSwitch(*app, std::move(msg->getData()), msg->getWindow());
        const bool isFocusedAppCloseable = !(app->switchData && app->switchData->disableAppClose) &&
                                           currentlyFocusedApp->closeable() && !currentlyFocusedApp->blockClosing;
        const bool isFocusedAppCloseable =
            closeCurrentlyFocusedApp && currentlyFocusedApp->closeable() && !currentlyFocusedApp->blockClosing;
        requestApplicationClose(*currentlyFocusedApp, isFocusedAppCloseable);
        return true;
    }


@@ 405,12 405,40 @@ namespace app::manager

    auto ApplicationManager::handleAction(ActionRequest *actionMsg) -> bool
    {
        auto action = actionMsg->getAction();
        if (action == actions::Launch) {
        switch (const auto action = actionMsg->getAction(); action) {
        case actions::Home:
            return handleHomeAction();
        case actions::Launch: {
            auto params = static_cast<ApplicationLaunchData *>(actionMsg->getData().get());
            return handleLaunchAction(params);
        }
        default: {
            auto &actionParams = actionMsg->getData();
            return handleCustomAction(action, std::move(actionParams));
        }
        }
    }

    auto ApplicationManager::handleHomeAction() -> bool
    {
        SwitchRequest switchRequest(ServiceName, rootApplicationName, gui::name::window::main_window, nullptr);
        return handleSwitchApplication(&switchRequest);
    }

    auto ApplicationManager::handleLaunchAction(ApplicationLaunchData *launchParams) -> bool
    {
        auto targetApp = getApplication(launchParams->getTargetApplicationName());
        if (targetApp == nullptr || !targetApp->handles(actions::Launch)) {
            return false;
        }

        SwitchRequest switchRequest(ServiceName, targetApp->name(), gui::name::window::main_window, nullptr);
        return handleSwitchApplication(&switchRequest);
    }

    auto ApplicationManager::handleCustomAction(actions::ActionId action, actions::ActionParamsPtr &&actionParams)
        -> bool
    {
        const auto actionHandlers = applications.findByAction(action);
        if (actionHandlers.empty()) {
            LOG_ERROR("No applications handling action #%d.", action);


@@ 421,34 449,20 @@ namespace app::manager
            return false;
        }

        auto &actionData     = actionMsg->getData();
        const auto targetApp = actionHandlers.front();
        if (targetApp->state() != ApplicationHandle::State::ACTIVE_FORGROUND) {
            pendingAction = std::make_tuple(targetApp->name(), action, std::move(actionData));
            const auto focusedAppClose = !(actionParams && actionParams->disableAppClose);
            pendingAction              = std::make_tuple(targetApp->name(), action, std::move(actionParams));

            SwitchRequest switchRequest(actionMsg->getSenderName(),
                                        targetApp->name(),
                                        targetApp->switchWindow,
                                        std::move(targetApp->switchData));
            return handleSwitchApplication(&switchRequest);
            SwitchRequest switchRequest(
                ServiceName, targetApp->name(), targetApp->switchWindow, std::move(targetApp->switchData));
            return handleSwitchApplication(&switchRequest, focusedAppClose);
        }

        app::Application::requestAction(this, targetApp->name(), action, std::move(actionData));
        app::Application::requestAction(this, targetApp->name(), action, std::move(actionParams));
        return true;
    }

    auto ApplicationManager::handleLaunchAction(ApplicationLaunchData *launchParams) -> bool
    {
        auto targetApp = getApplication(launchParams->getTargetApplicationName());
        if (targetApp == nullptr || !targetApp->handles(actions::Launch)) {
            return false;
        }

        SwitchRequest switchRequest(
            ServiceName, targetApp->name(), targetApp->switchWindow, std::move(targetApp->switchData));
        return handleSwitchApplication(&switchRequest);
    }

    auto ApplicationManager::handleSwitchBack(SwitchBackRequest *msg) -> bool
    {
        auto previousApp = getPreviousApplication();


@@ 470,10 484,12 @@ namespace app::manager
            return false;
        }

        LOG_DEBUG("Switch applications: [%s](%s) -> [%s](%s)",
        LOG_DEBUG("Switch applications: [%s][%s](%s) -> [%s][%s](%s)",
                  currentlyFocusedApp->name().c_str(),
                  currentlyFocusedApp->switchWindow.c_str(),
                  app::Application::stateStr(currentlyFocusedApp->state()),
                  previousApp->name().c_str(),
                  previousApp->switchWindow.c_str(),
                  app::Application::stateStr(previousApp->state()));

        onApplicationSwitchToPrev(*previousApp, std::move(msg->getData()));


@@ 482,12 498,10 @@ namespace app::manager
    }

    void ApplicationManager::onApplicationSwitchToPrev(ApplicationHandle &previousApp,
                                                       std::unique_ptr<gui::SwitchData> &&data,
                                                       std::string targetWindow)
                                                       std::unique_ptr<gui::SwitchData> &&data)
    {
        popApplication();
        previousApp.switchData   = std::move(data);
        previousApp.switchWindow = std::move(targetWindow);
        previousApp.switchData = std::move(data);
    }

    auto ApplicationManager::handleInitApplication(ApplicationInitialised *msg) -> bool

M module-services/service-appmgr/service-appmgr/Actions.hpp => module-services/service-appmgr/service-appmgr/Actions.hpp +16 -0
@@ 22,8 22,22 @@ namespace app::manager

        enum Action : ActionId
        {
            Home,
            Launch,
            Call,
            Dial,
            ShowCallLog,
            CreateSms,
            ShowSmsTemplates,
            ShowContacts,
            ShowEmergencyContacts,
            AddContact,
            EditContact,
            ShowContactDetails,
            ShowSpecialInput,
            SelectSimCard,
            ShowAlarm,
            ShowReminder,
            RequestPin,
            RequestPuk,
            RequestPinChange,


@@ 31,6 45,8 @@ namespace app::manager
            BlockSim,
            DisplayCMEError,
            UserAction // The last enumerator in the Action enum.
                       // All user-defined actions shall have values greater than UserAction.
                       // All system-wide actions shall have values lesser than UserAction.
        };

        class ConvertibleToAction

M module-services/service-appmgr/service-appmgr/Controller.hpp => module-services/service-appmgr/service-appmgr/Controller.hpp +13 -9
@@ 22,28 22,32 @@ namespace sys

namespace app::manager
{
    enum class OnSwitchBehaviour
    {
        Close,
        RunInBackground
    };

    class Controller
    {
      public:
        Controller() = delete;

        static auto sendAction(sys::Service *sender, actions::ActionId actionId, actions::ActionParamsPtr &&data)
            -> bool;
        static auto applicationInitialised(sys::Service *sender,
                                           StartupStatus status,
                                           StartInBackground startInBackground) -> bool;
        static auto switchApplication(sys::Service *sender,
                                      const ApplicationName &applicationName,
                                      const std::string &windowName,
                                      std::unique_ptr<gui::SwitchData> data = nullptr) -> bool;
        static auto sendAction(sys::Service *sender,
                               actions::ActionId actionId,
                               actions::ActionParamsPtr &&data     = nullptr,
                               OnSwitchBehaviour onSwitchBehaviour = OnSwitchBehaviour::Close) -> bool;
        static auto switchBack(sys::Service *sender, std::unique_ptr<SwitchBackRequest> msg = nullptr) -> bool;
        static auto confirmSwitch(sys::Service *sender) -> bool;
        static auto closeApplication(sys::Service *sender, const ApplicationName &name) -> bool;
        static auto confirmClose(sys::Service *sender) -> bool;

        static auto changeDisplayLanguage(sys::Service *sender, utils::Lang language) -> bool;
        static auto changeInputLanguage(sys::Service *sender, utils::Lang language) -> bool;
        static auto changePowerSaveMode(sys::Service *sender) -> bool;
        static auto stopApplicationManager(sys::Service *sender) -> bool;
        static auto preventBlockingDevice(sys::Service *sender) -> bool;
        static auto confirmSwitch(sys::Service *sender) -> bool;
        static auto confirmClose(sys::Service *sender) -> bool;
    };
} // namespace app::manager

M module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp => module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp +4 -4
@@ 111,8 111,10 @@ namespace app::manager
        // Message handlers
        void registerMessageHandlers();
        auto handleAction(ActionRequest *actionMsg) -> bool;
        auto handleHomeAction() -> bool;
        auto handleLaunchAction(ApplicationLaunchData *launchParams) -> bool;
        auto handleSwitchApplication(SwitchRequest *msg) -> bool;
        auto handleCustomAction(actions::ActionId action, actions::ActionParamsPtr &&actionParams) -> bool;
        auto handleSwitchApplication(SwitchRequest *msg, bool closeCurrentlyFocusedApp = true) -> bool;
        auto handleCloseConfirmation(CloseConfirmation *msg) -> bool;
        auto handleSwitchConfirmation(SwitchConfirmation *msg) -> bool;
        auto handleSwitchBack(SwitchBackRequest *msg) -> bool;


@@ 126,9 128,7 @@ namespace app::manager
        void onApplicationSwitch(ApplicationHandle &app,
                                 std::unique_ptr<gui::SwitchData> &&data,
                                 std::string targetWindow);
        void onApplicationSwitchToPrev(ApplicationHandle &previousApp,
                                       std::unique_ptr<gui::SwitchData> &&data,
                                       std::string targetWindow = {});
        void onApplicationSwitchToPrev(ApplicationHandle &previousApp, std::unique_ptr<gui::SwitchData> &&data);
        void onApplicationInitialised(ApplicationHandle &app, StartInBackground startInBackground);
        void onApplicationInitFailure(ApplicationHandle &app);
        auto onSwitchConfirmed(ApplicationHandle &app) -> bool;

M module-services/service-evtmgr/alarm/EventManagerAlarm.cpp => module-services/service-evtmgr/alarm/EventManagerAlarm.cpp +3 -3
@@ 53,9 53,9 @@ void EventManager::HandleAlarmTrigger(sys::DataMessage *msgl)
        // round time and compare to alaram timestamp
        if (alarmTimestamp == (currentTime % 86400)) {
            alarmIsValid = false;
            // run bell application
            std::unique_ptr<gui::SwitchData> switchMessage = std::make_unique<sevm::EVMAlarmSwitchData>(alarmID);
            app::manager::Controller::switchApplication(this, "bell", "main", std::move(switchMessage));
            // Run "alarm" application.
            // std::unique_ptr<gui::SwitchData> switchMessage = std::make_unique<sevm::EVMAlarmSwitchData>(alarmID);
            // app::manager::Controller::sendAction(this, app::manager::actions::ShowAlarm, std::move(switchMessage));
        }
        // check if alarm is not obsolete
        else if ((alarmTimestamp < (currentTime % 86400)) && ((currentTime + 60) % 86400) > (currentTime % 86400)) {

M module-services/service-time/timeEvents/CalendarTimeEvents.cpp => module-services/service-time/timeEvents/CalendarTimeEvents.cpp +1 -2
@@ 85,7 85,6 @@ namespace stm
        auto event = std::make_shared<EventsRecord>(eventRecord);
        eventData->setData(event);

        app::manager::Controller::switchApplication(
            service(), app::name_calendar, style::window::calendar::name::event_reminder_window, std::move(eventData));
        app::manager::Controller::sendAction(service(), app::manager::actions::ShowReminder, std::move(eventData));
    }
} // namespace stm

M source/MessageType.hpp => source/MessageType.hpp +8 -7
@@ 126,13 126,14 @@ enum class MessageType
    APMConfirmSwitch,   ///< Used when application confirms that it is loosing focus and also when application confirms
                        ///< that is has gained focus
    APMConfirmClose,    ///< Sent by application to confirm completion of the close procedure
    APMRegister,        ///< when application finishes initHandler it is sending this messag to inform whether init was
                        ///< successful or not.
    APMInit,            ///< Send by application to confirm completion its initialisation process
    APMDelayedClose,    ///< this message is sent internally from and to application manager to close specified
                        ///< application.
    APMChangeLanguage,  ///< this message is sent from any application to inform application manager that it should send
                        ///< gui rebuild command to all applications in background and currently active application.
    APMConfirmWindowSwitch, ///<
    APMRegister,       ///< when application finishes initHandler it is sending this messag to inform whether init was
                       ///< successful or not.
    APMInit,           ///< Send by application to confirm completion its initialisation process
    APMDelayedClose,   ///< this message is sent internally from and to application manager to close specified
                       ///< application.
    APMChangeLanguage, ///< this message is sent from any application to inform application manager that it should send
                       ///< gui rebuild command to all applications in background and currently active application.
    APMClose, ///< this message will trigger application manager to close itself, all running applications gui and eink
              ///< services.
    APMPreventBlocking,   ///< Prevents application manager from initializing device blocking.