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
This commit is contained in:
Dave Townsend 2019-02-27 15:45:51 -08:00
Родитель bbb9bd1286
Коммит 5e41c25e13
17 изменённых файлов: 295 добавлений и 322 удалений

Просмотреть файл

@ -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'],
},
]

Просмотреть файл

@ -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']

Просмотреть файл

@ -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 <dlfcn.h>
NS_IMPL_ISUPPORTS(nsDBusRemoteService, nsIRemoteService)
const char *introspect_template =
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection "
"1.0//EN\"\n"
@ -47,7 +44,7 @@ const char *introspect_template =
" </interface>\n"
"</node>\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<nsDBusRemoteService *>(user_data);
auto interface = static_cast<nsDBusRemoteServer *>(user_data);
return interface->HandleDBusMessage(conn, msg);
}
static void unregister(DBusConnection *conn, void *user_data) {
auto interface = static_cast<nsDBusRemoteService *>(user_data);
auto interface = static_cast<nsDBusRemoteServer *>(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;
}

Просмотреть файл

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

Просмотреть файл

@ -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 <gtk/gtk.h>
#include <gdk/gdk.h>
@ -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;
}

Просмотреть файл

@ -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 <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#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;

Просмотреть файл

@ -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();
};

Просмотреть файл

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

Просмотреть файл

@ -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 <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#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<nsDBusRemoteServer>();
}
# endif
if (useX11Remote) {
mRemoteServer = MakeUnique<nsGTKRemoteServer>();
}
#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<nsIObserverService> 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<nsICommandLineRunner> 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...]<workingdir>\0<argv[0]>\0argv[1]...\0
// (offset is from the beginning of the buffer)
int32_t argc = TO_LITTLE_ENDIAN32(*reinterpret_cast<const int32_t*>(aBuffer));
const char* wd = aBuffer + ((argc + 1) * sizeof(int32_t));
nsCOMPtr<nsIFile> 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<const int32_t*>(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";
}

Просмотреть файл

@ -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<nsIRemoteService> mDBusRemoteService;
nsCOMPtr<nsIRemoteService> 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<nsRemoteServer> mRemoteServer;
};
#endif // __nsRemoteService_h__

Просмотреть файл

@ -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<nsICommandLineRunner> 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...]<workingdir>\0<argv[0]>\0argv[1]...\0
// (offset is from the beginning of the buffer)
int32_t argc = TO_LITTLE_ENDIAN32(*reinterpret_cast<const int32_t*>(aBuffer));
const char* wd = aBuffer + ((argc + 1) * sizeof(int32_t));
nsCOMPtr<nsIFile> 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<const int32_t*>(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";
}

Просмотреть файл

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

Просмотреть файл

@ -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<char **>(XAtomNames),

Просмотреть файл

@ -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 <X11/Xlib.h>
#include <X11/X.h>
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

Просмотреть файл

@ -91,6 +91,10 @@ elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
UNIFIED_SOURCES += [
'nsNativeAppSupportUnix.cpp',
]
LOCAL_INCLUDES += [
'../components/remote',
]
else:
UNIFIED_SOURCES += [
'nsNativeAppSupportDefault.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 <sched.h>
@ -2925,7 +2925,7 @@ class XREMain {
nsCOMPtr<nsIFile> mProfLD;
nsCOMPtr<nsIProfileLock> mProfileLock;
#if defined(MOZ_WIDGET_GTK)
nsCOMPtr<nsIRemoteService> mRemoteService;
RefPtr<nsRemoteService> mRemoteService;
nsProfileLock mRemoteLock;
nsCOMPtr<nsIFile> 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();

Просмотреть файл

@ -9,6 +9,7 @@
#include <dbus/dbus.h>
#include "mozilla/UniquePtr.h"
#include "mozilla/RefPtr.h"
namespace mozilla {