~aleteoryx/muditaos

bc6b79fea673ee2f9b5d318f95a061d6d503e0ad — Wojtek Rzepecki 4 years ago ce51ed0
[EGD-7673] Fix adding alarm before actual time

Fixed adding of an alarm before actual
system time
M module-apps/application-alarm-clock/models/AlarmsModel.cpp => module-apps/application-alarm-clock/models/AlarmsModel.cpp +9 -0
@@ 47,6 47,7 @@ namespace app::alarmClock
        auto item               = new gui::AlarmItem(std::make_shared<AlarmRRulePresenter>(record));
        item->activatedCallback = [this, record](gui::Item &) {
            record->enabled = !record->enabled;
            onAlarmEnableChange(record);
            alarmsRepository->update(*record, nullptr);
            return true;
        };


@@ 78,4 79,12 @@ namespace app::alarmClock

        return updateRecords(records);
    }

    void AlarmsModel::onAlarmEnableChange(const std::shared_ptr<AlarmEventRecord> record)
    {
        if (record->enabled) {
            record->startDate = GetFollowingDayTime(record->startDate, std::chrono::system_clock::now());
        }
    }

} // namespace app::alarmClock

M module-apps/application-alarm-clock/models/AlarmsModel.hpp => module-apps/application-alarm-clock/models/AlarmsModel.hpp +1 -0
@@ 33,6 33,7 @@ namespace app::alarmClock

      private:
        bool onAlarmsRetrieved(const std::vector<AlarmEventRecord> &records, unsigned int alarmsRepoCount);
        void onAlarmEnableChange(const std::shared_ptr<AlarmEventRecord> record);
        std::shared_ptr<AbstractAlarmsRepository> alarmsRepository;
    };
} // namespace app::alarmClock

M module-apps/application-alarm-clock/widgets/AlarmTimeItem.cpp => module-apps/application-alarm-clock/widgets/AlarmTimeItem.cpp +2 -1
@@ 128,7 128,8 @@ namespace gui
            }
            newTime->tm_min = utils::toNumeric(minuteInput->getText());

            record->startDate = TimePointFloorMinutes(std::chrono::system_clock::from_time_t(std::mktime(newTime)));
            auto alarmTime    = TimePointFloorMinutes(std::chrono::system_clock::from_time_t(std::mktime(newTime)));
            record->startDate = GetFollowingDayTime(alarmTime, std::chrono::system_clock::now());
            record->endDate   = record->startDate;
        };


M module-utils/time/test/CMakeLists.txt => module-utils/time/test/CMakeLists.txt +9 -0
@@ 15,6 15,15 @@ add_catch2_executable(
    LIBS
        utils-time
)

add_catch2_executable(
    NAME
        utils-dateCommon
    SRCS
        unittest_dateCommon.cpp
    LIBS
        utils-time
)
# time tests
add_catch2_executable(
    NAME

A module-utils/time/test/unittest_dateCommon.cpp => module-utils/time/test/unittest_dateCommon.cpp +47 -0
@@ 0,0 1,47 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>

#include <time/dateCommon.hpp>

TEST_CASE("Get date after given time")
{
    auto givenTime   = TimePointFromString("2022-11-11 11:00:00");
    auto timeBefore1 = TimePointFromString("2022-11-11 10:59:01");
    auto timeBefore2 = TimePointFromString("2022-11-05 10:59:01");
    auto timeBefore3 = TimePointFromString("2022-11-05 15:59:01");
    auto timeBefore4 = TimePointFromString("1999-01-05 10:59:01");

    auto timeAfter1 = TimePointFromString("2022-11-11 11:00:01");
    auto timeAfter2 = TimePointFromString("2022-11-12 11:00:01");
    auto timeAfter3 = TimePointFromString("2022-11-12 10:59:01");
    auto timeAfter4 = TimePointFromString("2222-11-12 11:59:01");

    SECTION("Time Before")
    {
        auto result = GetFollowingDayTime(givenTime, givenTime);
        REQUIRE(result == TimePointFromString("2022-11-12 11:00:00"));
        result = GetFollowingDayTime(timeBefore1, givenTime);
        REQUIRE(result == TimePointFromString("2022-11-12 10:59:01"));
        result = GetFollowingDayTime(timeBefore2, givenTime);
        REQUIRE(result == TimePointFromString("2022-11-12 10:59:01"));
        result = GetFollowingDayTime(timeBefore3, givenTime);
        REQUIRE(result == TimePointFromString("2022-11-11 15:59:01"));
        result = GetFollowingDayTime(timeBefore4, givenTime);
        REQUIRE(result == TimePointFromString("2022-11-12 10:59:01"));
    }

    SECTION("Time After")
    {
        auto result = GetFollowingDayTime(timeAfter1, givenTime);
        REQUIRE(result == timeAfter1);
        result = GetFollowingDayTime(timeAfter2, givenTime);
        REQUIRE(result == TimePointFromString("2022-11-11 11:00:01"));
        result = GetFollowingDayTime(timeAfter3, givenTime);
        REQUIRE(result == timeAfter3);
        result = GetFollowingDayTime(timeAfter4, givenTime);
        REQUIRE(result == TimePointFromString("2022-11-11 11:59:01"));
    }
}

M module-utils/time/time/dateCommon.hpp => module-utils/time/time/dateCommon.hpp +18 -0
@@ 349,6 349,24 @@ inline TimePoint TimePointFloorMinutes(const TimePoint &tp)
    return std::chrono::floor<std::chrono::minutes>(tp);
}

/// Returns TimePoint within 24h after relative time based on tp as source of daytime
inline TimePoint GetFollowingDayTime(const TimePoint &tp, const TimePoint &relativeTime)
{
    auto diff = relativeTime - tp;
    if (diff > std::chrono::hours{0}) {
        return tp + std::chrono::ceil<date::days>(diff);
    }
    else if (diff == std::chrono::hours{0}) {
        return tp + date::days{1};
    }
    else if (diff < std::chrono::hours{0} && std::chrono::abs(diff) > std::chrono::hours{24}) {
        return tp - std::chrono::floor<date::days>(std::chrono::abs(diff));
    }
    else {
        return tp;
    }
}

inline std::string createUID()
{
    constexpr uint32_t bufferLimit = 16;

M products/PurePhone/alarms/CMakeLists.txt => products/PurePhone/alarms/CMakeLists.txt +2 -0
@@ 4,11 4,13 @@ add_library(pure::alarms ALIAS alarms)
target_sources(alarms
    PRIVATE
        PureAlarmHandler.cpp
        src/actions/AlarmRecordAction.cpp
        src/actions/PlayAudioActions.cpp
        src/actions/NotifyGUIAction.cpp

        include/AbstractAlarmAction.hpp
        include/PureAlarmHandler.hpp
        src/actions/AlarmRecordAction.hpp
        src/actions/PlayAudioActions.hpp
        src/actions/NotifyGUIAction.hpp
    PUBLIC

M products/PurePhone/alarms/PureAlarmHandler.cpp => products/PurePhone/alarms/PureAlarmHandler.cpp +2 -0
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PureAlarmHandler.hpp"
#include "src/actions/AlarmRecordAction.hpp"
#include "src/actions/PlayAudioActions.hpp"
#include "src/actions/NotifyGUIAction.hpp"



@@ 36,6 37,7 @@ namespace alarms
    auto PureAlarmClockHandler::getActions(sys::Service *service) -> Actions
    {
        Actions actions;
        actions.emplace_back(std::make_unique<AlarmRecordAction>(*service));
        actions.emplace_back(std::make_unique<PlayToneAction>(*service));
        actions.emplace_back(std::make_unique<NotifyGUIAction>(*service));
        return actions;

A products/PurePhone/alarms/src/actions/AlarmRecordAction.cpp => products/PurePhone/alarms/src/actions/AlarmRecordAction.cpp +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

#include "AlarmRecordAction.hpp"
#include <AlarmEventRecord.hpp>
#include <service-time/AlarmServiceAPI.hpp>

namespace alarms
{
    AlarmRecordAction::AlarmRecordAction(sys::Service &service) : service{service}
    {}

    bool AlarmRecordAction::execute(const AlarmEventRecord &record)
    {
        return true;
    }

    bool AlarmRecordAction::turnOff(const AlarmEventRecord &record)
    {
        if (record.rruleText.empty()) {
            auto updatedRecord    = record;
            updatedRecord.enabled = false;
            AlarmServiceAPI::requestUpdateAlarm(&service, updatedRecord);
        }
        return true;
    }
} // namespace alarms

A products/PurePhone/alarms/src/actions/AlarmRecordAction.hpp => products/PurePhone/alarms/src/actions/AlarmRecordAction.hpp +23 -0
@@ 0,0 1,23 @@
// 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 "AbstractAlarmAction.hpp"

#include <Service/Service.hpp>

namespace alarms
{
    class AlarmRecordAction : public AbstractAlarmAction
    {
      public:
        explicit AlarmRecordAction(sys::Service &service);
        virtual bool execute(const AlarmEventRecord &record) override;
        bool turnOff(const AlarmEventRecord &record) override;

      private:
        sys::Service &service;
    };

} // namespace alarms