Skip to content

Commit

Permalink
Shield Telemetry (#341)
Browse files Browse the repository at this point in the history
* Fix #315, fully implement Telemetry for Shield study
* Also fixes #342, as an experiment wasn't necessary to check if the sidebar is open
* Move the experiment/ directory into addon/, which makes packaging easier
* Implement polling to identify if Side View is being used
* Add a null/empty add-on
  • Loading branch information
ianb authored Oct 10, 2018
1 parent 5fb3e90 commit f57c73e
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 13 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
node_modules
web-ext-artifacts
addon.xpi
addon*.xpi
addon/build
addon/manifest.json
/experiment/study
/addon/experiment/study
/null-addon/addon/experiment
.DS_Store
/Profile
4 changes: 2 additions & 2 deletions addon/background.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global TestPilotGA, buildSettings */
/* global TestPilotGA, buildSettings, shieldSetup */

const FIREFOX_VERSION = /rv:([0-9.]+)/.exec(navigator.userAgent)[1];

Expand Down Expand Up @@ -47,7 +47,7 @@ async function sendEvent(args) {
return;
}
if (isShield) {
console.info("Aborting event for Shield");
shieldSetup.sendShieldEvent(args);
return;
}
if (args.forUrl || sidebarUrl) {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 8 additions & 5 deletions addon/manifest.json.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@
"experiment_apis": {
{{#SHIELD}}
"study": {
"schema": "../experiment/study/schema.json",
"schema": "./experiment/study/schema.json",
"parent": {
"scopes": ["addon_parent"],
"script": "../experiment/study/api.js",
"paths": [["study", "studyDebug"]]
"script": "./experiment/study/api.js",
"paths": [["study"]]
}
},
{{/SHIELD}}
"sideview": {
"schema": "../experiment/schema.json",
"schema": "./experiment/schema.json",
"parent": {
"scopes": ["addon_parent"],
"script": "../experiment/api.js",
"script": "./experiment/api.js",
"paths": [["sideview"]]
}
}
Expand All @@ -46,6 +46,9 @@
{{^SHIELD_OR_AMO}}
"build/testpilot-ga.js",
{{/SHIELD_OR_AMO}}
{{#SHIELD}}
"shield-setup.js",
{{/SHIELD}}
"background.js"
]
},
Expand Down
93 changes: 93 additions & 0 deletions addon/shield-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
this.shieldSetup = (function () {

// Every CHECK_SIDEBAR_PERIOD we see if the sidebar is open, and send a usage telemetry if it is
// We also look for any normal events
const CHECK_SIDEBAR_PERIOD = 1000 * 60 * 60; // 1 hour
// And then if we find something, we send a telemetry event, but only this often:
const SEND_OPEN_TELEMETRY_LIMIT = 1000 * 60 * 60 * 24; // 1 day
let exports = {};

exports.sendShieldEvent = async function(args) {
if (args.ec === "startup") {
browser.study.sendTelemetry({message: "addon_init"});
} else if (args.ea === "load-url") {
// Any kind of load event uses ea=load-url (pageAction, browserAction, contextMenu, etc)
try {
flagUsed();
await browser.study.sendTelemetry({message: "uri_to_sv", uri_sent: "true"});
} catch (e) {
console.warn("Failure in sendTelemetry:", String(e), e.stack);
}
}
};

let lastUsed = null;

function flagUsed() {
if (!lastUsed || Date.now() - lastUsed >= SEND_OPEN_TELEMETRY_LIMIT) {
browser.study.sendTelemetry({message: "panel_used_today", panel_used: "true"});
lastUsed = Date.now();
}
}

setInterval(async () => {
if (await browser.sidebarAction.isOpen({})) {
flagUsed();
}
}, CHECK_SIDEBAR_PERIOD);

async function init() {
try {
await browser.study.setup({
activeExperimentName: "side-view-1", // Note: the control add-on must have the same activeExperimentName
studyType: "shield",
telemetry: {
send: true,
// Marks pings with testing=true. Set flag to `true` before final release
removeTestingFlag: false,
},
endings: {
/** standard endings */
"user-disable": {
baseUrls: [
"https://qsurvey.mozilla.com/s3/side-view-shield-study/?reason=user-disable",
],
},
ineligible: {
baseUrls: [],
},
expired: {
baseUrls: [
"https://qsurvey.mozilla.com/s3/side-view-shield-study/?reason=expired",
],
},
/** Study specific endings */
"user-used-the-feature": {
baseUrls: [
// FIXME: do we want this?
// If we do, we have to use browser.study.endStudy("user-used-the-feature")
"https://qsurvey.mozilla.com/s3/side-view-shield-study/?reason=user-used-the-feature",
],
category: "ended-positive",
},
},
weightedVariations: [
{
name: "feature-active",
weight: 1,
},
],
// maximum time that the study should run, from the first run
expire: {
days: 365,
},
});
} catch (e) {
console.warn("Error in Shield init():", String(e), e.stack);
}
}

init();

return exports;
})();
13 changes: 13 additions & 0 deletions null-addon/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Null Add-on

This is a temporary add-on we are using for the control in a [Shield study](https://wiki.mozilla.org/Firefox/Shield)

## Installation

You can build an XPI with the command:

```sh
npm run package-null
```

This creates `addon-null.xpi`
30 changes: 30 additions & 0 deletions null-addon/addon/background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
async function init() {
try {
await browser.study.setup({
activeExperimentName: "side-view-1", // Note: the control add-on must have the same activeExperimentName
studyType: "shield",
telemetry: {
send: true,
// Marks pings with testing=true. Set flag to `true` before final release
removeTestingFlag: false,
},
endings: {
},
weightedVariations: [
{
name: "control",
weight: 1,
},
],
// maximum time that the study should run, from the first run
expire: {
days: 365,
},
});
browser.study.sendTelemetry({message: "addon_control_init"});
} catch (e) {
console.warn("Error in Shield init():", String(e), e.stack);
}
}

init();
33 changes: 33 additions & 0 deletions null-addon/addon/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"manifest_version": 2,
"name": "Side View Control",
"version": "0.1",
"description": "This is an empty add-on that has no functionality",
"icons": {
// "48": "side-view.png",
// "96": "side-view.png"
},
"author": "Mozilla (https://mozilla.org/)",
"homepage_url": "https://github.com/mozilla/side-view/",
"applications": {
"gecko": {
"id": "[email protected]",
"strict_min_version": "57.0a1"
}
},
"experiment_apis": {
"study": {
"schema": "./experiment/study/schema.json",
"parent": {
"scopes": ["addon_parent"],
"script": "./experiment/study/api.js",
"paths": [["study"]]
}
}
},
"background": {
"scripts": [
"background.js"
]
}
}
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,18 @@
"lint:styles": "stylelint ./addon/*.css",
"build": "npm-run-all build:*",
"build:ga": "mkdir -p addon/build && cp $(node -e 'console.log(require.resolve(\"testpilot-ga\"))') addon/build/testpilot-ga.js",
"build:testutils": "if [[ -n \"$SHIELD\" ]] ; then copyStudyUtils ./experiment/ ; else rm -rf ./experiment/study/ ; fi",
"build:testutils": "if [[ -n \"$SHIELD\" ]] ; then copyStudyUtils ./addon/experiment/ ; else rm -rf ./addon/experiment/study/ ; fi",
"build:manifest": "node -e 'let input = JSON.parse(fs.readFileSync(\"package.json\")); input.version = input.version.slice(0, -1) + Math.floor((Date.now() - new Date(new Date().getFullYear().toString()).getTime()) / 3600000); Object.assign(input, process.env); input.SHIELD_OR_AMO = input.SHIELD || input.IS_AMO ; console.log(JSON.stringify(input))' | mustache - addon/manifest.json.tmpl > addon/manifest.json",
"build:buildSettings": "node -e 'console.log(JSON.stringify(process.env))' | mustache - addon/buildSettings.js.tmpl > addon/build/buildSettings.js",
"build:web-ext": "web-ext build --source-dir=addon --overwrite-dest --ignore-files '*.tmpl' && zip -r web-ext-artifacts/`ls -t1 web-ext-artifacts | head -n 1` experiment",
"build:web-ext": "web-ext build --source-dir=addon --overwrite-dest --ignore-files '*.tmpl'",
"build-amo": "npm-run-all build-amo:*",
"build-amo:buildSettings": "IS_AMO=1 npm-run-all build:buildSettings build:manifest",
"build-amo:web-ext": "web-ext build --source-dir=addon --overwrite-dest --ignore-files '*.tmpl' --ignore-files 'build/testpilot-ga.js'",
"build-null": "copyStudyUtils ./null-addon/addon/experiment/ && web-ext build --source-dir=null-addon/addon/ --overwrite-dest",
"package": "npm run build && cp web-ext-artifacts/`ls -t1 web-ext-artifacts | head -n 1` addon.xpi",
"package-amo": "npm run build-amo && cp web-ext-artifacts/`ls -t1 web-ext-artifacts | head -n 1` addon.xpi",
"run": "mkdir -p ./Profile && web-ext run --source-dir=addon -p ./Profile --browser-console --keep-profile-changes -f nightly",
"package-amo": "npm run build-amo && cp web-ext-artifacts/`ls -t1 web-ext-artifacts | head -n 1` addon-amo.xpi",
"package-null": "npm run build-null && cp web-ext-artifacts/`ls -t1 web-ext-artifacts | head -n 1` addon-null.xpi",
"run": "mkdir -p ./Profile && web-ext run --source-dir=addon -p ./Profile --browser-console --keep-profile-changes -f nightly --pref=shieldStudy.logLevel=All",
"test": "npm run lint"
}
}

0 comments on commit f57c73e

Please sign in to comment.