commit 9f9deb6f26a1ee9ff39466371e8b5aff85ec5634
parent d2e4f8aafe188d6a3e73c71fc8a3ed2b42db2fa5
Author: Duncan McIntosh <dmcintosh@mozilla.com>
Date: Thu, 9 Oct 2025 21:59:45 +0000
Bug 1986557 - Part 1: Record with telemetry the number of Taskbar Tabs that the user has installed. r=nrishel,mossop
Differential Revision: https://phabricator.services.mozilla.com/D265682
Diffstat:
5 files changed, 98 insertions(+), 0 deletions(-)
diff --git a/browser/components/taskbartabs/TaskbarTabs.sys.mjs b/browser/components/taskbartabs/TaskbarTabs.sys.mjs
@@ -46,9 +46,25 @@ export const TaskbarTabs = new (class {
this.#registry = registry;
this.#windowManager = initWindowManager(registry);
initPinManager(registry);
+
+ this.#setupTelemetry(registry);
});
}
+ #setupTelemetry(aRegistry) {
+ function updateMetrics() {
+ Glean.webApp.installedWebAppCount.set(aRegistry.countTaskbarTabs());
+ }
+
+ aRegistry.on(kTaskbarTabsRegistryEvents.created, updateMetrics);
+ aRegistry.on(kTaskbarTabsRegistryEvents.removed, updateMetrics);
+ updateMetrics();
+ }
+
+ async waitUntilReady() {
+ await this.#ready;
+ }
+
async getTaskbarTab(...args) {
await this.#ready;
return this.#registry.getTaskbarTab(...args);
diff --git a/browser/components/taskbartabs/TaskbarTabsRegistry.sys.mjs b/browser/components/taskbartabs/TaskbarTabsRegistry.sys.mjs
@@ -392,6 +392,15 @@ export class TaskbarTabsRegistry {
}
/**
+ * Gets the number of taskbar tabs that are registered in this registry.
+ *
+ * @returns {number} The number of registered taskbar tabs.
+ */
+ countTaskbarTabs() {
+ return this.#taskbarTabs.length;
+ }
+
+ /**
* Passthrough to `EventEmitter.on`.
*
* @param {...any} args - Same as `EventEmitter.on`.
diff --git a/browser/components/taskbartabs/metrics.yaml b/browser/components/taskbartabs/metrics.yaml
@@ -123,3 +123,18 @@ web_app:
notification_emails:
- nrishel@mozilla.com
expires: never
+
+ installed_web_app_count:
+ type: quantity
+ unit: web apps
+ description: >
+ Count of currently installed web apps. Note that Firefox does not detect
+ unpinning or deleting the shortcut outside of Firefox, so this could
+ include web apps that the user has no way to access; see bug 1990342.
+ bugs:
+ - bugzilla.mozilla.org/show_bug.cgi?id=1986557
+ data_reviews:
+ - https://phabricator.services.mozilla.com/D265682
+ notification_emails:
+ - nrishel@mozilla.com
+ expires: never
diff --git a/browser/components/taskbartabs/test/xpcshell/test_taskbarTabs_installedCountMetric.js b/browser/components/taskbartabs/test/xpcshell/test_taskbarTabs_installedCountMetric.js
@@ -0,0 +1,56 @@
+/* Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// This test ensures that the installedWebAppCount metric is updated at
+// startup. Remaining telemetry tests are in browser_taskbarTabs_telemetry.js;
+// this one is separate since it needs to check behaviour when the browser
+// starts, which we can't reliably do in a Mochitest.
+
+ChromeUtils.defineESModuleGetters(this, {
+ sinon: "resource://testing-common/Sinon.sys.mjs",
+ TaskbarTabsPin: "resource:///modules/taskbartabs/TaskbarTabsPin.sys.mjs",
+});
+
+add_setup(function test_setup() {
+ do_get_profile();
+ Services.fog.initializeFOG();
+
+ sinon.stub(TaskbarTabsPin, "pinTaskbarTab");
+ sinon.stub(TaskbarTabsPin, "unpinTaskbarTab");
+});
+
+add_task(async function test_installedCounterMetric() {
+ const value = () => Glean.webApp.installedWebAppCount.testGetValue();
+ equal(value(), undefined, "Should not be set before initializing");
+
+ // We do not want to import this unknowingly, since that would mess up the
+ // telemetry count, so import it explicitly right now.
+ const { TaskbarTabs } = ChromeUtils.importESModule(
+ "resource:///modules/taskbartabs/TaskbarTabs.sys.mjs"
+ );
+
+ // Initialization is asynchronous, so do something to wait for it.
+ await TaskbarTabs.waitUntilReady();
+
+ equal(value(), 0, "No taskbar tabs exist yet");
+
+ const tt1 = await TaskbarTabs.findOrCreateTaskbarTab(
+ Services.io.newURI("https://example.com"),
+ 0
+ );
+ equal(value(), 1, "First new taskbar tab was accounted for");
+
+ const tt2 = await TaskbarTabs.findOrCreateTaskbarTab(
+ Services.io.newURI("https://example.edu"),
+ 0
+ );
+ equal(value(), 2, "Second new taskbar tab was accounted for");
+
+ await TaskbarTabs.removeTaskbarTab(tt1.id);
+ equal(value(), 1, "Removing first taskbar tab was accounted for");
+
+ await TaskbarTabs.removeTaskbarTab(tt2.id);
+ equal(value(), 0, "Removing second taskbar tab was accounted for");
+});
diff --git a/browser/components/taskbartabs/test/xpcshell/xpcshell.toml b/browser/components/taskbartabs/test/xpcshell/xpcshell.toml
@@ -8,6 +8,8 @@ support-files = [
"test_taskbarTabs_nonames.json",
]
+["test_taskbarTabs_installedCountMetric.js"]
+
["test_taskbarTabs_pin.js"]
support-files = [
"../../../places/tests/browser/favicon-normal16.png",