dbusServices/extensions: Proxy Extensions API
Similar to the previously added org.freedesktop.Notifications proxy, this exposes the org.gnome.Shell.Extensions API and forwards any request to the real implementation in gnome-shell. The motivation differs though: We want to be able to package the extension app as flatpak and distribute it separately, but the extension prefs dialog is hard to impossible to sandbox: - filenames need translating between host and sandbox, and we can only do that in some cases (serializing/deserializing extensions), but not others (extension settings that refer to files) - system extensions install their GSettings schemas in the system path; the best we can do there is assume a host prefix of /usr and set GSETTINGS_SCHEMA_DIR in the flatpak (eeks) - extensions may rely on additional typelibs that are present on the host (for example because gnome-shell itself depends on them), but not inside the sandbox - unless we bundle all of gnome-shell's dependencies - if gjs/mozjs differ between host and sandbox, extensions must handle different runtimes for the extension and its prefs And all those issues occur despite a very permissive sandbox (full host filesystem access, full dconf access, full org.gnome.Shell access (including Eval()!)). This new service will give us an alternative place for handling the preference dialog: - it runs outside of gnome-shell process, so can open windows - it runs on the host, so the extension's prefs get to run in the same namespace as the extension itself That is, the service will provide portal-like functionality (albeit not using the org.freedesktop.portal.* namespace, as extension management is an inherently privileged operation). https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1106
This commit is contained in:
parent
d76162c1c0
commit
91b7474d5a
127
js/dbusServices/extensions/extensionsService.js
Normal file
127
js/dbusServices/extensions/extensionsService.js
Normal file
@ -0,0 +1,127 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported ExtensionsService */
|
||||
|
||||
const { Gio, GLib } = imports.gi;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
const { ServiceImplementation } = imports.dbusService;
|
||||
|
||||
const ExtensionsIface = loadInterfaceXML('org.gnome.Shell.Extensions');
|
||||
const ExtensionsProxy = Gio.DBusProxy.makeProxyWrapper(ExtensionsIface);
|
||||
|
||||
var ExtensionsService = class extends ServiceImplementation {
|
||||
constructor() {
|
||||
super(ExtensionsIface, '/org/gnome/Shell/Extensions');
|
||||
|
||||
this._proxy = new ExtensionsProxy(Gio.DBus.session,
|
||||
'org.gnome.Shell', '/org/gnome/Shell');
|
||||
|
||||
this._proxy.connectSignal('ExtensionStateChanged',
|
||||
(proxy, sender, params) => {
|
||||
this._dbusImpl.emit_signal('ExtensionStateChanged',
|
||||
new GLib.Variant('(sa{sv})', params));
|
||||
});
|
||||
|
||||
this._proxy.connect('g-properties-changed', () => {
|
||||
this._dbusImpl.emit_property_changed('UserExtensionsEnabled',
|
||||
new GLib.Variant('b', this._proxy.UserExtensionsEnabled));
|
||||
});
|
||||
}
|
||||
|
||||
get ShellVersion() {
|
||||
return this._proxy.ShellVersion;
|
||||
}
|
||||
|
||||
get UserExtensionsEnabled() {
|
||||
return this._proxy.UserExtensionsEnabled;
|
||||
}
|
||||
|
||||
set UserExtensionsEnabled(enable) {
|
||||
this._proxy.UserExtensionsEnabled = enable;
|
||||
}
|
||||
|
||||
ListExtensionsAsync(params, invocation) {
|
||||
this._proxy.ListExtensionsRemote(...params, (res, error) => {
|
||||
if (this._handleError(invocation, error))
|
||||
return;
|
||||
|
||||
invocation.return_value(new GLib.Variant('(a{sa{sv}})', res));
|
||||
});
|
||||
}
|
||||
|
||||
GetExtensionInfoAsync(params, invocation) {
|
||||
this._proxy.GetExtensionInfoRemote(...params, (res, error) => {
|
||||
if (this._handleError(invocation, error))
|
||||
return;
|
||||
|
||||
invocation.return_value(new GLib.Variant('(a{sv})', res));
|
||||
});
|
||||
}
|
||||
|
||||
GetExtensionErrorsAsync(params, invocation) {
|
||||
this._proxy.GetExtensionErrorsRemote(...params, (res, error) => {
|
||||
if (this._handleError(invocation, error))
|
||||
return;
|
||||
|
||||
invocation.return_value(new GLib.Variant('(as)', res));
|
||||
});
|
||||
}
|
||||
|
||||
InstallRemoteExtensionAsync(params, invocation) {
|
||||
this._proxy.InstallRemoteExtensionRemote(...params, (res, error) => {
|
||||
if (this._handleError(invocation, error))
|
||||
return;
|
||||
|
||||
invocation.return_value(new GLib.Variant('(s)', res));
|
||||
});
|
||||
}
|
||||
|
||||
UninstallExtensionAsync(params, invocation) {
|
||||
this._proxy.UninstallExtensionRemote(...params, (res, error) => {
|
||||
if (this._handleError(invocation, error))
|
||||
return;
|
||||
|
||||
invocation.return_value(new GLib.Variant('(b)', res));
|
||||
});
|
||||
}
|
||||
|
||||
EnableExtensionAsync(params, invocation) {
|
||||
this._proxy.EnableExtensionRemote(...params, (res, error) => {
|
||||
if (this._handleError(invocation, error))
|
||||
return;
|
||||
|
||||
invocation.return_value(new GLib.Variant('(b)', res));
|
||||
});
|
||||
}
|
||||
|
||||
DisableExtensionAsync(params, invocation) {
|
||||
this._proxy.DisableExtensionRemote(...params, (res, error) => {
|
||||
if (this._handleError(invocation, error))
|
||||
return;
|
||||
|
||||
invocation.return_value(new GLib.Variant('(b)', res));
|
||||
});
|
||||
}
|
||||
|
||||
LaunchExtensionPrefsAsync([uuid], invocation) {
|
||||
this.OpenExtensionPrefsAsync([uuid, '', {}], invocation);
|
||||
}
|
||||
|
||||
OpenExtensionPrefsAsync(params, invocation) {
|
||||
this._proxy.OpenExtensionPrefsRemote(...params, (res, error) => {
|
||||
if (this._handleError(invocation, error))
|
||||
return;
|
||||
|
||||
invocation.return_value(null);
|
||||
});
|
||||
}
|
||||
|
||||
CheckForUpdatesAsync(params, invocation) {
|
||||
this._proxy.CheckForUpdatesRemote(...params, (res, error) => {
|
||||
if (this._handleError(invocation, error))
|
||||
return;
|
||||
|
||||
invocation.return_value(null);
|
||||
});
|
||||
}
|
||||
};
|
11
js/dbusServices/extensions/main.js
Normal file
11
js/dbusServices/extensions/main.js
Normal file
@ -0,0 +1,11 @@
|
||||
/* exported main */
|
||||
|
||||
const { DBusService } = imports.dbusService;
|
||||
const { ExtensionsService } = imports.extensionsService;
|
||||
|
||||
function main() {
|
||||
const service = new DBusService(
|
||||
'org.gnome.Shell.Extensions',
|
||||
new ExtensionsService());
|
||||
service.run();
|
||||
}
|
@ -4,6 +4,7 @@ launcherconf.set('prefix', prefix)
|
||||
launcherconf.set('libdir', libdir)
|
||||
|
||||
dbus_services = {
|
||||
'org.gnome.Shell.Extensions': 'extensions',
|
||||
'org.gnome.Shell.Notifications': 'notifications',
|
||||
}
|
||||
|
||||
|
11
js/dbusServices/org.gnome.Shell.Extensions.src.gresource.xml
Normal file
11
js/dbusServices/org.gnome.Shell.Extensions.src.gresource.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/Shell/Extensions/js">
|
||||
<file>main.js</file>
|
||||
<file>extensionsService.js</file>
|
||||
<file>dbusService.js</file>
|
||||
|
||||
<file>misc/config.js</file>
|
||||
<file>misc/fileUtils.js</file>
|
||||
</gresource>
|
||||
</gresources>
|
Loading…
Reference in New Issue
Block a user