summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/AlarmClock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/utils/AlarmClock.cpp')
-rw-r--r--xbmc/utils/AlarmClock.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/xbmc/utils/AlarmClock.cpp b/xbmc/utils/AlarmClock.cpp
new file mode 100644
index 0000000..f37f828
--- /dev/null
+++ b/xbmc/utils/AlarmClock.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "AlarmClock.h"
+
+#include "ServiceBroker.h"
+#include "dialogs/GUIDialogKaiToast.h"
+#include "events/EventLog.h"
+#include "events/NotificationEvent.h"
+#include "guilib/LocalizeStrings.h"
+#include "log.h"
+#include "messaging/ApplicationMessenger.h"
+#include "utils/StringUtils.h"
+
+#include <mutex>
+#include <utility>
+
+using namespace std::chrono_literals;
+
+CAlarmClock::CAlarmClock() : CThread("AlarmClock")
+{
+}
+
+CAlarmClock::~CAlarmClock() = default;
+
+void CAlarmClock::Start(const std::string& strName, float n_secs, const std::string& strCommand, bool bSilent /* false */, bool bLoop /* false */)
+{
+ // make lower case so that lookups are case-insensitive
+ std::string lowerName(strName);
+ StringUtils::ToLower(lowerName);
+ Stop(lowerName);
+ SAlarmClockEvent event;
+ event.m_fSecs = static_cast<double>(n_secs);
+ event.m_strCommand = strCommand;
+ event.m_loop = bLoop;
+ if (!m_bIsRunning)
+ {
+ StopThread();
+ Create();
+ m_bIsRunning = true;
+ }
+
+ uint32_t labelAlarmClock;
+ uint32_t labelStarted;
+ if (StringUtils::EqualsNoCase(strName, "shutdowntimer"))
+ {
+ labelAlarmClock = 20144;
+ labelStarted = 20146;
+ }
+ else
+ {
+ labelAlarmClock = 13208;
+ labelStarted = 13210;
+ }
+
+ EventPtr alarmClockActivity(new CNotificationEvent(
+ labelAlarmClock,
+ StringUtils::Format(g_localizeStrings.Get(labelStarted), static_cast<int>(event.m_fSecs) / 60,
+ static_cast<int>(event.m_fSecs) % 60)));
+
+ auto eventLog = CServiceBroker::GetEventLog();
+ if (eventLog)
+ {
+ if (bSilent)
+ eventLog->Add(alarmClockActivity);
+ else
+ eventLog->AddWithNotification(alarmClockActivity);
+ }
+
+ event.watch.StartZero();
+ std::unique_lock<CCriticalSection> lock(m_events);
+ m_event.insert(make_pair(lowerName,event));
+ CLog::Log(LOGDEBUG, "started alarm with name: {}", lowerName);
+}
+
+void CAlarmClock::Stop(const std::string& strName, bool bSilent /* false */)
+{
+ std::unique_lock<CCriticalSection> lock(m_events);
+
+ std::string lowerName(strName);
+ StringUtils::ToLower(lowerName); // lookup as lowercase only
+ std::map<std::string,SAlarmClockEvent>::iterator iter = m_event.find(lowerName);
+
+ if (iter == m_event.end())
+ return;
+
+ uint32_t labelAlarmClock;
+ if (StringUtils::EqualsNoCase(strName, "shutdowntimer"))
+ labelAlarmClock = 20144;
+ else
+ labelAlarmClock = 13208;
+
+ std::string strMessage;
+ float elapsed = 0.f;
+
+ if (iter->second.watch.IsRunning())
+ elapsed = iter->second.watch.GetElapsedSeconds();
+
+ if (elapsed > static_cast<float>(iter->second.m_fSecs))
+ strMessage = g_localizeStrings.Get(13211);
+ else
+ {
+ float remaining = static_cast<float>(iter->second.m_fSecs) - elapsed;
+ strMessage = StringUtils::Format(g_localizeStrings.Get(13212), static_cast<int>(remaining) / 60,
+ static_cast<int>(remaining) % 60);
+ }
+
+ if (iter->second.m_strCommand.empty() || static_cast<float>(iter->second.m_fSecs) > elapsed)
+ {
+ EventPtr alarmClockActivity(new CNotificationEvent(labelAlarmClock, strMessage));
+ auto eventLog = CServiceBroker::GetEventLog();
+ if (eventLog)
+ {
+ if (bSilent)
+ eventLog->Add(alarmClockActivity);
+ else
+ eventLog->AddWithNotification(alarmClockActivity);
+ }
+ }
+ else
+ {
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr,
+ iter->second.m_strCommand);
+ if (iter->second.m_loop)
+ {
+ iter->second.watch.Reset();
+ return;
+ }
+ }
+
+ iter->second.watch.Stop();
+ m_event.erase(iter);
+}
+
+void CAlarmClock::Process()
+{
+ while( !m_bStop)
+ {
+ std::string strLast;
+ {
+ std::unique_lock<CCriticalSection> lock(m_events);
+ for (std::map<std::string,SAlarmClockEvent>::iterator iter=m_event.begin();iter != m_event.end(); ++iter)
+ if (iter->second.watch.IsRunning() &&
+ iter->second.watch.GetElapsedSeconds() >= static_cast<float>(iter->second.m_fSecs))
+ {
+ Stop(iter->first);
+ if ((iter = m_event.find(strLast)) == m_event.end())
+ break;
+ }
+ else
+ strLast = iter->first;
+ }
+ CThread::Sleep(100ms);
+ }
+}
+