Bug 928969 - Telemetry infrastructure for Shumway. r=till

This commit is contained in:
Yury Delendik 2013-10-21 10:59:43 -05:00
parent d096ae1b2a
commit a5e0799345
6 changed files with 247 additions and 7 deletions

View File

@ -41,6 +41,9 @@ Cu.import('resource://gre/modules/NetUtil.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'PrivateBrowsingUtils',
'resource://gre/modules/PrivateBrowsingUtils.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'ShumwayTelemetry',
'resource://shumway/ShumwayTelemetry.jsm');
let appInfo = Cc['@mozilla.org/xre/app-info;1'].getService(Ci.nsIXULAppInfo);
let Svc = {};
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
@ -196,6 +199,12 @@ function ChromeActions(url, window, document) {
this.externalComInitialized = false;
this.allowScriptAccess = false;
this.crossdomainRequestsCache = Object.create(null);
this.telemetry = {
startTime: Date.now(),
features: [],
errors: [],
pageIndex: 0
};
}
ChromeActions.prototype = {
@ -334,12 +343,14 @@ ChromeActions.prototype = {
}
});
},
fallback: function() {
fallback: function(automatic) {
var obj = this.window.frameElement;
var doc = obj.ownerDocument;
var e = doc.createEvent("CustomEvent");
e.initCustomEvent("MozPlayPlugin", true, true, null);
obj.dispatchEvent(e);
ShumwayTelemetry.onFallback(!automatic);
},
setClipboard: function (data) {
if (typeof data !== 'string' ||
@ -365,6 +376,45 @@ ChromeActions.prototype = {
ActivationQueue.activateNext();
}
},
reportTelemetry: function (data) {
var topic = data.topic;
switch (topic) {
case 'firstFrame':
var time = Date.now() - this.telemetry.startTime;
ShumwayTelemetry.onFirstFrame(time);
break;
case 'parseInfo':
ShumwayTelemetry.onParseInfo({
parseTime: +data.parseTime,
size: +data.bytesTotal,
swfVersion: data.swfVersion|0,
frameRate: +data.frameRate,
width: data.width|0,
height: data.height|0,
bannerType: data.bannerType|0,
isAvm2: !!data.isAvm2
});
break;
case 'feature':
var featureType = data.feature|0;
var MIN_FEATURE_TYPE = 0, MAX_FEATURE_TYPE = 999;
if (featureType >= MIN_FEATURE_TYPE && featureType <= MAX_FEATURE_TYPE &&
!this.telemetry.features[featureType]) {
this.telemetry.features[featureType] = true; // record only one feature per SWF
ShumwayTelemetry.onFeature(featureType);
}
break;
case 'error':
var errorType = data.error|0;
var MIN_ERROR_TYPE = 0, MAX_ERROR_TYPE = 2;
if (errorType >= MIN_ERROR_TYPE && errorType <= MAX_ERROR_TYPE &&
!this.telemetry.errors[errorType]) {
this.telemetry.errors[errorType] = true; // record only one report per SWF
ShumwayTelemetry.onError(errorType);
}
break;
}
},
externalCom: function (data) {
if (!this.allowScriptAccess)
return;
@ -452,6 +502,14 @@ var ActivationQueue = {
this.activateNext();
}
},
findLastOnPage: function ActivationQueue_findLastOnPage(baseUrl) {
for (var i = this.nonActive.length - 1; i >= 0; i--) {
if (this.nonActive[i].baseUrl === baseUrl) {
return this.nonActive[i];
}
}
return null;
},
activateNext: function ActivationQueue_activateNext() {
function weightInstance(actions) {
// set of heuristics for find the most important instance to load
@ -814,10 +872,21 @@ ShumwayStreamConverterBase.prototype = {
domWindow.document,
converter.getUrlHint(originalURI));
if (!isShumwayEnabledFor(actions)) {
actions.fallback();
actions.fallback(true);
return;
}
// Report telemetry on amount of swfs on the page
if (actions.isOverlay) {
// Looking for last actions with same baseUrl
var prevPageActions = ActivationQueue.findLastOnPage(actions.baseUrl);
var pageIndex = !prevPageActions ? 1 : (prevPageActions.telemetry.pageIndex + 1);
actions.telemetry.pageIndex = pageIndex;
ShumwayTelemetry.onPageIndex(pageIndex);
} else {
ShumwayTelemetry.onPageIndex(0);
}
actions.activationCallback = function(domWindow, isSimpleMode) {
delete this.activationCallback;
activateShumwayScripts(domWindow, isSimpleMode);

View File

@ -0,0 +1,73 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Copyright 2013 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* jshint esnext:true */
'use strict';
this.EXPORTED_SYMBOLS = ['ShumwayTelemetry'];
const Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
const BANNER_SIZES = [
"88x31", "120x60", "120x90", "120x240", "120x600", "125x125", "160x600",
"180x150", "234x60", "240x400", "250x250", "300x100", "300x250", "300x600",
"300x1050", "336x280", "468x60", "550x480", "720x100", "728x90", "970x90",
"970x250"];
function getBannerType(width, height) {
return BANNER_SIZES.indexOf(width + 'x' + height) + 1;
}
this.ShumwayTelemetry = {
onFirstFrame: function (timeToDisplay) {
var histogram = Services.telemetry.getHistogramById("SHUMWAY_TIME_TO_VIEW_MS");
histogram.add(timeToDisplay);
},
onParseInfo: function (parseInfo) {
var histogram = Services.telemetry.getHistogramById("SHUMWAY_PARSING_MS");
histogram.add(parseInfo.parseTime);
var histogram = Services.telemetry.getHistogramById("SHUMWAY_SWF_SIZE_KB");
histogram.add(parseInfo.size / 1024);
var histogram = Services.telemetry.getHistogramById("SHUMWAY_SWF_VERSION");
histogram.add(parseInfo.swfVersion);
var histogram = Services.telemetry.getHistogramById("SHUMWAY_SWF_FRAME_RATE");
histogram.add(parseInfo.frameRate);
var histogram = Services.telemetry.getHistogramById("SHUMWAY_SWF_AREA");
histogram.add(parseInfo.width * parseInfo.height);
var histogram = Services.telemetry.getHistogramById("SHUMWAY_SWF_BANNER");
histogram.add(getBannerType(parseInfo.width, parseInfo.height));
var histogram = Services.telemetry.getHistogramById("SHUMWAY_SWF_AVM2");
histogram.add(parseInfo.isAvm2);
},
onError: function (errorType) {
var histogram = Services.telemetry.getHistogramById("SHUMWAY_ERROR");
histogram.add(errorType);
},
onPageIndex: function (pageIndex) {
var histogram = Services.telemetry.getHistogramById("SHUMWAY_SWF_INDEX_ON_PAGE");
histogram.add(pageIndex);
},
onFeature: function (featureType) {
var histogram = Services.telemetry.getHistogramById("SHUMWAY_FEATURE_USED");
histogram.add(featureType);
},
onFallback: function (userAction) {
var histogram = Services.telemetry.getHistogramById("SHUMWAY_FALLBACK");
histogram.add(userAction);
}
};

View File

@ -435,6 +435,12 @@ QuadTree.prototype._subdivide = function () {
this.nodes[2] = new QuadTree(this.x, midY, halfWidth, halfHeight, level);
this.nodes[3] = new QuadTree(midX, midY, halfWidth, halfHeight, level);
};
var EXTERNAL_INTERFACE_FEATURE = 1;
var CLIPBOARD_FEATURE = 2;
var SHAREDOBJECT_FEATURE = 3;
var VIDEO_FEATURE = 4;
var SOUND_FEATURE = 5;
var NETCONNECTION_FEATURE = 6;
var create = Object.create;
var defineProperty = Object.defineProperty;
var keys = Object.keys;
@ -3494,8 +3500,23 @@ var LoaderDefinition = function () {
},
oncomplete: function (result) {
commitData(result);
var stats;
if (typeof result.swfVersion === 'number') {
var bbox = result.bbox;
stats = {
topic: 'parseInfo',
parseTime: result.parseTime,
bytesTotal: result.bytesTotal,
swfVersion: result.swfVersion,
frameRate: result.frameRate,
width: (bbox.xMax - bbox.xMin) / 20,
height: (bbox.yMax - bbox.yMin) / 20,
isAvm2: !(!result.fileAttributes.doAbc)
};
}
commitData({
command: 'complete'
command: 'complete',
stats: stats
});
}
};
@ -3610,6 +3631,10 @@ var LoaderDefinition = function () {
Promise.when(frameConstructed, this._lastPromise).then(function () {
this.contentLoaderInfo._dispatchEvent('complete');
}.bind(this));
var stats = data.stats;
if (stats) {
TelemetryService.reportTelemetry(stats);
}
this._worker && this._worker.terminate();
break;
case 'empty':
@ -6438,7 +6463,8 @@ CompressedPipe.prototype = {
};
function BodyParser(swfVersion, length, options) {
this.swf = {
swfVersion: swfVersion
swfVersion: swfVersion,
parseTime: 0
};
this.buffer = new HeadTailBuffer(32768);
this.initialize = true;
@ -6489,7 +6515,9 @@ BodyParser.prototype = {
swf.bytesLoaded = progressInfo.bytesLoaded;
swf.bytesTotal = progressInfo.bytesTotal;
}
var readStartTime = Date.now();
readTags(swf, stream, swfVersion, options.onprogress);
swf.parseTime += Date.now() - readStartTime;
var read = stream.pos;
buffer.removeHead(read);
this.totalRead += read;

View File

@ -7668,7 +7668,8 @@ CompressedPipe.prototype = {
};
function BodyParser(swfVersion, length, options) {
this.swf = {
swfVersion: swfVersion
swfVersion: swfVersion,
parseTime: 0
};
this.buffer = new HeadTailBuffer(32768);
this.initialize = true;
@ -7719,7 +7720,9 @@ BodyParser.prototype = {
swf.bytesLoaded = progressInfo.bytesLoaded;
swf.bytesTotal = progressInfo.bytesTotal;
}
var readStartTime = Date.now();
readTags(swf, stream, swfVersion, options.onprogress);
swf.parseTime += Date.now() - readStartTime;
var read = stream.pos;
buffer.removeHead(read);
this.totalRead += read;
@ -9272,6 +9275,11 @@ function interpretActions(actionsData, scopeContainer, constantPool, registers)
if (e instanceof AS2Error) {
throw e;
}
var AVM1_ERROR_TYPE = 1;
TelemetryService.reportTelemetry({
topic: 'error',
error: AVM1_ERROR_TYPE
});
stream.position = nextPosition;
if (stackItemsExpected > 0) {
while (stackItemsExpected--) {
@ -39173,6 +39181,12 @@ QuadTree.prototype._subdivide = function () {
this.nodes[2] = new QuadTree(this.x, midY, halfWidth, halfHeight, level);
this.nodes[3] = new QuadTree(midX, midY, halfWidth, halfHeight, level);
};
var EXTERNAL_INTERFACE_FEATURE = 1;
var CLIPBOARD_FEATURE = 2;
var SHAREDOBJECT_FEATURE = 3;
var VIDEO_FEATURE = 4;
var SOUND_FEATURE = 5;
var NETCONNECTION_FEATURE = 6;
{
var BitmapDefinition = function () {
function setBitmapData(value) {
@ -41341,8 +41355,23 @@ var LoaderDefinition = function () {
},
oncomplete: function (result) {
commitData(result);
var stats;
if (typeof result.swfVersion === 'number') {
var bbox = result.bbox;
stats = {
topic: 'parseInfo',
parseTime: result.parseTime,
bytesTotal: result.bytesTotal,
swfVersion: result.swfVersion,
frameRate: result.frameRate,
width: (bbox.xMax - bbox.xMin) / 20,
height: (bbox.yMax - bbox.yMin) / 20,
isAvm2: !(!result.fileAttributes.doAbc)
};
}
commitData({
command: 'complete'
command: 'complete',
stats: stats
});
}
};
@ -41457,6 +41486,10 @@ var LoaderDefinition = function () {
Promise.when(frameConstructed, this._lastPromise).then(function () {
this.contentLoaderInfo._dispatchEvent('complete');
}.bind(this));
var stats = data.stats;
if (stats) {
TelemetryService.reportTelemetry(stats);
}
this._worker && this._worker.terminate();
break;
case 'empty':
@ -42567,6 +42600,11 @@ var MovieClipDefinition = function () {
scripts[i].call(this);
}
} catch (e) {
var AVM2_ERROR_TYPE = 2;
TelemetryService.reportTelemetry({
topic: 'error',
error: AVM2_ERROR_TYPE
});
if (false) {
console.error('error ' + e + ', stack: \n' + e.stack);
}
@ -44459,6 +44497,10 @@ var TimerEventDefinition = function () {
_initJS: function _initJS() {
if (initialized)
return;
TelemetryService.reportTelemetry({
topic: 'feature',
feature: EXTERNAL_INTERFACE_FEATURE
});
initialized = true;
FirefoxCom.initJS(callIn);
},
@ -45453,6 +45495,10 @@ var SoundDefinition = function () {
});
this._soundData = soundData;
}
TelemetryService.reportTelemetry({
topic: 'feature',
feature: SOUND_FEATURE
});
},
close: function close() {
somewhatImplemented('Sound.close');
@ -46208,6 +46254,10 @@ var StageVideoDefinition = function () {
var VideoDefinition = function () {
var def = {
initialize: function initialize() {
TelemetryService.reportTelemetry({
topic: 'feature',
feature: VIDEO_FEATURE
});
},
attachNetStream: function (netStream) {
this._netStream = netStream;
@ -46365,6 +46415,10 @@ var NetConnectionDefinition = function () {
return {
__class__: 'flash.net.NetConnection',
initialize: function () {
TelemetryService.reportTelemetry({
topic: 'feature',
feature: NETCONNECTION_FEATURE
});
},
_invoke: function (index, args) {
var simulated = false, result;
@ -46981,6 +47035,10 @@ var SharedObjectDefinition = function () {
this._objectEncoding = _defaultObjectEncoding;
this._data[Multiname.getPublicQualifiedName('levelCompleted')] = 32;
this._data[Multiname.getPublicQualifiedName('completeLevels')] = 32;
TelemetryService.reportTelemetry({
topic: 'feature',
feature: SHAREDOBJECT_FEATURE
});
},
__glue__: {
native: {
@ -47622,6 +47680,10 @@ var SystemDefinition = function () {
static: {
setClipboard: function setClipboard(string) {
FirefoxCom.request('setClipboard', string);
TelemetryService.reportTelemetry({
topic: 'feature',
feature: CLIPBOARD_FEATURE
});
},
pause: function pause() {
notImplemented('System.pause');

View File

@ -1 +1 @@
0.7.352
0.7.354

View File

@ -159,6 +159,12 @@ window.addEventListener("message", function handlerMessage(e) {
}
}, true);
var TelemetryService = {
reportTelemetry: function (data) {
FirefoxCom.request('reportTelemetry', data, null);
}
};
var FileLoadingService = {
get baseUrl() { return movieUrl; },
nextSessionId: 1, // 0 - is reserved
@ -247,6 +253,8 @@ function frame(e) {
// marking that movie is started
document.body.classList.add("started");
TelemetryService.reportTelemetry({topic: "firstFrame"});
// skipping frame 0
initializeFrameControl = false;
return;