diff --git a/assets/webconfig/content/conf_events.html b/assets/webconfig/content/conf_events.html
new file mode 100644
index 00000000..df98b737
--- /dev/null
+++ b/assets/webconfig/content/conf_events.html
@@ -0,0 +1,11 @@
+
+
+
diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json
index 0b238935..c2ff8c2f 100644
--- a/assets/webconfig/i18n/en.json
+++ b/assets/webconfig/i18n/en.json
@@ -192,6 +192,8 @@
"conf_network_tok_intro": "Here you can create and delete tokens for API authentication. Created tokens will only be displayed once.",
"conf_network_tok_lastuse": "Last use",
"conf_network_tok_title": "Token Management",
+ "conf_system_events_heading_title": "System Events",
+ "conf_system_events_intro": "Settings related to diffent Operating System events Hyperion can handle",
"conf_webconfig_label_intro": "Webconfiguration settings. Edit wisely.",
"dashboard_active_instance": "Selected instance",
"dashboard_alert_message_confedit": "Your Hyperion configuration has been modified. To apply it, restart Hyperion.",
@@ -475,6 +477,12 @@
"edt_conf_smooth_updateDelay_title": "Output delay",
"edt_conf_smooth_updateFrequency_expl": "The output speed to your LED controller.",
"edt_conf_smooth_updateFrequency_title": "Update frequency",
+ "edt_conf_system_events_lockEnable_title": "Listen to lock events",
+ "edt_conf_system_events_lockEnable_expl": "Listen to screen lock/unlock events",
+ "edt_conf_system_events_suspendEnable_title": "Listen to suspend events",
+ "edt_conf_system_events_suspendEnable_expl": "Listen to system suspend/resume events",
+ "edt_conf_system_events_suspendOnLockEnable_title": "Suspend when locked",
+ "edt_conf_system_events_suspendOnLockEnable_expl": "Suspend when the screen is locked, otherwise go into idle mode",
"edt_conf_v4l2_blueSignalThreshold_expl": "Darkens low blue values (recognized as black)",
"edt_conf_v4l2_blueSignalThreshold_title": "Blue signal threshold",
"edt_conf_v4l2_cecDetection_expl": "If enabled, USB capture will be temporarily disabled when CEC standby event received from HDMI bus.",
@@ -983,6 +991,8 @@
"main_menu_dashboard_token": "Dashboard",
"main_menu_effect_conf_token": "Effects",
"main_menu_effectsconfigurator_token": "Effects Configurator",
+ "main_menu_events": "Event Services",
+ "main_menu_event_services_token": "Event Services",
"main_menu_general_conf_token": "General",
"main_menu_grabber_conf_token": "Capturing Hardware",
"main_menu_input_selection_token": "Input Selection",
diff --git a/assets/webconfig/index.html b/assets/webconfig/index.html
index 9249eb39..88bf52b3 100644
--- a/assets/webconfig/index.html
+++ b/assets/webconfig/index.html
@@ -280,6 +280,7 @@
System
+ -
-
-
- Update
diff --git a/assets/webconfig/js/content_events.js b/assets/webconfig/js/content_events.js
new file mode 100644
index 00000000..ae78b8d6
--- /dev/null
+++ b/assets/webconfig/js/content_events.js
@@ -0,0 +1,37 @@
+$(document).ready(function () {
+ performTranslation();
+
+ var conf_editor_systemEvents = null;
+
+ if (window.showOptHelp) {
+ //System Events
+ $('#conf_cont').append(createRow('conf_cont_system_events'));
+ $('#conf_cont_system_events').append(createOptPanel('fa-laptop', $.i18n("conf_system_events_heading_title"), 'editor_container_system_events', 'btn_submit_system_events', 'panel-system'));
+ $('#conf_cont_system_events').append(createHelpTable(window.schema.systemEvents.properties, $.i18n("conf_system_events_heading_title")));
+ }
+ else {
+ $('#conf_cont').addClass('row');
+ $('#conf_cont').append(createOptPanel('fa-laptop', $.i18n("conf_system_events_heading_title"), 'editor_container_system_events', 'btn_submit_system_events'));
+ }
+
+ //System Events
+ conf_editor_systemEvents = createJsonEditor('editor_container_system_events', {
+ systemEvents: window.schema.systemEvents
+ }, true, true);
+
+ conf_editor_systemEvents.on('change', function () {
+ conf_editor_systemEvents.validate().length || window.readOnlyMode ? $('#btn_submit_system_events').prop('disabled', true) : $('#btn_submit_system_events').prop('disabled', false);
+ });
+
+ $('#btn_submit_system_events').off().on('click', function () {
+ requestWriteConfig(conf_editor_systemEvents.getValue());
+ });
+
+ //create introduction
+ if (window.showOptHelp) {
+ createHint("intro", $.i18n('conf_system_events_intro'), "editor_container_system_events");
+ }
+
+ removeOverlay();
+});
+
diff --git a/config/hyperion.config.json.default b/config/hyperion.config.json.default
index e1649479..12325cde 100644
--- a/config/hyperion.config.json.default
+++ b/config/hyperion.config.json.default
@@ -248,5 +248,10 @@
"vmax": 0.08,
"vmin": 0
}
- ]
+ ],
+
+ "systemEvents": {
+ "suspendEnable": true,
+ "lockEnable": true
+ }
}
diff --git a/include/db/SettingsTable.h b/include/db/SettingsTable.h
index d7184869..4adad496 100644
--- a/include/db/SettingsTable.h
+++ b/include/db/SettingsTable.h
@@ -112,6 +112,8 @@ public:
list << "jsonServer" << "protoServer" << "flatbufServer" << "forwarder" << "webConfig" << "network"
// capture
<< "framegrabber" << "grabberV4L2" << "grabberAudio"
+ //Events
+ << "systemEvents"
// other
<< "logger" << "general";
diff --git a/include/hyperion/HyperionIManager.h b/include/hyperion/HyperionIManager.h
index 347a9d53..b682a696 100644
--- a/include/hyperion/HyperionIManager.h
+++ b/include/hyperion/HyperionIManager.h
@@ -84,7 +84,13 @@ public slots:
void resume();
///
- /// @brief Toggle the state of all Hyperion instances for an idle sceanrio (user is not interacting with the system
+ /// @brief Toggle the state of all Hyperion instances for a suspend sceanrio (user is not interacting with the system)
+ /// @param isSuspend, If true all instances toggle to suspend, else to resume
+ ///
+ void toggleSuspend(bool isSuspend);
+
+ ///
+ /// @brief Toggle the state of all Hyperion instances for an idle sceanrio
/// @param isIdle, If true all instances toggle to idle, else to resume
///
void toggleIdle(bool isIdle);
diff --git a/include/utils/settings.h b/include/utils/settings.h
index dab90204..64e0d999 100644
--- a/include/utils/settings.h
+++ b/include/utils/settings.h
@@ -30,6 +30,7 @@ namespace settings {
NETWORK,
FLATBUFSERVER,
PROTOSERVER,
+ SYSTEMEVENTS,
INVALID
};
@@ -42,29 +43,30 @@ namespace settings {
{
switch (type)
{
- case BGEFFECT: return "backgroundEffect";
- case FGEFFECT: return "foregroundEffect";
- case BLACKBORDER: return "blackborderdetector";
- case BOBLSERVER: return "boblightServer";
- case COLOR: return "color";
- case DEVICE: return "device";
- case EFFECTS: return "effects";
- case NETFORWARD: return "forwarder";
- case SYSTEMCAPTURE: return "framegrabber";
- case GENERAL: return "general";
- case V4L2: return "grabberV4L2";
- case AUDIO: return "grabberAudio";
- case JSONSERVER: return "jsonServer";
- case LEDCONFIG: return "ledConfig";
- case LEDS: return "leds";
- case LOGGER: return "logger";
- case SMOOTHING: return "smoothing";
- case WEBSERVER: return "webConfig";
- case INSTCAPTURE: return "instCapture";
- case NETWORK: return "network";
- case FLATBUFSERVER: return "flatbufServer";
- case PROTOSERVER: return "protoServer";
- default: return "invalid";
+ case BGEFFECT: return "backgroundEffect";
+ case FGEFFECT: return "foregroundEffect";
+ case BLACKBORDER: return "blackborderdetector";
+ case BOBLSERVER: return "boblightServer";
+ case COLOR: return "color";
+ case DEVICE: return "device";
+ case EFFECTS: return "effects";
+ case NETFORWARD: return "forwarder";
+ case SYSTEMCAPTURE: return "framegrabber";
+ case GENERAL: return "general";
+ case V4L2: return "grabberV4L2";
+ case AUDIO: return "grabberAudio";
+ case JSONSERVER: return "jsonServer";
+ case LEDCONFIG: return "ledConfig";
+ case LEDS: return "leds";
+ case LOGGER: return "logger";
+ case SMOOTHING: return "smoothing";
+ case WEBSERVER: return "webConfig";
+ case INSTCAPTURE: return "instCapture";
+ case NETWORK: return "network";
+ case FLATBUFSERVER: return "flatbufServer";
+ case PROTOSERVER: return "protoServer";
+ case SYSTEMEVENTS: return "systemEvents";
+ default: return "invalid";
}
}
@@ -97,6 +99,7 @@ namespace settings {
else if (type == "network") return NETWORK;
else if (type == "flatbufServer") return FLATBUFSERVER;
else if (type == "protoServer") return PROTOSERVER;
+ else if (type == "systemEvents") return SYSTEMEVENTS;
else return INVALID;
}
}
diff --git a/libsrc/hyperion/HyperionIManager.cpp b/libsrc/hyperion/HyperionIManager.cpp
index 428d7fa0..64ca08d2 100644
--- a/libsrc/hyperion/HyperionIManager.cpp
+++ b/libsrc/hyperion/HyperionIManager.cpp
@@ -83,6 +83,16 @@ void HyperionIManager::resume()
}
}
+void HyperionIManager::toggleSuspend(bool isSuspend)
+{
+ Info(_log,"Put all instances in %s state", isSuspend ? "suspend" : "working");
+ QMap instCopy = _runningInstances;
+ for(const auto instance : instCopy)
+ {
+ emit instance->suspendRequest(isSuspend);
+ }
+}
+
void HyperionIManager::toggleIdle(bool isIdle)
{
Info(_log,"Put all instances in %s state", isIdle ? "idle" : "working");
diff --git a/libsrc/hyperion/hyperion.schema.json b/libsrc/hyperion/hyperion.schema.json
index 12e1ba73..1fa52c8d 100644
--- a/libsrc/hyperion/hyperion.schema.json
+++ b/libsrc/hyperion/hyperion.schema.json
@@ -90,6 +90,10 @@
"leds":
{
"$ref": "schema-leds.json"
+ },
+ "systemEvents":
+ {
+ "$ref": "schema-systemEvents.json"
}
},
"additionalProperties" : false
diff --git a/libsrc/hyperion/resource.qrc b/libsrc/hyperion/resource.qrc
index f1c327cf..f7ea7cad 100644
--- a/libsrc/hyperion/resource.qrc
+++ b/libsrc/hyperion/resource.qrc
@@ -23,5 +23,6 @@
schema/schema-leds.json
schema/schema-instCapture.json
schema/schema-network.json
+ schema/schema-systemEvents.json
diff --git a/libsrc/hyperion/schema/schema-systemEvents.json b/libsrc/hyperion/schema/schema-systemEvents.json
new file mode 100644
index 00000000..6563e7da
--- /dev/null
+++ b/libsrc/hyperion/schema/schema-systemEvents.json
@@ -0,0 +1,34 @@
+{
+ "type" : "object",
+ "required" : true,
+ "title" : "edt_conf_system_events_heading_title",
+ "properties": {
+ "suspendEnable": {
+ "type": "boolean",
+ "required": true,
+ "title": "edt_conf_system_events_suspendEnable_title",
+ "default": true,
+ "propertyOrder": 1
+ },
+ "lockEnable": {
+ "type": "boolean",
+ "required": true,
+ "title": "edt_conf_system_events_lockEnable_title",
+ "default": true,
+ "propertyOrder": 2
+ },
+ "suspendOnLockEnable": {
+ "type": "boolean",
+ "required": false,
+ "title": "edt_conf_system_events_suspendOnLockEnable_title",
+ "default": false,
+ "options": {
+ "dependencies": {
+ "lockEnable": true
+ }
+ },
+ "propertyOrder": 3
+ }
+ },
+ "additionalProperties" : false
+}
diff --git a/src/hyperiond/SuspendHandler.cpp b/src/hyperiond/SuspendHandler.cpp
index b680b3ea..36e6f35e 100644
--- a/src/hyperiond/SuspendHandler.cpp
+++ b/src/hyperiond/SuspendHandler.cpp
@@ -1,36 +1,195 @@
#include "SuspendHandler.h"
#include
+#include
+#include
#include
#include
SuspendHandlerBase::SuspendHandlerBase()
- : _isSuspended(false)
+ : _isSuspendEnabled(false)
+ , _isLockEnabled(false)
+ , _isSuspendOnLock(false)
+ , _isSuspendRegistered(false)
+ , _isLockRegistered(false)
+ , _isSuspended(false)
, _isIdle(false)
, _isLocked (false)
+
{
- // Trigger suspend/resume/idle scenarios to be executed by Instance mMnager
- connect(this, &SuspendHandlerBase::suspendEvent, HyperionIManager::getInstance(), &HyperionIManager::suspend);
- connect(this, &SuspendHandlerBase::resumeEvent, HyperionIManager::getInstance(), &HyperionIManager::resume);
- connect(this, &SuspendHandlerBase::lockedEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
- connect(this, &SuspendHandlerBase::idleEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
-
-
- // Listen to suspend/resume/idle events received by the Instance Manager via API
- connect(HyperionIManager::getInstance(), &HyperionIManager::triggerSuspend, this, QOverload::of(&SuspendHandler::suspend));
- connect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleSuspend, this, &SuspendHandler::toggleSuspend);
- connect(HyperionIManager::getInstance(), &HyperionIManager::triggerIdle, this, &SuspendHandler::idle);
- connect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleIdle, this, &SuspendHandler::toggleIdle);
+ _log = Logger::getInstance("EVENTS");
}
SuspendHandlerBase::~SuspendHandlerBase()
{
+ unregisterLockHandler();
+ unregisterSuspendHandler();
+
+ unregisterIdleApiHandler();
+ unregisterSuspendApiHandler();
+}
+
+void SuspendHandlerBase::handleSettingsUpdate(settings::type type, const QJsonDocument& config)
+{
+ if(type == settings::SYSTEMEVENTS)
+ {
+ const QJsonObject& obj = config.object();
+
+ //Suspend on lock or go into idle mode
+ bool prevIsSuspendOnLock = _isSuspendOnLock;
+ _isSuspendOnLock = obj["suspendOnLockEnable"].toBool(false);
+
+ //Handle OS event related configurations
+ _isSuspendEnabled = obj["suspendEnable"].toBool(true);
+ if (_isSuspendEnabled)
+ {
+ // Listen to suspend/resume/idle events received by the OS
+ registerSuspendHandler();
+ }
+ else
+ {
+ unregisterSuspendHandler();
+ }
+
+ _isLockEnabled = obj["lockEnable"].toBool(true);
+ if (_isLockEnabled || _isSuspendOnLock != prevIsSuspendOnLock)
+ {
+ // Listen to lock/screensaver events received by the OS
+ registerLockHandler();
+ }
+ else
+ {
+ unregisterLockHandler();
+ }
+
+ //Handle API event related configurations
+ _isSuspendApiEnabled = obj["suspendApiEnable"].toBool(true);
+ if (_isSuspendApiEnabled)
+ {
+ // Listen to suspend/resume/idle events received by the OS
+ registerSuspendApiHandler();
+ }
+ else
+ {
+ unregisterSuspendApiHandler();
+ }
+
+ _isIdleApiEnabled = obj["idleApiEnable"].toBool(true);
+ if (_isIdleApiEnabled)
+ {
+ // Listen to lock/screensaver events received by the OS
+ registerIdleApiHandler();
+ }
+ else
+ {
+ unregisterIdleApiHandler();
+ }
+ }
+}
+
+bool SuspendHandlerBase::registerSuspendHandler()
+{
+ Debug(_log, "_isSuspendRegistered: %d", _isSuspendRegistered);
+ if (!_isSuspendRegistered)
+ {
+ connect(this, &SuspendHandlerBase::suspendEvent, HyperionIManager::getInstance(), &HyperionIManager::suspend);
+ connect(this, &SuspendHandlerBase::resumeEvent, HyperionIManager::getInstance(), &HyperionIManager::resume);
+ Info(_log, "Registered for suspend/resume events.");
+ _isSuspendRegistered = true;
+ }
+ return true;
+}
+
+void SuspendHandlerBase::unregisterSuspendHandler()
+{
+ if (_isSuspendRegistered)
+ {
+ disconnect(this, &SuspendHandlerBase::suspendEvent, HyperionIManager::getInstance(), &HyperionIManager::suspend);
+ disconnect(this, &SuspendHandlerBase::resumeEvent, HyperionIManager::getInstance(), &HyperionIManager::resume);
+ Info(_log, "Unregistered for suspend/resume events.");
+ _isSuspendRegistered = false;
+ }
+}
+
+bool SuspendHandlerBase::registerLockHandler()
+{
+ disconnect(this, &SuspendHandlerBase::lockedEvent,nullptr, nullptr);
+ if (_isSuspendOnLock)
+ {
+ connect(this, &SuspendHandlerBase::lockedEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleSuspend);
+ }
+ else
+ {
+ connect(this, &SuspendHandlerBase::lockedEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
+ }
+ connect(this, &SuspendHandlerBase::idleEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
+ Info(_log, "Registered for lock/unlock events. %s on lock event.", _isSuspendOnLock ? "Suspend" : "Idle");
+ _isLockRegistered = true;
+ return true;
+}
+
+void SuspendHandlerBase::unregisterLockHandler()
+{
+ if (_isLockRegistered)
+ {
+ disconnect(this, &SuspendHandlerBase::lockedEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleSuspend);
+ disconnect(this, &SuspendHandlerBase::lockedEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
+ disconnect(this, &SuspendHandlerBase::idleEvent, HyperionIManager::getInstance(), &HyperionIManager::toggleIdle);
+ Info(_log, "Unregistered for lock/unlock events.");
+ _isLockRegistered = false;
+ }
+}
+
+
+bool SuspendHandlerBase::registerSuspendApiHandler()
+{
+ if (!_isSuspendApiRegistered)
+ {
+ connect(HyperionIManager::getInstance(), &HyperionIManager::triggerSuspend, this, QOverload::of(&SuspendHandler::suspend));
+ connect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleSuspend, this, &SuspendHandler::toggleSuspend);
+ Info(_log, "Registered for suspend/resume API events.");
+ _isSuspendApiRegistered = true;
+ }
+ return true;
+}
+
+void SuspendHandlerBase::unregisterSuspendApiHandler()
+{
+ if (_isSuspendApiRegistered)
+ {
+ disconnect(HyperionIManager::getInstance(), &HyperionIManager::triggerSuspend, this, QOverload::of(&SuspendHandler::suspend));
+ disconnect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleSuspend, this, &SuspendHandler::toggleSuspend);
+ Info(_log, "Unregistered for suspend/resume API events.");
+ _isSuspendApiRegistered = false;
+ }
+}
+
+bool SuspendHandlerBase::registerIdleApiHandler()
+{
+ if (!_isIdleApiRegistered)
+ {
+ connect(HyperionIManager::getInstance(), &HyperionIManager::triggerIdle, this, &SuspendHandler::idle);
+ connect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleIdle, this, &SuspendHandler::toggleIdle);
+ Info(_log, "Registered for idle API events.");
+ _isIdleApiRegistered = true;
+ }
+ return true;
+}
+
+void SuspendHandlerBase::unregisterIdleApiHandler()
+{
+ if (_isIdleApiRegistered)
+ {
+ disconnect(HyperionIManager::getInstance(), &HyperionIManager::triggerIdle, this, &SuspendHandler::idle);
+ disconnect(HyperionIManager::getInstance(), &HyperionIManager::triggerToggleIdle, this, &SuspendHandler::toggleIdle);
+ Info(_log, "Unregistered for idle API events.");
+ _isIdleApiRegistered = false;
+ }
}
void SuspendHandlerBase::suspend()
{
- Debug(Logger::getInstance("DAEMON"), "");
suspend(true);
}
@@ -41,39 +200,38 @@ void SuspendHandlerBase::suspend(bool sleep)
if (!_isSuspended)
{
_isSuspended = true;
- Info(Logger::getInstance("DAEMON"), "Suspend event received - Hyperion is going to sleep");
+ Info(_log, "Suspend event received - Hyperion is going to sleep");
emit suspendEvent();
}
else
{
- Debug(Logger::getInstance("DAEMON"), "Suspend event ignored - already suspended");
+ Debug(_log, "Suspend event ignored - already suspended");
}
}
else
{
if (_isSuspended || _isIdle)
{
- Info(Logger::getInstance("DAEMON"), "Resume event received - Hyperion is going into working mode");
+ Info(_log, "Resume event received - Hyperion is going into working mode");
emit resumeEvent();
_isSuspended = false;
_isIdle = false;
}
else
{
- Debug(Logger::getInstance("DAEMON"), "Resume event ignored - not in suspend nor idle mode");
+ Debug(_log, "Resume event ignored - not in suspend nor idle mode");
}
}
}
void SuspendHandlerBase::resume()
{
- Debug(Logger::getInstance("DAEMON"), "");
suspend(false);
}
void SuspendHandlerBase::toggleSuspend()
{
- Debug(Logger::getInstance("DAEMON"), "Toggle suspend event received");
+ Debug(_log, "Toggle suspend event received");
if (!_isSuspended)
{
suspend(true);
@@ -93,7 +251,7 @@ void SuspendHandlerBase::idle(bool isIdle)
if (!_isIdle)
{
_isIdle = true;
- Info(Logger::getInstance("DAEMON"), "Idle event received");
+ Info(_log, "Idle event received");
emit idleEvent(isIdle);
}
}
@@ -101,7 +259,7 @@ void SuspendHandlerBase::idle(bool isIdle)
{
if (_isIdle)
{
- Info(Logger::getInstance("DAEMON"), "Resume from idle event recevied");
+ Info(_log, "Resume from idle event recevied");
emit idleEvent(isIdle);
_isIdle = false;
}
@@ -109,13 +267,13 @@ void SuspendHandlerBase::idle(bool isIdle)
}
else
{
- Debug(Logger::getInstance("DAEMON"), "Idle event ignored - Hyperion is suspended");
+ Debug(_log, "Idle event ignored - Hyperion is suspended");
}
}
void SuspendHandlerBase::toggleIdle()
{
- Debug(Logger::getInstance("DAEMON"), "Toggle idle event received");
+ Debug(_log, "Toggle idle event received");
if (!_isIdle)
{
idle(true);
@@ -135,7 +293,7 @@ void SuspendHandlerBase::lock(bool isLocked)
if (!_isLocked)
{
_isLocked = true;
- Info(Logger::getInstance("DAEMON"), "Screen lock event received");
+ Info(_log, "Screen lock event received");
emit lockedEvent(isLocked);
}
}
@@ -143,7 +301,7 @@ void SuspendHandlerBase::lock(bool isLocked)
{
if (_isLocked)
{
- Info(Logger::getInstance("DAEMON"), "Screen unlock event received");
+ Info(_log, "Screen unlock event received");
emit lockedEvent(isLocked);
_isLocked = false;
}
@@ -151,7 +309,7 @@ void SuspendHandlerBase::lock(bool isLocked)
}
else
{
- Debug(Logger::getInstance("DAEMON"), "Screen lock event ignored - Hyperion is suspended");
+ Debug(_log, "Screen lock event ignored - Hyperion is suspended");
}
}
@@ -165,36 +323,12 @@ void SuspendHandlerBase::lock(bool isLocked)
SuspendHandlerWindows::SuspendHandlerWindows()
{
- auto handle = reinterpret_cast (_widget.winId());
-
- _notifyHandle = RegisterSuspendResumeNotification(handle, DEVICE_NOTIFY_WINDOW_HANDLE);
- if (_notifyHandle != NULL)
- {
- QCoreApplication::instance()->installNativeEventFilter(this);
- }
- else
- {
- Error(Logger::getInstance("DAEMON"), "Could not register for suspend/resume events!");
- }
-
- if (!WTSRegisterSessionNotification(handle, NOTIFY_FOR_THIS_SESSION))
- {
- Error(Logger::getInstance("DAEMON"), "Could not register for lock/unlock events!");
- }
}
SuspendHandlerWindows::~SuspendHandlerWindows()
{
- if (_notifyHandle != NULL)
- {
- QCoreApplication::instance()->removeNativeEventFilter(this);
-
- UnregisterSuspendResumeNotification(_notifyHandle);
-
- auto handle = reinterpret_cast (_widget.winId());
- WTSUnRegisterSessionNotification(handle);
- }
- _notifyHandle = NULL;
+ unregisterLockHandler();
+ unregisterSuspendHandler();
}
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
@@ -238,6 +372,68 @@ bool SuspendHandlerWindows::nativeEventFilter(const QByteArray& eventType, void*
return false;
}
+bool SuspendHandlerWindows::registerSuspendHandler()
+{
+ bool isRegistered {false};
+ if (!_isSuspendRegistered)
+ {
+ auto handle = reinterpret_cast (_widget.winId());
+ _notifyHandle = RegisterSuspendResumeNotification(handle, DEVICE_NOTIFY_WINDOW_HANDLE);
+ if (_notifyHandle != NULL)
+ {
+ QCoreApplication::instance()->installNativeEventFilter(this);
+ isRegistered = SuspendHandlerBase::registerSuspendHandler();
+ }
+ else
+ {
+ Error(_log, "Could not register for suspend/resume events!");
+ }
+ }
+ return isRegistered;
+}
+
+void SuspendHandlerWindows::unregisterSuspendHandler()
+{
+ if (_isSuspendRegistered)
+ {
+ if (_notifyHandle != NULL)
+ {
+ QCoreApplication::instance()->removeNativeEventFilter(this);
+ UnregisterSuspendResumeNotification(_notifyHandle);
+ }
+ _notifyHandle = NULL;
+ SuspendHandlerBase::unregisterSuspendHandler();
+ }
+}
+
+bool SuspendHandlerWindows::registerLockHandler()
+{
+ bool isRegistered {false};
+ if (!_isLockRegistered)
+ {
+ auto handle = reinterpret_cast (_widget.winId());
+ if (WTSRegisterSessionNotification(handle, NOTIFY_FOR_THIS_SESSION))
+ {
+ isRegistered = SuspendHandlerBase::registerLockHandler();
+ }
+ else
+ {
+ Error(_log, "Could not register for lock/unlock events!");
+ }
+ }
+ return isRegistered;
+}
+
+void SuspendHandlerWindows::unregisterLockHandler()
+{
+ if (_isLockRegistered)
+ {
+ auto handle = reinterpret_cast (_widget.winId());
+ WTSUnRegisterSessionNotification(handle);
+ SuspendHandlerBase::unregisterLockHandler();
+ }
+}
+
#elif defined(__linux__) && defined(HYPERION_HAS_DBUS)
#include
@@ -265,48 +461,158 @@ const DbusSignalsMap dbusSignals = {
SuspendHandlerLinux::SuspendHandlerLinux()
{
- QDBusConnection systemBus = QDBusConnection::systemBus();
- if (!systemBus.isConnected())
+}
+
+bool SuspendHandlerLinux::registerSuspendHandler()
+{
+ bool isRegistered {_isSuspendRegistered};
+ if (!_isSuspendRegistered)
{
- Info(Logger::getInstance("DAEMON"), "The suspend/resume feature is not supported by your system configuration");
- }
- else
- {
- QString service = dbusSignals.find("Suspend").value().service;
- if (!systemBus.connect(service,
- dbusSignals.find("Suspend").value().path,
- dbusSignals.find("Suspend").value().interface,
- dbusSignals.find("Suspend").value().name,
- this, SLOT(suspend(bool))))
- Error(Logger::getInstance("DAEMON"), "Could not register for suspend/resume events [%s]!", QSTRING_CSTR(service));
+ QDBusConnection systemBus = QDBusConnection::systemBus();
+ if (!systemBus.isConnected())
+ {
+ Info(_log, "The suspend/resume feature is not supported by your system configuration");
+ }
else
{
- Debug(Logger::getInstance("DAEMON"), "Registered for suspend/resume events [%s].", QSTRING_CSTR(service));
- }
- }
-
- QDBusConnection sessionBus = QDBusConnection::sessionBus();
- if (!sessionBus.isConnected())
- {
- Info(Logger::getInstance("DAEMON"), "The lock/unlock feature is not supported by your system configuration");
- }
- else
- {
- DbusSignalsMap::const_iterator iter = dbusSignals.find("ScreenSaver");
- while (iter != dbusSignals.end() && iter.key() == "ScreenSaver") {
- QString service = iter.value().service;
- if (!sessionBus.connect(service,
- iter.value().path,
- iter.value().interface,
- iter.value().name,
- this, SLOT(lock(bool))))
- Error(Logger::getInstance("DAEMON"), "Could not register for lock/unlock events [%s]!", QSTRING_CSTR(service));
+ QString service = dbusSignals.find("Suspend").value().service;
+ if (systemBus.connect(service,
+ dbusSignals.find("Suspend").value().path,
+ dbusSignals.find("Suspend").value().interface,
+ dbusSignals.find("Suspend").value().name,
+ this, SLOT(suspend(bool))))
+ {
+ Debug(_log, "Registered for suspend/resume events via service: %s", QSTRING_CSTR(service));
+ isRegistered = true;
+ }
else
{
- Debug(Logger::getInstance("DAEMON"), "Registered for lock/unlock events [%s].", QSTRING_CSTR(service));
+ Error(_log, "Could not register for suspend/resume events via service: %s", QSTRING_CSTR(service));
+ }
+ }
+
+ if (isRegistered)
+ {
+ isRegistered = SuspendHandlerBase::registerSuspendHandler();
+ }
+
+ }
+ return isRegistered;
+}
+
+void SuspendHandlerLinux::unregisterSuspendHandler()
+{
+ if (_isSuspendRegistered)
+ {
+ QDBusConnection systemBus = QDBusConnection::systemBus();
+ if (!systemBus.isConnected())
+ {
+ Info(_log, "The suspend/resume feature is not supported by your system configuration");
+ }
+ else
+ {
+ QString service = dbusSignals.find("Suspend").value().service;
+ if (systemBus.disconnect(service,
+ dbusSignals.find("Suspend").value().path,
+ dbusSignals.find("Suspend").value().interface,
+ dbusSignals.find("Suspend").value().name,
+ this, SLOT(suspend(bool))))
+ {
+ Debug(_log, "Unregistered for suspend/resume events via service: %s", QSTRING_CSTR(service));
+ SuspendHandlerBase::unregisterSuspendHandler();
+ }
+ else
+ {
+ Error(_log, "Could not unregister for suspend/resume events via service: %s", QSTRING_CSTR(service));
}
- ++iter;
}
}
}
+
+bool SuspendHandlerLinux::registerLockHandler()
+{
+ bool isRegistered {_isLockRegistered};
+
+ if (!_isLockRegistered)
+ {
+ QDBusConnection sessionBus = QDBusConnection::sessionBus();
+ if (!sessionBus.isConnected())
+ {
+ Info(_log, "The lock/unlock feature is not supported by your system configuration");
+ }
+ else
+ {
+ DbusSignalsMap::const_iterator iter = dbusSignals.find("ScreenSaver");
+ while (iter != dbusSignals.end() && iter.key() == "ScreenSaver") {
+ QString service = iter.value().service;
+ if (sessionBus.connect(service,
+ iter.value().path,
+ iter.value().interface,
+ iter.value().name,
+ this, SLOT(lock(bool))))
+ {
+ Debug(_log, "Registered for lock/unlock events via service: %s", QSTRING_CSTR(service));
+ isRegistered = true;
+ }
+ else
+ {
+ Error(_log, "Could not register for lock/unlock events via service: %s", QSTRING_CSTR(service));
+
+ }
+ ++iter;
+ }
+
+ }
+ }
+
+ if (isRegistered)
+ {
+ isRegistered = SuspendHandlerBase::registerLockHandler();
+ }
+
+ return isRegistered;
+}
+
+void SuspendHandlerLinux::unregisterLockHandler()
+{
+ bool isUnregistered {false};
+
+ if (_isLockRegistered)
+ {
+ QDBusConnection sessionBus = QDBusConnection::sessionBus();
+ if (!sessionBus.isConnected())
+ {
+ Info(_log, "The lock/unlock feature is not supported by your system configuration");
+ }
+ else
+ {
+ DbusSignalsMap::const_iterator iter = dbusSignals.find("ScreenSaver");
+ while (iter != dbusSignals.end() && iter.key() == "ScreenSaver") {
+ QString service = iter.value().service;
+ if (sessionBus.disconnect(service,
+ iter.value().path,
+ iter.value().interface,
+ iter.value().name,
+ this, SLOT(lock(bool))))
+ {
+ Debug(_log, "Unregistered for lock/unlock events via service: %s", QSTRING_CSTR(service));
+ isUnregistered = true;
+ }
+ else
+ {
+ Error(_log, "Could not unregister for lock/unlock events via service: %s", QSTRING_CSTR(service));
+
+ }
+ ++iter;
+ }
+
+ if (isUnregistered)
+ {
+ SuspendHandlerBase::unregisterLockHandler();
+ }
+ }
+ }
+}
+
+
#endif
diff --git a/src/hyperiond/SuspendHandler.h b/src/hyperiond/SuspendHandler.h
index d5f89e81..fd3051e2 100644
--- a/src/hyperiond/SuspendHandler.h
+++ b/src/hyperiond/SuspendHandler.h
@@ -1,6 +1,11 @@
#ifndef SUSPENDHANDLER_H
#define SUSPENDHANDLER_H
#include
+#include
+
+#include
+
+class Logger;
class SuspendHandlerBase : public QObject {
Q_OBJECT
@@ -22,6 +27,8 @@ public slots:
void lock(bool isLocked);
+ virtual void handleSettingsUpdate(settings::type type, const QJsonDocument& config);
+
signals:
void suspendEvent();
@@ -29,6 +36,31 @@ signals:
void lockedEvent(bool);
void idleEvent(bool);
+protected:
+
+ virtual bool registerSuspendHandler();
+ virtual void unregisterSuspendHandler();
+ virtual bool registerLockHandler();
+ virtual void unregisterLockHandler();
+
+ virtual bool registerSuspendApiHandler();
+ virtual void unregisterSuspendApiHandler();
+ virtual bool registerIdleApiHandler();
+ virtual void unregisterIdleApiHandler();
+
+ bool _isSuspendEnabled;
+ bool _isLockEnabled;
+ bool _isSuspendApiEnabled;
+ bool _isIdleApiEnabled;
+ bool _isSuspendOnLock;
+
+ bool _isSuspendRegistered;
+ bool _isLockRegistered;
+ bool _isSuspendApiRegistered;
+ bool _isIdleApiRegistered;
+
+ Logger * _log {};
+
private:
bool _isSuspended;
@@ -56,6 +88,12 @@ protected:
#endif
private:
+
+ bool registerSuspendHandler() override;
+ bool unregisterSuspendHandler() override;
+ void registerLockHandler() override;
+ void unregisterLockHandler() override;
+
QWidget _widget;
HPOWERNOTIFY _notifyHandle;
};
@@ -65,9 +103,16 @@ using SuspendHandler = SuspendHandlerWindows;
#elif defined(__linux__) && defined(HYPERION_HAS_DBUS)
class SuspendHandlerLinux : public SuspendHandlerBase {
+ Q_OBJECT
public:
SuspendHandlerLinux();
+
+private:
+ bool registerSuspendHandler() override;
+ void unregisterSuspendHandler() override;
+ bool registerLockHandler() override;
+ void unregisterLockHandler() override;
};
using SuspendHandler = SuspendHandlerLinux;
diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp
index b1ba12d4..b34de01d 100644
--- a/src/hyperiond/hyperiond.cpp
+++ b/src/hyperiond/hyperiond.cpp
@@ -92,8 +92,8 @@ HyperionDaemon::HyperionDaemon(const QString& rootPath, QObject* parent, bool lo
, _osxGrabber(nullptr)
, _qtGrabber(nullptr)
, _dxGrabber(nullptr)
- , _ssdp(nullptr)
, _audioGrabber(nullptr)
+ , _ssdp(nullptr)
#ifdef ENABLE_CEC
, _cecHandler(nullptr)
#endif
@@ -177,7 +177,8 @@ HyperionDaemon::HyperionDaemon(const QString& rootPath, QObject* parent, bool lo
// ---- network services -----
startNetworkServices();
- _suspendHandler = new SuspendHandler();
+ // init events services
+ handleSettingsUpdate(settings::SYSTEMEVENTS, getSetting(settings::SYSTEMEVENTS));
}
HyperionDaemon::~HyperionDaemon()
@@ -742,6 +743,19 @@ void HyperionDaemon::handleSettingsUpdate(settings::type settingsType, const QJs
Debug(_log, "Audio capture not supported on this platform");
#endif
}
+ else if (settingsType == settings::SYSTEMEVENTS)
+ {
+ // Create suspend handler
+ if (_suspendHandler == nullptr)
+ {
+ _suspendHandler = new SuspendHandler();
+ _suspendHandler->handleSettingsUpdate(settings::SYSTEMEVENTS, getSetting(settings::SYSTEMEVENTS));
+
+ connect(this, &HyperionDaemon::settingsChanged, _suspendHandler, &SuspendHandler::handleSettingsUpdate);
+
+ Debug(_log, "SuspendHandler created");
+ }
+ }
}
void HyperionDaemon::createGrabberDispmanx(const QJsonObject& /*grabberConfig*/)