#include "remote_control_manager.h" #ifndef QT_NO_DEBUG #define CHECK_TRUE(instruction) Q_ASSERT(instruction) #else #define CHECK_TRUE(instruction) (instruction) #endif RemoteControlManager::RemoteControlManager(QQmlApplicationEngine *engine, MainQMLAdaptor *main_gui, DBusAPI *dbus_api) : QObject() { Q_ASSERT(dbus_api != nullptr); Q_ASSERT(main_gui != nullptr); Q_ASSERT(engine != nullptr); _current_session = nullptr; _sessions = new QSet; _dbus_api = dbus_api; _main_gui = main_gui; _engine = engine; } bool RemoteControlManager::setConnectButtonEnabled(bool enabled) { // Find item via 'objectName' QQuickItem *scene_remote_control = _engine->rootObjects().takeFirst()-> findChild("Scene_remote_control"); QQuickItem *item = scene_remote_control-> findChild("start_support_button"); if (item) { item->setProperty("enabled", enabled); if (item->property("checked").toBool()) { item->setProperty("text", tr("Stop remote support session")); } else { item->setProperty("text", tr("Start remote support session")); } } else { qWarning() << "Unable to find 'start_support_button' Item!"; return false; } return true; } bool RemoteControlManager::setConnectButtonChecked(bool checked) { // Find item via 'objectName' QQuickItem *scene_remote_control = _engine->rootObjects().takeFirst()-> findChild("Scene_remote_control"); QQuickItem *item = scene_remote_control-> findChild("start_support_button"); if (item) { item->setProperty("checked", checked); } else { qWarning() << "Unable to find 'start_support_button' Item!"; return false; } return true; } bool RemoteControlManager::setStatusIndicatorText(QString status_text) { // Find item via 'objectName' QQuickItem *scene_remote_control = _engine->rootObjects().takeFirst()-> findChild("Scene_remote_control"); QQuickItem *item = scene_remote_control-> findChild("dbus_api_status_text"); if (item) { item->setProperty("text", status_text); } else { qWarning() << "Unable to find 'dbus_api_status_text' Item!"; return false; } return true; } bool RemoteControlManager::setStatusIndicatorColor(bool active, QColor color) { // Find item via 'objectName' QQuickItem *scene_remote_control = _engine->rootObjects().takeFirst()-> findChild("Scene_remote_control"); QQuickItem *item = scene_remote_control-> findChild("dbus_api_status_indicator"); if (item) { item->setProperty("active", active); item->setProperty("color", color); } else { qWarning() << "Unable to find 'dbus_api_status_indicator' Item!"; return false; } return true; } void RemoteControlManager::handleCopyToClipboardButtonClick(QString copy_data) { QClipboard *clipboard = QApplication::clipboard(); QString originalText = clipboard->text(); clipboard->setText(copy_data); qDebug() << "Copied into clipboard:" << copy_data; } QString RemoteControlManager::getURL() { if (getCurrentSession() == nullptr) { return tr("Not available yet"); } return getCurrentSession()->getURL(); } QString RemoteControlManager::getPin() { if (getCurrentSession() == nullptr) { return "-----"; } return getCurrentSession()->getPin(); } QString RemoteControlManager::getSessionID() { if (getCurrentSession() == nullptr) { return "-----"; } return getCurrentSession()->getSessionID(); } Session* RemoteControlManager::getCurrentSession() { return _current_session; } void RemoteControlManager::addSession(Session *session) { _sessions->insert(session); } bool RemoteControlManager::removeSession(Session *session) { if (getCurrentSession() == session) { setCurrentSession(nullptr); } bool ok = _sessions->remove(session); if (session != nullptr) { session->disconnect(); session->deleteLater(); } setConnectButtonChecked(false); setConnectButtonEnabled(true); currentSessionUrlChanged(tr("Not available yet")); currentSessionPinChanged("-----"); currentSessionSessionIDChanged("-----"); return ok; } void RemoteControlManager::setCurrentSession(Session *session) { if (session == nullptr) { qDebug() << "Deselecting currentSession."; _current_session = nullptr; return; } if (_sessions->contains(session)) { qDebug() << "Set currentSession to new session."; _current_session = session; connectSession(_current_session); } else { qDebug() << "Given session was not in _sessions!"; } } void RemoteControlManager::connectSession(Session *session) { // session --statusChanged-> this.currentSessionStatusChanged() CHECK_TRUE(QObject::connect(session, &Session::statusChanged, this, &RemoteControlManager::currentSessionStatusChanged)); // session --pinChanged-> this.currentSessionPinChanged() CHECK_TRUE(QObject::connect(session, &Session::pinChanged, this, &RemoteControlManager::currentSessionPinChanged)); // session --urlChanged-> this.currentSessionUrlChanged() CHECK_TRUE(QObject::connect(session, &Session::urlChanged, this, &RemoteControlManager::currentSessionUrlChanged)); // session --sessionIDChanged-> this.currentSessionSessionIDChanged() CHECK_TRUE(QObject::connect(session, &Session::sessionIDChanged, this, &RemoteControlManager::currentSessionSessionIDChanged)); // session --startSucceeded -> this.currentSessionStartSucceeded() CHECK_TRUE(QObject::connect(session, &Session::startSucceeded, this, &RemoteControlManager::currentSessionStartSucceeded)); // session --startFailed-> this.currentSessionStartFailed() CHECK_TRUE(QObject::connect(session, &Session::startFailed, this, &RemoteControlManager::currentSessionStartFailed)); // session --stopSucceeded-> this.currentSessionStopSucceeded() CHECK_TRUE(QObject::connect(session, &Session::stopSucceeded, this, &RemoteControlManager::currentSessionStopSucceeded)); // session --stopFailed-> this.currentSessionStopFailed() CHECK_TRUE(QObject::connect(session, &Session::stopFailed, this, &RemoteControlManager::currentSessionStopFailed)); // session --statusSucceeded-> this.currentSessionStatusSucceeded() CHECK_TRUE(QObject::connect(session, &Session::statusSucceeded, this, &RemoteControlManager::currentSessionStatusSucceeded)); // session --statusFailed-> this.currentSessionStatusFailed() CHECK_TRUE(QObject::connect(session, &Session::statusFailed, this, &RemoteControlManager::currentSessionStatusFailed)); } void RemoteControlManager::currentSessionStartFailed(QString error_message) { _main_gui->showToast(error_message, 6000, Toast::ToastType::ToastError); // Start failed. No need to stop session, so remove it directly. removeSession(getCurrentSession()); setConnectButtonChecked(false); setConnectButtonEnabled(true); emit _main_gui->showWindow(); } void RemoteControlManager::currentSessionStopFailed(QString error_message) { _main_gui->showToast(error_message, 6000, Toast::ToastType::ToastError); // Stop failed, so don't do anything! The user should try again. // Set status indicator to the corresponding error message. QString translated = translateStatusIndicatorText("stop_session_error"); setStatusIndicatorText(translated); setConnectButtonChecked(true); setConnectButtonEnabled(true); emit _main_gui->showWindow(); } void RemoteControlManager::currentSessionStatusFailed(QString error_message) { _main_gui->showToast(error_message, 6000, Toast::ToastType::ToastError); // Set status indicator to the corresponding error message. QString translated = translateStatusIndicatorText("status_session_error"); setStatusIndicatorText(translated); setConnectButtonChecked(false); setConnectButtonEnabled(true); currentSessionUrlChanged(tr("Not available yet")); currentSessionPinChanged("-----"); currentSessionSessionIDChanged("-----"); emit _main_gui->showWindow(); } void RemoteControlManager::currentSessionStartSucceeded() { Session *current_session = getCurrentSession(); if (current_session != nullptr) { _main_gui->showToast( tr("Session was started on '%0' successfully") .arg(current_session->getHost()->alias()), 6000, Toast::ToastType::ToastSuccess ); } else { qCritical().noquote() << tr("currentSessionStartSucceeded(): " "Current Session is nullptr!"); _engine->exit(1); } // Set status indicator to the corresponding error message. QString translated = translateStatusIndicatorText("start_session_success"); setStatusIndicatorText(translated); setConnectButtonChecked(true); setConnectButtonEnabled(true); } void RemoteControlManager::currentSessionStopSucceeded() { qDebug() << "Session stop succeeded: Delete current session object now."; bool ok = removeSession(getCurrentSession()); if (!ok) { qWarning() << tr("Couldn't remove current session out of '_sessions' list."); } _main_gui->showToast(tr("Remote support session was stopped."), 6000, Toast::ToastType::ToastSuccess); // Set status indicator to the corresponding error message. QString translated = translateStatusIndicatorText("stop_session_success"); setStatusIndicatorText(translated); setConnectButtonChecked(false); setConnectButtonEnabled(true); } void RemoteControlManager::currentSessionUnexpectedStop(QString error_message) { _main_gui->showToast(error_message, 6000, Toast::ToastType::ToastError); setConnectButtonChecked(false); setConnectButtonEnabled(true); qDebug() << "Delete current session object now."; bool ok = removeSession(getCurrentSession()); if (!ok) { qWarning() << tr("Couldn't remove current session out of '_sessions' list."); } } void RemoteControlManager::currentSessionStatusSucceeded() { // Nothing to do. } void RemoteControlManager::currentSessionStatusChanged(QString new_status_code) { Session *current_session = getCurrentSession(); if (current_session == nullptr || !current_session->started) { qDebug() << "RemoteControlManager::currentSessionStatusChanged(QString): " "got called even though the session isn't even started."; return; } QString translated = translateStatusIndicatorText(new_status_code); setStatusIndicatorText(translated); } QString RemoteControlManager::translateStatusIndicatorText(QString status_code) { QString guiString = tr("Unknown state of service"); setStatusIndicatorColor(false); if (status_code == "dead") { /* Session died */ guiString = tr("Remote Support session was stopped ungracefully"); // Red color setStatusIndicatorColor(true, QColor(255, 0, 0, 127)); currentSessionUnexpectedStop(guiString); } else if (status_code == "stopped") { /* Session was stopped normally somehow other than the users request. * Remote support partner could have clicked exit for example */ guiString = tr("Remote Support session was stopped"); // Green color setStatusIndicatorColor(true, QColor(0, 255, 0, 127)); currentSessionUnexpectedStop(guiString); } else if (status_code == "active") { /* Partner is connected */ guiString = tr("Your partner is connected to the Remote Support session"); // Green color setStatusIndicatorColor(true, QColor(0, 255, 0, 127)); } else if (status_code == "start_session_success" || status_code == "running") { /* Session successfully started */ guiString = tr("Remote Support session successfully started! " "Waiting for your remote support partner to connect."); // yellow color (will be green when partner is connected) setStatusIndicatorColor(true, QColor(255, 255, 0, 127)); } else if (status_code == "start_session_error") { /* Session couldn't be started */ guiString = tr("Remote Support session couldn't be started!"); // Red color setStatusIndicatorColor(true, QColor(255, 0, 0, 127)); } else if (status_code == "stop_session_success") { /* Session was successfully stopped by the users request */ guiString = tr("Session stopped successfully."); // Green color setStatusIndicatorColor(true, QColor(0, 255, 0, 127)); } else if (status_code == "stop_session_error") { /* Session couldn't be stopped */ guiString = tr("Session could not be stopped!") + "\n" + tr("remote support partner could still be connected!"); // Red color setStatusIndicatorColor(true, QColor(255, 0, 0, 127)); } else if (status_code == "status_session_error") { /* Session's status couldn't be refreshed */ guiString = tr("Session status could not be refreshed! " "Your remote support partner could still be connected!"); // Red color setStatusIndicatorColor(true, QColor(255, 0, 0, 127)); } qDebug().noquote() << QString("Translating status code '%0' to '%1'") .arg(status_code) .arg(guiString); return guiString; } void RemoteControlManager::currentSessionPinChanged(QString pin) { emit pinChanged(pin); } void RemoteControlManager::currentSessionUrlChanged(QString url) { emit urlChanged(url); } void RemoteControlManager::currentSessionSessionIDChanged(QString session_id) { emit sessionIDChanged(session_id); } void RemoteControlManager::connectToDBusAPI(Session *session) { // _dbus_api --sessionStartResponse-> this.start_response() CHECK_TRUE(QObject::connect(_dbus_api, &DBusAPI::serviceStartResponse, session, &Session::start_response)); // _dbus_api --serviceStopResponse-> this.stop_response() CHECK_TRUE(QObject::connect(_dbus_api, &DBusAPI::serviceStopResponse, session, &Session::stop_response, Qt::DirectConnection)); // _dbus_api --sessionStatusResponse-> this.status_response() CHECK_TRUE(QObject::connect(_dbus_api, &DBusAPI::serviceStatusResponse, session, &Session::status_response)); } void RemoteControlManager::handleConnectButtonClick(bool checked) { if (checked) { // Create a Session object and start it. qDebug() << "Creating and starting a new session object now."; RWAHost *selected_host = _main_gui->getSelectedRWAHost(); if (selected_host) { qInfo() << tr("Creating a new session object."); Session *new_session = new Session(_dbus_api, selected_host); connectToDBusAPI(new_session); qDebug() << "Adding session to QSet"; addSession(new_session); qDebug() << "Setting session as current session."; setCurrentSession(new_session); qInfo().noquote() << tr("Starting a remote support session on host '%0' " "using the new session object.") .arg(selected_host->uuid()); new_session->start(); } else { qCritical().noquote() << tr("Can't start a remote support session. " "There is no RWA host is selected!"); } setConnectButtonChecked(false); setConnectButtonEnabled(false); } else { Session *current_session = getCurrentSession(); if (current_session != nullptr) { emit current_session->stop(); } else { qCritical().noquote() << tr("RemoteControlManager::" "handleConnectButtonClick(): Current Session " "is nullptr!"); setConnectButtonChecked(false); setConnectButtonEnabled(true); } } } /*void RemoteControlManager::onCloseHandler() { // To cleanup things here // check current session nullptr getCurrentSession()->stop(); }*/