Bug 1434544 - When launching remote instance without profile name search for already running firefox instances, r?jhorak draft
authorMartin Stransky <stransky@redhat.com>
Fri, 02 Feb 2018 13:54:31 +0100
changeset 754414 ce03999766d0424ee721cedb1d1d36aac5a49a53
parent 754399 38b3c1d03a594664c6b32c35533734283c258f43
child 754416 9a9b8f776e39f31eb4e8446a25f14b2f3f8e0bb5
push id98846
push userstransky@redhat.com
push dateTue, 13 Feb 2018 12:42:38 +0000
reviewersjhorak
bugs1434544
milestone60.0a1
Bug 1434544 - When launching remote instance without profile name search for already running firefox instances, r?jhorak We don't have profile name available when running with default profile. With this patch Firefox looks for existing DBus interfaces and tries to pick one instead of creating a new instance. MozReview-Commit-ID: 223rRcEvTWv
widget/xremoteclient/DBusRemoteClient.cpp
widget/xremoteclient/DBusRemoteClient.h
--- a/widget/xremoteclient/DBusRemoteClient.cpp
+++ b/widget/xremoteclient/DBusRemoteClient.cpp
@@ -73,33 +73,82 @@ DBusRemoteClient::SendCommandLine (const
   free(commandLine);
   *aWindowFound = NS_SUCCEEDED(rv);
 
   MOZ_LOG(sRemoteLm, LogLevel::Debug, ("DoSendDBusCommandLine returning 0x%" PRIx32 "\n",
                                        static_cast<uint32_t>(rv)));
   return rv;
 }
 
+bool
+DBusRemoteClient::GetRemoteDestinationName(const char *aProgram,
+                                           const char *aProfile,
+                                           nsCString &aDestinationName)
+{
+  if(!aProfile || aProfile[0] == '\0') {
+    // We don't have a profile name - search for active mozilla instances.
+    RefPtr<DBusMessage> msg = already_AddRefed<DBusMessage>(
+        dbus_message_new_method_call("org.freedesktop.DBus",
+                                     "/org/freedesktop/DBus",
+                                     "org.freedesktop.DBus",
+                                     "ListNames"));
+    if (!msg) {
+      return false;
+    }
+
+    // send message and get a handle for a reply
+    RefPtr<DBusMessage> reply = already_AddRefed<DBusMessage>(
+        dbus_connection_send_with_reply_and_block(mConnection, msg, -1, nullptr));
+    if (!reply) {
+      return false;
+    }
+
+    char **interfaces;
+    dbus_int32_t interfaceNums;
+    if (!dbus_message_get_args(reply, nullptr, DBUS_TYPE_ARRAY,
+                               DBUS_TYPE_STRING, &interfaces, &interfaceNums,
+                               DBUS_TYPE_INVALID)) {
+      return false;
+    }
+
+    nsAutoCString destinationTemplate;
+    destinationTemplate = nsPrintfCString("org.mozilla.%s", aProgram);
+
+    aDestinationName.SetLength(0);
+    for (int i = 0; i < interfaceNums; i++) {
+      if (strstr(interfaces[i], destinationTemplate.get())) {
+        aDestinationName = interfaces[i];
+        break;
+      }
+    }
+    dbus_free_string_array(interfaces);
+
+    return (!aDestinationName.IsEmpty());
+  } else {
+    // We have a profile name - just create the destination.
+    // D-Bus names can contain only [a-z][A-Z][0-9]_
+    // characters so adjust the profile string properly.
+    nsAutoCString profileName;
+    nsresult rv = mozilla::Base64Encode(nsAutoCString(aProfile), profileName);
+    NS_ENSURE_SUCCESS(rv, false);
+    profileName.ReplaceChar("+/=", '_');
+
+    aDestinationName = nsPrintfCString("org.mozilla.%s.%s", aProgram,
+                                                            profileName.get());
+    return true;
+  }
+}
+
 nsresult
 DBusRemoteClient::DoSendDBusCommandLine(const char *aProgram, const char *aProfile,
                                         const char* aBuffer, int aLength)
 {
-  if(!aProfile || aProfile[0] == '\0') {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  // D-Bus names can contain only [a-z][A-Z][0-9]_
-  // characters so adjust the profile string properly.
-  nsAutoCString profileName;
-  nsresult rv = mozilla::Base64Encode(nsAutoCString(aProfile), profileName);
-  NS_ENSURE_SUCCESS(rv, rv);
-  profileName.ReplaceChar("+/=", '_');
-
   nsAutoCString destinationName;
-  destinationName = nsPrintfCString("org.mozilla.%s.%s", aProgram, profileName.get());
+  if (!GetRemoteDestinationName(aProgram, aProfile, destinationName))
+    return NS_ERROR_FAILURE;
 
   nsAutoCString pathName;
   pathName = nsPrintfCString("/org/mozilla/%s/Remote", aProgram);
 
   nsAutoCString remoteInterfaceName;
   remoteInterfaceName = nsPrintfCString("org.mozilla.%s", aProgram);
 
   RefPtr<DBusMessage> msg = already_AddRefed<DBusMessage>(
--- a/widget/xremoteclient/DBusRemoteClient.h
+++ b/widget/xremoteclient/DBusRemoteClient.h
@@ -4,30 +4,35 @@
  * 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"
+#include "nsString.h"
 
 class DBusRemoteClient : public nsRemoteClient
 {
 public:
   DBusRemoteClient();
   ~DBusRemoteClient();
 
   virtual nsresult Init() override;
   virtual nsresult SendCommandLine(const char *aProgram, const char *aUsername,
                                    const char *aProfile,
                                    int32_t argc, char **argv,
                                    const char* aDesktopStartupID,
                                    char **aResponse, bool *aSucceeded) override;
   void Shutdown();
 
 private:
-  nsresult         DoSendDBusCommandLine(const char *aProgram, const char *aProfile,
+  bool             GetRemoteDestinationName(const char *aProgram,
+                                            const char *aProfile,
+                                            nsCString &aDestinationName);
+  nsresult         DoSendDBusCommandLine(const char *aProgram,
+                                         const char *aProfile,
                                          const char* aBuffer, int aLength);
   RefPtr<DBusConnection> mConnection;
 };
 
 #endif // DBusRemoteClient_h__