Bug 1501375 - Clear primed listeners on extension shutdown r=aswan

In D9959 and D10954, the implementation of background page machinery
was updated so that the `build` method of `BackgroundPage` is
guaranteed to return eventually, without error. Even if the load of
the background page was interrupted by an extension shut down.

When an extension shuts down during start-up, primed listeners have
likely not been re-registered. To prevent interruption of startup
from causing the loss of persistent listeners, this commit changes
the implementation such that persistent listeners are only updated if
the background page was fully loaded.
Otherwise listeners are cleared from memory, but not unregistered.

Depends on D10954

Differential Revision: https://phabricator.services.mozilla.com/D17700

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Rob Wu 2019-02-20 21:53:08 +00:00
Родитель b2f6293ddd
Коммит 60b907f11d
2 изменённых файлов: 18 добавлений и 3 удалений

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

@ -2157,7 +2157,10 @@ class EventManager {
// Remove any primed listeners that were not re-registered.
// This function is called after the background page has started.
static clearPrimedListeners(extension) {
// The removed listeners are removed from the set of saved listeners, unless
// `clearPersistent` is false. If false, the listeners are cleared from
// memory, but not removed from the extension's startup data.
static clearPrimedListeners(extension, clearPersistent = true) {
for (let [module, moduleEntry] of extension.persistentListeners) {
for (let [event, listeners] of moduleEntry) {
for (let [key, listener] of listeners) {
@ -2170,7 +2173,9 @@ class EventManager {
evt.reject(new Error("listener not re-registered"));
}
if (clearPersistent) {
EventManager.clearPersistentListener(extension, module, event, key);
}
primed.unregister();
}
}

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

@ -97,8 +97,16 @@ this.backgroundPage = class extends ExtensionAPI {
EventManager.primeListeners(extension);
extension.once("start-background-page", async () => {
if (!this.extension) {
// Extension was shut down. Don't build the background page.
// Primed listeners have been cleared in onShutdown.
return;
}
await this.build();
EventManager.clearPrimedListeners(extension);
// |this.extension| may be null if the extension was shut down.
// In that case, we still want to clear the primed listeners,
// but not update the persistent listeners in the startupData.
EventManager.clearPrimedListeners(extension, !!this.extension);
});
// There are two ways to start the background page:
@ -121,6 +129,8 @@ this.backgroundPage = class extends ExtensionAPI {
onShutdown() {
if (this.bgPage) {
this.bgPage.shutdown();
} else {
EventManager.clearPrimedListeners(this.extension, false);
}
}
};