~aleteoryx/muditaos

81adfe41ab8f915e6cfcee02d9acf35442a93d7a — Piotr Tański 5 years ago 14a0194
[EGD-6347] Refactored phone modes handling in applications

PhoneModeObserver doesn't work properly in applications.
Applications have to handle the phone mode changes via AppMgr.
Phone mode and tethering handlers separated.
56 files changed, 435 insertions(+), 193 deletions(-)

M module-apps/Application.cpp
M module-apps/Application.hpp
M module-apps/ApplicationLauncher.hpp
M module-apps/application-alarm-clock/ApplicationAlarmClock.cpp
M module-apps/application-alarm-clock/ApplicationAlarmClock.hpp
M module-apps/application-antenna/ApplicationAntenna.cpp
M module-apps/application-antenna/ApplicationAntenna.hpp
M module-apps/application-calculator/ApplicationCalculator.cpp
M module-apps/application-calculator/ApplicationCalculator.hpp
M module-apps/application-calendar/ApplicationCalendar.cpp
M module-apps/application-calendar/ApplicationCalendar.hpp
M module-apps/application-call/ApplicationCall.cpp
M module-apps/application-call/ApplicationCall.hpp
M module-apps/application-calllog/ApplicationCallLog.cpp
M module-apps/application-calllog/ApplicationCallLog.hpp
M module-apps/application-clock/ApplicationClock.cpp
M module-apps/application-clock/ApplicationClock.hpp
M module-apps/application-desktop/ApplicationDesktop.cpp
M module-apps/application-desktop/ApplicationDesktop.hpp
M module-apps/application-meditation/ApplicationMeditation.cpp
M module-apps/application-meditation/ApplicationMeditation.hpp
M module-apps/application-messages/ApplicationMessages.cpp
M module-apps/application-messages/ApplicationMessages.hpp
M module-apps/application-music-player/ApplicationMusicPlayer.cpp
M module-apps/application-music-player/ApplicationMusicPlayer.hpp
M module-apps/application-notes/ApplicationNotes.cpp
M module-apps/application-notes/ApplicationNotes.hpp
M module-apps/application-onboarding/ApplicationOnBoarding.cpp
M module-apps/application-onboarding/ApplicationOnBoarding.hpp
M module-apps/application-phonebook/ApplicationPhonebook.cpp
M module-apps/application-phonebook/ApplicationPhonebook.hpp
M module-apps/application-settings-new/ApplicationSettings.cpp
M module-apps/application-settings-new/ApplicationSettings.hpp
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/popups/TetheringPhoneModePopup.cpp
A module-apps/popups/data/PhoneModeParams.hpp
A module-apps/popups/data/PopupRequestParams.hpp
M module-services/service-antenna/ServiceAntenna.cpp
M module-services/service-appmgr/model/ApplicationHandle.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/model/ApplicationHandle.hpp
M module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp
M module-services/service-audio/ServiceAudio.cpp
M module-services/service-audio/service-audio/ServiceAudio.hpp
M module-services/service-cellular/ServiceCellular.cpp
M module-sys/PhoneModes/Common.hpp
M module-sys/PhoneModes/Observer.cpp
M module-sys/PhoneModes/Observer.hpp
M module-sys/PhoneModes/Subject.cpp
M module-sys/PhoneModes/Subject.hpp
M module-sys/SystemManager/messages/TetheringPhoneModeChangeProhibitedMessage.hpp
M module-sys/SystemManager/messages/TetheringQuestionRequest.hpp
M module-apps/Application.cpp => module-apps/Application.cpp +32 -23
@@ 6,6 6,8 @@
#include "GuiTimer.hpp"      // for GuiTimer
#include "Item.hpp"          // for Item
#include "MessageType.hpp"   // for MessageType
#include "module-apps/popups/data/PopupRequestParams.hpp"
#include "module-apps/popups/data/PhoneModeParams.hpp"
#include "module-sys/Timers/TimerFactory.hpp" // for Timer
#include "TopBar.hpp"
#include "popups/TetheringConfirmationPopup.hpp"


@@ 82,6 84,7 @@ namespace app

    Application::Application(std::string name,
                             std::string parent,
                             sys::phone_modes::PhoneMode mode,
                             StartInBackground startInBackground,
                             uint32_t stackDepth,
                             sys::ServicePriority priority)


@@ 89,14 92,12 @@ namespace app
          default_window(gui::name::window::main_window), windowsStack(this),
          keyTranslator{std::make_unique<gui::KeyInputSimpleTranslation>()}, startInBackground{startInBackground},
          callbackStorage{std::make_unique<CallbackStorage>()}, topBarManager{std::make_unique<TopBarManager>()},
          settings(std::make_unique<settings::Settings>(this)),
          phoneModeObserver(std::make_unique<sys::phone_modes::Observer>())
          settings(std::make_unique<settings::Settings>(this)), phoneMode{mode}
    {
        topBarManager->enableIndicators({gui::top_bar::Indicator::Time});
        topBarManager->set(utils::dateAndTimeSettings.isTimeFormat12() ? gui::top_bar::TimeMode::Time12h
                                                                       : gui::top_bar::TimeMode::Time24h);
        bus.channels.push_back(sys::BusChannel::ServiceCellularNotifications);
        bus.channels.push_back(sys::BusChannel::PhoneModeChanges);

        longPressTimer = sys::TimerFactory::createPeriodicTimer(this,
                                                                "LongPress",


@@ 111,22 112,22 @@ namespace app
        connect(typeid(AppUpdateWindowMessage),
                [&](sys::Message *msg) -> sys::MessagePointer { return handleUpdateWindow(msg); });

        // handle phone mode changes
        phoneModeObserver->connect(this);
        phoneModeObserver->subscribe(
            [&](sys::phone_modes::PhoneMode phoneMode, sys::phone_modes::Tethering tetheringMode) {
                handlePhoneModeChanged(phoneMode, tetheringMode);
            });

        addActionReceiver(app::manager::actions::PhoneModeChanged, [this](auto &&params) {
            if (params != nullptr) {
                auto modeParams = static_cast<gui::PhoneModeParams *>(params.get());
                phoneMode       = modeParams->getPhoneMode();
            }
            return actionHandled();
        });
        addActionReceiver(app::manager::actions::ShowPopup, [this](auto &&params) {
            auto popupParams = static_cast<app::PopupRequestParams *>(params.get());
            auto popupParams = static_cast<gui::PopupRequestParams *>(params.get());
            if (const auto popupId = popupParams->getPopupId(); isPopupPermitted(popupId)) {
                switchWindow(gui::popup::resolveWindowName(popupId));
                showPopup(popupId, popupParams);
            }
            return actionHandled();
        });
        addActionReceiver(app::manager::actions::AbortPopup, [this](auto &&params) {
            auto popupParams   = static_cast<app::PopupRequestParams *>(params.get());
            auto popupParams   = static_cast<gui::PopupRequestParams *>(params.get());
            const auto popupId = popupParams->getPopupId();
            abortPopup(popupId);
            return actionHandled();


@@ 186,7 187,7 @@ namespace app
            window->updateSignalStrength();
            window->updateNetworkAccessTechnology();
            window->updateTime();
            window->updatePhoneMode(phoneModeObserver->getCurrentPhoneMode());
            window->updatePhoneMode(phoneMode);

            auto message = std::make_shared<service::gui::DrawMessage>(window->buildDrawList(), mode);



@@ 687,19 688,15 @@ namespace app
        sender->bus.sendUnicast(msg, application);
    }

    void Application::handlePhoneModeChanged(sys::phone_modes::PhoneMode mode, sys::phone_modes::Tethering tethering)
    void Application::handlePhoneModeChanged(sys::phone_modes::PhoneMode mode)
    {
        // only foreground rendering application will react to mode changes
        if (state != State::ACTIVE_FORGROUND) {
            return;
        }

        using namespace gui::popup;
        if (getCurrentWindow()->getName() == window::phone_modes_window) {
            updateWindow(window::phone_modes_window, std::make_unique<gui::ModesPopupData>(mode));
        const auto &popupName = resolveWindowName(gui::popup::ID::PhoneModes);
        if (const auto currentWindowName = getCurrentWindow()->getName(); currentWindowName == popupName) {
            updateWindow(popupName, std::make_unique<gui::ModesPopupData>(mode));
        }
        else {
            switchWindow(window::phone_modes_window, std::make_unique<gui::ModesPopupData>(mode));
            switchWindow(popupName, std::make_unique<gui::ModesPopupData>(mode));
        }
    }



@@ 738,6 735,18 @@ namespace app
        }
    }

    void Application::showPopup(gui::popup::ID id, const gui::PopupRequestParams *params)
    {
        using namespace gui::popup;
        if (id == ID::PhoneModes) {
            auto popupParams = static_cast<const gui::PhoneModePopupRequestParams *>(params);
            handlePhoneModeChanged(popupParams->getPhoneMode());
        }
        else {
            switchWindow(gui::popup::resolveWindowName(id));
        }
    }

    void Application::abortPopup(gui::popup::ID id)
    {
        const auto popupName = gui::popup::resolveWindowName(id);

M module-apps/Application.hpp => module-apps/Application.hpp +5 -18
@@ 48,6 48,7 @@ namespace gui
namespace gui
{
    class Item;
    class PopupRequestParams;
}
namespace gui
{


@@ 188,6 189,7 @@ namespace app

        Application(std::string name,
                    std::string parent                  = "",
                    sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                    StartInBackground startInBackground = {false},
                    uint32_t stackDepth                 = 4096,
                    sys::ServicePriority priority       = sys::ServicePriority::Idle);


@@ 326,7 328,7 @@ namespace app
        /// Handle the change of phone mode and tethering mode
        /// @param mode new phone mode
        /// @param tethering new tethering mode
        void handlePhoneModeChanged(sys::phone_modes::PhoneMode mode, sys::phone_modes::Tethering tethering);
        void handlePhoneModeChanged(sys::phone_modes::PhoneMode mode);

        /// @ingrup AppWindowStack
        WindowsStack windowsStack;


@@ 334,6 336,7 @@ namespace app

        /// Method used to attach popups windows to application
        void attachPopups(const std::vector<gui::popup::ID> &popupsList);
        void showPopup(gui::popup::ID id, const gui::PopupRequestParams *params);
        void abortPopup(gui::popup::ID id);

      public:


@@ 391,7 394,7 @@ namespace app

        /// application's settings
        std::unique_ptr<settings::Settings> settings;
        std::unique_ptr<sys::phone_modes::Observer> phoneModeObserver;
        sys::phone_modes::PhoneMode phoneMode;

      public:
        void setLockScreenPasscodeOn(bool screenPasscodeOn) noexcept;


@@ 415,20 418,4 @@ namespace app
      private:
        ApplicationName targetAppName;
    };

    class PopupRequestParams : public manager::actions::ActionParams
    {
      public:
        explicit PopupRequestParams(gui::popup::ID popupId)
            : manager::actions::ActionParams{"Popup request parameters"}, popupId{popupId}
        {}

        [[nodiscard]] auto getPopupId() const noexcept
        {
            return popupId;
        }

      private:
        gui::popup::ID popupId;
    };
} /* namespace app */

M module-apps/ApplicationLauncher.hpp => module-apps/ApplicationLauncher.hpp +6 -6
@@ 65,12 65,12 @@ namespace app
            return (preventAutoLocking == PreventAutoLocking::True);
        }

        virtual bool run(sys::Service *caller = nullptr)
        virtual bool run(sys::phone_modes::PhoneMode mode, sys::Service *caller = nullptr)
        {
            return false;
        }

        virtual bool runBackground(sys::Service *caller = nullptr)
        virtual bool runBackground(sys::phone_modes::PhoneMode mode, sys::Service *caller = nullptr)
        {
            return false;
        }


@@ 89,17 89,17 @@ namespace app
            : ApplicationLauncher(name, std::move(manifest), isCloseable, preventBlocking)
        {}

        bool run(sys::Service *caller) override
        bool run(sys::phone_modes::PhoneMode mode, sys::Service *caller) override
        {
            parent = (caller == nullptr ? "" : caller->GetName());
            handle = std::make_shared<T>(name, parent);
            handle = std::make_shared<T>(name, parent, mode);
            return sys::SystemManager::RunApplication(handle, caller);
        }

        bool runBackground(sys::Service *caller) override
        bool runBackground(sys::phone_modes::PhoneMode mode, sys::Service *caller) override
        {
            parent = (caller == nullptr ? "" : caller->GetName());
            handle = std::make_shared<T>(name, parent, true);
            handle = std::make_shared<T>(name, parent, mode, true);
            return sys::SystemManager::RunApplication(handle, caller);
        }
    };

M module-apps/application-alarm-clock/ApplicationAlarmClock.cpp => module-apps/application-alarm-clock/ApplicationAlarmClock.cpp +2 -1
@@ 19,9 19,10 @@ namespace app

    ApplicationAlarmClock::ApplicationAlarmClock(std::string name,
                                                 std::string parent,
                                                 sys::phone_modes::PhoneMode mode,
                                                 uint32_t stackDepth,
                                                 sys::ServicePriority priority)
        : Application(name, parent, false, stackDepth, priority)
        : Application(name, parent, mode, false, stackDepth, priority)
    {
        bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);
    }

M module-apps/application-alarm-clock/ApplicationAlarmClock.hpp => module-apps/application-alarm-clock/ApplicationAlarmClock.hpp +5 -4
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 14,8 14,9 @@ namespace app
      public:
        ApplicationAlarmClock(std::string name,
                              std::string parent,
                              uint32_t stackDepth           = 4096,
                              sys::ServicePriority priority = sys::ServicePriority::Idle);
                              sys::phone_modes::PhoneMode mode = sys::phone_modes::PhoneMode::Connected,
                              uint32_t stackDepth              = 4096,
                              sys::ServicePriority priority    = sys::ServicePriority::Idle);

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



@@ 36,7 37,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::Launch, manager::actions::PhoneModeChanged}};
        }
    };
} // namespace app

M module-apps/application-antenna/ApplicationAntenna.cpp => module-apps/application-antenna/ApplicationAntenna.cpp +5 -2
@@ 36,8 36,11 @@ namespace app

    inline constexpr auto antennaApplicationStackSize = 1024 * 3;

    ApplicationAntenna::ApplicationAntenna(std::string name, std::string parent, StartInBackground startInBackground)
        : Application(name, parent, startInBackground, antennaApplicationStackSize)
    ApplicationAntenna::ApplicationAntenna(std::string name,
                                           std::string parent,
                                           sys::phone_modes::PhoneMode mode,
                                           StartInBackground startInBackground)
        : Application(name, parent, mode, startInBackground, antennaApplicationStackSize)
    {
        bus.channels.push_back(sys::BusChannel::AntennaNotifications);
        appTimer = sys::TimerFactory::createPeriodicTimer(

M module-apps/application-antenna/ApplicationAntenna.hpp => module-apps/application-antenna/ApplicationAntenna.hpp +2 -1
@@ 40,6 40,7 @@ namespace app
      public:
        ApplicationAntenna(std::string name                    = name_antenna,
                           std::string parent                  = {},
                           sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                           StartInBackground startInBackground = {false});
        virtual ~ApplicationAntenna();



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

M module-apps/application-calculator/ApplicationCalculator.cpp => module-apps/application-calculator/ApplicationCalculator.cpp +2 -1
@@ 9,8 9,9 @@ namespace app
{
    ApplicationCalculator::ApplicationCalculator(std::string name,
                                                 std::string parent,
                                                 sys::phone_modes::PhoneMode mode,
                                                 StartInBackground startInBackground)
        : Application(name, parent, startInBackground, stack_size)
        : Application(name, parent, mode, startInBackground, stack_size)
    {}

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

M module-apps/application-calculator/ApplicationCalculator.hpp => module-apps/application-calculator/ApplicationCalculator.hpp +2 -1
@@ 15,6 15,7 @@ namespace app
      public:
        ApplicationCalculator(std::string name                    = name_calculator,
                              std::string parent                  = {},
                              sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                              StartInBackground startInBackground = {false});
        ~ApplicationCalculator() override = default;



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

M module-apps/application-calendar/ApplicationCalendar.cpp => module-apps/application-calendar/ApplicationCalendar.cpp +2 -1
@@ 44,10 44,11 @@ namespace app

    ApplicationCalendar::ApplicationCalendar(std::string name,
                                             std::string parent,
                                             sys::phone_modes::PhoneMode mode,
                                             StartInBackground startInBackground,
                                             uint32_t stackDepth,
                                             sys::ServicePriority priority)
        : Application(name, parent, startInBackground, stackDepth, priority)
        : Application(name, parent, mode, startInBackground, stackDepth, priority)
    {
        bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);
        addActionReceiver(manager::actions::ShowReminder, [this](auto &&data) {

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

#pragma once


@@ 25,6 25,7 @@ namespace app
      public:
        ApplicationCalendar(std::string name,
                            std::string parent,
                            sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                            StartInBackground startInBackground = {false},
                            uint32_t stackDepth                 = 8192,
                            sys::ServicePriority priority       = sys::ServicePriority::Idle);


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

M module-apps/application-call/ApplicationCall.cpp => module-apps/application-call/ApplicationCall.cpp +5 -2
@@ 30,8 30,11 @@

namespace app
{
    ApplicationCall::ApplicationCall(std::string name, std::string parent, StartInBackground startInBackground)
        : Application(name, parent, startInBackground, app::call_stack_size)
    ApplicationCall::ApplicationCall(std::string name,
                                     std::string parent,
                                     sys::phone_modes::PhoneMode mode,
                                     StartInBackground startInBackground)
        : Application(name, parent, mode, startInBackground, app::call_stack_size)
    {
        using namespace gui::top_bar;
        topBarManager->enableIndicators({Indicator::Signal,

M module-apps/application-call/ApplicationCall.hpp => module-apps/application-call/ApplicationCall.hpp +3 -1
@@ 82,6 82,7 @@ namespace app
      public:
        ApplicationCall(std::string name                    = name_call,
                        std::string parent                  = {},
                        sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                        StartInBackground startInBackground = {false});
        sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;
        sys::ReturnCodes InitHandler() override;


@@ 131,7 132,8 @@ namespace app
                     manager::actions::EmergencyDial,
                     manager::actions::NotAnEmergencyNotification,
                     manager::actions::NoSimNotification,
                     manager::actions::CallRejectedByOfflineNotification}};
                     manager::actions::CallRejectedByOfflineNotification,
                     manager::actions::PhoneModeChanged}};
        }
    };
} /* namespace app */

M module-apps/application-calllog/ApplicationCallLog.cpp => module-apps/application-calllog/ApplicationCallLog.cpp +5 -2
@@ 22,8 22,11 @@ using namespace calllog;

namespace app
{
    ApplicationCallLog::ApplicationCallLog(std::string name, std::string parent, StartInBackground startInBackground)
        : Application(name, parent, startInBackground, 4096)
    ApplicationCallLog::ApplicationCallLog(std::string name,
                                           std::string parent,
                                           sys::phone_modes::PhoneMode mode,
                                           StartInBackground startInBackground)
        : Application(name, parent, mode, startInBackground, 4096)
    {
        addActionReceiver(manager::actions::ShowCallLog, [this](auto &&data) {
            switchWindow(gui::name::window::main_window, std::move(data));

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

#pragma once


@@ 17,6 17,7 @@ namespace app
      public:
        ApplicationCallLog(std::string name                    = CallLogAppStr,
                           std::string parent                  = {},
                           sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                           StartInBackground startInBackground = {false});
        ~ApplicationCallLog() override;



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

M module-apps/application-clock/ApplicationClock.cpp => module-apps/application-clock/ApplicationClock.cpp +2 -1
@@ 21,10 21,11 @@ namespace app
{
    ApplicationClock::ApplicationClock(std::string name,
                                       std::string parent,
                                       sys::phone_modes::PhoneMode mode,
                                       StartInBackground startInBackground,
                                       uint32_t stackDepth,
                                       sys::ServicePriority priority)
        : Application(name, parent, startInBackground, stackDepth, priority)
        : Application(name, parent, mode, startInBackground, stackDepth, priority)
    {
        timerClock = sys::TimerFactory::createPeriodicTimer(
            this, "Clock", std::chrono::milliseconds{1000}, [&](sys::Timer &) { timerClockCallback(); });

M module-apps/application-clock/ApplicationClock.hpp => module-apps/application-clock/ApplicationClock.hpp +2 -1
@@ 21,6 21,7 @@ namespace app
      public:
        ApplicationClock(std::string name                    = name_clock,
                         std::string parent                  = {},
                         sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                         StartInBackground startInBackground = {false},
                         uint32_t stackDepth                 = 4096,
                         sys::ServicePriority priority       = sys::ServicePriority::Idle);


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

M module-apps/application-desktop/ApplicationDesktop.cpp => module-apps/application-desktop/ApplicationDesktop.cpp +5 -2
@@ 72,8 72,11 @@ namespace app
        }
    } // namespace

    ApplicationDesktop::ApplicationDesktop(std::string name, std::string parent, StartInBackground startInBackground)
        : Application(name, parent, startInBackground), lockHandler(this)
    ApplicationDesktop::ApplicationDesktop(std::string name,
                                           std::string parent,
                                           sys::phone_modes::PhoneMode mode,
                                           StartInBackground startInBackground)
        : Application(name, parent, mode, startInBackground), lockHandler(this)
    {
        using namespace gui::top_bar;
        topBarManager->enableIndicators({Indicator::Signal,

M module-apps/application-desktop/ApplicationDesktop.hpp => module-apps/application-desktop/ApplicationDesktop.hpp +3 -1
@@ 56,6 56,7 @@ namespace app

        ApplicationDesktop(std::string name                    = name_desktop,
                           std::string parent                  = {},
                           sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                           StartInBackground startInBackground = {false});
        virtual ~ApplicationDesktop();
        sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;


@@ 131,7 132,8 @@ namespace app
                     manager::actions::DisplayCMEError,
                     manager::actions::DisplayLowBatteryScreen,
                     manager::actions::SystemBrownout,
                     manager::actions::DisplayLogoAtExit}};
                     manager::actions::DisplayLogoAtExit,
                     manager::actions::PhoneModeChanged}};
        }
    };


M module-apps/application-meditation/ApplicationMeditation.cpp => module-apps/application-meditation/ApplicationMeditation.cpp +2 -1
@@ 12,8 12,9 @@ namespace app
{
    ApplicationMeditation::ApplicationMeditation(std::string name,
                                                 std::string parent,
                                                 sys::phone_modes::PhoneMode mode,
                                                 StartInBackground startInBackground)
        : Application{name, parent, startInBackground}, state{std::make_unique<gui::OptionsData>()}
        : Application{name, parent, mode, startInBackground}, state{std::make_unique<gui::OptionsData>()}
    {}

    auto ApplicationMeditation::InitHandler() -> sys::ReturnCodes

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

#pragma once


@@ 17,6 17,7 @@ namespace app
      public:
        explicit ApplicationMeditation(std::string name                    = name_meditation,
                                       std::string parent                  = {},
                                       sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                                       StartInBackground startInBackground = {false});

        auto InitHandler() -> sys::ReturnCodes override;


@@ 32,7 33,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::Launch, manager::actions::PhoneModeChanged}};
        }
    };
} // namespace app

M module-apps/application-messages/ApplicationMessages.cpp => module-apps/application-messages/ApplicationMessages.cpp +5 -2
@@ 41,8 41,11 @@ namespace app
{
    static constexpr auto messagesStackDepth = 1024 * 6; // 6Kb stack size

    ApplicationMessages::ApplicationMessages(std::string name, std::string parent, StartInBackground startInBackground)
        : Application(name, parent, startInBackground, messagesStackDepth), AsyncCallbackReceiver{this}
    ApplicationMessages::ApplicationMessages(std::string name,
                                             std::string parent,
                                             sys::phone_modes::PhoneMode mode,
                                             StartInBackground startInBackground)
        : Application(name, parent, mode, startInBackground, messagesStackDepth), AsyncCallbackReceiver{this}
    {
        bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);
        addActionReceiver(manager::actions::CreateSms, [this](auto &&data) {

M module-apps/application-messages/ApplicationMessages.hpp => module-apps/application-messages/ApplicationMessages.hpp +3 -1
@@ 40,6 40,7 @@ namespace app
      public:
        ApplicationMessages(std::string name                    = name_messages,
                            std::string parent                  = {},
                            sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                            StartInBackground startInBackground = {false});

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


@@ 87,7 88,8 @@ namespace app
                     manager::actions::CreateSms,
                     manager::actions::ShowSmsTemplates,
                     manager::actions::SmsRejectNoSim,
                     manager::actions::SMSRejectedByOfflineNotification}};
                     manager::actions::SMSRejectedByOfflineNotification,
                     manager::actions::PhoneModeChanged}};
        }
    };
} /* namespace app */

M module-apps/application-music-player/ApplicationMusicPlayer.cpp => module-apps/application-music-player/ApplicationMusicPlayer.cpp +2 -1
@@ 18,8 18,9 @@ namespace app

    ApplicationMusicPlayer::ApplicationMusicPlayer(std::string name,
                                                   std::string parent,
                                                   sys::phone_modes::PhoneMode mode,
                                                   StartInBackground startInBackground)
        : Application(std::move(name), std::move(parent), startInBackground, applicationMusicPlayerStackSize)
        : Application(std::move(name), std::move(parent), mode, startInBackground, applicationMusicPlayerStackSize)
    {
        LOG_INFO("ApplicationMusicPlayer::create");
        connect(typeid(AudioStartPlaybackResponse), [&](sys::Message *msg) {

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

#pragma once


@@ 31,6 31,7 @@ namespace app
      public:
        explicit ApplicationMusicPlayer(std::string name                    = name_music_player,
                                        std::string parent                  = {},
                                        sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                                        StartInBackground startInBackground = {false});

        sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl,


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

M module-apps/application-notes/ApplicationNotes.cpp => module-apps/application-notes/ApplicationNotes.cpp +5 -2
@@ 27,8 27,11 @@ namespace app
        constexpr auto NotesStackSize = 4096U;
    } // namespace

    ApplicationNotes::ApplicationNotes(std::string name, std::string parent, StartInBackground startInBackground)
        : Application(std::move(name), std::move(parent), startInBackground, NotesStackSize)
    ApplicationNotes::ApplicationNotes(std::string name,
                                       std::string parent,
                                       sys::phone_modes::PhoneMode mode,
                                       StartInBackground startInBackground)
        : Application(std::move(name), std::move(parent), mode, startInBackground, NotesStackSize)
    {
        bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);
    }

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

#pragma once


@@ 25,6 25,7 @@ namespace app
      public:
        explicit ApplicationNotes(std::string name                    = name_notes,
                                  std::string parent                  = {},
                                  sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                                  StartInBackground startInBackground = {false});

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


@@ 40,7 41,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::Launch, manager::actions::PhoneModeChanged}};
        }
    };
} // namespace app

M module-apps/application-onboarding/ApplicationOnBoarding.cpp => module-apps/application-onboarding/ApplicationOnBoarding.cpp +2 -1
@@ 30,8 30,9 @@ namespace app

    ApplicationOnBoarding::ApplicationOnBoarding(std::string name,
                                                 std::string parent,
                                                 sys::phone_modes::PhoneMode mode,
                                                 StartInBackground startInBackground)
        : Application(std::move(name), std::move(parent), startInBackground, OnBoardingStackSize)
        : Application(std::move(name), std::move(parent), mode, startInBackground, OnBoardingStackSize)
    {
        using namespace gui::top_bar;
        topBarManager->enableIndicators({Indicator::Signal,

M module-apps/application-onboarding/ApplicationOnBoarding.hpp => module-apps/application-onboarding/ApplicationOnBoarding.hpp +2 -1
@@ 27,6 27,7 @@ namespace app
      public:
        explicit ApplicationOnBoarding(std::string name                    = name_onboarding,
                                       std::string parent                  = {},
                                       sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                                       StartInBackground startInBackground = {false});

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


@@ 44,7 45,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
            return {{manager::actions::Launch, manager::actions::PhoneModeChanged}};
        }
    };
} // namespace app

M module-apps/application-phonebook/ApplicationPhonebook.cpp => module-apps/application-phonebook/ApplicationPhonebook.cpp +2 -1
@@ 21,8 21,9 @@ namespace app
{
    ApplicationPhonebook::ApplicationPhonebook(std::string name,
                                               std::string parent,
                                               sys::phone_modes::PhoneMode mode,
                                               StartInBackground startInBackground)
        : Application(name, parent, startInBackground, phonebook_stack_size)
        : Application(name, parent, mode, startInBackground, phonebook_stack_size)
    {
        bus.channels.push_back(sys::BusChannel::ServiceDBNotifications);
        addActionReceiver(manager::actions::ShowContacts, [this](auto &&data) {

M module-apps/application-phonebook/ApplicationPhonebook.hpp => module-apps/application-phonebook/ApplicationPhonebook.hpp +3 -1
@@ 32,6 32,7 @@ namespace app
      public:
        ApplicationPhonebook(std::string name                    = name_phonebook,
                             std::string parent                  = {},
                             sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                             StartInBackground startInBackground = {false});
        ~ApplicationPhonebook() override = default;



@@ 59,7 60,8 @@ namespace app
                     manager::actions::AddContact,
                     manager::actions::EditContact,
                     manager::actions::ShowContactDetails,
                     manager::actions::ShowEmergencyContacts}};
                     manager::actions::ShowEmergencyContacts,
                     manager::actions::PhoneModeChanged}};
        }
    };
} // namespace app

M module-apps/application-settings-new/ApplicationSettings.cpp => module-apps/application-settings-new/ApplicationSettings.cpp +6 -3
@@ 96,8 96,9 @@ namespace app

    ApplicationSettingsNew::ApplicationSettingsNew(std::string name,
                                                   std::string parent,
                                                   sys::phone_modes::PhoneMode mode,
                                                   StartInBackground startInBackground)
        : Application(std::move(name), std::move(parent), startInBackground), AsyncCallbackReceiver{this}
        : Application(std::move(name), std::move(parent), mode, startInBackground), AsyncCallbackReceiver{this}
    {
        if ((Store::GSM::SIM::SIM1 == selectedSim || Store::GSM::SIM::SIM2 == selectedSim) &&
            Store::GSM::get()->sim == selectedSim) {


@@ 537,8 538,10 @@ namespace app
        windowsFactory.attach(gui::window::name::connection_frequency, [](Application *app, const std::string &name) {
            return std::make_unique<gui::ConnectionFrequencyWindow>(app, static_cast<ApplicationSettingsNew *>(app));
        });
        attachPopups(
            {gui::popup::ID::Volume, gui::popup::ID::TetheringPhoneModeChangeProhibited, gui::popup::ID::Tethering});
        attachPopups({gui::popup::ID::Volume,
                      gui::popup::ID::TetheringPhoneModeChangeProhibited,
                      gui::popup::ID::Tethering,
                      gui::popup::ID::PhoneModes});
    }

    void ApplicationSettingsNew::destroyUserInterface()

M module-apps/application-settings-new/ApplicationSettings.hpp => module-apps/application-settings-new/ApplicationSettings.hpp +2 -1
@@ 180,6 180,7 @@ namespace app
      public:
        explicit ApplicationSettingsNew(std::string name                    = name_settings_new,
                                        std::string parent                  = {},
                                        sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                                        StartInBackground startInBackground = {false});
        ~ApplicationSettingsNew() override;
        auto DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) -> sys::MessagePointer override;


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

M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +5 -2
@@ 41,8 41,11 @@ namespace gui::window::name

namespace app
{
    ApplicationSettings::ApplicationSettings(std::string name, std::string parent, StartInBackground startInBackground)
        : Application(name, parent, startInBackground)
    ApplicationSettings::ApplicationSettings(std::string name,
                                             std::string parent,
                                             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) {

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

#ifndef MODULE_APPS_APPLICATION_SETTINGS_APPLICATIONSETTINGS_HPP_


@@ 35,6 35,7 @@ namespace app
      public:
        ApplicationSettings(std::string name                    = name_settings,
                            std::string parent                  = {},
                            sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                            StartInBackground startInBackground = {false});
        virtual ~ApplicationSettings();
        sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;


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

M module-apps/application-special-input/ApplicationSpecialInput.cpp => module-apps/application-special-input/ApplicationSpecialInput.cpp +3 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ApplicationSpecialInput.hpp"


@@ 14,8 14,9 @@ namespace

ApplicationSpecialInput::ApplicationSpecialInput(std::string name,
                                                 std::string parent,
                                                 sys::phone_modes::PhoneMode mode,
                                                 StartInBackground startInBackground)
    : Application(name, parent, startInBackground, SpecialInputAppStackDepth)
    : Application(name, parent, mode, startInBackground, SpecialInputAppStackDepth)
{
    addActionReceiver(manager::actions::ShowSpecialInput, [this](auto &&data) {
        switchWindow(app::char_select, std::move(data));

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

#pragma once


@@ 21,6 21,7 @@ namespace app

        ApplicationSpecialInput(std::string name                    = special_input,
                                std::string parent                  = {},
                                sys::phone_modes::PhoneMode mode    = sys::phone_modes::PhoneMode::Connected,
                                StartInBackground startInBackground = {true});
        virtual ~ApplicationSpecialInput() = default;



@@ 39,7 40,7 @@ namespace app
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::ShowSpecialInput}};
            return {{manager::actions::ShowSpecialInput, manager::actions::PhoneModeChanged}};
        }
    };
}; // namespace app

M module-apps/popups/TetheringPhoneModePopup.cpp => module-apps/popups/TetheringPhoneModePopup.cpp +2 -2
@@ 4,7 4,7 @@
#include "TetheringPhoneModePopup.hpp"
#include "DialogMetadataMessage.hpp"
#include "Application.hpp"
#include "SystemManager/messages/TetheringPhoneModeChangeProhibitedMessage.hpp"
#include "data/PopupRequestParams.hpp"
#include <service-appmgr/Controller.hpp>

namespace gui


@@ 20,7 20,7 @@ namespace gui
        metadata.text   = utils::translateI18("tethering_phone_mode_change_prohibited");
        metadata.icon   = "info_big_circle_W_G";
        metadata.action = [this]() {
            auto params = std::make_unique<app::PopupRequestParams>(gui::popup::ID::TetheringPhoneModeChangeProhibited);
            auto params = std::make_unique<gui::PopupRequestParams>(gui::popup::ID::TetheringPhoneModeChangeProhibited);
            app::manager::Controller::sendAction(application, app::manager::actions::AbortPopup, std::move(params));
            return true;
        };

A module-apps/popups/data/PhoneModeParams.hpp => module-apps/popups/data/PhoneModeParams.hpp +27 -0
@@ 0,0 1,27 @@
// 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/Popups.hpp"

#include <service-appmgr/Actions.hpp>
#include <module-sys/PhoneModes/Common.hpp>

namespace gui
{
    class PhoneModeParams : public app::manager::actions::ActionParams
    {
      public:
        explicit PhoneModeParams(sys::phone_modes::PhoneMode mode) : phoneMode{mode}
        {}

        [[nodiscard]] auto getPhoneMode() const noexcept
        {
            return phoneMode;
        }

      private:
        sys::phone_modes::PhoneMode phoneMode;
    };
} // namespace gui

A module-apps/popups/data/PopupRequestParams.hpp => module-apps/popups/data/PopupRequestParams.hpp +44 -0
@@ 0,0 1,44 @@
// 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/Popups.hpp"

#include <service-appmgr/Actions.hpp>
#include <module-sys/PhoneModes/Common.hpp>

namespace gui
{
    class PopupRequestParams : public app::manager::actions::ActionParams
    {
      public:
        explicit PopupRequestParams(gui::popup::ID popupId)
            : app::manager::actions::ActionParams{"Popup request parameters"}, popupId{popupId}
        {}

        [[nodiscard]] auto getPopupId() const noexcept
        {
            return popupId;
        }

      private:
        gui::popup::ID popupId;
    };

    class PhoneModePopupRequestParams : public PopupRequestParams
    {
      public:
        explicit PhoneModePopupRequestParams(sys::phone_modes::PhoneMode mode)
            : PopupRequestParams{gui::popup::ID::PhoneModes}, phoneMode{mode}
        {}

        [[nodiscard]] auto getPhoneMode() const noexcept
        {
            return phoneMode;
        }

      private:
        sys::phone_modes::PhoneMode phoneMode;
    };
} // namespace gui

M module-services/service-antenna/ServiceAntenna.cpp => module-services/service-antenna/ServiceAntenna.cpp +8 -9
@@ 78,15 78,14 @@ ServiceAntenna::ServiceAntenna()
    bus.channels.push_back(sys::BusChannel::PhoneModeChanges);

    phoneModeObserver->connect(this);
    phoneModeObserver->subscribe(
        [=]([[maybe_unused]] sys::phone_modes::PhoneMode mode, sys::phone_modes::Tethering tethering) {
            if (mode == sys::phone_modes::PhoneMode::Offline) {
                this->handleLockRequest(antenna::lockState::locked);
            }
            else {
                this->handleLockRequest(antenna::lockState::unlocked);
            }
        });
    phoneModeObserver->subscribe([this](sys::phone_modes::PhoneMode mode) {
        if (mode == sys::phone_modes::PhoneMode::Offline) {
            handleLockRequest(antenna::lockState::locked);
        }
        else {
            handleLockRequest(antenna::lockState::unlocked);
        }
    });
}

ServiceAntenna::~ServiceAntenna()

M module-services/service-appmgr/model/ApplicationHandle.cpp => module-services/service-appmgr/model/ApplicationHandle.cpp +5 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <service-appmgr/model/ApplicationHandle.hpp>


@@ 58,14 58,14 @@ namespace app::manager
        return manifest.contains(action);
    }

    void ApplicationHandle::run(sys::Service *caller)
    void ApplicationHandle::run(sys::phone_modes::PhoneMode mode, sys::Service *caller)
    {
        launcher->run(caller);
        launcher->run(mode, caller);
    }

    void ApplicationHandle::runInBackground(sys::Service *caller)
    void ApplicationHandle::runInBackground(sys::phone_modes::PhoneMode mode, sys::Service *caller)
    {
        launcher->runBackground(caller);
        launcher->runBackground(mode, caller);
    }

    void ApplicationHandle::close() noexcept

M module-services/service-appmgr/model/ApplicationManager.cpp => module-services/service-appmgr/model/ApplicationManager.cpp +61 -6
@@ 5,6 5,8 @@
#include <service-appmgr/Controller.hpp>

#include <module-apps/messages/AppMessage.hpp>
#include <module-apps/popups/data/PhoneModeParams.hpp>
#include <module-apps/popups/data/PopupRequestParams.hpp>
#include <Common.hpp>
#include <Service/Message.hpp>
#include <module-sys/Timers/TimerFactory.hpp>


@@ 103,6 105,26 @@ namespace app::manager
        return applications.findByName(name);
    }

    auto ApplicationManagerBase::getRunningApplications() noexcept -> std::vector<ApplicationHandle *>
    {
        const auto &stackOfUniqueApps = getStackOfUniqueApplications();
        std::vector<ApplicationHandle *> runningApps;
        std::transform(stackOfUniqueApps.begin(),
                       stackOfUniqueApps.end(),
                       std::back_inserter(runningApps),
                       [this](const auto &appName) { return getApplication(appName); });
        return runningApps;
    }

    auto ApplicationManagerBase::getStackOfUniqueApplications() const -> ApplicationsStack
    {
        auto stackOfUniqueApps = stack;
        std::sort(stackOfUniqueApps.begin(), stackOfUniqueApps.end());
        const auto last = std::unique(stackOfUniqueApps.begin(), stackOfUniqueApps.end());
        stackOfUniqueApps.erase(last, stackOfUniqueApps.end());
        return stackOfUniqueApps;
    }

    ApplicationManager::ApplicationManager(const ApplicationName &serviceName,
                                           std::vector<std::unique_ptr<app::ApplicationLauncher>> &&launchers,
                                           const ApplicationName &_rootApplicationName)


@@ 198,7 220,7 @@ namespace app::manager
    {
        for (const auto &name : std::vector<ApplicationName>{app::name_call, app::special_input}) {
            if (auto app = getApplication(name); app != nullptr) {
                app->runInBackground(this);
                app->runInBackground(phoneModeObserver->getCurrentPhoneMode(), this);
            }
        }
    }


@@ 237,10 259,11 @@ namespace app::manager
    void ApplicationManager::registerMessageHandlers()
    {
        phoneModeObserver->connect(this);
        phoneModeObserver->subscribe(
            [](sys::phone_modes::PhoneMode phoneMode, sys::phone_modes::Tethering tetheringMode) {
                LOG_INFO("Phone mode changed.");
            });
        phoneModeObserver->subscribe([this](sys::phone_modes::PhoneMode phoneMode) {
            handlePhoneModeChanged(phoneMode);
            actionsRegistry.enqueue(
                ActionEntry{actions::ShowPopup, std::make_unique<gui::PhoneModePopupRequestParams>(phoneMode)});
        });

        connect(typeid(StartAllowedMessage), [this](sys::Message *request) {
            auto msg = static_cast<StartAllowedMessage *>(request);


@@ 398,7 421,7 @@ namespace app::manager
        }
        else {
            LOG_INFO("Starting application %s", app.name().c_str());
            app.run(this);
            app.run(phoneModeObserver->getCurrentPhoneMode(), this);
        }
        return true;
    }


@@ 515,6 538,20 @@ namespace app::manager
        actionsRegistry.enqueue(std::move(entry));
    }

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

    void ApplicationManager::changePhoneMode(sys::phone_modes::PhoneMode phoneMode, const ApplicationHandle *app)
    {
        ActionEntry action{actions::PhoneModeChanged, std::make_unique<gui::PhoneModeParams>(phoneMode)};
        action.setTargetApplication(app->name());
        actionsRegistry.enqueue(std::move(action));
    }

    ActionProcessStatus ApplicationManager::handleAction(ActionEntry &action)
    {
        switch (action.actionId) {


@@ 522,6 559,8 @@ namespace app::manager
            return handleHomeAction(action);
        case actions::Launch:
            return handleLaunchAction(action);
        case actions::PhoneModeChanged:
            return handlePhoneModeChangedAction(action);
        case actions::ShowPopup:
            [[fallthrough]];
        case actions::AbortPopup:


@@ 551,6 590,22 @@ namespace app::manager
        return handleSwitchApplication(&switchRequest) ? ActionProcessStatus::Accepted : ActionProcessStatus::Dropped;
    }

    auto ApplicationManager::handlePhoneModeChangedAction(ActionEntry &action) -> ActionProcessStatus
    {
        const auto &targetName = action.target;
        auto targetApp         = getApplication(targetName);
        if (targetApp == nullptr || !targetApp->handles(action.actionId)) {
            return ActionProcessStatus::Dropped;
        }

        if (targetApp->state() == ApplicationHandle::State::ACTIVE_FORGROUND ||
            targetApp->state() == ApplicationHandle::State::ACTIVE_BACKGROUND) {
            app::Application::requestAction(this, targetName, action.actionId, std::move(action.params));
            return ActionProcessStatus::Accepted;
        }
        return ActionProcessStatus::Skipped;
    }

    auto ApplicationManager::handlePopupAction(ActionEntry &action) -> ActionProcessStatus
    {
        auto targetApp = getFocusedApplication();

M module-services/service-appmgr/service-appmgr/Actions.hpp => module-services/service-appmgr/service-appmgr/Actions.hpp +1 -0
@@ 60,6 60,7 @@ namespace app::manager
            DisplayLogoAtExit,
            SMSRejectedByOfflineNotification,
            CallRejectedByOfflineNotification,
            PhoneModeChanged,
            ShowPopup,
            AbortPopup,
            UserAction // The last enumerator in the Action enum.

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

#pragma once


@@ 24,8 24,8 @@ namespace app::manager
        explicit ApplicationHandle(std::unique_ptr<app::ApplicationLauncher> &&_launcher);

        void setState(State state) noexcept;
        void run(sys::Service *caller);
        void runInBackground(sys::Service *caller);
        void run(sys::phone_modes::PhoneMode mode, sys::Service *caller);
        void runInBackground(sys::phone_modes::PhoneMode mode, sys::Service *caller);
        void close() noexcept;

        auto valid() const noexcept -> bool;

M module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp => module-services/service-appmgr/service-appmgr/model/ApplicationManager.hpp +6 -0
@@ 68,6 68,7 @@ namespace app::manager
        auto getLaunchingApplication() const noexcept -> ApplicationHandle *;
        auto getPreviousApplication() const noexcept -> ApplicationHandle *;
        auto getApplication(const ApplicationName &name) const noexcept -> ApplicationHandle *;
        auto getRunningApplications() noexcept -> std::vector<ApplicationHandle *>;
        auto getApplications() const noexcept -> const ApplicationsContainer &
        {
            return applications.getAll();


@@ 85,6 86,8 @@ namespace app::manager
      private:
        using ApplicationsStack = std::deque<ApplicationName>;

        auto getStackOfUniqueApplications() const -> ApplicationsStack;

        State state = State::Running;
        ApplicationsStack stack;
    };


@@ 120,6 123,9 @@ namespace app::manager
        auto handleHomeAction(ActionEntry &action) -> ActionProcessStatus;
        auto handleLaunchAction(ActionEntry &action) -> ActionProcessStatus;
        auto handlePopupAction(ActionEntry &action) -> ActionProcessStatus;
        auto handlePhoneModeChangedAction(ActionEntry &action) -> ActionProcessStatus;
        void handlePhoneModeChanged(sys::phone_modes::PhoneMode phoneMode);
        void changePhoneMode(sys::phone_modes::PhoneMode phoneMode, const ApplicationHandle *app);
        auto handleCustomAction(ActionEntry &action) -> ActionProcessStatus;
        auto handleSwitchApplication(SwitchRequest *msg, bool closeCurrentlyFocusedApp = true) -> bool;
        auto handleCloseConfirmation(CloseConfirmation *msg) -> bool;

M module-services/service-audio/ServiceAudio.cpp => module-services/service-audio/ServiceAudio.cpp +2 -5
@@ 165,9 165,7 @@ ServiceAudio::ServiceAudio()
    bus.channels.push_back(sys::BusChannel::PhoneModeChanges);

    phoneModeObserver->connect(this);
    phoneModeObserver->subscribe([&](sys::phone_modes::PhoneMode phoneMode, sys::phone_modes::Tethering tetheringMode) {
        HandlePhoneModeChange(phoneMode, tetheringMode);
    });
    phoneModeObserver->subscribe([&](sys::phone_modes::PhoneMode phoneMode) { HandlePhoneModeChange(phoneMode); });

    connect(typeid(BluetoothDeviceVolumeChanged),
            [this](sys::Message *msg) -> sys::MessagePointer { return handleVolumeChangedOnBluetoothDevice(msg); });


@@ 546,8 544,7 @@ auto ServiceAudio::HandleKeyPressed(const int step) -> std::unique_ptr<AudioKeyP
        audio::RetCode::Success, newVolume, AudioKeyPressedResponse::ShowPopup::True, context);
}

void ServiceAudio::HandlePhoneModeChange(sys::phone_modes::PhoneMode phoneMode,
                                         sys::phone_modes::Tethering tetheringMode)
void ServiceAudio::HandlePhoneModeChange(sys::phone_modes::PhoneMode phoneMode)
{
    LOG_INFO("Phone mode changed to %s", utils::enumToString(phoneMode).c_str());
    for (auto &input : audioMux.GetAllInputs()) {

M module-services/service-audio/service-audio/ServiceAudio.hpp => module-services/service-audio/service-audio/ServiceAudio.hpp +1 -1
@@ 81,7 81,7 @@ class ServiceAudio : public sys::Service
    auto HandleGetFileTags(const std::string &fileName) -> std::unique_ptr<AudioResponseMessage>;
    void HandleNotification(const AudioNotificationMessage::Type &type, const audio::Token &token);
    auto HandleKeyPressed(const int step) -> std::unique_ptr<AudioKeyPressedResponse>;
    void HandlePhoneModeChange(sys::phone_modes::PhoneMode phoneMode, sys::phone_modes::Tethering tetheringMode);
    void HandlePhoneModeChange(sys::phone_modes::PhoneMode phoneMode);
    void MuteCurrentOperation();
    void VibrationUpdate(const audio::PlaybackType &type               = audio::PlaybackType::None,
                         std::optional<audio::AudioMux::Input *> input = std::nullopt);

M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +15 -15
@@ 326,22 326,22 @@ void handleCellularSimNewPinDataMessage(CellularSimNewPinDataMessage *msg)
void ServiceCellular::registerMessageHandlers()
{
    phoneModeObserver->connect(this);
    phoneModeObserver->subscribe(
        [=]([[maybe_unused]] sys::phone_modes::PhoneMode mode, sys::phone_modes::Tethering tethering) {
            using bsp::cellular::USB::setPassthrough;
            using bsp::cellular::USB::PassthroughState;
            setPassthrough(tethering == sys::phone_modes::Tethering::On ? PassthroughState::ENABLED
                                                                        : PassthroughState::DISABLED);

            if (mode == sys::phone_modes::PhoneMode::Offline) {
                this->switchToOffline();
            }
            else {
                if (!this->isModemRadioModuleOn()) {
                    this->turnOnRadioModule();
                }
    phoneModeObserver->subscribe([this](sys::phone_modes::PhoneMode mode) {
        if (mode == sys::phone_modes::PhoneMode::Offline) {
            this->switchToOffline();
        }
        else {
            if (!this->isModemRadioModuleOn()) {
                this->turnOnRadioModule();
            }
        });
        }
    });
    phoneModeObserver->subscribe([](sys::phone_modes::Tethering tethering) {
        using bsp::cellular::USB::setPassthrough;
        using bsp::cellular::USB::PassthroughState;
        setPassthrough(tethering == sys::phone_modes::Tethering::On ? PassthroughState::ENABLED
                                                                    : PassthroughState::DISABLED);
    });

    connect(typeid(CellularSimCardPinLockStateRequestDataMessage),
            [&](sys::Message * /*request*/) -> sys::MessagePointer {

M module-sys/PhoneModes/Common.hpp => module-sys/PhoneModes/Common.hpp +16 -5
@@ 23,27 23,38 @@ namespace sys::phone_modes
    class PhoneModeChanged : public DataMessage
    {
      public:
        PhoneModeChanged(PhoneMode phoneMode, Tethering tetheringMode)
            : DataMessage{MessageType::MessageTypeUninitialized}, phoneMode{phoneMode}, tethering{tetheringMode}
        explicit PhoneModeChanged(PhoneMode phoneMode)
            : DataMessage{MessageType::MessageTypeUninitialized}, phoneMode{phoneMode}
        {}

        [[nodiscard]] auto getPhoneMode() const noexcept
        {
            return phoneMode;
        }

      private:
        PhoneMode phoneMode;
    };

    class TetheringChanged : public DataMessage
    {
      public:
        explicit TetheringChanged(Tethering tetheringMode)
            : DataMessage{MessageType::MessageTypeUninitialized}, tethering{tetheringMode}
        {}

        [[nodiscard]] auto getTetheringMode() const noexcept
        {
            return tethering;
        }

      private:
        PhoneMode phoneMode;
        Tethering tethering;
    };

    class PhoneModeChangedSuccessfully : public ResponseMessage
    class ChangedSuccessfully : public ResponseMessage
    {};

    class PhoneModeChangeFailed : public ResponseMessage
    class ChangeFailed : public ResponseMessage
    {};
} // namespace sys::phone_modes

M module-sys/PhoneModes/Observer.cpp => module-sys/PhoneModes/Observer.cpp +50 -20
@@ 7,20 7,51 @@

namespace sys::phone_modes
{
    namespace
    {
        template <typename F> void onChanged(const F &onChanged, const Observer::OnFinishedCallbacks &onFinished)
        {
            try {
                onChanged();
                if (onFinished.onComplete) {
                    onFinished.onComplete();
                }
            }
            catch (const std::exception &error) {
                if (onFinished.onError) {
                    onFinished.onError(error);
                }
                throw;
            }
        }
    } // namespace

    void Observer::connect(Service *owner)
    {
        owner->connect(typeid(PhoneModeChanged), [this](sys::Message *request) -> sys::MessagePointer {
            return handlePhoneModeChange(static_cast<PhoneModeChanged *>(request));
        });
        owner->connect(typeid(TetheringChanged), [this](sys::Message *request) -> sys::MessagePointer {
            return handleTetheringChange(static_cast<TetheringChanged *>(request));
        });
    }

    void Observer::subscribe(OnPhoneModeChangedCallback &&onChange,
                             OnCompleteCallback &&onComplete,
                             OnErrorCallback &&onError) noexcept
    {
        onPhoneModeChangedCallback           = std::move(onChange);
        onPhoneModeChangeFinished.onComplete = std::move(onComplete);
        onPhoneModeChangeFinished.onError    = std::move(onError);
    }

    void Observer::subscribe(OnChangeCallback &&onChange,
    void Observer::subscribe(OnTetheringChangedCallback &&onChange,
                             OnCompleteCallback &&onComplete,
                             OnErrorCallback &&onError) noexcept
    {
        onChangeCallback   = std::move(onChange);
        onCompleteCallback = std::move(onComplete);
        onErrorCallback    = std::move(onError);
        onTetheringChangedCallback           = std::move(onChange);
        onTetheringChangeFinished.onComplete = std::move(onComplete);
        onTetheringChangeFinished.onError    = std::move(onError);
    }

    bool Observer::isInMode(PhoneMode mode) const noexcept


@@ 41,35 72,34 @@ namespace sys::phone_modes
    sys::MessagePointer Observer::handlePhoneModeChange(PhoneModeChanged *message)
    {
        phoneMode     = message->getPhoneMode();
        tetheringMode = message->getTetheringMode();
        if (!onPhoneModeChangedCallback) {
            LOG_WARN("No subscriber on phone mode change.");
            return MessageNone{};
        }

        try {
            onPhoneModeChanged();
            onChanged([this]() { onPhoneModeChangedCallback(phoneMode); }, onPhoneModeChangeFinished);
        }
        catch (const std::exception &) {
            return std::make_shared<PhoneModeChangeFailed>();
            return std::make_shared<ChangeFailed>();
        }
        return std::make_shared<PhoneModeChangedSuccessfully>();
        return std::make_shared<ChangedSuccessfully>();
    }

    void Observer::onPhoneModeChanged()
    sys::MessagePointer Observer::handleTetheringChange(TetheringChanged *message)
    {
        if (!onChangeCallback) {
        tetheringMode = message->getTetheringMode();
        if (!onTetheringChangedCallback) {
            LOG_WARN("No subscriber on phone mode change.");
            return;
            return MessageNone{};
        }

        try {
            onChangeCallback(phoneMode, tetheringMode);
            if (onCompleteCallback) {
                onCompleteCallback();
            }
            onChanged([this]() { onTetheringChangedCallback(tetheringMode); }, onTetheringChangeFinished);
        }
        catch (const std::exception &error) {
            if (onErrorCallback) {
                onErrorCallback(error);
            }
            throw;
        catch (const std::exception &) {
            return std::make_shared<ChangeFailed>();
        }
        return std::make_shared<ChangedSuccessfully>();
    }
} // namespace sys::phone_modes

M module-sys/PhoneModes/Observer.hpp => module-sys/PhoneModes/Observer.hpp +16 -6
@@ 18,12 18,21 @@ namespace sys::phone_modes
    class Observer
    {
      public:
        using OnChangeCallback   = std::function<void(PhoneMode, Tethering)>;
        using OnPhoneModeChangedCallback = std::function<void(PhoneMode)>;
        using OnTetheringChangedCallback = std::function<void(Tethering)>;
        using OnCompleteCallback = std::function<void()>;
        using OnErrorCallback    = std::function<void(const std::exception &)>;
        struct OnFinishedCallbacks
        {
            OnCompleteCallback onComplete;
            OnErrorCallback onError;
        };

        void connect(Service *owner);
        void subscribe(OnChangeCallback &&onChange,
        void subscribe(OnPhoneModeChangedCallback &&onChange,
                       OnCompleteCallback &&onComplete = {},
                       OnErrorCallback &&onError       = {}) noexcept;
        void subscribe(OnTetheringChangedCallback &&onChange,
                       OnCompleteCallback &&onComplete = {},
                       OnErrorCallback &&onError       = {}) noexcept;



@@ 33,11 42,12 @@ namespace sys::phone_modes

      private:
        sys::MessagePointer handlePhoneModeChange(PhoneModeChanged *message);
        void onPhoneModeChanged();
        sys::MessagePointer handleTetheringChange(TetheringChanged *message);

        OnChangeCallback onChangeCallback;
        OnCompleteCallback onCompleteCallback;
        OnErrorCallback onErrorCallback;
        OnPhoneModeChangedCallback onPhoneModeChangedCallback;
        OnTetheringChangedCallback onTetheringChangedCallback;
        OnFinishedCallbacks onPhoneModeChangeFinished;
        OnFinishedCallbacks onTetheringChangeFinished;
        PhoneMode phoneMode     = PhoneMode::Connected;
        Tethering tetheringMode = Tethering::Off;
    };

M module-sys/PhoneModes/Subject.cpp => module-sys/PhoneModes/Subject.cpp +20 -11
@@ 21,18 21,22 @@ namespace sys::phone_modes

    bool Subject::setMode(PhoneMode _phoneMode, Tethering _tetheringMode)
    {
        const bool changed = changePhoneMode(_phoneMode) || changeTetheringMode(_tetheringMode);
        if (changed) {
            notifyChange();
        const bool phoneModeChanged = changePhoneMode(_phoneMode);
        if (phoneModeChanged) {
            notifyPhoneModeChange();
        }
        return changed;
        const bool tetheringChanged = changeTetheringMode(_tetheringMode);
        if (tetheringChanged) {
            notifyTetheringChange();
        }
        return phoneModeChanged || tetheringChanged;
    }

    bool Subject::setPhoneMode(PhoneMode mode)
    {
        const auto changed = changePhoneMode(mode);
        if (changed) {
            notifyChange();
            notifyPhoneModeChange();
        }
        return changed;
    }


@@ 46,7 50,7 @@ namespace sys::phone_modes
    {
        const auto changed = changeTetheringMode(mode);
        if (changed) {
            notifyChange();
            notifyTetheringChange();
        }
        return changed;
    }


@@ 56,13 60,18 @@ namespace sys::phone_modes
        return std::exchange(tetheringMode, mode) != mode;
    }

    void Subject::notifyChange()
    void Subject::notifyPhoneModeChange()
    {
        LOG_INFO("Phone mode changed to: [%s]. Notifying phone modes observers.",
                 magic_enum::enum_name(phoneMode).data());
        owner->bus.sendMulticast(std::make_shared<PhoneModeChanged>(phoneMode), BusChannel::PhoneModeChanges);
    }

    void Subject::notifyTetheringChange()
    {
        LOG_INFO("Phone modes changed: Phone mode: [%s]; Tethering: [%s]. Notifying phone modes observers.",
                 magic_enum::enum_name(phoneMode).data(),
        LOG_INFO("Tethering mode changed to: [%s]. Notifying phone modes observers.",
                 magic_enum::enum_name(tetheringMode).data());
        auto message = std::make_shared<PhoneModeChanged>(phoneMode, tetheringMode);
        owner->bus.sendMulticast(std::move(message), BusChannel::PhoneModeChanges);
        owner->bus.sendMulticast(std::make_shared<TetheringChanged>(tetheringMode), BusChannel::PhoneModeChanges);
    }
    bool Subject::isTetheringEnabled() const noexcept
    {

M module-sys/PhoneModes/Subject.hpp => module-sys/PhoneModes/Subject.hpp +2 -1
@@ 42,9 42,10 @@ namespace sys::phone_modes
        bool isTetheringEnabled() const noexcept;

      private:
        void notifyChange();
        bool changePhoneMode(PhoneMode mode) noexcept;
        void notifyPhoneModeChange();
        bool changeTetheringMode(Tethering mode) noexcept;
        void notifyTetheringChange();

        Service *owner;
        PhoneMode phoneMode     = PhoneMode::Connected;

M module-sys/SystemManager/messages/TetheringPhoneModeChangeProhibitedMessage.hpp => module-sys/SystemManager/messages/TetheringPhoneModeChangeProhibitedMessage.hpp +1 -1
@@ 19,7 19,7 @@ namespace sys

        std::unique_ptr<app::manager::ActionRequest> toAction() const override
        {
            auto params = std::make_unique<app::PopupRequestParams>(gui::popup::ID::TetheringPhoneModeChangeProhibited);
            auto params = std::make_unique<gui::PopupRequestParams>(gui::popup::ID::TetheringPhoneModeChangeProhibited);
            return std::make_unique<app::manager::ActionRequest>(
                sender, app::manager::actions::ShowPopup, std::move(params));
        }

M module-sys/SystemManager/messages/TetheringQuestionRequest.hpp => module-sys/SystemManager/messages/TetheringQuestionRequest.hpp +4 -2
@@ 5,6 5,8 @@

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

#include <module-apps/popups/data/PopupRequestParams.hpp>

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



@@ 18,7 20,7 @@ namespace sys

        std::unique_ptr<app::manager::ActionRequest> toAction() const override
        {
            auto params = std::make_unique<app::PopupRequestParams>(gui::popup::ID::Tethering);
            auto params = std::make_unique<gui::PopupRequestParams>(gui::popup::ID::Tethering);
            return std::make_unique<app::manager::ActionRequest>(
                sender, app::manager::actions::ShowPopup, std::move(params));
        }


@@ 32,7 34,7 @@ namespace sys

        std::unique_ptr<app::manager::ActionRequest> toAction() const override
        {
            auto params = std::make_unique<app::PopupRequestParams>(gui::popup::ID::Tethering);
            auto params = std::make_unique<gui::PopupRequestParams>(gui::popup::ID::Tethering);
            return std::make_unique<app::manager::ActionRequest>(
                sender, app::manager::actions::AbortPopup, std::move(params));
        }