extensionUtils: Add functions to (de)serialize extensions

Serializing an extension for sending over D-Bus is currently done by the
appropriate D-Bus method implementations. Split out the code as utility
function and add a corresponding deserialization function, which we will
soon use when consuming the D-Bus extension API from the extension-prefs
tool.

https://bugzilla.gnome.org/show_bug.cgi?id=789852
This commit is contained in:
Didier Roche 2018-11-01 13:55:17 +01:00 committed by Florian Müllner
parent 4589da957b
commit 58806359ee
2 changed files with 54 additions and 39 deletions

View File

@ -3,10 +3,11 @@
// Common utils for the extension system and the extension // Common utils for the extension system and the extension
// preferences tool // preferences tool
const Gettext = imports.gettext; const { Gio, GLib } = imports.gi;
const Signals = imports.signals;
const Gio = imports.gi.Gio; const Gettext = imports.gettext;
const Lang = imports.lang;
const Signals = imports.signals;
const Config = imports.misc.config; const Config = imports.misc.config;
const FileUtils = imports.misc.fileUtils; const FileUtils = imports.misc.fileUtils;
@ -29,6 +30,8 @@ var ExtensionState = {
UNINSTALLED: 99 UNINSTALLED: 99
}; };
const SERIALIZED_PROPERTIES = ['type', 'state', 'path', 'error', 'hasPrefs'];
// Maps uuid -> metadata object // Maps uuid -> metadata object
var extensions = {}; var extensions = {};
@ -222,6 +225,52 @@ function createExtensionObject(uuid, dir, type) {
return extension; return extension;
} }
function serializeExtension(extension) {
let obj = {};
Lang.copyProperties(extension.metadata, obj);
SERIALIZED_PROPERTIES.forEach(prop => {
obj[prop] = extension[prop];
});
let res = {};
for (let key in obj) {
let val = obj[key];
let type;
switch (typeof val) {
case 'string':
type = 's';
break;
case 'number':
type = 'd';
break;
case 'boolean':
type = 'b';
break;
default:
continue;
}
res[key] = GLib.Variant.new(type, val);
}
return res;
}
function deserializeExtension(variant) {
let res = { metadata: {} };
for (let prop in variant) {
let val = variant[prop].unpack();
if (SERIALIZED_PROPERTIES.includes(prop))
res[prop] = val;
else
res.metadata[prop] = val;
}
// add the 2 additional properties to create a valid extension object, as createExtensionObject()
res.uuid = res.metadata.uuid;
res.dir = Gio.File.new_for_path(res.path);
return res;
}
function installImporter(extension) { function installImporter(extension) {
let oldSearchPath = imports.searchPath.slice(); // make a copy let oldSearchPath = imports.searchPath.slice(); // make a copy
imports.searchPath = [extension.dir.get_parent().get_path()]; imports.searchPath = [extension.dir.get_parent().get_path()];

View File

@ -1,7 +1,6 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const { Gio, GLib, Meta, Shell } = imports.gi; const { Gio, GLib, Meta, Shell } = imports.gi;
const Lang = imports.lang;
const Config = imports.misc.config; const Config = imports.misc.config;
const ExtensionDownloader = imports.ui.extensionDownloader; const ExtensionDownloader = imports.ui.extensionDownloader;
@ -264,41 +263,8 @@ var GnomeShellExtensions = class {
} }
GetExtensionInfo(uuid) { GetExtensionInfo(uuid) {
let extension = ExtensionUtils.extensions[uuid]; let extension = ExtensionUtils.extensions[uuid] || {};
if (!extension) return ExtensionUtils.serializeExtension(extension);
return {};
let obj = {};
Lang.copyProperties(extension.metadata, obj);
// Only serialize the properties that we actually need.
const serializedProperties = ["type", "state", "path", "error", "hasPrefs"];
serializedProperties.forEach(prop => {
obj[prop] = extension[prop];
});
let out = {};
for (let key in obj) {
let val = obj[key];
let type;
switch (typeof val) {
case 'string':
type = 's';
break;
case 'number':
type = 'd';
break;
case 'boolean':
type = 'b';
break;
default:
continue;
}
out[key] = GLib.Variant.new(type, val);
}
return out;
} }
GetExtensionErrors(uuid) { GetExtensionErrors(uuid) {