Merge mozilla-central into services-central

This commit is contained in:
Gregory Szorc 2012-08-03 14:12:09 -07:00
Родитель 1cfbabc9fb 6d09b2c201
Коммит 89af42f6ad
70 изменённых файлов: 917 добавлений и 212 удалений

Просмотреть файл

@ -202,6 +202,7 @@
</html:select>
</markup>
<!-- Temporarily disabled for causing bug 733848
<markup ref="html:img" ruleset="htmlimage">
<html:span id="l1" a11yname="test2">test2</html:span>
<html:span id="l2" a11yname="test3">test3</html:span>
@ -223,6 +224,7 @@
alt=""
src="../moz.png"/>
</markup>
-->
<markup ref="html:table/html:tr/html:td" ruleset="htmlelm"
id="markup4test">

Просмотреть файл

@ -77,14 +77,17 @@ const gXPInstallObserver = {
messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
[brandShortName, installInfo.originatingURI.host]);
let secHistogram = Components.classes["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry).getHistogramById("SECURITY_UI");
action = {
label: gNavigatorBundle.getString("xpinstallPromptAllowButton"),
accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"),
callback: function() {
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_ADDON_ASKING_PREVENTED_CLICK_THROUGH);
installInfo.install();
}
};
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_ADDON_ASKING_PREVENTED);
PopupNotifications.show(browser, notificationID, messageString, anchorID,
action, null, options);
break;

Просмотреть файл

@ -160,10 +160,10 @@ let SocialShareButton = {
updateProfileInfo: function SSB_updateProfileInfo() {
let profileRow = document.getElementById("editSharePopupHeader");
let profile = Social.provider.profile;
if (profile && profile.portrait && profile.displayName) {
if (profile && profile.displayName) {
profileRow.hidden = false;
let portrait = document.getElementById("socialUserPortrait");
portrait.style.listStyleImage = profile.portrait;
portrait.setAttribute("src", profile.portrait || "chrome://browser/skin/social/social.png");
let displayName = document.getElementById("socialUserDisplayName");
displayName.setAttribute("label", profile.displayName);
} else {

Просмотреть файл

@ -2519,9 +2519,13 @@ let BrowserOnClick = {
onAboutCertError: function BrowserOnClick_onAboutCertError(aTargetElm, aOwnerDoc) {
let elmId = aTargetElm.getAttribute("id");
let secHistogram = Cc["@mozilla.org/base/telemetry;1"].
getService(Ci.nsITelemetry).
getHistogramById("SECURITY_UI");
switch (elmId) {
case "exceptionDialogButton":
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_CLICK_ADD_EXCEPTION);
let params = { exceptionAdded : false, handlePrivateBrowsing : true };
try {
@ -2545,21 +2549,37 @@ let BrowserOnClick = {
break;
case "getMeOutOfHereButton":
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_GET_ME_OUT_OF_HERE);
getMeOutOfHere();
break;
case "technicalContent":
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_TECHNICAL_DETAILS);
break;
case "expertContent":
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_BAD_CERT_UNDERSTAND_RISKS);
break;
}
},
onAboutBlocked: function BrowserOnClick_onAboutBlocked(aTargetElm, aOwnerDoc) {
let elmId = aTargetElm.getAttribute("id");
let secHistogram = Cc["@mozilla.org/base/telemetry;1"].
getService(Ci.nsITelemetry).
getHistogramById("SECURITY_UI");
// The event came from a button on a malware/phishing block page
// First check whether it's malware or phishing, so that we can
// use the right strings/links
let isMalware = /e=malwareBlocked/.test(aOwnerDoc.documentURI);
let bucketName = isMalware ? "WARNING_MALWARE_PAGE_":"WARNING_PHISHING_PAGE_";
let nsISecTel = Ci.nsISecurityUITelemetry;
switch (elmId) {
case "getMeOutButton":
secHistogram.add(nsISecTel[bucketName + "GET_ME_OUT_OF_HERE"]);
getMeOutOfHere();
break;
@ -2568,6 +2588,10 @@ let BrowserOnClick = {
// we can fetch a site-specific report, for phishing, we redirect
// to the generic page describing phishing protection.
// We log even if malware/phishing info URL couldn't be found:
// the measurement is for how many users clicked the WHY BLOCKED button
secHistogram.add(nsISecTel[bucketName + "WHY_BLOCKED"]);
if (isMalware) {
// Get the stop badware "why is this blocked" report url,
// append the current url, and go there.
@ -2589,6 +2613,7 @@ let BrowserOnClick = {
break;
case "ignoreWarningButton":
secHistogram.add(nsISecTel[bucketName + "IGNORE_WARNING"]);
this.ignoreWarningButton(isMalware);
break;
}

Просмотреть файл

@ -23,7 +23,7 @@ function test() {
var tests = {
testProfileSet: function(next) {
let profile = {
portrait: "chrome://branding/content/icon48.png",
portrait: "https://example.com/portrait.jpg",
userName: "trickster",
displayName: "Kuma Lisa",
profileURL: "http://en.wikipedia.org/wiki/Kuma_Lisa"
@ -31,7 +31,7 @@ var tests = {
Social.provider.updateUserProfile(profile);
// check dom values
let portrait = document.getElementById("social-statusarea-user-portrait").getAttribute("src");
is(portrait, profile.portrait, "portrait is set");
is(profile.portrait, portrait, "portrait is set");
let userButton = document.getElementById("social-statusarea-username");
ok(!userButton.hidden, "username is visible");
is(userButton.label, profile.userName, "username is set");

Просмотреть файл

@ -611,7 +611,6 @@ WebConsole.prototype = {
let position = Services.prefs.getCharPref("devtools.webconsole.position");
this.positionConsole(position);
this._currentUIPosition = position;
},
/**
@ -622,8 +621,10 @@ WebConsole.prototype = {
{
this.iframe.removeEventListener("load", this._onIframeLoad, true);
let position = Services.prefs.getCharPref("devtools.webconsole.position");
this.iframeWindow = this.iframe.contentWindow.wrappedJSObject;
this.ui = new this.iframeWindow.WebConsoleFrame(this, this._currentUIPosition);
this.ui = new this.iframeWindow.WebConsoleFrame(this, position);
this._setupMessageManager();
},
@ -695,8 +696,6 @@ WebConsole.prototype = {
this.iframe.flex = 1;
panel.setAttribute("height", height);
this._afterPositionConsole("window", lastIndex);
}).bind(this);
panel.addEventListener("popupshown", onPopupShown,false);
@ -736,6 +735,9 @@ WebConsole.prototype = {
if (this.splitter.parentNode) {
this.splitter.parentNode.removeChild(this.splitter);
}
this._beforePositionConsole("window", lastIndex);
panel.appendChild(this.iframe);
let space = this.chromeDocument.createElement("spacer");
@ -822,6 +824,8 @@ WebConsole.prototype = {
this.splitter.parentNode.removeChild(this.splitter);
}
this._beforePositionConsole(aPosition, lastIndex);
if (aPosition == "below") {
nBox.appendChild(this.splitter);
nBox.appendChild(this.iframe);
@ -841,12 +845,10 @@ WebConsole.prototype = {
this.iframe.removeAttribute("height");
this.iframe.style.height = height + "px";
}
this._afterPositionConsole(aPosition, lastIndex);
},
/**
* Common code that needs to execute after the Web Console is repositioned.
* Common code that needs to execute before the Web Console is repositioned.
* @private
* @param string aPosition
* The new position: "above", "below" or "window".
@ -854,8 +856,8 @@ WebConsole.prototype = {
* The last visible message in the console output before repositioning
* occurred.
*/
_afterPositionConsole:
function WC__afterPositionConsole(aPosition, aLastIndex)
_beforePositionConsole:
function WC__beforePositionConsole(aPosition, aLastIndex)
{
if (!this.ui) {
return;

Просмотреть файл

@ -37,7 +37,7 @@ function waitForPosition(aPosition, aCallback) {
{
return hudRef._currentUIPosition == aPosition;
},
successFn: aCallback,
successFn: executeSoon.bind(null, aCallback),
failureFn: finishTest,
});
}
@ -55,9 +55,10 @@ function consoleOpened(aHudRef) {
"position menu checkbox is below");
is(Services.prefs.getCharPref(POSITION_PREF), "below", "pref is below");
hudRef.positionConsole("above");
waitForPosition("above", onPositionAbove);
executeSoon(function() {
hudRef.positionConsole("above");
waitForPosition("above", onPositionAbove);
});
}
function onPositionAbove() {
@ -81,8 +82,10 @@ function onPositionAbove() {
Services.prefs.setIntPref(TOP_PREF, 50);
Services.prefs.setIntPref(LEFT_PREF, 51);
hudRef.positionConsole("window");
waitForPosition("window", onPositionWindow);
executeSoon(function() {
hudRef.positionConsole("window");
waitForPosition("window", onPositionWindow);
});
}
function onPositionWindow() {

Просмотреть файл

@ -55,6 +55,24 @@ public:
NS_DECL_NSIXHRSENDABLE
NS_DECL_NSIMUTABLE
void
SetLazyData(const nsAString& aName, const nsAString& aContentType,
PRUint64 aLength)
{
NS_ASSERTION(aLength, "must have length");
mName = aName;
mContentType = aContentType;
mLength = aLength;
mIsFile = !aName.IsVoid();
}
bool IsSizeUnknown() const
{
return mLength == UINT64_MAX;
}
protected:
nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
PRUint64 aLength)
@ -86,11 +104,6 @@ protected:
virtual ~nsDOMFileBase() {}
bool IsSizeUnknown() const
{
return mLength == UINT64_MAX;
}
virtual bool IsStoredFile() const
{
return false;

Просмотреть файл

@ -105,16 +105,13 @@ MOCHITEST_FILES = \
test_reactivate.html \
test_readyState.html \
test_replay_metadata.html \
test_seek.html \
test_seek2.html \
test_seek_out_of_range.html \
test_source.html \
test_source_write.html \
test_source_null.html \
test_standalone.html \
test_streams_element_capture.html \
test_streams_element_capture_reset.html \
test_timeupdate_small_files.html \
test_too_many_elements.html \
test_volume.html \
test_video_to_canvas.html \
@ -122,10 +119,6 @@ MOCHITEST_FILES = \
test_audiowrite.html \
test_mozHasAudio.html \
test_source_media.html \
$(NULL)
# Bug 759221
MOCHITEST_FILES += \
test_autoplay_contentEditable.html \
test_buffered.html \
test_bug448534.html \
@ -136,6 +129,19 @@ MOCHITEST_FILES += \
test_seekLies.html \
$(NULL)
# Tests disabled on Linux for frequent intermittent failures
ifneq (Linux,$(OS_ARCH))
MOCHITEST_FILES += \
test_seek.html \
test_seek_out_of_range.html \
test_timeupdate_small_files.html \
$(NULL)
else
$(warning test_seek.html is disabled on Linux for timeouts. Bug 620598)
$(warning test_seek_out_of_range.html is disabled on Linux for timeouts. Bug 661076)
$(warning test_timeupdate_small_files.html is disabled on Linux for timeouts. Bug 687972)
endif
# Don't run in suite
ifndef MOZ_SUITE
MOCHITEST_FILES += test_play_twice.html

Просмотреть файл

@ -7,7 +7,7 @@
var gSmallTests = [
{ name:"small-shot.ogg", type:"audio/ogg", duration:0.276 },
{ name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233 },
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266 },
{ name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 },
{ name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 },
{ name:"bogus.duh", type:"bogus/duh" }
@ -19,7 +19,7 @@ var gProgressTests = [
{ name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0, size:11069 },
{ name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 },
{ name:"seek.ogv", type:"video/ogg", duration:3.966, size:285310 },
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942 },
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, size:28942 },
{ name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
{ name:"bogus.duh", type:"bogus/duh" }
];
@ -40,7 +40,7 @@ var gCloneTests = gSmallTests.concat([
{ name:"bug520908.ogv", type:"video/ogg", duration:9000 },
// short-video is more like 1s, so if you load this twice you'll get an unexpected duration
{ name:"dynamic_resource.sjs?key=" + cloneKey + "&res1=320x240.ogv&res2=short-video.ogv",
type:"video/ogg", duration:0.233 },
type:"video/ogg", duration:0.266 },
]);
// Used by test_play_twice. Need one test file per decoder backend, plus
@ -59,7 +59,7 @@ var gPausedAfterEndedTests = gSmallTests.concat([
// Test the mozHasAudio property
var gMozHasAudioTests = [
{ name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444, hasAudio:undefined },
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942, hasAudio:false },
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.266, size:28942, hasAudio:false },
{ name:"short-video.ogv", type:"video/ogg", duration:1.081, hasAudio:true },
{ name:"seek.webm", type:"video/webm", duration:3.966, size:215529, hasAudio:false },
{ name:"bogus.duh", type:"bogus/duh" }
@ -128,7 +128,7 @@ var gPlayTests = [
// Test playback/metadata work after a redirect
{ name:"redirect.sjs?domain=mochi.test:8888&file=320x240.ogv",
type:"video/ogg", duration:0.233 },
type:"video/ogg", duration:0.266 },
// Test playback of a webm file
{ name:"seek.webm", type:"video/webm", duration:3.966 },
@ -258,7 +258,7 @@ var gSeekTests = [
{ name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
{ name:"audio.wav", type:"audio/x-wav", duration:0.031247 },
{ name:"seek.ogv", type:"video/ogg", duration:3.966 },
{ name:"320x240.ogv", type:"video/ogg", duration:0.233 },
{ name:"320x240.ogv", type:"video/ogg", duration:0.266 },
{ name:"seek.webm", type:"video/webm", duration:3.966 },
{ name:"bug516323.indexed.ogv", type:"video/ogg", duration:4.208 },
{ name:"split.webm", type:"video/webm", duration:1.967 },

Просмотреть файл

@ -54,7 +54,11 @@ var eventsToLog = ["play", "canplay", "canplaythrough", "loadstart", "loadedmeta
"waiting", "pause"];
function logEvent(event) {
if (event.target.gotEnded > (event.type == "ended" ? 1 : 0)) {
ok(false, event.target.currentSrc + " got unexpected " + event.type + " after ended");
if (event.target.currentSrc.slice(-9) == "seek.webm" && event.type == "stalled") {
todo(false, event.target.currentSrc + " got unexpected stalled after ended (bug 760770)");
} else {
ok(false, event.target.currentSrc + " got unexpected " + event.type + " after ended");
}
} else {
info(event.target.currentSrc + " got " + event.type);
}

Просмотреть файл

@ -192,6 +192,9 @@
#include "mozilla/StartupTimeline.h"
#include "nsIFrameMessageManager.h"
#include "mozilla/Telemetry.h"
#include "nsISecurityUITelemetry.h"
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
@ -4040,8 +4043,16 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
rv = stss->IsStsURI(aURI, &isStsHost);
NS_ENSURE_SUCCESS(rv, rv);
if (isStsHost)
PRUint32 bucketId;
if (isStsHost) {
cssClass.AssignLiteral("badStsCert");
//measuring STS separately allows us to measure click through
//rates easily
bucketId = nsISecurityUITelemetry::WARNING_BAD_CERT_STS;
} else {
bucketId = nsISecurityUITelemetry::WARNING_BAD_CERT;
}
if (Preferences::GetBool(
"browser.xul.error_pages.expert_bad_cert", false)) {
@ -4054,6 +4065,10 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
"security.alternate_certificate_error_page");
if (alternateErrorPage)
errorPage.Assign(alternateErrorPage);
if (errorPage.EqualsIgnoreCase("certerror"))
mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, bucketId);
} else {
error.AssignLiteral("nssFailure2");
}
@ -4071,10 +4086,19 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
if (alternateErrorPage)
errorPage.Assign(alternateErrorPage);
if (NS_ERROR_PHISHING_URI == aError)
PRUint32 bucketId;
if (NS_ERROR_PHISHING_URI == aError) {
error.AssignLiteral("phishingBlocked");
else
bucketId = nsISecurityUITelemetry::WARNING_PHISHING_PAGE;
} else {
error.AssignLiteral("malwareBlocked");
bucketId = nsISecurityUITelemetry::WARNING_MALWARE_PAGE;
}
if (errorPage.EqualsIgnoreCase("blocked"))
mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI,
bucketId);
cssClass.AssignLiteral("blacklist");
}
else {

Просмотреть файл

@ -8,6 +8,7 @@
#include "IDBObjectStore.h"
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
#include "nsIJSContextStack.h"
#include "nsIOutputStream.h"
@ -585,6 +586,47 @@ GetAddInfoCallback(JSContext* aCx, void* aClosure)
return NS_OK;
}
inline
BlobChild*
ActorFromRemoteBlob(nsIDOMBlob* aBlob)
{
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
if (remoteBlob) {
BlobChild* actor =
static_cast<BlobChild*>(static_cast<PBlobChild*>(remoteBlob->GetPBlob()));
NS_ASSERTION(actor, "Null actor?!");
return actor;
}
return nullptr;
}
inline
bool
ResolveMysteryBlob(nsIDOMBlob* aBlob, const nsString& aName,
const nsString& aContentType, PRUint64 aSize)
{
BlobChild* actor = ActorFromRemoteBlob(aBlob);
if (actor) {
return actor->SetMysteryBlobInfo(aName, aContentType, aSize);
}
return true;
}
inline
bool
ResolveMysteryBlob(nsIDOMBlob* aBlob, const nsString& aContentType,
PRUint64 aSize)
{
BlobChild* actor = ActorFromRemoteBlob(aBlob);
if (actor) {
return actor->SetMysteryBlobInfo(aContentType, aSize);
}
return true;
}
} // anonymous namespace
JSClass IDBObjectStore::sDummyPropJSClass = {
@ -1098,6 +1140,9 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
if (aTag == SCTAG_DOM_BLOB) {
nsCOMPtr<nsIDOMBlob> domBlob;
if (file.mFile) {
if (!ResolveMysteryBlob(file.mFile, convType, size)) {
return nullptr;
}
domBlob = file.mFile;
}
else {
@ -1126,6 +1171,9 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
nsCOMPtr<nsIDOMFile> domFile;
if (file.mFile) {
if (!ResolveMysteryBlob(file.mFile, convName, convType, size)) {
return nullptr;
}
domFile = do_QueryInterface(file.mFile);
NS_ASSERTION(domFile, "This should never fail!");
}

Просмотреть файл

@ -182,7 +182,6 @@
yield;
}
</script>
<script type="text/javascript;version=1.7" src="file.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>

Просмотреть файл

@ -15,6 +15,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/Monitor.h"
#include "mozilla/unused.h"
#include "mozilla/net/NeckoMessageUtils.h"
#include "nsDOMFile.h"
#include "nsThreadUtils.h"
@ -301,6 +302,16 @@ SetBlobOnParams(BlobParent* aActor, SlicedBlobConstructorParams& aParams)
aParams.sourceParent() = aActor;
}
inline
nsDOMFileBase*
ToConcreteBlob(nsIDOMBlob* aBlob)
{
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to grow
// a real interface or something.
return static_cast<nsDOMFileBase*>(aBlob);
}
} // anonymous namespace
namespace mozilla {
@ -530,13 +541,23 @@ public:
NS_DECL_ISUPPORTS_INHERITED
RemoteBlob(const nsAString& aName, const nsAString& aContentType,
PRUint64 aLength)
PRUint64 aLength)
: nsDOMFile(aName, aContentType, aLength), mActor(nullptr)
{ }
{
mImmutable = true;
}
RemoteBlob(const nsAString& aContentType, PRUint64 aLength)
: nsDOMFile(aContentType, aLength), mActor(nullptr)
{ }
{
mImmutable = true;
}
RemoteBlob()
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX), mActor(nullptr)
{
mImmutable = true;
}
virtual ~RemoteBlob()
{
@ -594,16 +615,22 @@ public:
template <ActorFlavorEnum ActorFlavor>
Blob<ActorFlavor>::Blob(nsIDOMBlob* aBlob)
: mBlob(aBlob), mRemoteBlob(nullptr), mOwnsBlob(true)
: mBlob(aBlob), mRemoteBlob(nullptr), mOwnsBlob(true), mBlobIsFile(false)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
aBlob->AddRef();
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
mBlobIsFile = !!file;
}
template <ActorFlavorEnum ActorFlavor>
Blob<ActorFlavor>::Blob(const BlobConstructorParams& aParams)
: mBlob(nullptr), mRemoteBlob(nullptr), mOwnsBlob(true)
: mBlob(nullptr), mRemoteBlob(nullptr), mOwnsBlob(false), mBlobIsFile(false)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<RemoteBlobType> remoteBlob;
switch (aParams.type()) {
@ -620,6 +647,13 @@ Blob<ActorFlavor>::Blob(const BlobConstructorParams& aParams)
remoteBlob =
new RemoteBlobType(params.name(), params.contentType(),
params.length());
mBlobIsFile = true;
break;
}
case BlobConstructorParams::TMysteryBlobConstructorParams: {
remoteBlob = new RemoteBlobType();
mBlobIsFile = true;
break;
}
@ -629,23 +663,19 @@ Blob<ActorFlavor>::Blob(const BlobConstructorParams& aParams)
MOZ_ASSERT(remoteBlob);
if (NS_FAILED(remoteBlob->SetMutable(false))) {
MOZ_NOT_REACHED("Failed to make remote blob immutable!");
}
remoteBlob->SetActor(this);
remoteBlob.forget(&mRemoteBlob);
mBlob = mRemoteBlob;
SetRemoteBlob(remoteBlob);
}
template <ActorFlavorEnum ActorFlavor>
Blob<ActorFlavor>*
Blob<ActorFlavor>::Create(const BlobConstructorParams& aParams)
{
MOZ_ASSERT(NS_IsMainThread());
switch (aParams.type()) {
case BlobConstructorParams::TNormalBlobConstructorParams:
case BlobConstructorParams::TFileBlobConstructorParams:
case BlobConstructorParams::TMysteryBlobConstructorParams:
return new Blob<ActorFlavor>(aParams);
case BlobConstructorParams::TSlicedBlobConstructorParams: {
@ -675,6 +705,7 @@ template <ActorFlavorEnum ActorFlavor>
already_AddRefed<nsIDOMBlob>
Blob<ActorFlavor>::GetBlob()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob);
nsCOMPtr<nsIDOMBlob> blob;
@ -695,6 +726,63 @@ Blob<ActorFlavor>::GetBlob()
return blob.forget();
}
template <ActorFlavorEnum ActorFlavor>
bool
Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aName,
const nsString& aContentType,
PRUint64 aLength)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob);
MOZ_ASSERT(mRemoteBlob);
MOZ_ASSERT(aLength);
ToConcreteBlob(mBlob)->SetLazyData(aName, aContentType, aLength);
FileBlobConstructorParams params(aName, aContentType, aLength);
return BaseType::SendResolveMystery(params);
}
template <ActorFlavorEnum ActorFlavor>
bool
Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aContentType,
PRUint64 aLength)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob);
MOZ_ASSERT(mRemoteBlob);
MOZ_ASSERT(aLength);
nsString voidString;
voidString.SetIsVoid(true);
ToConcreteBlob(mBlob)->SetLazyData(voidString, aContentType, aLength);
NormalBlobConstructorParams params(aContentType, aLength);
return BaseType::SendResolveMystery(params);
}
template <ActorFlavorEnum ActorFlavor>
void
Blob<ActorFlavor>::SetRemoteBlob(nsRefPtr<RemoteBlobType>& aRemoteBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mBlob);
MOZ_ASSERT(!mRemoteBlob);
MOZ_ASSERT(!mOwnsBlob);
MOZ_ASSERT(aRemoteBlob);
if (NS_FAILED(aRemoteBlob->SetMutable(false))) {
MOZ_NOT_REACHED("Failed to make remote blob immutable!");
}
aRemoteBlob->SetActor(this);
aRemoteBlob.forget(&mRemoteBlob);
mBlob = mRemoteBlob;
mOwnsBlob = true;
}
template <ActorFlavorEnum ActorFlavor>
void
Blob<ActorFlavor>::NoteDyingRemoteBlob()
@ -703,12 +791,15 @@ Blob<ActorFlavor>::NoteDyingRemoteBlob()
MOZ_ASSERT(mRemoteBlob);
MOZ_ASSERT(!mOwnsBlob);
// This may be called on any thread due to the fact that RemoteBlob is
// designed to be passed between threads. We must start the shutdown process
// on the main thread, so we proxy here if necessary.
if (!NS_IsMainThread()) {
nsCOMPtr<nsIRunnable> runnable =
NS_NewNonOwningRunnableMethod(this,
&Blob<ActorFlavor>::NoteDyingRemoteBlob);
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
MOZ_NOT_REACHED("Should never fail!");
MOZ_ASSERT(false, "Should never fail!");
}
return;
@ -718,13 +809,14 @@ Blob<ActorFlavor>::NoteDyingRemoteBlob()
// access a dangling pointer.
mRemoteBlob = nullptr;
BaseType::Send__delete__(this);
mozilla::unused << BaseType::Send__delete__(this);
}
template <ActorFlavorEnum ActorFlavor>
void
Blob<ActorFlavor>::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob);
if (mRemoteBlob) {
@ -736,10 +828,51 @@ Blob<ActorFlavor>::ActorDestroy(ActorDestroyReason aWhy)
}
}
template <ActorFlavorEnum ActorFlavor>
bool
Blob<ActorFlavor>::RecvResolveMystery(const ResolveMysteryParams& aParams)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob);
MOZ_ASSERT(!mRemoteBlob);
MOZ_ASSERT(mOwnsBlob);
if (!mBlobIsFile) {
MOZ_ASSERT(false, "Must always be a file!");
return false;
}
nsDOMFileBase* blob = ToConcreteBlob(mBlob);
switch (aParams.type()) {
case ResolveMysteryParams::TNormalBlobConstructorParams: {
const NormalBlobConstructorParams& params =
aParams.get_NormalBlobConstructorParams();
nsString voidString;
voidString.SetIsVoid(true);
blob->SetLazyData(voidString, params.contentType(), params.length());
break;
}
case ResolveMysteryParams::TFileBlobConstructorParams: {
const FileBlobConstructorParams& params =
aParams.get_FileBlobConstructorParams();
blob->SetLazyData(params.name(), params.contentType(), params.length());
break;
}
default:
MOZ_NOT_REACHED("Unknown params!");
}
return true;
}
template <ActorFlavorEnum ActorFlavor>
bool
Blob<ActorFlavor>::RecvPBlobStreamConstructor(StreamType* aActor)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob);
MOZ_ASSERT(!mRemoteBlob);
@ -754,6 +887,7 @@ template <ActorFlavorEnum ActorFlavor>
typename Blob<ActorFlavor>::StreamType*
Blob<ActorFlavor>::AllocPBlobStream()
{
MOZ_ASSERT(NS_IsMainThread());
return new InputStreamActor<ActorFlavor>();
}
@ -761,6 +895,7 @@ template <ActorFlavorEnum ActorFlavor>
bool
Blob<ActorFlavor>::DeallocPBlobStream(StreamType* aActor)
{
MOZ_ASSERT(NS_IsMainThread());
delete aActor;
return true;
}

Просмотреть файл

@ -55,6 +55,8 @@ class RemoteBlob;
template <ActorFlavorEnum ActorFlavor>
class Blob : public BlobTraits<ActorFlavor>::BaseType
{
friend class RemoteBlob<ActorFlavor>;
public:
typedef typename BlobTraits<ActorFlavor>::BaseType BaseType;
typedef typename BlobTraits<ActorFlavor>::StreamType StreamType;
@ -69,6 +71,7 @@ protected:
nsIDOMBlob* mBlob;
RemoteBlobType* mRemoteBlob;
bool mOwnsBlob;
bool mBlobIsFile;
public:
// This create function is called on the sending side.
@ -82,11 +85,20 @@ public:
static Blob*
Create(const BlobConstructorParams& aParams);
// Get the blob associated with this actor. This may always be called on the
// sending side. It may also be called on the receiving side unless this is a
// "mystery" blob that has not yet received a SetMysteryBlobInfo() call.
already_AddRefed<nsIDOMBlob>
GetBlob();
void
NoteDyingRemoteBlob();
// Use this for files.
bool
SetMysteryBlobInfo(const nsString& aName, const nsString& aContentType,
PRUint64 aLength);
// Use this for non-file blobs.
bool
SetMysteryBlobInfo(const nsString& aContentType, PRUint64 aLength);
private:
// This constructor is called on the sending side.
@ -95,10 +107,19 @@ private:
// This constructor is called on the receiving side.
Blob(const BlobConstructorParams& aParams);
void
SetRemoteBlob(nsRefPtr<RemoteBlobType>& aRemoteBlob);
void
NoteDyingRemoteBlob();
// These methods are only called by the IPDL message machinery.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool
RecvResolveMystery(const ResolveMysteryParams& aParams) MOZ_OVERRIDE;
virtual bool
RecvPBlobStreamConstructor(StreamType* aActor) MOZ_OVERRIDE;

Просмотреть файл

@ -85,7 +85,7 @@
#include "mozilla/dom/sms/SmsChild.h"
#include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
#include "nsIDOMFile.h"
#include "nsDOMFile.h"
#include "nsIRemoteBlob.h"
#include "StructuredCloneUtils.h"
@ -433,6 +433,7 @@ ContentChild::DeallocPBlob(PBlobChild* aActor)
BlobChild*
ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aBlob, "Null pointer!");
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
@ -444,32 +445,44 @@ ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
return actor;
}
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to grow
// a real interface or something.
const nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
BlobConstructorParams params;
nsString contentType;
nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, nullptr);
PRUint64 length;
rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, nullptr);
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
if (file) {
FileBlobConstructorParams fileParams;
rv = file->GetName(fileParams.name());
if (blob->IsSizeUnknown()) {
// We don't want to call GetSize yet since that may stat a file on the main
// thread here. Instead we'll learn the size lazily from the other process.
params = MysteryBlobConstructorParams();
}
else {
nsString contentType;
nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType;
fileParams.length() = length;
PRUint64 length;
rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, nullptr);
params = fileParams;
} else {
NormalBlobConstructorParams blobParams;
blobParams.contentType() = contentType;
blobParams.length() = length;
params = blobParams;
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
if (file) {
FileBlobConstructorParams fileParams;
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType;
fileParams.length() = length;
params = fileParams;
} else {
NormalBlobConstructorParams blobParams;
blobParams.contentType() = contentType;
blobParams.length() = length;
params = blobParams;
}
}
BlobChild* actor = BlobChild::Create(aBlob);

Просмотреть файл

@ -42,13 +42,13 @@
#include "nsConsoleMessage.h"
#include "nsDebugImpl.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDOMFile.h"
#include "nsExternalHelperAppService.h"
#include "nsFrameMessageManager.h"
#include "nsHashPropertyBag.h"
#include "nsIAlertsService.h"
#include "nsIClipboard.h"
#include "nsIConsoleService.h"
#include "nsIDOMFile.h"
#include "nsIDOMGeoGeolocation.h"
#include "nsIDOMWindow.h"
#include "nsIFilePicker.h"
@ -891,6 +891,7 @@ ContentParent::DeallocPBlob(PBlobParent* aActor)
BlobParent*
ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aBlob, "Null pointer!");
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
@ -903,32 +904,44 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
return actor;
}
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to grow
// a real interface or something.
const nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
BlobConstructorParams params;
nsString contentType;
nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, nullptr);
PRUint64 length;
rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, nullptr);
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
if (file) {
FileBlobConstructorParams fileParams;
rv = file->GetName(fileParams.name());
if (blob->IsSizeUnknown()) {
// We don't want to call GetSize yet since that may stat a file on the main
// thread here. Instead we'll learn the size lazily from the other process.
params = MysteryBlobConstructorParams();
}
else {
nsString contentType;
nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType;
fileParams.length() = length;
PRUint64 length;
rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, nullptr);
params = fileParams;
} else {
NormalBlobConstructorParams blobParams;
blobParams.contentType() = contentType;
blobParams.length() = length;
params = blobParams;
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
if (file) {
FileBlobConstructorParams fileParams;
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType;
fileParams.length() = length;
params = fileParams;
} else {
NormalBlobConstructorParams blobParams;
blobParams.contentType() = contentType;
blobParams.length() = length;
params = blobParams;
}
}
BlobParent* actor = BlobParent::Create(aBlob);

Просмотреть файл

@ -17,5 +17,18 @@ struct ClonedMessageData
PBlob[] blobs;
};
struct NormalBlobConstructorParams
{
nsString contentType;
uint64_t length;
};
struct FileBlobConstructorParams
{
nsString name;
nsString contentType;
uint64_t length;
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -5,9 +5,17 @@
include protocol PBlobStream;
include protocol PContent;
include DOMTypes;
namespace mozilla {
namespace dom {
union ResolveMysteryParams
{
NormalBlobConstructorParams;
FileBlobConstructorParams;
};
protocol PBlob
{
manager PContent;
@ -17,6 +25,8 @@ both:
__delete__();
PBlobStream();
ResolveMystery(ResolveMysteryParams params);
};
} // namespace dom

Просмотреть файл

@ -101,19 +101,6 @@ union DeviceStorageParams
DeviceStorageEnumerationParams;
};
struct NormalBlobConstructorParams
{
nsString contentType;
uint64_t length;
};
struct FileBlobConstructorParams
{
nsString name;
nsString contentType;
uint64_t length;
};
struct SlicedBlobConstructorParams
{
PBlob source;
@ -122,11 +109,17 @@ struct SlicedBlobConstructorParams
nsString contentType;
};
struct MysteryBlobConstructorParams
{
// Nothing is known about this type of blob.
};
union BlobConstructorParams
{
NormalBlobConstructorParams;
FileBlobConstructorParams;
SlicedBlobConstructorParams;
MysteryBlobConstructorParams;
};
rpc protocol PContent

Просмотреть файл

@ -139,7 +139,7 @@ void nsVolumeService::UpdateVolume(const nsVolume *aVolume)
return;
}
vol->Set(aVolume);
nsRefPtr<nsIObserverService> obs = GetObserverService();
nsCOMPtr<nsIObserverService> obs = GetObserverService();
if (!obs) {
return;
}

Просмотреть файл

@ -301,6 +301,23 @@ struct RemoteImageData {
* (because layers can only be used on the main thread) and we want to
* be able to set the current Image from any thread, to facilitate
* video playback without involving the main thread, for example.
*
* An ImageContainer can operate in one of three modes:
* 1) Normal. Triggered by constructing the ImageContainer with
* DISABLE_ASYNC or when compositing is happening on the main thread.
* SetCurrentImage changes ImageContainer state but nothing is sent to the
* compositor until the next layer transaction.
* 2) Asynchronous. Initiated by constructing the ImageContainer with
* ENABLE_ASYNC when compositing is happening on the main thread.
* SetCurrentImage sends a message through the ImageBridge to the compositor
* thread to update the image, without going through the main thread or
* a layer transaction.
* 3) Remote. Initiated by calling SetRemoteImageData on the ImageContainer
* before any other activity.
* The ImageContainer uses a shared memory block containing a cross-process mutex
* to communicate with the compositor thread. SetCurrentImage synchronously
* updates the shared state to point to the new image and the old image
* is immediately released (not true in Normal or Asynchronous modes).
*/
class THEBES_API ImageContainer {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageContainer)

Просмотреть файл

@ -444,7 +444,7 @@ jsd_AppendUCSourceText(JSDContext* jsdc,
}
}
while(remaining && jsdsrc) {
int bytes = JS_MIN(remaining, UNICODE_TRUNCATE_BUF_SIZE);
int bytes = (remaining < UNICODE_TRUNCATE_BUF_SIZE) ? remaining : UNICODE_TRUNCATE_BUF_SIZE;
int i;
for(i = 0; i < bytes; i++)
buf[i] = (const char) *(text++);

Просмотреть файл

@ -6715,7 +6715,7 @@ frontend::NewSrcNote(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type)
bce->current->lastNoteOffset = offset;
if (delta >= SN_DELTA_LIMIT) {
do {
xdelta = JS_MIN(delta, SN_XDELTA_MASK);
xdelta = Min(delta, SN_XDELTA_MASK);
SN_MAKE_XDELTA(sn, xdelta);
delta -= xdelta;
index = AllocSrcNote(cx, bce);
@ -6948,7 +6948,7 @@ frontend::FinishTakingSrcNotes(JSContext *cx, BytecodeEmitter *bce, jssrcnote *n
offset -= delta;
if (offset == 0)
break;
delta = JS_MIN(offset, SN_XDELTA_MASK);
delta = Min(offset, SN_XDELTA_MASK);
sn = bce->main.notes;
}
}

Просмотреть файл

@ -323,7 +323,7 @@ MapAlignedPages(size_t size, size_t alignment)
}
/* Overallocate and unmap the region's edges. */
size_t reqSize = JS_MIN(size + 2 * alignment, 2 * size);
size_t reqSize = Min(size + 2 * alignment, 2 * size);
void *region = mmap(NULL, reqSize, prot, flags, -1, 0);
if (region == MAP_FAILED)
return NULL;

Просмотреть файл

@ -2111,7 +2111,7 @@ AddNameToArray(JSContext *cx, PropertyName *name, JSIdArray *ida, int *ip)
int i = *ip;
int length = ida->length;
if (i >= length) {
ida = SetIdArrayLength(cx, ida, JS_MAX(length * 2, 8));
ida = SetIdArrayLength(cx, ida, Max(length * 2, 8));
if (!ida)
return NULL;
JS_ASSERT(i < ida->length);

Просмотреть файл

@ -2653,9 +2653,9 @@ array_splice(JSContext *cx, unsigned argc, Value *vp)
/* Step 6. */
uint32_t actualStart;
if (relativeStart < 0)
actualStart = JS_MAX(len + relativeStart, 0);
actualStart = Max(len + relativeStart, 0.0);
else
actualStart = JS_MIN(relativeStart, len);
actualStart = Min(relativeStart, double(len));
/* Step 7. */
uint32_t actualDeleteCount;
@ -2663,7 +2663,7 @@ array_splice(JSContext *cx, unsigned argc, Value *vp)
double deleteCountDouble;
if (!ToInteger(cx, argc >= 2 ? args[1] : Int32Value(0), &deleteCountDouble))
return false;
actualDeleteCount = JS_MIN(JS_MAX(deleteCountDouble, 0), len - actualStart);
actualDeleteCount = Min(Max(deleteCountDouble, 0.0), double(len - actualStart));
} else {
/*
* Non-standard: if start was specified but deleteCount was omitted,

Просмотреть файл

@ -379,7 +379,7 @@ JSStructuredCloneWriter::checkStack()
/* To avoid making serialization O(n^2), limit stack-checking at 10. */
const size_t MAX = 10;
size_t limit = JS_MIN(counts.length(), MAX);
size_t limit = Min(counts.length(), MAX);
JS_ASSERT(objs.length() == counts.length());
size_t total = 0;
for (size_t i = 0; i < limit; i++) {

Просмотреть файл

@ -541,6 +541,9 @@ struct JSRuntime : js::RuntimeFriendFields
/* The gcNumber at the time of the most recent GC's first slice. */
uint64_t gcStartNumber;
/* Whether the currently running GC can finish in multiple slices. */
int gcIsIncremental;
/* Whether all compartments are being collected in first GC slice. */
bool gcIsFull;

Просмотреть файл

@ -738,7 +738,7 @@ ndigits(size_t n, size_t *result, const jschar *s, size_t* i, size_t limit)
{
size_t init = *i;
if (digits(result, s, i, JS_MIN(limit, init+n)))
if (digits(result, s, i, Min(limit, init+n)))
return ((*i - init) == n);
*i = init;

Просмотреть файл

@ -275,7 +275,7 @@ JS_DHashTableSetAlphaBounds(JSDHashTable *table,
JS_ASSERT(JS_DHASH_MIN_SIZE - (maxAlpha * JS_DHASH_MIN_SIZE) >= 1);
if (JS_DHASH_MIN_SIZE - (maxAlpha * JS_DHASH_MIN_SIZE) < 1) {
maxAlpha = (float)
(JS_DHASH_MIN_SIZE - JS_MAX(JS_DHASH_MIN_SIZE / 256, 1))
(JS_DHASH_MIN_SIZE - Max(JS_DHASH_MIN_SIZE / 256, 1))
/ JS_DHASH_MIN_SIZE;
}
@ -287,7 +287,7 @@ JS_DHashTableSetAlphaBounds(JSDHashTable *table,
JS_ASSERT(minAlpha < maxAlpha / 2);
if (minAlpha >= maxAlpha / 2) {
size = JS_DHASH_TABLE_SIZE(table);
minAlpha = (size * maxAlpha - JS_MAX(size / 256, 1)) / (2 * size);
minAlpha = (size * maxAlpha - Max(size / 256, 1U)) / (2 * size);
}
table->maxAlphaFrac = (uint8_t)(maxAlpha * 256);

Просмотреть файл

@ -780,6 +780,12 @@ SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback)
return old;
}
JS_FRIEND_API(bool)
WasIncrementalGC(JSRuntime *rt)
{
return rt->gcIsIncremental;
}
jschar *
GCDescription::formatMessage(JSRuntime *rt) const
{

Просмотреть файл

@ -745,6 +745,10 @@ typedef void
extern JS_FRIEND_API(GCSliceCallback)
SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback);
/* Was the most recent GC run incrementally? */
extern JS_FRIEND_API(bool)
WasIncrementalGC(JSRuntime *rt);
/*
* Signals a good place to do an incremental slice, because the browser is
* drawing a frame.

Просмотреть файл

@ -3186,7 +3186,7 @@ ShouldPreserveJITCode(JSCompartment *c, int64_t currentTime)
}
static void
BeginMarkPhase(JSRuntime *rt, bool isIncremental)
BeginMarkPhase(JSRuntime *rt)
{
int64_t currentTime = PRMJ_Now();
@ -3197,7 +3197,7 @@ BeginMarkPhase(JSRuntime *rt, bool isIncremental)
* arenas. This purge call ensures that we only mark arenas that have had
* allocations after the incremental GC started.
*/
if (isIncremental) {
if (rt->gcIsIncremental) {
for (GCCompartmentsIter c(rt); !c.done(); c.next())
c->arenas.purge();
}
@ -3221,7 +3221,7 @@ BeginMarkPhase(JSRuntime *rt, bool isIncremental)
JS_ASSERT(IS_GC_MARKING_TRACER(&rt->gcMarker));
/* For non-incremental GC the following sweep discards the jit code. */
if (isIncremental) {
if (rt->gcIsIncremental) {
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_MARK_DISCARD_CODE);
c->discardJitCode(rt->defaultFreeOp());
@ -3314,7 +3314,7 @@ ValidateIncrementalMarking(JSRuntime *rt);
#endif
static void
EndMarkPhase(JSRuntime *rt, bool isIncremental)
EndMarkPhase(JSRuntime *rt)
{
{
gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_MARK);
@ -3324,7 +3324,7 @@ EndMarkPhase(JSRuntime *rt, bool isIncremental)
JS_ASSERT(rt->gcMarker.isDrained());
#ifdef DEBUG
if (isIncremental)
if (rt->gcIsIncremental)
ValidateIncrementalMarking(rt);
#endif
@ -3889,8 +3889,8 @@ IncrementalCollectSlice(JSRuntime *rt,
}
#endif
bool isIncremental = rt->gcIncrementalState != NO_INCREMENTAL ||
budget != SliceBudget::Unlimited;
rt->gcIsIncremental = rt->gcIncrementalState != NO_INCREMENTAL ||
budget != SliceBudget::Unlimited;
if (zeal == ZealIncrementalRootsThenFinish || zeal == ZealIncrementalMarkAllThenFinish) {
/*
@ -3908,7 +3908,7 @@ IncrementalCollectSlice(JSRuntime *rt,
switch (rt->gcIncrementalState) {
case MARK_ROOTS:
BeginMarkPhase(rt, isIncremental);
BeginMarkPhase(rt);
PushZealSelectedObjects(rt);
rt->gcIncrementalState = MARK;
@ -3943,7 +3943,7 @@ IncrementalCollectSlice(JSRuntime *rt,
break;
}
EndMarkPhase(rt, isIncremental);
EndMarkPhase(rt);
rt->gcIncrementalState = SWEEP;

Просмотреть файл

@ -2707,7 +2707,7 @@ END_VARLEN_CASE
BEGIN_CASE(JSOP_ACTUALSFILLED)
{
PUSH_INT32(JS_MAX(regs.fp()->numActualArgs(), GET_UINT16(regs.pc)));
PUSH_INT32(Max(regs.fp()->numActualArgs(), GET_UINT16(regs.pc)));
}
END_CASE(JSOP_ACTUALSFILLED)

Просмотреть файл

@ -3617,7 +3617,7 @@ JSObject::growElements(JSContext *cx, unsigned newcap)
? oldcap * 2
: oldcap + (oldcap >> 3);
uint32_t actualCapacity = JS_MAX(newcap, nextsize);
uint32_t actualCapacity = Max(newcap, nextsize);
if (actualCapacity >= CAPACITY_CHUNK)
actualCapacity = JS_ROUNDUP(actualCapacity, CAPACITY_CHUNK);
else if (actualCapacity < SLOT_CAPACITY_MIN)

Просмотреть файл

@ -629,7 +629,7 @@ js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value sp
uint32_t len;
JS_ALWAYS_TRUE(js_GetLengthProperty(cx, replacer, &len));
if (replacer->isDenseArray())
len = JS_MIN(len, replacer->getDenseArrayCapacity());
len = Min(len, replacer->getDenseArrayCapacity());
HashSet<jsid> idSet(cx);
if (!idSet.init(len))
@ -702,7 +702,7 @@ js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value sp
/* Step 6. */
double d;
JS_ALWAYS_TRUE(ToInteger(cx, space, &d));
d = JS_MIN(10, d);
d = Min(10.0, d);
if (d >= 1 && !gap.appendN(' ', uint32_t(d)))
return false;
} else if (space.isString()) {
@ -711,7 +711,7 @@ js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value sp
if (!str)
return false;
JS::Anchor<JSString *> anchor(str);
size_t len = JS_MIN(10, space.toString()->length());
size_t len = Min(size_t(10), space.toString()->length());
if (!gap.append(str->chars(), len))
return false;
} else {

Просмотреть файл

@ -110,7 +110,7 @@ SkipSpace(const jschar *s, const jschar *end)
inline bool
CompareChars(const jschar *s1, size_t l1, const jschar *s2, size_t l2, int32_t *result)
{
size_t n = JS_MIN(l1, l2);
size_t n = Min(l1, l2);
for (size_t i = 0; i < n; i++) {
if (int32_t cmp = s1[i] - s2[i]) {
*result = cmp;

Просмотреть файл

@ -147,8 +147,6 @@
***********************************************************************/
#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y))
#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y))
#define JS_MIN(x,y) ((x)<(y)?(x):(y))
#define JS_MAX(x,y) ((x)>(y)?(x):(y))
#include "jscpucfg.h"

Просмотреть файл

@ -177,7 +177,7 @@ ValToBin(unsigned logscale, uint32_t val)
: (logscale == 2)
? (unsigned) JS_CEILING_LOG2W(val)
: val;
return JS_MIN(bin, 10);
return Min(bin, 10U);
}
void

Просмотреть файл

@ -74,8 +74,8 @@ VerifyRange(void *start1, size_t size1, void *start2, size_t size2)
uintptr_t end1 = uintptr_t(start1) + size1;
uintptr_t end2 = uintptr_t(start2) + size2;
uintptr_t lowest = JS_MIN(uintptr_t(start1), uintptr_t(start2));
uintptr_t highest = JS_MAX(end1, end2);
uintptr_t lowest = Min(uintptr_t(start1), uintptr_t(start2));
uintptr_t highest = Max(end1, end2);
return (highest - lowest < INT_MAX);
}

Просмотреть файл

@ -423,7 +423,7 @@ PRMJ_Now(void)
/* On some dual processor/core systems, we might get an earlier time
so we cache the last time that we returned */
calibration.last = JS_MAX(calibration.last, int64_t(highresTime));
calibration.last = js::Max(calibration.last, int64_t(highresTime));
returnedTime = calibration.last;
MUTEX_UNLOCK(&calibration.data_lock);
@ -692,7 +692,7 @@ DSTOffsetCache::getDSTOffsetMilliseconds(int64_t localTimeMilliseconds, JSContex
oldRangeEndSeconds = rangeEndSeconds;
if (rangeStartSeconds <= localTimeSeconds) {
int64_t newEndSeconds = JS_MIN(rangeEndSeconds + RANGE_EXPANSION_AMOUNT, MAX_UNIX_TIMET);
int64_t newEndSeconds = js::Min(rangeEndSeconds + RANGE_EXPANSION_AMOUNT, MAX_UNIX_TIMET);
if (newEndSeconds >= localTimeSeconds) {
int64_t endOffsetMilliseconds = computeDSTOffsetMilliseconds(newEndSeconds);
if (endOffsetMilliseconds == offsetMilliseconds) {
@ -715,7 +715,7 @@ DSTOffsetCache::getDSTOffsetMilliseconds(int64_t localTimeMilliseconds, JSContex
return offsetMilliseconds;
}
int64_t newStartSeconds = JS_MAX(rangeStartSeconds - RANGE_EXPANSION_AMOUNT, 0);
int64_t newStartSeconds = js::Max(rangeStartSeconds - RANGE_EXPANSION_AMOUNT, int64_t(0));
if (newStartSeconds <= localTimeSeconds) {
int64_t startOffsetMilliseconds = computeDSTOffsetMilliseconds(newStartSeconds);
if (startOffsetMilliseconds == offsetMilliseconds) {

Просмотреть файл

@ -178,7 +178,7 @@ OptionParser::printHelp(const char *progname)
size_t fmtChars = sizeof(fmt) - 2;
size_t lhsLen = 0;
for (Option **it = arguments.begin(), **end = arguments.end(); it != end; ++it)
lhsLen = JS_MAX(lhsLen, strlen((*it)->longflag) + fmtChars);
lhsLen = Max(lhsLen, strlen((*it)->longflag) + fmtChars);
for (Option **it = arguments.begin(), **end = arguments.end(); it != end; ++it) {
Option *arg = *it;
@ -206,7 +206,7 @@ OptionParser::printHelp(const char *progname)
size_t len = fmtLen + longflagLen;
if (opt->isValued())
len += strlen(opt->asValued()->metavar);
lhsLen = JS_MAX(lhsLen, len);
lhsLen = Max(lhsLen, len);
}
/* Print option help text. */

Просмотреть файл

@ -4102,13 +4102,13 @@ ApplyOrCall(JSContext *cx, unsigned argc, Value *vp, ApplyOrCallMode mode)
RootedObject argsobj(cx, &args[1].toObject());
if (!js_GetLengthProperty(cx, argsobj, &callArgc))
return false;
callArgc = unsigned(JS_MIN(callArgc, StackSpace::ARGS_LENGTH_MAX));
callArgc = unsigned(Min(callArgc, StackSpace::ARGS_LENGTH_MAX));
if (!argv.growBy(callArgc) || !GetElements(cx, argsobj, callArgc, argv.begin()))
return false;
callArgv = argv.begin();
}
} else {
callArgc = argc > 0 ? unsigned(JS_MIN(argc - 1, StackSpace::ARGS_LENGTH_MAX)) : 0;
callArgc = argc > 0 ? unsigned(Min(argc - 1, StackSpace::ARGS_LENGTH_MAX)) : 0;
callArgv = args.array() + 1;
}
for (unsigned i = 0; i < callArgc; i++) {

Просмотреть файл

@ -277,14 +277,14 @@ template<typename T>
inline T
min(T t1, T t2)
{
return JS_MIN(t1, t2);
return js::Min(t1, t2);
}
template<typename T>
inline T
max(T t1, T t2)
{
return JS_MAX(t1, t2);
return js::Max(t1, t2);
}
template<typename T>

Просмотреть файл

@ -482,7 +482,7 @@ inline JSBool
XPCNativeSet::MatchesSetUpToInterface(const XPCNativeSet* other,
XPCNativeInterface* iface) const
{
int count = JS_MIN((int)mInterfaceCount, (int)other->mInterfaceCount);
int count = js::Min(int(mInterfaceCount), int(other->mInterfaceCount));
XPCNativeInterface* const * pp1 = mInterfaces;
XPCNativeInterface* const * pp2 = other->mInterfaces;

Просмотреть файл

@ -22,6 +22,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "nsLayoutStatics.h"
#include "nsContentUtils.h"
#include "nsCCUncollectableMarker.h"
#include "jsfriendapi.h"
@ -564,6 +565,103 @@ DoDeferredRelease(nsTArray<T> &array)
}
}
class XPCIncrementalReleaseRunnable : public nsRunnable
{
XPCJSRuntime *runtime;
nsTArray<nsISupports *> items;
static const PRTime SliceMillis = 10; /* ms */
public:
XPCIncrementalReleaseRunnable(XPCJSRuntime *rt, nsTArray<nsISupports *> &items);
virtual ~XPCIncrementalReleaseRunnable();
void ReleaseNow(bool limited);
NS_DECL_NSIRUNNABLE
};
XPCIncrementalReleaseRunnable::XPCIncrementalReleaseRunnable(XPCJSRuntime *rt,
nsTArray<nsISupports *> &items)
: runtime(rt)
{
nsLayoutStatics::AddRef();
this->items.SwapElements(items);
}
XPCIncrementalReleaseRunnable::~XPCIncrementalReleaseRunnable()
{
MOZ_ASSERT(this != runtime->mReleaseRunnable);
nsLayoutStatics::Release();
}
void
XPCIncrementalReleaseRunnable::ReleaseNow(bool limited)
{
MOZ_ASSERT(NS_IsMainThread());
TimeDuration sliceTime = TimeDuration::FromMilliseconds(SliceMillis);
TimeStamp started = TimeStamp::Now();
PRUint32 counter = 0;
while (1) {
PRUint32 count = items.Length();
if (!count)
break;
nsISupports *wrapper = items[count - 1];
items.RemoveElementAt(count - 1);
NS_RELEASE(wrapper);
if (limited) {
/* We don't want to read the clock too often. */
counter++;
if (counter == 100) {
counter = 0;
if (TimeStamp::Now() - started >= sliceTime)
break;
}
}
}
MOZ_ASSERT_IF(items.Length(), limited);
if (!items.Length()) {
MOZ_ASSERT(runtime->mReleaseRunnable == this);
runtime->mReleaseRunnable = nullptr;
}
}
NS_IMETHODIMP
XPCIncrementalReleaseRunnable::Run()
{
if (runtime->mReleaseRunnable != this) {
/* These items were already processed synchronously in JSGC_BEGIN. */
MOZ_ASSERT(!items.Length());
return NS_OK;
}
ReleaseNow(true);
if (items.Length()) {
nsresult rv = NS_DispatchToMainThread(this);
if (NS_FAILED(rv))
ReleaseNow(false);
}
return NS_OK;
}
void
XPCJSRuntime::ReleaseIncrementally(nsTArray<nsISupports *> &array)
{
MOZ_ASSERT(!mReleaseRunnable);
mReleaseRunnable = new XPCIncrementalReleaseRunnable(this, array);
nsresult rv = NS_DispatchToMainThread(mReleaseRunnable);
if (NS_FAILED(rv))
mReleaseRunnable->ReleaseNow(false);
}
/* static */ void
XPCJSRuntime::GCCallback(JSRuntime *rt, JSGCStatus status)
{
@ -585,15 +683,21 @@ XPCJSRuntime::GCCallback(JSRuntime *rt, JSGCStatus status)
}
case JSGC_END:
{
/*
* If the previous GC created a runnable to release objects
* incrementally, and if it hasn't finished yet, finish it now. We
* don't want these to build up. We also don't want to allow any
* existing incremental release runnables to run after a
* non-incremental GC, since they are often used to detect leaks.
*/
if (self->mReleaseRunnable)
self->mReleaseRunnable->ReleaseNow(false);
// Do any deferred releases of native objects.
#ifdef XPC_TRACK_DEFERRED_RELEASES
printf("XPC - Begin deferred Release of %d nsISupports pointers\n",
self->mNativesToReleaseArray.Length());
#endif
DoDeferredRelease(self->mNativesToReleaseArray);
#ifdef XPC_TRACK_DEFERRED_RELEASES
printf("XPC - End deferred Releases\n");
#endif
if (js::WasIncrementalGC(rt))
self->ReleaseIncrementally(self->mNativesToReleaseArray);
else
DoDeferredRelease(self->mNativesToReleaseArray);
self->GetXPConnect()->ClearGCBeforeCC();
break;
@ -964,6 +1068,8 @@ XPCJSRuntime::GetJSCycleCollectionContext()
XPCJSRuntime::~XPCJSRuntime()
{
MOZ_ASSERT(!mReleaseRunnable);
if (mWatchdogWakeup) {
// If the watchdog thread is running, tell it to terminate waking it
// up if necessary and wait until it signals that it finished. As we
@ -2000,6 +2106,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
mWatchdogThread(nullptr),
mWatchdogHibernating(false),
mLastActiveTime(-1),
mReleaseRunnable(nullptr),
mExceptionManagerNotAvailable(false)
{
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN

Просмотреть файл

@ -638,6 +638,7 @@ private:
// no virtuals. no refcounting.
class XPCJSContextStack;
class XPCIncrementalReleaseRunnable;
class XPCJSRuntime
{
public:
@ -866,6 +867,8 @@ private:
static void WatchdogMain(void *arg);
void ReleaseIncrementally(nsTArray<nsISupports *> &array);
static bool gNewDOMBindingsEnabled;
static bool gExperimentalBindingsEnabled;
@ -906,12 +909,14 @@ private:
nsTArray<JSGCCallback> extraGCCallbacks;
bool mWatchdogHibernating;
PRTime mLastActiveTime; // -1 if active NOW
XPCIncrementalReleaseRunnable *mReleaseRunnable;
nsCOMPtr<nsIException> mPendingException;
nsCOMPtr<nsIExceptionManager> mExceptionManager;
bool mExceptionManagerNotAvailable;
friend class AutoLockWatchdog;
friend class XPCIncrementalReleaseRunnable;
};
/***************************************************************************/

Просмотреть файл

@ -220,17 +220,47 @@ bool
CommonElementAnimationData::CanAnimatePropertyOnCompositor(const dom::Element *aElement,
nsCSSProperty aProperty)
{
static bool sShouldLog;
static bool sShouldLogPrefCached;
if (!sShouldLogPrefCached) {
sShouldLogPrefCached = true;
Preferences::AddBoolVarCache(&sShouldLog,
"layers.offmainthreadcomposition.log-animations");
}
nsIFrame* frame = aElement->GetPrimaryFrame();
if (aProperty == eCSSProperty_opacity) {
return nsLayoutUtils::AreOpacityAnimationsEnabled();
bool enabled = nsLayoutUtils::AreOpacityAnimationsEnabled();
if (!enabled && sShouldLog) {
printf_stderr("Performance warning: Async animation of 'opacity' is disabled\n");
}
return enabled;
}
if (aProperty == eCSSProperty_transform && !(frame &&
frame->Preserves3D() &&
frame->Preserves3DChildren())) {
if (frame && frame->IsSVGTransformed()) {
if (aProperty == eCSSProperty_transform) {
if (frame &&
frame->Preserves3D() &&
frame->Preserves3DChildren()) {
if (sShouldLog) {
printf_stderr("Gecko bug: Async animation of 'preserve-3d' transforms is not supported. See bug 779598\n");
}
return false;
}
return nsLayoutUtils::AreTransformAnimationsEnabled();
if (frame && frame->IsSVGTransformed()) {
if (sShouldLog) {
printf_stderr("Gecko bug: Async 'transform' animations of frames with SVG transforms is not supported. See bug 779599\n");
}
return false;
}
bool enabled = nsLayoutUtils::AreTransformAnimationsEnabled();
if (!enabled && sShouldLog) {
printf_stderr("Performance warning: Async animation of 'transform' is disabled\n");
}
return enabled;
}
if (sShouldLog) {
const nsAFlatCString propName = nsCSSProps::GetStringValue(aProperty);
printf_stderr("Performance warning: Async animation cancelled because of unsupported property '%s'\n", propName.get());
}
return false;
}

Просмотреть файл

@ -504,4 +504,20 @@ public class Utils {
final long duration = endMillis - startMillis;
return new DecimalFormat("#0.00 seconds").format(((double) duration) / 1000);
}
}
/**
* This will take a string containing a UTF-8 representation of a UTF-8
* byte array e.g., "pïgéons1" and return UTF-8 (e.g., "pïgéons1").
*
* This is the format produced by desktop Firefox when exchanging credentials
* containing non-ASCII characters.
*/
public static String decodeUTF8(final String in) throws UnsupportedEncodingException {
final int length = in.length();
final byte[] asciiBytes = new byte[length];
for (int i = 0; i < length; ++i) {
asciiBytes[i] = (byte) in.codePointAt(i);
}
return new String(asciiBytes, "UTF-8");
}
}

Просмотреть файл

@ -129,14 +129,22 @@ public class BaseResource implements Resource {
context.setAttribute(ClientContext.AUTH_CACHE, authCache);
}
/**
* Return a Header object representing an Authentication header for HTTP Basic.
*/
public static Header getBasicAuthHeader(final String credentials) {
Credentials creds = new UsernamePasswordCredentials(credentials);
// This must be UTF-8 to generate the same Basic Auth headers as desktop for non-ASCII passwords.
return BasicScheme.authenticate(creds, "UTF-8", false);
}
/**
* Apply the provided credentials string to the provided request.
* @param credentials a string, "user:pass".
*/
private static void applyCredentials(String credentials, HttpUriRequest request, HttpContext context) {
Credentials creds = new UsernamePasswordCredentials(credentials);
Header header = BasicScheme.authenticate(creds, "US-ASCII", false);
request.addHeader(header);
request.addHeader(getBasicAuthHeader(credentials));
Logger.trace(LOG_TAG, "Adding Basic Auth header.");
}

Просмотреть файл

@ -4,6 +4,7 @@
package org.mozilla.gecko.sync.setup.activities;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import org.json.simple.JSONObject;
@ -11,6 +12,7 @@ import org.mozilla.gecko.R;
import org.mozilla.gecko.sync.GlobalConstants;
import org.mozilla.gecko.sync.Logger;
import org.mozilla.gecko.sync.ThreadPool;
import org.mozilla.gecko.sync.Utils;
import org.mozilla.gecko.sync.jpake.JPakeClient;
import org.mozilla.gecko.sync.jpake.JPakeNoActivePairingException;
import org.mozilla.gecko.sync.setup.Constants;
@ -392,6 +394,13 @@ public class SetupSyncActivity extends AccountAuthenticatorActivity {
String syncKey = (String) jCreds.get(Constants.JSON_KEY_SYNCKEY);
String serverURL = (String) jCreds.get(Constants.JSON_KEY_SERVER);
// The password we get is double-encoded.
try {
password = Utils.decodeUTF8(password);
} catch (UnsupportedEncodingException e) {
Logger.warn(LOG_TAG, "Unsupported encoding when decoding UTF-8 ASCII J-PAKE message. Ignoring.");
}
final SyncAccountParameters syncAccount = new SyncAccountParameters(mContext, mAccountManager, accountName,
syncKey, password, serverURL);
createAccountOnThread(syncAccount);

Просмотреть файл

@ -226,6 +226,21 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter implements GlobalSe
return delayMilliseconds() > 0;
}
/**
* Request that no sync start right away. A new sync won't start until
* at least <code>backoff</code> milliseconds from now.
*
* @param backoff time to wait in milliseconds.
*/
@Override
public void requestBackoff(long backoff) {
if (backoff > 0) {
// Fuzz the backoff time (up to 25% more) to prevent client lock-stepping; agrees with desktop.
backoff = backoff + Math.round((double) backoff * 0.25d * Math.random());
this.extendEarliestNextSync(System.currentTimeMillis() + backoff);
}
}
/**
* Asynchronously request an immediate sync, optionally syncing only the given
* named stages.
@ -530,13 +545,6 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter implements GlobalSe
Logger.trace(LOG_TAG, "Stage completed: " + currentState);
}
@Override
public void requestBackoff(long backoff) {
if (backoff > 0) {
this.extendEarliestNextSync(System.currentTimeMillis() + backoff);
}
}
@Override
public synchronized String getAccountGUID() {
String accountGUID = mAccountManager.getUserData(localAccount, Constants.ACCOUNT_GUID);

Просмотреть файл

@ -229,7 +229,7 @@ pref("gfx.font_rendering.directwrite.use_gdi_table_loading", true);
pref("gfx.canvas.azure.enabled", true);
// comma separated list of backends to use in order of preference
// e.g., pref("gfx.canvas.azure.backends", "direct2d,skia,cairo");
pref("gfx.canvas.azure.backends", "direct2d");
pref("gfx.canvas.azure.backends", "direct2d,cairo");
pref("gfx.content.azure.enabled", true);
#else
#ifdef XP_MACOSX
@ -237,7 +237,7 @@ pref("gfx.canvas.azure.enabled", true);
pref("gfx.canvas.azure.backends", "cg");
#else
pref("gfx.canvas.azure.enabled", false);
pref("gfx.canvas.azure.backends", "cairo,skia");
pref("gfx.canvas.azure.backends", "cairo");
#endif
#endif

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <windows.h>
#include "../../../../toolkit/components/maintenanceservice/pathhash.h"
#include "../../../../toolkit/mozapps/update/common/pathhash.h"
#pragma comment(lib, "advapi32.lib")

Просмотреть файл

@ -92,11 +92,11 @@ LINK32=link.exe
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=\toolkit\components\maintenanceservice\pathhash.cpp
SOURCE=\toolkit\mozapps\update\common\pathhash.cpp
# End Source File
# Begin Source File
SOURCE=\toolkit\components\maintenanceservice\pathhash.h
SOURCE=\toolkit\mozapps\update\common\pathhash.h
# End Source File
# Begin Source File

Просмотреть файл

@ -178,7 +178,7 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\..\..\..\toolkit\components\maintenanceservice\pathhash.cpp"
RelativePath="..\..\..\..\toolkit\mozapps\update\common\pathhash.cpp"
>
</File>
<File

Просмотреть файл

@ -19,6 +19,7 @@ SDK_XPIDLSRCS = \
XPIDLSRCS = \
nsISSLStatusProvider.idl \
nsIBufEntropyCollector.idl \
nsISecurityUITelemetry.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,86 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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/. */
#include "nsISupports.idl"
[scriptable, uuid(454b5cbb-fd18-4f34-a616-4d543f68717d)]
interface nsISecurityUITelemetry : nsISupports {
/*
* Addon installation warnings
*/
// Firefox prevented this site from asking you to install addon
const PRUint32 WARNING_ADDON_ASKING_PREVENTED = 1;
// User clicks through and allows site to ask to install addons
const PRUint32 WARNING_ADDON_ASKING_PREVENTED_CLICK_THROUGH = 2;
// Are you sure you want to install this addon? Only install addons you trust
const PRUint32 WARNING_CONFIRM_ADDON_INSTALL = 3;
// User clicked she is sure after waiting 3secs
const PRUint32 WARNING_CONFIRM_ADDON_INSTALL_CLICK_THROUGH = 4;
/*
* modal dialogs/warnings
*/
const PRUint32 WARNING_ENTERING_SECURE_SITE = 5;
const PRUint32 WARNING_ENTERING_WEAK_SITE = 6;
const PRUint32 WARNING_LEAVING_SECURE_SITE = 7;
const PRUint32 WARNING_MIXED_CONTENT = 8;
// For confirmation dialogs, the clickthrough constant needs to be 1
// more than the dialog constant so that
// WARNING_CONFIRM_<X> + 1 == WARNING_CONFIRM_<X>_CLICK_THROUGH
const PRUint32 WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE = 9;
const PRUint32 WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE_CLICK_THROUGH = 10;
const PRUint32 WARNING_CONFIRM_POST_TO_INSECURE_FROM_INSECURE = 11;
const PRUint32 WARNING_CONFIRM_POST_TO_INSECURE_FROM_INSECURE_CLICK_THROUGH = 12;
/*
* Phishing / Malware page warnings
*/
const PRUint32 WARNING_MALWARE_PAGE = 13;
const PRUint32 WARNING_MALWARE_PAGE_WHY_BLOCKED = 14;
const PRUint32 WARNING_MALWARE_PAGE_GET_ME_OUT_OF_HERE = 15;
const PRUint32 WARNING_MALWARE_PAGE_IGNORE_WARNING = 16;
const PRUint32 WARNING_PHISHING_PAGE = 17;
const PRUint32 WARNING_PHISHING_PAGE_WHY_BLOCKED = 18;
const PRUint32 WARNING_PHISHING_PAGE_GET_ME_OUT_OF_HERE = 19;
const PRUint32 WARNING_PHISHING_PAGE_IGNORE_WARNING = 20;
/*
* SSL Error dialogs
*/
const PRUint32 WARNING_BAD_CERT = 21;
const PRUint32 WARNING_BAD_CERT_STS = 22;
const PRUint32 WARNING_BAD_CERT_CLICK_ADD_EXCEPTION = 23;
const PRUint32 WARNING_BAD_CERT_CLICK_VIEW_CERT = 24;
const PRUint32 WARNING_BAD_CERT_DONT_REMEMBER_EXCEPTION = 25;
const PRUint32 WARNING_BAD_CERT_GET_ME_OUT_OF_HERE = 27;
const PRUint32 WARNING_BAD_CERT_UNDERSTAND_RISKS = 28;
const PRUint32 WARNING_BAD_CERT_TECHINICAL_DETAILS = 29;
/*
* Note that if we add more possibilities in the warning dialogs,
* it is a new experiment and we shouldn't reuse these buckets.
*/
const PRUint32 WARNING_BAD_CERT_ADD_EXCEPTION_BASE = 30;
const PRUint32 WARNING_BAD_CERT_ADD_EXCEPTION_FLAG_UNTRUSTED = 1;
const PRUint32 WARNING_BAD_CERT_ADD_EXCEPTION_FLAG_DOMAIN = 2;
const PRUint32 WARNING_BAD_CERT_ADD_EXCEPTION_FLAG_TIME = 4;
const PRUint32 WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_BASE = 38;
const PRUint32 WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_FLAG_UNTRUSTED = 1;
const PRUint32 WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_FLAG_DOMAIN = 2;
const PRUint32 WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_FLAG_TIME = 4;
// This uses up buckets till 45
};

Просмотреть файл

@ -17,6 +17,9 @@
#include "nsThreadUtils.h"
#include "nsAutoPtr.h"
#include "mozilla/Telemetry.h"
#include "nsISecurityUITelemetry.h"
NS_IMPL_THREADSAFE_ISUPPORTS1(nsSecurityWarningDialogs, nsISecurityWarningDialogs)
#define STRING_BUNDLE_URL "chrome://pipnss/locale/security.properties"
@ -60,7 +63,8 @@ nsSecurityWarningDialogs::ConfirmEnteringSecure(nsIInterfaceRequestor *ctx, bool
rv = AlertDialog(ctx, ENTER_SITE_PREF,
NS_LITERAL_STRING("EnterSecureMessage").get(),
NS_LITERAL_STRING("EnterSecureShowAgain").get(),
false);
false,
nsISecurityUITelemetry::WARNING_ENTERING_SECURE_SITE);
*_retval = true;
return rv;
@ -74,7 +78,8 @@ nsSecurityWarningDialogs::ConfirmEnteringWeak(nsIInterfaceRequestor *ctx, bool *
rv = AlertDialog(ctx, WEAK_SITE_PREF,
NS_LITERAL_STRING("WeakSecureMessage").get(),
NS_LITERAL_STRING("WeakSecureShowAgain").get(),
false);
false,
nsISecurityUITelemetry::WARNING_ENTERING_WEAK_SITE);
*_retval = true;
return rv;
@ -88,7 +93,8 @@ nsSecurityWarningDialogs::ConfirmLeavingSecure(nsIInterfaceRequestor *ctx, bool
rv = AlertDialog(ctx, LEAVE_SITE_PREF,
NS_LITERAL_STRING("LeaveSecureMessage").get(),
NS_LITERAL_STRING("LeaveSecureShowAgain").get(),
false);
false,
nsISecurityUITelemetry::WARNING_LEAVING_SECURE_SITE);
*_retval = true;
return rv;
@ -103,7 +109,8 @@ nsSecurityWarningDialogs::ConfirmMixedMode(nsIInterfaceRequestor *ctx, bool *_re
rv = AlertDialog(ctx, MIXEDCONTENT_PREF,
NS_LITERAL_STRING("MixedContentMessage").get(),
NS_LITERAL_STRING("MixedContentShowAgain").get(),
true);
true,
nsISecurityUITelemetry::WARNING_MIXED_CONTENT);
*_retval = true;
return rv;
@ -117,11 +124,13 @@ public:
const PRUnichar* aDialogMessageName,
const PRUnichar* aShowAgainName,
nsIPrefBranch* aPrefBranch,
nsIStringBundle* aStringBundle)
nsIStringBundle* aStringBundle,
PRUint32 aBucket)
: mPrompt(aPrompt), mPrefName(aPrefName),
mDialogMessageName(aDialogMessageName),
mShowAgainName(aShowAgainName), mPrefBranch(aPrefBranch),
mStringBundle(aStringBundle) {}
mStringBundle(aStringBundle),
mBucket(aBucket) {}
NS_IMETHOD Run();
protected:
@ -131,6 +140,7 @@ protected:
nsString mShowAgainName;
nsCOMPtr<nsIPrefBranch> mPrefBranch;
nsCOMPtr<nsIStringBundle> mStringBundle;
PRUint32 mBucket;
};
NS_IMETHODIMP
@ -146,6 +156,7 @@ nsAsyncAlert::Run()
// Stop if alert is not requested
if (!prefValue) return NS_OK;
mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, mBucket);
// Check for a show-once pref for this dialog.
// If the show-once pref is set to true:
// - The default value of the "show every time" checkbox is unchecked
@ -189,7 +200,8 @@ nsSecurityWarningDialogs::AlertDialog(nsIInterfaceRequestor* aCtx,
const char* aPrefName,
const PRUnichar* aDialogMessageName,
const PRUnichar* aShowAgainName,
bool aAsync)
bool aAsync,
const PRUint32 aBucket)
{
// Get Prompt to use
nsCOMPtr<nsIPrompt> prompt = do_GetInterface(aCtx);
@ -200,7 +212,9 @@ nsSecurityWarningDialogs::AlertDialog(nsIInterfaceRequestor* aCtx,
aDialogMessageName,
aShowAgainName,
mPrefBranch,
mStringBundle);
mStringBundle,
aBucket);
NS_ENSURE_TRUE(alert, NS_ERROR_OUT_OF_MEMORY);
return aAsync ? NS_DispatchToCurrentThread(alert) : alert->Run();
}
@ -212,9 +226,11 @@ nsSecurityWarningDialogs::ConfirmPostToInsecure(nsIInterfaceRequestor *ctx, bool
{
nsresult rv;
// The Telemetry clickthrough constant is 1 more than the constant for the dialog.
rv = ConfirmDialog(ctx, INSECURE_SUBMIT_PREF,
NS_LITERAL_STRING("PostToInsecureFromInsecureMessage").get(),
NS_LITERAL_STRING("PostToInsecureFromInsecureShowAgain").get(),
nsISecurityUITelemetry::WARNING_CONFIRM_POST_TO_INSECURE_FROM_INSECURE,
_result);
return rv;
@ -225,9 +241,11 @@ nsSecurityWarningDialogs::ConfirmPostToInsecureFromSecure(nsIInterfaceRequestor
{
nsresult rv;
// The Telemetry clickthrough constant is 1 more than the constant for the dialog.
rv = ConfirmDialog(ctx, nullptr, // No preference for this one - it's too important
NS_LITERAL_STRING("PostToInsecureFromSecureMessage").get(),
nullptr,
nullptr,
nsISecurityUITelemetry::WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE,
_result);
return rv;
@ -237,6 +255,7 @@ nsresult
nsSecurityWarningDialogs::ConfirmDialog(nsIInterfaceRequestor *ctx, const char *prefName,
const PRUnichar *messageName,
const PRUnichar *showAgainName,
const PRUint32 aBucket,
bool* _result)
{
nsresult rv;
@ -256,6 +275,8 @@ nsSecurityWarningDialogs::ConfirmDialog(nsIInterfaceRequestor *ctx, const char *
return NS_OK;
}
MOZ_ASSERT(NS_IsMainThread());
mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, aBucket);
// See AlertDialog() for a description of how showOnce works.
nsCAutoString showOncePref(prefName);
showOncePref += ".show_once";
@ -312,6 +333,11 @@ nsSecurityWarningDialogs::ConfirmDialog(nsIInterfaceRequestor *ctx, const char *
if (NS_FAILED(rv)) return rv;
*_result = (buttonPressed != 1);
if (*_result) {
// For confirmation dialogs, the clickthrough constant is 1 more
// than the constant for the dialog.
mozilla::Telemetry::Accumulate(mozilla::Telemetry::SECURITY_UI, aBucket + 1);
}
if (!prefValue && prefName != nullptr) {
mPrefBranch->SetBoolPref(prefName, false);

Просмотреть файл

@ -27,10 +27,11 @@ protected:
nsresult AlertDialog(nsIInterfaceRequestor *ctx, const char *prefName,
const PRUnichar *messageName,
const PRUnichar *showAgainName,
bool aAsync);
bool aAsync, const PRUint32 aBucket);
nsresult ConfirmDialog(nsIInterfaceRequestor *ctx, const char *prefName,
const PRUnichar *messageName,
const PRUnichar *showAgainName, bool* _result);
const PRUnichar *showAgainName, const PRUint32 aBucket,
bool* _result);
nsCOMPtr<nsIStringBundle> mStringBundle;
nsCOMPtr<nsIPrefBranch> mPrefBranch;
};

Просмотреть файл

@ -11,6 +11,8 @@ var gCert;
var gChecking;
var gBroken;
var gNeedReset;
var gSecHistogram;
var gNsISecTel;
function badCertListener() {}
badCertListener.prototype = {
@ -42,6 +44,10 @@ function initExceptionDialog() {
gDialog = document.documentElement;
gBundleBrand = srGetStrBundle("chrome://branding/locale/brand.properties");
gPKIBundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
gSecHistogram = Components.classes["@mozilla.org/base/telemetry;1"].
getService(Components.interfaces.nsITelemetry).
getHistogramById("SECURITY_UI");
gNsISecTel = Components.interfaces.nsISecurityUITelemetry;
var brandName = gBundleBrand.GetStringFromName("brandShortName");
@ -203,6 +209,7 @@ function updateCertStatus() {
var shortDesc3, longDesc3;
var use2 = false;
var use3 = false;
let bucketId = gNsISecTel.WARNING_BAD_CERT_ADD_EXCEPTION_BASE;
if(gCert) {
if(gBroken) {
var mms = "addExceptionDomainMismatchShort";
@ -213,11 +220,13 @@ function updateCertStatus() {
var utl = "addExceptionUnverifiedOrBadSignatureLong";
var use1 = false;
if (gSSLStatus.isDomainMismatch) {
bucketId += gNsISecTel.WARNING_BAD_CERT_ADD_EXCEPTION_FLAG_DOMAIN;
use1 = true;
shortDesc = mms;
longDesc = mml;
}
if (gSSLStatus.isNotValidAtThisTime) {
bucketId += gNsISecTel.WARNING_BAD_CERT_ADD_EXCEPTION_FLAG_TIME;
if (!use1) {
use1 = true;
shortDesc = exs;
@ -230,6 +239,7 @@ function updateCertStatus() {
}
}
if (gSSLStatus.isUntrusted) {
bucketId += gNsISecTel.WARNING_BAD_CERT_ADD_EXCEPTION_FLAG_UNTRUSTED;
if (!use1) {
use1 = true;
shortDesc = uts;
@ -246,7 +256,8 @@ function updateCertStatus() {
longDesc3 = utl;
}
}
gSecHistogram.add(bucketId);
// In these cases, we do want to enable the "Add Exception" button
gDialog.getButton("extra1").disabled = false;
@ -317,6 +328,7 @@ function updateCertStatus() {
* Handle user request to display certificate details
*/
function viewCertButtonClick() {
gSecHistogram.add(gNsISecTel.WARNING_BAD_CERT_CLICK_VIEW_CERT);
if (gCert)
viewCertHelper(this, gCert);
@ -332,16 +344,26 @@ function addException() {
var overrideService = Components.classes["@mozilla.org/security/certoverride;1"]
.getService(Components.interfaces.nsICertOverrideService);
var flags = 0;
if(gSSLStatus.isUntrusted)
let confirmBucketId = gNsISecTel.WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_BASE;
if (gSSLStatus.isUntrusted) {
flags |= overrideService.ERROR_UNTRUSTED;
if(gSSLStatus.isDomainMismatch)
confirmBucketId += gNsISecTel.WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_FLAG_UNTRUSTED;
}
if (gSSLStatus.isDomainMismatch) {
flags |= overrideService.ERROR_MISMATCH;
if(gSSLStatus.isNotValidAtThisTime)
confirmBucketId += gNsISecTel.WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_FLAG_DOMAIN;
}
if (gSSLStatus.isNotValidAtThisTime) {
flags |= overrideService.ERROR_TIME;
confirmBucketId += gNsISecTel.WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_FLAG_TIME;
}
var permanentCheckbox = document.getElementById("permanent");
var shouldStorePermanently = permanentCheckbox.checked && !inPrivateBrowsingMode();
if(!permanentCheckbox.checked)
gSecHistogram.add(gNsISecTel.WARNING_BAD_CERT_DONT_REMEMBER_EXCEPTION);
gSecHistogram.add(confirmBucketId);
var uri = getURI();
overrideService.rememberValidityOverride(
uri.asciiHost, uri.port,

Просмотреть файл

@ -13,21 +13,22 @@ def print_test_dirs(topsrcdir, manifest_file):
into manifests, as we currently have no need for that.
"""
dirs = set()
# output the directory of this (parent) manifest
topsrcdir = os.path.abspath(topsrcdir)
scriptdir = os.path.abspath(os.path.dirname(__file__))
print scriptdir[len(topsrcdir) + 1:]
dirs.add(scriptdir[len(topsrcdir) + 1:])
# output the directories of all the other manifests
dirs = set()
manifest = TestManifest()
manifest.read(manifest_file)
for i in manifest.get():
dirs.add(os.path.dirname(i['manifest'])[len(topsrcdir) + 1:])
d = os.path.dirname(i['manifest'])[len(topsrcdir) + 1:]
dirs.add(d)
for path in dirs:
path = path.replace('\\', '/')
print path
if __name__ == '__main__':
if len(sys.argv) < 3:
print >>sys.stderr, "Usage: %s topsrcdir manifest.ini" % sys.argv[0]

Просмотреть файл

@ -201,6 +201,20 @@ SocialProvider.prototype = {
updateUserProfile: function(profile) {
this.profile = profile;
// Sanitize the portrait from any potential script-injection.
if (profile.portrait) {
try {
let portraitUri = Services.io.newURI(profile.portrait, null, null);
let scheme = portraitUri ? portraitUri.scheme : "";
if (scheme != "data" && scheme != "http" && scheme != "https") {
profile.portrait = "";
}
} catch (ex) {
profile.portrait = "";
}
}
if (profile.iconURL)
this.iconURL = profile.iconURL;

Просмотреть файл

@ -43,7 +43,7 @@ let tests = {
testProfile: function(next) {
let expect = {
portrait: "chrome://branding/content/icon48.png",
portrait: "https://example.com/portrait.jpg",
userName: "trickster",
displayName: "Kuma Lisa",
profileURL: "http://en.wikipedia.org/wiki/Kuma_Lisa"

Просмотреть файл

@ -518,6 +518,11 @@ HISTOGRAM(BROWSERPROVIDER_XUL_IMPORT_BOOKMARKS, 1, 50000, 20, EXPONENTIAL, "Numb
HISTOGRAM(BROWSERPROVIDER_XUL_IMPORT_HISTORY, 1, 1000000, 20, EXPONENTIAL, "Number of history entries in the original XUL places database")
#endif
/**
* Security UI Telemetry
*/
HISTOGRAM_ENUMERATED_VALUES(SECURITY_UI, 100, "Security UI Telemetry")
#undef HISTOGRAM_ENUMERATED_VALUES
#undef HISTOGRAM_BOOLEAN
#undef HISTOGRAM_FLAG

Просмотреть файл

@ -173,6 +173,10 @@ Installer.prototype = {
args.wrappedJSObject = args;
try {
Cc["@mozilla.org/base/telemetry;1"].
getService(Ci.nsITelemetry).
getHistogramById("SECURITY_UI").
add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL);
Services.ww.openWindow(this.window, URI_XPINSTALL_DIALOG,
null, "chrome,modal,centerscreen", args);
} catch (e) {

Просмотреть файл

@ -138,6 +138,10 @@ XPInstallConfirm.init = function ()
XPInstallConfirm.onOK = function ()
{
Components.classes["@mozilla.org/base/telemetry;1"].
getService(Components.interfaces.nsITelemetry).
getHistogramById("SECURITY_UI").
add(Components.interfaces.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL_CLICK_THROUGH);
args.installs.forEach(function(install) {
install.install();
});

Просмотреть файл

@ -151,8 +151,11 @@ function test2() {
ok(box.mozMatchesSelector(":hover"), "Box should be hovered");
// Unhover box and iframe by moving the mouse outside the window.
moveMouseTo(0, 150, function () {
ok(!gIFrame.mozMatchesSelector(":hover"), "iframe shouldn't be hovered");
ok(!box.mozMatchesSelector(":hover"), "box shouldn't be hovered");
const isOSXSnowLeopard = navigator.userAgent.indexOf("Mac OS X 10.6") != -1;
if (!isOSXSnowLeopard) {
ok(!gIFrame.mozMatchesSelector(":hover"), "iframe shouldn't be hovered");
ok(!box.mozMatchesSelector(":hover"), "box shouldn't be hovered");
}
finalize();
});
}, gLeftWindow, box);