Add: DDBusSender class is useful tools to make a dbus call
author石博文 <sbw@sbw.so>
Tue, 27 Mar 2018 03:49:52 +0000 (11:49 +0800)
committer石博文 <sbw@sbw.so>
Thu, 29 Mar 2018 08:10:12 +0000 (08:10 +0000)
Change-Id: If5a83586dea9ce46fb3cbbb6756083712bdc3528

src/util/DDBusSender [new file with mode: 0644]
src/util/ddbussender.cpp [new file with mode: 0644]
src/util/ddbussender.h [new file with mode: 0644]
src/util/util.pri
tests/dutiltester.cpp
tests/dutiltester.h
tests/tests.pro

diff --git a/src/util/DDBusSender b/src/util/DDBusSender
new file mode 100644 (file)
index 0000000..8881ba7
--- /dev/null
@@ -0,0 +1 @@
+#include "ddbussender.h"
diff --git a/src/util/ddbussender.cpp b/src/util/ddbussender.cpp
new file mode 100644 (file)
index 0000000..c3498fe
--- /dev/null
@@ -0,0 +1,91 @@
+#include "ddbussender.h"
+
+#include <QDBusInterface>
+#include <QDebug>
+
+DDBusSender::DDBusSender()
+    : m_dbusData(std::make_shared<DDBusData>())
+{
+}
+
+DDBusSender DDBusSender::service(const QString &service)
+{
+    m_dbusData->service = service;
+
+    return *this;
+}
+
+DDBusSender DDBusSender::interface(const QString &interface)
+{
+    m_dbusData->interface = interface;
+
+    return *this;
+}
+
+DDBusCaller DDBusSender::method(const QString &method)
+{
+    return DDBusCaller(method, m_dbusData);
+}
+
+DDBusProperty DDBusSender::property(const QString &property)
+{
+    return DDBusProperty(property, m_dbusData);
+}
+
+DDBusSender DDBusSender::path(const QString &path)
+{
+    m_dbusData->path = path;
+
+    return *this;
+}
+
+DDBusSender DDBusSender::type(const QDBusConnection::BusType busType)
+{
+    switch (busType)
+    {
+    case QDBusConnection::SessionBus:
+        m_dbusData->connection = QDBusConnection::sessionBus();
+        break;
+
+    case QDBusConnection::SystemBus:
+        m_dbusData->connection = QDBusConnection::systemBus();
+        break;
+
+    default:
+        Q_UNREACHABLE_IMPL();
+    }
+
+    return *this;
+}
+
+DDBusData::DDBusData()
+    : connection(QDBusConnection::sessionBus())
+{
+
+}
+
+QDBusPendingCall DDBusCaller::call()
+{
+    QDBusInterface iface(m_dbusData->service, m_dbusData->path, m_dbusData->interface, m_dbusData->connection);
+
+    return iface.asyncCallWithArgumentList(m_methodName, m_arguments);
+}
+
+DDBusCaller::DDBusCaller(const QString &method, std::shared_ptr<DDBusData> data)
+    : m_dbusData(data)
+    , m_methodName(method)
+{
+}
+
+QDBusPendingCall DDBusProperty::get()
+{
+    QDBusInterface iface(m_dbusData->service, m_dbusData->path, QStringLiteral("org.freedesktop.DBus.Properties"), m_dbusData->connection);
+
+    return iface.asyncCallWithArgumentList(QStringLiteral("Get"), { QVariant::fromValue(m_dbusData->interface), QVariant::fromValue(m_propertyName) });
+}
+
+DDBusProperty::DDBusProperty(const QString &property, std::shared_ptr<DDBusData> data)
+    : m_dbusData(data)
+    , m_propertyName(property)
+{
+}
diff --git a/src/util/ddbussender.h b/src/util/ddbussender.h
new file mode 100644 (file)
index 0000000..67e76f7
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef DDBUSSENDER_H
+#define DDBUSSENDER_H
+
+#include <QObject>
+#include <QDBusConnection>
+#include <QDBusPendingCall>
+#include <QDBusInterface>
+
+#include <memory>
+
+class DDBusData
+{
+public:
+    DDBusData();
+
+    QString service;
+    QString path;
+    QString interface;
+    QString queryName;
+    QDBusConnection connection;
+};
+
+class DDBusCaller
+{
+    friend class DDBusSender;
+
+public:
+    QDBusPendingCall call();
+
+    template <typename T>
+    DDBusCaller arg(const T &argument);
+
+private:
+    explicit DDBusCaller(const QString &method, std::shared_ptr<DDBusData> data);
+
+private:
+    std::shared_ptr<DDBusData> m_dbusData;
+    QString m_methodName;
+    QVariantList m_arguments;
+};
+
+template <typename T>
+DDBusCaller DDBusCaller::arg(const T &argument)
+{
+    m_arguments << QVariant::fromValue(argument);
+
+    return *this;
+}
+
+class DDBusProperty
+{
+    friend class DDBusSender;
+
+public:
+    QDBusPendingCall get();
+    template <typename T>
+    QDBusPendingCall set(const T &value);
+
+private:
+    explicit DDBusProperty(const QString &property, std::shared_ptr<DDBusData> data);
+
+private:
+    std::shared_ptr<DDBusData> m_dbusData;
+    QString m_propertyName;
+};
+
+template <typename T>
+QDBusPendingCall DDBusProperty::set(const T &value)
+{
+    QDBusInterface iface(m_dbusData->service, m_dbusData->path, QStringLiteral("org.freedesktop.DBus.Properties"), m_dbusData->connection);
+
+    const QVariantList args = { QVariant::fromValue(m_dbusData->interface), QVariant::fromValue(m_propertyName), QVariant::fromValue(QDBusVariant(value)) };
+
+    return iface.asyncCallWithArgumentList(QStringLiteral("Set"), args);
+}
+
+class DDBusSender
+{
+public:
+    explicit DDBusSender();
+
+    DDBusSender service(const QString &service);
+    DDBusSender interface(const QString &interface);
+    DDBusSender path(const QString &path);
+    DDBusCaller method(const QString &method);
+    DDBusProperty property(const QString &property);
+
+private:
+    DDBusSender type(const QDBusConnection::BusType busType);
+
+private:
+    std::shared_ptr<DDBusData> m_dbusData;
+};
+
+#endif // DDBUSSENDER_H
index 60eaaa154aded0f6b6c6c557c9271a2ee45bec69..d04bfb7acaec76a6ca33960e4a18bb8bb1c649ad 100644 (file)
@@ -3,7 +3,8 @@ HEADERS += \
     $$PWD/dpinyin.h \
     $$PWD/dtimeunitformatter.h \
     $$PWD/dabstractunitformatter.h \
-    $$PWD/ddisksizeformatter.h
+    $$PWD/ddisksizeformatter.h \
+    $$PWD/ddbussender.h
 
 includes.files += $$PWD/*.h
 includes.files += \
@@ -16,4 +17,5 @@ RESOURCES += \
 SOURCES += \
     $$PWD/dtimeunitformatter.cpp \
     $$PWD/dabstractunitformatter.cpp \
-    $$PWD/ddisksizeformatter.cpp
+    $$PWD/ddisksizeformatter.cpp \
+    $$PWD/ddbussender.cpp
index 2c63b96d6abb207de8562ba28794c2e6f54e2ca5..69edb3f6da8fe3de155ee05e51a89e44ad8c0ac0 100644 (file)
 #include <QtTest/QtTest>
 #include <QStandardPaths>
 #include <QThread>
+#include <QDBusPendingCall>
+#include <QDBusReply>
 
 #include "log/LogManager.h"
 #include "filesystem/dpathbuf.h"
 #include "singletontester.h"
 #include "util/dtimeunitformatter.h"
 #include "util/ddisksizeformatter.h"
+#include "util/ddbussender.h"
 #include "settings/dsettings.h"
 #include "settings/dsettingsgroup.h"
 #include "settings/dsettingsoption.h"
@@ -153,6 +156,56 @@ void TestDUtil::testDiskFormatter1024()
     Q_ASSERT(qFuzzyCompare(0.09094947017729282, d2));
 }
 
+void TestDUtil::testDBusSender()
+{
+    // basic method call
+    DDBusSender()
+        .service("com.deepin.dde.ControlCenter")
+        .interface("com.deepin.dde.ControlCenter")
+        .path("/com/deepin/dde/ControlCenter")
+        .method("ShowPage")
+        .arg(QString("update"))
+        .arg(QString("available-updates"))
+        .call();
+
+    // property set
+    QDBusPendingReply<> r1 = DDBusSender()
+        .service("com.deepin.dde.daemon.Dock")
+        .interface("com.deepin.dde.daemon.Dock")
+        .path("/com/deepin/dde/daemon/Dock")
+        .property("DisplayMode")
+        .set(1); // set to efficient mode
+
+    // property get
+    QDBusPendingReply<QVariant> r2 = DDBusSender()
+        .service("com.deepin.dde.daemon.Dock")
+        .interface("com.deepin.dde.daemon.Dock")
+        .path("/com/deepin/dde/daemon/Dock")
+        .property("DisplayMode")
+        .get(); // read mode
+
+    if (!r2.isError() && !r1.isError())
+        Q_ASSERT(r2.value().toInt() == 1);
+
+    // complex type property get
+    QDBusPendingReply<QVariant> r3 = DDBusSender()
+        .service("com.deepin.dde.ControlCenter")
+        .interface("com.deepin.dde.ControlCenter")
+        .path("/com/deepin/dde/ControlCenter")
+        .property("Rect")
+        .get();
+
+    QVariant variant = r3.value();
+    const QDBusArgument v = variant.value<QDBusArgument>();
+
+    int x, y, w, h;
+    v.beginStructure();
+    v >> x >> y >> w >> h;
+    v.endStructure();
+
+    qDebug() << x << y << w << h;
+}
+
 void TestDUtil::testGroups()
 {
     auto path = ":/data/dt-settings.json";
index a17e4136f012786aab17445110c9678f4ae413d2..4cc5a5fe293449a7d96a7d7eebb1565922e8089c 100644 (file)
@@ -32,6 +32,7 @@ private Q_SLOTS:
     void testDiskFormatter();
     void testDiskFormatterList();
     void testDiskFormatter1024();
+    void testDBusSender();
 
     void testGroups();
 };
index ecd8d4181586cb7933bf9a8d2178f2791a083b52..a632c0d152345f3f9077cb9d0cc5238d86a8d955 100644 (file)
@@ -1,4 +1,4 @@
-QT += testlib
+QT += testlib dbus
 QT -= gui
 
 TEMPLATE = app