Bug 1761072 - Replace use of ExtensionParent in devtools' ExtensionsBackgroundScriptStatusWatcher r=rpl,jdescottes

ExtensionParent.jsm cannot be loaded without a profile, as explained at
https://bugzilla.mozilla.org/show_bug.cgi?id=1761072#c5.

But ExtensionsBackgroundScriptStatusWatcher would try to (lazily) load
the module before a profile was ready, in order to subscribe to future
changes. To avoid loading this whole ExtensionParent.jsm module, I have
replaced the event propagation mechanism with observers.

Differential Revision: https://phabricator.services.mozilla.com/D142065
This commit is contained in:
Rob Wu 2022-03-25 22:24:11 +00:00
Родитель 0bd9035ceb
Коммит 5b0e505389
3 изменённых файлов: 30 добавлений и 50 удалений

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

@ -4,11 +4,7 @@
"use strict";
loader.lazyImporter(
this,
"ExtensionParent",
"resource://gre/modules/ExtensionParent.jsm"
);
const Services = require("Services");
const {
TYPES: { EXTENSIONS_BGSCRIPT_STATUS },
@ -33,20 +29,25 @@ class ExtensionsBackgroundScriptStatusWatcher {
* Dictionary object with following attributes:
* - onAvailable: mandatory function
* This will be called for each resource.
* - onUpdated: optional function
* This would be called multiple times for each resource.
*/
async watch(rootActor, { onAvailable, onUpdated }) {
async watch(rootActor, { onAvailable }) {
this.rootActor = rootActor;
this.onAvailable = onAvailable;
this.onUpdated = onUpdated;
this.unwatchBackgroundStatusUpdates = ExtensionParent.DebugUtils.watchBackgroundScriptStatusUpdates(
this.onBackgroundScriptStatus
);
Services.obs.addObserver(this, "extension:background-script-status");
}
onBackgroundScriptStatus = (addonId, isRunning) => {
observe(subject, topic, data) {
switch (topic) {
case "extension:background-script-status": {
const { addonId, isRunning } = subject.wrappedJSObject;
this.onBackgroundScriptStatus(addonId, isRunning);
break;
}
}
}
onBackgroundScriptStatus(addonId, isRunning) {
this.onAvailable([
{
resourceType: EXTENSIONS_BGSCRIPT_STATUS,
@ -56,10 +57,13 @@ class ExtensionsBackgroundScriptStatusWatcher {
},
},
]);
};
}
destroy() {
this.unwatchBackgroundStatusUpdates?.();
if (this.onAvailable) {
this.onAvailable = null;
Services.obs.removeObserver(this, "extension:background-script-status");
}
}
}

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

@ -1503,17 +1503,6 @@ const DebugUtils = {
throw Error(`Unable to terminate background script for ${addonId}`);
},
watchBackgroundScriptStatusUpdates(callback) {
const listener = (_evtName, addonId, isRunning) => {
callback(addonId, isRunning);
};
apiManager.on(`devtools:background-script-status`, listener);
return () => {
apiManager.off(`devtools:background-script-status`, listener);
};
},
/**
* Retrieve a XUL browser element which has been configured to be able to connect
* the devtools actor with the process where the extension is running.

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

@ -40,6 +40,13 @@ XPCOMUtils.defineLazyPreferenceGetter(
delay => Math.min(Math.max(delay, 100), 5 * 60 * 1000)
);
function notifyBackgroundScriptStatus(addonId, isRunning) {
// Notify devtools when the background scripts is started or stopped
// (used to show the current status in about:debugging).
const subject = { addonId, isRunning };
Services.obs.notifyObservers(subject, "extension:background-script-status");
}
// Responsible for the background_page section of the manifest.
class BackgroundPage extends HiddenExtensionPage {
constructor(extension, options) {
@ -100,20 +107,10 @@ class BackgroundPage extends HiddenExtensionPage {
await Promise.all(context.listenerPromises);
context.listenerPromises = null;
// Notify devtools when the background scripts is started or stopped
// (used to show the current status in about:debugging).
extensions.emit(
`devtools:background-script-status`,
extension.id,
true /* isRunning */
);
notifyBackgroundScriptStatus(extension.id, true);
context.callOnClose({
close() {
extensions.emit(
`devtools:background-script-status`,
extension.id,
false /* isRunning */
);
notifyBackgroundScriptStatus(extension.id, false);
},
});
}
@ -211,20 +208,10 @@ class BackgroundWorker {
await Promise.all(context.listenerPromises);
context.listenerPromises = null;
// Notify devtools when the background scripts is started or stopped
// (used to show the current status in about:debugging).
extensions.emit(
`devtools:background-script-status`,
extension.id,
true /* isRunning */
);
notifyBackgroundScriptStatus(extension.id, true);
context.callOnClose({
close() {
extensions.emit(
`devtools:background-script-status`,
extension.id,
false /* isRunning */
);
notifyBackgroundScriptStatus(extension.id, false);
},
});
}