From 5e41c25e131c7e8495d89cb218d5ef16cbffa358 Mon Sep 17 00:00:00 2001 From: Dave Townsend Date: Wed, 27 Feb 2019 15:45:51 -0800 Subject: [PATCH] Bug 1518639: Break out the remote server pieces from nsRemoteService and deCOMtaminate. r=jimm This code is only ever used from c++ so does not need to be an XPCOM component. Broken out a single nsRemoteService that is responsible for choosing the server implementation to use. Differential Revision: https://phabricator.services.mozilla.com/D19067 --HG-- rename : toolkit/components/remote/nsDBusRemoteService.cpp => toolkit/components/remote/nsDBusRemoteServer.cpp rename : toolkit/components/remote/nsDBusRemoteService.h => toolkit/components/remote/nsDBusRemoteServer.h rename : toolkit/components/remote/nsGTKRemoteService.cpp => toolkit/components/remote/nsGTKRemoteServer.cpp rename : toolkit/components/remote/nsGTKRemoteService.h => toolkit/components/remote/nsGTKRemoteServer.h rename : toolkit/components/remote/nsXRemoteService.cpp => toolkit/components/remote/nsXRemoteServer.cpp rename : toolkit/components/remote/nsXRemoteService.h => toolkit/components/remote/nsXRemoteServer.h extra : rebase_source : 631ee45923c64acde92e23c155cbbbbc7a1d9c4d --- toolkit/components/remote/components.conf | 14 -- toolkit/components/remote/moz.build | 22 +-- ...moteService.cpp => nsDBusRemoteServer.cpp} | 31 ++-- ...usRemoteService.h => nsDBusRemoteServer.h} | 23 ++- ...emoteService.cpp => nsGTKRemoteServer.cpp} | 39 ++-- ...GTKRemoteService.h => nsGTKRemoteServer.h} | 23 ++- .../components/remote/nsIRemoteService.idl | 38 ---- toolkit/components/remote/nsRemoteServer.h | 21 +++ toolkit/components/remote/nsRemoteService.cpp | 173 +++--------------- toolkit/components/remote/nsRemoteService.h | 18 +- .../components/remote/nsUnixRemoteServer.cpp | 111 +++++++++++ .../components/remote/nsUnixRemoteServer.h | 28 +++ ...XRemoteService.cpp => nsXRemoteServer.cpp} | 33 ++-- .../{nsXRemoteService.h => nsXRemoteServer.h} | 26 +-- toolkit/xre/moz.build | 4 + toolkit/xre/nsAppRunner.cpp | 12 +- uriloader/exthandler/DBusHelpers.h | 1 + 17 files changed, 295 insertions(+), 322 deletions(-) delete mode 100644 toolkit/components/remote/components.conf rename toolkit/components/remote/{nsDBusRemoteService.cpp => nsDBusRemoteServer.cpp} (89%) rename toolkit/components/remote/{nsDBusRemoteService.h => nsDBusRemoteServer.h} (61%) rename toolkit/components/remote/{nsGTKRemoteService.cpp => nsGTKRemoteServer.cpp} (59%) rename toolkit/components/remote/{nsGTKRemoteService.h => nsGTKRemoteServer.h} (55%) delete mode 100644 toolkit/components/remote/nsIRemoteService.idl create mode 100644 toolkit/components/remote/nsRemoteServer.h create mode 100644 toolkit/components/remote/nsUnixRemoteServer.cpp create mode 100644 toolkit/components/remote/nsUnixRemoteServer.h rename toolkit/components/remote/{nsXRemoteService.cpp => nsXRemoteServer.cpp} (85%) rename toolkit/components/remote/{nsXRemoteService.h => nsXRemoteServer.h} (61%) diff --git a/toolkit/components/remote/components.conf b/toolkit/components/remote/components.conf deleted file mode 100644 index df6bc46ea0bf..000000000000 --- a/toolkit/components/remote/components.conf +++ /dev/null @@ -1,14 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -Classes = [ - { - 'cid': '{c0773e90-5799-4eff-ad03-3ebcd85624ac}', - 'contract_ids': ['@mozilla.org/toolkit/remote-service;1'], - 'type': 'nsRemoteService', - 'headers': ['/toolkit/components/remote/nsRemoteService.h'], - }, -] diff --git a/toolkit/components/remote/moz.build b/toolkit/components/remote/moz.build index 3c3cd773ecf0..2adad3fc6932 100644 --- a/toolkit/components/remote/moz.build +++ b/toolkit/components/remote/moz.build @@ -7,31 +7,21 @@ with Files('**'): BUG_COMPONENT = ('Toolkit', 'Startup and Profile System') -XPIDL_SOURCES += [ - 'nsIRemoteService.idl', -] - -XPIDL_MODULE = 'toolkitremote' - SOURCES += [ - 'nsXRemoteService.cpp', + 'nsRemoteService.cpp', ] if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: SOURCES += [ - 'nsGTKRemoteService.cpp', - 'nsRemoteService.cpp', + 'nsGTKRemoteServer.cpp', + 'nsUnixRemoteServer.cpp', + 'nsXRemoteServer.cpp', ] if CONFIG['MOZ_ENABLE_DBUS']: SOURCES += [ - 'nsDBusRemoteService.cpp', + 'nsDBusRemoteServer.cpp', ] CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] - - XPCOM_MANIFESTS += [ - 'components.conf', - ] + CXXFLAGS += CONFIG['TK_CFLAGS'] FINAL_LIBRARY = 'xul' - -CXXFLAGS += CONFIG['TK_CFLAGS'] diff --git a/toolkit/components/remote/nsDBusRemoteService.cpp b/toolkit/components/remote/nsDBusRemoteServer.cpp similarity index 89% rename from toolkit/components/remote/nsDBusRemoteService.cpp rename to toolkit/components/remote/nsDBusRemoteServer.cpp index f761b5c9cc42..7f42a08029e3 100644 --- a/toolkit/components/remote/nsDBusRemoteService.cpp +++ b/toolkit/components/remote/nsDBusRemoteServer.cpp @@ -5,8 +5,7 @@ * 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 "nsDBusRemoteService.h" -#include "nsRemoteService.h" +#include "nsDBusRemoteServer.h" #include "nsIBaseWindow.h" #include "nsIDocShell.h" @@ -28,8 +27,6 @@ #include -NS_IMPL_ISUPPORTS(nsDBusRemoteService, nsIRemoteService) - const char *introspect_template = "\n" "\n"; -DBusHandlerResult nsDBusRemoteService::Introspect(DBusMessage *msg) { +DBusHandlerResult nsDBusRemoteServer::Introspect(DBusMessage *msg) { DBusMessage *reply; reply = dbus_message_new_method_return(msg); @@ -66,7 +63,7 @@ DBusHandlerResult nsDBusRemoteService::Introspect(DBusMessage *msg) { return DBUS_HANDLER_RESULT_HANDLED; } -DBusHandlerResult nsDBusRemoteService::OpenURL(DBusMessage *msg) { +DBusHandlerResult nsDBusRemoteServer::OpenURL(DBusMessage *msg) { DBusMessage *reply = nullptr; const char *commandLine; int length; @@ -82,7 +79,7 @@ DBusHandlerResult nsDBusRemoteService::OpenURL(DBusMessage *msg) { if (timestamp == GDK_CURRENT_TIME) { timestamp = guint32(g_get_monotonic_time() / 1000); } - nsRemoteService::HandleCommandLine(commandLine, timestamp); + HandleCommandLine(commandLine, timestamp); reply = dbus_message_new_method_return(msg); } @@ -92,7 +89,7 @@ DBusHandlerResult nsDBusRemoteService::OpenURL(DBusMessage *msg) { return DBUS_HANDLER_RESULT_HANDLED; } -DBusHandlerResult nsDBusRemoteService::HandleDBusMessage( +DBusHandlerResult nsDBusRemoteServer::HandleDBusMessage( DBusConnection *aConnection, DBusMessage *msg) { NS_ASSERTION(mConnection == aConnection, "Wrong D-Bus connection."); @@ -115,19 +112,19 @@ DBusHandlerResult nsDBusRemoteService::HandleDBusMessage( return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -void nsDBusRemoteService::UnregisterDBusInterface(DBusConnection *aConnection) { +void nsDBusRemoteServer::UnregisterDBusInterface(DBusConnection *aConnection) { NS_ASSERTION(mConnection == aConnection, "Wrong D-Bus connection."); // Not implemented } static DBusHandlerResult message_handler(DBusConnection *conn, DBusMessage *msg, void *user_data) { - auto interface = static_cast(user_data); + auto interface = static_cast(user_data); return interface->HandleDBusMessage(conn, msg); } static void unregister(DBusConnection *conn, void *user_data) { - auto interface = static_cast(user_data); + auto interface = static_cast(user_data); interface->UnregisterDBusInterface(conn); } @@ -136,8 +133,8 @@ static DBusObjectPathVTable remoteHandlersTable = { .message_function = message_handler, }; -NS_IMETHODIMP -nsDBusRemoteService::Startup(const char *aAppName, const char *aProfileName) { +nsresult nsDBusRemoteServer::Startup(const char *aAppName, + const char *aProfileName) { if (mConnection && dbus_connection_get_is_connected(mConnection)) { // We're already connected so we don't need to reconnect return NS_ERROR_ALREADY_INITIALIZED; @@ -210,11 +207,13 @@ nsDBusRemoteService::Startup(const char *aAppName, const char *aProfileName) { return NS_OK; } -NS_IMETHODIMP -nsDBusRemoteService::Shutdown() { +void nsDBusRemoteServer::Shutdown() { + if (!mConnection) { + return; + } + dbus_connection_unregister_object_path(mConnection, mPathName.get()); // dbus_connection_unref() will be called by RefPtr here. mConnection = nullptr; - return NS_OK; } diff --git a/toolkit/components/remote/nsDBusRemoteService.h b/toolkit/components/remote/nsDBusRemoteServer.h similarity index 61% rename from toolkit/components/remote/nsDBusRemoteService.h rename to toolkit/components/remote/nsDBusRemoteServer.h index f099bf040c4c..3bb2ec6fdc12 100644 --- a/toolkit/components/remote/nsDBusRemoteService.h +++ b/toolkit/components/remote/nsDBusRemoteServer.h @@ -5,28 +5,27 @@ * 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 __nsDBusRemoteService_h__ -#define __nsDBusRemoteService_h__ +#ifndef __nsDBusRemoteServer_h__ +#define __nsDBusRemoteServer_h__ -#include "nsIRemoteService.h" +#include "nsRemoteServer.h" +#include "nsUnixRemoteServer.h" #include "mozilla/DBusHelpers.h" -#include "nsString.h" -class nsDBusRemoteService final : public nsIRemoteService { +class nsDBusRemoteServer final : public nsRemoteServer, + public nsUnixRemoteServer { public: - // We will be a static singleton, so don't use the ordinary methods. - NS_DECL_ISUPPORTS - NS_DECL_NSIREMOTESERVICE + nsDBusRemoteServer() : mConnection(nullptr), mAppName(nullptr) {} + ~nsDBusRemoteServer() override { Shutdown(); } - nsDBusRemoteService() : mConnection(nullptr), mAppName(nullptr) {} + nsresult Startup(const char *aAppName, const char *aProfileName) override; + void Shutdown() override; DBusHandlerResult HandleDBusMessage(DBusConnection *aConnection, DBusMessage *msg); void UnregisterDBusInterface(DBusConnection *aConnection); private: - ~nsDBusRemoteService() {} - DBusHandlerResult OpenURL(DBusMessage *msg); DBusHandlerResult Introspect(DBusMessage *msg); @@ -36,4 +35,4 @@ class nsDBusRemoteService final : public nsIRemoteService { nsCString mPathName; }; -#endif // __nsDBusRemoteService_h__ +#endif // __nsDBusRemoteServer_h__ diff --git a/toolkit/components/remote/nsGTKRemoteService.cpp b/toolkit/components/remote/nsGTKRemoteServer.cpp similarity index 59% rename from toolkit/components/remote/nsGTKRemoteService.cpp rename to toolkit/components/remote/nsGTKRemoteServer.cpp index 51e20ce27b1e..402a1dc7ffe6 100644 --- a/toolkit/components/remote/nsGTKRemoteService.cpp +++ b/toolkit/components/remote/nsGTKRemoteServer.cpp @@ -5,7 +5,7 @@ * 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 "nsGTKRemoteService.h" +#include "nsGTKRemoteServer.h" #include #include @@ -23,13 +23,13 @@ #include "nsGTKToolkit.h" -NS_IMPL_ISUPPORTS(nsGTKRemoteService, nsIRemoteService) - -NS_IMETHODIMP -nsGTKRemoteService::Startup(const char* aAppName, const char* aProfileName) { +nsresult nsGTKRemoteServer::Startup(const char* aAppName, + const char* aProfileName) { NS_ASSERTION(aAppName, "Don't pass a null appname!"); - if (mServerWindow) return NS_ERROR_ALREADY_INITIALIZED; + if (mServerWindow) { + return NS_ERROR_ALREADY_INITIALIZED; + } XRemoteBaseStartup(aAppName, aProfileName); @@ -40,36 +40,35 @@ nsGTKRemoteService::Startup(const char* aAppName, const char* aProfileName) { return NS_OK; } -NS_IMETHODIMP -nsGTKRemoteService::Shutdown() { - if (!mServerWindow) return NS_ERROR_NOT_INITIALIZED; +void nsGTKRemoteServer::Shutdown() { + if (!mServerWindow) { + return; + } gtk_widget_destroy(mServerWindow); mServerWindow = nullptr; - - return NS_OK; } -void nsGTKRemoteService::HandleCommandsFor(GtkWidget* widget) { +void nsGTKRemoteServer::HandleCommandsFor(GtkWidget* widget) { g_signal_connect(G_OBJECT(widget), "property_notify_event", - G_CALLBACK(HandlePropertyChange), nullptr); + G_CALLBACK(HandlePropertyChange), this); gtk_widget_add_events(widget, GDK_PROPERTY_CHANGE_MASK); Window window = gdk_x11_window_get_xid(gtk_widget_get_window(widget)); - nsXRemoteService::HandleCommandsFor(window); + nsXRemoteServer::HandleCommandsFor(window); } -gboolean nsGTKRemoteService::HandlePropertyChange(GtkWidget* aWidget, - GdkEventProperty* pevent, - void* aData) { +gboolean nsGTKRemoteServer::HandlePropertyChange(GtkWidget* aWidget, + GdkEventProperty* pevent, + nsGTKRemoteServer* aThis) { if (pevent->state == GDK_PROPERTY_NEW_VALUE) { Atom changedAtom = gdk_x11_atom_to_xatom(pevent->atom); XID window = gdk_x11_window_get_xid(gtk_widget_get_window(aWidget)); - return HandleNewProperty(window, - GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), - pevent->time, changedAtom); + return aThis->HandleNewProperty( + window, GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), pevent->time, + changedAtom); } return FALSE; } diff --git a/toolkit/components/remote/nsGTKRemoteService.h b/toolkit/components/remote/nsGTKRemoteServer.h similarity index 55% rename from toolkit/components/remote/nsGTKRemoteService.h rename to toolkit/components/remote/nsGTKRemoteServer.h index 352d86c5da0a..767f2f54adb1 100644 --- a/toolkit/components/remote/nsGTKRemoteService.h +++ b/toolkit/components/remote/nsGTKRemoteServer.h @@ -5,31 +5,30 @@ * 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 __nsGTKRemoteService_h__ -#define __nsGTKRemoteService_h__ +#ifndef __nsGTKRemoteServer_h__ +#define __nsGTKRemoteServer_h__ #include #include #include -#include "nsIRemoteService.h" -#include "nsXRemoteService.h" +#include "nsRemoteServer.h" +#include "nsXRemoteServer.h" #include "mozilla/Attributes.h" -class nsGTKRemoteService final : public nsIRemoteService, - public nsXRemoteService { +class nsGTKRemoteServer final : public nsXRemoteServer { public: - NS_DECL_ISUPPORTS - NS_DECL_NSIREMOTESERVICE + nsGTKRemoteServer() : mServerWindow(nullptr) {} + ~nsGTKRemoteServer() override { Shutdown(); } - nsGTKRemoteService() : mServerWindow(nullptr) {} + nsresult Startup(const char* aAppName, const char* aProfileName) override; + void Shutdown() override; static gboolean HandlePropertyChange(GtkWidget* widget, - GdkEventProperty* event, void* aData); + GdkEventProperty* event, + nsGTKRemoteServer* aData); private: - ~nsGTKRemoteService() {} - void HandleCommandsFor(GtkWidget* aWidget); GtkWidget* mServerWindow; diff --git a/toolkit/components/remote/nsIRemoteService.idl b/toolkit/components/remote/nsIRemoteService.idl deleted file mode 100644 index f5c8462c6aa1..000000000000 --- a/toolkit/components/remote/nsIRemoteService.idl +++ /dev/null @@ -1,38 +0,0 @@ -/* 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 "nsISupports.idl" - -interface mozIDOMWindow; - -/** - * Start and stop the remote service (xremote/phremote), and register - * windows with the service for backwards compatibility with old xremote - * clients. - * - * @status FLUID This interface is not frozen and is not intended for embedders - * who want a frozen API. If you are an embedder and need this - * functionality, contact Benjamin Smedberg about the possibility - * of freezing the functionality you need. - */ - -[scriptable, uuid(bf23f1c3-7012-42dd-b0bb-a84060ccc52e)] -interface nsIRemoteService : nsISupports -{ - /** - * Start the remote service. This should not be done until app startup - * appears to have been successful. - * - * @param appName (Required) Sets a window property identifying the - * application. - * @param profileName (May be null) Sets a window property identifying the - * profile name. - */ - void startup(in string appName, in string profileName); - - /** - * Stop the remote service from accepting additional requests. - */ - void shutdown(); -}; diff --git a/toolkit/components/remote/nsRemoteServer.h b/toolkit/components/remote/nsRemoteServer.h new file mode 100644 index 000000000000..7c24bdce7111 --- /dev/null +++ b/toolkit/components/remote/nsRemoteServer.h @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=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 __nsRemoteServer_h__ +#define __nsRemoteServer_h__ + +#include "nsString.h" + +class nsRemoteServer { + public: + virtual ~nsRemoteServer() = default; + + virtual nsresult Startup(const char* aAppName, const char* aProfileName) = 0; + virtual void Shutdown() = 0; +}; + +#endif // __nsRemoteServer_h__ diff --git a/toolkit/components/remote/nsRemoteService.cpp b/toolkit/components/remote/nsRemoteService.cpp index 3f3169e3fa51..53c7a414a2ed 100644 --- a/toolkit/components/remote/nsRemoteService.cpp +++ b/toolkit/components/remote/nsRemoteService.cpp @@ -5,48 +5,46 @@ * 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 "nsGTKRemoteService.h" -#ifdef MOZ_ENABLE_DBUS -# include "nsDBusRemoteService.h" +#ifdef MOZ_WIDGET_GTK +# include "nsGTKRemoteServer.h" +# ifdef MOZ_ENABLE_DBUS +# include "nsDBusRemoteServer.h" +# endif #endif #include "nsRemoteService.h" -#include -#include -#include - -#include "nsIServiceManager.h" -#include "nsIAppShellService.h" -#include "nsAppShellCID.h" -#include "nsInterfaceHashtable.h" -#include "nsGTKToolkit.h" -#include "nsICommandLineRunner.h" -#include "nsCommandLine.h" #include "nsString.h" -#include "nsIFile.h" +#include "nsServiceManagerUtils.h" +#include "mozilla/ModuleUtils.h" -NS_IMPL_ISUPPORTS(nsRemoteService, nsIRemoteService, nsIObserver) +using namespace mozilla; -NS_IMETHODIMP -nsRemoteService::Startup(const char* aAppName, const char* aProfileName) { +NS_IMPL_ISUPPORTS(nsRemoteService, nsIObserver) + +void nsRemoteService::Startup(const char* aAppName, const char* aProfileName) { + if (mRemoteServer) { + return; + } + +#ifdef MOZ_WIDGET_GTK bool useX11Remote = GDK_IS_X11_DISPLAY(gdk_display_get_default()); -#if defined(MOZ_ENABLE_DBUS) +# if defined(MOZ_ENABLE_DBUS) if (!useX11Remote) { - nsresult rv; - mDBusRemoteService = new nsDBusRemoteService(); - rv = mDBusRemoteService->Startup(aAppName, aProfileName); - if (NS_FAILED(rv)) { - mDBusRemoteService = nullptr; - } + mRemoteServer = MakeUnique(); + } +# endif + if (useX11Remote) { + mRemoteServer = MakeUnique(); } #endif - if (useX11Remote) { - mGtkRemoteService = new nsGTKRemoteService(); - mGtkRemoteService->Startup(aAppName, aProfileName); - } - if (!mDBusRemoteService && !mGtkRemoteService) return NS_ERROR_FAILURE; + nsresult rv = mRemoteServer->Startup(aAppName, aProfileName); + + if (NS_FAILED(rv)) { + mRemoteServer = nullptr; + return; + } nsCOMPtr obs( do_GetService("@mozilla.org/observer-service;1")); @@ -54,24 +52,9 @@ nsRemoteService::Startup(const char* aAppName, const char* aProfileName) { obs->AddObserver(this, "xpcom-shutdown", false); obs->AddObserver(this, "quit-application", false); } - - return NS_OK; } -NS_IMETHODIMP -nsRemoteService::Shutdown() { -#if defined(MOZ_ENABLE_DBUS) - if (mDBusRemoteService) { - mDBusRemoteService->Shutdown(); - mDBusRemoteService = nullptr; - } -#endif - if (mGtkRemoteService) { - mGtkRemoteService->Shutdown(); - mGtkRemoteService = nullptr; - } - return NS_OK; -} +void nsRemoteService::Shutdown() { mRemoteServer = nullptr; } nsRemoteService::~nsRemoteService() { Shutdown(); } @@ -83,101 +66,3 @@ nsRemoteService::Observe(nsISupports* aSubject, const char* aTopic, Shutdown(); return NS_OK; } - -// Set desktop startup ID to the passed ID, if there is one, so that any created -// windows get created with the right window manager metadata, and any windows -// that get new tabs and are activated also get the right WM metadata. -// The timestamp will be used if there is no desktop startup ID, or if we're -// raising an existing window rather than showing a new window for the first -// time. -void nsRemoteService::SetDesktopStartupIDOrTimestamp( - const nsACString& aDesktopStartupID, uint32_t aTimestamp) { - nsGTKToolkit* toolkit = nsGTKToolkit::GetToolkit(); - if (!toolkit) return; - - if (!aDesktopStartupID.IsEmpty()) { - toolkit->SetDesktopStartupID(aDesktopStartupID); - } - - toolkit->SetFocusTimestamp(aTimestamp); -} - -static bool FindExtensionParameterInCommand(const char* aParameterName, - const nsACString& aCommand, - char aSeparator, - nsACString* aValue) { - nsAutoCString searchFor; - searchFor.Append(aSeparator); - searchFor.Append(aParameterName); - searchFor.Append('='); - - nsACString::const_iterator start, end; - aCommand.BeginReading(start); - aCommand.EndReading(end); - if (!FindInReadable(searchFor, start, end)) return false; - - nsACString::const_iterator charStart, charEnd; - charStart = end; - aCommand.EndReading(charEnd); - nsACString::const_iterator idStart = charStart, idEnd; - if (FindCharInReadable(aSeparator, charStart, charEnd)) { - idEnd = charStart; - } else { - idEnd = charEnd; - } - *aValue = nsDependentCSubstring(idStart, idEnd); - return true; -} - -const char* nsRemoteService::HandleCommandLine(const char* aBuffer, - uint32_t aTimestamp) { - nsCOMPtr cmdline(new nsCommandLine()); - - // the commandline property is constructed as an array of int32_t - // followed by a series of null-terminated strings: - // - // [argc][offsetargv0][offsetargv1...]\0\0argv[1]...\0 - // (offset is from the beginning of the buffer) - - int32_t argc = TO_LITTLE_ENDIAN32(*reinterpret_cast(aBuffer)); - const char* wd = aBuffer + ((argc + 1) * sizeof(int32_t)); - - nsCOMPtr lf; - nsresult rv = - NS_NewNativeLocalFile(nsDependentCString(wd), true, getter_AddRefs(lf)); - if (NS_FAILED(rv)) return "509 internal error"; - - nsAutoCString desktopStartupID; - - const char** argv = (const char**)malloc(sizeof(char*) * argc); - if (!argv) return "509 internal error"; - - const int32_t* offset = reinterpret_cast(aBuffer) + 1; - - for (int i = 0; i < argc; ++i) { - argv[i] = aBuffer + TO_LITTLE_ENDIAN32(offset[i]); - - if (i == 0) { - nsDependentCString cmd(argv[0]); - FindExtensionParameterInCommand("DESKTOP_STARTUP_ID", cmd, ' ', - &desktopStartupID); - } - } - - rv = cmdline->Init(argc, argv, lf, nsICommandLine::STATE_REMOTE_AUTO); - - free(argv); - if (NS_FAILED(rv)) { - return "509 internal error"; - } - - SetDesktopStartupIDOrTimestamp(desktopStartupID, aTimestamp); - - rv = cmdline->Run(); - - if (NS_ERROR_ABORT == rv) return "500 command not parseable"; - - if (NS_FAILED(rv)) return "509 internal error"; - - return "200 executed command"; -} diff --git a/toolkit/components/remote/nsRemoteService.h b/toolkit/components/remote/nsRemoteService.h index ad45b0aad8f0..74095a8e2b1a 100644 --- a/toolkit/components/remote/nsRemoteService.h +++ b/toolkit/components/remote/nsRemoteService.h @@ -8,31 +8,27 @@ #ifndef __nsRemoteService_h__ #define __nsRemoteService_h__ -#include "nsIRemoteService.h" +#include "nsRemoteServer.h" #include "nsIObserverService.h" #include "nsIObserver.h" #include "nsPIDOMWindow.h" +#include "mozilla/UniquePtr.h" -class nsRemoteService final : public nsIRemoteService, public nsIObserver { +class nsRemoteService final : public nsIObserver { public: // We will be a static singleton, so don't use the ordinary methods. NS_DECL_ISUPPORTS - NS_DECL_NSIREMOTESERVICE NS_DECL_NSIOBSERVER - static const char* HandleCommandLine(const char* aBuffer, - uint32_t aTimestamp); + nsRemoteService() = default; - nsCOMPtr mDBusRemoteService; - nsCOMPtr mGtkRemoteService; - - nsRemoteService() {} + void Startup(const char* aAppName, const char* aProfileName); + void Shutdown(); private: ~nsRemoteService(); - static void SetDesktopStartupIDOrTimestamp( - const nsACString& aDesktopStartupID, uint32_t aTimestamp); + mozilla::UniquePtr mRemoteServer; }; #endif // __nsRemoteService_h__ diff --git a/toolkit/components/remote/nsUnixRemoteServer.cpp b/toolkit/components/remote/nsUnixRemoteServer.cpp new file mode 100644 index 000000000000..b8424fbb93b5 --- /dev/null +++ b/toolkit/components/remote/nsUnixRemoteServer.cpp @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=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/. */ + +#include "nsUnixRemoteServer.h" +#include "nsGTKToolkit.h" +#include "nsCOMPtr.h" +#include "nsICommandLineRunner.h" +#include "nsCommandLine.h" +#include "nsIFile.h" + +// Set desktop startup ID to the passed ID, if there is one, so that any created +// windows get created with the right window manager metadata, and any windows +// that get new tabs and are activated also get the right WM metadata. +// The timestamp will be used if there is no desktop startup ID, or if we're +// raising an existing window rather than showing a new window for the first +// time. +void nsUnixRemoteServer::SetDesktopStartupIDOrTimestamp( + const nsACString& aDesktopStartupID, uint32_t aTimestamp) { + nsGTKToolkit* toolkit = nsGTKToolkit::GetToolkit(); + if (!toolkit) return; + + if (!aDesktopStartupID.IsEmpty()) { + toolkit->SetDesktopStartupID(aDesktopStartupID); + } + + toolkit->SetFocusTimestamp(aTimestamp); +} + +static bool FindExtensionParameterInCommand(const char* aParameterName, + const nsACString& aCommand, + char aSeparator, + nsACString* aValue) { + nsAutoCString searchFor; + searchFor.Append(aSeparator); + searchFor.Append(aParameterName); + searchFor.Append('='); + + nsACString::const_iterator start, end; + aCommand.BeginReading(start); + aCommand.EndReading(end); + if (!FindInReadable(searchFor, start, end)) return false; + + nsACString::const_iterator charStart, charEnd; + charStart = end; + aCommand.EndReading(charEnd); + nsACString::const_iterator idStart = charStart, idEnd; + if (FindCharInReadable(aSeparator, charStart, charEnd)) { + idEnd = charStart; + } else { + idEnd = charEnd; + } + *aValue = nsDependentCSubstring(idStart, idEnd); + return true; +} + +const char* nsUnixRemoteServer::HandleCommandLine(const char* aBuffer, + uint32_t aTimestamp) { + nsCOMPtr cmdline(new nsCommandLine()); + + // the commandline property is constructed as an array of int32_t + // followed by a series of null-terminated strings: + // + // [argc][offsetargv0][offsetargv1...]\0\0argv[1]...\0 + // (offset is from the beginning of the buffer) + + int32_t argc = TO_LITTLE_ENDIAN32(*reinterpret_cast(aBuffer)); + const char* wd = aBuffer + ((argc + 1) * sizeof(int32_t)); + + nsCOMPtr lf; + nsresult rv = + NS_NewNativeLocalFile(nsDependentCString(wd), true, getter_AddRefs(lf)); + if (NS_FAILED(rv)) return "509 internal error"; + + nsAutoCString desktopStartupID; + + const char** argv = (const char**)malloc(sizeof(char*) * argc); + if (!argv) return "509 internal error"; + + const int32_t* offset = reinterpret_cast(aBuffer) + 1; + + for (int i = 0; i < argc; ++i) { + argv[i] = aBuffer + TO_LITTLE_ENDIAN32(offset[i]); + + if (i == 0) { + nsDependentCString cmd(argv[0]); + FindExtensionParameterInCommand("DESKTOP_STARTUP_ID", cmd, ' ', + &desktopStartupID); + } + } + + rv = cmdline->Init(argc, argv, lf, nsICommandLine::STATE_REMOTE_AUTO); + + free(argv); + if (NS_FAILED(rv)) { + return "509 internal error"; + } + + SetDesktopStartupIDOrTimestamp(desktopStartupID, aTimestamp); + + rv = cmdline->Run(); + + if (NS_ERROR_ABORT == rv) return "500 command not parseable"; + + if (NS_FAILED(rv)) return "509 internal error"; + + return "200 executed command"; +} diff --git a/toolkit/components/remote/nsUnixRemoteServer.h b/toolkit/components/remote/nsUnixRemoteServer.h new file mode 100644 index 000000000000..17116578703a --- /dev/null +++ b/toolkit/components/remote/nsUnixRemoteServer.h @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:expandtab:shiftwidth=2:tabstop=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 __nsUnixRemoteServer_h__ +#define __nsUnixRemoteServer_h__ + +#include "nsString.h" + +#ifdef IS_BIG_ENDIAN +# define TO_LITTLE_ENDIAN32(x) \ + ((((x)&0xff000000) >> 24) | (((x)&0x00ff0000) >> 8) | \ + (((x)&0x0000ff00) << 8) | (((x)&0x000000ff) << 24)) +#else +# define TO_LITTLE_ENDIAN32(x) (x) +#endif + +class nsUnixRemoteServer { + protected: + void SetDesktopStartupIDOrTimestamp(const nsACString& aDesktopStartupID, + uint32_t aTimestamp); + const char* HandleCommandLine(const char* aBuffer, uint32_t aTimestamp); +}; + +#endif // __nsGTKRemoteService_h__ diff --git a/toolkit/components/remote/nsXRemoteService.cpp b/toolkit/components/remote/nsXRemoteServer.cpp similarity index 85% rename from toolkit/components/remote/nsXRemoteService.cpp rename to toolkit/components/remote/nsXRemoteServer.cpp index 4efe7ac3a160..dc3e72a844a4 100644 --- a/toolkit/components/remote/nsXRemoteService.cpp +++ b/toolkit/components/remote/nsXRemoteServer.cpp @@ -7,8 +7,7 @@ #include "mozilla/ArrayUtils.h" -#include "nsXRemoteService.h" -#include "nsRemoteService.h" +#include "nsXRemoteServer.h" #include "nsIObserverService.h" #include "nsCOMPtr.h" #include "nsIServiceManager.h" @@ -54,18 +53,18 @@ static const char *XAtomNames[] = { MOZILLA_COMMANDLINE_PROP}; static Atom XAtoms[MOZ_ARRAY_LENGTH(XAtomNames)]; -Atom nsXRemoteService::sMozVersionAtom; -Atom nsXRemoteService::sMozLockAtom; -Atom nsXRemoteService::sMozResponseAtom; -Atom nsXRemoteService::sMozUserAtom; -Atom nsXRemoteService::sMozProfileAtom; -Atom nsXRemoteService::sMozProgramAtom; -Atom nsXRemoteService::sMozCommandLineAtom; +Atom nsXRemoteServer::sMozVersionAtom; +Atom nsXRemoteServer::sMozLockAtom; +Atom nsXRemoteServer::sMozResponseAtom; +Atom nsXRemoteServer::sMozUserAtom; +Atom nsXRemoteServer::sMozProfileAtom; +Atom nsXRemoteServer::sMozProgramAtom; +Atom nsXRemoteServer::sMozCommandLineAtom; -nsXRemoteService::nsXRemoteService() = default; +nsXRemoteServer::nsXRemoteServer() = default; -void nsXRemoteService::XRemoteBaseStartup(const char *aAppName, - const char *aProfileName) { +void nsXRemoteServer::XRemoteBaseStartup(const char *aAppName, + const char *aProfileName) { EnsureAtoms(); mAppName = aAppName; @@ -74,7 +73,7 @@ void nsXRemoteService::XRemoteBaseStartup(const char *aAppName, mProfileName = aProfileName; } -void nsXRemoteService::HandleCommandsFor(Window aWindowId) { +void nsXRemoteServer::HandleCommandsFor(Window aWindowId) { // set our version XChangeProperty(mozilla::DefaultXDisplay(), aWindowId, sMozVersionAtom, XA_STRING, 8, PropModeReplace, kRemoteVersion, @@ -101,8 +100,8 @@ void nsXRemoteService::HandleCommandsFor(Window aWindowId) { } } -bool nsXRemoteService::HandleNewProperty(XID aWindowId, Display *aDisplay, - Time aEventTime, Atom aChangedAtom) { +bool nsXRemoteServer::HandleNewProperty(XID aWindowId, Display *aDisplay, + Time aEventTime, Atom aChangedAtom) { if (aChangedAtom == sMozCommandLineAtom) { // We got a new command atom. int result; @@ -132,7 +131,7 @@ bool nsXRemoteService::HandleNewProperty(XID aWindowId, Display *aDisplay, return false; // cool, we got the property data. - const char *response = nsRemoteService::HandleCommandLine(data, aEventTime); + const char *response = HandleCommandLine(data, aEventTime); // put the property onto the window as the response XChangeProperty(aDisplay, aWindowId, sMozResponseAtom, XA_STRING, 8, @@ -155,7 +154,7 @@ bool nsXRemoteService::HandleNewProperty(XID aWindowId, Display *aDisplay, return false; } -void nsXRemoteService::EnsureAtoms(void) { +void nsXRemoteServer::EnsureAtoms(void) { if (sMozVersionAtom) return; XInternAtoms(mozilla::DefaultXDisplay(), const_cast(XAtomNames), diff --git a/toolkit/components/remote/nsXRemoteService.h b/toolkit/components/remote/nsXRemoteServer.h similarity index 61% rename from toolkit/components/remote/nsXRemoteService.h rename to toolkit/components/remote/nsXRemoteServer.h index 38e9311e2d76..405bafe7892c 100644 --- a/toolkit/components/remote/nsXRemoteService.h +++ b/toolkit/components/remote/nsXRemoteServer.h @@ -5,32 +5,24 @@ * 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 NSXREMOTESERVICE_H -#define NSXREMOTESERVICE_H +#ifndef NSXREMOTESERVER_H +#define NSXREMOTESERVER_H #include "nsString.h" +#include "nsRemoteServer.h" +#include "nsUnixRemoteServer.h" #include #include -class nsIDOMWindow; - -#ifdef IS_BIG_ENDIAN -# define TO_LITTLE_ENDIAN32(x) \ - ((((x)&0xff000000) >> 24) | (((x)&0x00ff0000) >> 8) | \ - (((x)&0x0000ff00) << 8) | (((x)&0x000000ff) << 24)) -#else -# define TO_LITTLE_ENDIAN32(x) (x) -#endif - /** Base class for GTK/Qt remote service */ -class nsXRemoteService { +class nsXRemoteServer : public nsRemoteServer, public nsUnixRemoteServer { protected: - nsXRemoteService(); - static bool HandleNewProperty(Window aWindowId, Display* aDisplay, - Time aEventTime, Atom aChangedAtom); + nsXRemoteServer(); + bool HandleNewProperty(Window aWindowId, Display* aDisplay, Time aEventTime, + Atom aChangedAtom); void XRemoteBaseStartup(const char* aAppName, const char* aProfileName); void HandleCommandsFor(Window aWindowId); @@ -49,4 +41,4 @@ class nsXRemoteService { static Atom sMozCommandLineAtom; }; -#endif // NSXREMOTESERVICE_H +#endif // NSXREMOTESERVER_H diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build index 87ca08b9c8b8..f1dc060325a9 100644 --- a/toolkit/xre/moz.build +++ b/toolkit/xre/moz.build @@ -91,6 +91,10 @@ elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: UNIFIED_SOURCES += [ 'nsNativeAppSupportUnix.cpp', ] + + LOCAL_INCLUDES += [ + '../components/remote', + ] else: UNIFIED_SOURCES += [ 'nsNativeAppSupportDefault.cpp', diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 9818f18df936..6e34aa19b7b7 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -189,7 +189,7 @@ // for X remote support #if defined(MOZ_WIDGET_GTK) # include "XRemoteClient.h" -# include "nsIRemoteService.h" +# include "nsRemoteService.h" # include "nsProfileLock.h" # include "SpecialSystemDirectory.h" # include @@ -2925,7 +2925,7 @@ class XREMain { nsCOMPtr mProfLD; nsCOMPtr mProfileLock; #if defined(MOZ_WIDGET_GTK) - nsCOMPtr mRemoteService; + RefPtr mRemoteService; nsProfileLock mRemoteLock; nsCOMPtr mRemoteLockDir; #endif @@ -4628,10 +4628,12 @@ nsresult XREMain::XRE_mainRun() { #if defined(MOZ_WIDGET_GTK) // if we have X remote support, start listening for requests on the // proxy window. - if (!mDisableRemote) - mRemoteService = do_GetService("@mozilla.org/toolkit/remote-service;1"); - if (mRemoteService) + if (!mDisableRemote) { + mRemoteService = new nsRemoteService(); + } + if (mRemoteService) { mRemoteService->Startup(mAppData->remotingName, mProfileName.get()); + } if (mRemoteLockDir) { mRemoteLock.Unlock(); mRemoteLock.Cleanup(); diff --git a/uriloader/exthandler/DBusHelpers.h b/uriloader/exthandler/DBusHelpers.h index 8b7391bf8fb9..4f4f64309d2e 100644 --- a/uriloader/exthandler/DBusHelpers.h +++ b/uriloader/exthandler/DBusHelpers.h @@ -9,6 +9,7 @@ #include #include "mozilla/UniquePtr.h" +#include "mozilla/RefPtr.h" namespace mozilla {