mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge fx-team to central, a=merge
This commit is contained in:
commit
f969d53eca
@ -1292,11 +1292,11 @@ DownloadsPlacesView.prototype = {
|
||||
goUpdateCommand("downloadsCmd_clearDownloads");
|
||||
break;
|
||||
default: {
|
||||
// Slicing the array to get a freezed list of selected items. Otherwise,
|
||||
// the selectedItems array is live and doCommand may alter the selection
|
||||
// while we are trying to do one particular action, like removing items
|
||||
// from history.
|
||||
let selectedElements = this._richlistbox.selectedItems.slice();
|
||||
// Cloning the nodelist into an array to get a frozen list of selected items.
|
||||
// Otherwise, the selectedItems nodelist is live and doCommand may alter the
|
||||
// selection while we are trying to do one particular action, like removing
|
||||
// items from history.
|
||||
let selectedElements = [... this._richlistbox.selectedItems];
|
||||
for (let element of selectedElements) {
|
||||
element._shell.doCommand(aCommand);
|
||||
}
|
||||
|
@ -72,6 +72,9 @@ const MESSAGES = [
|
||||
// A crashed tab was revived by navigating to a different page. Remove its
|
||||
// browser from the list of crashed browsers to stop ignoring its messages.
|
||||
"SessionStore:crashedTabRevived",
|
||||
|
||||
// The content script encountered an error.
|
||||
"SessionStore:error",
|
||||
];
|
||||
|
||||
// The list of messages we accept from <xul:browser>s that have no tab
|
||||
@ -85,6 +88,9 @@ const NOTAB_MESSAGES = new Set([
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:update",
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:error",
|
||||
]);
|
||||
|
||||
// The list of messages we accept without an "epoch" parameter.
|
||||
@ -95,6 +101,9 @@ const NOEPOCH_MESSAGES = new Set([
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:crashedTabRevived",
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:error",
|
||||
]);
|
||||
|
||||
// The list of messages we want to receive even during the short period after a
|
||||
@ -106,6 +115,9 @@ const CLOSED_MESSAGES = new Set([
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:update",
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:error",
|
||||
]);
|
||||
|
||||
// These are tab events that we listen to.
|
||||
@ -808,6 +820,9 @@ var SessionStoreInternal = {
|
||||
case "SessionStore:crashedTabRevived":
|
||||
this._crashedBrowsers.delete(browser.permanentKey);
|
||||
break;
|
||||
case "SessionStore:error":
|
||||
this.reportInternalError(data);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`received unknown message '${aMessage.name}'`);
|
||||
break;
|
||||
@ -3848,6 +3863,19 @@ var SessionStoreInternal = {
|
||||
*/
|
||||
resetEpoch(browser) {
|
||||
this._browserEpochs.delete(browser.permanentKey);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle an error report from a content process.
|
||||
*/
|
||||
reportInternalError(data) {
|
||||
// For the moment, we only report errors through Telemetry.
|
||||
if (data.telemetry) {
|
||||
for (let key of Object.keys(data.telemetry)) {
|
||||
let histogram = Telemetry.getHistogramById(key);
|
||||
histogram.add(data.telemetry[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -29,10 +29,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "SessionHistory",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
|
||||
"resource:///modules/sessionstore/SessionStorage.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsISyncMessageSender");
|
||||
|
||||
Cu.import("resource:///modules/sessionstore/FrameTree.jsm", this);
|
||||
var gFrameTree = new FrameTree(this);
|
||||
|
||||
@ -692,12 +688,21 @@ var MessageQueue = {
|
||||
FX_SESSION_RESTORE_CONTENT_COLLECT_DATA_LONGEST_OP_MS: durationMs
|
||||
}
|
||||
|
||||
// Send all data to the parent process.
|
||||
sendMessage("SessionStore:update", {
|
||||
id: this._id, data, telemetry, flushID,
|
||||
isFinal: options.isFinal || false,
|
||||
epoch: gCurrentEpoch
|
||||
});
|
||||
try {
|
||||
// Send all data to the parent process.
|
||||
sendMessage("SessionStore:update", {
|
||||
id: this._id, data, telemetry, flushID,
|
||||
isFinal: options.isFinal || false,
|
||||
epoch: gCurrentEpoch
|
||||
});
|
||||
} catch (ex if ex && ex.result == Cr.NS_ERROR_OUT_OF_MEMORY) {
|
||||
let telemetry = {
|
||||
FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM: 1
|
||||
};
|
||||
sendMessage("SessionStore:error", {
|
||||
telemetry
|
||||
});
|
||||
}
|
||||
|
||||
// Increase our unique message ID.
|
||||
this._id++;
|
||||
|
@ -211,3 +211,4 @@ skip-if = true
|
||||
skip-if = os == "mac"
|
||||
|
||||
[browser_911547.js]
|
||||
[browser_send_async_message_oom.js]
|
||||
|
@ -0,0 +1,71 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
|
||||
const HISTOGRAM_NAME = "FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM";
|
||||
|
||||
/**
|
||||
* Test that an OOM in sendAsyncMessage in a framescript will be reported
|
||||
* to Telemetry.
|
||||
*/
|
||||
|
||||
add_task(function* init() {
|
||||
Services.telemetry.canRecordExtended = true;
|
||||
});
|
||||
|
||||
function frameScript() {
|
||||
// Make send[A]syncMessage("SessionStore:update", ...) simulate OOM.
|
||||
// Other operations are unaffected.
|
||||
let mm = docShell.sameTypeRootTreeItem.
|
||||
QueryInterface(Ci.nsIDocShell).
|
||||
QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIContentFrameMessageManager);
|
||||
|
||||
let wrap = function(original) {
|
||||
return function(name, ...args) {
|
||||
if (name != "SessionStore:update") {
|
||||
return original(name, ...args);
|
||||
}
|
||||
throw new Components.Exception("Simulated OOM", Cr.NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
mm.sendAsyncMessage = wrap(mm.sendAsyncMessage);
|
||||
mm.sendSyncMessage = wrap(mm.sendSyncMessage);
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
// Capture original state.
|
||||
let snapshot = Services.telemetry.getHistogramById(HISTOGRAM_NAME).snapshot();
|
||||
|
||||
// Open a browser, configure it to cause OOM.
|
||||
let newTab = gBrowser.addTab("about:robots");
|
||||
let browser = newTab.linkedBrowser;
|
||||
yield ContentTask.spawn(browser, null, frameScript);
|
||||
|
||||
|
||||
let promiseReported = new Promise(resolve => {
|
||||
browser.messageManager.addMessageListener("SessionStore:error", resolve);
|
||||
});
|
||||
|
||||
// Attempt to flush. This should fail.
|
||||
let promiseFlushed = TabStateFlusher.flush(browser);
|
||||
promiseFlushed.then(() => {throw new Error("Flush should have failed")});
|
||||
|
||||
// The frame script should report an error.
|
||||
yield promiseReported;
|
||||
|
||||
// Give us some time to handle that error.
|
||||
yield new Promise(resolve => setTimeout(resolve, 10));
|
||||
|
||||
// By now, Telemetry should have been updated.
|
||||
let snapshot2 = Services.telemetry.getHistogramById(HISTOGRAM_NAME).snapshot();
|
||||
gBrowser.removeTab(newTab);
|
||||
|
||||
Assert.ok(snapshot2.sum > snapshot.sum);
|
||||
});
|
||||
|
||||
add_task(function* cleanup() {
|
||||
Services.telemetry.canRecordExtended = false;
|
||||
});
|
@ -440,12 +440,16 @@ Section "-Application" APP_IDX
|
||||
${If} $R0 == "true"
|
||||
; Only proceed if we have HKLM write access
|
||||
${AndIf} $TmpVal == "HKLM"
|
||||
; On Windows 2000 we do not install the maintenance service.
|
||||
${AndIf} ${AtLeastWinXP}
|
||||
; The user is an admin so we should default to install service yes
|
||||
StrCpy $InstallMaintenanceService "1"
|
||||
; On Windows < XP SP3 we do not install the maintenance service.
|
||||
${If} ${IsWinXP}
|
||||
${AndIf} ${AtMostServicePack} 2
|
||||
StrCpy $InstallMaintenanceService "0"
|
||||
${Else}
|
||||
; The user is an admin, so we should default to installing the service.
|
||||
StrCpy $InstallMaintenanceService "1"
|
||||
${EndIf}
|
||||
${Else}
|
||||
; The user is not admin so we should default to install service no
|
||||
; The user is not admin, so we can't install the service.
|
||||
StrCpy $InstallMaintenanceService "0"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
@ -916,10 +920,11 @@ Function preComponents
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
; On Windows 2000 we do not install the maintenance service.
|
||||
${Unless} ${AtLeastWinXP}
|
||||
; On Windows < XP SP3 we do not install the maintenance service.
|
||||
${If} ${IsWinXP}
|
||||
${AndIf} ${AtMostServicePack} 2
|
||||
Abort
|
||||
${EndUnless}
|
||||
${EndIf}
|
||||
|
||||
; Don't show the custom components page if the
|
||||
; user is not an admin
|
||||
|
@ -1021,9 +1021,19 @@ Function createOptions
|
||||
${NSD_Check} $CheckboxSendPing
|
||||
|
||||
!ifdef MOZ_MAINTENANCE_SERVICE
|
||||
; Only show the maintenance service checkbox if we have write access to HKLM
|
||||
; We can only install the maintenance service if the user is an admin.
|
||||
Call IsUserAdmin
|
||||
Pop $0
|
||||
|
||||
; Only show the maintenance service checkbox if we're on XP SP3 or higher;
|
||||
; we don't ever want to install it on XP without at least SP3 installed.
|
||||
${If} $0 == "true"
|
||||
${AndIf} ${IsWinXP}
|
||||
${AndIf} ${AtMostServicePack} 2
|
||||
StrCpy $0 "false"
|
||||
${EndIf}
|
||||
|
||||
; Only show the maintenance service checkbox if we have write access to HKLM
|
||||
ClearErrors
|
||||
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \
|
||||
"Write Test"
|
||||
|
@ -7,7 +7,7 @@
|
||||
"use strict";
|
||||
|
||||
loader.lazyRequireGetter(this, "React",
|
||||
"resource://devtools/client/shared/vendor/react.js");
|
||||
"devtools/client/shared/vendor/react");
|
||||
loader.lazyRequireGetter(this, "TargetListComponent",
|
||||
"devtools/client/aboutdebugging/components/target-list", true);
|
||||
loader.lazyRequireGetter(this, "Services");
|
||||
|
@ -7,7 +7,7 @@
|
||||
"use strict";
|
||||
|
||||
loader.lazyRequireGetter(this, "React",
|
||||
"resource://devtools/client/shared/vendor/react.js");
|
||||
"devtools/client/shared/vendor/react");
|
||||
loader.lazyRequireGetter(this, "TargetComponent",
|
||||
"devtools/client/aboutdebugging/components/target", true);
|
||||
loader.lazyRequireGetter(this, "Services");
|
||||
|
@ -8,7 +8,7 @@
|
||||
"use strict";
|
||||
|
||||
loader.lazyRequireGetter(this, "React",
|
||||
"resource://devtools/client/shared/vendor/react.js");
|
||||
"devtools/client/shared/vendor/react");
|
||||
loader.lazyRequireGetter(this, "TargetFactory",
|
||||
"devtools/client/framework/target", true);
|
||||
loader.lazyRequireGetter(this, "Toolbox",
|
||||
|
@ -9,7 +9,7 @@
|
||||
loader.lazyRequireGetter(this, "Ci",
|
||||
"chrome", true);
|
||||
loader.lazyRequireGetter(this, "React",
|
||||
"resource://devtools/client/shared/vendor/react.js");
|
||||
"devtools/client/shared/vendor/react");
|
||||
loader.lazyRequireGetter(this, "TargetListComponent",
|
||||
"devtools/client/aboutdebugging/components/target-list", true);
|
||||
loader.lazyRequireGetter(this, "Services");
|
||||
|
@ -34,6 +34,9 @@ const L10N = new ViewHelpers.L10N(STRINGS_URI);
|
||||
const MILLIS_TIME_FORMAT_MAX_DURATION = 4000;
|
||||
// The minimum spacing between 2 time graduation headers in the timeline (px).
|
||||
const TIME_GRADUATION_MIN_SPACING = 40;
|
||||
// The size of the fast-track icon (for compositor-running animations), this is
|
||||
// used to position the icon correctly.
|
||||
const FAST_TRACK_ICON_SIZE = 20;
|
||||
|
||||
/**
|
||||
* UI component responsible for displaying a preview of the target dom node of
|
||||
@ -631,7 +634,9 @@ AnimationsTimeline.prototype = {
|
||||
parent: this.animationsEl,
|
||||
nodeType: "li",
|
||||
attributes: {
|
||||
"class": "animation"
|
||||
"class": "animation" + (animation.state.isRunningOnCompositor
|
||||
? " fast-track"
|
||||
: "")
|
||||
}
|
||||
});
|
||||
|
||||
@ -801,6 +806,8 @@ AnimationTimeBlock.prototype = {
|
||||
|
||||
let x = TimeScale.startTimeToDistance(start + (delay / rate), width);
|
||||
let w = TimeScale.durationToDistance(duration / rate, width);
|
||||
let iterationW = w * (count || 1);
|
||||
let delayW = TimeScale.durationToDistance(Math.abs(delay) / rate, width);
|
||||
|
||||
let iterations = createNode({
|
||||
parent: this.containerEl,
|
||||
@ -809,7 +816,7 @@ AnimationTimeBlock.prototype = {
|
||||
// Individual iterations are represented by setting the size of the
|
||||
// repeating linear-gradient.
|
||||
"style": `left:${x}px;
|
||||
width:${w * (count || 1)}px;
|
||||
width:${iterationW}px;
|
||||
background-size:${Math.max(w, 2)}px 100%;`
|
||||
}
|
||||
});
|
||||
@ -817,15 +824,17 @@ AnimationTimeBlock.prototype = {
|
||||
// The animation name is displayed over the iterations.
|
||||
// Note that in case of negative delay, we push the name towards the right
|
||||
// so the delay can be shown.
|
||||
let negativeDelayW = delay < 0 ? delayW : 0;
|
||||
createNode({
|
||||
parent: iterations,
|
||||
attributes: {
|
||||
"class": "name",
|
||||
"title": this.getTooltipText(state),
|
||||
"style": delay < 0
|
||||
? "margin-left:" +
|
||||
TimeScale.durationToDistance(Math.abs(delay), width) + "px"
|
||||
: ""
|
||||
// Position the fast-track icon with background-position, and make space
|
||||
// for the negative delay with a margin-left.
|
||||
"style": "background-position:" +
|
||||
(iterationW - FAST_TRACK_ICON_SIZE - negativeDelayW) +
|
||||
"px center;margin-left:" + negativeDelayW + "px"
|
||||
},
|
||||
textContent: state.name
|
||||
});
|
||||
@ -835,9 +844,6 @@ AnimationTimeBlock.prototype = {
|
||||
// Negative delays need to start at 0.
|
||||
let delayX = TimeScale.durationToDistance(
|
||||
(delay < 0 ? 0 : delay) / rate, width);
|
||||
let delayW = TimeScale.durationToDistance(
|
||||
Math.abs(delay) / rate, width);
|
||||
|
||||
createNode({
|
||||
parent: iterations,
|
||||
attributes: {
|
||||
@ -864,6 +870,9 @@ AnimationTimeBlock.prototype = {
|
||||
let iterations = L10N.getStr("player.animationIterationCountLabel") + " " +
|
||||
(state.iterationCount ||
|
||||
L10N.getStr("player.infiniteIterationCountText"));
|
||||
return [title, duration, iterations, delay].join("\n");
|
||||
let compositor = state.isRunningOnCompositor
|
||||
? L10N.getStr("player.runningOnCompositorTooltip")
|
||||
: "";
|
||||
return [title, duration, iterations, delay, compositor].join("\n");
|
||||
}
|
||||
};
|
||||
|
@ -20,6 +20,7 @@ support-files =
|
||||
[browser_animation_refresh_on_added_animation.js]
|
||||
[browser_animation_refresh_on_removed_animation.js]
|
||||
[browser_animation_refresh_when_active.js]
|
||||
[browser_animation_running_on_compositor.js]
|
||||
[browser_animation_same_nb_of_playerWidgets_and_playerFronts.js]
|
||||
[browser_animation_shows_player_on_valid_node.js]
|
||||
[browser_animation_target_highlight_select.js]
|
||||
|
@ -0,0 +1,43 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that when animations displayed in the timeline are running on the
|
||||
// compositor, they get a special icon and information in the tooltip.
|
||||
|
||||
const STRINGS_URI = "chrome://browser/locale/devtools/animationinspector.properties";
|
||||
const L10N = new ViewHelpers.L10N(STRINGS_URI);
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
|
||||
let {inspector, panel} = yield openAnimationInspector();
|
||||
let timeline = panel.animationsTimelineComponent;
|
||||
|
||||
info("Select a test node we know has an animation running on the compositor");
|
||||
yield selectNode(".animated", inspector);
|
||||
|
||||
let animationEl = timeline.animationsEl.querySelector(".animation");
|
||||
ok(animationEl.classList.contains("fast-track"),
|
||||
"The animation element has the fast-track css class");
|
||||
ok(hasTooltip(animationEl),
|
||||
"The animation element has the right tooltip content");
|
||||
|
||||
info("Select a node we know doesn't have an animation on the compositor");
|
||||
yield selectNode(".no-compositor", inspector);
|
||||
|
||||
animationEl = timeline.animationsEl.querySelector(".animation");
|
||||
ok(!animationEl.classList.contains("fast-track"),
|
||||
"The animation element does not have the fast-track css class");
|
||||
ok(!hasTooltip(animationEl),
|
||||
"The animation element has the right tooltip content");
|
||||
});
|
||||
|
||||
function hasTooltip(animationEl) {
|
||||
let el = animationEl.querySelector(".name");
|
||||
let tooltip = el.getAttribute("title");
|
||||
|
||||
let expected = L10N.getStr("player.runningOnCompositorTooltip");
|
||||
return tooltip.indexOf(expected) !== -1;
|
||||
}
|
@ -74,6 +74,14 @@
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.no-compositor {
|
||||
top: 0;
|
||||
right: 10px;
|
||||
background: gold;
|
||||
|
||||
animation: no-compositor 10s cubic-bezier(.57,-0.02,1,.31) forwards;
|
||||
}
|
||||
|
||||
@keyframes simple-animation {
|
||||
100% {
|
||||
transform: translateX(300px);
|
||||
@ -85,6 +93,12 @@
|
||||
background: blue;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes no-compositor {
|
||||
100% {
|
||||
margin-right: 600px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -97,5 +111,6 @@
|
||||
<div class="ball short"></div>
|
||||
<div class="ball long"></div>
|
||||
<div class="ball negative-delay"></div>
|
||||
<div class="ball no-compositor"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -341,6 +341,12 @@ body {
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.animation-timeline .fast-track .name {
|
||||
/* Animations running on the compositor have the fast-track background image*/
|
||||
background-image: url("images/animation-fast-track.svg");
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.animation-timeline .animation .delay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -4,6 +4,6 @@
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="12">
|
||||
<g transform="matrix(1.0251088,0,0,0.85613344,-3.1546734,-888.94343)">
|
||||
<path d="m 5.1284819,1038.3667 6.4950901,0 -2.7147491,4.6651 2.9438561,0 -8.1148915,9.3081 1.6126718,-6.8973 -2.2701022,0 z" style="fill:#4cb0e1;"/>
|
||||
<path d="m 5.1284819,1038.3667 6.4950901,0 -2.7147491,4.6651 2.9438561,0 -8.1148915,9.3081 1.6126718,-6.8973 -2.2701022,0 z" style="fill:white;"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 514 B |
@ -306,6 +306,8 @@ var interfaceNamesInGlobalScope =
|
||||
"ChannelSplitterNode",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"CharacterData",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "ChromeNodeList", xbl: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "ChromeWindow", xbl: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -4,7 +4,7 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
[ChromeOnly, Constructor]
|
||||
[Constructor, Func="IsChromeOrXBL"]
|
||||
interface ChromeNodeList : NodeList {
|
||||
[Throws]
|
||||
void append(Node aNode);
|
||||
|
@ -602,6 +602,8 @@ public class GeckoEvent {
|
||||
int value) {
|
||||
GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_HISTOGRAM_ADD);
|
||||
event.mCharacters = histogram;
|
||||
// Set the extras with null so that it cannot be mistaken with a keyed histogram.
|
||||
event.mCharactersExtra = null;
|
||||
event.mCount = value;
|
||||
return event;
|
||||
}
|
||||
|
@ -267,6 +267,10 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
// We are adding descendants to this LayerView, but we don't want the
|
||||
// descendants to affect the way LayerView retains its focus.
|
||||
setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);
|
||||
|
||||
// This check should not be done before the view is attached to a window
|
||||
// as hardware acceleration will not be enabled at that point.
|
||||
// We must create and add the SurfaceView instance before the view tree
|
||||
|
@ -146,6 +146,8 @@ public class TabQueueService extends Service {
|
||||
TabQueueHelper.removeURLFromFile(applicationContext, intentUrl, TabQueueHelper.FILE_NAME);
|
||||
}
|
||||
openNow(safeIntent.getUnsafe());
|
||||
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "tabqueue-doubletap");
|
||||
stopSelfResult(startId);
|
||||
}
|
||||
});
|
||||
@ -186,6 +188,8 @@ public class TabQueueService extends Service {
|
||||
stopServiceRunnable = null;
|
||||
removeView();
|
||||
openNow(intent);
|
||||
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "tabqueue-now");
|
||||
stopSelfResult(startId);
|
||||
}
|
||||
});
|
||||
@ -207,8 +211,6 @@ public class TabQueueService extends Service {
|
||||
.remove(GeckoPreferences.PREFS_TAB_QUEUE_LAST_TIME)
|
||||
.apply();
|
||||
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "tabqueue-now");
|
||||
|
||||
executorService.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -130,6 +130,7 @@ skip-if = android_version == "10" || android_version == "18"
|
||||
# disabled on 4.3, bug 1158363
|
||||
skip-if = android_version == "18"
|
||||
[src/org/mozilla/gecko/tests/testUITelemetry.java]
|
||||
[src/org/mozilla/gecko/tests/testBug1217581.java]
|
||||
[src/org/mozilla/gecko/tests/testVideoControls.java]
|
||||
# disabled on Android 2.3 due to video playback issues, bug 1088038; on 4.3, bug 1098532
|
||||
skip-if = android_version == "10" || android_version == "18"
|
||||
|
@ -0,0 +1,31 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.tests;
|
||||
|
||||
|
||||
import org.mozilla.gecko.Telemetry;
|
||||
|
||||
public class testBug1217581 extends BaseTest {
|
||||
// Take arbitrary histogram names used by Fennec.
|
||||
private static final String TEST_HISTOGRAM_NAME = "FENNEC_SYNC_NUMBER_OF_SYNCS_COMPLETED";
|
||||
private static final String TEST_KEYED_HISTOGRAM_NAME = "ABOUT_ACCOUNTS_CONTENT_SERVER_LOAD_STARTED_COUNT";
|
||||
private static final String TEST_KEY_NAME = "testBug1217581";
|
||||
|
||||
|
||||
public void testBug1217581() {
|
||||
blockForGeckoReady();
|
||||
|
||||
mAsserter.ok(true, "Checking that adding to a keyed histogram then adding to a normal histogram does not cause a crash.", "");
|
||||
Telemetry.addToKeyedHistogram(TEST_KEYED_HISTOGRAM_NAME, TEST_KEY_NAME, 1);
|
||||
Telemetry.addToHistogram(TEST_HISTOGRAM_NAME, 1);
|
||||
mAsserter.ok(true, "Adding to a keyed histogram then to a normal histogram was a success!", "");
|
||||
|
||||
mAsserter.ok(true, "Checking that adding to a normal histogram then adding to a keyed histogram does not cause a crash.", "");
|
||||
Telemetry.addToHistogram(TEST_HISTOGRAM_NAME, 1);
|
||||
Telemetry.addToKeyedHistogram(TEST_KEYED_HISTOGRAM_NAME, TEST_KEY_NAME, 1);
|
||||
mAsserter.ok(true, "Adding to a normal histogram then to a keyed histogram was a success!", "");
|
||||
}
|
||||
}
|
@ -41,12 +41,10 @@
|
||||
#include <mach/mach_types.h>
|
||||
#include <mach/message.h>
|
||||
#include <mach/thread_info.h>
|
||||
#endif // defined(XP_MACOSX)
|
||||
|
||||
#if defined(XP_LINUX)
|
||||
#elif defined(XP_UNIX)
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif // defined(XP_LINUX)
|
||||
#endif // defined(XP_UNIX)
|
||||
/* ------------------------------------------------------
|
||||
*
|
||||
* Utility functions.
|
||||
|
@ -4352,6 +4352,12 @@
|
||||
"extended_statistics_ok": true,
|
||||
"description": "Session restore: Time spent blocking the main thread while restoring a window state (ms)"
|
||||
},
|
||||
"FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM": {
|
||||
"alert_emails": ["session-restore-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "default",
|
||||
"kind": "count",
|
||||
"description": "Count of messages sent by SessionRestore from child frames to the parent and that cannot be transmitted as they eat up too much memory."
|
||||
},
|
||||
"FX_TABLETMODE_PAGE_LOAD": {
|
||||
"expires_in_version": "47",
|
||||
"kind": "exponential",
|
||||
@ -4725,6 +4731,7 @@
|
||||
"kind": "linear",
|
||||
"high": "13",
|
||||
"n_buckets": 12,
|
||||
"bug_numbers": [1162538],
|
||||
"description": "Number of directories in the archive at scan"
|
||||
},
|
||||
"TELEMETRY_ARCHIVE_OLDEST_DIRECTORY_AGE": {
|
||||
@ -4733,6 +4740,7 @@
|
||||
"kind": "linear",
|
||||
"high": "13",
|
||||
"n_buckets": 12,
|
||||
"bug_numbers": [1162538],
|
||||
"description": "The age of the oldest Telemetry archive directory in months"
|
||||
},
|
||||
"TELEMETRY_ARCHIVE_SCAN_PING_COUNT": {
|
||||
@ -4741,12 +4749,14 @@
|
||||
"kind": "exponential",
|
||||
"high": "100000",
|
||||
"n_buckets": 100,
|
||||
"bug_numbers": [1162538],
|
||||
"description": "Number of Telemetry pings in the archive at scan"
|
||||
},
|
||||
"TELEMETRY_ARCHIVE_SESSION_PING_COUNT": {
|
||||
"alert_emails": ["telemetry-client-dev@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"bug_numbers": [1162538],
|
||||
"description": "Number of Telemetry pings added to the archive during the session"
|
||||
},
|
||||
"TELEMETRY_ARCHIVE_SIZE_MB": {
|
||||
@ -4755,6 +4765,7 @@
|
||||
"kind": "linear",
|
||||
"high": "300",
|
||||
"n_buckets": 60,
|
||||
"bug_numbers": [1162538],
|
||||
"description": "The size of the Telemetry archive (MB)"
|
||||
},
|
||||
"TELEMETRY_ARCHIVE_EVICTED_OVER_QUOTA": {
|
||||
@ -4763,6 +4774,7 @@
|
||||
"kind": "exponential",
|
||||
"high": "100000",
|
||||
"n_buckets": 100,
|
||||
"bug_numbers": [1162538],
|
||||
"description": "Number of Telemetry pings evicted from the archive during cleanup, because they were over the quota"
|
||||
},
|
||||
"TELEMETRY_ARCHIVE_EVICTED_OLD_DIRS": {
|
||||
@ -4771,6 +4783,7 @@
|
||||
"kind": "linear",
|
||||
"high": "13",
|
||||
"n_buckets": 12,
|
||||
"bug_numbers": [1162538],
|
||||
"description": "Number of Telemetry directories evicted from the archive during cleanup, because they were too old"
|
||||
},
|
||||
"TELEMETRY_ARCHIVE_EVICTING_DIRS_MS": {
|
||||
@ -4779,6 +4792,7 @@
|
||||
"kind": "exponential",
|
||||
"high": "300000",
|
||||
"n_buckets": 20,
|
||||
"bug_numbers": [1162538],
|
||||
"description": "Time (ms) it takes for evicting old directories"
|
||||
},
|
||||
"TELEMETRY_ARCHIVE_CHECKING_OVER_QUOTA_MS": {
|
||||
@ -4787,6 +4801,7 @@
|
||||
"kind": "exponential",
|
||||
"high": "300000",
|
||||
"n_buckets": 20,
|
||||
"bug_numbers": [1162538],
|
||||
"description": "Time (ms) it takes for checking if the archive is over-quota"
|
||||
},
|
||||
"TELEMETRY_ARCHIVE_EVICTING_OVER_QUOTA_MS": {
|
||||
@ -4795,6 +4810,7 @@
|
||||
"kind": "exponential",
|
||||
"high": "300000",
|
||||
"n_buckets": 20,
|
||||
"bug_numbers": [1162538],
|
||||
"description": "Time (ms) it takes for evicting over-quota pings"
|
||||
},
|
||||
"TELEMETRY_PENDING_LOAD_FAILURE_READ": {
|
||||
|
189
toolkit/components/telemetry/bucket-whitelist.json
Normal file
189
toolkit/components/telemetry/bucket-whitelist.json
Normal file
@ -0,0 +1,189 @@
|
||||
[
|
||||
"MEMORY_RESIDENT",
|
||||
"MEMORY_JS_MAIN_RUNTIME_TEMPORARY_PEAK",
|
||||
"MEMORY_JS_GC_HEAP",
|
||||
"MEMORY_HEAP_ALLOCATED",
|
||||
"SYSTEM_FONT_FALLBACK_SCRIPT",
|
||||
"HTTP_REQUEST_PER_PAGE_FROM_CACHE",
|
||||
"SSL_TIME_UNTIL_READY",
|
||||
"SSL_TIME_UNTIL_HANDSHAKE_FINISHED",
|
||||
"CERT_VALIDATION_HTTP_REQUEST_CANCELED_TIME",
|
||||
"CERT_VALIDATION_HTTP_REQUEST_SUCCEEDED_TIME",
|
||||
"CERT_VALIDATION_HTTP_REQUEST_FAILED_TIME",
|
||||
"SSL_OBSERVED_END_ENTITY_CERTIFICATE_LIFETIME",
|
||||
"SPDY_SERVER_INITIATED_STREAMS",
|
||||
"STS_POLL_AND_EVENTS_CYCLE",
|
||||
"STS_POLL_CYCLE",
|
||||
"STS_POLL_AND_EVENT_THE_LAST_CYCLE",
|
||||
"STS_POLL_BLOCK_TIME",
|
||||
"PRCONNECT_BLOCKING_TIME_NORMAL",
|
||||
"PRCONNECT_BLOCKING_TIME_SHUTDOWN",
|
||||
"PRCONNECT_BLOCKING_TIME_CONNECTIVITY_CHANGE",
|
||||
"PRCONNECT_BLOCKING_TIME_LINK_CHANGE",
|
||||
"PRCONNECT_BLOCKING_TIME_OFFLINE",
|
||||
"PRCONNECTCONTINUE_BLOCKING_TIME_NORMAL",
|
||||
"PRCONNECTCONTINUE_BLOCKING_TIME_SHUTDOWN",
|
||||
"PRCONNECTCONTINUE_BLOCKING_TIME_CONNECTIVITY_CHANGE",
|
||||
"PRCONNECTCONTINUE_BLOCKING_TIME_LINK_CHANGE",
|
||||
"PRCONNECTCONTINUE_BLOCKING_TIME_OFFLINE",
|
||||
"PRCLOSE_TCP_BLOCKING_TIME_NORMAL",
|
||||
"PRCLOSE_TCP_BLOCKING_TIME_SHUTDOWN",
|
||||
"PRCLOSE_TCP_BLOCKING_TIME_CONNECTIVITY_CHANGE",
|
||||
"PRCLOSE_TCP_BLOCKING_TIME_LINK_CHANGE",
|
||||
"PRCLOSE_TCP_BLOCKING_TIME_OFFLINE",
|
||||
"PRCLOSE_UDP_BLOCKING_TIME_NORMAL",
|
||||
"PRCLOSE_UDP_BLOCKING_TIME_SHUTDOWN",
|
||||
"PRCLOSE_UDP_BLOCKING_TIME_CONNECTIVITY_CHANGE",
|
||||
"PRCLOSE_UDP_BLOCKING_TIME_LINK_CHANGE",
|
||||
"PRCLOSE_UDP_BLOCKING_TIME_OFFLINE",
|
||||
"UPDATE_PREF_UPDATE_CANCELATIONS_EXTERNAL",
|
||||
"UPDATE_PREF_UPDATE_CANCELATIONS_NOTIFY",
|
||||
"UPDATE_STATUS_ERROR_CODE_COMPLETE_STARTUP",
|
||||
"UPDATE_STATUS_ERROR_CODE_PARTIAL_STARTUP",
|
||||
"UPDATE_STATUS_ERROR_CODE_UNKNOWN_STARTUP",
|
||||
"UPDATE_STATUS_ERROR_CODE_COMPLETE_STAGE",
|
||||
"UPDATE_STATUS_ERROR_CODE_PARTIAL_STAGE",
|
||||
"UPDATE_STATUS_ERROR_CODE_UNKNOWN_STAGE",
|
||||
"SECURITY_UI",
|
||||
"HEALTHREPORT_PAYLOAD_UNCOMPRESSED_BYTES",
|
||||
"HEALTHREPORT_PAYLOAD_COMPRESSED_BYTES",
|
||||
"CRASH_STORE_COMPRESSED_BYTES",
|
||||
"SHUMWAY_FEATURE_USED",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_RELOAD_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_RELOAD_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_NAVIGATETO_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_NAVIGATETO_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_EVENTLISTENERS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_EVENTLISTENERS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_DETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_DETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_RESUME_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_RESUME_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_INTERRUPT_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_INTERRUPT_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_CLIENTEVALUATE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_CLIENTEVALUATE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_RELEASEMANY_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_RELEASEMANY_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_THREADGRIPS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_THREADGRIPS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_SOURCES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_SOURCES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_FRAMES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_FRAMES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_PARAMETERNAMES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_PARAMETERNAMES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_OWNPROPERTYNAMES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_OWNPROPERTYNAMES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_PROTOTYPEANDPROPERTIES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_PROTOTYPEANDPROPERTIES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_ENUMPROPERTIES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_ENUMPROPERTIES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_PROTOTYPESANDPROPERTIES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_PROTOTYPESANDPROPERTIES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_PROPERTY_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_PROPERTY_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_PROTOTYPE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_PROTOTYPE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_DISPLAYSTRING_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_DISPLAYSTRING_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_SUBSTRING_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_SUBSTRING_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_RELEASE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_RELEASE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_LISTTABS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_LISTTABS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_PROTOCOLDESCRIPTION_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_PROTOCOLDESCRIPTION_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_LISTADDONS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_LISTADDONS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_LISTWORKERS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_LISTWORKERS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_LISTPROCESSES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_LISTPROCESSES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_DELETE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_DELETE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_THREADDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_THREADDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_ADDONDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_ADDONDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_TABDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_TABDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_WORKERDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_WORKERDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_DISPLAY_SOURCE_LOCAL_MS",
|
||||
"DEVTOOLS_DEBUGGER_DISPLAY_SOURCE_REMOTE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_RECONFIGURETAB_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_RECONFIGURETAB_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_RECONFIGURETHREAD_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_RECONFIGURETHREAD_MS",
|
||||
"MEDIA_WMF_DECODE_ERROR",
|
||||
"VIDEO_CANPLAYTYPE_H264_CONSTRAINT_SET_FLAG",
|
||||
"VIDEO_CANPLAYTYPE_H264_PROFILE",
|
||||
"VIDEO_DECODED_H264_SPS_CONSTRAINT_SET_FLAG",
|
||||
"VIDEO_DECODED_H264_SPS_PROFILE",
|
||||
"WEBRTC_CANDIDATE_TYPES_GIVEN_SUCCESS",
|
||||
"WEBRTC_CANDIDATE_TYPES_GIVEN_FAILURE",
|
||||
"WEBRTC_AVSYNC_WHEN_AUDIO_LAGS_VIDEO_MS",
|
||||
"WEBRTC_AVSYNC_WHEN_VIDEO_LAGS_AUDIO_MS",
|
||||
"WEBRTC_VIDEO_QUALITY_INBOUND_BANDWIDTH_KBITS",
|
||||
"WEBRTC_AUDIO_QUALITY_INBOUND_BANDWIDTH_KBITS",
|
||||
"WEBRTC_VIDEO_QUALITY_OUTBOUND_BANDWIDTH_KBITS",
|
||||
"WEBRTC_AUDIO_QUALITY_OUTBOUND_BANDWIDTH_KBITS",
|
||||
"WEBRTC_AUDIO_QUALITY_INBOUND_JITTER",
|
||||
"WEBRTC_VIDEO_QUALITY_OUTBOUND_JITTER",
|
||||
"WEBRTC_AUDIO_QUALITY_OUTBOUND_JITTER",
|
||||
"WEBRTC_VIDEO_ERROR_RECOVERY_MS",
|
||||
"WEBRTC_VIDEO_RECOVERY_BEFORE_ERROR_PER_MIN",
|
||||
"WEBRTC_VIDEO_RECOVERY_AFTER_ERROR_PER_MIN",
|
||||
"WEBRTC_VIDEO_QUALITY_OUTBOUND_RTT",
|
||||
"WEBRTC_AUDIO_QUALITY_OUTBOUND_RTT",
|
||||
"WEBRTC_CALL_DURATION",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_TRACERDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_TRACERDETACH_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_STARTTRACE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_STARTTRACE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_STOPTRACE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_STOPTRACE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_GET_EXECUTABLE_LINES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_GET_EXECUTABLE_LINES_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_BLACKBOX_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_BLACKBOX_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_UNBLACKBOX_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_UNBLACKBOX_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_SCOPE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_SCOPE_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_BINDINGS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_BINDINGS_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_LOCAL_ASSIGN_MS",
|
||||
"DEVTOOLS_DEBUGGER_RDP_REMOTE_ASSIGN_MS",
|
||||
"DEVTOOLS_SAVE_HEAP_SNAPSHOT_MS",
|
||||
"DEVTOOLS_READ_HEAP_SNAPSHOT_MS",
|
||||
"DEVTOOLS_HEAP_SNAPSHOT_NODE_COUNT",
|
||||
"DEVTOOLS_HEAP_SNAPSHOT_EDGE_COUNT",
|
||||
"NETWORK_CACHE_HIT_RATE_PER_CACHE_SIZE",
|
||||
"NETWORK_CACHE_METADATA_FIRST_READ_SIZE",
|
||||
"NETWORK_CACHE_METADATA_SIZE",
|
||||
"NETWORK_CACHE_HASH_STATS",
|
||||
"SSL_CIPHER_SUITE_FULL",
|
||||
"SSL_CIPHER_SUITE_RESUMED",
|
||||
"SSL_REASONS_FOR_NOT_FALSE_STARTING",
|
||||
"SSL_CERT_VERIFICATION_ERRORS",
|
||||
"CERT_VALIDATION_SUCCESS_BY_CA",
|
||||
"CERT_PINNING_FAILURES_BY_CA",
|
||||
"CERT_PINNING_MOZ_RESULTS_BY_HOST",
|
||||
"CERT_PINNING_MOZ_TEST_RESULTS_BY_HOST",
|
||||
"LOOP_CANDIDATE_TYPES_GIVEN_SUCCESS",
|
||||
"LOOP_CANDIDATE_TYPES_GIVEN_FAILURE",
|
||||
"LOOP_VIDEO_QUALITY_INBOUND_BANDWIDTH_KBITS",
|
||||
"LOOP_AUDIO_QUALITY_INBOUND_BANDWIDTH_KBITS",
|
||||
"LOOP_VIDEO_QUALITY_OUTBOUND_BANDWIDTH_KBITS",
|
||||
"LOOP_AUDIO_QUALITY_OUTBOUND_BANDWIDTH_KBITS",
|
||||
"LOOP_VIDEO_ERROR_RECOVERY_MS",
|
||||
"LOOP_VIDEO_RECOVERY_BEFORE_ERROR_PER_MIN",
|
||||
"LOOP_VIDEO_RECOVERY_AFTER_ERROR_PER_MIN",
|
||||
"LOOP_VIDEO_QUALITY_OUTBOUND_RTT",
|
||||
"LOOP_AUDIO_QUALITY_OUTBOUND_RTT",
|
||||
"LOOP_CALL_DURATION",
|
||||
"GFX_CRASH"
|
||||
]
|
@ -75,7 +75,20 @@ def exponential_buckets(dmin, dmax, n_buckets):
|
||||
return ret_array
|
||||
|
||||
always_allowed_keys = ['kind', 'description', 'cpp_guard', 'expires_in_version',
|
||||
'alert_emails', 'keyed', 'releaseChannelCollection']
|
||||
'alert_emails', 'keyed', 'releaseChannelCollection',
|
||||
'bug_numbers']
|
||||
|
||||
n_buckets_whitelist = None;
|
||||
try:
|
||||
whitelist_path = os.path.join(os.path.abspath(os.path.realpath(os.path.dirname(__file__))), 'bucket-whitelist.json')
|
||||
with open(whitelist_path, 'r') as f:
|
||||
try:
|
||||
n_buckets_whitelist = set(json.load(f))
|
||||
except ValueError, e:
|
||||
raise BaseException, 'error parsing bucket whitelist (%s)' % whitelist_path
|
||||
except IOError:
|
||||
n_buckets_whitelist = None
|
||||
print 'Unable to parse whitelist (%s). Assuming all histograms are acceptable.' % whitelist_path
|
||||
|
||||
class Histogram:
|
||||
"""A class for representing a histogram definition."""
|
||||
@ -209,6 +222,7 @@ is enabled."""
|
||||
lambda allowed_keys: Histogram.check_keys(name, definition, allowed_keys))
|
||||
|
||||
Histogram.check_expiration(name, definition)
|
||||
Histogram.check_bug_numbers(name, definition)
|
||||
|
||||
def check_name(self, name):
|
||||
if '#' in name:
|
||||
@ -228,6 +242,18 @@ is enabled."""
|
||||
|
||||
definition['expires_in_version'] = expiration
|
||||
|
||||
@staticmethod
|
||||
def check_bug_numbers(name, definition):
|
||||
bug_numbers = definition.get('bug_numbers')
|
||||
if not bug_numbers:
|
||||
return
|
||||
|
||||
if not isinstance(bug_numbers, list):
|
||||
raise ValueError, 'bug_numbers field for "%s" should be an array' % (name)
|
||||
|
||||
if not all(type(num) is int for num in bug_numbers):
|
||||
raise ValueError, 'bug_numbers array for "%s" should only contain integers' % (name)
|
||||
|
||||
@staticmethod
|
||||
def check_keys(name, definition, allowed_keys):
|
||||
for key in definition.iterkeys():
|
||||
@ -243,6 +269,11 @@ is enabled."""
|
||||
self._low = try_to_coerce_to_number(low)
|
||||
self._high = try_to_coerce_to_number(high)
|
||||
self._n_buckets = try_to_coerce_to_number(n_buckets)
|
||||
if n_buckets_whitelist is not None and self._n_buckets > 100 and type(self._n_buckets) is int:
|
||||
if self._name not in n_buckets_whitelist:
|
||||
raise KeyError, ('New histogram %s is not permitted to have more than 100 buckets. '
|
||||
'Histograms with large numbers of buckets use disproportionately high amounts of resources. '
|
||||
'Contact :vladan or the Perf team if you think an exception ought to be made.' % self._name)
|
||||
|
||||
@staticmethod
|
||||
def boolean_flag_bucket_parameters(definition):
|
||||
|
@ -158,7 +158,8 @@ this.PageThumbs = {
|
||||
*/
|
||||
getThumbnailURL: function PageThumbs_getThumbnailURL(aUrl) {
|
||||
return this.scheme + "://" + this.staticHost +
|
||||
"/?url=" + encodeURIComponent(aUrl);
|
||||
"/?url=" + encodeURIComponent(aUrl) +
|
||||
"&revision=" + PageThumbsStorage.getRevision(aUrl);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -542,6 +543,44 @@ this.PageThumbsStorage = {
|
||||
return OS.Path.join(this.path, this.getLeafNameForURL(aURL));
|
||||
},
|
||||
|
||||
_revisionTable: {},
|
||||
|
||||
// Generate an arbitrary revision tag, i.e. one that can't be used to
|
||||
// infer URL frecency.
|
||||
_updateRevision(aURL) {
|
||||
// Initialize with a random value and increment on each update. Wrap around
|
||||
// modulo _revisionRange, so that even small values carry no meaning.
|
||||
let rev = this._revisionTable[aURL];
|
||||
if (rev == null)
|
||||
rev = Math.floor(Math.random() * this._revisionRange);
|
||||
this._revisionTable[aURL] = (rev + 1) % this._revisionRange;
|
||||
},
|
||||
|
||||
// If two thumbnails with the same URL and revision are in cache at the
|
||||
// same time, the image loader may pick the stale thumbnail in some cases.
|
||||
// Therefore _revisionRange must be large enough to prevent this, e.g.
|
||||
// in the pathological case image.cache.size (5MB by default) could fill
|
||||
// with (abnormally small) 10KB thumbnail images if the browser session
|
||||
// runs long enough (though this is unlikely as thumbnails are usually
|
||||
// only updated every MAX_THUMBNAIL_AGE_SECS).
|
||||
_revisionRange: 8192,
|
||||
|
||||
/**
|
||||
* Return a revision tag for the thumbnail stored for a given URL.
|
||||
*
|
||||
* @param aURL The URL spec string
|
||||
* @return A revision tag for the corresponding thumbnail. Returns a changed
|
||||
* value whenever the stored thumbnail changes.
|
||||
*/
|
||||
getRevision(aURL) {
|
||||
let rev = this._revisionTable[aURL];
|
||||
if (rev == null) {
|
||||
this._updateRevision(aURL);
|
||||
rev = this._revisionTable[aURL];
|
||||
}
|
||||
return rev;
|
||||
},
|
||||
|
||||
/**
|
||||
* Write the contents of a thumbnail, off the main thread.
|
||||
*
|
||||
@ -571,7 +610,7 @@ this.PageThumbsStorage = {
|
||||
msg /*we don't want that message garbage-collected,
|
||||
as OS.Shared.Type.void_t.in_ptr.toMsg uses C-level
|
||||
memory tricks to enforce zero-copy*/).
|
||||
then(null, this._eatNoOverwriteError(aNoOverwrite));
|
||||
then(() => this._updateRevision(aURL), this._eatNoOverwriteError(aNoOverwrite));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -590,7 +629,7 @@ this.PageThumbsStorage = {
|
||||
let targetFile = this.getFilePathForURL(aTargetURL);
|
||||
let options = { noOverwrite: aNoOverwrite };
|
||||
return PageThumbsWorker.post("copy", [sourceFile, targetFile, options]).
|
||||
then(null, this._eatNoOverwriteError(aNoOverwrite));
|
||||
then(() => this._updateRevision(aTargetURL), this._eatNoOverwriteError(aNoOverwrite));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -10,9 +10,10 @@
|
||||
*
|
||||
* URL structure:
|
||||
*
|
||||
* moz-page-thumb://thumbnail/?url=http%3A%2F%2Fwww.mozilla.org%2F
|
||||
* moz-page-thumb://thumbnail/?url=http%3A%2F%2Fwww.mozilla.org%2F&revision=XX
|
||||
*
|
||||
* This URL requests an image for 'http://www.mozilla.org/'.
|
||||
* The value of the revision key may change when the stored thumbnail changes.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
@ -88,11 +88,6 @@ function capIfStaleErrorResponseUpdateTest() {
|
||||
yield addTab(URL);
|
||||
|
||||
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
||||
|
||||
// image cache entry timestamps have second resolution
|
||||
// so make sure the second part of this test takes part in a different second.
|
||||
yield wait(2000);
|
||||
|
||||
// update the thumbnail to be stale, then re-request it. The server will
|
||||
// return a 400 response and a red thumbnail.
|
||||
// The service should not save the thumbnail - so we (a) check the thumbnail
|
||||
@ -124,11 +119,6 @@ function capIfStaleGoodResponseUpdateTest() {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
|
||||
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
||||
|
||||
// image cache entry timestamps have second resolution
|
||||
// so make sure the second part of this test takes part in a different second.
|
||||
yield wait(2000);
|
||||
|
||||
// update the thumbnail to be stale, then re-request it. The server will
|
||||
// return a 200 response and a red thumbnail - so that new thumbnail should
|
||||
// end up captured.
|
||||
@ -158,11 +148,6 @@ function regularCapErrorResponseUpdateTest() {
|
||||
yield addTab(URL);
|
||||
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
|
||||
// image cache entry timestamps have second resolution
|
||||
// so make sure the second part of this test takes part in a different second.
|
||||
yield wait(2000);
|
||||
|
||||
// do it again - the server will return a 400, so the foreground service
|
||||
// should not update it.
|
||||
yield addTab(URL);
|
||||
@ -177,11 +162,6 @@ function regularCapGoodResponseUpdateTest() {
|
||||
yield addTab(URL);
|
||||
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
|
||||
// image cache entry timestamps have second resolution
|
||||
// so make sure the second part of this test takes part in a different second.
|
||||
yield wait(2000);
|
||||
|
||||
// do it again - the server will return a 200, so the foreground service
|
||||
// should update it.
|
||||
yield addTab(URL);
|
||||
|
@ -145,33 +145,21 @@ function captureAndCheckColor(aRed, aGreen, aBlue, aMessage) {
|
||||
function retrieveImageDataForURL(aURL, aCallback) {
|
||||
let width = 100, height = 100;
|
||||
let thumb = PageThumbs.getThumbnailURL(aURL, width, height);
|
||||
// create a tab with a chrome:// URL so it can host the thumbnail image.
|
||||
// Note that we tried creating the element directly in the top-level chrome
|
||||
// document, but this caused a strange problem:
|
||||
// * call this with the url of an image.
|
||||
// * immediately change the image content.
|
||||
// * call this again with the same url (now holding different content)
|
||||
// The original image data would be used. Maybe the img hadn't been
|
||||
// collected yet and the platform noticed the same URL, so reused the
|
||||
// content? Not sure - but this solves the problem.
|
||||
addTab("chrome://global/content/mozilla.xhtml", () => {
|
||||
let doc = gBrowser.selectedBrowser.contentDocument;
|
||||
let htmlns = "http://www.w3.org/1999/xhtml";
|
||||
let img = doc.createElementNS(htmlns, "img");
|
||||
img.setAttribute("src", thumb);
|
||||
|
||||
whenLoaded(img, function () {
|
||||
let canvas = document.createElementNS(htmlns, "canvas");
|
||||
canvas.setAttribute("width", width);
|
||||
canvas.setAttribute("height", height);
|
||||
let htmlns = "http://www.w3.org/1999/xhtml";
|
||||
let img = document.createElementNS(htmlns, "img");
|
||||
img.setAttribute("src", thumb);
|
||||
|
||||
// Draw the image to a canvas and compare the pixel color values.
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
let result = ctx.getImageData(0, 0, 100, 100).data;
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
aCallback(result);
|
||||
});
|
||||
whenLoaded(img, function () {
|
||||
let canvas = document.createElementNS(htmlns, "canvas");
|
||||
canvas.setAttribute("width", width);
|
||||
canvas.setAttribute("height", height);
|
||||
|
||||
// Draw the image to a canvas and compare the pixel color values.
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
let result = ctx.getImageData(0, 0, 100, 100).data;
|
||||
aCallback(result);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@
|
||||
</setter>
|
||||
</property>
|
||||
|
||||
<field name="selectedItems">[]</field>
|
||||
<field name="selectedItems">new ChromeNodeList()</field>
|
||||
|
||||
<method name="addItemToSelection">
|
||||
<parameter name="aItem"/>
|
||||
@ -186,7 +186,7 @@
|
||||
if (aItem.selected)
|
||||
return;
|
||||
|
||||
this.selectedItems.push(aItem);
|
||||
this.selectedItems.append(aItem);
|
||||
aItem.selected = true;
|
||||
|
||||
this._fireOnSelect();
|
||||
@ -201,14 +201,8 @@
|
||||
if (!aItem.selected)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < this.selectedItems.length; ++i) {
|
||||
if (this.selectedItems[i] == aItem) {
|
||||
this.selectedItems.splice(i, 1);
|
||||
aItem.selected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.selectedItems.remove(aItem);
|
||||
aItem.selected = false;
|
||||
this._fireOnSelect();
|
||||
]]>
|
||||
</body>
|
||||
@ -355,10 +349,11 @@
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this.selectedItems) {
|
||||
for (var i = this.selectedItems.length - 1; i >= 0; --i)
|
||||
this.selectedItems[i].selected = false;
|
||||
|
||||
this.selectedItems.length = 0;
|
||||
while (this.selectedItems.length > 0) {
|
||||
let item = this.selectedItems[0];
|
||||
item.selected = false;
|
||||
this.selectedItems.remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
this._selectionStart = null;
|
||||
@ -700,7 +695,7 @@
|
||||
for (var index = 0; index < count; index++) {
|
||||
var item = this.getItemAtIndex(index);
|
||||
if (item.getAttribute("selected") == "true")
|
||||
this.selectedItems.push(item);
|
||||
this.selectedItems.append(item);
|
||||
}
|
||||
]]>
|
||||
</constructor>
|
||||
|
@ -61,7 +61,7 @@
|
||||
var state = this.currentItem ? this.currentItem.id : "";
|
||||
if (this.selType == "multiple" && this.selectedCount) {
|
||||
let getId = function getId(aItem) { return aItem.id; }
|
||||
state += " " + this.selectedItems.filter(getId).map(getId).join(" ");
|
||||
state += " " + [... this.selectedItems].filter(getId).map(getId).join(" ");
|
||||
}
|
||||
if (state)
|
||||
this.setAttribute("last-selected", state);
|
||||
@ -393,13 +393,17 @@
|
||||
// try to restore the selected items according to their IDs
|
||||
// (applies after a template rebuild, if last-selected was not set)
|
||||
if (this.selectedItems) {
|
||||
let itemIds = [];
|
||||
for (i = this.selectedCount - 1; i >= 0; i--) {
|
||||
if (this.selectedItems[i] && this.selectedItems[i].id)
|
||||
this.selectedItems[i] = document.getElementById(this.selectedItems[i].id);
|
||||
else
|
||||
this.selectedItems[i] = null;
|
||||
if (!this.selectedItems[i])
|
||||
this.selectedItems.splice(i, 1);
|
||||
let selectedItem = this.selectedItems[i];
|
||||
itemIds.push(selectedItem.id);
|
||||
this.selectedItems.remove(selectedItem);
|
||||
}
|
||||
for (i = 0; i < itemIds.length; i++) {
|
||||
let selectedItem = document.getElementById(itemIds[i]);
|
||||
if (selectedItem) {
|
||||
this.selectedItems.append(selectedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.currentItem && this.currentItem.id)
|
||||
@ -417,7 +421,7 @@
|
||||
var children = this.children;
|
||||
for (var i = 0; i < children.length; ++i) {
|
||||
if (children[i].getAttribute("selected") == "true")
|
||||
this.selectedItems.push(children[i]);
|
||||
this.selectedItems.append(children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -871,10 +871,86 @@ function releaseSDCardMountLock() {
|
||||
* @return true if the service should be used for updates.
|
||||
*/
|
||||
function shouldUseService() {
|
||||
if (AppConstants.MOZ_MAINTENANCE_SERVICE && isServiceInstalled()) {
|
||||
return getPref("getBoolPref",
|
||||
PREF_APP_UPDATE_SERVICE_ENABLED, false);
|
||||
// This function will return true if the mantenance service should be used if
|
||||
// all of the following conditions are met:
|
||||
// 1) This build was done with the maintenance service enabled
|
||||
// 2) The maintenance service is installed
|
||||
// 3) The pref for using the service is enabled
|
||||
// 4) The Windows version is XP Service Pack 3 or above (for SHA-2 support)
|
||||
// The maintenance service requires SHA-2 support because we sign our binaries
|
||||
// with a SHA-2 certificate and the certificate is verified before the binary
|
||||
// is launched.
|
||||
if (!AppConstants.MOZ_MAINTENANCE_SERVICE || !isServiceInstalled() ||
|
||||
!getPref("getBoolPref", PREF_APP_UPDATE_SERVICE_ENABLED, false) ||
|
||||
!AppConstants.isPlatformAndVersionAtLeast("win", "5.1") /* WinXP */) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it's newer than XP, then the service pack doesn't matter.
|
||||
if (Services.sysinfo.getProperty("version") != "5.1") {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the Windows version is XP, we also need to check the service pack.
|
||||
// We'll return false if only < SP3 is installed, or if we can't tell.
|
||||
// Check the service pack level by calling GetVersionEx via ctypes.
|
||||
const BYTE = ctypes.uint8_t;
|
||||
const WORD = ctypes.uint16_t;
|
||||
const DWORD = ctypes.uint32_t;
|
||||
const WCHAR = ctypes.char16_t;
|
||||
const BOOL = ctypes.int;
|
||||
// This structure is described at:
|
||||
// http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
|
||||
const SZCSDVERSIONLENGTH = 128;
|
||||
const OSVERSIONINFOEXW = new ctypes.StructType('OSVERSIONINFOEXW',
|
||||
[
|
||||
{dwOSVersionInfoSize: DWORD},
|
||||
{dwMajorVersion: DWORD},
|
||||
{dwMinorVersion: DWORD},
|
||||
{dwBuildNumber: DWORD},
|
||||
{dwPlatformId: DWORD},
|
||||
{szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH)},
|
||||
{wServicePackMajor: WORD},
|
||||
{wServicePackMinor: WORD},
|
||||
{wSuiteMask: WORD},
|
||||
{wProductType: BYTE},
|
||||
{wReserved: BYTE}
|
||||
]);
|
||||
|
||||
let kernel32 = false;
|
||||
try {
|
||||
kernel32 = ctypes.open("Kernel32");
|
||||
} catch (e) {
|
||||
Cu.reportError("Unable to open kernel32! " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kernel32) {
|
||||
try {
|
||||
try {
|
||||
let GetVersionEx = kernel32.declare("GetVersionExW",
|
||||
ctypes.default_abi,
|
||||
BOOL,
|
||||
OSVERSIONINFOEXW.ptr);
|
||||
let winVer = OSVERSIONINFOEXW();
|
||||
winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;
|
||||
|
||||
if (0 !== GetVersionEx(winVer.address())) {
|
||||
return winVer.wServicePackMajor >= 3;
|
||||
} else {
|
||||
Cu.reportError("Unknown failure in GetVersionEX (returned 0)");
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError("Error getting service pack information. Exception: " + e);
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
kernel32.close();
|
||||
}
|
||||
}
|
||||
|
||||
// If the service pack check couldn't be done, assume we can't use the service.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user