[gnome-shell/wip/rstrode/login-screen-extensions: 46/134] extensionSystem: Move extension loading into ExtensionManager
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/rstrode/login-screen-extensions: 46/134] extensionSystem: Move extension loading into ExtensionManager
- Date: Thu, 26 Aug 2021 19:30:59 +0000 (UTC)
commit 99c9451f7d7864886ac54f213834e7ecc3378a6f
Author: Florian Müllner <fmuellner gnome org>
Date: Sun Jul 7 23:38:27 2019 +0200
extensionSystem: Move extension loading into ExtensionManager
Now that extension loading and the extensions map are no longer shared
between the gnome-shell and gnome-shell-extension-prefs processes, we
can move both into the ExtensionManager which makes much more sense
conceptually.
https://bugzilla.gnome.org/show_bug.cgi?id=789852
js/misc/extensionUtils.js | 95 ++-----------------------------------
js/ui/extensionDownloader.js | 12 ++---
js/ui/extensionSystem.js | 110 ++++++++++++++++++++++++++++++++++++-------
js/ui/lookingGlass.js | 4 +-
js/ui/main.js | 1 +
js/ui/shellDBus.js | 8 ++--
6 files changed, 111 insertions(+), 119 deletions(-)
---
diff --git a/js/misc/extensionUtils.js b/js/misc/extensionUtils.js
index 025cd042e3..c513ebc065 100644
--- a/js/misc/extensionUtils.js
+++ b/js/misc/extensionUtils.js
@@ -7,10 +7,8 @@ const { Gio, GLib } = imports.gi;
const Gettext = imports.gettext;
const Lang = imports.lang;
-const Signals = imports.signals;
const Config = imports.misc.config;
-const FileUtils = imports.misc.fileUtils;
var ExtensionType = {
SYSTEM: 1,
@@ -33,9 +31,6 @@ var ExtensionState = {
const SERIALIZED_PROPERTIES = ['type', 'state', 'path', 'error', 'hasPrefs', 'canChange'];
-// Maps uuid -> metadata object
-var extensions = {};
-
/**
* getCurrentExtension:
*
@@ -66,13 +61,17 @@ function getCurrentExtension() {
if (!match)
return null;
+ // local import, as the module is used from outside the gnome-shell process
+ // as well (not this function though)
+ let extensionManager = imports.ui.main.extensionManager;
+
let path = match[1];
let file = Gio.File.new_for_path(path);
// Walk up the directory tree, looking for an extension with
// the same UUID as a directory name.
while (file != null) {
- let extension = extensions[file.get_basename()];
+ let extension = extensionManager.extensions[file.get_basename()];
if (extension !== undefined)
return extension;
file = file.get_parent();
@@ -178,57 +177,6 @@ function isOutOfDate(extension) {
return false;
}
-function createExtensionObject(uuid, dir, type) {
- let info;
-
- let metadataFile = dir.get_child('metadata.json');
- if (!metadataFile.query_exists(null)) {
- throw new Error('Missing metadata.json');
- }
-
- let metadataContents, success, tag;
- try {
- [success, metadataContents, tag] = metadataFile.load_contents(null);
- if (metadataContents instanceof Uint8Array)
- metadataContents = imports.byteArray.toString(metadataContents);
- } catch (e) {
- throw new Error('Failed to load metadata.json: ' + e);
- }
- let meta;
- try {
- meta = JSON.parse(metadataContents);
- } catch (e) {
- throw new Error('Failed to parse metadata.json: ' + e);
- }
-
- let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
- for (let i = 0; i < requiredProperties.length; i++) {
- let prop = requiredProperties[i];
- if (!meta[prop]) {
- throw new Error('missing "' + prop + '" property in metadata.json');
- }
- }
-
- if (uuid != meta.uuid) {
- throw new Error('uuid "' + meta.uuid + '" from metadata.json does not match directory name "' + uuid
+ '"');
- }
-
- let extension = {};
-
- extension.metadata = meta;
- extension.uuid = meta.uuid;
- extension.type = type;
- extension.dir = dir;
- extension.path = dir.get_path();
- extension.error = '';
- extension.hasPrefs = dir.get_child('prefs.js').query_exists(null);
- extension.canChange = false;
-
- extensions[uuid] = extension;
-
- return extension;
-}
-
function serializeExtension(extension) {
let obj = {};
Lang.copyProperties(extension.metadata, obj);
@@ -283,36 +231,3 @@ function installImporter(extension) {
extension.imports = imports[extension.uuid];
imports.searchPath = oldSearchPath;
}
-
-var ExtensionFinder = class {
- _loadExtension(extensionDir, info, perUserDir) {
- let fileType = info.get_file_type();
- if (fileType != Gio.FileType.DIRECTORY)
- return;
- let uuid = info.get_name();
- let existing = extensions[uuid];
- if (existing) {
- log('Extension %s already installed in %s. %s will not be loaded'.format(uuid, existing.path,
extensionDir.get_path()));
- return;
- }
-
- let extension;
- let type = extensionDir.has_prefix(perUserDir) ? ExtensionType.PER_USER
- : ExtensionType.SYSTEM;
- try {
- extension = createExtensionObject(uuid, extensionDir, type);
- } catch(e) {
- logError(e, 'Could not load extension %s'.format(uuid));
- return;
- }
- this.emit('extension-found', extension);
- }
-
- scanExtensions() {
- let perUserDir = Gio.File.new_for_path(global.userdatadir);
- FileUtils.collectFromDatadirs('extensions', true, (dir, info) => {
- this._loadExtension(dir, info, perUserDir);
- });
- }
-};
-Signals.addSignalMethods(ExtensionFinder.prototype);
diff --git a/js/ui/extensionDownloader.js b/js/ui/extensionDownloader.js
index de52edfa6d..1d92a5740c 100644
--- a/js/ui/extensionDownloader.js
+++ b/js/ui/extensionDownloader.js
@@ -43,7 +43,7 @@ function installExtension(uuid, invocation) {
}
function uninstallExtension(uuid) {
- let extension = ExtensionUtils.extensions[uuid];
+ let extension = Main.extensionManager.extensions[uuid];
if (!extension)
return false;
@@ -112,7 +112,7 @@ function updateExtension(uuid) {
_httpSession.queue_message(message, (session, message) => {
gotExtensionZipFile(session, message, uuid, newExtensionTmpDir, () => {
- let oldExtension = ExtensionUtils.extensions[uuid];
+ let oldExtension = Main.extensionManager.extensions[uuid];
let extensionDir = oldExtension.dir;
if (!Main.extensionManager.unloadExtension(oldExtension))
@@ -124,7 +124,7 @@ function updateExtension(uuid) {
let extension = null;
try {
- extension = ExtensionUtils.createExtensionObject(uuid, extensionDir,
ExtensionUtils.ExtensionType.PER_USER);
+ extension = Main.extensionManager.createExtensionObject(uuid, extensionDir,
ExtensionUtils.ExtensionType.PER_USER);
Main.extensionManager.loadExtension(extension);
} catch(e) {
if (extension)
@@ -150,8 +150,8 @@ function updateExtension(uuid) {
function checkForUpdates() {
let metadatas = {};
- for (let uuid in ExtensionUtils.extensions) {
- metadatas[uuid] = ExtensionUtils.extensions[uuid].metadata;
+ for (let uuid in Main.extensionManager.extensions) {
+ metadatas[uuid] = Main.extensionManager.extensions[uuid].metadata;
}
let params = { shell_version: Config.PACKAGE_VERSION,
@@ -229,7 +229,7 @@ class InstallExtensionDialog extends ModalDialog.ModalDialog {
function callback() {
try {
- let extension = ExtensionUtils.createExtensionObject(uuid, dir,
ExtensionUtils.ExtensionType.PER_USER);
+ let extension = Main.extensionManager.createExtensionObject(uuid, dir,
ExtensionUtils.ExtensionType.PER_USER);
Main.extensionManager.loadExtension(extension);
if (!Main.extensionManager.enableExtension(uuid))
throw new Error(`Cannot add ${uuid} to enabled extensions gsettings key`);
diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js
index a83e53c83c..0fd49c5ca6 100644
--- a/js/ui/extensionSystem.js
+++ b/js/ui/extensionSystem.js
@@ -4,9 +4,10 @@ const { Gio, St } = imports.gi;
const Signals = imports.signals;
const ExtensionUtils = imports.misc.extensionUtils;
+const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main;
-const { ExtensionState } = ExtensionUtils;
+const { ExtensionState, ExtensionType } = ExtensionUtils;
const ENABLED_EXTENSIONS_KEY = 'enabled-extensions';
const DISABLE_USER_EXTENSIONS_KEY = 'disable-user-extensions';
@@ -17,15 +18,23 @@ var ExtensionManager = class {
this._initted = false;
this._enabled = false;
+ this._extensions = {};
this._enabledExtensions = [];
this._extensionOrder = [];
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
+ }
+
+ init() {
this._sessionUpdated();
}
+ get extensions() {
+ return this._extensions;
+ }
+
_callExtensionDisable(uuid) {
- let extension = ExtensionUtils.extensions[uuid];
+ let extension = this._extensions[uuid];
if (!extension)
return;
@@ -47,7 +56,7 @@ var ExtensionManager = class {
for (let i = 0; i < orderReversed.length; i++) {
let uuid = orderReversed[i];
try {
- ExtensionUtils.extensions[uuid].stateObj.disable();
+ this._extensions[uuid].stateObj.disable();
} catch (e) {
this.logExtensionError(uuid, e);
}
@@ -68,7 +77,7 @@ var ExtensionManager = class {
for (let i = 0; i < order.length; i++) {
let uuid = order[i];
try {
- ExtensionUtils.extensions[uuid].stateObj.enable();
+ this._extensions[uuid].stateObj.enable();
} catch (e) {
this.logExtensionError(uuid, e);
}
@@ -83,7 +92,7 @@ var ExtensionManager = class {
}
_callExtensionEnable(uuid) {
- let extension = ExtensionUtils.extensions[uuid];
+ let extension = this._extensions[uuid];
if (!extension)
return;
@@ -127,7 +136,7 @@ var ExtensionManager = class {
}
enableExtension(uuid) {
- if (!ExtensionUtils.extensions[uuid])
+ if (!this._extensions[uuid])
return false;
let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
@@ -140,7 +149,7 @@ var ExtensionManager = class {
}
disableExtension(uuid) {
- if (!ExtensionUtils.extensions[uuid])
+ if (!this._extensions[uuid])
return false;
let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
@@ -153,7 +162,7 @@ var ExtensionManager = class {
}
logExtensionError(uuid, error) {
- let extension = ExtensionUtils.extensions[uuid];
+ let extension = this._extensions[uuid];
if (!extension)
return;
@@ -169,6 +178,54 @@ var ExtensionManager = class {
this.emit('extension-state-changed', extension);
}
+ createExtensionObject(uuid, dir, type) {
+ let metadataFile = dir.get_child('metadata.json');
+ if (!metadataFile.query_exists(null)) {
+ throw new Error('Missing metadata.json');
+ }
+
+ let metadataContents, success;
+ try {
+ [success, metadataContents] = metadataFile.load_contents(null);
+ if (metadataContents instanceof Uint8Array)
+ metadataContents = imports.byteArray.toString(metadataContents);
+ } catch (e) {
+ throw new Error(`Failed to load metadata.json: ${e}`);
+ }
+ let meta;
+ try {
+ meta = JSON.parse(metadataContents);
+ } catch (e) {
+ throw new Error(`Failed to parse metadata.json: ${e}`);
+ }
+
+ let requiredProperties = ['uuid', 'name', 'description', 'shell-version'];
+ for (let i = 0; i < requiredProperties.length; i++) {
+ let prop = requiredProperties[i];
+ if (!meta[prop]) {
+ throw new Error(`missing "${prop}" property in metadata.json`);
+ }
+ }
+
+ if (uuid != meta.uuid) {
+ throw new Error(`uuid "${meta.uuid}" from metadata.json does not match directory name
"${uuid}"`);
+ }
+
+ let extension = {
+ metadata: meta,
+ uuid: meta.uuid,
+ type,
+ dir,
+ path: dir.get_path(),
+ error: '',
+ hasPrefs: dir.get_child('prefs.js').query_exists(null),
+ canChange: false
+ };
+ this._extensions[uuid] = extension;
+
+ return extension;
+ }
+
loadExtension(extension) {
// Default to error, we set success as the last step
extension.state = ExtensionState.ERROR;
@@ -202,7 +259,7 @@ var ExtensionManager = class {
extension.state = ExtensionState.UNINSTALLED;
this.emit('extension-state-changed', extension);
- delete ExtensionUtils.extensions[extension.uuid];
+ delete this._extensions[extension.uuid];
return true;
}
@@ -217,7 +274,7 @@ var ExtensionManager = class {
// Now, recreate the extension and load it.
let newExtension;
try {
- newExtension = ExtensionUtils.createExtensionObject(uuid, dir, type);
+ newExtension = this.createExtensionObject(uuid, dir, type);
} catch (e) {
this.logExtensionError(uuid, e);
return;
@@ -227,7 +284,7 @@ var ExtensionManager = class {
}
_callExtensionInit(uuid) {
- let extension = ExtensionUtils.extensions[uuid];
+ let extension = this._extensions[uuid];
let dir = extension.dir;
if (!extension)
@@ -328,7 +385,7 @@ var ExtensionManager = class {
}
_onSettingsWritableChanged() {
- for (let uuid in ExtensionUtils.extensions) {
+ for (let uuid in this._extensions) {
let extension = ExtensionUtils.extensions[uuid];
this._updateCanChange(extension);
this.emit('extension-state-changed', extension);
@@ -340,8 +397,8 @@ var ExtensionManager = class {
// extensions when allowed by the sessionMode, so
// temporarily disable them all
this._enabledExtensions = [];
- for (let uuid in ExtensionUtils.extensions)
- this.reloadExtension(ExtensionUtils.extensions[uuid]);
+ for (let uuid in this._extensions)
+ this.reloadExtension(this._extensions[uuid]);
this._enabledExtensions = this._getEnabledExtensions();
if (Main.sessionMode.allowExtensions) {
@@ -363,11 +420,30 @@ var ExtensionManager = class {
this._enabledExtensions = this._getEnabledExtensions();
- let finder = new ExtensionUtils.ExtensionFinder();
- finder.connect('extension-found', (finder, extension) => {
+ let perUserDir = Gio.File.new_for_path(global.userdatadir);
+ FileUtils.collectFromDatadirs('extensions', true, (dir, info) => {
+ let fileType = info.get_file_type();
+ if (fileType != Gio.FileType.DIRECTORY)
+ return;
+ let uuid = info.get_name();
+ let existing = this._extensions[uuid];
+ if (existing) {
+ log(`Extension ${uuid} already installed in ${existing.path}. ${dir.get_path()} will not be
loaded`);
+ return;
+ }
+
+ let extension;
+ let type = dir.has_prefix(perUserDir)
+ ? ExtensionType.PER_USER
+ : ExtensionType.SYSTEM;
+ try {
+ extension = this.createExtensionObject(uuid, dir, type);
+ } catch (e) {
+ logError(e, `Could not load extension ${uuid}`);
+ return;
+ }
this.loadExtension(extension);
});
- finder.scanExtensions();
}
_enableAllExtensions() {
diff --git a/js/ui/lookingGlass.js b/js/ui/lookingGlass.js
index e947574f2c..b8f8b14c97 100644
--- a/js/ui/lookingGlass.js
+++ b/js/ui/lookingGlass.js
@@ -620,7 +620,7 @@ var Extensions = class Extensions {
this._extensionsList.add(this._noExtensions);
this.actor.add(this._extensionsList);
- for (let uuid in ExtensionUtils.extensions)
+ for (let uuid in Main.extensionManager.extensions)
this._loadExtension(null, uuid);
Main.extensionManager.connect('extension-loaded',
@@ -628,7 +628,7 @@ var Extensions = class Extensions {
}
_loadExtension(o, uuid) {
- let extension = ExtensionUtils.extensions[uuid];
+ let extension = Main.extensionManager.extensions[uuid];
// There can be cases where we create dummy extension metadata
// that's not really a proper extension. Don't bother with these.
if (!extension.metadata.name)
diff --git a/js/ui/main.js b/js/ui/main.js
index b2e0a6abe0..729063f19f 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -214,6 +214,7 @@ function _initializeUI() {
ExtensionDownloader.init();
extensionManager = new ExtensionSystem.ExtensionManager();
+ extensionManager.init();
if (sessionMode.isGreeter && screenShield) {
layoutManager.connect('startup-prepared', () => {
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index 23274c0a3f..dc3a61df67 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -254,7 +254,7 @@ var GnomeShellExtensions = class {
ListExtensions() {
let out = {};
- for (let uuid in ExtensionUtils.extensions) {
+ for (let uuid in Main.extensionManager.extensions) {
let dbusObj = this.GetExtensionInfo(uuid);
out[uuid] = dbusObj;
}
@@ -262,12 +262,12 @@ var GnomeShellExtensions = class {
}
GetExtensionInfo(uuid) {
- let extension = ExtensionUtils.extensions[uuid] || {};
+ let extension = Main.extensionManager.extensions[uuid] || {};
return ExtensionUtils.serializeExtension(extension);
}
GetExtensionErrors(uuid) {
- let extension = ExtensionUtils.extensions[uuid];
+ let extension = Main.extensionManager.extensions[uuid];
if (!extension)
return [];
@@ -303,7 +303,7 @@ var GnomeShellExtensions = class {
}
ReloadExtension(uuid) {
- let extension = ExtensionUtils.extensions[uuid];
+ let extension = Main.extensionManager.extensions[uuid];
if (!extension)
return;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]