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");
|
goUpdateCommand("downloadsCmd_clearDownloads");
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
// Slicing the array to get a freezed list of selected items. Otherwise,
|
// Cloning the nodelist into an array to get a frozen list of selected items.
|
||||||
// the selectedItems array is live and doCommand may alter the selection
|
// Otherwise, the selectedItems nodelist is live and doCommand may alter the
|
||||||
// while we are trying to do one particular action, like removing items
|
// selection while we are trying to do one particular action, like removing
|
||||||
// from history.
|
// items from history.
|
||||||
let selectedElements = this._richlistbox.selectedItems.slice();
|
let selectedElements = [... this._richlistbox.selectedItems];
|
||||||
for (let element of selectedElements) {
|
for (let element of selectedElements) {
|
||||||
element._shell.doCommand(aCommand);
|
element._shell.doCommand(aCommand);
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,9 @@ const MESSAGES = [
|
|||||||
// A crashed tab was revived by navigating to a different page. Remove its
|
// 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.
|
// browser from the list of crashed browsers to stop ignoring its messages.
|
||||||
"SessionStore:crashedTabRevived",
|
"SessionStore:crashedTabRevived",
|
||||||
|
|
||||||
|
// The content script encountered an error.
|
||||||
|
"SessionStore:error",
|
||||||
];
|
];
|
||||||
|
|
||||||
// The list of messages we accept from <xul:browser>s that have no tab
|
// 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.
|
// For a description see above.
|
||||||
"SessionStore:update",
|
"SessionStore:update",
|
||||||
|
|
||||||
|
// For a description see above.
|
||||||
|
"SessionStore:error",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// The list of messages we accept without an "epoch" parameter.
|
// The list of messages we accept without an "epoch" parameter.
|
||||||
@ -95,6 +101,9 @@ const NOEPOCH_MESSAGES = new Set([
|
|||||||
|
|
||||||
// For a description see above.
|
// For a description see above.
|
||||||
"SessionStore:crashedTabRevived",
|
"SessionStore:crashedTabRevived",
|
||||||
|
|
||||||
|
// For a description see above.
|
||||||
|
"SessionStore:error",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// The list of messages we want to receive even during the short period after a
|
// 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.
|
// For a description see above.
|
||||||
"SessionStore:update",
|
"SessionStore:update",
|
||||||
|
|
||||||
|
// For a description see above.
|
||||||
|
"SessionStore:error",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// These are tab events that we listen to.
|
// These are tab events that we listen to.
|
||||||
@ -808,6 +820,9 @@ var SessionStoreInternal = {
|
|||||||
case "SessionStore:crashedTabRevived":
|
case "SessionStore:crashedTabRevived":
|
||||||
this._crashedBrowsers.delete(browser.permanentKey);
|
this._crashedBrowsers.delete(browser.permanentKey);
|
||||||
break;
|
break;
|
||||||
|
case "SessionStore:error":
|
||||||
|
this.reportInternalError(data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`received unknown message '${aMessage.name}'`);
|
throw new Error(`received unknown message '${aMessage.name}'`);
|
||||||
break;
|
break;
|
||||||
@ -3848,6 +3863,19 @@ var SessionStoreInternal = {
|
|||||||
*/
|
*/
|
||||||
resetEpoch(browser) {
|
resetEpoch(browser) {
|
||||||
this._browserEpochs.delete(browser.permanentKey);
|
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",
|
XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
|
||||||
"resource:///modules/sessionstore/SessionStorage.jsm");
|
"resource:///modules/sessionstore/SessionStorage.jsm");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
|
||||||
"@mozilla.org/childprocessmessagemanager;1",
|
|
||||||
"nsISyncMessageSender");
|
|
||||||
|
|
||||||
Cu.import("resource:///modules/sessionstore/FrameTree.jsm", this);
|
Cu.import("resource:///modules/sessionstore/FrameTree.jsm", this);
|
||||||
var gFrameTree = new FrameTree(this);
|
var gFrameTree = new FrameTree(this);
|
||||||
|
|
||||||
@ -692,12 +688,21 @@ var MessageQueue = {
|
|||||||
FX_SESSION_RESTORE_CONTENT_COLLECT_DATA_LONGEST_OP_MS: durationMs
|
FX_SESSION_RESTORE_CONTENT_COLLECT_DATA_LONGEST_OP_MS: durationMs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send all data to the parent process.
|
try {
|
||||||
sendMessage("SessionStore:update", {
|
// Send all data to the parent process.
|
||||||
id: this._id, data, telemetry, flushID,
|
sendMessage("SessionStore:update", {
|
||||||
isFinal: options.isFinal || false,
|
id: this._id, data, telemetry, flushID,
|
||||||
epoch: gCurrentEpoch
|
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.
|
// Increase our unique message ID.
|
||||||
this._id++;
|
this._id++;
|
||||||
|
@ -211,3 +211,4 @@ skip-if = true
|
|||||||
skip-if = os == "mac"
|
skip-if = os == "mac"
|
||||||
|
|
||||||
[browser_911547.js]
|
[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"
|
${If} $R0 == "true"
|
||||||
; Only proceed if we have HKLM write access
|
; Only proceed if we have HKLM write access
|
||||||
${AndIf} $TmpVal == "HKLM"
|
${AndIf} $TmpVal == "HKLM"
|
||||||
; On Windows 2000 we do not install the maintenance service.
|
; On Windows < XP SP3 we do not install the maintenance service.
|
||||||
${AndIf} ${AtLeastWinXP}
|
${If} ${IsWinXP}
|
||||||
; The user is an admin so we should default to install service yes
|
${AndIf} ${AtMostServicePack} 2
|
||||||
StrCpy $InstallMaintenanceService "1"
|
StrCpy $InstallMaintenanceService "0"
|
||||||
|
${Else}
|
||||||
|
; The user is an admin, so we should default to installing the service.
|
||||||
|
StrCpy $InstallMaintenanceService "1"
|
||||||
|
${EndIf}
|
||||||
${Else}
|
${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"
|
StrCpy $InstallMaintenanceService "0"
|
||||||
${EndIf}
|
${EndIf}
|
||||||
${EndIf}
|
${EndIf}
|
||||||
@ -916,10 +920,11 @@ Function preComponents
|
|||||||
Abort
|
Abort
|
||||||
${EndIf}
|
${EndIf}
|
||||||
|
|
||||||
; On Windows 2000 we do not install the maintenance service.
|
; On Windows < XP SP3 we do not install the maintenance service.
|
||||||
${Unless} ${AtLeastWinXP}
|
${If} ${IsWinXP}
|
||||||
|
${AndIf} ${AtMostServicePack} 2
|
||||||
Abort
|
Abort
|
||||||
${EndUnless}
|
${EndIf}
|
||||||
|
|
||||||
; Don't show the custom components page if the
|
; Don't show the custom components page if the
|
||||||
; user is not an admin
|
; user is not an admin
|
||||||
|
@ -1021,9 +1021,19 @@ Function createOptions
|
|||||||
${NSD_Check} $CheckboxSendPing
|
${NSD_Check} $CheckboxSendPing
|
||||||
|
|
||||||
!ifdef MOZ_MAINTENANCE_SERVICE
|
!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
|
Call IsUserAdmin
|
||||||
Pop $0
|
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
|
ClearErrors
|
||||||
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \
|
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \
|
||||||
"Write Test"
|
"Write Test"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
loader.lazyRequireGetter(this, "React",
|
loader.lazyRequireGetter(this, "React",
|
||||||
"resource://devtools/client/shared/vendor/react.js");
|
"devtools/client/shared/vendor/react");
|
||||||
loader.lazyRequireGetter(this, "TargetListComponent",
|
loader.lazyRequireGetter(this, "TargetListComponent",
|
||||||
"devtools/client/aboutdebugging/components/target-list", true);
|
"devtools/client/aboutdebugging/components/target-list", true);
|
||||||
loader.lazyRequireGetter(this, "Services");
|
loader.lazyRequireGetter(this, "Services");
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
loader.lazyRequireGetter(this, "React",
|
loader.lazyRequireGetter(this, "React",
|
||||||
"resource://devtools/client/shared/vendor/react.js");
|
"devtools/client/shared/vendor/react");
|
||||||
loader.lazyRequireGetter(this, "TargetComponent",
|
loader.lazyRequireGetter(this, "TargetComponent",
|
||||||
"devtools/client/aboutdebugging/components/target", true);
|
"devtools/client/aboutdebugging/components/target", true);
|
||||||
loader.lazyRequireGetter(this, "Services");
|
loader.lazyRequireGetter(this, "Services");
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
loader.lazyRequireGetter(this, "React",
|
loader.lazyRequireGetter(this, "React",
|
||||||
"resource://devtools/client/shared/vendor/react.js");
|
"devtools/client/shared/vendor/react");
|
||||||
loader.lazyRequireGetter(this, "TargetFactory",
|
loader.lazyRequireGetter(this, "TargetFactory",
|
||||||
"devtools/client/framework/target", true);
|
"devtools/client/framework/target", true);
|
||||||
loader.lazyRequireGetter(this, "Toolbox",
|
loader.lazyRequireGetter(this, "Toolbox",
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
loader.lazyRequireGetter(this, "Ci",
|
loader.lazyRequireGetter(this, "Ci",
|
||||||
"chrome", true);
|
"chrome", true);
|
||||||
loader.lazyRequireGetter(this, "React",
|
loader.lazyRequireGetter(this, "React",
|
||||||
"resource://devtools/client/shared/vendor/react.js");
|
"devtools/client/shared/vendor/react");
|
||||||
loader.lazyRequireGetter(this, "TargetListComponent",
|
loader.lazyRequireGetter(this, "TargetListComponent",
|
||||||
"devtools/client/aboutdebugging/components/target-list", true);
|
"devtools/client/aboutdebugging/components/target-list", true);
|
||||||
loader.lazyRequireGetter(this, "Services");
|
loader.lazyRequireGetter(this, "Services");
|
||||||
|
@ -34,6 +34,9 @@ const L10N = new ViewHelpers.L10N(STRINGS_URI);
|
|||||||
const MILLIS_TIME_FORMAT_MAX_DURATION = 4000;
|
const MILLIS_TIME_FORMAT_MAX_DURATION = 4000;
|
||||||
// The minimum spacing between 2 time graduation headers in the timeline (px).
|
// The minimum spacing between 2 time graduation headers in the timeline (px).
|
||||||
const TIME_GRADUATION_MIN_SPACING = 40;
|
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
|
* UI component responsible for displaying a preview of the target dom node of
|
||||||
@ -631,7 +634,9 @@ AnimationsTimeline.prototype = {
|
|||||||
parent: this.animationsEl,
|
parent: this.animationsEl,
|
||||||
nodeType: "li",
|
nodeType: "li",
|
||||||
attributes: {
|
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 x = TimeScale.startTimeToDistance(start + (delay / rate), width);
|
||||||
let w = TimeScale.durationToDistance(duration / 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({
|
let iterations = createNode({
|
||||||
parent: this.containerEl,
|
parent: this.containerEl,
|
||||||
@ -809,7 +816,7 @@ AnimationTimeBlock.prototype = {
|
|||||||
// Individual iterations are represented by setting the size of the
|
// Individual iterations are represented by setting the size of the
|
||||||
// repeating linear-gradient.
|
// repeating linear-gradient.
|
||||||
"style": `left:${x}px;
|
"style": `left:${x}px;
|
||||||
width:${w * (count || 1)}px;
|
width:${iterationW}px;
|
||||||
background-size:${Math.max(w, 2)}px 100%;`
|
background-size:${Math.max(w, 2)}px 100%;`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -817,15 +824,17 @@ AnimationTimeBlock.prototype = {
|
|||||||
// The animation name is displayed over the iterations.
|
// The animation name is displayed over the iterations.
|
||||||
// Note that in case of negative delay, we push the name towards the right
|
// Note that in case of negative delay, we push the name towards the right
|
||||||
// so the delay can be shown.
|
// so the delay can be shown.
|
||||||
|
let negativeDelayW = delay < 0 ? delayW : 0;
|
||||||
createNode({
|
createNode({
|
||||||
parent: iterations,
|
parent: iterations,
|
||||||
attributes: {
|
attributes: {
|
||||||
"class": "name",
|
"class": "name",
|
||||||
"title": this.getTooltipText(state),
|
"title": this.getTooltipText(state),
|
||||||
"style": delay < 0
|
// Position the fast-track icon with background-position, and make space
|
||||||
? "margin-left:" +
|
// for the negative delay with a margin-left.
|
||||||
TimeScale.durationToDistance(Math.abs(delay), width) + "px"
|
"style": "background-position:" +
|
||||||
: ""
|
(iterationW - FAST_TRACK_ICON_SIZE - negativeDelayW) +
|
||||||
|
"px center;margin-left:" + negativeDelayW + "px"
|
||||||
},
|
},
|
||||||
textContent: state.name
|
textContent: state.name
|
||||||
});
|
});
|
||||||
@ -835,9 +844,6 @@ AnimationTimeBlock.prototype = {
|
|||||||
// Negative delays need to start at 0.
|
// Negative delays need to start at 0.
|
||||||
let delayX = TimeScale.durationToDistance(
|
let delayX = TimeScale.durationToDistance(
|
||||||
(delay < 0 ? 0 : delay) / rate, width);
|
(delay < 0 ? 0 : delay) / rate, width);
|
||||||
let delayW = TimeScale.durationToDistance(
|
|
||||||
Math.abs(delay) / rate, width);
|
|
||||||
|
|
||||||
createNode({
|
createNode({
|
||||||
parent: iterations,
|
parent: iterations,
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -864,6 +870,9 @@ AnimationTimeBlock.prototype = {
|
|||||||
let iterations = L10N.getStr("player.animationIterationCountLabel") + " " +
|
let iterations = L10N.getStr("player.animationIterationCountLabel") + " " +
|
||||||
(state.iterationCount ||
|
(state.iterationCount ||
|
||||||
L10N.getStr("player.infiniteIterationCountText"));
|
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_added_animation.js]
|
||||||
[browser_animation_refresh_on_removed_animation.js]
|
[browser_animation_refresh_on_removed_animation.js]
|
||||||
[browser_animation_refresh_when_active.js]
|
[browser_animation_refresh_when_active.js]
|
||||||
|
[browser_animation_running_on_compositor.js]
|
||||||
[browser_animation_same_nb_of_playerWidgets_and_playerFronts.js]
|
[browser_animation_same_nb_of_playerWidgets_and_playerFronts.js]
|
||||||
[browser_animation_shows_player_on_valid_node.js]
|
[browser_animation_shows_player_on_valid_node.js]
|
||||||
[browser_animation_target_highlight_select.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;
|
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 {
|
@keyframes simple-animation {
|
||||||
100% {
|
100% {
|
||||||
transform: translateX(300px);
|
transform: translateX(300px);
|
||||||
@ -85,6 +93,12 @@
|
|||||||
background: blue;
|
background: blue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes no-compositor {
|
||||||
|
100% {
|
||||||
|
margin-right: 600px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -97,5 +111,6 @@
|
|||||||
<div class="ball short"></div>
|
<div class="ball short"></div>
|
||||||
<div class="ball long"></div>
|
<div class="ball long"></div>
|
||||||
<div class="ball negative-delay"></div>
|
<div class="ball negative-delay"></div>
|
||||||
|
<div class="ball no-compositor"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -341,6 +341,12 @@ body {
|
|||||||
padding: 0 2px;
|
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 {
|
.animation-timeline .animation .delay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="12">
|
<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)">
|
<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>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 514 B |
@ -306,6 +306,8 @@ var interfaceNamesInGlobalScope =
|
|||||||
"ChannelSplitterNode",
|
"ChannelSplitterNode",
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
"CharacterData",
|
"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!
|
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||||
{name: "ChromeWindow", xbl: true},
|
{name: "ChromeWindow", xbl: true},
|
||||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
// 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/.
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[ChromeOnly, Constructor]
|
[Constructor, Func="IsChromeOrXBL"]
|
||||||
interface ChromeNodeList : NodeList {
|
interface ChromeNodeList : NodeList {
|
||||||
[Throws]
|
[Throws]
|
||||||
void append(Node aNode);
|
void append(Node aNode);
|
||||||
|
@ -602,6 +602,8 @@ public class GeckoEvent {
|
|||||||
int value) {
|
int value) {
|
||||||
GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_HISTOGRAM_ADD);
|
GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_HISTOGRAM_ADD);
|
||||||
event.mCharacters = histogram;
|
event.mCharacters = histogram;
|
||||||
|
// Set the extras with null so that it cannot be mistaken with a keyed histogram.
|
||||||
|
event.mCharactersExtra = null;
|
||||||
event.mCount = value;
|
event.mCount = value;
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +267,10 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onAttachedToWindow() {
|
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
|
// This check should not be done before the view is attached to a window
|
||||||
// as hardware acceleration will not be enabled at that point.
|
// as hardware acceleration will not be enabled at that point.
|
||||||
// We must create and add the SurfaceView instance before the view tree
|
// 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);
|
TabQueueHelper.removeURLFromFile(applicationContext, intentUrl, TabQueueHelper.FILE_NAME);
|
||||||
}
|
}
|
||||||
openNow(safeIntent.getUnsafe());
|
openNow(safeIntent.getUnsafe());
|
||||||
|
|
||||||
|
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "tabqueue-doubletap");
|
||||||
stopSelfResult(startId);
|
stopSelfResult(startId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -186,6 +188,8 @@ public class TabQueueService extends Service {
|
|||||||
stopServiceRunnable = null;
|
stopServiceRunnable = null;
|
||||||
removeView();
|
removeView();
|
||||||
openNow(intent);
|
openNow(intent);
|
||||||
|
|
||||||
|
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "tabqueue-now");
|
||||||
stopSelfResult(startId);
|
stopSelfResult(startId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -207,8 +211,6 @@ public class TabQueueService extends Service {
|
|||||||
.remove(GeckoPreferences.PREFS_TAB_QUEUE_LAST_TIME)
|
.remove(GeckoPreferences.PREFS_TAB_QUEUE_LAST_TIME)
|
||||||
.apply();
|
.apply();
|
||||||
|
|
||||||
Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, "tabqueue-now");
|
|
||||||
|
|
||||||
executorService.submit(new Runnable() {
|
executorService.submit(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -130,6 +130,7 @@ skip-if = android_version == "10" || android_version == "18"
|
|||||||
# disabled on 4.3, bug 1158363
|
# disabled on 4.3, bug 1158363
|
||||||
skip-if = android_version == "18"
|
skip-if = android_version == "18"
|
||||||
[src/org/mozilla/gecko/tests/testUITelemetry.java]
|
[src/org/mozilla/gecko/tests/testUITelemetry.java]
|
||||||
|
[src/org/mozilla/gecko/tests/testBug1217581.java]
|
||||||
[src/org/mozilla/gecko/tests/testVideoControls.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
|
# 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"
|
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/mach_types.h>
|
||||||
#include <mach/message.h>
|
#include <mach/message.h>
|
||||||
#include <mach/thread_info.h>
|
#include <mach/thread_info.h>
|
||||||
#endif // defined(XP_MACOSX)
|
#elif defined(XP_UNIX)
|
||||||
|
|
||||||
#if defined(XP_LINUX)
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#endif // defined(XP_LINUX)
|
#endif // defined(XP_UNIX)
|
||||||
/* ------------------------------------------------------
|
/* ------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Utility functions.
|
* Utility functions.
|
||||||
|
@ -4352,6 +4352,12 @@
|
|||||||
"extended_statistics_ok": true,
|
"extended_statistics_ok": true,
|
||||||
"description": "Session restore: Time spent blocking the main thread while restoring a window state (ms)"
|
"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": {
|
"FX_TABLETMODE_PAGE_LOAD": {
|
||||||
"expires_in_version": "47",
|
"expires_in_version": "47",
|
||||||
"kind": "exponential",
|
"kind": "exponential",
|
||||||
@ -4725,6 +4731,7 @@
|
|||||||
"kind": "linear",
|
"kind": "linear",
|
||||||
"high": "13",
|
"high": "13",
|
||||||
"n_buckets": 12,
|
"n_buckets": 12,
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "Number of directories in the archive at scan"
|
"description": "Number of directories in the archive at scan"
|
||||||
},
|
},
|
||||||
"TELEMETRY_ARCHIVE_OLDEST_DIRECTORY_AGE": {
|
"TELEMETRY_ARCHIVE_OLDEST_DIRECTORY_AGE": {
|
||||||
@ -4733,6 +4740,7 @@
|
|||||||
"kind": "linear",
|
"kind": "linear",
|
||||||
"high": "13",
|
"high": "13",
|
||||||
"n_buckets": 12,
|
"n_buckets": 12,
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "The age of the oldest Telemetry archive directory in months"
|
"description": "The age of the oldest Telemetry archive directory in months"
|
||||||
},
|
},
|
||||||
"TELEMETRY_ARCHIVE_SCAN_PING_COUNT": {
|
"TELEMETRY_ARCHIVE_SCAN_PING_COUNT": {
|
||||||
@ -4741,12 +4749,14 @@
|
|||||||
"kind": "exponential",
|
"kind": "exponential",
|
||||||
"high": "100000",
|
"high": "100000",
|
||||||
"n_buckets": 100,
|
"n_buckets": 100,
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "Number of Telemetry pings in the archive at scan"
|
"description": "Number of Telemetry pings in the archive at scan"
|
||||||
},
|
},
|
||||||
"TELEMETRY_ARCHIVE_SESSION_PING_COUNT": {
|
"TELEMETRY_ARCHIVE_SESSION_PING_COUNT": {
|
||||||
"alert_emails": ["telemetry-client-dev@mozilla.com"],
|
"alert_emails": ["telemetry-client-dev@mozilla.com"],
|
||||||
"expires_in_version": "never",
|
"expires_in_version": "never",
|
||||||
"kind": "count",
|
"kind": "count",
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "Number of Telemetry pings added to the archive during the session"
|
"description": "Number of Telemetry pings added to the archive during the session"
|
||||||
},
|
},
|
||||||
"TELEMETRY_ARCHIVE_SIZE_MB": {
|
"TELEMETRY_ARCHIVE_SIZE_MB": {
|
||||||
@ -4755,6 +4765,7 @@
|
|||||||
"kind": "linear",
|
"kind": "linear",
|
||||||
"high": "300",
|
"high": "300",
|
||||||
"n_buckets": 60,
|
"n_buckets": 60,
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "The size of the Telemetry archive (MB)"
|
"description": "The size of the Telemetry archive (MB)"
|
||||||
},
|
},
|
||||||
"TELEMETRY_ARCHIVE_EVICTED_OVER_QUOTA": {
|
"TELEMETRY_ARCHIVE_EVICTED_OVER_QUOTA": {
|
||||||
@ -4763,6 +4774,7 @@
|
|||||||
"kind": "exponential",
|
"kind": "exponential",
|
||||||
"high": "100000",
|
"high": "100000",
|
||||||
"n_buckets": 100,
|
"n_buckets": 100,
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "Number of Telemetry pings evicted from the archive during cleanup, because they were over the quota"
|
"description": "Number of Telemetry pings evicted from the archive during cleanup, because they were over the quota"
|
||||||
},
|
},
|
||||||
"TELEMETRY_ARCHIVE_EVICTED_OLD_DIRS": {
|
"TELEMETRY_ARCHIVE_EVICTED_OLD_DIRS": {
|
||||||
@ -4771,6 +4783,7 @@
|
|||||||
"kind": "linear",
|
"kind": "linear",
|
||||||
"high": "13",
|
"high": "13",
|
||||||
"n_buckets": 12,
|
"n_buckets": 12,
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "Number of Telemetry directories evicted from the archive during cleanup, because they were too old"
|
"description": "Number of Telemetry directories evicted from the archive during cleanup, because they were too old"
|
||||||
},
|
},
|
||||||
"TELEMETRY_ARCHIVE_EVICTING_DIRS_MS": {
|
"TELEMETRY_ARCHIVE_EVICTING_DIRS_MS": {
|
||||||
@ -4779,6 +4792,7 @@
|
|||||||
"kind": "exponential",
|
"kind": "exponential",
|
||||||
"high": "300000",
|
"high": "300000",
|
||||||
"n_buckets": 20,
|
"n_buckets": 20,
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "Time (ms) it takes for evicting old directories"
|
"description": "Time (ms) it takes for evicting old directories"
|
||||||
},
|
},
|
||||||
"TELEMETRY_ARCHIVE_CHECKING_OVER_QUOTA_MS": {
|
"TELEMETRY_ARCHIVE_CHECKING_OVER_QUOTA_MS": {
|
||||||
@ -4787,6 +4801,7 @@
|
|||||||
"kind": "exponential",
|
"kind": "exponential",
|
||||||
"high": "300000",
|
"high": "300000",
|
||||||
"n_buckets": 20,
|
"n_buckets": 20,
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "Time (ms) it takes for checking if the archive is over-quota"
|
"description": "Time (ms) it takes for checking if the archive is over-quota"
|
||||||
},
|
},
|
||||||
"TELEMETRY_ARCHIVE_EVICTING_OVER_QUOTA_MS": {
|
"TELEMETRY_ARCHIVE_EVICTING_OVER_QUOTA_MS": {
|
||||||
@ -4795,6 +4810,7 @@
|
|||||||
"kind": "exponential",
|
"kind": "exponential",
|
||||||
"high": "300000",
|
"high": "300000",
|
||||||
"n_buckets": 20,
|
"n_buckets": 20,
|
||||||
|
"bug_numbers": [1162538],
|
||||||
"description": "Time (ms) it takes for evicting over-quota pings"
|
"description": "Time (ms) it takes for evicting over-quota pings"
|
||||||
},
|
},
|
||||||
"TELEMETRY_PENDING_LOAD_FAILURE_READ": {
|
"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
|
return ret_array
|
||||||
|
|
||||||
always_allowed_keys = ['kind', 'description', 'cpp_guard', 'expires_in_version',
|
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:
|
class Histogram:
|
||||||
"""A class for representing a histogram definition."""
|
"""A class for representing a histogram definition."""
|
||||||
@ -209,6 +222,7 @@ is enabled."""
|
|||||||
lambda allowed_keys: Histogram.check_keys(name, definition, allowed_keys))
|
lambda allowed_keys: Histogram.check_keys(name, definition, allowed_keys))
|
||||||
|
|
||||||
Histogram.check_expiration(name, definition)
|
Histogram.check_expiration(name, definition)
|
||||||
|
Histogram.check_bug_numbers(name, definition)
|
||||||
|
|
||||||
def check_name(self, name):
|
def check_name(self, name):
|
||||||
if '#' in name:
|
if '#' in name:
|
||||||
@ -228,6 +242,18 @@ is enabled."""
|
|||||||
|
|
||||||
definition['expires_in_version'] = expiration
|
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
|
@staticmethod
|
||||||
def check_keys(name, definition, allowed_keys):
|
def check_keys(name, definition, allowed_keys):
|
||||||
for key in definition.iterkeys():
|
for key in definition.iterkeys():
|
||||||
@ -243,6 +269,11 @@ is enabled."""
|
|||||||
self._low = try_to_coerce_to_number(low)
|
self._low = try_to_coerce_to_number(low)
|
||||||
self._high = try_to_coerce_to_number(high)
|
self._high = try_to_coerce_to_number(high)
|
||||||
self._n_buckets = try_to_coerce_to_number(n_buckets)
|
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
|
@staticmethod
|
||||||
def boolean_flag_bucket_parameters(definition):
|
def boolean_flag_bucket_parameters(definition):
|
||||||
|
@ -158,7 +158,8 @@ this.PageThumbs = {
|
|||||||
*/
|
*/
|
||||||
getThumbnailURL: function PageThumbs_getThumbnailURL(aUrl) {
|
getThumbnailURL: function PageThumbs_getThumbnailURL(aUrl) {
|
||||||
return this.scheme + "://" + this.staticHost +
|
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));
|
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.
|
* 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,
|
msg /*we don't want that message garbage-collected,
|
||||||
as OS.Shared.Type.void_t.in_ptr.toMsg uses C-level
|
as OS.Shared.Type.void_t.in_ptr.toMsg uses C-level
|
||||||
memory tricks to enforce zero-copy*/).
|
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 targetFile = this.getFilePathForURL(aTargetURL);
|
||||||
let options = { noOverwrite: aNoOverwrite };
|
let options = { noOverwrite: aNoOverwrite };
|
||||||
return PageThumbsWorker.post("copy", [sourceFile, targetFile, options]).
|
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:
|
* 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/'.
|
* 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";
|
"use strict";
|
||||||
|
@ -88,11 +88,6 @@ function capIfStaleErrorResponseUpdateTest() {
|
|||||||
yield addTab(URL);
|
yield addTab(URL);
|
||||||
|
|
||||||
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
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
|
// update the thumbnail to be stale, then re-request it. The server will
|
||||||
// return a 400 response and a red thumbnail.
|
// return a 400 response and a red thumbnail.
|
||||||
// The service should not save the thumbnail - so we (a) check the thumbnail
|
// The service should not save the thumbnail - so we (a) check the thumbnail
|
||||||
@ -124,11 +119,6 @@ function capIfStaleGoodResponseUpdateTest() {
|
|||||||
let browser = gBrowser.selectedBrowser;
|
let browser = gBrowser.selectedBrowser;
|
||||||
|
|
||||||
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
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
|
// 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
|
// return a 200 response and a red thumbnail - so that new thumbnail should
|
||||||
// end up captured.
|
// end up captured.
|
||||||
@ -158,11 +148,6 @@ function regularCapErrorResponseUpdateTest() {
|
|||||||
yield addTab(URL);
|
yield addTab(URL);
|
||||||
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
||||||
gBrowser.removeTab(gBrowser.selectedTab);
|
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
|
// do it again - the server will return a 400, so the foreground service
|
||||||
// should not update it.
|
// should not update it.
|
||||||
yield addTab(URL);
|
yield addTab(URL);
|
||||||
@ -177,11 +162,6 @@ function regularCapGoodResponseUpdateTest() {
|
|||||||
yield addTab(URL);
|
yield addTab(URL);
|
||||||
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
yield captureAndCheckColor(0, 255, 0, "we have a green thumbnail");
|
||||||
gBrowser.removeTab(gBrowser.selectedTab);
|
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
|
// do it again - the server will return a 200, so the foreground service
|
||||||
// should update it.
|
// should update it.
|
||||||
yield addTab(URL);
|
yield addTab(URL);
|
||||||
|
@ -145,33 +145,21 @@ function captureAndCheckColor(aRed, aGreen, aBlue, aMessage) {
|
|||||||
function retrieveImageDataForURL(aURL, aCallback) {
|
function retrieveImageDataForURL(aURL, aCallback) {
|
||||||
let width = 100, height = 100;
|
let width = 100, height = 100;
|
||||||
let thumb = PageThumbs.getThumbnailURL(aURL, width, height);
|
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 htmlns = "http://www.w3.org/1999/xhtml";
|
||||||
let canvas = document.createElementNS(htmlns, "canvas");
|
let img = document.createElementNS(htmlns, "img");
|
||||||
canvas.setAttribute("width", width);
|
img.setAttribute("src", thumb);
|
||||||
canvas.setAttribute("height", height);
|
|
||||||
|
|
||||||
// Draw the image to a canvas and compare the pixel color values.
|
whenLoaded(img, function () {
|
||||||
let ctx = canvas.getContext("2d");
|
let canvas = document.createElementNS(htmlns, "canvas");
|
||||||
ctx.drawImage(img, 0, 0, width, height);
|
canvas.setAttribute("width", width);
|
||||||
let result = ctx.getImageData(0, 0, 100, 100).data;
|
canvas.setAttribute("height", height);
|
||||||
gBrowser.removeTab(gBrowser.selectedTab);
|
|
||||||
aCallback(result);
|
// 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>
|
</setter>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
<field name="selectedItems">[]</field>
|
<field name="selectedItems">new ChromeNodeList()</field>
|
||||||
|
|
||||||
<method name="addItemToSelection">
|
<method name="addItemToSelection">
|
||||||
<parameter name="aItem"/>
|
<parameter name="aItem"/>
|
||||||
@ -186,7 +186,7 @@
|
|||||||
if (aItem.selected)
|
if (aItem.selected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.selectedItems.push(aItem);
|
this.selectedItems.append(aItem);
|
||||||
aItem.selected = true;
|
aItem.selected = true;
|
||||||
|
|
||||||
this._fireOnSelect();
|
this._fireOnSelect();
|
||||||
@ -201,14 +201,8 @@
|
|||||||
if (!aItem.selected)
|
if (!aItem.selected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (var i = 0; i < this.selectedItems.length; ++i) {
|
this.selectedItems.remove(aItem);
|
||||||
if (this.selectedItems[i] == aItem) {
|
aItem.selected = false;
|
||||||
this.selectedItems.splice(i, 1);
|
|
||||||
aItem.selected = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._fireOnSelect();
|
this._fireOnSelect();
|
||||||
]]>
|
]]>
|
||||||
</body>
|
</body>
|
||||||
@ -355,10 +349,11 @@
|
|||||||
<body>
|
<body>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
if (this.selectedItems) {
|
if (this.selectedItems) {
|
||||||
for (var i = this.selectedItems.length - 1; i >= 0; --i)
|
while (this.selectedItems.length > 0) {
|
||||||
this.selectedItems[i].selected = false;
|
let item = this.selectedItems[0];
|
||||||
|
item.selected = false;
|
||||||
this.selectedItems.length = 0;
|
this.selectedItems.remove(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._selectionStart = null;
|
this._selectionStart = null;
|
||||||
@ -700,7 +695,7 @@
|
|||||||
for (var index = 0; index < count; index++) {
|
for (var index = 0; index < count; index++) {
|
||||||
var item = this.getItemAtIndex(index);
|
var item = this.getItemAtIndex(index);
|
||||||
if (item.getAttribute("selected") == "true")
|
if (item.getAttribute("selected") == "true")
|
||||||
this.selectedItems.push(item);
|
this.selectedItems.append(item);
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
</constructor>
|
</constructor>
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
var state = this.currentItem ? this.currentItem.id : "";
|
var state = this.currentItem ? this.currentItem.id : "";
|
||||||
if (this.selType == "multiple" && this.selectedCount) {
|
if (this.selType == "multiple" && this.selectedCount) {
|
||||||
let getId = function getId(aItem) { return aItem.id; }
|
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)
|
if (state)
|
||||||
this.setAttribute("last-selected", state);
|
this.setAttribute("last-selected", state);
|
||||||
@ -393,13 +393,17 @@
|
|||||||
// try to restore the selected items according to their IDs
|
// try to restore the selected items according to their IDs
|
||||||
// (applies after a template rebuild, if last-selected was not set)
|
// (applies after a template rebuild, if last-selected was not set)
|
||||||
if (this.selectedItems) {
|
if (this.selectedItems) {
|
||||||
|
let itemIds = [];
|
||||||
for (i = this.selectedCount - 1; i >= 0; i--) {
|
for (i = this.selectedCount - 1; i >= 0; i--) {
|
||||||
if (this.selectedItems[i] && this.selectedItems[i].id)
|
let selectedItem = this.selectedItems[i];
|
||||||
this.selectedItems[i] = document.getElementById(this.selectedItems[i].id);
|
itemIds.push(selectedItem.id);
|
||||||
else
|
this.selectedItems.remove(selectedItem);
|
||||||
this.selectedItems[i] = null;
|
}
|
||||||
if (!this.selectedItems[i])
|
for (i = 0; i < itemIds.length; i++) {
|
||||||
this.selectedItems.splice(i, 1);
|
let selectedItem = document.getElementById(itemIds[i]);
|
||||||
|
if (selectedItem) {
|
||||||
|
this.selectedItems.append(selectedItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.currentItem && this.currentItem.id)
|
if (this.currentItem && this.currentItem.id)
|
||||||
@ -417,7 +421,7 @@
|
|||||||
var children = this.children;
|
var children = this.children;
|
||||||
for (var i = 0; i < children.length; ++i) {
|
for (var i = 0; i < children.length; ++i) {
|
||||||
if (children[i].getAttribute("selected") == "true")
|
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.
|
* @return true if the service should be used for updates.
|
||||||
*/
|
*/
|
||||||
function shouldUseService() {
|
function shouldUseService() {
|
||||||
if (AppConstants.MOZ_MAINTENANCE_SERVICE && isServiceInstalled()) {
|
// This function will return true if the mantenance service should be used if
|
||||||
return getPref("getBoolPref",
|
// all of the following conditions are met:
|
||||||
PREF_APP_UPDATE_SERVICE_ENABLED, false);
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user