author | Mike de Boer <mdeboer@mozilla.com> |
Tue, 24 Mar 2015 11:21:20 +0100 | |
changeset 235362 | 5c87c00175317df304dfbd6f96170d58b6f6ee69 |
parent 235361 | 6ea6b9136d588edea4123e1a052b731f37b728d1 |
child 235363 | d4a39def58114f2146efa7a363d079a1bdb6f28f |
push id | 57400 |
push user | ryanvm@gmail.com |
push date | Tue, 24 Mar 2015 15:59:13 +0000 |
treeherder | mozilla-inbound@47fa87252df0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | Standard8, vladan |
bugs | 1135095 |
milestone | 39.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/components/loop/MozLoopAPI.jsm +++ b/browser/components/loop/MozLoopAPI.jsm @@ -634,16 +634,23 @@ function injectLoopAPI(targetWindow) { TWO_WAY_MEDIA_CONN_LENGTH: { enumerable: true, get: function() { return Cu.cloneInto(TWO_WAY_MEDIA_CONN_LENGTH, targetWindow); } }, + SHARING_STATE_CHANGE: { + enumerable: true, + get: function() { + return Cu.cloneInto(SHARING_STATE_CHANGE, targetWindow); + } + }, + fxAEnabled: { enumerable: true, get: function() { return MozLoopService.fxAEnabled; }, }, logInToFxA: {
--- a/browser/components/loop/MozLoopService.jsm +++ b/browser/components/loop/MozLoopService.jsm @@ -24,30 +24,44 @@ const LOOP_SESSION_TYPE = { */ const TWO_WAY_MEDIA_CONN_LENGTH = { SHORTER_THAN_10S: "SHORTER_THAN_10S", BETWEEN_10S_AND_30S: "BETWEEN_10S_AND_30S", BETWEEN_30S_AND_5M: "BETWEEN_30S_AND_5M", MORE_THAN_5M: "MORE_THAN_5M", }; +/** + * Buckets that we segment sharing state change telemetry probes into. + * + * @type {{WINDOW_ENABLED: String, WINDOW_DISABLED: String, + * BROWSER_ENABLED: String, BROWSER_DISABLED: String}} + */ +const SHARING_STATE_CHANGE = { + WINDOW_ENABLED: "WINDOW_ENABLED", + WINDOW_DISABLED: "WINDOW_DISABLED", + BROWSER_ENABLED: "BROWSER_ENABLED", + BROWSER_DISABLED: "BROWSER_DISABLED" +}; + // See LOG_LEVELS in Console.jsm. Common examples: "All", "Info", "Warn", & "Error". const PREF_LOG_LEVEL = "loop.debug.loglevel"; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/osfile.jsm", this); Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/Timer.jsm"); Cu.import("resource://gre/modules/FxAccountsOAuthClient.jsm"); Cu.importGlobalProperties(["URL"]); -this.EXPORTED_SYMBOLS = ["MozLoopService", "LOOP_SESSION_TYPE", "TWO_WAY_MEDIA_CONN_LENGTH"]; +this.EXPORTED_SYMBOLS = ["MozLoopService", "LOOP_SESSION_TYPE", + "TWO_WAY_MEDIA_CONN_LENGTH", "SHARING_STATE_CHANGE"]; XPCOMUtils.defineLazyModuleGetter(this, "injectLoopAPI", "resource:///modules/loop/MozLoopAPI.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "convertToRTCStatsReport", "resource://gre/modules/media/RTCStatsReport.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Chat", "resource:///modules/Chat.jsm");
--- a/browser/components/loop/content/shared/js/otSdkDriver.js +++ b/browser/components/loop/content/shared/js/otSdkDriver.js @@ -160,16 +160,18 @@ loop.OTSdkDriver = (function() { } var config = _.extend(this._getCopyPublisherConfig(), options); this.screenshare = this.sdk.initPublisher(this.getScreenShareElementFunc(), config); this.screenshare.on("accessAllowed", this._onScreenShareGranted.bind(this)); this.screenshare.on("accessDenied", this._onScreenShareDenied.bind(this)); + + this._noteSharingState(options.videoSource, true); }, /** * Initiates switching the browser window that is being shared. * * @param {Integer} windowId The windowId of the browser. */ switchAcquiredWindow: function(windowId) { @@ -191,16 +193,17 @@ loop.OTSdkDriver = (function() { if (!this.screenshare) { return false; } this.session.unpublish(this.screenshare); this.screenshare.off("accessAllowed accessDenied"); this.screenshare.destroy(); delete this.screenshare; + this._noteSharingState(this._windowId ? "browser" : "window", false); delete this._windowId; return true; }, /** * Connects a session for the SDK, listening to the required events. * * sessionData items: @@ -643,25 +646,25 @@ loop.OTSdkDriver = (function() { * Wrapper for adding a keyed value that also updates * connectionLengthNoted calls and sets the twoWayMediaStartTime to * this.CONNECTION_START_TIME_ALREADY_NOTED. * * @param {number} callLengthSeconds the call length in seconds * @private */ _noteConnectionLength: function(callLengthSeconds) { + var buckets = this.mozLoop.TWO_WAY_MEDIA_CONN_LENGTH; - var bucket = this.mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.SHORTER_THAN_10S; - + var bucket = buckets.SHORTER_THAN_10S; if (callLengthSeconds >= 10 && callLengthSeconds <= 30) { - bucket = this.mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.BETWEEN_10S_AND_30S; + bucket = buckets.BETWEEN_10S_AND_30S; } else if (callLengthSeconds > 30 && callLengthSeconds <= 300) { - bucket = this.mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.BETWEEN_30S_AND_5M; + bucket = buckets.BETWEEN_30S_AND_5M; } else if (callLengthSeconds > 300) { - bucket = this.mozLoop.TWO_WAY_MEDIA_CONN_LENGTH.MORE_THAN_5M; + bucket = buckets.MORE_THAN_5M; } this.mozLoop.telemetryAddKeyedValue("LOOP_TWO_WAY_MEDIA_CONN_LENGTH", bucket); this._setTwoWayMediaStartTime(this.CONNECTION_START_TIME_ALREADY_NOTED); this._connectionLengthNotedCalls++; if (this._debugTwoWayMediaTelemetry) { @@ -700,14 +703,39 @@ loop.OTSdkDriver = (function() { var callLengthSeconds = (endTime - startTime) / 1000; this._noteConnectionLength(callLengthSeconds); }, /** * If set to true, make it easy to test/verify 2-way media connection * telemetry code operation by viewing the logs. */ - _debugTwoWayMediaTelemetry: false + _debugTwoWayMediaTelemetry: false, + + /** + * Note the sharing state. If this.mozLoop is not defined, we're assumed to + * be running in the standalone client and return immediately. + * + * @param {String} type Type of sharing that was flipped. May be 'window' + * or 'tab'. + * @param {Boolean} enabled Flag that tells us if the feature was flipped on + * or off. + * @private + */ + _noteSharingState: function(type, enabled) { + if (!this.mozLoop) { + return; + } + + var bucket = this.mozLoop.SHARING_STATE_CHANGE[type.toUpperCase() + "_" + + (enabled ? "ENABLED" : "DISABLED")]; + if (!bucket) { + console.error("No sharing state bucket found for '" + type + "'"); + return; + } + + this.mozLoop.telemetryAddKeyedValue("LOOP_SHARING_STATE_CHANGE", bucket); + } }; return OTSdkDriver; })();
--- a/browser/components/loop/test/mochitest/browser_mozLoop_telemetry.js +++ b/browser/components/loop/test/mochitest/browser_mozLoop_telemetry.js @@ -42,8 +42,34 @@ add_task(function* test_mozLoop_telemetr } let snapshot = histogram.snapshot(); is(snapshot["SHORTER_THAN_10S"].sum, 1, "TWO_WAY_MEDIA_CONN_LENGTH.SHORTER_THAN_10S"); is(snapshot["BETWEEN_10S_AND_30S"].sum, 2, "TWO_WAY_MEDIA_CONN_LENGTH.BETWEEN_10S_AND_30S"); is(snapshot["BETWEEN_30S_AND_5M"].sum, 3, "TWO_WAY_MEDIA_CONN_LENGTH.BETWEEN_30S_AND_5M"); is(snapshot["MORE_THAN_5M"].sum, 4, "TWO_WAY_MEDIA_CONN_LENGTH.MORE_THAN_5M"); }); + +add_task(function* test_mozLoop_telemetryAdd_sharing_buckets() { + let histogramId = "LOOP_SHARING_STATE_CHANGE"; + let histogram = Services.telemetry.getKeyedHistogramById(histogramId); + const SHARING_STATES = gMozLoopAPI.SHARING_STATE_CHANGE; + + histogram.clear(); + for (let value of [SHARING_STATES.WINDOW_ENABLED, + SHARING_STATES.WINDOW_DISABLED, + SHARING_STATES.WINDOW_DISABLED, + SHARING_STATES.BROWSER_ENABLED, + SHARING_STATES.BROWSER_ENABLED, + SHARING_STATES.BROWSER_ENABLED, + SHARING_STATES.BROWSER_DISABLED, + SHARING_STATES.BROWSER_DISABLED, + SHARING_STATES.BROWSER_DISABLED, + SHARING_STATES.BROWSER_DISABLED]) { + gMozLoopAPI.telemetryAddKeyedValue(histogramId, value); + } + + let snapshot = histogram.snapshot(); + Assert.strictEqual(snapshot["WINDOW_ENABLED"].sum, 1, "SHARING_STATE_CHANGE.WINDOW_ENABLED"); + Assert.strictEqual(snapshot["WINDOW_DISABLED"].sum, 2, "SHARING_STATE_CHANGE.WINDOW_DISABLED"); + Assert.strictEqual(snapshot["BROWSER_ENABLED"].sum, 3, "SHARING_STATE_CHANGE.BROWSER_ENABLED"); + Assert.strictEqual(snapshot["BROWSER_DISABLED"].sum, 4, "SHARING_STATE_CHANGE.BROWSER_DISABLED"); +});
--- a/browser/components/loop/test/shared/otSdkDriver_test.js +++ b/browser/components/loop/test/shared/otSdkDriver_test.js @@ -66,16 +66,22 @@ describe("loop.OTSdkDriver", function () mozLoop = { telemetryAddKeyedValue: sinon.stub(), TWO_WAY_MEDIA_CONN_LENGTH: { SHORTER_THAN_10S: "SHORTER_THAN_10S", BETWEEN_10S_AND_30S: "BETWEEN_10S_AND_30S", BETWEEN_30S_AND_5M: "BETWEEN_30S_AND_5M", MORE_THAN_5M: "MORE_THAN_5M" + }, + SHARING_STATE_CHANGE: { + WINDOW_ENABLED: "WINDOW_ENABLED", + WINDOW_DISABLED: "WINDOW_DISABLED", + BROWSER_ENABLED: "BROWSER_ENABLED", + BROWSER_DISABLED: "BROWSER_DISABLED" } }; driver = new loop.OTSdkDriver({ dispatcher: dispatcher, sdk: sdk, mozLoop: mozLoop, isDesktop: true @@ -184,16 +190,17 @@ describe("loop.OTSdkDriver", function () }); }); describe("#startScreenShare", function() { var fakeElement; beforeEach(function() { sandbox.stub(dispatcher, "dispatch"); + sandbox.stub(driver, "_noteSharingState"); fakeElement = { className: "fakeVideo" }; driver.getScreenShareElementFunc = function() { return fakeElement; }; @@ -209,16 +216,29 @@ describe("loop.OTSdkDriver", function () scrollWithPage: true } }; driver.startScreenShare(options); sinon.assert.calledOnce(sdk.initPublisher); sinon.assert.calledWithMatch(sdk.initPublisher, fakeElement, options); }); + + it("should log a telemetry action", function() { + var options = { + videoSource: "browser", + constraints: { + browserWindow: 42, + scrollWithPage: true + } + }; + driver.startScreenShare(options); + + sinon.assert.calledWithExactly(driver._noteSharingState, "browser", true); + }); }); describe("#switchAcquiredWindow", function() { beforeEach(function() { var options = { videoSource: "browser", constraints: { browserWindow: 42, @@ -246,36 +266,80 @@ describe("loop.OTSdkDriver", function () sinon.assert.notCalled(publisher._.switchAcquiredWindow); }); }); describe("#endScreenShare", function() { beforeEach(function() { driver.getScreenShareElementFunc = function() {}; + sandbox.stub(dispatcher, "dispatch"); + sandbox.stub(driver, "_noteSharingState"); + }); + + it("should unpublish the share", function() { driver.startScreenShare({ videoSource: "window" }); - - sandbox.stub(dispatcher, "dispatch"); + driver.session = session; - driver.session = session; - }); - - it("should unpublish the share", function() { driver.endScreenShare(new sharedActions.EndScreenShare()); sinon.assert.calledOnce(session.unpublish); }); + it("should log a telemetry action", function() { + driver.startScreenShare({ + videoSource: "window" + }); + driver.session = session; + + driver.endScreenShare(new sharedActions.EndScreenShare()); + + sinon.assert.calledWithExactly(driver._noteSharingState, "window", false); + }); + it("should destroy the share", function() { + driver.startScreenShare({ + videoSource: "window" + }); + driver.session = session; + expect(driver.endScreenShare()).to.equal(true); sinon.assert.calledOnce(publisher.destroy); }); + + it("should unpublish the share too when type is 'browser'", function() { + driver.startScreenShare({ + videoSource: "browser", + constraints: { + browserWindow: 42 + } + }); + driver.session = session; + + driver.endScreenShare(new sharedActions.EndScreenShare()); + + sinon.assert.calledOnce(session.unpublish); + }); + + it("should log a telemetry action too when type is 'browser'", function() { + driver.startScreenShare({ + videoSource: "browser", + constraints: { + browserWindow: 42 + } + }); + driver.session = session; + + driver.endScreenShare(new sharedActions.EndScreenShare()); + + sinon.assert.calledWithExactly(driver._noteSharingState, "browser", false); + }); }); describe("#connectSession", function() { it("should initialise a new session", function() { driver.connectSession(sessionData); sinon.assert.calledOnce(sdk.initSession); sinon.assert.calledWithExactly(sdk.initSession, "3216549870"); @@ -426,16 +490,54 @@ describe("loop.OTSdkDriver", function () driver._isDesktop = false; driver._noteConnectionLengthIfNeeded(startTimeMS, endTimeMS); sinon.assert.notCalled(mozLoop.telemetryAddKeyedValue); }); }); + describe("#_noteSharingState", function() { + it("should record enabled sharing states for window", function() { + driver._noteSharingState("window", true); + + sinon.assert.calledOnce(mozLoop.telemetryAddKeyedValue); + sinon.assert.calledWithExactly(mozLoop.telemetryAddKeyedValue, + "LOOP_SHARING_STATE_CHANGE", + mozLoop.SHARING_STATE_CHANGE.WINDOW_ENABLED); + }); + + it("should record enabled sharing states for browser", function() { + driver._noteSharingState("browser", true); + + sinon.assert.calledOnce(mozLoop.telemetryAddKeyedValue); + sinon.assert.calledWithExactly(mozLoop.telemetryAddKeyedValue, + "LOOP_SHARING_STATE_CHANGE", + mozLoop.SHARING_STATE_CHANGE.BROWSER_ENABLED); + }); + + it("should record disabled sharing states for window", function() { + driver._noteSharingState("window", false); + + sinon.assert.calledOnce(mozLoop.telemetryAddKeyedValue); + sinon.assert.calledWithExactly(mozLoop.telemetryAddKeyedValue, + "LOOP_SHARING_STATE_CHANGE", + mozLoop.SHARING_STATE_CHANGE.WINDOW_DISABLED); + }); + + it("should record disabled sharing states for browser", function() { + driver._noteSharingState("browser", false); + + sinon.assert.calledOnce(mozLoop.telemetryAddKeyedValue); + sinon.assert.calledWithExactly(mozLoop.telemetryAddKeyedValue, + "LOOP_SHARING_STATE_CHANGE", + mozLoop.SHARING_STATE_CHANGE.BROWSER_DISABLED); + }); + }); + describe("#forceDisconnectAll", function() { it("should not disconnect anything when not connected", function() { driver.session = session; driver.forceDisconnectAll(function() {}); sinon.assert.notCalled(session.forceDisconnect); });
--- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -7282,16 +7282,24 @@ }, "LOOP_TWO_WAY_MEDIA_CONN_LENGTH": { "expires_in_version": "43", "kind": "count", "keyed": true, "releaseChannelCollection": "opt-out", "description": "Connection length for bi-directionally connected media" }, + "LOOP_SHARING_STATE_CHANGE": { + "alert_emails": ["firefox-dev@mozilla.org", "mdeboer@mozilla.com"], + "expires_in_version": "43", + "kind": "count", + "keyed": true, + "releaseChannelCollection": "opt-in", + "description": "Number of times the sharing feature has been enabled and disabled" + }, "E10S_AUTOSTART": { "expires_in_version": "never", "kind": "boolean", "description": "Whether a session is set to autostart e10s windows" }, "E10S_WINDOW": { "expires_in_version": "never", "kind": "boolean",