Add Suspend/Resume support (#1535)

* Add Suspend/Resume support

* Support Suspend/Resume/Restart via API, UI and Systray

* Support screen lock/unlock scenario

* Handle idle scenario

* Align with fix for #1368

* Update Windows build

* Refactor SuspendHandler to maintain state

* Do not start BG-Effect, if system goes into suspend mode

* Correct Idle and Resume interaction
This commit is contained in:
LordGrey
2022-12-22 12:40:39 +01:00
committed by GitHub
parent 2217135336
commit 1189f86c1a
32 changed files with 994 additions and 67 deletions

View File

@@ -99,6 +99,26 @@ signals:
///
void forwardJsonMessage(QJsonObject);
///
/// Signal emits whenever a suspend/resume request for all instances should be forwarded
///
void suspendAll(bool isSuspend);
///
/// Signal emits whenever a toggle suspend/resume request for all instances should be forwarded
///
void toggleSuspendAll();
///
/// Signal emits whenever a idle mode request for all instances should be forwarded
///
void idleAll(bool isIdle);
///
/// Signal emits whenever a toggle idle/working mode request for all instances should be forwarded
///
void toggleIdleAll();
private:
// true if further callbacks are forbidden (http)
bool _noListener;
@@ -298,6 +318,12 @@ private:
///
void handleServiceCommand(const QJsonObject &message, const QString &command, int tan);
/// Handle an incoming JSON message for actions related to the overall Hyperion system
///
/// @param message the incoming message
///
void handleSystemCommand(const QJsonObject &message, const QString &command, int tan);
///
/// Handle an incoming JSON message of unknown type
///

View File

@@ -20,6 +20,7 @@ public:
, _hyperion(hyperion)
, _prioMuxer(_hyperion->getMuxerInstance())
, _isBgEffectEnabled(false)
, _isSuspended(false)
{
QString subComponent = parent()->property("instance").toString();
_log = Logger::getInstance("HYPERION", subComponent);
@@ -33,6 +34,11 @@ public:
this->handlePriorityUpdate();
});
// listen for suspend/resume requests, to not start a background effect when system goes into suspend mode
connect(_hyperion, &Hyperion::suspendRequest, this, [=] (bool isSuspended) {
_isSuspended = isSuspended;
});
// initialization
handleSettingsUpdate(settings::BGEFFECT, _hyperion->getSetting(settings::BGEFFECT));
}
@@ -109,7 +115,7 @@ private slots:
Debug(_log,"Stop background (color-) effect as it moved out of scope");
_hyperion->clear(PriorityMuxer::BG_PRIORITY);
}
else if (_prioMuxer->getCurrentPriority() == PriorityMuxer::LOWEST_PRIORITY && _isBgEffectEnabled)
else if (!_isSuspended && _prioMuxer->getCurrentPriority() == PriorityMuxer::LOWEST_PRIORITY && _isBgEffectEnabled)
{
Debug(_log,"Start background (color-) effect as it moved in scope");
emit handleSettingsUpdate (settings::BGEFFECT, _bgEffectConfig);
@@ -126,6 +132,8 @@ private:
QJsonDocument _bgEffectConfig;
bool _isBgEffectEnabled;
bool _isSuspended;
};
#endif // BGEFFECTHANDLER_H

View File

@@ -7,12 +7,15 @@
#include <map>
#include <QObject>
#include <QVector>
class Hyperion;
typedef QVector<hyperion::Components> ComponentList;
///
/// @brief The component register reflects and manages the current state of all components and Hyperion as a whole
/// It emits also real component state changes (triggert from the specific component), which can be used for listening APIs (Network Clients/Plugins)
/// It emits also real component state changes (triggered from the specific component), which can be used for listening APIs (Network Clients/Plugins)
///
class ComponentRegister : public QObject
{
@@ -36,23 +39,32 @@ signals:
///
/// @brief Emits whenever a component changed (really) the state
/// @param comp The component
/// @param state The new state of the component
/// @param isActive The new state of the component
///
void updatedComponentState(hyperion::Components comp, bool state);
void updatedComponentState(hyperion::Components comp, bool isActive);
public slots:
///
/// @brief is called whenever a component change a state, DO NOT CALL FROM API, use signal hyperion->compStateChangeRequest
/// @param comp The component
/// @param state The new state of the component
/// @param isActive The new state of the component
///
void setNewComponentState(hyperion::Components comp, bool activated);
void setNewComponentState(hyperion::Components comp, bool isActive);
private slots:
///
/// @brief Handle COMP_ALL changes from Hyperion->compStateChangeRequest
/// @param comp COMP_ALL
/// @param isActive The new state for all components
///
void handleCompStateChangeRequest(hyperion::Components comps, bool activated);
void handleCompStateChangeRequest(hyperion::Components comps, bool isActive);
///
/// @brief Activate/Deactivate all components, except those provided by the list of excluded components
/// @param isActive The new state for all components
/// @param execludeList of excluded components
///
void handleCompStateChangeRequestAll(bool isActive, const ComponentList& excludeList = ComponentList{});
private:
/// Hyperion instance

View File

@@ -389,6 +389,20 @@ public slots:
int getLatchTime() const;
///
/// @brief Set hyperion in suspend mode or resume from suspend/idle.
/// All instances and components will be disabled/enabled.
/// @param isSupend True, components will be deactivated, else put into their previous state before suspend
///
void setSuspend(bool isSupend);
///
/// @brief Set hyperion in idle /working mode.
/// In idle, all instances and components will be disabled besides the output processing (LED-Devices, smoothing).
/// @param isIdle True, selected components will be deactivated, else put into their previous state before idle
///
void setIdle(bool isIdle);
signals:
/// Signal which is emitted when a priority channel is actively cleared
/// This signal will not be emitted when a priority channel time out
@@ -406,6 +420,18 @@ signals:
///
void compStateChangeRequest(hyperion::Components component, bool enabled);
///
/// @brief Emits when all (besides excluded) components are subject to state changes
/// @param isActive The new state for all components
/// @param execlude List of excluded components
void compStateChangeRequestAll(bool isActive, const ComponentList& excludeList = {});
/// Signal which is emitted, when system is to be suspended/resumed
void suspendRequest(bool isSuspend);
/// Signal which is emitted, when system should go into idle/working mode
void idleRequest(bool isIdle);
///
/// @brief Emits whenever the imageToLedsMapping has changed
/// @param mappingType The new mapping type

View File

@@ -74,10 +74,26 @@ public slots:
bool stopInstance(quint8 inst);
///
/// @brief Toggle the state of all Hyperion instances
/// @param pause If true all instances toggle to pause, else to resume
/// @brief Suspend (disable) all Hyperion instances
///
void toggleStateAllInstances(bool pause = false);
void suspend();
///
/// @brief Resume (resume) all Hyperion instances
///
void resume();
///
/// @brief Toggle the state of all Hyperion instances for an idle sceanrio (user is not interacting with the system
/// @param isIdle, If true all instances toggle to idle, else to resume
///
void toggleIdle(bool isIdle);
///
/// @brief Toggle the state of all Hyperion instances
/// @param enable, If false all instances toggle to pause, else to resume
///
void toggleStateAllInstances(bool enable = false);
///
/// @brief Create a new Hyperion instance entry in db
@@ -125,6 +141,11 @@ signals:
///
void startInstanceResponse(QObject *caller, const int &tan);
void triggerSuspend(bool isSuspend);
void triggerToggleSuspend();
void triggerIdle(bool isIdle);
void triggerToggleIdle();
signals:
///////////////////////////////////////
/// FROM HYPERIONDAEMON TO HYPERION ///