File indexing completed on 2024-05-05 05:34:20

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