~aleteoryx/muditaos

bd4db9e1b5d4759bf1335454da804ac30d1e878e — Wojciech Rzepecki 4 years ago 24e87ec
[EGD-7960] Fix of concurrent alarms handling

fixed the processing of alarms set to the same time
also taking into account concurrent snoozes
M module-apps/apps-common/popups/presenter/AlarmPresenter.cpp => module-apps/apps-common/popups/presenter/AlarmPresenter.cpp +3 -2
@@ 40,8 40,9 @@ namespace app::popup

    template <typename requestType, typename responseType> void AlarmPopupContract::AlarmModel::snoozeAlarm()
    {
        auto request =
            std::make_unique<requestType>(record->ID, TimePointNow() + std::chrono::minutes(record->snoozeDuration));
        auto request = std::make_unique<requestType>(record->ID,
                                                     std::chrono::floor<std::chrono::minutes>(TimePointNow()) +
                                                         std::chrono::minutes(record->snoozeDuration));
        auto task = async(std::move(request), service::name::service_time);
        auto cb   = [&](auto response) {
            auto result = dynamic_cast<responseType *>(response);

M module-services/service-time/AlarmOperations.cpp => module-services/service-time/AlarmOperations.cpp +15 -3
@@ 136,6 136,9 @@ namespace alarms
        }
        switchAlarmExecution(*(*found), false);
        ongoingSingleEvents.erase(found);

        processOngoingEvents();

        handleActiveAlarmsCountChange();
        callback(true);
    }


@@ 193,6 196,8 @@ namespace alarms
        switchAlarmExecution(*(*found), false);
        ongoingSingleEvents.erase(found);

        processOngoingEvents();

        handleSnoozedAlarmsCountChange();
        handleActiveAlarmsCountChange();



@@ 280,13 285,20 @@ namespace alarms
            processSnoozedEventsQueue(now);
        }

        if (!isHandlingInProgress && !ongoingSingleEvents.empty()) {
        if (!isHandlingInProgress) {
            processOngoingEvents();
            return true;
        }
        return false;
    }

    void AlarmOperationsCommon::processOngoingEvents()
    {
        if (!ongoingSingleEvents.empty()) {
            switchAlarmExecution(*(ongoingSingleEvents.front()), true);
            handleActiveAlarmsCountChange();
            handleSnoozedAlarmsCountChange();
            return true;
        }
        return false;
    }

    void AlarmOperationsCommon::addAlarmExecutionHandler(const alarms::AlarmType type,

M module-services/service-time/AlarmOperations.hpp => module-services/service-time/AlarmOperations.hpp +1 -0
@@ 141,6 141,7 @@ namespace alarms
        void checkAndUpdateCache(AlarmEventRecord record);
        void switchAlarmExecution(const SingleEventRecord &singleAlarmEvent, bool newStateOn);
        bool processEvents(TimePoint now);
        void processOngoingEvents();
        void processNextEventsQueue(const TimePoint now);
        void processSnoozedEventsQueue(const TimePoint now);
        virtual void onAlarmTurnedOff(const std::shared_ptr<AlarmEventRecord> &event, alarms::AlarmType alarmType);

M module-services/service-time/tests/tests-AlarmOperations.cpp => module-services/service-time/tests/tests-AlarmOperations.cpp +40 -0
@@ 608,3 608,43 @@ TEST_F(AlarmOperationsFixture, recurrentAlarmEnablingDisabling)
    alarmOperations->updateAlarm(alarmRecord, universalBoolCallback);
    EXPECT_FALSE(alarmActive);
}

TEST_F(AlarmOperationsFixture, handleMultipleConcurrentAlarms)
{
    auto alarmRepoMock         = std::make_unique<MockAlarmEventsRepository>();
    const auto alarmTime       = TimePointFromStringWithShift("2022-11-11 11:00:00");
    const auto alarmTimeSnooze = TimePointFromStringWithShift("2022-11-11 11:10:00");
    alarmRepoMock->nextRecords.push_back(
        AlarmEventRecord(1, AlarmTime{11h, 0min}, defMusic, defEnabled, defSnooze, defRRule));
    alarmRepoMock->nextRecords.push_back(
        AlarmEventRecord(2, AlarmTime{11h, 0min}, defMusic, defEnabled, defSnooze, defRRule));
    alarmRepoMock->nextRecords.push_back(
        AlarmEventRecord(3, AlarmTime{11h, 0min}, defMusic, defEnabled, defSnooze, defRRule));

    auto alarmOperations = getMockedAlarmOperations(alarmRepoMock);
    auto handler         = std::make_shared<MockAlarmHandler>();
    EXPECT_CALL(*handler, handle(testing::_)).Times(6);
    alarmOperations->addAlarmExecutionHandler(alarms::AlarmType::Clock, handler);

    int snoozedCount   = 0;
    auto countcallback = [&](unsigned count) { snoozedCount = count; };
    alarmOperations->addSnoozedAlarmsCountChangeCallback(countcallback);
    bool alarmActive    = false;
    auto activeCallback = [&](bool isAnyActive) { alarmActive = isAnyActive; };
    alarmOperations->addActiveAlarmCountChangeCallback(activeCallback);

    alarmOperations->updateEventsCache(TimePointFromStringWithShift("2022-11-11 08:59:00"));

    alarmOperations->minuteUpdated(alarmTime);
    alarmOperations->snoozeRingingAlarm(1, alarmTimeSnooze, universalBoolCallback);
    alarmOperations->snoozeRingingAlarm(2, alarmTimeSnooze, universalBoolCallback);
    alarmOperations->snoozeRingingAlarm(3, alarmTimeSnooze, universalBoolCallback);
    EXPECT_EQ(snoozedCount, 3);
    EXPECT_TRUE(alarmActive);

    alarmOperations->minuteUpdated(alarmTimeSnooze);
    EXPECT_EQ(snoozedCount, 0);
    alarmOperations->turnOffRingingAlarm(1, universalBoolCallback);
    alarmOperations->turnOffRingingAlarm(2, universalBoolCallback);
    alarmOperations->turnOffRingingAlarm(3, universalBoolCallback);
}