~aleteoryx/muditaos

c77a104f3d781b7fb93773be5a2b5af6b97b2a8c — Maciej Gibowicz 1 year, 7 months ago b1648fb
[BH-1991] Creating a new application "What`s new"

We create a new "what's new" application, which starts after the update
is completed and when the saved version number is different from the
current one.
M module-services/service-appmgr/model/ApplicationManagerCommon.cpp => module-services/service-appmgr/model/ApplicationManagerCommon.cpp +2 -0
@@ 24,6 24,7 @@
#include <service-eink/ServiceEink.hpp>
#include <service-evtmgr/EventManagerCommon.hpp>
#include <AppWindowConstants.hpp>
#include <product/version.hpp>

#include <algorithm>
#include <utility>


@@ 485,6 486,7 @@ namespace app::manager
    {
        settings->setValue(
            settings::SystemProperties::onboardingDone, utils::to_string(true), settings::SettingsScope::Global);
        settings->setValue(settings::SystemProperties::osCurrentVersion, VERSION, settings::SettingsScope::Global);
        app::manager::Controller::sendAction(this, app::manager::actions::Home);
        return sys::msgHandled();
    }

M products/BellHybrid/BellHybridMain.cpp => products/BellHybrid/BellHybridMain.cpp +2 -0
@@ 14,6 14,7 @@
#include <application-bell-settings/ApplicationBellSettings.hpp>
#include <application-bell-powernap/ApplicationBellPowerNap.hpp>
#include <application-bell-focus-timer/ApplicationFocusTimer.hpp>
#include <application-bell-whats-new/ApplicationWhatsNew.hpp>

// modules
#include <module-db/databases/MultimediaFilesDB.hpp>


@@ 113,6 114,7 @@ int main()
                app::CreateLauncher<app::ApplicationBellRelaxation>(app::applicationBellRelaxationName));
            applications.push_back(app::CreateLauncher<app::MeditationTimer>(app::applicationMeditationTimerName));
            applications.push_back(app::CreateLauncher<app::ApplicationFocusTimer>(app::applicationFocusTimerName));
            applications.push_back(app::CreateLauncher<app::ApplicationWhatsNew>(app::applicationWhatsNewName));
            // start application manager
            return sysmgr->RunSystemService(
                std::make_shared<app::manager::ApplicationManager>(

M products/BellHybrid/CMakeLists.txt => products/BellHybrid/CMakeLists.txt +1 -0
@@ 56,6 56,7 @@ target_link_libraries(BellHybrid
        bell::app-focus-timer
        bell::app-powernap
        bell::app-settings
        bell::app-whats-new
        bell::db
        bell::audio
        bell::evtmgr

M products/BellHybrid/apps/CMakeLists.txt => products/BellHybrid/apps/CMakeLists.txt +1 -0
@@ 31,4 31,5 @@ add_subdirectory(application-bell-meditation-timer)
add_subdirectory(application-bell-settings)
add_subdirectory(application-bell-powernap)
add_subdirectory(application-bell-focus-timer)
add_subdirectory(application-bell-whats-new)
add_subdirectory(common)

A products/BellHybrid/apps/application-bell-whats-new/ApplicationWhatsNew.cpp => products/BellHybrid/apps/application-bell-whats-new/ApplicationWhatsNew.cpp +81 -0
@@ 0,0 1,81 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ApplicationWhatsNew.hpp"
#include "WhatsNewCommon.hpp"

#include "windows/WhatsNewWindow.hpp"
#include "presenter/WhatsNewPresenter.hpp"
#include "models/WhatsNewModel.hpp"

#include <common/windows/AppsBatteryStatusWindow.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>

namespace app
{
    ApplicationWhatsNew::ApplicationWhatsNew(std::string name,
                                             std::string parent,
                                             StatusIndicators statusIndicators,
                                             StartInBackground startInBackground,
                                             std::uint32_t stackDepth)
        : Application(std::move(name), std::move(parent), statusIndicators, startInBackground, stackDepth)
    {}

    ApplicationWhatsNew::~ApplicationWhatsNew()
    {
        cpuSentinel->BlockWfiMode(false);
    }

    sys::ReturnCodes ApplicationWhatsNew::InitHandler()
    {
        auto ret = Application::InitHandler();
        if (ret != sys::ReturnCodes::Success) {
            return ret;
        }

        whatsNewModel = std::make_unique<whatsNew::models::WhatsNewModel>();

        batteryModel                 = std::make_unique<app::BatteryModel>(this);
        lowBatteryInfoModel          = std::make_unique<app::LowBatteryInfoModel>();
        cpuSentinel                  = std::make_shared<sys::CpuSentinel>(applicationWhatsNewName, this);
        auto sentinelRegistrationMsg = std::make_shared<sys::SentinelRegistrationMessage>(cpuSentinel);
        bus.sendUnicast(std::move(sentinelRegistrationMsg), service::name::system_manager);
        cpuSentinel->BlockWfiMode(true);

        createUserInterface();

        return sys::ReturnCodes::Success;
    }

    void ApplicationWhatsNew::createUserInterface()
    {
        windowsFactory.attach(whatsNew::window::name::main, [this](ApplicationCommon *app, const std::string &name) {
            auto presenter = std::make_unique<app::whatsNew::WhatsNewPresenter>(*batteryModel, *lowBatteryInfoModel);
            return std::make_unique<whatsNew::WhatsNewWindow>(app, std::move(presenter));
        });

        windowsFactory.attach(whatsNew::window::name::whatsNewLowBattery,
                              [](ApplicationCommon *app, const std::string &name) {
                                  return std::make_unique<gui::AppsBatteryStatusWindow>(app, name);
                              });

        attachPopups({gui::popup::ID::AlarmActivated,
                      gui::popup::ID::AlarmDeactivated,
                      gui::popup::ID::PowerOff,
                      gui::popup::ID::Reboot,
                      gui::popup::ID::BedtimeNotification,
                      gui::popup::ID::ChargingNotification,
                      gui::popup::ID::ChargingDoneNotification});
    }

    sys::MessagePointer ApplicationWhatsNew::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
    {
        auto retMsg = Application::DataReceivedHandler(msgl);
        if (auto response = dynamic_cast<sys::ResponseMessage *>(retMsg.get());
            response != nullptr && response->retCode == sys::ReturnCodes::Success) {
            return retMsg;
        }

        return handleAsyncResponse(resp);
    }
} // namespace app

A products/BellHybrid/apps/application-bell-whats-new/CMakeLists.txt => products/BellHybrid/apps/application-bell-whats-new/CMakeLists.txt +40 -0
@@ 0,0 1,40 @@
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

add_library(application-bell-whats-new STATIC)
add_library(bell::app-whats-new ALIAS application-bell-whats-new)

target_include_directories(application-bell-whats-new
    PRIVATE
        $<BUILD_INTERFACE:
            ${CMAKE_CURRENT_SOURCE_DIR}
            include/application-bell-whats-new
            data
            models
            presenter
            windows
        >
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

target_sources(application-bell-whats-new
    PRIVATE
        ApplicationWhatsNew.cpp
        
        windows/WhatsNewWindow.cpp
        presenter/WhatsNewPresenter.cpp
        models/WhatsNewModel.cpp

    PUBLIC
        include/application-bell-whats-new/ApplicationWhatsNew.hpp
)

target_link_libraries(application-bell-whats-new
    PRIVATE
        bell::paths
        bell::db

    PUBLIC
        module-gui
)

A products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewCommon.hpp => products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewCommon.hpp +16 -0
@@ 0,0 1,16 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <AppWindowConstants.hpp>

namespace app::whatsNew
{
    namespace window::name
    {
        inline constexpr auto main               = gui::name::window::main_window;
        inline constexpr auto whatsNewLowBattery = "WhatsNewLowBatteryWindow";
    } // namespace window::name

} // namespace app::whatsNew

A products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewStyle.hpp => products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewStyle.hpp +10 -0
@@ 0,0 1,10 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Style.hpp>
#include "widgets/BellBaseLayout.hpp"

namespace app::whatsNew
{} // namespace app::whatsNew

A products/BellHybrid/apps/application-bell-whats-new/include/application-bell-whats-new/ApplicationWhatsNew.hpp => products/BellHybrid/apps/application-bell-whats-new/include/application-bell-whats-new/ApplicationWhatsNew.hpp +58 -0
@@ 0,0 1,58 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <Application.hpp>
#include <common/models/BatteryModel.hpp>
#include <common/models/LowBatteryInfoModel.hpp>

namespace app::whatsNew::models
{
    class WhatsNewModel;
} // namespace app::whatsNew::models

namespace app
{
    inline constexpr auto applicationWhatsNewName      = "ApplicationWhatsNew";
    inline constexpr auto applicationWhatsNewStackSize = 1024 * 8;

    class ApplicationWhatsNew : public Application
    {
      public:
        ApplicationWhatsNew(std::string name                    = applicationWhatsNewName,
                            std::string parent                  = "",
                            StatusIndicators statusIndicators   = StatusIndicators{},
                            StartInBackground startInBackground = false,
                            std::uint32_t stackDepth            = applicationWhatsNewStackSize);
        ~ApplicationWhatsNew();
        sys::ReturnCodes InitHandler() override;

        void createUserInterface() override;
        void destroyUserInterface() override
        {}

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

        sys::ReturnCodes SwitchPowerModeHandler([[maybe_unused]] const sys::ServicePowerMode mode) override final
        {
            return sys::ReturnCodes::Success;
        }

      private:
        std::unique_ptr<whatsNew::models::WhatsNewModel> whatsNewModel;

        std::unique_ptr<AbstractBatteryModel> batteryModel;
        std::unique_ptr<AbstractLowBatteryInfoModel> lowBatteryInfoModel;
        std::shared_ptr<sys::CpuSentinel> cpuSentinel;
    };

    template <>
    struct ManifestTraits<ApplicationWhatsNew>
    {
        static auto GetManifest() -> manager::ApplicationManifest
        {
            return {{manager::actions::Launch}};
        }
    };
} // namespace app

A products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.cpp => products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.cpp +11 -0
@@ 0,0 1,11 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "WhatsNewModel.hpp"

namespace app::whatsNew::models
{
    WhatsNewModel::WhatsNewModel()
    {}

} // namespace app::whatsNew::models

A products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.hpp => products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.hpp +13 -0
@@ 0,0 1,13 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

namespace app::whatsNew::models
{
    class WhatsNewModel
    {
      public:
        WhatsNewModel();
    };
} // namespace app::whatsNew::models

A products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.cpp => products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.cpp +37 -0
@@ 0,0 1,37 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "WhatsNewPresenter.hpp"

namespace app::whatsNew
{
    WhatsNewPresenter::WhatsNewPresenter(AbstractBatteryModel &batteryModel,
                                         AbstractLowBatteryInfoModel &lowBatteryInfoModel)
        : batteryModel{batteryModel}, lowBatteryInfoModel{lowBatteryInfoModel}
    {}

    Store::Battery WhatsNewPresenter::getBatteryState()
    {
        return batteryModel.getLevelState();
    }

    bool WhatsNewPresenter::isBatteryCharging(Store::Battery::State state) const
    {
        return batteryModel.isBatteryCharging(state);
    }

    bool WhatsNewPresenter::isBatteryBelowLowLevelThreshold(units::SOC soc) const
    {
        return soc < constants::lowBatteryInfoThreshold;
    }

    bool WhatsNewPresenter::isLowBatteryWindowHandled() const
    {
        return lowBatteryInfoModel.isInfoHandled();
    }

    void WhatsNewPresenter::handleLowBatteryWindow()
    {
        lowBatteryInfoModel.handleInfo();
    }
} // namespace app::whatsNew

A products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.hpp => products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.hpp +52 -0
@@ 0,0 1,52 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <apps-common/BasePresenter.hpp>
#include <common/models/BatteryModel.hpp>
#include <common/models/LowBatteryInfoModel.hpp>

namespace app
{
    class ApplicationCommon;
}

namespace app::whatsNew
{
    class WhatsNewContract
    {
      public:
        class View
        {
          public:
            virtual ~View() = default;
        };

        class Presenter : public BasePresenter<WhatsNewContract::View>
        {
          public:
            virtual ~Presenter()                                               = default;
            virtual Store::Battery getBatteryState()                           = 0;
            virtual bool isBatteryCharging(Store::Battery::State state) const  = 0;
            virtual bool isBatteryBelowLowLevelThreshold(units::SOC soc) const = 0;
            [[nodiscard]] virtual bool isLowBatteryWindowHandled() const       = 0;
            virtual void handleLowBatteryWindow()                              = 0;
        };
    };

    class WhatsNewPresenter : public WhatsNewContract::Presenter
    {
        AbstractBatteryModel &batteryModel;
        AbstractLowBatteryInfoModel &lowBatteryInfoModel;

        Store::Battery getBatteryState() override;
        [[nodiscard]] bool isBatteryCharging(Store::Battery::State state) const override;
        [[nodiscard]] bool isBatteryBelowLowLevelThreshold(units::SOC soc) const override;
        [[nodiscard]] bool isLowBatteryWindowHandled() const override;
        void handleLowBatteryWindow() override;

      public:
        WhatsNewPresenter(AbstractBatteryModel &batteryModel, AbstractLowBatteryInfoModel &lowBatteryInfoModel);
    };
} // namespace app::whatsNew

A products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewWindow.cpp => products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewWindow.cpp +35 -0
@@ 0,0 1,35 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "WhatsNewWindow.hpp"

#include <common/options/OptionBellMenu.hpp>
#include <common/data/BatteryStatusSwitchData.hpp>

namespace app::whatsNew
{
    using namespace gui;

    WhatsNewWindow::WhatsNewWindow(app::ApplicationCommon *app,
                                   std::unique_ptr<WhatsNewContract::Presenter> &&presenter,
                                   const std::string &name)
        : AppWindow(app, name), presenter{std::move(presenter)}
    {
        buildInterface();
    }

    void WhatsNewWindow::buildInterface()
    {
        AppWindow::buildInterface();
    }

    void WhatsNewWindow::onBeforeShow(gui::ShowMode mode, gui::SwitchData *data)
    {
        AppWindow::onBeforeShow(mode, data);
    }

    bool WhatsNewWindow::onInput(const gui::InputEvent &inputEvent)
    {
        return AppWindow::onInput(inputEvent);
    }
} // namespace app::whatsNew

A products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewWindow.hpp => products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewWindow.hpp +29 -0
@@ 0,0 1,29 @@
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "WhatsNewCommon.hpp"
#include <presenter/WhatsNewPresenter.hpp>

#include <apps-common/windows/AppWindow.hpp>

namespace app::whatsNew
{
    using namespace gui;

    class WhatsNewWindow : public gui::AppWindow, public WhatsNewContract::View
    {
      public:
        WhatsNewWindow(app::ApplicationCommon *app,
                       std::unique_ptr<WhatsNewContract::Presenter> &&presenter,
                       const std::string &name = window::name::main);

        void buildInterface() override;
        void onBeforeShow(gui::ShowMode mode, gui::SwitchData *data) override;
        bool onInput(const gui::InputEvent &inputEvent) override;

      private:
        std::unique_ptr<WhatsNewContract::Presenter> presenter;
    };
} // namespace app::whatsNew

M products/BellHybrid/services/appmgr/ApplicationManager.cpp => products/BellHybrid/services/appmgr/ApplicationManager.cpp +15 -1
@@ 7,12 7,15 @@
#include <appmgr/messages/ChangeHomescreenLayoutMessage.hpp>
#include <application-bell-main/ApplicationBellMain.hpp>
#include <application-bell-onboarding/BellOnBoardingNames.hpp>
#include <application-bell-whats-new/ApplicationWhatsNew.hpp>
#include <service-appmgr/ServiceApplicationManagerName.hpp>
#include <common/windows/BellWelcomeWindow.hpp>
#include <service-evtmgr/BatteryMessages.hpp>
#include "service-appmgr/Controller.hpp"
#include <service-db/agents/settings/SystemSettings.hpp>
#include <service-appmgr/Controller.hpp>
#include <popups/ChargingNotificationPopupRequestParams.hpp>
#include <popups/ChargingDoneNotificationPopupRequestParams.hpp>
#include <product/version.hpp>

namespace app::manager
{


@@ 38,6 41,9 @@ namespace app::manager
        if (checkOnBoarding()) {
            return app::applicationBellOnBoardingName;
        }
        else if (isWhatsNewAvailable()) {
            return app::applicationWhatsNewName;
        }
        return rootApplicationName;
    }



@@ 118,4 124,12 @@ namespace app::manager
        connect(typeid(BedtimeNotification), convertibleToActionHandler);
        connect(typeid(ChangeHomescreenLayoutMessage), convertibleToActionHandler);
    }

    auto ApplicationManager::isWhatsNewAvailable() -> bool
    {
        const auto lastVersionNumber =
            settings->getValue(settings::SystemProperties::osCurrentVersion, settings::SettingsScope::Global);
        return lastVersionNumber != VERSION;
    }

} // namespace app::manager

M products/BellHybrid/services/appmgr/CMakeLists.txt => products/BellHybrid/services/appmgr/CMakeLists.txt +1 -0
@@ 25,6 25,7 @@ target_link_libraries(appmgr
        module-apps
        application-bell-main
        application-bell-onboarding
        application-bell-whats-new
        service-appmgr
   PUBLIC
        alarms

M products/BellHybrid/services/appmgr/include/appmgr/ApplicationManager.hpp => products/BellHybrid/services/appmgr/include/appmgr/ApplicationManager.hpp +1 -0
@@ 25,5 25,6 @@ namespace app::manager
        auto startApplication(ApplicationHandle &app) -> bool override;
        auto resolveHomeApplication() -> std::string override;
        auto registerMessageHandlers() -> void override;
        auto isWhatsNewAvailable() -> bool;
    };
} // namespace app::manager