diff options
Diffstat (limited to 'devtools/client/shared/workers-listener.js')
-rw-r--r-- | devtools/client/shared/workers-listener.js | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/devtools/client/shared/workers-listener.js b/devtools/client/shared/workers-listener.js new file mode 100644 index 0000000000..7d544481d8 --- /dev/null +++ b/devtools/client/shared/workers-listener.js @@ -0,0 +1,145 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +/** + * Listening to worker updates requires watching various sources. This class provides + * a single addListener/removeListener API that will aggregate all possible worker update + * events. + * + * Only supports one listener at a time. + */ +class WorkersListener { + constructor(rootFront, { registrationsOnly = false } = {}) { + this.rootFront = rootFront; + this.registrationsOnly = registrationsOnly; + + // bind handlers + this._onContentProcessTargetAvailable = + this._onContentProcessTargetAvailable.bind(this); + this._onServiceWorkerRegistrationAvailable = + this._onServiceWorkerRegistrationAvailable.bind(this); + this._onProcessDescriptorAvailable = + this._onProcessDescriptorAvailable.bind(this); + this._onContentProcessTargetDestroyed = + this._onContentProcessTargetDestroyed.bind(this); + this._onServiceWorkerRegistrationDestroyed = + this._onServiceWorkerRegistrationDestroyed.bind(this); + this._onProcessDescriptorDestroyed = + this._onProcessDescriptorDestroyed.bind(this); + + // Array of contentProcessTarget fronts on which we will listen for worker events. + this._contentProcessFronts = []; + this._serviceWorkerRegistrationFronts = []; + this._processDescriptors = []; + this._listener = null; + } + + addListener(listener) { + if (this._listener) { + throw new Error("WorkersListener addListener called twice."); + } + + this._listener = listener; + if (!this.registrationsOnly) { + this.rootFront.on("workerListChanged", this._listener); + this.rootFront.watchFronts( + "processDescriptor", + this._onProcessDescriptorAvailable, + this._onProcessDescriptorDestroyed + ); + this.rootFront.on("processListChanged", this._listener); + } + + this.rootFront.watchFronts( + "serviceWorkerRegistration", + this._onServiceWorkerRegistrationAvailable, + this._onServiceWorkerRegistrationDestroyed + ); + + this.rootFront.on("serviceWorkerRegistrationListChanged", this._listener); + } + + removeListener(listener) { + if (!this._listener) { + return; + } + + this.rootFront.off("workerListChanged", this._listener); + this.rootFront.off("serviceWorkerRegistrationListChanged", this._listener); + this.rootFront.off("processListChanged", this._listener); + + for (const front of this._contentProcessFronts) { + front.off("workerListChanged", this._listener); + } + + for (const front of this._serviceWorkerRegistrationFronts) { + front.off("push-subscription-modified", this._listener); + front.off("registration-changed", this._listener); + } + + for (const processFront of this._processDescriptors) { + processFront.unwatchFronts( + "contentProcessTarget", + this._onContentProcessTargetAvailable + ); + } + + this.rootFront.unwatchFronts( + "processDescriptor", + this._onProcessDescriptorAvailable, + this._onProcessDescriptorDestroyed + ); + this.rootFront.unwatchFronts( + "serviceWorkerRegistration", + this._onServiceWorkerRegistrationAvailable, + this._onServiceWorkerRegistrationDestroyed + ); + + this._contentProcessFronts = []; + this._serviceWorkerRegistrationFronts = []; + this._processDescriptors = []; + this._listener = null; + } + + _onContentProcessTargetAvailable(front) { + this._contentProcessFronts.push(front); + front.on("workerListChanged", this._listener); + } + + _onContentProcessTargetDestroyed(front) { + this._contentProcessFronts = this._contentProcessFronts.filter( + f => f !== front + ); + } + + _onServiceWorkerRegistrationAvailable(front) { + this._serviceWorkerRegistrationFronts.push(front); + front.on("push-subscription-modified", this._listener); + front.on("registration-changed", this._listener); + } + + _onServiceWorkerRegistrationDestroyed(front) { + this._serviceWorkerRegistrationFronts = + this._serviceWorkerRegistrationFronts.filter(f => f !== front); + } + + _onProcessDescriptorAvailable(processFront) { + this._processDescriptors.push(processFront); + processFront.watchFronts( + "contentProcessTarget", + this._onContentProcessTargetAvailable, + this._onContentProcessTargetDestroyed + ); + } + + _onProcessDescriptorDestroyed(processFront) { + this._processDescriptors = this._processDescriptors.filter( + f => f !== processFront + ); + } +} + +exports.WorkersListener = WorkersListener; |