diff --git a/CellframeNodeDiagtool/AbstractDiagnostic.cpp b/CellframeNodeDiagtool/AbstractDiagnostic.cpp index 3f0c8fb932a67c75c8c3b8c98fe0039ecfb5614a..65f412858140cfbe9a944b96b48b74a02a7c62ee 100644 --- a/CellframeNodeDiagtool/AbstractDiagnostic.cpp +++ b/CellframeNodeDiagtool/AbstractDiagnostic.cpp @@ -234,6 +234,7 @@ QJsonObject AbstractDiagnostic::get_net_info(QString net) QString result = proc.readAll(); + // ---------- Status ---------------- QRegularExpression rx_state(R"(.*current: ([A-Z,_]+).*)"); QRegularExpression rx_addr(R"(.*current_addr: (.+))"); @@ -263,7 +264,35 @@ QJsonObject AbstractDiagnostic::get_net_info(QString net) resultObj.insert("links_count", match_req.captured(1)); } - + // ---------- Sync statuses ---------------- + QRegularExpression rxZeroChainSync(R"(zerochain: \s+status: (\S+|.+)\s+current: (\S+)\s+in network: (\S+)\s+percent: (\S+|.+))"); + QJsonObject objZeroChain; + + QRegularExpressionMatch match_zeroChain = rxZeroChainSync.match(result); + if (match_zeroChain.hasMatch()) { + objZeroChain.insert("status", match_zeroChain.captured(1)); + objZeroChain.insert("current", match_zeroChain.captured(2)); + objZeroChain.insert("network", match_zeroChain.captured(3)); + objZeroChain.insert("percent", match_zeroChain.captured(4)); + } + + QRegularExpression rxMainChainSync(R"(main: \s+status: (\S+|.+)\s+current: (\S+)\s+in network: (\S+)\s+percent: (\S+|.+))"); + QJsonObject objMainChain; + + QRegularExpressionMatch match_mainChain = rxMainChainSync.match(result); + if (match_mainChain.hasMatch()) { + objMainChain.insert("status", match_mainChain.captured(1)); + objMainChain.insert("current", match_mainChain.captured(2)); + objMainChain.insert("network", match_mainChain.captured(3)); + objMainChain.insert("percent", match_mainChain.captured(4)); + } + + QJsonObject syncObj{ + {"main", objMainChain}, + {"zero", objZeroChain} + }; + + resultObj.insert("sync_status", syncObj); resultObj.insert("balancer", get_balancer_links(net)); return resultObj; diff --git a/CellframeNodeDiagtool/DiagnosticWorker.cpp b/CellframeNodeDiagtool/DiagnosticWorker.cpp index 72ca0b0f0ead8ad9eba054d7c8e54d2548bd3ec1..a4b5bec3b8487134319fac5653d803d5ac5d8432 100644 --- a/CellframeNodeDiagtool/DiagnosticWorker.cpp +++ b/CellframeNodeDiagtool/DiagnosticWorker.cpp @@ -3,6 +3,7 @@ #include <QHttpPart> #include <QHttpMultiPart> #include <QNetworkReply> + static QString group = "global.users.statistic"; DiagnosticWorker::DiagnosticWorker(QObject * parent) @@ -37,6 +38,10 @@ void DiagnosticWorker::init() m_diagnostic = new MacDiagnostic(); #endif + m_notifyWorker = new NotifyWorker(); + m_notifyWorker->rcvNetObj(m_diagnostic->roles_processing()); + + connect(m_diagnostic, &AbstractDiagnostic::data_updated, this, &DiagnosticWorker::slot_diagnostic_data, Qt::QueuedConnection); @@ -112,9 +117,12 @@ void DiagnosticWorker::slot_diagnostic_data(QJsonDocument data) result = result.split("version")[1]; m_node_version = result.split('\n', QString::SkipEmptyParts).first().trimmed(); } + + m_notifyWorker->nodeIsOnline(); } proc.insert("version", m_node_version); + proc.insert("node_init", m_notifyWorker->m_docNodeInit.object()); obj.insert("process",proc); data.setObject(obj); m_lastSendedPack = data; diff --git a/CellframeNodeDiagtool/DiagnosticWorker.h b/CellframeNodeDiagtool/DiagnosticWorker.h index 51c1d3b79a416168152090ef7b36a1387ac2cfcb..b73a853bc805722aaea0478b7121594476c64b78 100644 --- a/CellframeNodeDiagtool/DiagnosticWorker.h +++ b/CellframeNodeDiagtool/DiagnosticWorker.h @@ -14,6 +14,8 @@ #include <stdio.h> #include <string.h> +#include "NotifyWorker.h" + #ifdef Q_OS_LINUX #include "LinuxDiagnostic.h" #elif defined Q_OS_WIN @@ -46,6 +48,7 @@ private: QString m_node_version{""}; QSettings m_settings; AbstractDiagnostic* m_diagnostic; + NotifyWorker* m_notifyWorker; QTimer *s_uptime_timer; QElapsedTimer *s_elapsed_timer; diff --git a/CellframeNodeDiagtool/NotifyWorker.cpp b/CellframeNodeDiagtool/NotifyWorker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..625ab913c7ee6731a7da0f9e7b2cfa2663d777d2 --- /dev/null +++ b/CellframeNodeDiagtool/NotifyWorker.cpp @@ -0,0 +1,287 @@ +#include "NotifyWorker.h" +#include "NodeTrayCommandController.h" + +QByteArrayList NotifyWorker::jsonListFromData(QByteArray data) +{ + return data.split('\x00'); +} + +NotifyWorker::NotifyWorker(QObject *parent) + :QObject(parent) +{ + NodeTrayCommandController *m_trayCtrl = &NodeTrayCommandController::getInstance(); + + if(m_trayCtrl->initConfTool()) + { + m_configWorkerPath = m_trayCtrl->m_confToolPath; + m_initTimer = new QTimer(this); + m_reconnectTimer = new QTimer(this); + + if(initWatcher()) + return; + else + { + m_initTimer->start(5000); + connect(m_initTimer, &QTimer::timeout, [=] { + qDebug()<<"Reinit timer tick"; + if(initWatcher()) + m_initTimer->stop(); + }); + } + } + m_statusInitWatcher = false; +} + +NotifyWorker::~NotifyWorker() +{ + delete m_initTimer; + delete m_reconnectTimer; +} + +QVariant NotifyWorker::readConfig(QString filename, QString section, QString param, QVariant defaultValue) +{ + QProcess proc; + proc.setProgram(m_configWorkerPath); + proc.setArguments(QStringList()<<"-e"<<"config"<<filename<<section<<param<<"get"); + + proc.start(); + + if(proc.waitForFinished()) + { + QByteArray res = proc.readAllStandardOutput(); + + QString strRes = QString(res).remove("\n").remove("\r").remove("\t"); + return strRes.split("=")[1]; + } + + qDebug()<<proc.readAllStandardError(); + return defaultValue; +} + +bool NotifyWorker::initWatcher() +{ + m_listenPath = readConfig("cellframe-node", "notify_server", "listen_path", "").toString(); + m_listenAddr = readConfig("cellframe-node", "notify_server", "listen_address", "").toString(); + m_listenPort = readConfig("cellframe-node", "notify_server", "listen_port", 0).toUInt(); + + if(m_listenAddr.contains(":")) + { + m_listenAddr = m_listenAddr.contains("[") ? m_listenAddr.remove("[") : m_listenAddr; + m_listenAddr = m_listenAddr.contains("]") ? m_listenAddr.remove("]") : m_listenAddr; + + m_listenPort = QString(m_listenAddr.split(":")[1]).toUInt(); + m_listenAddr = m_listenAddr.split(":")[0]; + } + + qDebug() << "Tcp config: " << m_listenAddr << m_listenPort; + connect(m_reconnectTimer, SIGNAL(timeout()), this, SLOT(slotReconnect())); + + if (!m_listenPath.isEmpty()) + { + m_socket = new QLocalSocket(this); + connect((QLocalSocket*)m_socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error), + this, &NotifyWorker::slotError); + + connect((QLocalSocket*)m_socket, &QLocalSocket::connected, + this, &NotifyWorker::socketConnected); + + connect((QLocalSocket*)m_socket, &QLocalSocket::disconnected, + this, &NotifyWorker::socketDisconnected); + + connect((QAbstractSocket*)m_socket, &QAbstractSocket::stateChanged, + this, &NotifyWorker::socketStateChanged); + + connect(m_socket, &QLocalSocket::readyRead, this, &NotifyWorker::socketReadyRead); + + ((QLocalSocket*)m_socket)->connectToServer(m_listenPath); + ((QLocalSocket*)m_socket)->waitForConnected(); + } + else + { + m_socket = new QTcpSocket(this); + connect((QTcpSocket*)m_socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), + this, &NotifyWorker::slotError); + + connect((QTcpSocket*)m_socket, &QTcpSocket::connected, + this, &NotifyWorker::socketConnected); + + connect((QTcpSocket*)m_socket, &QTcpSocket::disconnected, + this, &NotifyWorker::socketDisconnected); + + connect((QTcpSocket*)m_socket, &QTcpSocket::stateChanged, + this, &NotifyWorker::socketStateChanged); + + connect(m_socket, &QTcpSocket::readyRead, this, &NotifyWorker::socketReadyRead); + + ((QTcpSocket*)m_socket)->connectToHost(m_listenAddr, m_listenPort); + ((QTcpSocket*)m_socket)->waitForConnected(); + } + m_statusInitWatcher = true; + return true; +} + + +void NotifyWorker::slotError() +{ + qWarning() << "Notify socket error" << m_socket->errorString(); + reconnectFunc(); +} + +void NotifyWorker::slotReconnect() +{ + qInfo()<<"NotifyWorker::slotReconnect()" << m_listenAddr << m_listenPort << "Socket state" << m_socketState; + + ((QTcpSocket*)m_socket)->connectToHost(m_listenAddr, m_listenPort); + ((QTcpSocket*)m_socket)->waitForConnected(5000); +} + +void NotifyWorker::socketConnected() +{ + qInfo() << "Notify socket connected"; + m_reconnectTimer->stop(); + m_socket->waitForReadyRead(4000); +} + +void NotifyWorker::socketDisconnected() +{ + qWarning() << "Notify socket disconnected"; + reconnectFunc(); +} + +void NotifyWorker::socketStateChanged(QAbstractSocket::SocketState socketState) +{ + qDebug() << "Socket state changed" << socketState; + m_socketState = socketState; +} + +void NotifyWorker::socketReadyRead() +{ + // qDebug() << "Ready Read"; + QByteArray data = m_socket->readLine(); + // QByteArray data = socket->readAll(); + if (data[data.length() - 1] != '}') + data = data.left(data.length() - 1); + + if (data[0] != '{') + data = data.right(data.length() - 1); + + QByteArrayList list = jsonListFromData(data); + + for (int i = 0; i < list.length(); ++i) + { + QJsonParseError error; + QJsonDocument reply = QJsonDocument::fromJson(list[i], &error); + if (error.error != QJsonParseError::NoError) { + // qWarning()<<"Notify parse error. " << error.errorString(); // more logs + return; + } + + if(reply.object()["class"].toString() == "chain_init") + procNotifyData(reply.object()); + } +} + +void NotifyWorker::procNotifyData(const QJsonObject &rcvObj) +{ + m_rcvInitProgress = true; + + bool isContains{false}; + int itr{0}; + + for (const auto &net: qAsConst(m_arrNodeInit)) { + const auto findNet = net.toObject(); + + if (findNet["name"] == rcvObj["net"]) { + isContains = true; + + QJsonObject objChains = m_arrNodeInit[itr].toObject()["chains"].toObject(); + + if(rcvObj["chain_id"].toInt() == 1) + { + objChains["main"] = rcvObj["load_progress"]; + objChains["zero"] = 100; + } + else + objChains["zero"] = rcvObj["load_progress"]; + + QJsonObject object + { + {"name", rcvObj["net"].toString()}, + {"chains", objChains} + }; + + m_arrNodeInit[itr] = object; + break; + } + itr++; + } + + QJsonObject result{ + {"init_progress", m_arrNodeInit}, + {"notify_status", m_socketState == QAbstractSocket::SocketState::ConnectedState? + "connected" : "disconnected"} + }; + + m_docNodeInit.setObject(result); + +// qDebug()<<m_docNodeInit.toJson(); +} + +void NotifyWorker::nodeIsOnline() +{ + if(!m_rcvInitProgress) + { + m_arrNodeInit = QJsonArray(); + for(const auto &net: qAsConst(m_netList)) + { + QJsonObject chains; + chains.insert("main", 100); + chains.insert("zero", 100); + + QJsonObject obj; + obj.insert("name", net); + obj.insert("chains", chains); + + m_arrNodeInit.append(obj); + } + + QJsonObject result{ + {"init_progress", m_arrNodeInit}, + {"notify_status", m_socketState == QAbstractSocket::SocketState::ConnectedState? + "connected" : "disconnected"} + }; + + m_docNodeInit.setObject(result); + } +} + +void NotifyWorker::rcvNetObj(QJsonObject objNet) +{ + m_netList = objNet.keys(); + + for(const auto &net: qAsConst(m_netList)) + { + QJsonObject chains; + chains.insert("zero", 0); + chains.insert("main", 0); + + + QJsonObject obj; + obj.insert("name", net); + obj.insert("chains", chains); + + m_arrNodeInit.append(obj); + } +} + +void NotifyWorker::reconnectFunc() +{ + m_reconnectTimer->stop(); + + if(m_socketState != QAbstractSocket::SocketState::ConnectedState && + m_socketState != QAbstractSocket::SocketState::ConnectingState) + { + m_reconnectTimer->start(10000); + qWarning()<< "Notify socket reconnecting..."; + } +} diff --git a/CellframeNodeDiagtool/NotifyWorker.h b/CellframeNodeDiagtool/NotifyWorker.h new file mode 100644 index 0000000000000000000000000000000000000000..dc780cfa18ea8d7ccf54c7990386d9c4d7ffa4b2 --- /dev/null +++ b/CellframeNodeDiagtool/NotifyWorker.h @@ -0,0 +1,70 @@ +#ifndef NOTIFYWORKER_H +#define NOTIFYWORKER_H + +#include <QThread> +#include <QIODevice> +#include <QLocalSocket> +#include <QTcpSocket> +#include <QTimer> +#include <QJsonObject> +#include <QJsonArray> +#include <QJsonDocument> +#include <QDebug> +#include <QProcess> +#include <QVariant> + + +class NotifyWorker : public QObject +{ + Q_OBJECT +public: + explicit NotifyWorker(QObject *parent = nullptr); + ~NotifyWorker(); + + bool initWatcher(); + + const QString& getSocketState() const {return m_socketState;} + + QVariant readConfig(QString filename, QString section, QString param, QVariant defaultValue); + + bool m_statusInitWatcher{false}; + QJsonDocument m_docNodeInit; + QJsonArray m_arrNodeInit; + QStringList m_netList; + + void nodeIsOnline(); + void rcvNetObj(QJsonObject objNet); + +public slots: + void slotError(); + void socketConnected(); + void slotReconnect(); + void socketDisconnected(); + + void socketReadyRead(); + + void socketStateChanged(QAbstractSocket::SocketState socketState); + +signals: + void changeConnectState(QString); + +private: + void reconnectFunc(); + QByteArrayList jsonListFromData(QByteArray data); + + void procNotifyData(const QJsonObject &rcvObj); +private: + QString m_configWorkerPath; + QIODevice *m_socket; + QString m_listenPath; + QString m_listenAddr; + uint16_t m_listenPort; + QTimer * m_reconnectTimer; + QTimer * m_initTimer; + + bool m_rcvInitProgress{false}; + + QString m_socketState{""}; +}; + +#endif // NOTIFYWORKER_H diff --git a/CellframeNodeTray/NodeTrayCommandController.cpp b/CellframeNodeTray/NodeTrayCommandController.cpp index 66fa952955f2fbe517a54592f4ec1f5b5d869797..912bd81cbb40dd23916a9c55b46fa849425a2bdc 100644 --- a/CellframeNodeTray/NodeTrayCommandController.cpp +++ b/CellframeNodeTray/NodeTrayCommandController.cpp @@ -1,7 +1,18 @@ #include "NodeTrayCommandController.h" NodeTrayCommandController::NodeTrayCommandController(QObject *parent) - : QObject(parent) + : QObject{parent} +{ + +} + +NodeTrayCommandController &NodeTrayCommandController::getInstance() +{ + static NodeTrayCommandController instance; + return instance; +} + +void NodeTrayCommandController::init() { m_configDir = getConfigPath(); m_statusInitConftool = initConfTool(); @@ -11,9 +22,20 @@ NodeTrayCommandController::NodeTrayCommandController(QObject *parent) void NodeTrayCommandController::initEngine() { +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) + QString os = "linux"; +#elif defined Q_OS_WIN + QString os = "win"; +#elif defined Q_OS_MAC + QString os = "macos"; +#else + QString os = "unknown"; +#endif + QQmlContext * context = m_engine.rootContext(); context->setContextProperty("trayCommandController", this); context->setContextProperty("diagnosticWorker", &diagnosticWorker); + context->setContextProperty("CURRENT_OS", QVariant::fromValue(os)); const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&m_engine, &QQmlApplicationEngine::objectCreated, @@ -25,10 +47,6 @@ void NodeTrayCommandController::initEngine() m_engine.load(url); } -NodeTrayCommandController::~NodeTrayCommandController() -{ - -} QQmlApplicationEngine *NodeTrayCommandController::qmlEngine() { @@ -249,3 +267,51 @@ void NodeTrayCommandController::showMessage(const QString msg, const QMessageBox emit sigShowMessage("Celflrame Node Tray",msg); } + +#ifdef WIN32 +LONG NodeTrayCommandController::GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue) +{ + nValue = nDefaultValue; + DWORD dwBufferSize(sizeof(DWORD)); + DWORD nResult(0); + LONG nError = ::RegQueryValueExW(hKey, + strValueName.c_str(), + 0, + NULL, + reinterpret_cast<LPBYTE>(&nResult), + &dwBufferSize); + if (ERROR_SUCCESS == nError) + { + nValue = nResult; + } + return nError; +} + + +LONG NodeTrayCommandController::GetBoolRegKey(HKEY hKey, const std::wstring &strValueName, bool &bValue, bool bDefaultValue) +{ + DWORD nDefValue((bDefaultValue) ? 1 : 0); + DWORD nResult(nDefValue); + LONG nError = GetDWORDRegKey(hKey, strValueName.c_str(), nResult, nDefValue); + if (ERROR_SUCCESS == nError) + { + bValue = (nResult != 0) ? true : false; + } + return nError; +} + + +LONG NodeTrayCommandController::GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue) +{ + strValue = strDefaultValue; + WCHAR szBuffer[512]; + DWORD dwBufferSize = sizeof(szBuffer); + ULONG nError; + nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize); + if (ERROR_SUCCESS == nError) + { + strValue = szBuffer; + } + return nError; +} +#endif diff --git a/CellframeNodeTray/NodeTrayCommandController.h b/CellframeNodeTray/NodeTrayCommandController.h index e50f46adde4821530b22da1ea9181e75d94bb7d9..482a63a97be7685101403b0dff92aaae9dc78823 100644 --- a/CellframeNodeTray/NodeTrayCommandController.h +++ b/CellframeNodeTray/NodeTrayCommandController.h @@ -14,7 +14,6 @@ #include <QQmlEngine> - #include "DiagnosticWorker.h" #ifdef WIN32 @@ -24,9 +23,13 @@ class NodeTrayCommandController : public QObject { Q_OBJECT -public: explicit NodeTrayCommandController(QObject *parent = nullptr); - ~NodeTrayCommandController(); + +public: + static NodeTrayCommandController &getInstance(); + + void init(); + bool initConfTool(); QQmlApplicationEngine *qmlEngine(); @@ -49,7 +52,7 @@ public: DiagnosticWorker &diagnosticWorker = DiagnosticWorker::getInstance(); -private: +public: bool m_statusInitConftool{false}; QString m_confToolPath{""}; QString m_configDir{""}; @@ -57,7 +60,6 @@ private: QQmlApplicationEngine m_engine; private: - bool initConfTool(); QString getConfigPath(); QString sendRequest(QString req); @@ -65,6 +67,12 @@ private: QString getResult(QString find, QStringList list); +#ifdef WIN32 + LONG GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue); + LONG GetBoolRegKey(HKEY hKey, const std::wstring &strValueName, bool &bValue, bool bDefaultValue); + LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue); +#endif + signals: Q_INVOKABLE void sigResultStatus(bool status); Q_INVOKABLE void sigShowMessage(QString title, QString message); diff --git a/CellframeNodeTray/main.qml b/CellframeNodeTray/main.qml index f379feac47b7bc6f67a1c1f321af7aea34767bdf..3e02d5ed888275e82c9e34057eb51f7819f2e2d0 100644 --- a/CellframeNodeTray/main.qml +++ b/CellframeNodeTray/main.qml @@ -57,17 +57,17 @@ ApplicationWindow { } } MenuItem { - visible: autostartItemMenu.status + visible: CURRENT_OS === "macos" ? false : autostartItemMenu.status text: qsTr("Stop cellframe-node") onTriggered: trayCommandController.serviceCommand(3) } MenuItem { - visible: autostartItemMenu.status + visible: CURRENT_OS === "macos" ? false : autostartItemMenu.status text: qsTr("Start cellframe-node") onTriggered: trayCommandController.serviceCommand(4) } MenuItem { - visible: autostartItemMenu.status + visible: CURRENT_OS === "macos" ? false : autostartItemMenu.status text: qsTr("Restart cellframe-node") onTriggered: trayCommandController.serviceCommand(5) } diff --git a/cellfram-node-diagtool.pro b/cellfram-node-diagtool.pro index 34b3fbfbe35607fc80d1c2277b6e0153e2cd0251..50cd47c3852fec4360caa239cfaf0bdc5cab8ff9 100644 --- a/cellfram-node-diagtool.pro +++ b/cellfram-node-diagtool.pro @@ -10,12 +10,14 @@ INCLUDEPATH += CellframeNodeTray \ CellframeNodeDiagtool SOURCES += \ + CellframeNodeDiagtool/NotifyWorker.cpp \ CellframeNodeTray/NodeTrayCommandController.cpp \ main.cpp \ CellframeNodeDiagtool/AbstractDiagnostic.cpp \ CellframeNodeDiagtool/DiagnosticWorker.cpp HEADERS += \ + CellframeNodeDiagtool/NotifyWorker.h \ CellframeNodeTray/NodeTrayCommandController.h \ CellframeNodeDiagtool/AbstractDiagnostic.h \ CellframeNodeDiagtool/DiagnosticWorker.h diff --git a/main.cpp b/main.cpp index d283575a5b739ac03b1b00e178175a1fd946ba9a..d7e25ee9093e2af691915926312302dee9a09397 100644 --- a/main.cpp +++ b/main.cpp @@ -1,13 +1,7 @@ #include <QApplication> #include <QQmlApplicationEngine> -#include <QIcon> -#include <QQuickWidget> -#include <QSystemTrayIcon> -#include <QQmlContext> #include <QDebug> -#include <QProcess> - #include <QSystemSemaphore> #include <QSharedMemory> #include <QScreen> @@ -18,7 +12,6 @@ #include "DiagnosticWorker.h" - bool SingleApplicationTest(const QString &appName) { static QSystemSemaphore semaphore("<"+appName+" uniq semaphore id>", 1); @@ -58,7 +51,6 @@ bool SingleApplicationTest(const QString &appName) return true; } - bool findArg(char** begin, char** end, const std::string& option) { return std::find(begin, end, option) != end; @@ -91,7 +83,7 @@ qSetMessagePattern("%{type} %{if-category}%{category}: %{endif}%{function}: %{me QCoreApplication::setApplicationName(appName); - NodeTrayCommandController *trayCommandController = new NodeTrayCommandController(); + NodeTrayCommandController::getInstance().init(); } qDebug() << "Desctop session" << getDesctopSession();