Bug 1360560 - Implement XRemote client by D-Bus service, r?jhorak draft
authorMartin Stransky <stransky@redhat.com>
Thu, 02 Nov 2017 16:21:28 +0100
changeset 695545 7a7a7dc045e7bc045f40f98625e459ff5e5d5d5b
parent 692089 40a14ca1cf04499f398e4cb8ba359b39eae4e216
child 695546 74f218980e48de6832a70563dcc33d85f0e33bb0
push id88463
push userstransky@redhat.com
push dateThu, 09 Nov 2017 12:17:48 +0000
reviewersjhorak
bugs1360560
milestone58.0a1
Bug 1360560 - Implement XRemote client by D-Bus service, r?jhorak MozReview-Commit-ID: JDNEC8Jar5w
widget/xremoteclient/DBusRemoteClient.cpp
widget/xremoteclient/DBusRemoteClient.h
widget/xremoteclient/moz.build
new file mode 100644
--- /dev/null
+++ b/widget/xremoteclient/DBusRemoteClient.cpp
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=8:
+ */
+/* vim:set ts=8 sw=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DBusRemoteClient.h"
+#include "RemoteUtils.h"
+#include "mozilla/Logging.h"
+#include "nsPrintfCString.h"
+
+using mozilla::LogLevel;
+static mozilla::LazyLogModule sRemoteLm("DBusRemoteClient");
+
+DBusRemoteClient::DBusRemoteClient()
+{
+  mConnection = nullptr;
+  MOZ_LOG(sRemoteLm, LogLevel::Debug, ("DBusRemoteClient::DBusRemoteClient"));
+}
+
+DBusRemoteClient::~DBusRemoteClient()
+{
+  MOZ_LOG(sRemoteLm, LogLevel::Debug, ("DBusRemoteClient::~DBusRemoteClient"));
+  Shutdown();
+}
+
+nsresult
+DBusRemoteClient::Init()
+{
+  MOZ_LOG(sRemoteLm, LogLevel::Debug, ("DBusRemoteClient::Init"));
+
+  if (mConnection)
+    return NS_OK;
+
+  mConnection = already_AddRefed<DBusConnection>(
+    dbus_bus_get(DBUS_BUS_SESSION, nullptr));
+  if (!mConnection)
+    return NS_ERROR_FAILURE;
+
+  dbus_connection_set_exit_on_disconnect(mConnection, false);
+
+  return NS_OK;
+}
+
+void
+DBusRemoteClient::Shutdown (void)
+{
+  MOZ_LOG(sRemoteLm, LogLevel::Debug, ("DBusRemoteClient::Shutdown"));
+  // This connection is owned by libdbus and we don't need to close it
+  mConnection = nullptr;
+}
+
+nsresult
+DBusRemoteClient::SendCommandLine (const char *aProgram, const char *aUsername,
+                                const char *aProfile,
+                                int32_t argc, char **argv,
+                                const char* aDesktopStartupID,
+                                char **aResponse, bool *aWindowFound)
+{
+  MOZ_LOG(sRemoteLm, LogLevel::Debug, ("DBusRemoteClient::SendCommandLine"));
+
+  int commandLineLength;
+  char *commandLine = ConstructCommandLine(argc, argv, aDesktopStartupID,
+                                           &commandLineLength);
+  if (!commandLine)
+    return NS_ERROR_FAILURE;
+
+  nsresult rv = DoSendDBusCommandLine(aProgram, aProfile,
+                                      commandLine, commandLineLength);
+  free(commandLine);
+  *aWindowFound = NS_SUCCEEDED(rv);
+
+  MOZ_LOG(sRemoteLm, LogLevel::Debug, ("DoSendDBusCommandLine returning 0x%" PRIx32 "\n",
+                                       static_cast<uint32_t>(rv)));
+  return rv;
+}
+
+nsresult
+DBusRemoteClient::DoSendDBusCommandLine(const char *aProgram, const char *aProfile,
+                                        const char* aBuffer, int aLength)
+{
+  NS_ASSERTION(aProfile && aProfile[0] != '\0', "Missing user profile!");
+
+  nsAutoCString destinationName;
+  destinationName = nsPrintfCString("org.mozilla.%s.%s", aProgram, aProfile);
+
+  nsAutoCString objectName;
+  objectName = nsPrintfCString("/org/mozilla/%s/Remote", aProgram);
+
+  nsAutoCString remoteInterfaceName;
+  remoteInterfaceName = nsPrintfCString("org.mozilla.%s", aProgram);
+
+  RefPtr<DBusMessage> msg = already_AddRefed<DBusMessage>(
+      dbus_message_new_method_call(destinationName.get(),
+                                   objectName.get(), // object to call on
+                                   remoteInterfaceName.get(), // interface to call on
+                                   "OpenURL")); // method name
+  if (!msg) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // append arguments
+  if (!dbus_message_append_args(msg, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+                                &aBuffer, aLength, DBUS_TYPE_INVALID)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // send message and get a handle for a reply
+  DBusError err;
+  dbus_error_init(&err);
+  RefPtr<DBusMessage> reply = already_AddRefed<DBusMessage>(
+      dbus_connection_send_with_reply_and_block(mConnection, msg, -1, &err));
+
+  if (dbus_error_is_set(&err)) {
+      dbus_error_free(&err);
+      return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
new file mode 100644
--- /dev/null
+++ b/widget/xremoteclient/DBusRemoteClient.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ #ifndef DBusRemoteClient_h__
+ #define DBusRemoteClient_h__
+
+#include "nsRemoteClient.h"
+#include "mozilla/StaticPtr.h"
+#include "mozilla/DBusHelpers.h"
+
+class DBusRemoteClient : public nsRemoteClient
+{
+public:
+  DBusRemoteClient();
+  ~DBusRemoteClient();
+
+  virtual nsresult Init();
+  virtual nsresult SendCommandLine(const char *aProgram, const char *aUsername,
+                                   const char *aProfile,
+                                   int32_t argc, char **argv,
+                                   const char* aDesktopStartupID,
+                                   char **aResponse, bool *aSucceeded);
+  void Shutdown();
+
+private:
+  nsresult         DoSendDBusCommandLine(const char *aProgram, const char *aProfile,
+                                         const char* aBuffer, int aLength);
+  RefPtr<DBusConnection> mConnection;
+};
+
+#endif // DBusRemoteClient_h__
--- a/widget/xremoteclient/moz.build
+++ b/widget/xremoteclient/moz.build
@@ -8,8 +8,15 @@ with Files("**"):
     BUG_COMPONENT = ("Core", "Widget")
 
 FINAL_LIBRARY = 'xul'
 
 SOURCES += [
     'RemoteUtils.cpp',
     'XRemoteClient.cpp',
 ]
+
+if CONFIG['MOZ_ENABLE_DBUS'] and CONFIG['MOZ_WAYLAND']:
+    SOURCES += [
+        'DBusRemoteClient.cpp',
+    ]
+    CXXFLAGS += CONFIG['TK_CFLAGS']
+    CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']