From 3ba635a077fd3f35c5f559f646bcfbe08f8cc836 Mon Sep 17 00:00:00 2001 From: Elias Steurer Date: Sat, 18 Jul 2020 19:06:53 +0200 Subject: [PATCH] Merge SDKConnector into ScreenPlayManager --- ScreenPlay/CMakeLists.txt | 2 - ScreenPlay/app.cpp | 15 +- ScreenPlay/app.h | 16 --- ScreenPlay/main.qml | 2 +- ScreenPlay/src/screenplaymanager.cpp | 190 ++++++++++++++++++++++--- ScreenPlay/src/screenplaymanager.h | 48 ++++--- ScreenPlay/src/screenplaywallpaper.cpp | 24 ++-- ScreenPlay/src/screenplaywallpaper.h | 5 +- ScreenPlay/src/sdkconnection.cpp | 6 + ScreenPlay/src/sdkconnection.h | 2 +- ScreenPlay/src/sdkconnector.cpp | 178 ----------------------- ScreenPlay/src/sdkconnector.h | 90 ------------ 12 files changed, 232 insertions(+), 346 deletions(-) delete mode 100644 ScreenPlay/src/sdkconnector.cpp delete mode 100644 ScreenPlay/src/sdkconnector.h diff --git a/ScreenPlay/CMakeLists.txt b/ScreenPlay/CMakeLists.txt index 819b0b40..91103e97 100644 --- a/ScreenPlay/CMakeLists.txt +++ b/ScreenPlay/CMakeLists.txt @@ -32,7 +32,6 @@ set(src main.cpp src/settings.cpp src/profilelistmodel.cpp src/installedlistfilter.cpp - src/sdkconnector.cpp src/projectsettingslistmodel.cpp src/screenplaymanager.cpp src/sdkconnection.cpp @@ -52,7 +51,6 @@ set(headers app.h src/profile.h src/projectfile.h src/installedlistfilter.h - src/sdkconnector.h src/projectsettingslistitem.h src/projectsettingslistmodel.h src/screenplaymanager.h diff --git a/ScreenPlay/app.cpp b/ScreenPlay/app.cpp index ab4cdeca..6b75ad77 100644 --- a/ScreenPlay/app.cpp +++ b/ScreenPlay/app.cpp @@ -28,7 +28,6 @@ namespace ScreenPlay { Create--> CreateVideoImport App --> Util App --> Settings - App --> SDKConnector App --> InstalledListModel InstalledListModel --> ProjectFile App --> InstalledListFilter @@ -79,7 +78,6 @@ App::App() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); - qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); @@ -111,17 +109,15 @@ App::App() "SearchType", "Error: only enums"); - qmlRegisterAnonymousType("ScreenPlay", 1); qmlRegisterAnonymousType("ScreenPlay", 1); qmlRegisterAnonymousType("ScreenPlay", 1); qmlRegisterAnonymousType("ScreenPlay", 1); qmlRegisterAnonymousType("ScreenPlay", 1); - qmlRegisterAnonymousType("ScreenPlay", 1); - // SDKConnect first to check if another ScreenPlay Instace is running - m_sdkConnector = std::make_shared(); - m_isAnotherScreenPlayInstanceRunning = m_sdkConnector->m_isAnotherScreenPlayInstanceRunning; + // ScreenPlayManager first to check if another ScreenPlay Instace is running + m_screenPlayManager = std::make_unique(); + m_isAnotherScreenPlayInstanceRunning = m_screenPlayManager->isAnotherScreenPlayInstanceRunning(); } /*! @@ -144,6 +140,7 @@ void App::init() m_profileListModel = make_shared(m_globalVariables); m_settings = make_shared(m_globalVariables); m_mainWindowEngine = make_unique(); + m_screenPlayManager->init(m_globalVariables, m_monitorListModel, m_telemetry, m_settings); // Only create tracker if user did not disallow! if (m_settings->anonymousTelemetry()) { @@ -155,8 +152,6 @@ void App::init() } m_create = make_unique(m_globalVariables); - m_screenPlayManager = make_unique(m_globalVariables, m_monitorListModel, m_sdkConnector, m_telemetry, m_settings); - QObject::connect(m_sdkConnector.get(), &SDKConnector::requestDecreaseWidgetCount, m_screenPlayManager.get(), &ScreenPlayManager::decreaseActiveWidgetsCounter); // When the installed storage path changed QObject::connect(m_settings.get(), &Settings::resetInstalledListmodel, m_installedListModel.get(), &InstalledListModel::reset); @@ -167,7 +162,7 @@ void App::init() m_settings->resetInstalledListmodel(); m_settings->setqSetting("ScreenPlayContentPath", localStoragePath.toString()); }); - QObject::connect(m_monitorListModel.get(), &MonitorListModel::monitorConfigurationChanged, m_sdkConnector.get(), &SDKConnector::closeAllWallpapers); + QObject::connect(m_monitorListModel.get(), &MonitorListModel::monitorConfigurationChanged, m_screenPlayManager.get(), &ScreenPlayManager::closeAllWallpapers); // Init after we have the paths from settings m_installedListModel->init(); diff --git a/ScreenPlay/app.h b/ScreenPlay/app.h index baa20fc3..9b613809 100644 --- a/ScreenPlay/app.h +++ b/ScreenPlay/app.h @@ -60,7 +60,6 @@ #include "src/monitorlistmodel.h" #include "src/profilelistmodel.h" #include "src/screenplaymanager.h" -#include "src/sdkconnector.h" #include "src/settings.h" #include "src/util.h" @@ -75,7 +74,6 @@ class App : public QObject { Q_PROPERTY(Create* create READ create WRITE setCreate NOTIFY createChanged) Q_PROPERTY(Util* util READ util WRITE setUtil NOTIFY utilChanged) Q_PROPERTY(Settings* settings READ settings WRITE setSettings NOTIFY settingsChanged) - Q_PROPERTY(SDKConnector* sdkConnector READ sdkConnector WRITE setSdkConnector NOTIFY sdkConnectorChanged) Q_PROPERTY(InstalledListModel* installedListModel READ installedListModel WRITE setInstalledListModel NOTIFY installedListModelChanged) Q_PROPERTY(InstalledListFilter* installedListFilter READ installedListFilter WRITE setInstalledListFilter NOTIFY installedListFilterChanged) @@ -133,10 +131,6 @@ public: return m_installedListFilter.get(); } - SDKConnector* sdkConnector() const - { - return m_sdkConnector.get(); - } QQmlApplicationEngine* mainWindowEngine() const { @@ -153,7 +147,6 @@ signals: void monitorListModelChanged(MonitorListModel* monitorListModel); void profileListModelChanged(ProfileListModel* profileListModel); void installedListFilterChanged(InstalledListFilter* installedListFilter); - void sdkConnectorChanged(SDKConnector* sdkConnector); void mainWindowEngineChanged(QQmlApplicationEngine* mainWindowEngine); public slots: @@ -245,14 +238,6 @@ public slots: emit installedListFilterChanged(m_installedListFilter.get()); } - void setSdkConnector(SDKConnector* sdkConnector) - { - if (m_sdkConnector.get() == sdkConnector) - return; - - m_sdkConnector.reset(sdkConnector); - emit sdkConnectorChanged(m_sdkConnector.get()); - } void setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine) { @@ -273,7 +258,6 @@ private: std::shared_ptr m_telemetry; std::shared_ptr m_globalVariables; std::shared_ptr m_settings; - std::shared_ptr m_sdkConnector; std::shared_ptr m_installedListModel; std::shared_ptr m_monitorListModel; diff --git a/ScreenPlay/main.qml b/ScreenPlay/main.qml index 69f19d5a..cfb04364 100644 --- a/ScreenPlay/main.qml +++ b/ScreenPlay/main.qml @@ -123,7 +123,7 @@ ApplicationWindow { } Connections { - target: ScreenPlay.sdkConnector + target: ScreenPlay.screenPlayManager function onRequestRaise() { window.show() } diff --git a/ScreenPlay/src/screenplaymanager.cpp b/ScreenPlay/src/screenplaymanager.cpp index c88ad5e1..0dd40b3c 100644 --- a/ScreenPlay/src/screenplaymanager.cpp +++ b/ScreenPlay/src/screenplaymanager.cpp @@ -16,20 +16,57 @@ namespace ScreenPlay { \brief Constructor-. */ ScreenPlayManager::ScreenPlayManager( - const std::shared_ptr& globalVariables, - const std::shared_ptr& mlm, - const std::shared_ptr& sdkc, - const std::shared_ptr& telemetry, - const std::shared_ptr& settings, QObject* parent) : QObject { parent } - , m_globalVariables { globalVariables } - , m_monitorListModel { mlm } - , m_sdkconnector { sdkc } - , m_telemetry { telemetry } - , m_settings { settings } + + , m_server { std::make_unique() } { - QObject::connect(m_sdkconnector.get(), &SDKConnector::appConnected, this, &ScreenPlayManager::appConnected); + + if (checkIsAnotherScreenPlayInstanceRunning()) { + m_isAnotherScreenPlayInstanceRunning = true; + return; + } + + QObject::connect(m_server.get(), &QLocalServer::newConnection, this, &ScreenPlayManager::newConnection); + m_server->setSocketOptions(QLocalServer::WorldAccessOption); + if (!m_server->listen("ScreenPlay")) { + qCritical("Could not open Local Socket with the name ScreenPlay!"); + } +} + +/*! + \brief Checks if another ScreenPlay instance is running by trying to connect to a pipe + with the name ScreenPlay. + If successful we send a raise command and quit via m_isAnotherScreenPlayInstanceRunning = true. +*/ +bool ScreenPlayManager::checkIsAnotherScreenPlayInstanceRunning() +{ + QLocalSocket socket; + socket.connectToServer("ScreenPlay"); + + if (!socket.isOpen()) { + socket.close(); + return false; + } + + qInfo("Another ScreenPlay app is already running!"); + QByteArray msg = "command=requestRaise"; + socket.write(msg); + socket.waitForBytesWritten(500); + socket.close(); + return true; +} + +void ScreenPlayManager::init( + const std::shared_ptr& globalVariables, + const std::shared_ptr& mlm, + const std::shared_ptr& telemetry, + const std::shared_ptr& settings) +{ + m_globalVariables = globalVariables; + m_monitorListModel = mlm; + m_telemetry = telemetry; + m_settings = settings; loadProfiles(); } @@ -95,7 +132,6 @@ void ScreenPlayManager::createWallpaper( wallpaper = std::make_shared( monitorIndex, m_globalVariables, - m_sdkconnector, appID, path, previewImage, @@ -166,7 +202,7 @@ void ScreenPlayManager::removeAllWallpapers() { if (!m_screenPlayWallpapers.empty()) { - m_sdkconnector->closeAllWallpapers(); + closeAllWallpapers(); m_screenPlayWallpapers.clear(); m_monitorListModel->clearActiveWallpaper(); @@ -195,7 +231,7 @@ void ScreenPlayManager::removeAllWallpapers() void ScreenPlayManager::removeAllWidgets() { if (!m_screenPlayWidgets.empty()) { - m_sdkconnector->closeAllWidgets(); + closeAllWidgets(); m_screenPlayWidgets.clear(); saveProfiles(); setActiveWidgetsCounter(0); @@ -213,7 +249,7 @@ bool ScreenPlayManager::removeWallpaperAt(int index) if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) { saveProfiles(); - if (!m_sdkconnector->closeWallpaper(*appID)) { + if (!closeWallpaper(*appID)) { qWarning() << "Could not close socket. Abort!"; return false; } @@ -262,7 +298,7 @@ void ScreenPlayManager::setWallpaperValueAtMonitorIndex(const int index, const Q { if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) { - m_sdkconnector->setWallpaperValue(*appID, key, value); + setWallpaperValue(*appID, key, value); if (auto wallpaper = getWallpaperByAppID(*appID)) { } @@ -275,7 +311,7 @@ void ScreenPlayManager::setWallpaperValueAtMonitorIndex(const int index, const Q void ScreenPlayManager::setAllWallpaperValue(const QString& key, const QString& value) { for (const std::shared_ptr& uPtrWallpaper : qAsConst(m_screenPlayWallpapers)) { - m_sdkconnector->setWallpaperValue(uPtrWallpaper->appID(), key, value); + setWallpaperValue(uPtrWallpaper->appID(), key, value); } } @@ -292,6 +328,125 @@ std::optional> ScreenPlayManager::getWallpa return std::nullopt; } +/*! + \brief Appends a new SDKConnection object shared_ptr to the m_clients list. +*/ +void ScreenPlayManager::newConnection() +{ + auto connection = std::make_shared(m_server->nextPendingConnection()); + // Because user can close widgets by pressing x the widgets must send us the event + QObject::connect(connection.get(), &SDKConnection::requestDecreaseWidgetCount, this, [this]() { setActiveWidgetsCounter(activeWallpaperCounter() - 1); }); + QObject::connect(connection.get(), &SDKConnection::requestRaise, this, &ScreenPlayManager::requestRaise); + // Only after we receive the first message with appID and type we can set the shared reference to the + // ScreenPlayWallpaper or ScreenPlayWidgets class + QObject::connect(connection.get(), &SDKConnection::appConnected, this, [this](const SDKConnection* connection) { + for (const auto& client : m_clients) { + if (client.get() == connection) { + appConnected(client); + return; + } + } + }); + m_clients.append(connection); +} + +/*! + \brief Closes all m_clients connections and clears the QVector. +*/ +void ScreenPlayManager::closeAllConnections() +{ + for (auto& client : m_clients) { + client->close(); + } + m_clients.clear(); + m_clients.squeeze(); +} + +/*! + \brief Closes all wallpaper connection with the following type: + \list + \li videoWallpaper + \li qmlWallpaper + \li htmlWallpaper + \li godotWallpaper + \endlist +*/ +void ScreenPlayManager::closeAllWallpapers() +{ + closeConntectionByType(GlobalVariables::getAvailableWallpaper()); +} + +/*! + \brief Closes all widgets connection with the following type: + \list + \li qmlWidget + \li htmlWidget + \li standaloneWidget + \endlist +*/ +void ScreenPlayManager::closeAllWidgets() +{ + closeConntectionByType(GlobalVariables::getAvailableWidgets()); +} + +/*! + \brief Closes a connection by type. Used only by closeAllWidgets() and closeAllWallpapers() +*/ +void ScreenPlayManager::closeConntectionByType(const QStringList& list) +{ + for (auto& client : m_clients) { + if (list.contains(client->type(), Qt::CaseInsensitive)) { + client->close(); + m_clients.removeOne(client); + } + } +} + +/*! + \brief Closes a wallpaper by the given \a appID. +*/ +bool ScreenPlayManager::closeWallpaper(const QString& appID) +{ + for (auto& client : m_clients) { + if (client->appID() == appID) { + client->close(); + m_clients.removeOne(client); + return true; + } + } + return false; +} + +/*! + \brief Sets a given \a value to a given \a key. The \a appID is used to identify the receiver socket. +*/ +void ScreenPlayManager::setWallpaperValue(QString appID, QString key, QString value) +{ + + for (int i = 0; i < m_clients.count(); ++i) { + if (m_clients.at(i)->appID() == appID) { + QJsonObject obj; + obj.insert(key, QJsonValue(value)); + + QByteArray send = QJsonDocument(obj).toJson(); + m_clients.at(i)->socket()->write(send); + m_clients.at(i)->socket()->waitForBytesWritten(); + } + } +} + +void ScreenPlayManager::replace(const QString& appID, const QJsonObject& obj) +{ + for (int i = 0; i < m_clients.count(); ++i) { + if (m_clients.at(i)->appID() == appID) { + + QByteArray send = QJsonDocument(obj).toJson(); + m_clients.at(i)->socket()->write(send); + m_clients.at(i)->socket()->waitForBytesWritten(); + } + } +} + /*! \brief Saves a given wallpaper \a newProfileObject to a \a profileName. We ignore the profileName argument because we currently only support one profile. Returns \c true if successfuly saved to profiles.json, otherwise \c false. @@ -435,4 +590,5 @@ void ScreenPlayManager::loadProfiles() } } } + } diff --git a/ScreenPlay/src/screenplaymanager.h b/ScreenPlay/src/screenplaymanager.h index 6b97e0b7..1b094e1c 100644 --- a/ScreenPlay/src/screenplaymanager.h +++ b/ScreenPlay/src/screenplaymanager.h @@ -48,7 +48,6 @@ #include "projectsettingslistmodel.h" #include "screenplaywallpaper.h" #include "screenplaywidget.h" -#include "sdkconnector.h" #include "settings.h" #include "util.h" @@ -65,11 +64,7 @@ class ScreenPlayManager : public QObject { public: explicit ScreenPlayManager( - const std::shared_ptr& globalVariables, - const std::shared_ptr& mlm, - const std::shared_ptr& sdkc, - const std::shared_ptr& telemetry, - const std::shared_ptr& settings, + QObject* parent = nullptr); int activeWallpaperCounter() const @@ -81,6 +76,16 @@ public: { return m_activeWidgetsCounter; } + bool isAnotherScreenPlayInstanceRunning() + { + return m_isAnotherScreenPlayInstanceRunning; + } + + void init( + const std::shared_ptr& globalVariables, + const std::shared_ptr& mlm, + const std::shared_ptr& telemetry, + const std::shared_ptr& settings); signals: void projectSettingsListModelResult( @@ -89,10 +94,9 @@ signals: const ScreenPlay::InstalledType::InstalledType type = ScreenPlay::InstalledType::InstalledType::VideoWallpaper); void activeWallpaperCounterChanged(int activeWallpaperCounter); void activeWidgetsCounterChanged(int activeWidgetsCounter); + void requestRaise(); public slots: - void saveProfiles(); - // moc needs full enum namespace info see QTBUG-58454 void createWallpaper( const ScreenPlay::InstalledType::InstalledType type, @@ -109,8 +113,6 @@ public slots: const QString& previewImage, const bool saveToProfilesConfigFile); - void appConnected(const std::shared_ptr& connection); - void removeAllWallpapers(); void removeAllWidgets(); bool removeWallpaperAt(const int index); @@ -120,6 +122,16 @@ public slots: void setAllWallpaperValue(const QString& key, const QString& value); std::optional> getWallpaperByAppID(const QString& appID); + void saveProfiles(); + void newConnection(); + void closeAllConnections(); + void closeAllWallpapers(); + void closeAllWidgets(); + void closeConntectionByType(const QStringList& list); + bool closeWallpaper(const QString& appID); + void setWallpaperValue(QString appID, QString key, QString value); + void replace(const QString& appID, const QJsonObject& obj); + void setActiveWallpaperCounter(int activeWallpaperCounter) { if (m_activeWallpaperCounter == activeWallpaperCounter) @@ -170,20 +182,24 @@ public slots: private: void loadProfiles(); - + void appConnected(const std::shared_ptr& connection); + bool checkIsAnotherScreenPlayInstanceRunning(); [[nodiscard]] bool removeWallpaperByAppID(const QString& appID); private: - const std::shared_ptr& m_globalVariables; - const std::shared_ptr& m_monitorListModel; - const std::shared_ptr& m_sdkconnector; - const std::shared_ptr& m_telemetry; - const std::shared_ptr& m_settings; + std::shared_ptr m_globalVariables; + std::shared_ptr m_monitorListModel; + std::shared_ptr m_telemetry; + std::shared_ptr m_settings; + std::unique_ptr m_server; QVector> m_screenPlayWallpapers; QVector> m_screenPlayWidgets; + QVector> m_clients; int m_activeWallpaperCounter { 0 }; int m_activeWidgetsCounter { 0 }; + + bool m_isAnotherScreenPlayInstanceRunning = false; }; } diff --git a/ScreenPlay/src/screenplaywallpaper.cpp b/ScreenPlay/src/screenplaywallpaper.cpp index 279be2c4..38219fd0 100644 --- a/ScreenPlay/src/screenplaywallpaper.cpp +++ b/ScreenPlay/src/screenplaywallpaper.cpp @@ -16,7 +16,6 @@ namespace ScreenPlay { ScreenPlayWallpaper::ScreenPlayWallpaper( const QVector& screenNumber, const std::shared_ptr& globalVariables, - const std::shared_ptr& sdkConnector, const QString& appID, const QString& absolutePath, const QString& previewImage, @@ -29,7 +28,6 @@ ScreenPlayWallpaper::ScreenPlayWallpaper( : QObject(parent) , m_projectSettingsListModel { absolutePath + "/project.json" } , m_globalVariables { globalVariables } - , m_sdkConnector { sdkConnector } , m_screenNumber { screenNumber } , m_previewImage { previewImage } , m_type { type } @@ -116,22 +114,24 @@ ProjectSettingsListModel* ScreenPlayWallpaper::getProjectSettingsListModel() return &m_projectSettingsListModel; } -void ScreenPlayWallpaper::setSDKConnection(const std::shared_ptr &connection) +void ScreenPlayWallpaper::setSDKConnection(const std::shared_ptr& connection) { m_connection = connection; qInfo() << "App Wallpaper connected!"; - //QObject::connect(m_connection.get(),&SDKConnection::readyRead,this,[](){}); } void ScreenPlayWallpaper::replace( - const QString& absolutePath, - const QString& previewImage, - const QString& file, - const float volume, - const FillMode::FillMode fillMode, - const InstalledType::InstalledType type, - const bool checkWallpaperVisible) + const QString& absolutePath, + const QString& previewImage, + const QString& file, + const float volume, + const FillMode::FillMode fillMode, + const InstalledType::InstalledType type, + const bool checkWallpaperVisible) { + if (!m_connection) + return; + m_previewImage = previewImage; m_type = type; m_fillMode = fillMode; @@ -147,7 +147,7 @@ void ScreenPlayWallpaper::replace( obj.insert("file", file); obj.insert("checkWallpaperVisible", checkWallpaperVisible); - m_sdkConnector->replace(m_appID, obj); + m_connection->sendMessage(QJsonDocument(obj).toJson()); } } diff --git a/ScreenPlay/src/screenplaywallpaper.h b/ScreenPlay/src/screenplaywallpaper.h index db76b3d7..fc61c286 100644 --- a/ScreenPlay/src/screenplaywallpaper.h +++ b/ScreenPlay/src/screenplaywallpaper.h @@ -44,7 +44,6 @@ #include "globalvariables.h" #include "projectsettingslistmodel.h" #include "sdkconnection.h" -#include "sdkconnector.h" namespace ScreenPlay { @@ -69,7 +68,6 @@ public: explicit ScreenPlayWallpaper( const QVector& screenNumber, const std::shared_ptr& globalVariables, - const std::shared_ptr& sdkConnector, const QString& appID, const QString& absolutePath, const QString& previewImage, @@ -82,6 +80,8 @@ public: QJsonObject getActiveSettingsJson(); + bool m_isAnotherScreenPlayInstanceRunning { false }; + QVector screenNumber() const { return m_screenNumber; @@ -245,7 +245,6 @@ private: ProjectSettingsListModel m_projectSettingsListModel; const std::shared_ptr& m_globalVariables; - const std::shared_ptr& m_sdkConnector; std::shared_ptr m_connection; QVector m_screenNumber; diff --git a/ScreenPlay/src/sdkconnection.cpp b/ScreenPlay/src/sdkconnection.cpp index 1db784ee..6b657084 100644 --- a/ScreenPlay/src/sdkconnection.cpp +++ b/ScreenPlay/src/sdkconnection.cpp @@ -66,6 +66,12 @@ void ScreenPlay::SDKConnection::readyRead() } } +void ScreenPlay::SDKConnection::sendMessage(const QByteArray &message) +{ + m_socket->write(message); + m_socket->waitForBytesWritten(); +} + void ScreenPlay::SDKConnection::close() { diff --git a/ScreenPlay/src/sdkconnection.h b/ScreenPlay/src/sdkconnection.h index b5ec102b..3e32ff9f 100644 --- a/ScreenPlay/src/sdkconnection.h +++ b/ScreenPlay/src/sdkconnection.h @@ -103,7 +103,7 @@ signals: public slots: void readyRead(); - + void sendMessage(const QByteArray& message); void close(); void setAppID(QString appID) diff --git a/ScreenPlay/src/sdkconnector.cpp b/ScreenPlay/src/sdkconnector.cpp deleted file mode 100644 index 93c8e0e4..00000000 --- a/ScreenPlay/src/sdkconnector.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "sdkconnector.h" -#include "sdkconnection.h" - -namespace ScreenPlay { - -/*! - \class ScreenPlay::SDKConnector - \inmodule ScreenPlay - \brief SDKConnector is used for the QLocalSocket connection between ScreenPlay and the standalone ScreenPlayWallpaper and ScreenPlayWidget executables. - - To deal with crashes in faulty widgets and wallpaper we open an external application. The communication is done via the ScreenPlaySDK subproject. - To identify a incomming connection we use the appID. When a new connection is established we save the QLocalSocket and wait for the first message. - If the message contains "appID=MyUniqueKeyA-Z_a-z_0-9,type=qmlWallpaper" we cant map the socket to a wallpaper/widget. -*/ - -/*! - \brief Starts the QLocalServer with the pipename ScreenPlay. -*/ -SDKConnector::SDKConnector(QObject* parent) - : QObject(parent) - , m_server { std::make_unique() } -{ - - if (isAnotherScreenPlayInstanceRunning()) { - m_isAnotherScreenPlayInstanceRunning = true; - return; - } - - connect(m_server.get(), &QLocalServer::newConnection, this, &SDKConnector::newConnection); - m_server->setSocketOptions(QLocalServer::WorldAccessOption); - if (!m_server->listen("ScreenPlay")) { - qCritical("Could not open Local Socket with the name ScreenPlay!"); - } -} - -/*! - \brief Checks if another ScreenPlay instance is running by trying to connect to a pipe - with the name ScreenPlay. - If successful we send a raise command and quit via m_isAnotherScreenPlayInstanceRunning = true. -*/ -bool SDKConnector::isAnotherScreenPlayInstanceRunning() -{ - QLocalSocket socket; - socket.connectToServer("ScreenPlay"); - - if (!socket.isOpen()) { - socket.close(); - return false; - } - - qInfo("Another ScreenPlay app is already running!"); - QByteArray msg = "command=requestRaise"; - socket.write(msg); - socket.waitForBytesWritten(500); - socket.close(); - return true; -} - -/*! - \brief Appends a new SDKConnection object shared_ptr to the m_clients list. -*/ -void SDKConnector::newConnection() -{ - auto connection = std::make_shared(m_server->nextPendingConnection()); - // Because user can close widgets by pressing x the widgets must send us the event - QObject::connect(connection.get(), &SDKConnection::requestDecreaseWidgetCount, this, &SDKConnector::requestDecreaseWidgetCount); - QObject::connect(connection.get(), &SDKConnection::requestRaise, this, &SDKConnector::requestRaise); - // Only after we receive the first message with appID and type we can set the shared reference to the - // ScreenPlayWallpaper or ScreenPlayWidgets class - QObject::connect(connection.get(), &SDKConnection::appConnected, this, [this](const SDKConnection* connection) { - for (const auto& client : m_clients) { - if (client.get() == connection) { - emit appConnected(client); - return; - } - } - }); - m_clients.append(connection); -} - -/*! - \brief Closes all m_clients connections and clears the QVector. -*/ -void SDKConnector::closeAllConnections() -{ - for (auto& client : m_clients) { - client->close(); - } - m_clients.clear(); - m_clients.squeeze(); -} - -/*! - \brief Closes all wallpaper connection with the following type: - \list - \li videoWallpaper - \li qmlWallpaper - \li htmlWallpaper - \li godotWallpaper - \endlist -*/ -void SDKConnector::closeAllWallpapers() -{ - closeConntectionByType(GlobalVariables::getAvailableWallpaper()); -} - -/*! - \brief Closes all widgets connection with the following type: - \list - \li qmlWidget - \li htmlWidget - \li standaloneWidget - \endlist -*/ -void SDKConnector::closeAllWidgets() -{ - closeConntectionByType(GlobalVariables::getAvailableWidgets()); -} - -/*! - \brief Closes a connection by type. Used only by closeAllWidgets() and closeAllWallpapers() -*/ -void SDKConnector::closeConntectionByType(const QStringList& list) -{ - for (auto& client : m_clients) { - if (list.contains(client->type(), Qt::CaseInsensitive)) { - client->close(); - m_clients.removeOne(client); - } - } -} - -/*! - \brief Closes a wallpaper by the given \a appID. -*/ -bool SDKConnector::closeWallpaper(const QString& appID) -{ - for (auto& client : m_clients) { - if (client->appID() == appID) { - client->close(); - m_clients.removeOne(client); - return true; - } - } - return false; -} - -/*! - \brief Sets a given \a value to a given \a key. The \a appID is used to identify the receiver socket. -*/ -void SDKConnector::setWallpaperValue(QString appID, QString key, QString value) -{ - - for (int i = 0; i < m_clients.count(); ++i) { - if (m_clients.at(i)->appID() == appID) { - QJsonObject obj; - obj.insert(key, QJsonValue(value)); - - QByteArray send = QJsonDocument(obj).toJson(); - m_clients.at(i)->socket()->write(send); - m_clients.at(i)->socket()->waitForBytesWritten(); - } - } -} - -void SDKConnector::replace(const QString& appID, const QJsonObject& obj) -{ - for (int i = 0; i < m_clients.count(); ++i) { - if (m_clients.at(i)->appID() == appID) { - - QByteArray send = QJsonDocument(obj).toJson(); - m_clients.at(i)->socket()->write(send); - m_clients.at(i)->socket()->waitForBytesWritten(); - } - } -} - -} diff --git a/ScreenPlay/src/sdkconnector.h b/ScreenPlay/src/sdkconnector.h deleted file mode 100644 index 88b335f0..00000000 --- a/ScreenPlay/src/sdkconnector.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Elias Steurer (Kelteseth) -** Contact: https://screen-play.app -** -** This file is part of ScreenPlay. ScreenPlay is licensed under a dual license in -** order to ensure its sustainability. When you contribute to ScreenPlay -** you accept that your work will be available under the two following licenses: -** -** $SCREENPLAY_BEGIN_LICENSE$ -** -** #### Affero General Public License Usage (AGPLv3) -** Alternatively, this file may be used under the terms of the GNU Affero -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file "ScreenPlay License.md" included in the -** packaging of this App. Please review the following information to -** ensure the GNU Affero Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/agpl-3.0.en.html. -** -** #### Commercial License -** This code is owned by Elias Steurer. By changing/adding to the code you agree to the -** terms written in: -** * Legal/corporate_contributor_license_agreement.md - For corporate contributors -** * Legal/individual_contributor_license_agreement.md - For individual contributors -** -** #### Additional Limitations to the AGPLv3 and Commercial Lincese -** This License does not grant any rights in the trademarks, -** service marks, or logos. -** -** -** $SCREENPLAY_END_LICENSE$ -** -****************************************************************************/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "globalvariables.h" -#include "util.h" - -/*! - \class SDKConnector - \brief Used for every Wallpaper, Scene or Widget communication via Windows pipes/QLocalSocket - -*/ - -namespace ScreenPlay { -class SDKConnection; - -class SDKConnector : public QObject { - Q_OBJECT - -public: - explicit SDKConnector(QObject* parent = nullptr); - - bool m_isAnotherScreenPlayInstanceRunning { false }; - -signals: - void requestDecreaseWidgetCount(); - void requestRaise(); - void appConnected(const std::shared_ptr& connection); - -public slots: - void newConnection(); - void closeConntectionByType(const QStringList& list); - void closeAllConnections(); - void closeAllWallpapers(); - void closeAllWidgets(); - bool closeWallpaper(const QString& appID); - void setWallpaperValue(QString appID, QString key, QString value); - void replace(const QString& appID, const QJsonObject& obj); - -private: - std::unique_ptr m_server; - QVector> m_clients; - bool isAnotherScreenPlayInstanceRunning(); -}; - -}