/* * This file is part of Remote Support Desktop * https://gitlab.das-netzwerkteam.de/RemoteWebApp/rwa.support.desktopapp * Copyright 2020-2021 Daniel Teichmann * Copyright 2020-2021 Mike Gabriel * SPDX-License-Identifier: GPL-2.0-or-later * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "session.h" Session::Session(QObject *parent, MainQMLAdaptor* main_gui, RWAHost *host) : QObject(parent) { Q_ASSERT(main_gui != nullptr); Q_ASSERT(host != nullptr); _dbus_api = new DBusAPI(); _main_gui = main_gui; _host = host; // QML -> MainQMLAdaptor::handleConnectButtonClick --onConnectButtonClick--> this::handleConnectButtonClick QObject::connect(_main_gui, SIGNAL(onConnectButtonClick(bool)), this, SLOT(handleConnectButtonClick(bool))); // session::setPin --pinChanged--> MainQMLAdaptor::setPin --pinChanged--> QML QObject::connect(this, SIGNAL(pinChanged(QString)), main_gui, SLOT(setPin(QString))); // session::setURL --urlChanged--> MainQMLAdaptor::setURL --urlChanged--> QML QObject::connect(this, SIGNAL(urlChanged(QString)), main_gui, SLOT(setURL(QString))); // session::setSessionID --sessionIDChanged--> MainQMLAdaptor::setSessionID --sessionIDChanged--> QML QObject::connect(this, SIGNAL(sessionIDChanged(QString)), main_gui, SLOT(setSessionID(QString))); // QML -> MainQMLAdaptor::onCloseHandler --onCloseSignal--> session::onCloseHandler QObject::connect(main_gui, SIGNAL(onCloseSignal()), this, SLOT(onCloseHandler())); // _dbus_api --sessionStartResponse-> this.start_response() QObject::connect(_dbus_api, SIGNAL(serviceStartResponse(QJsonDocument*)), this, SLOT(start_response(QJsonDocument*))); // _dbus_api --sessionStopResponse-> this.stop_response() QObject::connect(_dbus_api, SIGNAL(serviceStopResponse(QJsonDocument*)), this, SLOT(stop_response(QJsonDocument*))); // _dbus_api --sessionStatusResponse-> this.status_response() QObject::connect(_dbus_api, SIGNAL(serviceStatusResponse(QJsonDocument*)), this, SLOT(status_response(QJsonDocument*))); this->init_vars(); } void Session::statusTimerEvent() { qDebug() << "Status timer event got triggered just now."; this->status(); } void Session::init_vars() { setPin("-----"); setSessionID("-----"); setURL(tr("Not available yet")); setStatus("unknown"); _main_gui->setConnectButtonChecked(false); _main_gui->setConnectButtonEnabled(true); _main_gui->setStatusIndicator(false); _minimizedBefore = false; } QString Session::getStatus() { return _status; } QString Session::getURL() { return _url; } QString Session::getSessionID() { return QString(_session_id); } QString Session::getPin() { return _pin; } bool Session::isSessionAliveOrRunning(QString status) { if (status == "running" || status == "active") { return true; } else { return false; } } void Session::minimizeWindow() { if (!_minimizedBefore) { qDebug() << "Minimizing window now..."; emit _main_gui->minimizeWindow(); _minimizedBefore = true; } } void Session::setStatus(QString status) { _status = status; QString guiString = tr("Unknown state of service"); _main_gui->setStatusIndicator(false); qDebug() << "setStatus(): Setting status to " << status; if (status == "running") { /* Session is running but no one is connected yet */ guiString = tr("Remote Support session is ready to be connected to"); _main_gui->setStatusIndicator(true, QColor(255, 255, 0, 127)); } else if (status == "dead") { /* Session died */ guiString = tr("Remote Support session was stopped ungracefully"); // Clear current variables this->init_vars(); _main_gui->setStatusIndicator(true, QColor(255, 0, 0, 127)); emit _main_gui->showWindow(); _main_gui->showToast(tr("Remote Support session was stopped ungracefully"), 5000); } else if (status == "stopped") { /* Session is stopped */ guiString = tr("Remote Support session was stopped"); // Clear current variables this->init_vars(); emit _main_gui->showWindow(); _main_gui->showToast(tr("Remote Support session was stopped"), 5000); } else if (status == "active") { /* Partner is connected */ QTimer::singleShot(1000, this, &Session::minimizeWindow); guiString = tr("Your partner is connected to the Remote Support session"); _main_gui->setStatusIndicator(true, QColor(0, 255, 0, 127)); } else if (status == "waiting_start_request_answer") { /* When pressing on start button display following message while waiting */ guiString = tr("Trying to reach session service..."); } else if (status == "start_session_error") { /* Session couldn't be started */ guiString = tr("Remote Support session couldn't be started!"); _main_gui->setStatusIndicator(true, QColor(255, 0, 0, 127)); _main_gui->showToast(tr("An error occured while trying to start a session!"), 5000); } else if (status == "start_session_success") { /* Session successfully started */ guiString = tr("Remote Support session successfully started!"); _main_gui->setStatusIndicator(true, QColor(255, 255, 0, 127)); _main_gui->showToast(tr("Session was started successfully")); } else if (status == "status_session_error") { /* Session's status couldn't be refreshed */ _main_gui->showToast(tr("Session status could not be refreshed!"), 5000); guiString = tr("Session status could not be refreshed!") + "\n" + tr("remote support partner could still be connected!"); _main_gui->setStatusIndicator(true, QColor(255, 0, 0, 127)); emit _main_gui->showWindow(); } else if (status == "stop_session_error") { /* Session couldn't be stopped */ _main_gui->showToast(tr("Session could not be stopped!"), 5000); guiString = tr("Session could not be stopped!") + "\n" + tr("remote support partner could still be connected!"); _main_gui->setStatusIndicator(true, QColor(255, 0, 0, 127)); emit _main_gui->showWindow(); } _main_gui->setStatus(guiString); emit statusChanged(_status); } void Session::setURL(QString url) { _url = url; emit urlChanged(url); } void Session::setSessionID(QString session_id) { _session_id = session_id; emit sessionIDChanged(session_id); } void Session::setPin(QString pin) { _pin = pin; emit pinChanged(pin); } void Session::handleConnectButtonClick(bool checked) { qDebug() << "-----Connect button handler-----" << "\nCurrent session #" << this->getSessionID(); // Stopping even if nothing is running _dbus_api->stop_request(_host, this->getSessionID()); if (checked) { // Start the Session again _dbus_api->start_request(_host); } qDebug() << "-----\\Connect button handler-----"; } void Session::start() { // Disable connect button to reduce spam. // And don't enable it as long there is no status update. // (Or something fails) _main_gui->setConnectButtonEnabled(false); this->setStatus("waiting_start_request_answer"); _dbus_api->start_request(_host); } void Session::start_response(QJsonDocument *doc) { Q_ASSERT(doc != nullptr); // Get the QJsonObject QJsonObject jObject = doc->object(); QVariantMap mainMap = jObject.toVariantMap(); // Status of request QString request_status = mainMap["status"].toString(); if (request_status == "success") { qDebug() << "Successfully started a Session."; this->setStatus("start_session_success"); // Immediately ask for the status of the session QTimer::singleShot(0, this, &Session::statusTimerEvent); } else { qCritical() << "An error occured while creating a new session!"; this->init_vars(); this->setStatus("start_session_error"); return; } bool ok; // URL of remote web app frontend QString url = mainMap["url"].toString(); this->setURL(url); // PIN long long pin = mainMap["pin"].toLongLong(&ok); this->setPin(QString::number(pin)); // Sanity Check if(ok == false){ qErrnoWarning("Unable to parse out of dbus answer!"); init_vars(); return; } // session_id = remote support id from the rwa-server long long session_id = mainMap["session_id"].toLongLong(); this->setSessionID(QString::number(session_id)); // Sanity Check if(ok == false){ qErrnoWarning("Unable to parse out of dbus answer!"); init_vars(); return; } qDebug() << "Got session_id:" << session_id << "\nGot url:" << url << "\nGot pin:" << pin; emit pinChanged(QString::number(pin)); emit urlChanged(url); emit sessionIDChanged(QString::number(session_id)); } void Session::stop() { _dbus_api->stop_request(_host, this->getSessionID()); // Clear current variables this->init_vars(); // Disable connect button to reduce spam. // And don't enable it as long there is no status update. // (Or something fails) _main_gui->setConnectButtonEnabled(false); } void Session::stop_response(QJsonDocument *doc) { Q_ASSERT(doc != nullptr); QJsonObject jObject = doc->object(); QVariantMap mainMap = jObject.toVariantMap(); QString new_status = mainMap["status"].toString(); qDebug() << "stop_response() retrieved json. Status now:" << new_status; // Clear current variables this->init_vars(); // But the status indicator should display that the Session has stopped this->setStatus(new_status); } void Session::status() { _dbus_api->status_request(_host, this->getSessionID()); } void Session::status_response(QJsonDocument *doc) { Q_ASSERT(doc != nullptr); QJsonObject jObject = doc->object(); QVariantMap mainMap = jObject.toVariantMap(); QString new_status = mainMap["status"].toString(); qDebug() << "status_response() retrieved json. Status:" << new_status; // Enable (dis)connect button _main_gui->setConnectButtonEnabled(true); this->setStatus(new_status); if (this->isSessionAliveOrRunning(new_status)) { // Ask status every 1000 millisecond QTimer::singleShot(1000, this, &Session::statusTimerEvent); } } void Session::onCloseHandler() { // To cleanup things here _dbus_api->stop_request(_host, this->getSessionID()); }