diff --git a/src/apps/deskflow-client/CMakeLists.txt b/src/apps/deskflow-client/CMakeLists.txt index 2c4fc34a2..7d7621a50 100644 --- a/src/apps/deskflow-client/CMakeLists.txt +++ b/src/apps/deskflow-client/CMakeLists.txt @@ -32,7 +32,6 @@ target_link_libraries( io mt net - ipc platform server app diff --git a/src/apps/deskflow-core/CMakeLists.txt b/src/apps/deskflow-core/CMakeLists.txt index 674897f65..cbb308656 100644 --- a/src/apps/deskflow-core/CMakeLists.txt +++ b/src/apps/deskflow-core/CMakeLists.txt @@ -27,7 +27,6 @@ target_link_libraries( io mt net - ipc platform server app diff --git a/src/apps/deskflow-daemon/CMakeLists.txt b/src/apps/deskflow-daemon/CMakeLists.txt index 46ebab44b..09c3052f3 100644 --- a/src/apps/deskflow-daemon/CMakeLists.txt +++ b/src/apps/deskflow-daemon/CMakeLists.txt @@ -21,7 +21,6 @@ if(WIN32) arch base io - ipc mt net platform diff --git a/src/apps/deskflow-gui/MainWindow.h b/src/apps/deskflow-gui/MainWindow.h index b4ea786a5..bff501dce 100644 --- a/src/apps/deskflow-gui/MainWindow.h +++ b/src/apps/deskflow-gui/MainWindow.h @@ -18,7 +18,6 @@ #include "ServerConfig.h" #include "VersionChecker.h" -#include "common/ipc.h" #include "gui/config/AppConfig.h" #include "gui/config/ConfigScopes.h" #include "gui/config/ServerConfigDialogState.h" @@ -146,7 +145,6 @@ private: void setIcon(); bool checkForApp(int which, QString &app); void setStatus(const QString &status); - void sendIpcMessage(IpcMessageType type, const char *buffer, bool showErrors); void updateFromLogLine(const QString &line); QString getIPAddresses() const; void enableServer(bool enable); diff --git a/src/apps/deskflow-server/CMakeLists.txt b/src/apps/deskflow-server/CMakeLists.txt index bc60d849e..f6855e9d2 100644 --- a/src/apps/deskflow-server/CMakeLists.txt +++ b/src/apps/deskflow-server/CMakeLists.txt @@ -32,7 +32,6 @@ target_link_libraries( io mt net - ipc platform server app diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index e01e51b9b..e936fa077 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -9,7 +9,6 @@ add_subdirectory(client) add_subdirectory(common) add_subdirectory(deskflow) add_subdirectory(io) -add_subdirectory(ipc) add_subdirectory(mt) add_subdirectory(net) add_subdirectory(platform) diff --git a/src/lib/base/Event.cpp b/src/lib/base/Event.cpp index a0eb89f35..f90fea09f 100644 --- a/src/lib/base/Event.cpp +++ b/src/lib/base/Event.cpp @@ -6,7 +6,6 @@ */ #include "base/Event.h" -#include "base/EventQueue.h" // // Event diff --git a/src/lib/base/EventQueue.cpp b/src/lib/base/EventQueue.cpp index 9d52539b0..b693c7709 100644 --- a/src/lib/base/EventQueue.cpp +++ b/src/lib/base/EventQueue.cpp @@ -8,21 +8,17 @@ #include "base/EventQueue.h" #include "arch/Arch.h" -#include "base/EventTypes.h" #include "base/IEventJob.h" #include "base/Log.h" #include "base/SimpleEventQueueBuffer.h" #include "base/Stopwatch.h" -#include "base/XBase.h" #include "mt/Lock.h" #include "mt/Mutex.h" +#include + EVENT_TYPE_ACCESSOR(Client) EVENT_TYPE_ACCESSOR(IStream) -EVENT_TYPE_ACCESSOR(IpcClient) -EVENT_TYPE_ACCESSOR(IpcClientProxy) -EVENT_TYPE_ACCESSOR(IpcServer) -EVENT_TYPE_ACCESSOR(IpcServerProxy) EVENT_TYPE_ACCESSOR(IDataSocket) EVENT_TYPE_ACCESSOR(IListenSocket) EVENT_TYPE_ACCESSOR(ISocket) @@ -55,10 +51,6 @@ EventQueue::EventQueue() m_nextType(Event::kLast), m_typesForClient(NULL), m_typesForIStream(NULL), - m_typesForIpcClient(NULL), - m_typesForIpcClientProxy(NULL), - m_typesForIpcServer(NULL), - m_typesForIpcServerProxy(NULL), m_typesForIDataSocket(NULL), m_typesForIListenSocket(NULL), m_typesForISocket(NULL), diff --git a/src/lib/base/EventQueue.h b/src/lib/base/EventQueue.h index 73705c422..e6f0b7209 100644 --- a/src/lib/base/EventQueue.h +++ b/src/lib/base/EventQueue.h @@ -130,10 +130,6 @@ public: // ClientEvents &forClient(); IStreamEvents &forIStream(); - IpcClientEvents &forIpcClient(); - IpcClientProxyEvents &forIpcClientProxy(); - IpcServerEvents &forIpcServer(); - IpcServerProxyEvents &forIpcServerProxy(); IDataSocketEvents &forIDataSocket(); IListenSocketEvents &forIListenSocket(); ISocketEvents &forISocket(); @@ -153,10 +149,6 @@ public: private: ClientEvents *m_typesForClient; IStreamEvents *m_typesForIStream; - IpcClientEvents *m_typesForIpcClient; - IpcClientProxyEvents *m_typesForIpcClientProxy; - IpcServerEvents *m_typesForIpcServer; - IpcServerProxyEvents *m_typesForIpcServerProxy; IDataSocketEvents *m_typesForIDataSocket; IListenSocketEvents *m_typesForIListenSocket; ISocketEvents *m_typesForISocket; diff --git a/src/lib/base/EventTypes.cpp b/src/lib/base/EventTypes.cpp index 1d6bb1699..e7fd2f246 100644 --- a/src/lib/base/EventTypes.cpp +++ b/src/lib/base/EventTypes.cpp @@ -45,26 +45,6 @@ REGISTER_EVENT(IStream, inputShutdown) REGISTER_EVENT(IStream, outputShutdown) REGISTER_EVENT(IStream, inputFormatError) -// -// IpcClient -// - -REGISTER_EVENT(IpcClient, connected) -REGISTER_EVENT(IpcClient, messageReceived) - -// -// IpcClientProxy -// - -REGISTER_EVENT(IpcClientProxy, messageReceived) -REGISTER_EVENT(IpcClientProxy, disconnected) - -// -// IpcServerProxy -// - -REGISTER_EVENT(IpcServerProxy, messageReceived) - // // IDataSocket // @@ -167,13 +147,6 @@ REGISTER_EVENT(IScreen, shapeChanged) REGISTER_EVENT(IScreen, suspend) REGISTER_EVENT(IScreen, resume) -// -// IpcServer -// - -REGISTER_EVENT(IpcServer, clientConnected) -REGISTER_EVENT(IpcServer, messageReceived) - // // Clipboard // diff --git a/src/lib/base/EventTypes.h b/src/lib/base/EventTypes.h index d161caed0..f5eeafaf5 100644 --- a/src/lib/base/EventTypes.h +++ b/src/lib/base/EventTypes.h @@ -145,94 +145,6 @@ private: Event::Type m_inputFormatError; }; -class IpcClientEvents : public EventTypes -{ -public: - IpcClientEvents() : m_connected(Event::kUnknown), m_messageReceived(Event::kUnknown) - { - } - - //! @name accessors - //@{ - - //! Raised when the socket is connected. - Event::Type connected(); - - //! Raised when a message is received. - Event::Type messageReceived(); - - //@} - -private: - Event::Type m_connected; - Event::Type m_messageReceived; -}; - -class IpcClientProxyEvents : public EventTypes -{ -public: - IpcClientProxyEvents() : m_messageReceived(Event::kUnknown), m_disconnected(Event::kUnknown) - { - } - - //! @name accessors - //@{ - - //! Raised when the server receives a message from a client. - Event::Type messageReceived(); - - //! Raised when the client disconnects from the server. - Event::Type disconnected(); - - //@} - -private: - Event::Type m_messageReceived; - Event::Type m_disconnected; -}; - -class IpcServerEvents : public EventTypes -{ -public: - IpcServerEvents() : m_clientConnected(Event::kUnknown), m_messageReceived(Event::kUnknown) - { - } - - //! @name accessors - //@{ - - //! Raised when we have created the client proxy. - Event::Type clientConnected(); - - //! Raised when a message is received through a client proxy. - Event::Type messageReceived(); - - //@} - -private: - Event::Type m_clientConnected; - Event::Type m_messageReceived; -}; - -class IpcServerProxyEvents : public EventTypes -{ -public: - IpcServerProxyEvents() : m_messageReceived(Event::kUnknown) - { - } - - //! @name accessors - //@{ - - //! Raised when the client receives a message from the server. - Event::Type messageReceived(); - - //@} - -private: - Event::Type m_messageReceived; -}; - class IDataSocketEvents : public EventTypes { public: diff --git a/src/lib/base/IEventQueue.h b/src/lib/base/IEventQueue.h index 97fe7766d..9882a3565 100644 --- a/src/lib/base/IEventQueue.h +++ b/src/lib/base/IEventQueue.h @@ -21,10 +21,6 @@ class EventQueueTimer; // Event type registration classes. class ClientEvents; class IStreamEvents; -class IpcClientEvents; -class IpcClientProxyEvents; -class IpcServerEvents; -class IpcServerProxyEvents; class IDataSocketEvents; class IListenSocketEvents; class ISocketEvents; @@ -216,10 +212,6 @@ public: virtual ClientEvents &forClient() = 0; virtual IStreamEvents &forIStream() = 0; - virtual IpcClientEvents &forIpcClient() = 0; - virtual IpcClientProxyEvents &forIpcClientProxy() = 0; - virtual IpcServerEvents &forIpcServer() = 0; - virtual IpcServerProxyEvents &forIpcServerProxy() = 0; virtual IDataSocketEvents &forIDataSocket() = 0; virtual IListenSocketEvents &forIListenSocket() = 0; virtual ISocketEvents &forISocket() = 0; diff --git a/src/lib/common/CMakeLists.txt b/src/lib/common/CMakeLists.txt index ec26b3c0b..e9e1bdae9 100644 --- a/src/lib/common/CMakeLists.txt +++ b/src/lib/common/CMakeLists.txt @@ -8,7 +8,6 @@ configure_file(constants.h.in constants.h @ONLY) add_library(common INTERFACE common.h IInterface.h - ipc.h stdbitset.h stddeque.h stdexcept.h diff --git a/src/lib/common/common.h b/src/lib/common/common.h index a99125f98..9356e73d3 100644 --- a/src/lib/common/common.h +++ b/src/lib/common/common.h @@ -45,7 +45,7 @@ enum #if WINAPI_MSWINDOWS namespace deskflow::common { -const auto kCloseEventName = "Global\\DeskflowCloseEvent"; +const auto kCloseEventName = "Global\\DeskflowClose"; } #endif diff --git a/src/lib/common/ipc.h b/src/lib/common/ipc.h deleted file mode 100644 index 9fb819b4c..000000000 --- a/src/lib/common/ipc.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "common.h" - -enum class IpcMessageType : uint8_t -{ - Hello, - HelloBack, - LogLine, - Command, - Shutdown, - Setting -}; - -enum class IpcClientType -{ - Unknown, - GUI, - Node -}; - -const auto kIpcHost = "127.0.0.1"; -const auto kIpcPort = 24801; - -// handshake: node/gui -> daemon -// $1 = type, the client identifies it's self as gui or core (server/client). -const auto kIpcMsgHello = "IHEL%1i"; - -// handshake: daemon -> node/gui -// the daemon responds to the handshake. -const auto kIpcMsgHelloBack = "IHEL"; - -// log line: daemon -> gui -// $1 = aggregate log lines collected from core (server/client) or the daemon -// itself. -const auto kIpcMsgLogLine = "ILOG%s"; - -// command: gui -> daemon -// $1 = command; the command for the daemon to launch, typically the full -// path to core (server/client). $2 = true when process must be elevated on ms -// windows. -const auto kIpcMsgCommand = "ICMD%s%1i"; - -// shutdown: daemon -> node -// the daemon tells core (server/client) to shut down gracefully. -const auto kIpcMsgShutdown = "ISDN"; - -// set setting: gui -> daemon -// $1 = setting name -// $2 = setting value -const auto kIpcMsgSetting = "SSET%s%s"; diff --git a/src/lib/deskflow/App.cpp b/src/lib/deskflow/App.cpp index 0973eacf1..a7c314400 100644 --- a/src/lib/deskflow/App.cpp +++ b/src/lib/deskflow/App.cpp @@ -1,6 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. + * SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception */ @@ -9,36 +9,23 @@ #include "DisplayInvalidException.h" #include "arch/Arch.h" -#include "arch/XArch.h" -#include "base/EventQueue.h" #include "base/Log.h" -#include "base/TMethodEventJob.h" -#include "base/XBase.h" #include "base/log_outputters.h" #include "common/constants.h" -#include "common/ipc.h" #include "deskflow/ArgsBase.h" #include "deskflow/Config.h" #include "deskflow/XDeskflow.h" #include "deskflow/protocol_types.h" -#include "ipc/IpcMessage.h" -#include "ipc/IpcServerProxy.h" -#include #if SYSAPI_WIN32 -#include "arch/win32/ArchMiscWindows.h" #include "base/IEventQueue.h" -#include "base/TMethodJob.h" #endif #if WINAPI_CARBON #include "platform/OSXDragSimulator.h" #endif -#include -#include #include -#include #include #include #include @@ -64,7 +51,6 @@ App::App(IEventQueue *events, deskflow::ArgsBase *args) m_args(args), m_fileLog(nullptr), m_appUtil(events), - m_ipcClient(nullptr), m_socketMultiplexer(nullptr) { assert(s_instance == nullptr); @@ -208,32 +194,6 @@ void App::initApp(int argc, const char **argv) loadConfig(); } -void App::initIpcClient() -{ - m_ipcClient = new IpcClient(m_events, m_socketMultiplexer); - m_ipcClient->connect(); - - m_events->adoptHandler( - m_events->forIpcClient().messageReceived(), m_ipcClient, new TMethodEventJob(this, &App::handleIpcMessage) - ); -} - -void App::cleanupIpcClient() -{ - m_ipcClient->disconnect(); - m_events->removeHandler(m_events->forIpcClient().messageReceived(), m_ipcClient); - delete m_ipcClient; -} - -void App::handleIpcMessage(const Event &e, void *) -{ - IpcMessage *m = static_cast(e.getDataObject()); - if (m->type() == IpcMessageType::Shutdown) { - LOG((CLOG_INFO "got ipc shutdown message")); - m_events->addEvent(Event(Event::kQuit)); - } -} - void App::runEventsLoop(void *) { m_events->loop(); diff --git a/src/lib/deskflow/App.h b/src/lib/deskflow/App.h index 072d0c375..5e85f8a30 100644 --- a/src/lib/deskflow/App.h +++ b/src/lib/deskflow/App.h @@ -1,6 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. + * SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd. * SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception */ @@ -11,7 +11,6 @@ #include "base/Log.h" #include "common/common.h" #include "deskflow/IApp.h" -#include "ipc/IpcClient.h" #if SYSAPI_WIN32 #include "deskflow/win32/AppUtilWindows.h" @@ -20,7 +19,6 @@ #endif #include -#include namespace deskflow { class Screen; @@ -110,12 +108,7 @@ public: void (*m_bye)(int); -private: - void handleIpcMessage(const Event &, void *); - protected: - void initIpcClient(); - void cleanupIpcClient(); void runEventsLoop(void *); bool m_suspended; @@ -126,7 +119,6 @@ private: static App *s_instance; FileLogOutputter *m_fileLog; ARCH_APP_UTIL m_appUtil; - IpcClient *m_ipcClient; SocketMultiplexer *m_socketMultiplexer; }; diff --git a/src/lib/deskflow/ArgParser.cpp b/src/lib/deskflow/ArgParser.cpp index 2882c0ede..c022a6808 100644 --- a/src/lib/deskflow/ArgParser.cpp +++ b/src/lib/deskflow/ArgParser.cpp @@ -188,8 +188,6 @@ bool ArgParser::parseGenericArgs(int argc, const char *const *argv, int &i) m_app->version(); } argsBase().m_shouldExitOk = true; - } else if (isArg(i, argc, argv, nullptr, "--ipc")) { - argsBase().m_enableIpc = true; } else if (isArg(i, argc, argv, nullptr, "--server")) { // HACK: stop error happening when using portable (deskflowp) } else if (isArg(i, argc, argv, nullptr, "--client")) { diff --git a/src/lib/deskflow/ArgsBase.h b/src/lib/deskflow/ArgsBase.h index e9b80e5b2..d7f69670d 100644 --- a/src/lib/deskflow/ArgsBase.h +++ b/src/lib/deskflow/ArgsBase.h @@ -56,8 +56,8 @@ public: /// @brief The name of the current computer std::string m_name; - /// @brief Tell the client to talk through IPC to the daemon - bool m_enableIpc = false; + /// @brief Should the app add a tray icon + bool m_disableTray = false; /// @brief Should drag drop support be enabled bool m_enableDragDrop = false; diff --git a/src/lib/deskflow/CMakeLists.txt b/src/lib/deskflow/CMakeLists.txt index 6e207a31e..1e990b188 100644 --- a/src/lib/deskflow/CMakeLists.txt +++ b/src/lib/deskflow/CMakeLists.txt @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: 2024 Chris Rizzitello -# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd +# SPDX-FileCopyrightText: 2012 - 2025 Symless Ltd # SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton # SPDX-License-Identifier: MIT @@ -170,7 +170,6 @@ if(UNIX) PRIVATE arch client - ipc net base platform diff --git a/src/lib/deskflow/ClientApp.cpp b/src/lib/deskflow/ClientApp.cpp index c742b0be3..ef95cd619 100644 --- a/src/lib/deskflow/ClientApp.cpp +++ b/src/lib/deskflow/ClientApp.cpp @@ -454,12 +454,6 @@ int ClientApp::mainLoop() // start client, etc appUtil().startNode(); - // init ipc client after node start, since create a new screen wipes out - // the event queue (the screen ctors call adoptBuffer). - if (argsBase().m_enableIpc) { - initIpcClient(); - } - // run event loop. if startClient() failed we're supposed to retry // later. the timer installed by startClient() will take care of // that. @@ -486,10 +480,6 @@ int ClientApp::mainLoop() updateStatus(); LOG((CLOG_NOTE "stopped client")); - if (argsBase().m_enableIpc) { - cleanupIpcClient(); - } - return kExitSuccess; } diff --git a/src/lib/deskflow/DaemonApp.cpp b/src/lib/deskflow/DaemonApp.cpp index 76a1b40a2..e2f44b5ab 100644 --- a/src/lib/deskflow/DaemonApp.cpp +++ b/src/lib/deskflow/DaemonApp.cpp @@ -4,26 +4,13 @@ * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception */ -// TODO: split this class into windows and unix to get rid -// of all the #ifdefs! - #include "deskflow/DaemonApp.h" #include "arch/XArch.h" #include "base/Log.h" -#include "base/TMethodEventJob.h" #include "base/log_outputters.h" #include "common/constants.h" -#include "common/ipc.h" #include "deskflow/App.h" -#include "deskflow/ArgParser.h" -#include "deskflow/ClientArgs.h" -#include "deskflow/ServerArgs.h" -#include "ipc/IpcClientProxy.h" -#include "ipc/IpcLogOutputter.h" -#include "ipc/IpcMessage.h" -#include "ipc/IpcSettingMessage.h" -#include "net/SocketMultiplexer.h" #if SYSAPI_WIN32 @@ -50,16 +37,6 @@ using namespace deskflow::core; const char *const kLogFilename = "deskflow-daemon.log"; namespace { -void updateSetting(const IpcMessage &message) -{ - try { - auto setting = static_cast(message); - ARCH->setting(setting.getName(), setting.getValue()); - } catch (const XArch &e) { - LOG((CLOG_ERR "failed to save setting: %s", e.what())); - } -} - bool isServerCommandLine(const std::vector &cmd) { auto isServer = false; @@ -76,7 +53,7 @@ bool isServerCommandLine(const std::vector &cmd) int mainLoopStatic() { - DaemonApp::instance().mainLoop(true); + DaemonApp::instance().mainLoop(); return kExitSuccess; } @@ -108,7 +85,7 @@ void DaemonApp::run() // run process in foreground instead of daemonizing. // useful for debugging. - mainLoop(false, m_foreground); + mainLoop(m_foreground); } else { #if SYSAPI_WIN32 LOG((CLOG_NOTE "daemonizing windows service")); @@ -260,7 +237,7 @@ DaemonApp::InitResult DaemonApp::init(IEventQueue *events, int argc, char **argv return FatalError; } -void DaemonApp::mainLoop(bool logToFile, bool foreground) +void DaemonApp::mainLoop(bool foreground) { if (m_events == nullptr) { throw XDeskflow("event queue not set"); @@ -269,17 +246,12 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground) try { DAEMON_RUNNING(true); - if (logToFile) { - m_fileLogOutputter = new FileLogOutputter(logFilename().c_str()); // NOSONAR -- Adopted by `Log` - CLOG->insert(m_fileLogOutputter); - } + m_fileLogOutputter = new FileLogOutputter(logFilename().c_str()); // NOSONAR - Adopted by `Log` + CLOG->insert(m_fileLogOutputter); #if SYSAPI_WIN32 m_watchdog = std::make_unique(false, foreground); m_watchdog->setFileLogOutputter(m_fileLogOutputter); -#endif - -#if SYSAPI_WIN32 // install the platform event queue to handle service stop events. m_events->adoptBuffer(new MSWindowsEventQueueBuffer(m_events)); @@ -293,14 +265,13 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground) m_watchdog->startAsync(); #endif + m_events->loop(); #if SYSAPI_WIN32 m_watchdog->stop(); #endif - CLOG->remove(m_ipcLogOutputter.get()); - DAEMON_RUNNING(false); } catch (std::exception &e) { LOG((CLOG_CRIT "an error occurred: %s", e.what())); diff --git a/src/lib/deskflow/DaemonApp.h b/src/lib/deskflow/DaemonApp.h index f64687418..919a968d6 100644 --- a/src/lib/deskflow/DaemonApp.h +++ b/src/lib/deskflow/DaemonApp.h @@ -13,11 +13,8 @@ #include -#include "common/common.h" - class Event; class IEventQueue; -class IpcLogOutputter; class FileLogOutputter; class QLocalServer; class QCoreApplication; @@ -49,15 +46,14 @@ public: InitResult init(IEventQueue *events, int argc, char **argv); void run(); - void mainLoop(bool logToFile, bool foreground = false); void restartCoreProcess(); void saveLogLevel(const QString &logLevel) const; + void mainLoop(bool foreground = false); + void setLogLevel(const QString &logLevel); void setElevate(bool elevate); void setCommand(const QString &command); void applyWatchdogCommand() const; void clearWatchdogCommand(); - - // Getters std::string logFilename(); static DaemonApp &instance() @@ -79,7 +75,6 @@ private: #endif private: - std::unique_ptr m_ipcLogOutputter; IEventQueue *m_events = nullptr; FileLogOutputter *m_fileLogOutputter = nullptr; deskflow::core::ipc::DaemonIpcServer *m_ipcServer = nullptr; diff --git a/src/lib/deskflow/ServerApp.cpp b/src/lib/deskflow/ServerApp.cpp index aa6f0484d..f2cf76319 100644 --- a/src/lib/deskflow/ServerApp.cpp +++ b/src/lib/deskflow/ServerApp.cpp @@ -706,12 +706,6 @@ int ServerApp::mainLoop() // start server, etc appUtil().startNode(); - // init ipc client after node start, since create a new screen wipes out - // the event queue (the screen ctors call adoptBuffer). - if (argsBase().m_enableIpc) { - initIpcClient(); - } - // handle hangup signal by reloading the server's configuration ARCH->setSignalHandler(Arch::kHANGUP, &reloadSignalHandler, NULL); m_events->adoptHandler( @@ -761,10 +755,6 @@ int ServerApp::mainLoop() updateStatus(); LOG((CLOG_NOTE "stopped server")); - if (argsBase().m_enableIpc) { - cleanupIpcClient(); - } - return kExitSuccess; } diff --git a/src/lib/gui/CMakeLists.txt b/src/lib/gui/CMakeLists.txt index f9e6a649e..31af3761d 100644 --- a/src/lib/gui/CMakeLists.txt +++ b/src/lib/gui/CMakeLists.txt @@ -64,13 +64,6 @@ add_library(${target} STATIC core/ServerMessage.h core/WaylandWarnings.cpp core/WaylandWarnings.h - ipc/IpcReader.cpp - ipc/IpcReader.h - ipc/IQIpcClient.cpp - ipc/IQIpcClient.h - ipc/QDataStreamProxy.h - ipc/QIpcClient.cpp - ipc/QIpcClient.h ipc/DaemonIpcClient.cpp ipc/DaemonIpcClient.h proxy/QNetworkAccessManagerProxy.cpp diff --git a/src/lib/gui/core/CoreProcess.cpp b/src/lib/gui/core/CoreProcess.cpp index 5933483da..c1cb17c4d 100644 --- a/src/lib/gui/core/CoreProcess.cpp +++ b/src/lib/gui/core/CoreProcess.cpp @@ -158,18 +158,6 @@ CoreProcess::CoreProcess(const IAppConfig &appConfig, const IServerConfig &serve m_pDeps(deps), m_daemonIpcClient{new ipc::DaemonIpcClient(this)} { - if (m_appConfig.processMode() == ProcessMode::kService) { - - connect(m_daemonIpcClient, &ipc::DaemonIpcClient::connected, this, &CoreProcess::daemonIpcClientConnected); - - const auto logPath = requestDaemonLogPath(); - if (!logPath.isEmpty()) { - qInfo() << "daemon log path:" << logPath; - m_daemonFileTail = new FileTail(logPath, this); - connect(m_daemonFileTail, &FileTail::newLine, this, &CoreProcess::handleLogLines); - } - } - connect(m_daemonIpcClient, &ipc::DaemonIpcClient::connected, this, &CoreProcess::daemonIpcClientConnected); connect(&m_pDeps->process(), &QProcessProxy::finished, this, &CoreProcess::onProcessFinished); @@ -191,30 +179,6 @@ CoreProcess::CoreProcess(const IAppConfig &appConfig, const IServerConfig &serve }); } -void CoreProcess::onIpcClientServiceReady() -{ - if (m_processState == ProcessState::Starting) { - qDebug("service ready, continuing core process start"); - start(); - } else if (m_processState == ProcessState::Stopping) { - qDebug("service ready, continuing core process stop"); - stop(); - } else { - // This may happen when the IPC connection fails and then reconnects. - qWarning("ignoring service ready, process state is not starting or stopping"); - } -} - -void CoreProcess::onIpcClientError(const QString &text) const -{ - qCritical().noquote() << text; -} - -void CoreProcess::onIpcClientRead(const QString &text) -{ - handleLogLines(text); -} - void CoreProcess::onProcessReadyReadStandardOutput() { if (m_pDeps->process()) { @@ -314,10 +278,6 @@ void CoreProcess::startProcessFromDaemon(const QString &app, const QStringList & qFatal("core process must be in starting state"); } - if (!m_daemonIpcClient->isConnected()) { - m_daemonIpcClient->connectToServer(); - } - QString commandQuoted = makeQuotedArgs(app, args); qInfo("running command: %s", qPrintable(commandQuoted)); @@ -506,8 +466,6 @@ void CoreProcess::cleanup() if (isDesktop && isRunning) { stop(); } - - m_pDeps->ipcClient().disconnectFromHost(); } bool CoreProcess::addGenericArgs(QStringList &args, const ProcessMode processMode) const @@ -518,9 +476,6 @@ bool CoreProcess::addGenericArgs(QStringList &args, const ProcessMode processMod args << "--name" << m_appConfig.screenName(); if (processMode != ProcessMode::kDesktop) { - // tell client/server to talk to daemon through ipc. - args << "--ipc"; - #if defined(Q_OS_WIN) // tell the client/server to shut down when a ms windows desk // is switched; this is because we may need to elevate or not diff --git a/src/lib/gui/core/CoreProcess.h b/src/lib/gui/core/CoreProcess.h index 6074c9da3..e279df066 100644 --- a/src/lib/gui/core/CoreProcess.h +++ b/src/lib/gui/core/CoreProcess.h @@ -9,7 +9,6 @@ #include "gui/FileTail.h" #include "gui/config/IAppConfig.h" #include "gui/config/IServerConfig.h" -#include "gui/ipc/QIpcClient.h" #include "gui/proxy/QProcessProxy.h" #include @@ -31,7 +30,6 @@ class CoreProcess : public QObject { using IServerConfig = deskflow::gui::IServerConfig; using QProcessProxy = deskflow::gui::proxy::QProcessProxy; - using IQIpcClient = deskflow::gui::ipc::IQIpcClient; Q_OBJECT @@ -43,17 +41,12 @@ public: { return m_process; } - virtual IQIpcClient &ipcClient() - { - return m_ipcClient; - } virtual QString appPath(const QString &name) const; virtual bool fileExists(const QString &path) const; virtual QString getProfileRoot() const; private: QProcessProxy m_process; - QIpcClient m_ipcClient; }; enum class Mode @@ -136,9 +129,6 @@ signals: void secureSocket(bool enabled); private slots: - void onIpcClientServiceReady(); - void onIpcClientRead(const QString &text); - void onIpcClientError(const QString &text) const; void onProcessFinished(int exitCode, QProcess::ExitStatus); void onProcessReadyReadStandardOutput(); void onProcessReadyReadStandardError(); diff --git a/src/lib/gui/ipc/IQIpcClient.cpp b/src/lib/gui/ipc/IQIpcClient.cpp deleted file mode 100644 index 696c31504..000000000 --- a/src/lib/gui/ipc/IQIpcClient.cpp +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2024 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -// empty .cpp for qt moc diff --git a/src/lib/gui/ipc/IQIpcClient.h b/src/lib/gui/ipc/IQIpcClient.h deleted file mode 100644 index ffb18d251..000000000 --- a/src/lib/gui/ipc/IQIpcClient.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2024 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include -#include - -#include "gui/config/ElevateMode.h" - -namespace deskflow::gui::ipc { - -class IQIpcClient : public QObject -{ - Q_OBJECT -public: - ~IQIpcClient() override = default; - virtual void sendHello() const = 0; - virtual void sendCommand(const QString &command, ElevateMode elevate) const = 0; - virtual void connectToHost() = 0; - virtual void disconnectFromHost() = 0; - virtual bool isConnected() const = 0; - -signals: - void read(const QString &text); - void serviceReady(); -}; - -} // namespace deskflow::gui::ipc diff --git a/src/lib/gui/ipc/IpcReader.cpp b/src/lib/gui/ipc/IpcReader.cpp deleted file mode 100644 index 814bcb0b9..000000000 --- a/src/lib/gui/ipc/IpcReader.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "IpcReader.h" - -#include "Logger.h" -#include "byte_utils.h" -#include "common/ipc.h" - -#include -#include -#include - -using namespace deskflow::gui; - -IpcReader::IpcReader(QTcpSocket *socket) : m_Socket(socket) -{ -} - -void IpcReader::start() const -{ - connect(m_Socket, &QTcpSocket::readyRead, this, &IpcReader::onSocketReadyRead); -} - -void IpcReader::stop() const -{ - disconnect(m_Socket, &QTcpSocket::readyRead, this, &IpcReader::onSocketReadyRead); -} - -void IpcReader::onSocketReadyRead() -{ - QMutexLocker locker(&m_Mutex); - logVerbose("ready read"); - - while (m_Socket->bytesAvailable()) { - logVerbose("bytes available"); - - char codeBuf[5]; - readStream(codeBuf, 4); - codeBuf[4] = 0; - logVerbose(QString("ipc read: %1").arg(codeBuf)); - - if (memcmp(codeBuf, kIpcMsgLogLine, 4) == 0) { - logVerbose("reading log line"); - - char lenBuf[4]; - readStream(lenBuf, 4); - int len = bytesToInt(lenBuf, 4); - - std::vector dataBuf(len); - readStream(dataBuf.data(), len); - QString text = QString::fromUtf8(dataBuf.data(), len); - - Q_EMIT read(text); - } else if (memcmp(codeBuf, kIpcMsgHelloBack, 4) == 0) { - logVerbose("reading hello back"); - Q_EMIT helloBack(); - } else { - qCritical("aborting ipc read, message invalid"); - return; - } - } - - logVerbose("read done"); -} - -bool IpcReader::readStream(char *buffer, int length) -{ - logVerbose("reading stream"); - - int read = 0; - while (read < length) { - int ask = length - read; - if (m_Socket->bytesAvailable() < ask) { - logVerbose("buffer too short, waiting"); - m_Socket->waitForReadyRead(-1); - } - - auto got = m_Socket->read(buffer, ask); - read += got; - - logVerbose(QString("ask=%1 got=%2 read=%3").arg(ask).arg(got).arg(read)); - - if (got == -1) { - logVerbose("socket ended, aborting"); - return false; - } else if (length - read > 0) { - logVerbose(QString("more remains, seek to %1").arg(got)); - buffer += got; - } - } - return true; -} diff --git a/src/lib/gui/ipc/IpcReader.h b/src/lib/gui/ipc/IpcReader.h deleted file mode 100644 index 1248e961e..000000000 --- a/src/lib/gui/ipc/IpcReader.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include -#include - -class QTcpSocket; - -class IpcReader : public QObject -{ - Q_OBJECT; - -public: - explicit IpcReader(QTcpSocket *socket); - ~IpcReader() override = default; - void start() const; - void stop() const; - -signals: - void read(const QString &text); - void helloBack(); - -private: - bool readStream(char *buffer, int length); - -private slots: - void onSocketReadyRead(); - -private: - QTcpSocket *m_Socket; - QMutex m_Mutex; -}; diff --git a/src/lib/gui/ipc/QDataStreamProxy.h b/src/lib/gui/ipc/QDataStreamProxy.h deleted file mode 100644 index e70e9f0a4..000000000 --- a/src/lib/gui/ipc/QDataStreamProxy.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2024 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include - -/** - * @brief Useful for overriding QDataStream. - */ -class QDataStreamProxy -{ -public: - explicit QDataStreamProxy() = default; - explicit QDataStreamProxy(QTcpSocket *socket) : m_Stream(std::make_unique(socket)) - { - } - virtual ~QDataStreamProxy() = default; - - virtual qint64 writeRawData(const char *data, int len) - { - assert(m_Stream); - return m_Stream->writeRawData(data, len); - } - -private: - std::unique_ptr m_Stream; -}; diff --git a/src/lib/gui/ipc/QIpcClient.cpp b/src/lib/gui/ipc/QIpcClient.cpp deleted file mode 100644 index 5099cb894..000000000 --- a/src/lib/gui/ipc/QIpcClient.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "QIpcClient.h" - -#include "IpcReader.h" -#include "byte_utils.h" -#include "common/ipc.h" - -#include -#include -#include -#include - -const auto kRetryInterval = 1000; -const auto kConnectTimeout = 5000; - -using namespace deskflow::gui; - -QIpcClient::QIpcClient(const StreamProvider &streamProvider) : m_streamProvider(streamProvider) -{ - - m_pSocket = std::make_unique(); - - if (!m_streamProvider) { - m_streamProvider = [this]() { return std::make_shared(m_pSocket.get()); }; - } - - connect(m_pSocket.get(), &QTcpSocket::connected, this, &QIpcClient::onSocketConnected); - connect(m_pSocket.get(), &QTcpSocket::errorOccurred, this, &QIpcClient::onSocketError); - - m_pReader = std::make_unique(m_pSocket.get()); - connect( - m_pReader.get(), &IpcReader::read, this, // - &QIpcClient::onIpcReaderRead - ); - connect(m_pReader.get(), &IpcReader::helloBack, this, &QIpcClient::onIpcReaderHelloBack); -} - -void QIpcClient::onSocketConnected() const -{ - sendHello(); -} - -void QIpcClient::connectToHost() -{ - m_isConnecting = true; - qInfo("connecting to background service..."); - const auto port = static_cast(kIpcPort); - m_pSocket->connectToHost(QHostAddress(QHostAddress::LocalHost), port); - - if (!m_readerStarted) { - m_pReader->start(); - m_readerStarted = true; - } - - QTimer::singleShot(kConnectTimeout, this, [this]() { - if (!m_isConnected) { - qCritical("ipc connection timeout"); - } - }); -} - -void QIpcClient::disconnectFromHost() -{ - m_pReader->stop(); - m_pSocket->flush(); - m_pSocket->close(); - - m_isConnecting = false; - m_isConnected = false; - - qInfo("disconnected from background service"); -} - -void QIpcClient::onSocketError(QAbstractSocket::SocketError socketError) -{ - QString text; - switch (socketError) { - case 0: - text = "connection refused"; - break; - case 1: - text = "remote host closed"; - break; - default: - text = QString("code=%1").arg(socketError); - break; - } - - qWarning("ipc connection error, %s", qUtf8Printable(text)); - m_isConnected = false; - - QTimer::singleShot(kRetryInterval, this, &QIpcClient::onRetryConnect); -} - -void QIpcClient::onRetryConnect() -{ - if (m_isConnected) { - qDebug("ipc already connected, skipping retry"); - return; - } else if (!m_isConnecting) { - qDebug("ipc not connecting, skipping retry"); - return; - } - - qInfo("retrying connection to background service..."); - connectToHost(); -} - -void QIpcClient::sendHello() const -{ - qDebug("sending ipc hello message"); - auto stream = m_streamProvider(); - stream->writeRawData(kIpcMsgHello, 4); - - char typeBuf[1]; - typeBuf[0] = static_cast(IpcClientType::GUI); - stream->writeRawData(typeBuf, 1); -} - -void QIpcClient::sendCommand(const QString &command, ElevateMode const elevate) const -{ - qDebug("sending ipc command: %s", qUtf8Printable(command)); - - auto stream = m_streamProvider(); - stream->writeRawData(kIpcMsgCommand, 4); - - std::string stdStringCommand = command.toStdString(); - const char *charCommand = stdStringCommand.c_str(); - auto length = static_cast(stdStringCommand.length()); - - QByteArray lenBuf = intToBytes(length); - if (lenBuf.size() != 4) { - qFatal("unexpected int buffer size: %lld", lenBuf.size()); - } - stream->writeRawData(lenBuf, 4); - stream->writeRawData(charCommand, length); - - char elevateBuf[1]; - // see enum ElevateMode documentation for why this flag is mapped this way - elevateBuf[0] = (elevate == ElevateMode::kAlways) ? 1 : 0; - stream->writeRawData(elevateBuf, 1); -} - -void QIpcClient::onIpcReaderHelloBack() -{ - qDebug("ipc hello back received"); - - if (m_isConnected) { - qWarning("ipc already connected, ignoring hello back"); - return; - } - - m_isConnected = true; - Q_EMIT serviceReady(); -} - -void QIpcClient::onIpcReaderRead(const QString &text) -{ - Q_EMIT read(text); -} diff --git a/src/lib/gui/ipc/QIpcClient.h b/src/lib/gui/ipc/QIpcClient.h deleted file mode 100644 index fbb94e895..000000000 --- a/src/lib/gui/ipc/QIpcClient.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include -#include -#include -#include -#include - -#include "IpcReader.h" -#include "QDataStreamProxy.h" -#include "gui/config/ElevateMode.h" -#include "gui/ipc/IQIpcClient.h" - -class IpcReader; - -class QIpcClient : public deskflow::gui::ipc::IQIpcClient -{ - Q_OBJECT - -public: - using StreamProvider = std::function()>; - - explicit QIpcClient(const StreamProvider &streamProvider = nullptr); - - void sendHello() const override; - void sendCommand(const QString &command, ElevateMode elevate) const override; - void connectToHost() override; - void disconnectFromHost() override; - bool isConnected() const override - { - return m_isConnected; - } - -private slots: - void onRetryConnect(); - void onSocketConnected() const; - void onIpcReaderHelloBack(); - void onSocketError(QAbstractSocket::SocketError error); - void onIpcReaderRead(const QString &text); - -private: - std::unique_ptr m_pSocket; - std::unique_ptr m_pReader; - bool m_readerStarted = false; - StreamProvider m_streamProvider; - bool m_isConnected = false; - bool m_isConnecting = false; -}; diff --git a/src/lib/ipc/CMakeLists.txt b/src/lib/ipc/CMakeLists.txt deleted file mode 100644 index c6ddb6ebc..000000000 --- a/src/lib/ipc/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-FileCopyrightText: 2024 Chris Rizzitello -# SPDX-FileCopyrightText: 2012 - 2024 Symless Ltd -# SPDX-FileCopyrightText: 2009 - 2012 Nick Bolton -# SPDX-License-Identifier: MIT - -add_library(ipc STATIC - IpcClient.cpp - IpcClient.h - IpcClientProxy.cpp - IpcClientProxy.h - IpcLogOutputter.cpp - IpcLogOutputter.h - IpcMessage.cpp - IpcMessage.h - IpcServer.cpp - IpcServer.h - IpcServerProxy.cpp - IpcServerProxy.h - IpcSettingMessage.cpp - IpcSettingMessage.h -) - -if(UNIX) - target_link_libraries( - ipc - arch - base - mt - io - net - app) -endif() diff --git a/src/lib/ipc/IpcClient.cpp b/src/lib/ipc/IpcClient.cpp deleted file mode 100644 index fdb6622c3..000000000 --- a/src/lib/ipc/IpcClient.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "ipc/IpcClient.h" -#include "base/TMethodEventJob.h" -#include "common/ipc.h" -#include "ipc/IpcMessage.h" -#include "ipc/IpcServerProxy.h" - -// -// IpcClient -// - -IpcClient::IpcClient(IEventQueue *events, SocketMultiplexer *socketMultiplexer) - : m_serverAddress(NetworkAddress(kIpcHost, kIpcPort)), - m_socket(events, socketMultiplexer), - m_server(nullptr), - m_events(events) -{ - init(); -} - -IpcClient::IpcClient(IEventQueue *events, SocketMultiplexer *socketMultiplexer, int port) - : m_serverAddress(NetworkAddress(kIpcHost, port)), - m_socket(events, socketMultiplexer), - m_server(nullptr), - m_events(events) -{ - init(); -} - -void IpcClient::init() -{ - m_serverAddress.resolve(); -} - -IpcClient::~IpcClient() -{ -} - -void IpcClient::connect() -{ - m_events->adoptHandler( - m_events->forIDataSocket().connected(), m_socket.getEventTarget(), - new TMethodEventJob(this, &IpcClient::handleConnected) - ); - - m_socket.connect(m_serverAddress); - m_server = new IpcServerProxy(m_socket, m_events); - - m_events->adoptHandler( - m_events->forIpcServerProxy().messageReceived(), m_server, - new TMethodEventJob(this, &IpcClient::handleMessageReceived) - ); -} - -void IpcClient::disconnect() -{ - m_events->removeHandler(m_events->forIDataSocket().connected(), m_socket.getEventTarget()); - m_events->removeHandler(m_events->forIpcServerProxy().messageReceived(), m_server); - - m_server->disconnect(); - delete m_server; - m_server = nullptr; -} - -void IpcClient::send(const IpcMessage &message) -{ - assert(m_server != nullptr); - m_server->send(message); -} - -void IpcClient::handleConnected(const Event &, void *) -{ - m_events->addEvent(Event(m_events->forIpcClient().connected(), this, m_server, Event::kDontFreeData)); - - IpcHelloMessage message(IpcClientType::Node); - send(message); -} - -void IpcClient::handleMessageReceived(const Event &e, void *) -{ - Event event(m_events->forIpcClient().messageReceived(), this); - event.setDataObject(e.getDataObject()); - m_events->addEvent(event); -} diff --git a/src/lib/ipc/IpcClient.h b/src/lib/ipc/IpcClient.h deleted file mode 100644 index 2ecdd39eb..000000000 --- a/src/lib/ipc/IpcClient.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "base/EventTypes.h" -#include "net/NetworkAddress.h" -#include "net/TCPSocket.h" - -class IpcServerProxy; -class IpcMessage; -class IEventQueue; -class SocketMultiplexer; - -//! IPC client for communication between daemon and GUI. -/*! - * See \ref IpcServer description. - */ -class IpcClient -{ -public: - IpcClient(IEventQueue *events, SocketMultiplexer *socketMultiplexer); - IpcClient(IEventQueue *events, SocketMultiplexer *socketMultiplexer, int port); - virtual ~IpcClient(); - - //! @name manipulators - //@{ - - //! Connects to the IPC server at localhost. - void connect(); - - //! Disconnects from the IPC server. - void disconnect(); - - //! Sends a message to the server. - void send(const IpcMessage &message); - - //@} - -private: - void init(); - void handleConnected(const Event &, void *); - void handleMessageReceived(const Event &, void *); - -private: - NetworkAddress m_serverAddress; - TCPSocket m_socket; - IpcServerProxy *m_server; - IEventQueue *m_events; -}; diff --git a/src/lib/ipc/IpcClientProxy.cpp b/src/lib/ipc/IpcClientProxy.cpp deleted file mode 100644 index 31427e4a6..000000000 --- a/src/lib/ipc/IpcClientProxy.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "ipc/IpcClientProxy.h" - -#include "base/Log.h" -#include "base/TMethodEventJob.h" -#include "common/ipc.h" -#include "deskflow/ProtocolUtil.h" -#include "io/IStream.h" -#include "ipc/IpcMessage.h" -#include "ipc/IpcSettingMessage.h" - -// -// IpcClientProxy -// - -IpcClientProxy::IpcClientProxy(deskflow::IStream &stream, IEventQueue *events) : m_stream(stream), m_events(events) -{ - m_events->adoptHandler( - m_events->forIStream().inputReady(), stream.getEventTarget(), - new TMethodEventJob(this, &IpcClientProxy::handleData) - ); - - m_events->adoptHandler( - m_events->forIStream().outputError(), stream.getEventTarget(), - new TMethodEventJob(this, &IpcClientProxy::handleWriteError) - ); - - m_events->adoptHandler( - m_events->forIStream().inputShutdown(), stream.getEventTarget(), - new TMethodEventJob(this, &IpcClientProxy::handleDisconnect) - ); - - m_events->adoptHandler( - m_events->forIStream().outputShutdown(), stream.getEventTarget(), - new TMethodEventJob(this, &IpcClientProxy::handleWriteError) - ); -} - -IpcClientProxy::~IpcClientProxy() -{ - m_events->removeHandler(m_events->forIStream().inputReady(), m_stream.getEventTarget()); - m_events->removeHandler(m_events->forIStream().outputError(), m_stream.getEventTarget()); - m_events->removeHandler(m_events->forIStream().inputShutdown(), m_stream.getEventTarget()); - m_events->removeHandler(m_events->forIStream().outputShutdown(), m_stream.getEventTarget()); - - // don't delete the stream while it's being used. - ARCH->lockMutex(m_readMutex); - ARCH->lockMutex(m_writeMutex); - delete &m_stream; - ARCH->unlockMutex(m_readMutex); - ARCH->unlockMutex(m_writeMutex); - - ARCH->closeMutex(m_readMutex); - ARCH->closeMutex(m_writeMutex); -} - -void IpcClientProxy::handleDisconnect(const Event &, void *) -{ - disconnect(); - LOG((CLOG_DEBUG "ipc client disconnected")); -} - -void IpcClientProxy::handleWriteError(const Event &, void *) -{ - disconnect(); - LOG((CLOG_DEBUG "ipc client write error")); -} - -void IpcClientProxy::handleData(const Event &, void *) -{ - // don't allow the dtor to destroy the stream while we're using it. - ArchMutexLock lock(m_readMutex); - - LOG((CLOG_DEBUG "start ipc handle data")); - - uint8_t code[4]; - uint32_t n = m_stream.read(code, 4); - while (n != 0) { - - LOG((CLOG_DEBUG "ipc read: %c%c%c%c", code[0], code[1], code[2], code[3])); - - IpcMessage *m = nullptr; - if (memcmp(code, kIpcMsgHello, 4) == 0) { - m = parseHello(); - } else if (memcmp(code, kIpcMsgCommand, 4) == 0) { - m = parseCommand(); - } else if (memcmp(code, kIpcMsgSetting, 4) == 0) { - m = parseSetting(); - } else { - LOG((CLOG_ERR "invalid ipc message")); - disconnect(); - } - - // don't delete with this event; the data is passed to a new event. - Event e(m_events->forIpcClientProxy().messageReceived(), this, NULL, Event::kDontFreeData); - e.setDataObject(m); - m_events->addEvent(e); - - n = m_stream.read(code, 4); - } - - LOG((CLOG_DEBUG "finished ipc handle data")); -} - -void IpcClientProxy::send(const IpcMessage &message) -{ - // don't allow other threads to write until we've finished the entire - // message. stream write is locked, but only for that single write. - // also, don't allow the dtor to destroy the stream while we're using it. - ArchMutexLock lock(m_writeMutex); - - LOG((CLOG_DEBUG4 "ipc write: %d", message.type())); - - switch (message.type()) { - case IpcMessageType::LogLine: { - const IpcLogLineMessage &llm = static_cast(message); - const std::string logLine = llm.logLine(); - ProtocolUtil::writef(&m_stream, kIpcMsgLogLine, &logLine); - break; - } - - case IpcMessageType::Shutdown: - ProtocolUtil::writef(&m_stream, kIpcMsgShutdown); - break; - - case IpcMessageType::HelloBack: - ProtocolUtil::writef(&m_stream, kIpcMsgHelloBack); - break; - - default: - LOG((CLOG_ERR "ipc message not supported: %d", message.type())); - break; - } -} - -IpcHelloMessage *IpcClientProxy::parseHello() -{ - uint8_t type; - ProtocolUtil::readf(&m_stream, kIpcMsgHello + 4, &type); - - m_clientType = static_cast(type); - - // must be deleted by event handler. - return new IpcHelloMessage(m_clientType); -} - -IpcCommandMessage *IpcClientProxy::parseCommand() -{ - std::string command; - uint8_t elevate; - ProtocolUtil::readf(&m_stream, kIpcMsgCommand + 4, &command, &elevate); - - // must be deleted by event handler. - return new IpcCommandMessage(command, elevate != 0); -} - -IpcSettingMessage *IpcClientProxy::parseSetting() const -{ - std::string name; - std::string value; - - ProtocolUtil::readf(&m_stream, kIpcMsgSetting + 4, &name, &value); - - // must be deleted by event handler. - return new IpcSettingMessage(name, value); -} - -void IpcClientProxy::disconnect() -{ - LOG((CLOG_DEBUG "ipc disconnect, closing stream")); - m_disconnecting = true; - m_stream.close(); - m_events->addEvent(Event(m_events->forIpcClientProxy().disconnected(), this)); -} diff --git a/src/lib/ipc/IpcClientProxy.h b/src/lib/ipc/IpcClientProxy.h deleted file mode 100644 index 515295605..000000000 --- a/src/lib/ipc/IpcClientProxy.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "arch/Arch.h" -#include "arch/IArchMultithread.h" -#include "base/Event.h" -#include "base/EventTypes.h" -#include "common/ipc.h" - -namespace deskflow { -class IStream; -} -class IpcMessage; -class IpcCommandMessage; -class IpcSettingMessage; -class IpcHelloMessage; -class IEventQueue; - -class IpcClientProxy -{ - friend class IpcServer; - -public: - IpcClientProxy(deskflow::IStream &stream, IEventQueue *events); - IpcClientProxy(IpcClientProxy const &) = delete; - IpcClientProxy(IpcClientProxy &&) = delete; - virtual ~IpcClientProxy(); - - IpcClientProxy &operator=(IpcClientProxy const &) = delete; - IpcClientProxy &operator=(IpcClientProxy &&) = delete; - -private: - void send(const IpcMessage &message); - void handleData(const Event &, void *); - void handleDisconnect(const Event &, void *); - void handleWriteError(const Event &, void *); - IpcHelloMessage *parseHello(); - IpcCommandMessage *parseCommand(); - IpcSettingMessage *parseSetting() const; - void disconnect(); - -private: - deskflow::IStream &m_stream; - IEventQueue *m_events; - IpcClientType m_clientType = IpcClientType::Unknown; - bool m_disconnecting = false; - ArchMutex m_readMutex = ARCH->newMutex(); - ArchMutex m_writeMutex = ARCH->newMutex(); -}; diff --git a/src/lib/ipc/IpcLogOutputter.cpp b/src/lib/ipc/IpcLogOutputter.cpp deleted file mode 100644 index 2f42ea5c9..000000000 --- a/src/lib/ipc/IpcLogOutputter.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "ipc/IpcLogOutputter.h" - -#include "arch/Arch.h" -#include "arch/XArch.h" -#include "base/Event.h" -#include "base/EventQueue.h" -#include "base/TMethodEventJob.h" -#include "base/TMethodJob.h" -#include "common/ipc.h" -#include "ipc/IpcClientProxy.h" -#include "ipc/IpcMessage.h" -#include "ipc/IpcServer.h" -#include "mt/Thread.h" - -enum EIpcLogOutputter -{ - kBufferMaxSize = 1000, - kMaxSendLines = 100, - kBufferRateWriteLimit = 1000, // writes per kBufferRateTime - kBufferRateTimeLimit = 1 // seconds -}; - -IpcLogOutputter::IpcLogOutputter(IpcServer &ipcServer, IpcClientType clientType, bool useThread) - : m_ipcServer(ipcServer), - m_bufferMutex(ARCH->newMutex()), - m_sending(false), - m_bufferThread(nullptr), - m_running(false), - m_notifyCond(ARCH->newCondVar()), - m_notifyMutex(ARCH->newMutex()), - m_bufferThreadId(0), - m_bufferWaiting(false), - m_bufferMaxSize(kBufferMaxSize), - m_bufferRateWriteLimit(kBufferRateWriteLimit), - m_bufferRateTimeLimit(kBufferRateTimeLimit), - m_bufferWriteCount(0), - m_bufferRateStart(ARCH->time()), - m_clientType(clientType), - m_runningMutex(ARCH->newMutex()) -{ - if (useThread) { - const auto outputter = - new TMethodJob(this, &IpcLogOutputter::bufferThread); // NOSONAR -- Adopted by `Log` - m_bufferThread = new Thread(outputter); - } -} - -IpcLogOutputter::~IpcLogOutputter() -{ - close(); - - ARCH->closeMutex(m_bufferMutex); - - if (m_bufferThread != nullptr) { - m_bufferThread->cancel(); - m_bufferThread->wait(); - delete m_bufferThread; - } - - ARCH->closeCondVar(m_notifyCond); - ARCH->closeMutex(m_notifyMutex); -} - -void IpcLogOutputter::open(const char *title) -{ -} - -void IpcLogOutputter::close() -{ - if (m_bufferThread != nullptr) { - ArchMutexLock lock(m_runningMutex); - m_running = false; - notifyBuffer(); - m_bufferThread->wait(5); - } -} - -void IpcLogOutputter::show(bool showIfEmpty) -{ -} - -bool IpcLogOutputter::write(ELevel, const char *text) -{ - // ignore events from the buffer thread (would cause recursion). - if (m_bufferThread != nullptr && Thread::getCurrentThread().getID() == m_bufferThreadId) { - return true; - } - - appendBuffer(text); - notifyBuffer(); - - return true; -} - -void IpcLogOutputter::appendBuffer(const std::string &text) -{ - ArchMutexLock lock(m_bufferMutex); - - double elapsed = ARCH->time() - m_bufferRateStart; - if (elapsed < m_bufferRateTimeLimit) { - if (m_bufferWriteCount >= m_bufferRateWriteLimit) { - // discard the log line if we've logged too much. - return; - } - } else { - m_bufferWriteCount = 0; - m_bufferRateStart = ARCH->time(); - } - - if (m_buffer.size() >= m_bufferMaxSize) { - // if the queue is exceeds size limit, - // throw away the oldest item - m_buffer.pop_front(); - } - - m_buffer.push_back(text); - m_bufferWriteCount++; -} - -bool IpcLogOutputter::isRunning() -{ - ArchMutexLock lock(m_runningMutex); - return m_running; -} - -void IpcLogOutputter::bufferThread(void *) -{ - m_bufferThreadId = m_bufferThread->getID(); - m_running = true; - - try { - while (isRunning()) { - if (m_buffer.empty() || !m_ipcServer.hasClients(m_clientType)) { - ArchMutexLock lock(m_notifyMutex); - ARCH->waitCondVar(m_notifyCond, m_notifyMutex, -1); - } - - sendBuffer(); - } - } catch (XArch &e) { - LOG((CLOG_ERR "ipc log buffer thread error, %s", e.what())); - } - - LOG((CLOG_DEBUG "ipc log buffer thread finished")); -} - -void IpcLogOutputter::notifyBuffer() -{ - ArchMutexLock lock(m_notifyMutex); - ARCH->broadcastCondVar(m_notifyCond); -} - -std::string IpcLogOutputter::getChunk(size_t count) -{ - ArchMutexLock lock(m_bufferMutex); - - if (m_buffer.size() < count) { - count = m_buffer.size(); - } - - std::string chunk; - for (size_t i = 0; i < count; i++) { - chunk.append(m_buffer.front()); - chunk.append("\n"); - m_buffer.pop_front(); - } - return chunk; -} - -void IpcLogOutputter::sendBuffer() -{ - if (m_buffer.empty() || !m_ipcServer.hasClients(m_clientType)) { - return; - } - - IpcLogLineMessage message(getChunk(kMaxSendLines)); - m_sending = true; - m_ipcServer.send(message, IpcClientType::GUI); - m_sending = false; -} - -void IpcLogOutputter::bufferMaxSize(uint16_t bufferMaxSize) -{ - m_bufferMaxSize = bufferMaxSize; -} - -uint16_t IpcLogOutputter::bufferMaxSize() const -{ - return m_bufferMaxSize; -} - -void IpcLogOutputter::bufferRateLimit(uint16_t writeLimit, double timeLimit) -{ - m_bufferRateWriteLimit = writeLimit; - m_bufferRateTimeLimit = timeLimit; -} diff --git a/src/lib/ipc/IpcLogOutputter.h b/src/lib/ipc/IpcLogOutputter.h deleted file mode 100644 index 5fa1793ad..000000000 --- a/src/lib/ipc/IpcLogOutputter.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "arch/Arch.h" -#include "arch/IArchMultithread.h" -#include "base/ILogOutputter.h" -#include "common/ipc.h" - -#include - -class IpcServer; -class Event; -class IpcClientProxy; - -//! Write log to GUI over IPC -/*! -This outputter writes output to the GUI via IPC. -*/ -class IpcLogOutputter : public ILogOutputter -{ -public: - /*! - If \p useThread is \c true, the buffer will be sent using a thread. - If \p useThread is \c false, then the buffer needs to be sent manually - using the \c sendBuffer() function. - */ - IpcLogOutputter(IpcServer &ipcServer, IpcClientType clientType, bool useThread); - IpcLogOutputter(IpcLogOutputter const &) = delete; - virtual ~IpcLogOutputter(); - - // ILogOutputter overrides - virtual void open(const char *title); - virtual void close(); - virtual void show(bool showIfEmpty); - virtual bool write(ELevel level, const char *message); - - //! @name manipulators - //@{ - - //! Notify that the buffer should be sent. - void notifyBuffer(); - - //! Set the buffer size - /*! - Set the maximum size of the buffer to protect memory - from runaway logging. - */ - void bufferMaxSize(uint16_t bufferMaxSize); - - //! Set the rate limit - /*! - Set the maximum number of \p writeRate for every \p timeRate in seconds. - */ - void bufferRateLimit(uint16_t writeLimit, double timeLimit); - - //! Send the buffer - /*! - Sends a chunk of the buffer to the IPC server, normally called - when threaded mode is on. - */ - void sendBuffer(); - - //@} - - //! @name accessors - //@{ - - //! Get the buffer size - /*! - Returns the maximum size of the buffer. - */ - uint16_t bufferMaxSize() const; - - //@} - -private: - void init(); - void bufferThread(void *); - std::string getChunk(size_t count); - void appendBuffer(const std::string &text); - bool isRunning(); - -private: - using Buffer = std::deque; - - IpcServer &m_ipcServer; - Buffer m_buffer; - ArchMutex m_bufferMutex; - bool m_sending; - Thread *m_bufferThread; - bool m_running; - ArchCond m_notifyCond; - ArchMutex m_notifyMutex; - bool m_bufferWaiting; - IArchMultithread::ThreadID m_bufferThreadId; - uint16_t m_bufferMaxSize; - uint16_t m_bufferRateWriteLimit; - double m_bufferRateTimeLimit; - uint16_t m_bufferWriteCount; - double m_bufferRateStart; - IpcClientType m_clientType; - ArchMutex m_runningMutex; -}; diff --git a/src/lib/ipc/IpcMessage.cpp b/src/lib/ipc/IpcMessage.cpp deleted file mode 100644 index 433f488a2..000000000 --- a/src/lib/ipc/IpcMessage.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "ipc/IpcMessage.h" -#include "common/ipc.h" - -IpcMessage::IpcMessage(IpcMessageType type) : m_type(type) -{ -} - -IpcHelloMessage::IpcHelloMessage(IpcClientType clientType) : IpcMessage(IpcMessageType::Hello), m_clientType(clientType) -{ -} - -IpcHelloBackMessage::IpcHelloBackMessage() : IpcMessage(IpcMessageType::HelloBack) -{ -} - -IpcShutdownMessage::IpcShutdownMessage() : IpcMessage(IpcMessageType::Shutdown) -{ -} - -IpcLogLineMessage::IpcLogLineMessage(const std::string &logLine) - : IpcMessage(IpcMessageType::LogLine), - m_logLine(logLine) -{ -} - -IpcCommandMessage::IpcCommandMessage(const std::string &command, bool elevate) - : IpcMessage(IpcMessageType::Command), - m_command(command), - m_elevate(elevate) -{ -} diff --git a/src/lib/ipc/IpcMessage.h b/src/lib/ipc/IpcMessage.h deleted file mode 100644 index fe5887bc3..000000000 --- a/src/lib/ipc/IpcMessage.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "base/Event.h" -#include "common/ipc.h" - -#include - -class IpcMessage : public EventData -{ -public: - ~IpcMessage() override = default; - - //! Gets the message type ID. - IpcMessageType type() const - { - return m_type; - } - -protected: - explicit IpcMessage(IpcMessageType type); - -private: - IpcMessageType m_type; -}; - -class IpcHelloMessage : public IpcMessage -{ -public: - explicit IpcHelloMessage(IpcClientType clientType); - ~IpcHelloMessage() override = default; - - //! Gets the message type ID. - IpcClientType clientType() const - { - return m_clientType; - } - -private: - IpcClientType m_clientType; -}; - -class IpcHelloBackMessage : public IpcMessage -{ -public: - explicit IpcHelloBackMessage(); - ~IpcHelloBackMessage() override = default; -}; - -class IpcShutdownMessage : public IpcMessage -{ -public: - explicit IpcShutdownMessage(); - ~IpcShutdownMessage() override = default; -}; - -class IpcLogLineMessage : public IpcMessage -{ -public: - explicit IpcLogLineMessage(const std::string &logLine); - ~IpcLogLineMessage() override = default; - - //! Gets the log line. - std::string logLine() const - { - return m_logLine; - } - -private: - std::string m_logLine; -}; - -class IpcCommandMessage : public IpcMessage -{ -public: - explicit IpcCommandMessage(const std::string &command, bool elevate); - ~IpcCommandMessage() override = default; - - //! Gets the command. - std::string command() const - { - return m_command; - } - - //! Gets whether or not the process should be elevated on MS Windows. - bool elevate() const - { - return m_elevate; - } - -private: - std::string m_command; - bool m_elevate; -}; diff --git a/src/lib/ipc/IpcServer.cpp b/src/lib/ipc/IpcServer.cpp deleted file mode 100644 index 2808c9834..000000000 --- a/src/lib/ipc/IpcServer.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "ipc/IpcServer.h" - -#include "base/Event.h" -#include "base/IEventQueue.h" -#include "base/Log.h" -#include "base/TMethodEventJob.h" -#include "common/ipc.h" -#include "io/IStream.h" -#include "ipc/IpcClientProxy.h" -#include "ipc/IpcMessage.h" -#include "net/IDataSocket.h" - -// -// IpcServer -// - -IpcServer::IpcServer(IEventQueue *events, SocketMultiplexer *socketMultiplexer) - : m_mock(false), - m_events(events), - m_socketMultiplexer(socketMultiplexer), - m_socket(nullptr), - m_address(NetworkAddress(kIpcHost, kIpcPort)) -{ - init(); -} - -IpcServer::IpcServer(IEventQueue *events, SocketMultiplexer *socketMultiplexer, int port) - : m_mock(false), - m_events(events), - m_socketMultiplexer(socketMultiplexer), - m_address(NetworkAddress(kIpcHost, port)) -{ - init(); -} - -void IpcServer::init() -{ - m_socket = new TCPListenSocket(m_events, m_socketMultiplexer, IArchNetwork::EAddressFamily::kINET); - - m_clientsMutex = ARCH->newMutex(); - m_address.resolve(); - - m_events->adoptHandler( - m_events->forIListenSocket().connecting(), m_socket, - new TMethodEventJob(this, &IpcServer::handleClientConnecting) - ); -} - -IpcServer::~IpcServer() -{ - if (m_mock) { - return; - } - - if (m_socket != nullptr) { - delete m_socket; - } - - ARCH->lockMutex(m_clientsMutex); - ClientList::iterator it; - for (it = m_clients.begin(); it != m_clients.end(); it++) { - deleteClient(*it); - } - m_clients.clear(); - ARCH->unlockMutex(m_clientsMutex); - ARCH->closeMutex(m_clientsMutex); - - m_events->removeHandler(m_events->forIListenSocket().connecting(), m_socket); -} - -void IpcServer::listen() -{ - m_socket->bind(m_address); -} - -void IpcServer::handleClientConnecting(const Event &, void *) -{ - deskflow::IStream *stream = m_socket->accept(); - if (stream == NULL) { - return; - } - - LOG((CLOG_DEBUG "accepted ipc client connection")); - - ARCH->lockMutex(m_clientsMutex); - IpcClientProxy *proxy = new IpcClientProxy(*stream, m_events); - m_clients.push_back(proxy); - ARCH->unlockMutex(m_clientsMutex); - - m_events->adoptHandler( - m_events->forIpcClientProxy().disconnected(), proxy, - new TMethodEventJob(this, &IpcServer::handleClientDisconnected) - ); - - m_events->adoptHandler( - m_events->forIpcClientProxy().messageReceived(), proxy, - new TMethodEventJob(this, &IpcServer::handleMessageReceived) - ); - - m_events->addEvent(Event(m_events->forIpcServer().clientConnected(), this, proxy, Event::kDontFreeData)); -} - -void IpcServer::handleClientDisconnected(const Event &e, void *) -{ - IpcClientProxy *proxy = static_cast(e.getTarget()); - - ArchMutexLock lock(m_clientsMutex); - m_clients.remove(proxy); - deleteClient(proxy); - - LOG((CLOG_DEBUG "ipc client proxy removed, connected=%d", m_clients.size())); -} - -void IpcServer::handleMessageReceived(const Event &e, void *) -{ - Event event(m_events->forIpcServer().messageReceived(), this); - event.setDataObject(e.getDataObject()); - m_events->addEvent(event); -} - -void IpcServer::deleteClient(IpcClientProxy *proxy) -{ - m_events->removeHandler(m_events->forIpcClientProxy().messageReceived(), proxy); - m_events->removeHandler(m_events->forIpcClientProxy().disconnected(), proxy); - delete proxy; -} - -bool IpcServer::hasClients(IpcClientType clientType) const -{ - ArchMutexLock lock(m_clientsMutex); - - if (m_clients.empty()) { - return false; - } - - ClientList::const_iterator it; - for (it = m_clients.begin(); it != m_clients.end(); it++) { - // at least one client is alive and type matches, there are clients. - IpcClientProxy *p = *it; - if (!p->m_disconnecting && p->m_clientType == clientType) { - return true; - } - } - - // all clients must be disconnecting, no active clients. - return false; -} - -void IpcServer::send(const IpcMessage &message, IpcClientType filterType) -{ - ArchMutexLock lock(m_clientsMutex); - - ClientList::iterator it; - for (it = m_clients.begin(); it != m_clients.end(); it++) { - IpcClientProxy *proxy = *it; - if (proxy->m_clientType == filterType) { - proxy->send(message); - } - } -} diff --git a/src/lib/ipc/IpcServer.h b/src/lib/ipc/IpcServer.h deleted file mode 100644 index fe362875e..000000000 --- a/src/lib/ipc/IpcServer.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "arch/Arch.h" -#include "base/EventTypes.h" -#include "common/ipc.h" -#include "net/NetworkAddress.h" -#include "net/TCPListenSocket.h" - -#include - -class Event; -class IpcClientProxy; -class IpcMessage; -class IEventQueue; -class SocketMultiplexer; - -//! IPC server for communication between daemon and GUI. -/*! -The IPC server listens on localhost. The IPC client runs on both the -client/server process or the GUI. The IPC server runs on the daemon process. -This allows the GUI to send config changes to the daemon and client/server, -and allows the daemon and client/server to send log data to the GUI. -*/ -class IpcServer -{ -public: - IpcServer(IEventQueue *events, SocketMultiplexer *socketMultiplexer); - IpcServer(IEventQueue *events, SocketMultiplexer *socketMultiplexer, int port); - IpcServer(IpcServer const &) = delete; - IpcServer(IpcServer &&) = delete; - virtual ~IpcServer(); - - IpcServer &operator=(IpcServer const &) = delete; - IpcServer &operator=(IpcServer &&) = delete; - - //! @name manipulators - //@{ - - //! Opens a TCP socket only allowing local connections. - virtual void listen(); - - //! Send a message to all clients matching the filter type. - virtual void send(const IpcMessage &message, IpcClientType filterType); - - //@} - //! @name accessors - //@{ - - //! Returns true when there are clients of the specified type connected. - virtual bool hasClients(IpcClientType clientType) const; - - //@} - -private: - void init(); - void handleClientConnecting(const Event &, void *); - void handleClientDisconnected(const Event &, void *); - void handleMessageReceived(const Event &, void *); - void deleteClient(IpcClientProxy *proxy); - -private: - using ClientList = std::list; - - bool m_mock; - IEventQueue *m_events; - SocketMultiplexer *m_socketMultiplexer; - TCPListenSocket *m_socket; - NetworkAddress m_address; - ClientList m_clients; - ArchMutex m_clientsMutex; - -#ifdef TEST_ENV -public: - IpcServer() : m_mock(true), m_events(nullptr), m_socketMultiplexer(nullptr), m_socket(nullptr) - { - } -#endif -}; diff --git a/src/lib/ipc/IpcServerProxy.cpp b/src/lib/ipc/IpcServerProxy.cpp deleted file mode 100644 index c86105957..000000000 --- a/src/lib/ipc/IpcServerProxy.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "ipc/IpcServerProxy.h" - -#include "base/Log.h" -#include "base/TMethodEventJob.h" -#include "common/ipc.h" -#include "deskflow/ProtocolUtil.h" -#include "io/IStream.h" -#include "ipc/IpcMessage.h" - -// -// IpcServerProxy -// - -IpcServerProxy::IpcServerProxy(deskflow::IStream &stream, IEventQueue *events) : m_stream(stream), m_events(events) -{ - m_events->adoptHandler( - m_events->forIStream().inputReady(), stream.getEventTarget(), - new TMethodEventJob(this, &IpcServerProxy::handleData) - ); -} - -IpcServerProxy::~IpcServerProxy() -{ - m_events->removeHandler(m_events->forIStream().inputReady(), m_stream.getEventTarget()); -} - -void IpcServerProxy::handleData(const Event &, void *) -{ - LOG((CLOG_DEBUG "start ipc handle data")); - - uint8_t code[4]; - uint32_t n = m_stream.read(code, 4); - while (n != 0) { - - LOG((CLOG_DEBUG "ipc read: %c%c%c%c", code[0], code[1], code[2], code[3])); - - IpcMessage *m = nullptr; - if (memcmp(code, kIpcMsgLogLine, 4) == 0) { - m = parseLogLine(); - } else if (memcmp(code, kIpcMsgShutdown, 4) == 0) { - m = new IpcShutdownMessage(); - } else { - LOG((CLOG_ERR "invalid ipc message")); - disconnect(); - } - - // don't delete with this event; the data is passed to a new event. - Event e(m_events->forIpcServerProxy().messageReceived(), this, NULL, Event::kDontFreeData); - e.setDataObject(m); - m_events->addEvent(e); - - n = m_stream.read(code, 4); - } - - LOG((CLOG_DEBUG "finished ipc handle data")); -} - -void IpcServerProxy::send(const IpcMessage &message) -{ - LOG((CLOG_DEBUG4 "ipc write: %d", message.type())); - - switch (message.type()) { - case IpcMessageType::Hello: { - const IpcHelloMessage &hm = static_cast(message); - ProtocolUtil::writef(&m_stream, kIpcMsgHello, hm.clientType()); - break; - } - - case IpcMessageType::Command: { - const IpcCommandMessage &cm = static_cast(message); - const std::string command = cm.command(); - ProtocolUtil::writef(&m_stream, kIpcMsgCommand, &command); - break; - } - - default: - LOG((CLOG_ERR "ipc message not supported: %d", message.type())); - break; - } -} - -IpcLogLineMessage *IpcServerProxy::parseLogLine() -{ - std::string logLine; - ProtocolUtil::readf(&m_stream, kIpcMsgLogLine + 4, &logLine); - - // must be deleted by event handler. - return new IpcLogLineMessage(logLine); -} - -void IpcServerProxy::disconnect() -{ - LOG((CLOG_DEBUG "ipc disconnect, closing stream")); - m_stream.close(); -} diff --git a/src/lib/ipc/IpcServerProxy.h b/src/lib/ipc/IpcServerProxy.h deleted file mode 100644 index 81f271257..000000000 --- a/src/lib/ipc/IpcServerProxy.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "base/Event.h" -#include "base/EventTypes.h" - -namespace deskflow { -class IStream; -} -class IpcMessage; -class IpcLogLineMessage; -class IEventQueue; - -class IpcServerProxy -{ - friend class IpcClient; - -public: - IpcServerProxy(deskflow::IStream &stream, IEventQueue *events); - IpcServerProxy(IpcServerProxy const &) = delete; - virtual ~IpcServerProxy(); - -private: - void send(const IpcMessage &message); - - void handleData(const Event &, void *); - IpcLogLineMessage *parseLogLine(); - void disconnect(); - -private: - deskflow::IStream &m_stream; - IEventQueue *m_events; -}; diff --git a/src/lib/ipc/IpcSettingMessage.cpp b/src/lib/ipc/IpcSettingMessage.cpp deleted file mode 100644 index 328eebdde..000000000 --- a/src/lib/ipc/IpcSettingMessage.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "IpcSettingMessage.h" - -IpcSettingMessage::IpcSettingMessage(const std::string &name, const std::string &value) - : IpcMessage(IpcMessageType::Setting), - m_name(name), - m_value(value) -{ -} - -const std::string &IpcSettingMessage::getName() const -{ - return m_name; -} - -const std::string &IpcSettingMessage::getValue() const -{ - return m_value; -} diff --git a/src/lib/ipc/IpcSettingMessage.h b/src/lib/ipc/IpcSettingMessage.h deleted file mode 100644 index e7b1b8d6d..000000000 --- a/src/lib/ipc/IpcSettingMessage.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "IpcMessage.h" -#include - -class IpcSettingMessage : public IpcMessage -{ -public: - //! - //! \brief IpcSettingMessage constructor - //! \param name - setting name - //! \param value - setting value - //! - IpcSettingMessage(const std::string &name, const std::string &value); - - //! - //! \brief getName is a getter for the setting name - //! \return setting name - //! - const std::string &getName() const; - - //! - //! \brief getValue is a getter for the setting value - //! \return setting value - //! - const std::string &getValue() const; - -private: - std::string m_name; - std::string m_value; -}; diff --git a/src/lib/platform/CMakeLists.txt b/src/lib/platform/CMakeLists.txt index 8f0ea2051..e1a59ae73 100644 --- a/src/lib/platform/CMakeLists.txt +++ b/src/lib/platform/CMakeLists.txt @@ -179,7 +179,6 @@ if(UNIX) platform io net - ipc app client ${libs}) diff --git a/src/lib/platform/MSWindowsProcess.cpp b/src/lib/platform/MSWindowsProcess.cpp index 9ec075ba4..e1e0ddc9a 100644 --- a/src/lib/platform/MSWindowsProcess.cpp +++ b/src/lib/platform/MSWindowsProcess.cpp @@ -8,7 +8,6 @@ #include "arch/win32/XArchWindows.h" #include "base/Log.h" -#include "ipc/IpcMessage.h" #define WIN32_LEAN_AND_MEAN #include diff --git a/src/lib/platform/MSWindowsWatchdog.cpp b/src/lib/platform/MSWindowsWatchdog.cpp index 2599ec56d..d3fa0f375 100644 --- a/src/lib/platform/MSWindowsWatchdog.cpp +++ b/src/lib/platform/MSWindowsWatchdog.cpp @@ -1,7 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2009 Chris Schoeneman + * SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd. * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception */ @@ -13,12 +12,8 @@ #include "base/Log.h" #include "base/TMethodJob.h" #include "base/log_outputters.h" -#include "common/ipc.h" #include "deskflow/App.h" #include "deskflow/ArgsBase.h" -#include "ipc/IpcLogOutputter.h" -#include "ipc/IpcMessage.h" -#include "ipc/IpcServer.h" #include "mt/Thread.h" #include @@ -437,7 +432,7 @@ void MSWindowsWatchdog::outputLoop(void *) // process output to the VS debug output window. // we could use the MSWindowsDebugOutputter, but it's really fiddly to // so, and there doesn't seem to be an advantage of doing that. - OutputDebugString(output.c_str()); + OutputDebugString(buffer); } #endif } diff --git a/src/lib/platform/MSWindowsWatchdog.h b/src/lib/platform/MSWindowsWatchdog.h index e360152b2..5ef19adfb 100644 --- a/src/lib/platform/MSWindowsWatchdog.h +++ b/src/lib/platform/MSWindowsWatchdog.h @@ -1,7 +1,6 @@ /* * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2009 Chris Schoeneman + * SPDX-FileCopyrightText: (C) 2012 - 2025 Symless Ltd. * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception */ @@ -19,8 +18,6 @@ #include class Thread; -class IpcLogOutputter; -class IpcServer; class FileLogOutputter; class MSWindowsWatchdog diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 0f3df7987..5bba82c95 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -140,7 +140,6 @@ macro(config_test_deps) server app mt - ipc gui GTest::gtest GTest::gmock diff --git a/src/test/integtests/ipc/IpcTests.cpp b/src/test/integtests/ipc/IpcTests.cpp deleted file mode 100644 index 2019644ad..000000000 --- a/src/test/integtests/ipc/IpcTests.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd. - * SPDX-FileCopyrightText: (C) 2012 Nick Bolton - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -// TODO: fix, tests failing intermittently on mac. -#ifndef WINAPI_CARBON - -#define TEST_ENV - -#include "arch/Arch.h" -#include "base/EventQueue.h" -#include "base/Log.h" -#include "base/TMethodEventJob.h" -#include "base/TMethodJob.h" -#include "common/ipc.h" -#include "ipc/IpcClient.h" -#include "ipc/IpcClientProxy.h" -#include "ipc/IpcMessage.h" -#include "ipc/IpcServer.h" -#include "ipc/IpcServerProxy.h" -#include "mt/Thread.h" -#include "net/SocketMultiplexer.h" -#include "test/shared/TestEventQueue.h" - -#include - -const int kTestPort = 24802; - -class IpcTests : public ::testing::Test -{ -public: - IpcTests(); - virtual ~IpcTests(); - - void connectToServer_handleMessageReceived(const Event &, void *); - void sendMessageToServer_serverHandleMessageReceived(const Event &, void *); - void sendMessageToClient_serverHandleClientConnected(const Event &, void *); - void sendMessageToClient_clientHandleMessageReceived(const Event &, void *); - -public: - SocketMultiplexer m_multiplexer; - bool m_connectToServer_helloMessageReceived; - bool m_connectToServer_hasClientNode; - IpcServer *m_connectToServer_server; - std::string m_sendMessageToServer_receivedString; - std::string m_sendMessageToClient_receivedString; - IpcClient *m_sendMessageToServer_client; - IpcServer *m_sendMessageToClient_server; - TestEventQueue m_events; -}; - -TEST_F(IpcTests, connectToServer) -{ - SocketMultiplexer socketMultiplexer; - IpcServer server(&m_events, &socketMultiplexer, kTestPort); - server.listen(); - m_connectToServer_server = &server; - - m_events.adoptHandler( - m_events.forIpcServer().messageReceived(), &server, - new TMethodEventJob(this, &IpcTests::connectToServer_handleMessageReceived) - ); - - IpcClient client(&m_events, &socketMultiplexer, kTestPort); - client.connect(); - - m_events.initQuitTimeout(5); - m_events.loop(); - m_events.removeHandler(m_events.forIpcServer().messageReceived(), &server); - m_events.cleanupQuitTimeout(); - - EXPECT_EQ(true, m_connectToServer_helloMessageReceived); - EXPECT_EQ(true, m_connectToServer_hasClientNode); -} - -TEST_F(IpcTests, sendMessageToServer) -{ - SocketMultiplexer socketMultiplexer; - IpcServer server(&m_events, &socketMultiplexer, kTestPort); - server.listen(); - - // event handler sends "test" command to server. - m_events.adoptHandler( - m_events.forIpcServer().messageReceived(), &server, - new TMethodEventJob(this, &IpcTests::sendMessageToServer_serverHandleMessageReceived) - ); - - IpcClient client(&m_events, &socketMultiplexer, kTestPort); - client.connect(); - m_sendMessageToServer_client = &client; - - m_events.initQuitTimeout(5); - m_events.loop(); - m_events.removeHandler(m_events.forIpcServer().messageReceived(), &server); - m_events.cleanupQuitTimeout(); - - EXPECT_EQ("test", m_sendMessageToServer_receivedString); -} - -TEST_F(IpcTests, sendMessageToClient) -{ - SocketMultiplexer socketMultiplexer; - IpcServer server(&m_events, &socketMultiplexer, kTestPort); - server.listen(); - m_sendMessageToClient_server = &server; - - // event handler sends "test" log line to client. - m_events.adoptHandler( - m_events.forIpcServer().messageReceived(), &server, - new TMethodEventJob(this, &IpcTests::sendMessageToClient_serverHandleClientConnected) - ); - - IpcClient client(&m_events, &socketMultiplexer, kTestPort); - client.connect(); - - m_events.adoptHandler( - m_events.forIpcClient().messageReceived(), &client, - new TMethodEventJob(this, &IpcTests::sendMessageToClient_clientHandleMessageReceived) - ); - - m_events.initQuitTimeout(5); - m_events.loop(); - m_events.removeHandler(m_events.forIpcServer().messageReceived(), &server); - m_events.removeHandler(m_events.forIpcClient().messageReceived(), &client); - m_events.cleanupQuitTimeout(); - - EXPECT_EQ("test", m_sendMessageToClient_receivedString); -} - -IpcTests::IpcTests() - : m_connectToServer_helloMessageReceived(false), - m_connectToServer_hasClientNode(false), - m_connectToServer_server(nullptr), - m_sendMessageToClient_server(nullptr), - m_sendMessageToServer_client(nullptr) -{ -} - -IpcTests::~IpcTests() -{ -} - -void IpcTests::connectToServer_handleMessageReceived(const Event &e, void *) -{ - IpcMessage *m = static_cast(e.getDataObject()); - if (m->type() == IpcMessageType::Hello) { - m_connectToServer_hasClientNode = m_connectToServer_server->hasClients(IpcClientType::Node); - m_connectToServer_helloMessageReceived = true; - m_events.raiseQuitEvent(); - } -} - -void IpcTests::sendMessageToServer_serverHandleMessageReceived(const Event &e, void *) -{ - IpcMessage *m = static_cast(e.getDataObject()); - if (m->type() == IpcMessageType::Hello) { - LOG((CLOG_DEBUG "client said hello, sending test to server")); - IpcCommandMessage m("test", true); - m_sendMessageToServer_client->send(m); - } else if (m->type() == IpcMessageType::Command) { - IpcCommandMessage *cm = static_cast(m); - LOG((CLOG_DEBUG "got ipc command message, %d", cm->command().c_str())); - m_sendMessageToServer_receivedString = cm->command(); - m_events.raiseQuitEvent(); - } -} - -void IpcTests::sendMessageToClient_serverHandleClientConnected(const Event &e, void *) -{ - IpcMessage *m = static_cast(e.getDataObject()); - if (m->type() == IpcMessageType::Hello) { - LOG((CLOG_DEBUG "client said hello, sending test to client")); - IpcLogLineMessage m("test"); - m_sendMessageToClient_server->send(m, IpcClientType::Node); - } -} - -void IpcTests::sendMessageToClient_clientHandleMessageReceived(const Event &e, void *) -{ - IpcMessage *m = static_cast(e.getDataObject()); - if (m->type() == IpcMessageType::LogLine) { - IpcLogLineMessage *llm = static_cast(m); - LOG((CLOG_DEBUG "got ipc log message, %d", llm->logLine().c_str())); - m_sendMessageToClient_receivedString = llm->logLine(); - m_events.raiseQuitEvent(); - } -} - -#endif // WINAPI_CARBON diff --git a/src/test/mock/deskflow/MockEventQueue.h b/src/test/mock/deskflow/MockEventQueue.h index 1b3fe5450..864821db6 100644 --- a/src/test/mock/deskflow/MockEventQueue.h +++ b/src/test/mock/deskflow/MockEventQueue.h @@ -34,10 +34,6 @@ public: MOCK_METHOD(void *, getSystemTarget, (), (override)); MOCK_METHOD(ClientEvents &, forClient, (), (override)); MOCK_METHOD(IStreamEvents &, forIStream, (), (override)); - MOCK_METHOD(IpcClientEvents &, forIpcClient, (), (override)); - MOCK_METHOD(IpcClientProxyEvents &, forIpcClientProxy, (), (override)); - MOCK_METHOD(IpcServerEvents &, forIpcServer, (), (override)); - MOCK_METHOD(IpcServerProxyEvents &, forIpcServerProxy, (), (override)); MOCK_METHOD(IDataSocketEvents &, forIDataSocket, (), (override)); MOCK_METHOD(IListenSocketEvents &, forIListenSocket, (), (override)); MOCK_METHOD(ISocketEvents &, forISocket, (), (override)); diff --git a/src/test/mock/ipc/MockIpcServer.h b/src/test/mock/ipc/MockIpcServer.h deleted file mode 100644 index b02a9e33c..000000000 --- a/src/test/mock/ipc/MockIpcServer.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2015 - 2016 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#pragma once - -#include "arch/Arch.h" -#include "ipc/IpcMessage.h" -#include "ipc/IpcServer.h" - -#include - -using ::testing::_; -using ::testing::Invoke; - -class IEventQueue; - -class MockIpcServer : public IpcServer -{ -public: - MockIpcServer() : m_sendCond(ARCH->newCondVar()), m_sendMutex(ARCH->newMutex()) - { - } - - ~MockIpcServer() - { - if (m_sendCond != NULL) { - ARCH->closeCondVar(m_sendCond); - } - - if (m_sendMutex != NULL) { - ARCH->closeMutex(m_sendMutex); - } - } - - MOCK_METHOD(void, listen, (), (override)); - MOCK_METHOD(void, send, (const IpcMessage &, IpcClientType), (override)); - MOCK_METHOD(bool, hasClients, (IpcClientType), (const, override)); - - void delegateToFake() - { - ON_CALL(*this, send(_, _)).WillByDefault(Invoke(this, &MockIpcServer::mockSend)); - } - - void waitForSend() - { - ARCH->waitCondVar(m_sendCond, m_sendMutex, 5); - } - -private: - void mockSend(const IpcMessage &, IpcClientType) - { - ArchMutexLock lock(m_sendMutex); - ARCH->broadcastCondVar(m_sendCond); - } - - ArchCond m_sendCond; - ArchMutex m_sendMutex; -}; diff --git a/src/test/unittests/deskflow/GenericArgsParsingTests.cpp b/src/test/unittests/deskflow/GenericArgsParsingTests.cpp index 5be09aaa5..5f37a85a0 100644 --- a/src/test/unittests/deskflow/GenericArgsParsingTests.cpp +++ b/src/test/unittests/deskflow/GenericArgsParsingTests.cpp @@ -205,18 +205,6 @@ TEST_F(GenericArgsParsingTests, parseGenericArgs_versionCmd_showVersion) EXPECT_EQ(1, i); } -TEST_F(GenericArgsParsingTests, parseGenericArgs_ipcCmd_enableIpcTrue) -{ - int i = 1; - const int argc = 2; - const char *kIpcCmd[argc] = {"stub", "--ipc"}; - - m_argParser->parseGenericArgs(argc, kIpcCmd, i); - - EXPECT_EQ(true, argsBase.m_enableIpc); - EXPECT_EQ(1, i); -} - #ifndef WINAPI_XWINDOWS TEST_F(GenericArgsParsingTests, parseGenericArgs_dragDropCmdOnNonLinux_enableDragDropTrue) { diff --git a/src/test/unittests/gui/core/CoreProcessTests.cpp b/src/test/unittests/gui/core/CoreProcessTests.cpp index e41d181cb..61dfcdcc7 100644 --- a/src/test/unittests/gui/core/CoreProcessTests.cpp +++ b/src/test/unittests/gui/core/CoreProcessTests.cpp @@ -6,7 +6,6 @@ #include "gui/config/IAppConfig.h" #include "gui/core/CoreProcess.h" -#include "gui/ipc/IQIpcClient.h" #include "gui/proxy/QProcessProxy.h" #include "shared/gui/mocks/AppConfigMock.h" #include "shared/gui/mocks/ServerConfigMock.h" @@ -45,41 +44,23 @@ public: MOCK_METHOD(QString, readAllStandardError, (), (override)); }; -class QIpcClientMock : public ipc::IQIpcClient -{ -public: - QIpcClientMock() - { - ON_CALL(*this, isConnected()).WillByDefault(Return(true)); - } - - MOCK_METHOD(void, sendHello, (), (const, override)); - MOCK_METHOD(void, sendCommand, (const QString &command, ElevateMode elevate), (const, override)); - MOCK_METHOD(void, connectToHost, (), (override)); - MOCK_METHOD(void, disconnectFromHost, (), (override)); - MOCK_METHOD(bool, isConnected, (), (const, override)); -}; - class DepsMock : public CoreProcess::Deps { public: DepsMock() { ON_CALL(*this, process()).WillByDefault(ReturnRef(m_process)); - ON_CALL(*this, ipcClient()).WillByDefault(ReturnRef(m_ipcClient)); ON_CALL(*this, appPath(_)).WillByDefault(Return("stub app path")); ON_CALL(*this, fileExists(_)).WillByDefault(Return(true)); ON_CALL(*this, getProfileRoot()).WillByDefault(Return("stub profile")); } MOCK_METHOD(proxy::QProcessProxy &, process, (), (override)); - MOCK_METHOD(ipc::IQIpcClient &, ipcClient, (), (override)); MOCK_METHOD(QString, appPath, (const QString &name), (const, override)); MOCK_METHOD(bool, fileExists, (const QString &path), (const, override)); MOCK_METHOD(QString, getProfileRoot, (), (const, override)); NiceMock m_process; - NiceMock m_ipcClient; }; class CoreProcessTests : public Test @@ -111,15 +92,6 @@ TEST_F(CoreProcessTests, start_serverDesktop_callsProcessStart) m_coreProcess.start(ProcessMode::kDesktop); } -TEST_F(CoreProcessTests, start_serverService_callsSendCommand) -{ - m_coreProcess.setMode(CoreProcess::Mode::Server); - - EXPECT_CALL(m_pDeps->m_ipcClient, sendCommand(_, _)).Times(1); - - m_coreProcess.start(ProcessMode::kService); -} - TEST_F(CoreProcessTests, start_clientDesktop_callsProcessStart) { m_coreProcess.setMode(CoreProcess::Mode::Client); @@ -130,16 +102,6 @@ TEST_F(CoreProcessTests, start_clientDesktop_callsProcessStart) m_coreProcess.start(ProcessMode::kDesktop); } -TEST_F(CoreProcessTests, start_clientService_callsSendCommand) -{ - m_coreProcess.setMode(CoreProcess::Mode::Client); - m_coreProcess.setAddress("stub address"); - - EXPECT_CALL(m_pDeps->m_ipcClient, sendCommand(_, _)).Times(1); - - m_coreProcess.start(ProcessMode::kService); -} - TEST_F(CoreProcessTests, stop_serverDesktop_callsProcessClose) { m_coreProcess.setMode(CoreProcess::Mode::Server); @@ -150,16 +112,6 @@ TEST_F(CoreProcessTests, stop_serverDesktop_callsProcessClose) m_coreProcess.stop(ProcessMode::kDesktop); } -TEST_F(CoreProcessTests, stop_serverService_callsSendCommand) -{ - m_coreProcess.setMode(CoreProcess::Mode::Server); - m_coreProcess.start(); - - EXPECT_CALL(m_pDeps->m_ipcClient, sendCommand(_, _)).Times(1); - - m_coreProcess.stop(ProcessMode::kService); -} - TEST_F(CoreProcessTests, stop_clientDesktop_callsProcessClose) { m_coreProcess.setMode(CoreProcess::Mode::Client); @@ -171,17 +123,6 @@ TEST_F(CoreProcessTests, stop_clientDesktop_callsProcessClose) m_coreProcess.stop(ProcessMode::kDesktop); } -TEST_F(CoreProcessTests, stop_clientService_callsSendCommand) -{ - m_coreProcess.setMode(CoreProcess::Mode::Client); - m_coreProcess.setAddress("stub address"); - m_coreProcess.start(); - - EXPECT_CALL(m_pDeps->m_ipcClient, sendCommand(_, _)).Times(1); - - m_coreProcess.stop(ProcessMode::kService); -} - TEST_F(CoreProcessTests, restart_serverDesktop_callsProcessStart) { ON_CALL(m_appConfig, processMode()).WillByDefault(Return(ProcessMode::kDesktop)); diff --git a/src/test/unittests/gui/ipc/QIpcClientTests.cpp b/src/test/unittests/gui/ipc/QIpcClientTests.cpp deleted file mode 100644 index 211454d98..000000000 --- a/src/test/unittests/gui/ipc/QIpcClientTests.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2024 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#include "gui/ipc/QIpcClient.h" - -#include -#include - -using testing::_; -using testing::StrEq; - -namespace { - -class MockStream : public QDataStreamProxy -{ -public: - MOCK_METHOD(qint64, writeRawData, (const char *, int), (override)); -}; - -} // namespace - -TEST(QIpcClientTests, sendCommand_anyCommand_commandSent) -{ - auto mockStream = std::make_shared(); - QIpcClient::StreamProvider streamProvider = [&mockStream]() { return mockStream; }; - - EXPECT_CALL(*mockStream, writeRawData(_, _)).Times(3); - EXPECT_CALL(*mockStream, writeRawData(StrEq("test"), 4)).Times(1); - - QIpcClient ipcClient(streamProvider); - ipcClient.sendCommand("test", ElevateMode::kAutomatic); -} diff --git a/src/test/unittests/ipc/IpcLogOutputterTests.cpp b/src/test/unittests/ipc/IpcLogOutputterTests.cpp deleted file mode 100644 index edf93dd37..000000000 --- a/src/test/unittests/ipc/IpcLogOutputterTests.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2015 - 2016 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#define TEST_ENV - -#include "test/mock/ipc/MockIpcServer.h" - -#include "base/String.h" -#include "common/common.h" -#include "ipc/IpcLogOutputter.h" -#include "mt/Thread.h" - -#include -#include - -// HACK: ipc logging only used on windows anyway -#if WINAPI_MSWINDOWS - -using ::testing::_; -using ::testing::AtLeast; -using ::testing::Matcher; -using ::testing::MatcherCast; -using ::testing::Property; -using ::testing::Return; -using ::testing::StrEq; - -using namespace deskflow; - -// TODO Fix the IPC Tests for windows, see #6709 -// Tests disabled due to gtest/gmock update causing build problems -// Decision to disable tests and create issue instead due to time constraints -// inline const Matcher IpcLogLineMessageEq(const std::string& s) -// { -// const Matcher m( -// Property(&IpcLogLineMessage::logLine, StrEq(s))); -// return MatcherCast(m); -// } -// -// TEST(IpcLogOutputterTests, write_threadingEnabled_bufferIsSent) -//{ -// MockIpcServer mockServer; -// mockServer.delegateToFake(); -// -// ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true)); -// -// EXPECT_CALL(mockServer, hasClients(_)).Times(AtLeast(3)); -// EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\n"), -// _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock -// 2\n"), _)).Times(1); -// -// IpcLogOutputter outputter(mockServer, IpcClientType::Unknown, true); -// outputter.write(kNOTE, "mock 1"); -// mockServer.waitForSend(); -// outputter.write(kNOTE, "mock 2"); -// mockServer.waitForSend(); -// } -// -// TEST(IpcLogOutputterTests, write_overBufferMaxSize_firstLineTruncated) -//{ -// MockIpcServer mockServer; -// -// ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true)); -// EXPECT_CALL(mockServer, hasClients(_)).Times(1); -// EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 2\nmock 3\n"), -// _)).Times(1); -// -// IpcLogOutputter outputter(mockServer, IpcClientType::Unknown, false); -// outputter.bufferMaxSize(2); -// -// // log more lines than the buffer can contain -// outputter.write(kNOTE, "mock 1"); -// outputter.write(kNOTE, "mock 2"); -// outputter.write(kNOTE, "mock 3"); -// outputter.sendBuffer(); -// } -// -// TEST(IpcLogOutputterTests, write_underBufferMaxSize_allLinesAreSent) -//{ -// MockIpcServer mockServer; -// -// ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true)); -// -// EXPECT_CALL(mockServer, hasClients(_)).Times(1); -// EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\nmock 2\n"), -// _)).Times(1); -// -// IpcLogOutputter outputter(mockServer, IpcClientType::Unknown, false); -// outputter.bufferMaxSize(2); -// -// // log more lines than the buffer can contain -// outputter.write(kNOTE, "mock 1"); -// outputter.write(kNOTE, "mock 2"); -// outputter.sendBuffer(); -// } -// -//// HACK: temporarily disable this intermittently failing unit test. -//// when the build machine is under heavy load, a race condition -//// usually happens. -// #if 0 -// TEST(IpcLogOutputterTests, write_overBufferRateLimit_lastLineTruncated) -//{ -// MockIpcServer mockServer; -// -// ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true)); -// -// EXPECT_CALL(mockServer, hasClients(_)).Times(2); -// EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\nmock 2\n"), -// _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock -// 4\nmock 5\n"), _)).Times(1); -// -// IpcLogOutputter outputter(mockServer, false); -// outputter.bufferRateLimit(2, 1); // 1s -// -// // log 1 more line than the buffer can accept in time limit. -// outputter.write(kNOTE, "mock 1"); -// outputter.write(kNOTE, "mock 2"); -// outputter.write(kNOTE, "mock 3"); -// -// outputter.sendBuffer(); -// -// // after waiting the time limit send another to make sure -// // we can log after the time limit passes. -// // HACK: sleep causes the unit test to fail intermittently, -// // so lets try 100ms (there must be a better way to solve this) -// ARCH->sleep(2); // 2s -// outputter.write(kNOTE, "mock 4"); -// outputter.write(kNOTE, "mock 5"); -// outputter.write(kNOTE, "mock 6"); -// -// outputter.sendBuffer(); -// } -// #endif -// -// TEST(IpcLogOutputterTests, write_underBufferRateLimit_allLinesAreSent) -//{ -// MockIpcServer mockServer; -// -// ON_CALL(mockServer, hasClients(_)).WillByDefault(Return(true)); -// -// EXPECT_CALL(mockServer, hasClients(_)).Times(2); -// EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\nmock 2\n"), -// _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock -// 3\nmock 4\n"), _)).Times(1); -// -// IpcLogOutputter outputter(mockServer, IpcClientType::Unknown, false); -// outputter.bufferRateLimit(4, 1); // 1s (should be plenty of time) -// -// // log 1 more line than the buffer can accept in time limit. -// outputter.write(kNOTE, "mock 1"); -// outputter.write(kNOTE, "mock 2"); -// outputter.sendBuffer(); -// -// // after waiting the time limit send another to make sure -// // we can log after the time limit passes. -// outputter.write(kNOTE, "mock 3"); -// outputter.write(kNOTE, "mock 4"); -// outputter.sendBuffer(); -// } - -#endif // WINAPI_MSWINDOWS diff --git a/src/test/unittests/ipc/IpcSettingMessageTests.cpp b/src/test/unittests/ipc/IpcSettingMessageTests.cpp deleted file mode 100644 index 3f9c8f5d4..000000000 --- a/src/test/unittests/ipc/IpcSettingMessageTests.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Deskflow -- mouse and keyboard sharing utility - * SPDX-FileCopyrightText: (C) 2015 - 2016 Symless Ltd. - * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception - */ - -#define TEST_ENV - -#include "ipc/IpcSettingMessage.h" - -#include - -TEST(IpcSettingMessage, testIpcSettingMessage) -{ - const std::string expected_name = "test"; - const std::string expected_value = "test_value"; - - IpcSettingMessage message("test", "test_value"); - - EXPECT_EQ(expected_name, message.getName()); - EXPECT_EQ(expected_value, message.getValue()); -}