File indexing completed on 2024-04-21 16:17:32
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Daniel Vratil <dvratil@redhat.com> 0003 * SPDX-FileCopyrightText: 2015 Sebastian Kügler <sebas@kde.org> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.1-or-later 0006 * 0007 */ 0008 0009 /** 0010 * WARNING: This header is *not* part of public API and is subject to change. 0011 * There are not guarantees or API or ABI stability or compatibility between 0012 * releases 0013 */ 0014 0015 #ifndef KSCREEN_BACKENDMANAGER_H 0016 #define KSCREEN_BACKENDMANAGER_H 0017 0018 #include <QDBusServiceWatcher> 0019 #include <QEventLoop> 0020 #include <QFileInfoList> 0021 #include <QObject> 0022 #include <QPluginLoader> 0023 #include <QProcess> 0024 #include <QTimer> 0025 0026 #include "kscreen_export.h" 0027 #include "types.h" 0028 0029 class QDBusPendingCallWatcher; 0030 class OrgKdeKscreenBackendInterface; 0031 0032 namespace KScreen 0033 { 0034 class AbstractBackend; 0035 0036 class KSCREEN_EXPORT BackendManager : public QObject 0037 { 0038 Q_OBJECT 0039 0040 public: 0041 enum Method { 0042 InProcess, 0043 OutOfProcess, 0044 }; 0045 0046 static BackendManager *instance(); 0047 ~BackendManager() override; 0048 0049 KScreen::ConfigPtr config() const; 0050 void setConfig(KScreen::ConfigPtr c); 0051 0052 /** Choose which backend to use 0053 * 0054 * This method uses a couple of heuristics to pick the backend to be loaded: 0055 * - If the @p backend argument is specified and not empty it's used to filter the 0056 * available backend list 0057 * - If specified, the KSCREEN_BACKEND env var is considered (case insensitive) 0058 * - Otherwise, the wayland backend is picked when the runtime platform is Wayland 0059 * (we assume kwin in this case 0060 * - Otherwise, if the runtime platform is X11, the XRandR backend is picked 0061 * - If neither is the case, we fall back to the QScreen backend, since that is the 0062 * most generally applicable and may work on platforms not explicitly supported 0063 * 0064 * @return the backend plugin to load 0065 * @since 5.7 0066 */ 0067 static QFileInfo preferredBackend(const QString &backend = QString()); 0068 0069 /** List installed backends 0070 * @return a list of installed backend plugins 0071 * @since 5.7 0072 */ 0073 static QFileInfoList listBackends(); 0074 0075 /** Set arguments map which a backend may use on initialization. 0076 * 0077 * Calling this method after a backend has been initialized will have no effect. 0078 * Arguments map will NOT be automatically cleared on backend shutdown; which 0079 * makes possible setting arguments before restarting backend in tests. 0080 * 0081 * @param map of arbitrary arguments for backends; each backend is free to interpret 0082 * them as it sees fit. 0083 * @since 5.27 0084 */ 0085 void setBackendArgs(const QVariantMap &arguments); 0086 0087 /** Get arguments map which a backend may use on initialization. 0088 * 0089 * @return map of arbitrary arguments for backends. 0090 * @since 5.27 0091 */ 0092 QVariantMap getBackendArgs(); 0093 0094 /** Encapsulates the plugin loading logic. 0095 * 0096 * @param loader a pointer to the QPluginLoader, the caller is 0097 * responsible for its memory management. 0098 * @param name name of the backend plugin 0099 * @param arguments arguments, used for unit tests 0100 * @return a pointer to the backend loaded from the plugin 0101 * @since 5.6 0102 */ 0103 static KScreen::AbstractBackend *loadBackendPlugin(QPluginLoader *loader, const QString &name, const QVariantMap &arguments); 0104 0105 KScreen::AbstractBackend *loadBackendInProcess(const QString &name); 0106 0107 BackendManager::Method method() const; 0108 void setMethod(BackendManager::Method m); 0109 0110 // For out-of-process operation 0111 void requestBackend(); 0112 void shutdownBackend(); 0113 0114 Q_SIGNALS: 0115 void backendReady(OrgKdeKscreenBackendInterface *backend); 0116 0117 private Q_SLOTS: 0118 void emitBackendReady(); 0119 0120 void startBackend(const QString &backend = QString(), const QVariantMap &arguments = QVariantMap()); 0121 void onBackendRequestDone(QDBusPendingCallWatcher *watcher); 0122 0123 void backendServiceUnregistered(const QString &serviceName); 0124 0125 private: 0126 friend class SetInProcessOperation; 0127 friend class InProcessConfigOperationPrivate; 0128 friend class SetConfigOperation; 0129 friend class SetConfigOperationPrivate; 0130 0131 explicit BackendManager(); 0132 static BackendManager *sInstance; 0133 0134 void initMethod(); 0135 0136 // For out-of-process operation 0137 void invalidateInterface(); 0138 void backendServiceReady(); 0139 0140 static const int sMaxCrashCount; 0141 OrgKdeKscreenBackendInterface *mInterface; 0142 int mCrashCount; 0143 0144 QString mBackendService; 0145 QDBusServiceWatcher mServiceWatcher; 0146 KScreen::ConfigPtr mConfig; 0147 QVariantMap mBackendArguments; 0148 QTimer mResetCrashCountTimer; 0149 bool mShuttingDown; 0150 int mRequestsCounter; 0151 QEventLoop mShutdownLoop; 0152 0153 // For in-process operation 0154 QPluginLoader *mLoader; 0155 KScreen::AbstractBackend *mInProcessBackend; 0156 0157 Method mMethod; 0158 }; 0159 0160 } 0161 0162 #endif // KSCREEN_BACKENDMANAGER_H