]> granicus.if.org Git - transmission/commitdiff
Refactor DBus IPC to allow for further extensibility
authorMike Gelfand <mikedld@mikedld.com>
Wed, 16 Dec 2015 17:57:05 +0000 (17:57 +0000)
committerMike Gelfand <mikedld@mikedld.com>
Wed, 16 Dec 2015 17:57:05 +0000 (17:57 +0000)
qt/Application.cc
qt/CMakeLists.txt
qt/DBusInteropHelper.cc [new file with mode: 0644]
qt/DBusInteropHelper.h [new file with mode: 0644]
qt/InteropObject.cc [moved from qt/DBusAdaptor.cc with 54% similarity]
qt/InteropObject.h [moved from qt/DBusAdaptor.h with 50% similarity]

index 6b23c95bc0d632705d2df1c169b7c267e978d264..51e56dafd687ec12ec2048767a670163995a2ed6 100644 (file)
@@ -11,9 +11,8 @@
 #include <iostream>
 
 #include <QDBusConnection>
-#include <QDBusConnectionInterface>
-#include <QDBusError>
 #include <QDBusMessage>
+#include <QDBusReply>
 #include <QIcon>
 #include <QLibraryInfo>
 #include <QMessageBox>
@@ -28,7 +27,7 @@
 
 #include "AddData.h"
 #include "Application.h"
-#include "DBusAdaptor.h"
+#include "DBusInteropHelper.h"
 #include "Formatter.h"
 #include "MainWindow.h"
 #include "OptionsDialog.h"
 
 namespace
 {
-  const QString DBUS_SERVICE     = QString::fromUtf8 ("com.transmissionbt.Transmission" );
-  const QString DBUS_OBJECT_PATH = QString::fromUtf8 ("/com/transmissionbt/Transmission");
-  const QString DBUS_INTERFACE   = QString::fromUtf8 ("com.transmissionbt.Transmission" );
-
   const QLatin1String MY_CONFIG_NAME ("transmission");
   const QLatin1String MY_READABLE_NAME ("transmission-qt");
 
@@ -162,41 +157,38 @@ Application::Application (int& argc, char ** argv):
 
   // try to delegate the work to an existing copy of Transmission
   // before starting ourselves...
-  QDBusConnection bus = QDBusConnection::sessionBus ();
-  if (bus.isConnected ())
-  {
-    bool delegated = false;
-    for (const QString& filename: filenames)
-      {
-        QDBusMessage request = QDBusMessage::createMethodCall (DBUS_SERVICE,
-                                                               DBUS_OBJECT_PATH,
-                                                               DBUS_INTERFACE,
-                                                               QString::fromUtf8 ("AddMetainfo"));
-        QList<QVariant> arguments;
-        AddData a (filename);
-        switch (a.type)
-          {
-            case AddData::URL:      arguments.push_back (a.url.toString ()); break;
-            case AddData::MAGNET:   arguments.push_back (a.magnet); break;
-            case AddData::FILENAME: arguments.push_back (QString::fromLatin1 (a.toBase64 ())); break;
-            case AddData::METAINFO: arguments.push_back (QString::fromLatin1 (a.toBase64 ())); break;
-            default:                break;
-          }
-        request.setArguments (arguments);
-
-        QDBusMessage response = bus.call (request);
-        //std::cerr << qPrintable (response.errorName ()) << std::endl;
-        //std::cerr << qPrintable (response.errorMessage ()) << std::endl;
-        arguments = response.arguments ();
-        delegated |= (arguments.size ()==1) && arguments[0].toBool ();
-      }
-
-    if (delegated)
-      {
-        quitLater ();
-        return;
-      }
-  }
+  DBusInteropHelper interopClient;
+  if (interopClient.isConnected ())
+    {
+      bool delegated = false;
+      for (const QString& filename: filenames)
+        {
+          QString metainfo;
+
+          AddData a (filename);
+          switch (a.type)
+            {
+              case AddData::URL:      metainfo = a.url.toString (); break;
+              case AddData::MAGNET:   metainfo = a.magnet; break;
+              case AddData::FILENAME: metainfo = QString::fromLatin1 (a.toBase64 ()); break;
+              case AddData::METAINFO: metainfo = QString::fromLatin1 (a.toBase64 ()); break;
+              default:                break;
+            }
+
+          if (metainfo.isEmpty ())
+            continue;
+
+          const QVariant result = interopClient.addMetainfo (metainfo);
+          if (result.isValid () && result.toBool ())
+            delegated = true;
+        }
+
+      if (delegated)
+        {
+          quitLater ();
+          return;
+        }
+    }
 
   // set the fallback config dir
   if (configDir.isNull ())
@@ -302,15 +294,7 @@ Application::Application (int& argc, char ** argv):
   for (const QString& filename: filenames)
     addTorrent (filename);
 
-  // register as the dbus handler for Transmission
-  if (bus.isConnected ())
-    {
-      new DBusAdaptor (this);
-      if (!bus.registerService (DBUS_SERVICE))
-        std::cerr << "couldn't register " << qPrintable (DBUS_SERVICE) << std::endl;
-      if (!bus.registerObject (DBUS_OBJECT_PATH, this))
-        std::cerr << "couldn't register " << qPrintable (DBUS_OBJECT_PATH) << std::endl;
-    }
+  DBusInteropHelper::registerObject (this);
 }
 
 void
@@ -558,32 +542,31 @@ Application::raise ()
 bool
 Application::notifyApp (const QString& title, const QString& body) const
 {
+  const QLatin1String dbusServiceName ("org.freedesktop.Notifications");
+  const QLatin1String dbusInterfaceName ("org.freedesktop.Notifications");
+  const QLatin1String dbusPath ("/org/freedesktop/Notifications");
+
   QDBusConnection bus = QDBusConnection::sessionBus ();
-  if (!bus.isConnected ())
+  if (bus.isConnected ())
     {
-      myWindow->trayIcon ().showMessage (title, body);
-      return true;
+      QDBusMessage m = QDBusMessage::createMethodCall (dbusServiceName, dbusPath, dbusInterfaceName, QLatin1String ("Notify"));
+      QVariantList args;
+      args.append (QLatin1String ("Transmission")); // app_name
+      args.append (0U);                             // replaces_id
+      args.append (QLatin1String ("transmission")); // icon
+      args.append (title);                          // summary
+      args.append (body);                           // body
+      args.append (QStringList ());                 // actions - unused for plain passive popups
+      args.append (QVariantMap ());                 // hints - unused atm
+      args.append (static_cast<int32_t> (-1));      // use the default timeout period
+      m.setArguments (args);
+      const QDBusReply<quint32> replyMsg = bus.call (m);
+      if (replyMsg.isValid () && replyMsg.value () > 0)
+        return true;
     }
 
-  const QString dbusServiceName   = QString::fromUtf8 ("org.freedesktop.Notifications");
-  const QString dbusInterfaceName = QString::fromUtf8 ("org.freedesktop.Notifications");
-  const QString dbusPath          = QString::fromUtf8 ("/org/freedesktop/Notifications");
-
-  QDBusMessage m = QDBusMessage::createMethodCall (dbusServiceName, dbusPath, dbusInterfaceName, QString::fromUtf8 ("Notify"));
-  QList<QVariant> args;
-  args.append (QString::fromUtf8 ("Transmission")); // app_name
-  args.append (0U);                                   // replaces_id
-  args.append (QString::fromUtf8 ("transmission")); // icon
-  args.append (title);                                // summary
-  args.append (body);                                 // body
-  args.append (QStringList ());                       // actions - unused for plain passive popups
-  args.append (QVariantMap ());                       // hints - unused atm
-  args.append (static_cast<int32_t> (-1));            // use the default timeout period
-  m.setArguments (args);
-  QDBusMessage replyMsg = bus.call (m);
-  //std::cerr << qPrintable (replyMsg.errorName ()) << std::endl;
-  //std::cerr << qPrintable (replyMsg.errorMessage ()) << std::endl;
-  return (replyMsg.type () == QDBusMessage::ReplyMessage) && !replyMsg.arguments ().isEmpty ();
+  myWindow->trayIcon ().showMessage (title, body);
+  return true;
 }
 
 FaviconCache& Application::faviconCache ()
index d0ed8e55330f45f7af63a096ee4b92cb0f00b313..2cde642099421c565fc3864b55167caff179c329 100644 (file)
@@ -29,7 +29,7 @@ set(${PROJECT_NAME}_SOURCES
     AddData.cc
     Application.cc
     ColumnResizer.cc
-    DBusAdaptor.cc
+    DBusInteropHelper.cc
     DetailsDialog.cc
     FaviconCache.cc
     FileTreeDelegate.cc
@@ -44,6 +44,7 @@ set(${PROJECT_NAME}_SOURCES
     Formatter.cc
     FreeSpaceLabel.cc
     IconToolButton.cc
+    InteropObject.cc
     LicenseDialog.cc
     MainWindow.cc
     MakeDialog.cc
@@ -77,7 +78,7 @@ set(${PROJECT_NAME}_HEADERS
     BaseDialog.h
     ColumnResizer.h
     CustomVariantType.h
-    DBusAdaptor.h
+    DBusInteropHelper.h
     DetailsDialog.h
     FaviconCache.h
     FileTreeDelegate.h
@@ -92,6 +93,7 @@ set(${PROJECT_NAME}_HEADERS
     Formatter.h
     FreeSpaceLabel.h
     IconToolButton.h
+    InteropObject.h
     LicenseDialog.h
     MainWindow.h
     MakeDialog.h
diff --git a/qt/DBusInteropHelper.cc b/qt/DBusInteropHelper.cc
new file mode 100644 (file)
index 0000000..94f2931
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * This file Copyright (C) 2015 Mnemosyne LLC
+ *
+ * It may be used under the GNU GPL versions 2 or 3
+ * or any future license endorsed by Mnemosyne LLC.
+ *
+ * $Id$
+ */
+
+#include <iostream>
+
+#include <QDBusConnection>
+#include <QDBusMessage>
+#include <QDBusReply>
+#include <QString>
+#include <QVariant>
+
+#include "DBusInteropHelper.h"
+#include "InteropObject.h"
+
+namespace
+{
+  const QLatin1String DBUS_SERVICE ("com.transmissionbt.Transmission");
+  const QLatin1String DBUS_OBJECT_PATH ("/com/transmissionbt/Transmission");
+  const QLatin1String DBUS_INTERFACE ("com.transmissionbt.Transmission");
+}
+
+bool
+DBusInteropHelper::isConnected () const
+{
+  return !QDBusConnection::sessionBus ().isConnected ();
+}
+
+QVariant
+DBusInteropHelper::addMetainfo (const QString& metainfo)
+{
+  QDBusMessage request = QDBusMessage::createMethodCall (DBUS_SERVICE, DBUS_OBJECT_PATH,
+                                                         DBUS_INTERFACE, QLatin1String ("AddMetainfo"));
+  request.setArguments (QVariantList () << metainfo);
+
+  const QDBusReply<bool> response = QDBusConnection::sessionBus ().call (request);
+  return response.isValid () ? QVariant (response.value ()) : QVariant ();
+}
+
+void
+DBusInteropHelper::registerObject (QObject * parent)
+{
+  QDBusConnection bus = QDBusConnection::sessionBus ();
+  if (!bus.isConnected ())
+    return;
+
+  if (!bus.registerService (DBUS_SERVICE))
+    std::cerr << "couldn't register " << qPrintable (DBUS_SERVICE) << std::endl;
+  if (!bus.registerObject (DBUS_OBJECT_PATH, new InteropObject (parent), QDBusConnection::ExportAllSlots))
+    std::cerr << "couldn't register " << qPrintable (DBUS_OBJECT_PATH) << std::endl;
+}
diff --git a/qt/DBusInteropHelper.h b/qt/DBusInteropHelper.h
new file mode 100644 (file)
index 0000000..1de98cf
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * This file Copyright (C) 2015 Mnemosyne LLC
+ *
+ * It may be used under the GNU GPL versions 2 or 3
+ * or any future license endorsed by Mnemosyne LLC.
+ *
+ * $Id$
+ */
+
+#ifndef QTR_DBUS_INTEROP_HELPER_H
+#define QTR_DBUS_INTEROP_HELPER_H
+
+class QObject;
+class QString;
+class QVariant;
+
+class DBusInteropHelper
+{
+  public:
+    bool isConnected () const;
+
+    QVariant addMetainfo (const QString& metainfo);
+
+    static void registerObject (QObject * parent);
+};
+
+#endif // QTR_DBUS_INTEROP_HELPER_H
similarity index 54%
rename from qt/DBusAdaptor.cc
rename to qt/InteropObject.cc
index 6e41cd83e4b6fe2d2c9ba4932e0ddae3ee98918f..074185e36c801d3ce161acd0aa1a28b00d73f894 100644 (file)
@@ -9,28 +9,27 @@
 
 #include "AddData.h"
 #include "Application.h"
-#include "DBusAdaptor.h"
+#include "InteropObject.h"
 
-DBusAdaptor::DBusAdaptor (Application* app):
-  QDBusAbstractAdaptor (app),
-  myApp (app)
+InteropObject::InteropObject (QObject * parent):
+  QObject (parent)
 {
 }
 
 bool
-DBusAdaptor::PresentWindow ()
+InteropObject::PresentWindow ()
 {
-  myApp->raise ();
+  qApp->raise ();
   return true;
 }
 
 bool
-DBusAdaptor::AddMetainfo (const QString& key)
+InteropObject::AddMetainfo (const QString& metainfo)
 {
-  AddData addme (key);
+  AddData addme (metainfo);
 
   if (addme.type != addme.NONE)
-    myApp->addTorrent (addme);
+    qApp->addTorrent (addme);
 
   return true;
 }
similarity index 50%
rename from qt/DBusAdaptor.h
rename to qt/InteropObject.h
index f09df97ea3eb7535672513f5c9027a455440d3ab..4ae1184811780cee004d6f72afe9306ab4f0dd1e 100644 (file)
@@ -7,28 +7,22 @@
  * $Id$
  */
 
-#ifndef QTR_DBUS_ADAPTOR_H
-#define QTR_DBUS_ADAPTOR_H
+#ifndef QTR_INTEROP_OBJECT_H
+#define QTR_INTEROP_OBJECT_H
 
-#include <QDBusAbstractAdaptor>
+#include <QObject>
 
-class Application;
-
-class DBusAdaptor: public QDBusAbstractAdaptor
+class InteropObject: public QObject
 {
     Q_OBJECT
     Q_CLASSINFO ("D-Bus Interface", "com.transmissionbt.Transmission")
 
   public:
-    DBusAdaptor (Application *);
-    virtual ~DBusAdaptor () {}
+    InteropObject (QObject * parent = nullptr);
 
   public slots:
     bool PresentWindow ();
-    bool AddMetainfo (const QString&);
-
-  private:
-    Application * myApp;
+    bool AddMetainfo (const QString& metainfo);
 };
 
-#endif // QTR_DBUS_ADAPTOR_H
+#endif // QTR_INTEROP_OBJECT_H