~aleteoryx/muditaos

635ad1ac05051ccea1528f4febb35420b46f1bfe — Maciej Gibowicz 2 years ago 2000c3c
[BH-1774] Fix frequency lock during user activity

- Sentinel locks the frequency when pressing buttons and the encoder.
- The "user activity" sentinel will be properly managed by the system
(CpuGovernor) just like other sentinels.
- Adding information about active sentinels in the power management
statistics logs
M harmony_changelog.md => harmony_changelog.md +1 -0
@@ 9,6 9,7 @@
* Fixed uneven screen refresh when turning on the device
* Fixed not disappearing snooze icon when an alarm is deactivated
* Fixed incorrect message after new alarm setting in some scenarios
* Fixed frequency lock during user activity

### Added
* Files not fully transferred via Center will be now removed when USB cable is unplugged

M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +0 -5
@@ 37,7 37,6 @@
#include <list>
#include <ctime>
#include <apps-common/messages/AppMessage.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>
#include <EventStore.hpp>
#include <ticks.hpp>
#include <purefs/filesystem_paths.hpp>


@@ 183,10 182,6 @@ sys::ReturnCodes EventManagerCommon::InitHandler()
    EventWorker->init(settings, eventManagerParams);
    EventWorker->run();

    cpuSentinel                  = std::make_shared<sys::TimedCpuSentinel>(service::name::evt_manager, this);
    auto sentinelRegistrationMsg = std::make_shared<sys::SentinelRegistrationMessage>(cpuSentinel);
    bus.sendUnicast(sentinelRegistrationMsg, service::name::system_manager);

    return sys::ReturnCodes::Success;
}


M module-services/service-evtmgr/service-evtmgr/EventManagerCommon.hpp => module-services/service-evtmgr/service-evtmgr/EventManagerCommon.hpp +1 -2
@@ 14,7 14,6 @@
#include <Service/Worker.hpp>
#include <service-db/DBServiceName.hpp>
#include <Timers/TimerHandle.hpp>
#include <SystemManager/CpuSentinel.hpp>

#include <cstdint>
#include <memory>


@@ 69,7 68,7 @@ class EventManagerCommon : public sys::Service

    std::shared_ptr<settings::Settings> settings;
    std::unique_ptr<WorkerEventCommon> EventWorker;
    std::shared_ptr<sys::TimedCpuSentinel> cpuSentinel;

    // application where key events are sent. This is also only application that is allowed to change keyboard long
    // press settings.
    std::string targetApplication;

M module-sys/SystemManager/CpuGovernor.cpp => module-sys/SystemManager/CpuGovernor.cpp +48 -11
@@ 1,12 1,53 @@
// 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 <SystemManager/CpuGovernor.hpp>
#include <algorithm>
#include <log/log.hpp>
#include "GovernorSentinelOperations.hpp"
#include <sstream>

namespace sys
{
    namespace
    {
        std::string FormatDuration(std::chrono::milliseconds ms)
        {
            using namespace std::chrono;
            auto secs = duration_cast<seconds>(ms);
            auto mins = duration_cast<minutes>(secs);
            secs -= duration_cast<seconds>(mins);
            auto hour = duration_cast<hours>(mins);
            mins -= duration_cast<minutes>(hour);

            std::stringstream ss;
            ss << hour.count() << " Hours : " << mins.count() << " Minutes : " << secs.count() << " Seconds";
            return ss.str();
        }
        void PrintSentinelName(const GovernorSentinelPointer &element)
        {
            auto sentinelWeakPointer = element->GetSentinel();
            if (!sentinelWeakPointer.expired()) {
                std::shared_ptr<CpuSentinel> sharedResource = sentinelWeakPointer.lock();
                LOG_INFO("Sentinel %s", sharedResource->GetName().c_str());
            }
        }
        void PrintActiveSentinel(const GovernorSentinelPointer &element)
        {
            auto sentinelWeakPointer = element->GetSentinel();
            if (!sentinelWeakPointer.expired()) {
                std::shared_ptr<CpuSentinel> sharedResource = sentinelWeakPointer.lock();
                const auto frequencyToHold                  = element->GetRequestedFrequency();
                if (frequencyToHold != bsp::CpuFrequencyMHz::Level_0) {
                    LOG_INFO(
                        "Sentinel %s holds %d MHz for %s",
                        sharedResource->GetName().c_str(),
                        static_cast<int>(frequencyToHold),
                        FormatDuration(static_cast<std::chrono::milliseconds>(sharedResource->getHoldTicks())).c_str());
                }
            }
        }
    } // namespace

    GovernorSentinel::GovernorSentinel(std::shared_ptr<CpuSentinel> newSentinel)
        : sentinelPtr(newSentinel), requestedFrequency(bsp::CpuFrequencyMHz::Level_0)


@@ 76,7 117,12 @@ namespace sys

    void CpuGovernor::PrintAllSentinels() const noexcept
    {
        std::for_each(std::begin(sentinels), std::end(sentinels), PrintName);
        std::for_each(std::begin(sentinels), std::end(sentinels), PrintSentinelName);
    }

    void CpuGovernor::PrintActiveSentinels() const noexcept
    {
        std::for_each(std::begin(sentinels), std::end(sentinels), PrintActiveSentinel);
    }

    void CpuGovernor::SetCpuFrequencyRequest(const std::string &sentinelName, bsp::CpuFrequencyMHz request)


@@ 137,13 183,4 @@ namespace sys

        for_each_sentinel(sentinels, foo);
    }

    void CpuGovernor::PrintName(const GovernorSentinelPointer &element)
    {
        auto sentinelWeakPointer = element->GetSentinel();
        if (!sentinelWeakPointer.expired()) {
            std::shared_ptr<CpuSentinel> sharedResource = sentinelWeakPointer.lock();
            LOG_INFO("Sentinel %s", sharedResource->GetName().c_str());
        }
    }
} // namespace sys

M module-sys/SystemManager/CpuSentinel.cpp => module-sys/SystemManager/CpuSentinel.cpp +18 -10
@@ 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 <SystemManager/CpuSentinel.hpp>


@@ 7,6 7,7 @@
#include "system/Constants.hpp"
#include <Timers/TimerFactory.hpp>
#include <memory>
#include <Utils.hpp>

namespace sys
{


@@ 28,6 29,7 @@ namespace sys

    void CpuSentinel::HoldMinimumFrequency(bsp::CpuFrequencyMHz frequencyToHold)
    {
        holdTicks = xTaskGetTickCount();
        if (currentFrequencyToHold != frequencyToHold) {
            auto msg =
                std::make_shared<sys::HoldCpuFrequencyMessage>(GetName(), frequencyToHold, xTaskGetCurrentTaskHandle());


@@ 67,6 69,21 @@ namespace sys
        currentFrequency = frequencyHz;
    }

    TaskHandle_t CpuSentinel::getTask()
    {
        return owner->GetHandle();
    }

    std::string CpuSentinel::getReason()
    {
        return currentReason;
    }

    TickType_t CpuSentinel::getHoldTicks() const noexcept
    {
        return utils::computeIncrease(xTaskGetTickCount(), holdTicks);
    }

    TimedCpuSentinel::TimedCpuSentinel(std::string name, sys::Service *service)
        : CpuSentinel(name, service), timerHandle{sys::TimerFactory::createSingleShotTimer(
                                          owner, "holdFrequencyTimer", defaultHoldFrequencyTime, [this](sys::Timer &) {


@@ 90,13 107,4 @@ namespace sys
        }
    }

    TaskHandle_t CpuSentinel::getTask()
    {
        return owner->GetHandle();
    }

    std::string CpuSentinel::getReason()
    {
        return currentReason;
    }
} // namespace sys

M module-sys/SystemManager/PowerManager.cpp => module-sys/SystemManager/PowerManager.cpp +1 -0
@@ 216,5 216,6 @@ namespace sys

        taskStatistics.Update();
        taskStatistics.LogCpuUsage();
        cpuGovernor->PrintActiveSentinels();
    }
} // namespace sys

M module-sys/SystemManager/SystemManagerCommon.cpp => module-sys/SystemManager/SystemManagerCommon.cpp +10 -0
@@ 61,6 61,16 @@ namespace sys
        }

    } // namespace

    namespace constants
    {
        using namespace std::chrono_literals;
        inline constexpr std::chrono::milliseconds timerInitInterval{30s};
        inline constexpr std::chrono::milliseconds timerPeriodInterval{100ms};
        inline constexpr std::chrono::milliseconds powerManagerLogsTimerInterval{1h};
        inline constexpr auto restoreTimeout{5000};
    } // namespace constants

    namespace state
    {
        template <typename T>

M module-sys/SystemManager/include/SystemManager/CpuGovernor.hpp => module-sys/SystemManager/include/SystemManager/CpuGovernor.hpp +2 -3
@@ 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

#pragma once


@@ 39,6 39,7 @@ namespace sys
        auto RemoveSentinel(std::string sentinelName) -> void;
        [[nodiscard]] auto GetNumberOfRegisteredSentinels() const noexcept -> uint32_t;
        void PrintAllSentinels() const noexcept;
        void PrintActiveSentinels() const noexcept;

        void SetCpuFrequencyRequest(const std::string &sentinelName, bsp::CpuFrequencyMHz request);
        void ResetCpuFrequencyRequest(const std::string &sentinelName);


@@ 47,8 48,6 @@ namespace sys
        void InformSentinelsAboutCpuFrequencyChange(bsp::CpuFrequencyMHz newFrequency) noexcept;

      private:
        static void PrintName(const GovernorSentinelPointer &element);

        /// this could be set - set is sorted :)
        GovernorSentinelsVector sentinels;
    };

M module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp => module-sys/SystemManager/include/SystemManager/CpuSentinel.hpp +5 -1
@@ 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

#pragma once


@@ 36,6 36,9 @@ namespace sys
        void ReadRegistrationData(bsp::CpuFrequencyMHz frequencyHz);
        TaskHandle_t getTask();
        std::string getReason();

        TickType_t getHoldTicks() const noexcept;

        virtual ~CpuSentinel() = default;

      protected:


@@ 43,6 46,7 @@ namespace sys
        bsp::CpuFrequencyMHz currentFrequencyToHold{bsp::CpuFrequencyMHz::Level_0};
        std::atomic<bsp::CpuFrequencyMHz> currentFrequency{bsp::CpuFrequencyMHz::Level_0};
        sys::Service *owner{nullptr};
        TickType_t holdTicks;

        /// function called from the PowerManager context
        /// to update resources immediately

M module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp => module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp +0 -9
@@ 29,15 29,6 @@ namespace app

namespace sys
{
    namespace constants
    {
        using namespace std::chrono_literals;
        inline constexpr std::chrono::milliseconds timerInitInterval{30s};
        inline constexpr std::chrono::milliseconds timerPeriodInterval{100ms};
        inline constexpr std::chrono::milliseconds powerManagerLogsTimerInterval{1h};
        inline constexpr auto restoreTimeout{5000};
    } // namespace constants

    enum class Code
    {
        CloseSystem,

M products/BellHybrid/services/evtmgr/EventManager.cpp => products/BellHybrid/services/evtmgr/EventManager.cpp +1 -1
@@ 44,7 44,7 @@ EventManager::EventManager(LogDumpFunction logDumpFunction, const std::string &n
                          .voltage{.shutdown            = constants::shutdownVoltageThreshold,
                                   .measurementMaxCount = constants::measurementThreshold}},
                         name),
      backlightHandler(settings, this), userActivityHandler(std::make_shared<sys::CpuSentinel>(name, this), this)
      backlightHandler(settings, this), userActivityHandler(this)
{
    buildKeySequences();


M products/BellHybrid/services/evtmgr/include/evtmgr/user-activity-handler/UserActivityHandler.hpp => products/BellHybrid/services/evtmgr/include/evtmgr/user-activity-handler/UserActivityHandler.hpp +2 -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

#pragma once


@@ 12,7 12,7 @@ namespace evm
    class UserActivityHandler
    {
      public:
        UserActivityHandler(std::shared_ptr<sys::CpuSentinel> cpuSentinel, sys::Service *parent);
        UserActivityHandler(sys::Service *parent);

        void handleUserInput();


M products/BellHybrid/services/evtmgr/user-activity-handler/UserActivityHandler.cpp => products/BellHybrid/services/evtmgr/user-activity-handler/UserActivityHandler.cpp +10 -4
@@ 1,8 1,10 @@
// 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 <evtmgr/user-activity-handler/UserActivityHandler.hpp>
#include <Timers/TimerFactory.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>
#include <system/Constants.hpp>

namespace evm
{


@@ 10,15 12,19 @@ namespace evm
    {
        constexpr auto userActivityTimerTime = std::chrono::seconds(10);
        constexpr auto userActivityCPULevel  = bsp::CpuFrequencyMHz::Level_5;
        constexpr auto sentinelName          = "UserActivity";
    } // namespace

    UserActivityHandler::UserActivityHandler(std::shared_ptr<sys::CpuSentinel> cpuSentinel, sys::Service *parent)
        : cpuSentinel{std::move(cpuSentinel)},
    UserActivityHandler::UserActivityHandler(sys::Service *parent)
        : cpuSentinel(std::make_shared<sys::CpuSentinel>(sentinelName, parent)),
          activityTimer{sys::TimerFactory::createSingleShotTimer(
              parent, "UserActivityTimer", userActivityTimerTime, [this]([[maybe_unused]] sys::Timer &timer) {
                  onUserActivityTimeout();
              })}
    {}
    {
        auto sentinelRegistrationMsg = std::make_shared<sys::SentinelRegistrationMessage>(cpuSentinel);
        parent->bus.sendUnicast(std::move(sentinelRegistrationMsg), service::name::system_manager);
    }

    void UserActivityHandler::handleUserInput()
    {

M products/PurePhone/services/evtmgr/include/evtmgr/EventManager.hpp => products/PurePhone/services/evtmgr/include/evtmgr/EventManager.hpp +1 -1
@@ 22,7 22,7 @@ class EventManager : public EventManagerCommon
                        .measurementMaxCount = constants::measurementThreshold}},
              name),
          vibrator(std::make_unique<vibra_handle::Vibra>(this)), backlightHandler(settings, this),
          userActivityHandler(std::make_shared<sys::CpuSentinel>(name, this), this)
          userActivityHandler(this)
    {}

  private:

M products/PurePhone/services/evtmgr/include/evtmgr/UserActivityHandler.hpp => products/PurePhone/services/evtmgr/include/evtmgr/UserActivityHandler.hpp +2 -2
@@ 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

#pragma once


@@ 12,7 12,7 @@ namespace evm
    class UserActivityHandler
    {
      public:
        UserActivityHandler(std::shared_ptr<sys::CpuSentinel> cpuSentinel, sys::Service *parent);
        UserActivityHandler(sys::Service *parent);

        void handleUserInput();


M products/PurePhone/services/evtmgr/user-activity-handler/UserActivityHandler.cpp => products/PurePhone/services/evtmgr/user-activity-handler/UserActivityHandler.cpp +10 -4
@@ 1,8 1,10 @@
// 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 <evtmgr/UserActivityHandler.hpp>
#include <Timers/TimerFactory.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>
#include <system/Constants.hpp>

namespace evm
{


@@ 10,15 12,19 @@ namespace evm
    {
        constexpr auto userActivityTimerTime = std::chrono::seconds(2);
        constexpr auto userActivityCPULevel  = bsp::CpuFrequencyMHz::Level_4;
        constexpr auto sentinelName          = "UserActivity";
    } // namespace

    UserActivityHandler::UserActivityHandler(std::shared_ptr<sys::CpuSentinel> cpuSentinel, sys::Service *parent)
        : cpuSentinel{std::move(cpuSentinel)},
    UserActivityHandler::UserActivityHandler(sys::Service *parent)
        : cpuSentinel(std::make_shared<sys::CpuSentinel>(sentinelName, parent)),
          activityTimer{sys::TimerFactory::createSingleShotTimer(
              parent, "UserActivityTimer", userActivityTimerTime, [this]([[maybe_unused]] sys::Timer &timer) {
                  onUserActivityTimeout();
              })}
    {}
    {
        auto sentinelRegistrationMsg = std::make_shared<sys::SentinelRegistrationMessage>(cpuSentinel);
        parent->bus.sendUnicast(std::move(sentinelRegistrationMsg), service::name::system_manager);
    }

    void UserActivityHandler::handleUserInput()
    {

M pure_changelog.md => pure_changelog.md +1 -0
@@ 50,6 50,7 @@
* Fixed phone number input style unification
* Fixed disappearing selections when setting custom alarm after popup is shown
* Fixed alarm preview playback behavior
* Fixed frequency lock during user activity

## [1.7.2 2023-07-28]