From f2a82cb6be470c46f5be1bd3a5a6a91e2dd57eae Mon Sep 17 00:00:00 2001 From: groovecoder Date: Thu, 6 Apr 2017 16:07:59 -0500 Subject: [PATCH 1/2] for #321: page count telemetry per activity --- docs/metrics.md | 11 ++++++ webextension/background.js | 72 +++++++++++++++++++++++++++++++------- webextension/manifest.json | 1 + 3 files changed, 71 insertions(+), 13 deletions(-) diff --git a/docs/metrics.md b/docs/metrics.md index 648af7f..135ed97 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -189,6 +189,17 @@ of a `testpilottest` telemetry ping for each scenario. } ``` +* The user goes idle + +```js + { + "uuid": , + "userContextId": , + "event": "page-requests-completed-per-activity", + "pageRequestCount": + } +``` + * The user chooses "Always Open in this Container" context menu option. (Note: We send two separate event names: one for assigning a site to a container, one for removing a site from a container.) ```js diff --git a/webextension/background.js b/webextension/background.js index 9631949..077ecdb 100644 --- a/webextension/background.js +++ b/webextension/background.js @@ -280,6 +280,20 @@ const messageHandler = { }); }); + browser.idle.onStateChanged.addListener((newState) => { + browser.tabs.query({}).then(tabs => { + for (let tab of tabs) { // eslint-disable-line prefer-const + if (newState === "idle" || newState === "locked") { + tabPageCounter.sendTabCountAndDelete(tab.id, "user-went-idle"); + } else if (newState === "active") { + tabPageCounter.initTabCounter(tab, "user-became-active"); + } + } + }).catch(e => { + throw e; + }); + }); + browser.webRequest.onCompleted.addListener((details) => { if (details.frameId !== 0 || details.tabId === -1) { return {}; @@ -333,30 +347,62 @@ const themeManager = { }; const tabPageCounter = { - counter: {}, + counters: {}, - initTabCounter(tab) { - if (tab.id in this.counter) { + initTabCounter(tab, why = "user-activated-tab") { + // When the user becomes active, + // we ONLY need to initialize the activity counter + if (tab.id in this.counters && why === "user-became-active") { + this.counters[tab.id].activity = { + "cookieStoreId": tab.cookieStoreId, + "pageRequests": 0 + }; return; } - this.counter[tab.id] = { + if (tab.id in this.counters) { + return; + } + this.counters[tab.id] = {}; + this.counters[tab.id].tab = { + "cookieStoreId": tab.cookieStoreId, + "pageRequests": 0 + }; + this.counters[tab.id].activity = { "cookieStoreId": tab.cookieStoreId, "pageRequests": 0 }; }, - sendTabCountAndDelete(tabId) { - browser.runtime.sendMessage({ - method: "sendTelemetryPayload", - event: "page-requests-completed-per-tab", - userContextId: this.counter[tabId].cookieStoreId, - pageRequestCount: this.counter[tabId].pageRequests - }); - delete this.counter[tabId]; + sendTabCountAndDelete(tabId, why = "user-closed-tab") { + if (why === "user-closed-tab") { + browser.runtime.sendMessage({ + method: "sendTelemetryPayload", + event: "page-requests-completed-per-tab", + userContextId: this.counters[tabId].tab.cookieStoreId, + pageRequestCount: this.counters[tabId].tab.pageRequests + }); + // When we send the ping because the user closed the tab, + // delete both the 'tab' and 'activity' counters + delete this.counters[tabId]; + } else if (why === "user-went-idle") { + browser.runtime.sendMessage({ + method: "sendTelemetryPayload", + event: "page-requests-completed-per-activity", + userContextId: this.counters[tabId].activity.cookieStoreId, + pageRequestCount: this.counters[tabId].activity.pageRequests + }); + // When we send the ping because the user went idle, + // only reset the 'activity' counter + this.counters[tabId].activity = { + "cookieStoreId": this.counters[tabId].tab.cookieStoreId, + "pageRequests": 0 + }; + } }, incrementTabCount(tab) { - this.counter[tab.id].pageRequests++; + this.counters[tab.id].tab.pageRequests++; + this.counters[tab.id].activity.pageRequests++; } }; diff --git a/webextension/manifest.json b/webextension/manifest.json index 4e30c9d..a5a85e0 100644 --- a/webextension/manifest.json +++ b/webextension/manifest.json @@ -24,6 +24,7 @@ "cookies", "contextMenus", "history", + "idle", "notifications", "storage", "tabs", From 6282201b2c7794ed2c9cd6930def86e9c26cb14c Mon Sep 17 00:00:00 2001 From: groovecoder Date: Tue, 11 Apr 2017 11:36:35 -0500 Subject: [PATCH 2/2] for #321: only send activity page counts for tabs that were activated --- webextension/background.js | 50 +++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/webextension/background.js b/webextension/background.js index 077ecdb..cc28549 100644 --- a/webextension/background.js +++ b/webextension/background.js @@ -283,10 +283,10 @@ const messageHandler = { browser.idle.onStateChanged.addListener((newState) => { browser.tabs.query({}).then(tabs => { for (let tab of tabs) { // eslint-disable-line prefer-const - if (newState === "idle" || newState === "locked") { + if (newState === "idle") { tabPageCounter.sendTabCountAndDelete(tab.id, "user-went-idle"); - } else if (newState === "active") { - tabPageCounter.initTabCounter(tab, "user-became-active"); + } else if (newState === "active" && tab.active) { + tabPageCounter.initTabCounter(tab); } } }).catch(e => { @@ -349,32 +349,38 @@ const themeManager = { const tabPageCounter = { counters: {}, - initTabCounter(tab, why = "user-activated-tab") { - // When the user becomes active, - // we ONLY need to initialize the activity counter - if (tab.id in this.counters && why === "user-became-active") { + initTabCounter(tab) { + if (tab.id in this.counters) { + if (!("activity" in this.counters[tab.id])) { + this.counters[tab.id].activity = { + "cookieStoreId": tab.cookieStoreId, + "pageRequests": 0 + }; + } + if (!("tab" in this.counters[tab.id])) { + this.counters[tab.id].tab = { + "cookieStoreId": tab.cookieStoreId, + "pageRequests": 0 + }; + } + } else { + this.counters[tab.id] = {}; + this.counters[tab.id].tab = { + "cookieStoreId": tab.cookieStoreId, + "pageRequests": 0 + }; this.counters[tab.id].activity = { "cookieStoreId": tab.cookieStoreId, "pageRequests": 0 }; - return; } - if (tab.id in this.counters) { - return; - } - this.counters[tab.id] = {}; - this.counters[tab.id].tab = { - "cookieStoreId": tab.cookieStoreId, - "pageRequests": 0 - }; - this.counters[tab.id].activity = { - "cookieStoreId": tab.cookieStoreId, - "pageRequests": 0 - }; }, sendTabCountAndDelete(tabId, why = "user-closed-tab") { - if (why === "user-closed-tab") { + if (!(this.counters[tabId])) { + return; + } + if (why === "user-closed-tab" && this.counters[tabId].tab) { browser.runtime.sendMessage({ method: "sendTelemetryPayload", event: "page-requests-completed-per-tab", @@ -384,7 +390,7 @@ const tabPageCounter = { // When we send the ping because the user closed the tab, // delete both the 'tab' and 'activity' counters delete this.counters[tabId]; - } else if (why === "user-went-idle") { + } else if (why === "user-went-idle" && this.counters[tabId].activity) { browser.runtime.sendMessage({ method: "sendTelemetryPayload", event: "page-requests-completed-per-activity",