summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/workers-listener.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/shared/workers-listener.js')
-rw-r--r--devtools/client/shared/workers-listener.js145
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;