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
--- 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__