refactor: Send log level to daemon over IPC instead of when sending command
This commit is contained in:
parent
80cc323f5a
commit
d6228416a1
8 changed files with 97 additions and 41 deletions
|
|
@ -296,6 +296,7 @@ void MainWindow::connectSlots()
|
||||||
|
|
||||||
connect(&m_appConfig, &AppConfig::tlsChanged, this, &MainWindow::appConfigTlsChanged);
|
connect(&m_appConfig, &AppConfig::tlsChanged, this, &MainWindow::appConfigTlsChanged);
|
||||||
connect(&m_appConfig, &AppConfig::screenNameChanged, this, &MainWindow::updateScreenName);
|
connect(&m_appConfig, &AppConfig::screenNameChanged, this, &MainWindow::updateScreenName);
|
||||||
|
connect(&m_appConfig, &AppConfig::logLevelChanged, &m_coreProcess, &CoreProcess::applyLogLevel);
|
||||||
|
|
||||||
connect(&m_coreProcess, &CoreProcess::starting, this, &MainWindow::coreProcessStarting, Qt::DirectConnection);
|
connect(&m_coreProcess, &CoreProcess::starting, this, &MainWindow::coreProcessStarting, Qt::DirectConnection);
|
||||||
connect(&m_coreProcess, &CoreProcess::error, this, &MainWindow::coreProcessError);
|
connect(&m_coreProcess, &CoreProcess::error, this, &MainWindow::coreProcessError);
|
||||||
|
|
@ -631,6 +632,8 @@ void MainWindow::open()
|
||||||
qDebug() << "update check disabled";
|
qDebug() << "update check disabled";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_coreProcess.applyLogLevel();
|
||||||
|
|
||||||
if (m_appConfig.startedBefore()) {
|
if (m_appConfig.startedBefore()) {
|
||||||
m_coreProcess.start();
|
m_coreProcess.start();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
using namespace deskflow::gui;
|
using namespace deskflow::gui;
|
||||||
|
|
@ -680,7 +681,10 @@ void AppConfig::setNetworkInterface(const QString &s)
|
||||||
|
|
||||||
void AppConfig::setLogLevel(int i)
|
void AppConfig::setLogLevel(int i)
|
||||||
{
|
{
|
||||||
|
const auto changed = (m_LogLevel != i);
|
||||||
m_LogLevel = i;
|
m_LogLevel = i;
|
||||||
|
if (changed)
|
||||||
|
Q_EMIT logLevelChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::setLogToFile(bool b)
|
void AppConfig::setLogToFile(bool b)
|
||||||
|
|
|
||||||
|
|
@ -342,4 +342,5 @@ private:
|
||||||
signals:
|
signals:
|
||||||
void tlsChanged();
|
void tlsChanged();
|
||||||
void screenNameChanged();
|
void screenNameChanged();
|
||||||
|
void logLevelChanged();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Deskflow -- mouse and keyboard sharing utility
|
* Deskflow -- mouse and keyboard sharing utility
|
||||||
* SPDX-FileCopyrightText: (C) 2016 Symless Ltd.
|
* SPDX-FileCopyrightText: (C) 2016 - 2025 Symless Ltd.
|
||||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -9,20 +9,20 @@
|
||||||
/**
|
/**
|
||||||
* @brief The elevate mode tristate determines two behaviors on Windows.
|
* @brief The elevate mode tristate determines two behaviors on Windows.
|
||||||
*
|
*
|
||||||
* The first, switch-on-desk-switch (SodS), passed through deskflowd as a
|
|
||||||
* command line argument to deskflow core, determines if the server restarts
|
|
||||||
* when switching Windows desktops (e.g. when Windows UAC dialog pops up).
|
|
||||||
* The second, passed as a boolean flag to Deskflowd over the IPC inside
|
|
||||||
* IpcMessageType::CommandMessage, determines whether Deskflow should be started
|
|
||||||
* with elevated privileges.
|
|
||||||
*
|
|
||||||
* The matrix for these two behaviors is as follows:
|
* The matrix for these two behaviors is as follows:
|
||||||
*
|
*
|
||||||
* | SodS | Elevate |
|
* | sods | elevate |
|
||||||
* |-----------|------------|
|
* |-----------|------------|
|
||||||
* kAutomatic | true | false |
|
* kAutomatic | true | false |
|
||||||
* kAlways | false | true |
|
* kAlways | false | true |
|
||||||
* kNever | false | false |
|
* kNever | false | false |
|
||||||
|
*
|
||||||
|
* The first, --stop-on-desk-switch (sods), is passed through the daemon as a
|
||||||
|
* command line argument to the server/client, and determines if it restarts
|
||||||
|
* when switching Windows desktops (e.g. when Windows UAC dialog pops up).
|
||||||
|
*
|
||||||
|
* The second, elevate, is passed as a boolean flag to the daemon over IPC,
|
||||||
|
* and determines whether the server/client should be started with elevated privileges.
|
||||||
*/
|
*/
|
||||||
enum class ElevateMode
|
enum class ElevateMode
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,16 @@ void CoreProcess::onProcessFinished(int exitCode, QProcess::ExitStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CoreProcess::applyLogLevel()
|
||||||
|
{
|
||||||
|
if (m_appConfig.processMode() == ProcessMode::kService) {
|
||||||
|
qDebug() << "setting daemon log level:" << m_appConfig.logLevelText();
|
||||||
|
if (!m_daemonIpcClient->sendLogLevel(m_appConfig.logLevelText())) {
|
||||||
|
qCritical() << "failed to set daemon ipc log level";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CoreProcess::startForegroundProcess(const QString &app, const QStringList &args)
|
void CoreProcess::startForegroundProcess(const QString &app, const QStringList &args)
|
||||||
{
|
{
|
||||||
using enum ProcessState;
|
using enum ProcessState;
|
||||||
|
|
@ -280,7 +290,12 @@ void CoreProcess::startProcessFromDaemon(const QString &app, const QStringList &
|
||||||
QString commandQuoted = makeQuotedArgs(app, args);
|
QString commandQuoted = makeQuotedArgs(app, args);
|
||||||
|
|
||||||
qInfo("running command: %s", qPrintable(commandQuoted));
|
qInfo("running command: %s", qPrintable(commandQuoted));
|
||||||
m_daemonIpcClient->sendCommand(commandQuoted, m_appConfig.elevateMode());
|
|
||||||
|
if (!m_daemonIpcClient->sendCommand(commandQuoted, m_appConfig.elevateMode())) {
|
||||||
|
qCritical("aborting process start, ipc connect failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setProcessState(Started);
|
setProcessState(Started);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ public:
|
||||||
void stop(std::optional<ProcessMode> processMode = std::nullopt);
|
void stop(std::optional<ProcessMode> processMode = std::nullopt);
|
||||||
void restart();
|
void restart();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
void applyLogLevel();
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
Mode mode() const
|
Mode mode() const
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
namespace deskflow::gui::ipc {
|
namespace deskflow::gui::ipc {
|
||||||
|
|
||||||
|
|
@ -20,27 +21,27 @@ DaemonIpcClient::DaemonIpcClient(QObject *parent) : QObject(parent), m_socket{ne
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DaemonIpcClient::~DaemonIpcClient()
|
bool DaemonIpcClient::connectToServer()
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void DaemonIpcClient::connectToServer()
|
|
||||||
{
|
{
|
||||||
qInfo("connecting to daemon ipc");
|
qInfo("connecting to daemon ipc");
|
||||||
|
|
||||||
m_socket->connectToServer(kDaemonIpcName);
|
m_socket->connectToServer(kDaemonIpcName);
|
||||||
if (!m_socket->waitForConnected(kTimeout)) {
|
if (!m_socket->waitForConnected(kTimeout)) {
|
||||||
qCritical() << "ipc client failed to connect to server:" << kDaemonIpcName;
|
qWarning() << "ipc client failed to connect to server:" << kDaemonIpcName;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage("hello", "hello", false);
|
if (!sendMessage("hello", "hello", false)) {
|
||||||
|
qWarning() << "ipc client failed to send hello";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
connect(m_socket, &QLocalSocket::disconnected, this, &DaemonIpcClient::handleDisconnected);
|
connect(m_socket, &QLocalSocket::disconnected, this, &DaemonIpcClient::handleDisconnected);
|
||||||
connect(m_socket, &QLocalSocket::errorOccurred, this, &DaemonIpcClient::handleErrorOccurred);
|
connect(m_socket, &QLocalSocket::errorOccurred, this, &DaemonIpcClient::handleErrorOccurred);
|
||||||
|
|
||||||
m_connected = true;
|
m_connected = true;
|
||||||
qInfo() << "ipc client connected to server:" << kDaemonIpcName;
|
qInfo() << "ipc client connected to server:" << kDaemonIpcName;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonIpcClient::handleDisconnected()
|
void DaemonIpcClient::handleDisconnected()
|
||||||
|
|
@ -55,50 +56,80 @@ void DaemonIpcClient::handleErrorOccurred()
|
||||||
m_connected = false;
|
m_connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonIpcClient::sendCommand(const QString &command, ElevateMode elevateMode)
|
bool DaemonIpcClient::keepAlive()
|
||||||
{
|
{
|
||||||
sendMessage("elevate=" + QString::number(static_cast<int>(elevateMode)));
|
if (!isConnected() && !connectToServer()) {
|
||||||
sendMessage("command=" + command);
|
qWarning() << "ipc client keep alive failed to connect";
|
||||||
sendMessage("restart");
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sendMessage("noop")) {
|
||||||
|
qWarning() << "ipc client keep alive ping failed";
|
||||||
|
m_connected = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonIpcClient::sendMessage(const QString &message, const QString &expectAck, const bool expectConnected)
|
bool DaemonIpcClient::sendLogLevel(const QString &logLevel)
|
||||||
|
{
|
||||||
|
if (!keepAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sendMessage("logLevel=" + logLevel);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DaemonIpcClient::sendCommand(const QString &command, ElevateMode elevateMode)
|
||||||
|
{
|
||||||
|
if (!keepAlive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sendMessage("elevate=" + (elevateMode == ElevateMode::kAlways ? QStringLiteral("yes") : QStringLiteral("no")));
|
||||||
|
sendMessage("command=" + command);
|
||||||
|
sendMessage("restart");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DaemonIpcClient::sendMessage(const QString &message, const QString &expectAck, const bool expectConnected)
|
||||||
{
|
{
|
||||||
if (expectConnected && !m_connected) {
|
if (expectConnected && !m_connected) {
|
||||||
qCritical() << "cannot send command, ipc not connected";
|
qWarning() << "cannot send command, ipc not connected";
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray messageData = message.toUtf8() + "\n";
|
QByteArray messageData = message.toUtf8() + "\n";
|
||||||
m_socket->write(messageData);
|
m_socket->write(messageData);
|
||||||
if (!m_socket->waitForBytesWritten(kTimeout)) {
|
if (!m_socket->waitForBytesWritten(kTimeout)) {
|
||||||
qCritical() << "ipc client failed to write command";
|
qWarning() << "ipc client failed to write command";
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_socket->waitForReadyRead(kTimeout)) {
|
if (!m_socket->waitForReadyRead(kTimeout)) {
|
||||||
qCritical() << "ipc client failed to read response";
|
qWarning() << "ipc client failed to read response";
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray response = m_socket->readAll();
|
QByteArray response = m_socket->readAll();
|
||||||
if (response.isEmpty()) {
|
if (response.isEmpty()) {
|
||||||
qCritical() << "ipc client got empty response";
|
qWarning() << "ipc client got empty response";
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString responseData = QString::fromUtf8(response);
|
QString responseData = QString::fromUtf8(response);
|
||||||
if (responseData.isEmpty()) {
|
if (responseData.isEmpty()) {
|
||||||
qCritical() << "ipc client failed to convert response to string";
|
qWarning() << "ipc client failed to convert response to string";
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseData != expectAck + "\n") {
|
if (responseData != expectAck + "\n") {
|
||||||
qCritical() << "ipc client got unexpected response: " << responseData;
|
qWarning() << "ipc client got unexpected response: " << responseData;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qInfo() << "ipc client sent message: " << messageData;
|
qDebug() << "ipc client sent message: " << messageData;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace deskflow::gui::ipc
|
} // namespace deskflow::gui::ipc
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,10 @@ class DaemonIpcClient : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DaemonIpcClient(QObject *parent = nullptr);
|
explicit DaemonIpcClient(QObject *parent = nullptr);
|
||||||
~DaemonIpcClient();
|
bool connectToServer();
|
||||||
void connectToServer();
|
bool sendLogLevel(const QString &logLevel);
|
||||||
void sendCommand(const QString &command, ElevateMode elevateMode);
|
bool sendCommand(const QString &command, ElevateMode elevateMode);
|
||||||
|
|
||||||
bool isConnected() const
|
bool isConnected() const
|
||||||
{
|
{
|
||||||
|
|
@ -34,7 +34,8 @@ private slots:
|
||||||
void handleErrorOccurred();
|
void handleErrorOccurred();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendMessage(const QString &message, const QString &expectAck = "ok", const bool expectConnected = true);
|
bool keepAlive();
|
||||||
|
bool sendMessage(const QString &message, const QString &expectAck = "ok", const bool expectConnected = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLocalSocket *m_socket;
|
QLocalSocket *m_socket;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue