~aleteoryx/muditaos

69a7c634178d9846e0205dd985d5df03c14133f7 — Lefucjusz 2 years ago e1b7f50
[MOS-1031] Fix Meditation app screen lock

Fix of the issue that Meditation app
would prevent phone from locking on
every screen, though it should do
so only on timer screen.
M module-apps/application-meditation/ApplicationMeditation.cpp => module-apps/application-meditation/ApplicationMeditation.cpp +14 -13
@@ 18,23 18,24 @@ namespace app
                                                 std::string parent,
                                                 StatusIndicators statusIndicators,
                                                 StartInBackground startInBackground)
        : Application{name, parent, statusIndicators, startInBackground}
        : Application{std::move(name), std::move(parent), statusIndicators, startInBackground}
    {}

    auto ApplicationMeditation::InitHandler() -> sys::ReturnCodes
    {
        const auto ret = Application::InitHandler();
        if (ret != sys::ReturnCodes::Success)
        if (ret != sys::ReturnCodes::Success) {
            return ret;
        }

        auto counterVisible =
        const auto counterVisible =
            getLocalSettingsValue(settings::Meditation::showCounter, Constants::Params::defaultCounterVisible);
        auto counterVisibleOnChangeCallback = [this](bool newValue) {
            settings->setValue(
                settings::Meditation::showCounter, utils::to_string(newValue), settings::SettingsScope::AppLocal);
        };

        auto preparationTime                 = std::chrono::seconds(getLocalSettingsValue(
        const auto preparationTime           = std::chrono::seconds(getLocalSettingsValue(
            settings::Meditation::preparationTime, Constants::Params::defaultPreparationTime.count()));
        auto preparationTimeOnChangeCallback = [this](std::chrono::seconds newValue) {
            settings->setValue(settings::Meditation::preparationTime,


@@ 42,8 43,8 @@ namespace app
                               settings::SettingsScope::AppLocal);
        };
        gui::OptionsData::OptionParams params = {
            .preparationTime{std::move(preparationTime), std::move(preparationTimeOnChangeCallback)},
            .showCounter{std::move(counterVisible), std::move(counterVisibleOnChangeCallback)}};
            .preparationTime{preparationTime, std::move(preparationTimeOnChangeCallback)},
            .showCounter{counterVisible, std::move(counterVisibleOnChangeCallback)}};

        state = std::make_unique<gui::OptionsData>(std::move(params));



@@ 55,7 56,7 @@ namespace app
    auto ApplicationMeditation::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
        -> sys::MessagePointer
    {
        auto retMsg = Application::DataReceivedHandler(msgl);
        const auto retMsg = Application::DataReceivedHandler(msgl);
        // if message was handled by application's template there is no need to process further.
        if (retMsg && (dynamic_cast<sys::ResponseMessage *>(retMsg.get())->retCode == sys::ReturnCodes::Success)) {
            return retMsg;


@@ 64,7 65,7 @@ namespace app
        return handleAsyncResponse(resp);
    }

    auto ApplicationMeditation::SwitchPowerModeHandler(sys::ServicePowerMode mode) -> sys::ReturnCodes
    auto ApplicationMeditation::SwitchPowerModeHandler([[maybe_unused]] sys::ServicePowerMode mode) -> sys::ReturnCodes
    {
        return sys::ReturnCodes::Success;
    }


@@ 73,13 74,13 @@ namespace app
    {
        windowsFactory.attach(
            app::window::name::meditation_main_window, [&](ApplicationCommon *app, const std::string &name) {
                auto durationInitValue =
                const auto durationInitValue =
                    getLocalSettingsValue(settings::Meditation::duration, Constants::Params::defaultMeditationDuration);
                auto durationOnChangeCallback = [this](std::int32_t newValue) {
                    settings->setValue(
                        settings::Meditation::duration, utils::to_string(newValue), settings::SettingsScope::AppLocal);
                };
                auto intervalChimeInitValue        = std::chrono::minutes(getLocalSettingsValue(
                const auto intervalChimeInitValue  = std::chrono::minutes(getLocalSettingsValue(
                    settings::Meditation::intervalChime, Constants::Params::defaultChimeInterval.count()));
                auto intervalChimeOnChangeCallback = [this](std::chrono::minutes newValue) {
                    settings->setValue(settings::Meditation::intervalChime,


@@ 87,9 88,9 @@ namespace app
                                       settings::SettingsScope::AppLocal);
                };
                MeditationParams params = {
                    .meditationDuration{.initValue        = std::move(durationInitValue),
                    .meditationDuration{.initValue        = durationInitValue,
                                        .onChangeCallback = std::move(durationOnChangeCallback)},
                    .intervalChime{.initValue        = std::move(intervalChimeInitValue),
                    .intervalChime{.initValue        = intervalChimeInitValue,
                                   .onChangeCallback = std::move(intervalChimeOnChangeCallback)}};

                return std::make_unique<gui::MeditationWindow>(app, std::move(params));


@@ 121,7 122,7 @@ namespace app
    template <typename T>
    T ApplicationMeditation::getLocalSettingsValue(const std::string &variableName, T defaultValue)
    {
        const std::string value = settings->getValue(variableName, settings::SettingsScope::AppLocal);
        const auto &value = settings->getValue(variableName, settings::SettingsScope::AppLocal);
        return value.empty() ? defaultValue : utils::getNumericValue<T>(value);
    }
} // namespace app

M module-apps/application-meditation/include/application-meditation/ApplicationMeditation.hpp => module-apps/application-meditation/include/application-meditation/ApplicationMeditation.hpp +1 -2
@@ 42,8 42,7 @@ namespace app
            return {{manager::actions::Launch,
                     manager::actions::PhoneModeChanged,
                     manager::actions::BluetoothModeChanged,
                     manager::actions::AlarmClockStatusChanged},
                    locks::AutoLockPolicy::PreventPermanently};
                     manager::actions::AlarmClockStatusChanged}};
        }
    };
} // namespace app

M module-apps/application-meditation/windows/MeditationTimerWindow.cpp => module-apps/application-meditation/windows/MeditationTimerWindow.cpp +45 -38
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "MeditationTimer.hpp"


@@ 38,8 38,8 @@ void MeditationTimerWindow::rebuild()

void MeditationTimerWindow::buildInterface()
{
    auto app = dynamic_cast<app::ApplicationMeditation *>(application);
    assert(app != nullptr); // Pre-condition check.
    const auto app = dynamic_cast<app::ApplicationMeditation *>(application);
    assert(app != nullptr);

    AppWindow::buildInterface();
    setTitle(utils::translate("app_meditation_title_main"));


@@ 57,6 57,8 @@ void MeditationTimerWindow::buildInterface()
                              style::meditation::timer::infoText::Width,
                              style::meditation::timer::infoText::Height);
    meditationInfo->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));

    preventsAutoLock = true;
}

void MeditationTimerWindow::destroyInterface()


@@ 65,45 67,47 @@ void MeditationTimerWindow::destroyInterface()
    invalidate();
}

void MeditationTimerWindow::onBeforeShow(ShowMode mode, SwitchData *data)
void MeditationTimerWindow::onBeforeShow([[maybe_unused]] ShowMode mode, SwitchData *data)
{
    auto timerData = dynamic_cast<MeditationTimerData *>(data);
    if (timerData != nullptr) {
        setVisiblePreparation();
        meditationTime           = timerData->getMeditationTime();
        meditationIntervalPeriod = timerData->getMeditationIntervals();

        auto onPreparation = [&]() -> void {
            setVisibleRunning();
            auto onMeditationEnd = [&]() -> void {
                // Workaround for the issue of phone self-unlocking after meditation has ended.
                // If the phone was manually locked on meditation timer screen, the window stack
                // is as follows: MainWindow->Timer->PhoneLockPopup.
                // setVisibleMeditationEnd() triggers window switch to MainWindow, so Timer and
                // PhoneLockPopup are getting dropped. This workaround prevents such behaviour
                // when phone is locked, in such case only meditation timer window is being dropped.
                if (application->getCurrentWindow()->getName() == gui::popup::window::phone_lock_window) {
                    application->popWindow(app::window::name::meditation_timer);
                }
                else {
                    setVisibleMeditationEnd();
                    application->refreshWindow(RefreshModes::GUI_REFRESH_DEEP);
                }
                timer->playSound();
            };
            timer->getTimer().registerOnFinishedCallback(onMeditationEnd);
            timer->getTimer().reset(meditationTime, meditationIntervalPeriod);
            timer->getTimer().start();
            timer->getProgress().setMaximum(meditationTime.count());
    const auto timerData = dynamic_cast<MeditationTimerData *>(data);
    if (timerData == nullptr) {
        return;
    }

    setVisiblePreparation();
    meditationTime           = timerData->getMeditationTime();
    meditationIntervalPeriod = timerData->getMeditationIntervals();

    auto onPreparation = [&]() -> void {
        setVisibleRunning();
        auto onMeditationEnd = [&]() -> void {
            // Workaround for the issue of phone self-unlocking after meditation has ended.
            // If the phone was manually locked on meditation timer screen, the window stack
            // is as follows: MainWindow->Timer->PhoneLockPopup.
            // setVisibleMeditationEnd() triggers window switch to MainWindow, so Timer and
            // PhoneLockPopup are getting dropped. This workaround prevents such behaviour
            // when phone is locked, in such case only meditation timer window is being dropped.
            if (application->getCurrentWindow()->getName() == gui::popup::window::phone_lock_window) {
                application->popWindow(app::window::name::meditation_timer);
            }
            else {
                setVisibleMeditationEnd();
                application->refreshWindow(RefreshModes::GUI_REFRESH_DEEP);
            }
            timer->playSound();
            application->refreshWindow(RefreshModes::GUI_REFRESH_DEEP);
        };
        timer->getTimer().registerOnFinishedCallback(onPreparation);
        timer->getTimer().reset(timerData->getPreparationTime());
        timer->getTimer().registerOnFinishedCallback(std::move(onMeditationEnd));
        timer->getTimer().reset(meditationTime, meditationIntervalPeriod);
        timer->getTimer().start();
        timer->getProgress().setMaximum(timerData->getPreparationTime().count());
        timer->setCounterVisible(timerData->isCounterEnabled());
    }
        timer->getProgress().setMaximum(meditationTime.count());
        timer->playSound();
        application->refreshWindow(RefreshModes::GUI_REFRESH_DEEP);
    };
    timer->getTimer().registerOnFinishedCallback(std::move(onPreparation));
    timer->getTimer().reset(timerData->getPreparationTime());
    timer->getTimer().start();
    timer->getProgress().setMaximum(timerData->getPreparationTime().count());
    timer->setCounterVisible(timerData->isCounterEnabled());
}

auto MeditationTimerWindow::onInput(const InputEvent &inputEvent) -> bool


@@ 147,6 151,7 @@ void MeditationTimerWindow::setWidgetVisible(bool sBar, bool bBar, bool counter)
    navBar->setActive(nav_bar::Side::Left, bBar);
    timer->setVisible(counter);
}

void MeditationTimerWindow::setVisibleRunning()
{
    setWidgetVisible(false, true, true);


@@ 154,12 159,14 @@ void MeditationTimerWindow::setVisibleRunning()
    navBar->setText(nav_bar::Side::Right, utils::translate(style::strings::common::stop));
    meditationInfo->setVisible(false);
}

void MeditationTimerWindow::setVisiblePaused()
{
    setWidgetVisible(true, true, true);
    navBar->setText(nav_bar::Side::Center, utils::translate(style::strings::common::resume));
    navBar->setText(nav_bar::Side::Right, utils::translate(style::strings::common::stop));
}

void MeditationTimerWindow::setVisiblePreparation()
{
    setWidgetVisible(false, false, false);

M module-apps/application-meditation/windows/MeditationWindow.cpp => module-apps/application-meditation/windows/MeditationWindow.cpp +1 -1
@@ 16,7 16,7 @@

namespace gui
{
    MeditationWindow::MeditationWindow(app::ApplicationCommon *app, const MeditationParams params)
    MeditationWindow::MeditationWindow(app::ApplicationCommon *app, const MeditationParams &params)
        : AppWindow{app, name::window::main_window}, meditationParams(params)
    {
        MeditationWindow::buildInterface();

M module-apps/application-meditation/windows/MeditationWindow.hpp => module-apps/application-meditation/windows/MeditationWindow.hpp +1 -1
@@ 14,7 14,7 @@ namespace gui
    class MeditationWindow : public AppWindow
    {
      public:
        MeditationWindow(app::ApplicationCommon *app, const MeditationParams params);
        MeditationWindow(app::ApplicationCommon *app, const MeditationParams &params);

        auto onInput(const InputEvent &inputEvent) -> bool override;


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

#include "LockPolicyHandler.hpp"


@@ 47,10 47,12 @@ void LockPolicyHandler::setPreventsAutoLockByStateCallback(
{
    preventsAutoLockByStateCallback = std::move(_preventsAutoLockByStateCallback);
}

bool LockPolicyHandler::preventsAutoLockByWindow()
{
    return owner->getCurrentWindow()->preventsAutoLocking();
}

bool LockPolicyHandler::preventsAutoLockByState() const
{
    Expects(preventsAutoLockByStateCallback != nullptr);

M module-gui/gui/core/FontManager.cpp => module-gui/gui/core/FontManager.cpp +1 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FontManager.hpp"


@@ 167,7 167,6 @@ namespace gui

    FontManager &FontManager::getInstance()
    {

        static FontManager instance;
        if (!instance.initialized) {
            LOG_WARN("Using uninitialized font manager will result in no font loaded");

M pure_changelog.md => pure_changelog.md +1 -0
@@ 38,6 38,7 @@
* Fixed showing "Copy text" option in empty note
* Fixed "Copy" option missing from the options list in "New message" window
* Fixed losing unsaved data on go back
* Fixed disabled screen autolock in meditation app

## [1.7.2 2023-07-28]