Merge mozilla-central into build-system

This commit is contained in:
Ms2ger 2013-01-03 10:46:16 +01:00
commit 4951adbb99
341 changed files with 6369 additions and 3421 deletions

View File

@ -151,13 +151,6 @@ SYMBOL_INDEX_NAME = \
buildsymbols:
ifdef MOZ_CRASHREPORTER
ifdef USE_ELF_HACK
ifeq (mobile,$(MOZ_BUILD_APP))
$(MAKE) -C mobile/xul/installer elfhack
else
$(MAKE) -C $(MOZ_BUILD_APP)/installer elfhack
endif
endif
echo building symbol store
$(RM) -r $(DIST)/crashreporter-symbols
$(RM) "$(DIST)/$(SYMBOL_ARCHIVE_BASENAME).zip"

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
@ -117,10 +118,12 @@ AccReorderEvent::IsShowHideEventTarget(const Accessible* aTarget) const
{
uint32_t count = mDependentEvents.Length();
for (uint32_t index = count - 1; index < count; index--) {
if (mDependentEvents[index]->mAccessible == aTarget &&
mDependentEvents[index]->mEventType == nsIAccessibleEvent::EVENT_SHOW ||
mDependentEvents[index]->mEventType == nsIAccessibleEvent::EVENT_HIDE) {
return mDependentEvents[index]->mEventType;
if (mDependentEvents[index]->mAccessible == aTarget) {
uint32_t eventType = mDependentEvents[index]->mEventType;
if (eventType == nsIAccessibleEvent::EVENT_SHOW ||
eventType == nsIAccessibleEvent::EVENT_HIDE) {
return mDependentEvents[index]->mEventType;
}
}
}

View File

@ -641,7 +641,6 @@ NotificationController::CoalesceTextChangeEventsFor(AccShowEvent* aTailEvent,
void
NotificationController::CreateTextChangeEventFor(AccMutationEvent* aEvent)
{
DocAccessible* document = aEvent->GetDocAccessible();
Accessible* container = aEvent->mAccessible->Parent();
if (!container)
return;

View File

@ -1460,6 +1460,9 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
case eTextLeafType:
newAcc = new TextLeafAccessibleWrap(aContent, document);
break;
default:
MOZ_ASSERT(false);
break;
}
return newAcc.forget();

View File

@ -264,6 +264,16 @@ Accessible::Name(nsString& aName)
aName.CompressWhitespace();
return eNameFromTooltip;
}
} else if (mContent->IsSVG()) {
// If user agents need to choose among multiple desc or title elements
// for processing, the user agent shall choose the first one.
for (nsIContent* childElm = mContent->GetFirstChild(); childElm;
childElm = childElm->GetNextSibling()) {
if (childElm->IsSVG(nsGkAtoms::title)) {
nsTextEquivUtils::AppendTextEquivFromContent(this, childElm, &aName);
return eNameFromTooltip;
}
}
}
if (nameFlag != eNoNameOnPurpose)
@ -307,25 +317,40 @@ Accessible::Description(nsString& aDescription)
// Try XUL <description control="[id]">description text</description>
XULDescriptionIterator iter(Document(), mContent);
Accessible* descr = nullptr;
while ((descr = iter.Next()))
while ((descr = iter.Next())) {
nsTextEquivUtils::AppendTextEquivFromContent(this, descr->GetContent(),
&aDescription);
}
}
if (aDescription.IsEmpty()) {
nsIAtom *descAtom = isXUL ? nsGkAtoms::tooltiptext :
nsGkAtoms::title;
if (mContent->GetAttr(kNameSpaceID_None, descAtom, aDescription)) {
nsAutoString name;
Name(name);
if (name.IsEmpty() || aDescription == name)
// Don't use tooltip for a description if this object
// has no name or the tooltip is the same as the name
aDescription.Truncate();
if (aDescription.IsEmpty()) {
// Keep the Name() method logic.
if (mContent->IsHTML()) {
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aDescription);
} else if (mContent->IsXUL()) {
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aDescription);
} else if (mContent->IsSVG()) {
for (nsIContent* childElm = mContent->GetFirstChild(); childElm;
childElm = childElm->GetNextSibling()) {
if (childElm->IsSVG(nsGkAtoms::title)) {
nsTextEquivUtils::AppendTextEquivFromContent(this, childElm,
&aDescription);
break;
}
}
}
if (!aDescription.IsEmpty()) {
nsAutoString name;
ENameValueFlag nameFlag = Name(name);
// Don't use tooltip for a description if it was used for a name.
if (nameFlag == eNameFromTooltip)
aDescription.Truncate();
}
}
aDescription.CompressWhitespace();
}
aDescription.CompressWhitespace();
}
NS_IMETHODIMP
@ -2494,6 +2519,18 @@ Accessible::NativeName(nsString& aName)
if (mContent->IsXUL())
return GetXULName(aName);
if (mContent->IsSVG()) {
// If user agents need to choose among multiple desc or title elements
// for processing, the user agent shall choose the first one.
for (nsIContent* childElm = mContent->GetFirstChild(); childElm;
childElm = childElm->GetNextSibling()) {
if (childElm->IsSVG(nsGkAtoms::desc)) {
nsTextEquivUtils::AppendTextEquivFromContent(this, childElm, &aName);
return eNameOK;
}
}
}
return eNameOK;
}

View File

@ -17,3 +17,16 @@ function testName(aAccOrElmOrID, aName, aMsg)
}
return acc;
}
/**
* Test accessible description for the given accessible.
*/
function testDescr(aAccOrElmOrID, aDescr)
{
var acc = getAccessible(aAccOrElmOrID);
if (!acc)
return;
is(acc.description, aDescr,
"Wrong description for " + prettyName(aAccOrElmOrID));
}

View File

@ -21,6 +21,7 @@ MOCHITEST_A11Y_FILES =\
test_link.html \
test_list.html \
test_markup.html \
test_svg.html \
test_browserui.xul \
test_tree.xul \
markuprules.xml \

View File

@ -0,0 +1,56 @@
<html>
<head>
<title>Accessible name and description for SVG elements</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../name.js"></script>
<script type="application/javascript">
function doTest()
{
testName("svg1", "A name");
testDescr("svg1", "A description");
testName("svg2", "A tooltip");
testDescr("svg2", "");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=459357"
title="Support accessible name computation for SVG">
Mozilla Bug 459357
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg1">
<title>A description</title>
<desc>A name</desc>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg2">
<title>A tooltip</title>
</svg>
</body>
</html>

View File

@ -8,18 +8,10 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="common.js"></script>
<script type="application/javascript"
src="name.js"></script>
<script type="application/javascript">
function testDescr(aAccOrElmOrID, aDescr)
{
var acc = getAccessible(aAccOrElmOrID);
if (!acc)
return;
is(acc.description, aDescr,
"Wrong description for " + prettyName(aAccOrElmOrID));
}
function doTest()
{
// Description from aria-describedby attribute

View File

@ -192,15 +192,15 @@ UpdatePrompt.prototype = {
this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
},
_copyProperties: ["appVersion", "buildID", "detailsURL", "displayVersion",
"errorCode", "isOSUpdate", "platformVersion",
"previousAppVersion", "state", "statusText"],
sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) {
let detail = {
displayVersion: aUpdate.displayVersion,
detailsURL: aUpdate.detailsURL,
statusText: aUpdate.statusText,
state: aUpdate.state,
errorCode: aUpdate.errorCode,
isOSUpdate: aUpdate.isOSUpdate
};
let detail = {};
for each (let property in this._copyProperties) {
detail[property] = aUpdate[property];
}
let patch = aUpdate.selectedPatch;
if (!patch && aUpdate.patchCount > 0) {

View File

@ -1750,7 +1750,6 @@ var nonBrowserWindowShutdown = gBrowserInit.nonBrowserWindowShutdown.bind(
function HandleAppCommandEvent(evt) {
evt.stopPropagation();
switch (evt.command) {
case "Back":
BrowserBack();
@ -1774,9 +1773,35 @@ function HandleAppCommandEvent(evt) {
case "Home":
BrowserHome();
break;
default:
case "New":
BrowserOpenTab();
break;
case "Close":
BrowserCloseTabOrWindow();
break;
case "Find":
gFindBar.onFindCommand();
break;
case "Help":
openHelpLink('firefox-help');
break;
case "Open":
BrowserOpenFileWindow();
break;
case "Print":
PrintUtils.print();
break;
case "Save":
saveDocument(window.content.document);
break;
case "SendMail":
MailIntegration.sendLinkForWindow(window.content);
break;
default:
return;
}
evt.stopPropagation();
evt.preventDefault();
}
function gotoHistoryIndex(aEvent) {

View File

@ -21,9 +21,10 @@ richlistitem.download {
[state="9"]) /* Blocked (policy) */)
.downloadRemoveFromHistoryMenuItem,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"]) /* Paused */)
[state="1"], /* Finished */
[state="4"], /* Paused */
[state="5"]) /* Starting (queued) */)
.downloadShowMenuItem,
.download-state[state="7"] .downloadCommandsSeparator

View File

@ -2,9 +2,14 @@
* 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/. */
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
let ContentAreaDownloadsView = {
init: function CADV_init() {
let view = new DownloadsPlacesView(document.getElementById("downloadsRichListBox"));
view.place = "place:transition=7&sort=4";
// Do not display the Places downloads in private windows
if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
view.place = "place:transition=7&sort=4";
}
}
};

View File

@ -57,9 +57,10 @@ richlistitem[type="download"]:not([selected]) button {
.downloadRemoveFromHistoryMenuItem,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"]) /* Paused */)
[state="1"], /* Finished */
[state="4"], /* Paused */
[state="5"]) /* Starting (queued) */)
.downloadShowMenuItem,
.download-state[state="7"] .downloadCommandsSeparator

View File

@ -32,6 +32,8 @@ XPCOMUtils.defineLazyServiceGetter(this, "gBrowserGlue",
"nsIBrowserGlue");
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
"resource:///modules/RecentWindow.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
////////////////////////////////////////////////////////////////////////////////
//// DownloadsUI
@ -112,28 +114,33 @@ DownloadsUI.prototype = {
_showDownloadManagerUI:
function DUI_showDownloadManagerUI(aWindowContext, aID, aReason)
{
let organizer = Services.wm.getMostRecentWindow("Places:Organizer");
if (!organizer) {
let parentWindow = aWindowContext;
// If we weren't given a window context, try to find a browser window
// to use as our parent - and if that doesn't work, error out and give
// up.
// If we weren't given a window context, try to find a browser window
// to use as our parent - and if that doesn't work, error out and give up.
let parentWindow = aWindowContext;
if (!parentWindow) {
parentWindow = RecentWindow.getMostRecentBrowserWindow();
if (!parentWindow) {
parentWindow = RecentWindow.getMostRecentBrowserWindow();
if (!parentWindow) {
Components.utils
.reportError("Couldn't find a browser window to open " +
"the Places Downloads View from.");
return;
}
Components.utils.reportError(
"Couldn't find a browser window to open the Places Downloads View " +
"from.");
return;
}
parentWindow.openDialog("chrome://browser/content/places/places.xul",
"", "chrome,toolbar=yes,dialog=no,resizable",
"Downloads");
}
else {
organizer.PlacesOrganizer.selectLeftPaneQuery("Downloads");
organizer.focus();
// If window is private then show it in a tab.
if (PrivateBrowsingUtils.isWindowPrivate(parentWindow)) {
parentWindow.openUILinkIn("about:downloads", "tab");
return;
} else {
let organizer = Services.wm.getMostRecentWindow("Places:Organizer");
if (!organizer) {
parentWindow.openDialog("chrome://browser/content/places/places.xul",
"", "chrome,toolbar=yes,dialog=no,resizable",
"Downloads");
} else {
organizer.PlacesOrganizer.selectLeftPaneQuery("Downloads");
organizer.focus();
}
}
}
};

View File

@ -910,13 +910,13 @@ BrowserGlue.prototype = {
*
* - The last accepted/refused policy (either by accepting the prompt or by
* manually flipping the telemetry preference) is already at version
* TELEMETRY_DISPLAY_REV.
* TELEMETRY_DISPLAY_REV or higher (to avoid the prompt in tests).
*/
var telemetryDisplayed;
try {
telemetryDisplayed = Services.prefs.getIntPref(PREF_TELEMETRY_DISPLAYED);
} catch(e) {}
if (telemetryDisplayed === TELEMETRY_DISPLAY_REV)
if (telemetryDisplayed >= TELEMETRY_DISPLAY_REV)
return;
#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
@ -925,7 +925,8 @@ BrowserGlue.prototype = {
*
* - Telemetry is disabled
* - Telemetry was explicitly refused through the UI
* - Opt-in telemetry was enabled and this is the first run with opt-out.
* - Opt-in telemetry was already enabled, don't notify the user until next
* policy update. (Do the check only at first run with opt-out builds)
*/
var telemetryEnabled = Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED);

View File

@ -117,7 +117,7 @@ let gSyncPane = {
* "reset" -- reset sync
*/
openSetup: function (wizardType) {
var win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
if (win)
win.focus();
else {
@ -150,6 +150,6 @@ let gSyncPane = {
resetSync: function () {
this.openSetup("reset");
}
}
},
};

View File

@ -118,7 +118,7 @@ let gSyncPane = {
* "reset" -- reset sync
*/
openSetup: function (wizardType) {
var win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
if (win)
win.focus();
else {
@ -151,6 +151,6 @@ let gSyncPane = {
resetSync: function () {
this.openSetup("reset");
}
}
},
};

View File

@ -6,6 +6,7 @@
let gTests;
function test() {
waitForExplicitFinish();
requestLongerTimeout(2);
gTests = runTest();
moveAlong();
}

View File

@ -35,7 +35,7 @@ function test() {
"The checkbox should not be disabled");
win.close();
callback();
executeSoon(callback);
});
}, false);
}

View File

@ -18,7 +18,7 @@ function test() {
is(crhCommand.hasAttribute("disabled"), aPrivateMode,
"Clear Recent History command should be disabled according to the private browsing mode");
aCallback();
executeSoon(aCallback);
});
};

View File

@ -8,7 +8,6 @@ function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
Services.prefs.clearUserPref("browser.sessionstore.interval");
ss.setBrowserState(originalState);
});
@ -34,8 +33,6 @@ function runNextTest() {
let currentTest = tests.shift();
waitForBrowserState(testState, currentTest);
} else {
Services.prefs.clearUserPref("browser.sessionstore.interval");
ss.setBrowserState(originalState);
finish();
}
}
@ -105,33 +102,34 @@ function test_2() {
// Test opening default-normal-private-normal windows and closing a normal window
function test_3() {
testOnWindow(false, function(normalWindow) {
let tab = normalWindow.gBrowser.addTab("http://www.example.com/1");
whenBrowserLoaded(tab.linkedBrowser, function() {
waitForTabLoad(normalWindow, "http://www.example.com/", function() {
testOnWindow(true, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/2");
testOnWindow(false, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/3");
waitForTabLoad(aWindow, "http://www.example.com/", function() {
testOnWindow(false, function(aWindow) {
waitForTabLoad(aWindow, "http://www.example.com/", function() {
let curState = JSON.parse(ss.getBrowserState());
is (curState.windows.length, 4, "Browser has opened 4 windows");
is (curState.windows[2].isPrivate, true, "Window 2 is private");
is (curState.selectedWindow, 4, "Last window opened is the one selected");
let curState = JSON.parse(ss.getBrowserState());
is(curState.windows.length, 4, "Browser has opened 4 windows");
is(curState.windows[2].isPrivate, true, "Window 2 is private");
is(curState.selectedWindow, 4, "Last window opened is the one selected");
waitForWindowClose(normalWindow, function() {
forceWriteState(function(state) {
is(state.windows.length, 2,
"sessionstore state: 2 windows in data being writted to disk");
is(state.selectedWindow, 2,
"Selected window is updated to match one of the saved windows");
state.windows.forEach(function(win) {
is(!win.isPrivate, true, "Saved window is not private");
waitForWindowClose(normalWindow, function() {
forceWriteState(function(state) {
is(state.windows.length, 2,
"sessionstore state: 2 windows in data being writted to disk");
is(state.selectedWindow, 2,
"Selected window is updated to match one of the saved windows");
state.windows.forEach(function(win) {
is(!win.isPrivate, true, "Saved window is not private");
});
is(state._closedWindows.length, 1,
"sessionstore state: 1 closed window in data being writted to disk");
state._closedWindows.forEach(function(win) {
is(!win.isPrivate, true, "Closed window is not private");
});
runNextTest();
});
});
is(state._closedWindows.length, 1,
"sessionstore state: 1 closed window in data being writted to disk");
state._closedWindows.forEach(function(win) {
is(!win.isPrivate, true, "Closed window is not private");
});
runNextTest();
});
});
});
@ -141,30 +139,27 @@ function test_3() {
}
function waitForWindowClose(aWin, aCallback) {
Services.obs.addObserver(function observe(aSubject, aTopic, aData) {
if (aTopic == "domwindowclosed" && aWin == aSubject) {
Services.obs.removeObserver(observe, aTopic);
checkWindowIsClosed(aWin, aCallback);
let winCount = JSON.parse(ss.getBrowserState()).windows.length;
aWin.addEventListener("SSWindowClosing", function onWindowClosing() {
aWin.removeEventListener("SSWindowClosing", onWindowClosing, false);
function checkCount() {
let state = JSON.parse(ss.getBrowserState());
if (state.windows.length == (winCount - 1)) {
aCallback();
} else {
executeSoon(checkCount);
}
}
}, "domwindowclosed", false);
executeSoon(checkCount);
}, false);
aWin.close();
}
function checkWindowIsClosed(aWin, aCallback) {
if (aWin.closed) {
info("Window is closed");
executeSoon(aCallback);
} else {
executeSoon(function() {
checkWindowIsClosed(aWin, aCallback);
});
}
}
function forceWriteState(aCallback) {
Services.obs.addObserver(function observe(aSubject, aTopic, aData) {
if (aTopic == "sessionstore-state-write") {
Services.obs.removeObserver(observe, aTopic);
Services.prefs.clearUserPref("browser.sessionstore.interval");
aSubject.QueryInterface(Ci.nsISupportsString);
aCallback(JSON.parse(aSubject.data));
}
@ -179,3 +174,11 @@ function testOnWindow(aIsPrivate, aCallback) {
executeSoon(function() { aCallback(win); });
}, false);
}
function waitForTabLoad(aWin, aURL, aCallback) {
aWin.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
aWin.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
aCallback();
}, true);
aWin.gBrowser.selectedBrowser.loadURI(aURL);
}

View File

@ -18,6 +18,9 @@ else
. $topsrcdir/build/win32/mozconfig.vs2010
fi
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -27,6 +27,9 @@ else
. $topsrcdir/build/win32/mozconfig.vs2010
fi
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -24,6 +24,9 @@ else
. $topsrcdir/build/win32/mozconfig.vs2010
fi
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -13,6 +13,9 @@ if test -z "${_PYMAKE}"; then
mk_add_options MOZ_MAKE_FLAGS=-j1
fi
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -22,6 +22,9 @@ if test -z "${_PYMAKE}"; then
mk_add_options MOZ_MAKE_FLAGS=-j1
fi
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -18,10 +18,13 @@
display: none;
}
#downloadsHistory {
background: transparent;
#downloadsFooter {
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
}
#downloadsHistory {
background: transparent;
color: hsl(210,100%,75%);
cursor: pointer;
}

View File

@ -407,8 +407,9 @@ user_pref("app.update.enabled", false);
user_pref("app.update.staging.enabled", false);
user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
user_pref("dom.w3c_touch_events.enabled", 1);
#expand user_pref("toolkit.telemetry.prompted", __MOZ_TELEMETRY_DISPLAY_REV__);
#expand user_pref("toolkit.telemetry.notifiedOptOut", __MOZ_TELEMETRY_DISPLAY_REV__);
// Set a future policy version to avoid the telemetry prompt.
user_pref("toolkit.telemetry.prompted", 999);
user_pref("toolkit.telemetry.notifiedOptOut", 999);
// Existing tests assume there is no font size inflation.
user_pref("font.size.inflation.emPerLine", 0);
user_pref("font.size.inflation.minTwips", 0);

View File

@ -585,7 +585,7 @@ void ElfSegment::removeSection(ElfSection *section)
unsigned int ElfSegment::getFileSize()
{
if (type == PT_GNU_RELRO)
if (type == PT_GNU_RELRO || isElfHackFillerSegment())
return filesz;
if (sections.empty())
@ -604,7 +604,7 @@ unsigned int ElfSegment::getFileSize()
unsigned int ElfSegment::getMemSize()
{
if (type == PT_GNU_RELRO)
if (type == PT_GNU_RELRO || isElfHackFillerSegment())
return memsz;
if (sections.empty())
@ -621,6 +621,10 @@ unsigned int ElfSegment::getOffset()
(sections.front()->getAddr() != vaddr))
throw std::runtime_error("PT_GNU_RELRO segment doesn't start on a section start");
// Neither bionic nor glibc linkers seem to like when the offset of that segment is 0
if (isElfHackFillerSegment())
return vaddr;
return sections.empty() ? 0 : sections.front()->getOffset();
}
@ -630,6 +634,9 @@ unsigned int ElfSegment::getAddr()
(sections.front()->getAddr() != vaddr))
throw std::runtime_error("PT_GNU_RELRO segment doesn't start on a section start");
if (isElfHackFillerSegment())
return vaddr;
return sections.empty() ? 0 : sections.front()->getAddr();
}

View File

@ -376,7 +376,7 @@ void set_relative_reloc(Elf_Rela *rel, Elf *elf, unsigned int value) {
rel->r_addend = value;
}
void maybe_split_segment(Elf *elf, ElfSegment *segment)
void maybe_split_segment(Elf *elf, ElfSegment *segment, bool fill)
{
std::list<ElfSection *>::iterator it = segment->begin();
for (ElfSection *last = *(it++); it != segment->end(); last = *(it++)) {
@ -396,19 +396,40 @@ void maybe_split_segment(Elf *elf, ElfSegment *segment)
phdr.p_memsz = (unsigned int)-1;
ElfSegment *newSegment = new ElfSegment(&phdr);
elf->insertSegmentAfter(segment, newSegment);
ElfSection *section = *it;
for (; it != segment->end(); ++it) {
newSegment->addSection(*it);
}
for (it = newSegment->begin(); it != newSegment->end(); it++) {
segment->removeSection(*it);
}
// Fill the virtual address space gap left between the two PT_LOADs
// with a new PT_LOAD with no permissions. This avoids the linker
// (especially bionic's) filling the gap with anonymous memory,
// which breakpad doesn't like.
// /!\ running strip on a elfhacked binary will break this filler
// PT_LOAD.
if (!fill)
break;
ElfSection *previous = section->getPrevious();
phdr.p_vaddr = (previous->getAddr() + previous->getSize() + segment->getAlign() - 1) & ~(segment->getAlign() - 1);
phdr.p_paddr = phdr.p_vaddr + segment->getVPDiff();
phdr.p_flags = 0;
phdr.p_align = 0;
phdr.p_filesz = (section->getAddr() & ~(newSegment->getAlign() - 1)) - phdr.p_vaddr;
phdr.p_memsz = phdr.p_filesz;
if (phdr.p_filesz) {
newSegment = new ElfSegment(&phdr);
assert(newSegment->isElfHackFillerSegment());
elf->insertSegmentAfter(segment, newSegment);
}
break;
}
}
}
template <typename Rel_Type>
int do_relocation_section(Elf *elf, unsigned int rel_type, unsigned int rel_type2, bool force)
int do_relocation_section(Elf *elf, unsigned int rel_type, unsigned int rel_type2, bool force, bool fill)
{
ElfDynamic_Section *dyn = elf->getDynSection();
if (dyn ==NULL) {
@ -568,7 +589,7 @@ int do_relocation_section(Elf *elf, unsigned int rel_type, unsigned int rel_type
// Adjust PT_LOAD segments
for (ElfSegment *segment = elf->getSegmentByType(PT_LOAD); segment;
segment = elf->getSegmentByType(PT_LOAD, segment)) {
maybe_split_segment(elf, segment);
maybe_split_segment(elf, segment, fill);
}
// Ensure Elf sections will be at their final location.
@ -599,7 +620,7 @@ static inline int backup_file(const char *name)
return rename(name, fname.c_str());
}
void do_file(const char *name, bool backup = false, bool force = false)
void do_file(const char *name, bool backup = false, bool force = false, bool fill = false)
{
std::ifstream file(name, std::ios::in|std::ios::binary);
Elf elf(file);
@ -622,13 +643,13 @@ void do_file(const char *name, bool backup = false, bool force = false)
int exit = -1;
switch (elf.getMachine()) {
case EM_386:
exit = do_relocation_section<Elf_Rel>(&elf, R_386_RELATIVE, R_386_32, force);
exit = do_relocation_section<Elf_Rel>(&elf, R_386_RELATIVE, R_386_32, force, fill);
break;
case EM_X86_64:
exit = do_relocation_section<Elf_Rela>(&elf, R_X86_64_RELATIVE, R_X86_64_64, force);
exit = do_relocation_section<Elf_Rela>(&elf, R_X86_64_RELATIVE, R_X86_64_64, force, fill);
break;
case EM_ARM:
exit = do_relocation_section<Elf_Rel>(&elf, R_ARM_RELATIVE, R_ARM_ABS32, force);
exit = do_relocation_section<Elf_Rel>(&elf, R_ARM_RELATIVE, R_ARM_ABS32, force, fill);
break;
}
if (exit == 0) {
@ -677,8 +698,14 @@ void undo_file(const char *name, bool backup = false)
ElfSegment *first = elf.getSegmentByType(PT_LOAD);
ElfSegment *second = elf.getSegmentByType(PT_LOAD, first);
ElfSegment *filler = NULL;
// If the second PT_LOAD is a filler from elfhack --fill, check the third.
if (!second->isElfHackFillerSegment()) {
filler = second;
second = elf.getSegmentByType(PT_LOAD, filler);
}
if (second->getFlags() != first->getFlags()) {
fprintf(stderr, "First two PT_LOAD segments don't have the same flags. Skipping\n");
fprintf(stderr, "Couldn't identify elfhacked PT_LOAD segments. Skipping\n");
return;
}
// Move sections from the second PT_LOAD to the first, and remove the
@ -688,6 +715,8 @@ void undo_file(const char *name, bool backup = false)
first->addSection(*section);
elf.removeSegment(second);
if (filler)
elf.removeSegment(filler);
if (backup && backup_file(name) != 0) {
fprintf(stderr, "Couln't create backup file\n");
@ -704,6 +733,7 @@ int main(int argc, char *argv[])
bool backup = false;
bool force = false;
bool revert = false;
bool fill = false;
char *lastSlash = rindex(argv[0], '/');
if (lastSlash != NULL)
rundir = strndup(argv[0], lastSlash - argv[0]);
@ -714,10 +744,12 @@ int main(int argc, char *argv[])
backup = true;
else if (strcmp(argv[arg], "-r") == 0)
revert = true;
else if (revert)
else if (strcmp(argv[arg], "--fill") == 0)
fill = true;
else if (revert) {
undo_file(argv[arg], backup);
else
do_file(argv[arg], backup, force);
} else
do_file(argv[arg], backup, force, fill);
}
free(rundir);

View File

@ -460,6 +460,10 @@ public:
std::list<ElfSection *>::iterator end() { return sections.end(); }
void clear();
bool isElfHackFillerSegment() {
return type == PT_LOAD && flags == 0;
}
private:
unsigned int type;
int v_p_diff; // Difference between physical and virtual address

View File

@ -3710,8 +3710,8 @@ if test -n "$MOZ_LINKER"; then
ARM_ARCH=`${CC-cc} ${CFLAGS} -dM -E - < /dev/null | sed -n 's/.*__ARM_ARCH_\([[0-9]]*\).*/\1/p'`
dnl When building for < ARMv7, we need to ensure 16k alignment of ELF segments
if test -n "$ARM_ARCH" && test "$ARM_ARCH" -lt 7; then
LDFLAGS="$LDFLAGS -Wl,-z,max-page-size=0x4000"
_SUBDIR_LDFLAGS="$_SUBDIR_LDFLAGS -Wl,-z,max-page-size=0x4000"
LDFLAGS="$LDFLAGS -Wl,-z,max-page-size=0x4000 -Wl,-z,common-page-size=0x4000"
_SUBDIR_LDFLAGS="$_SUBDIR_LDFLAGS -Wl,-z,max-page-size=0x4000 -Wl,-z,common-page-size=0x4000"
fi
fi
fi

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var frameDoc = document.getElementById("f").contentDocument;
var confusedNode = frameDoc.createTextNode("y");
confusedNode.__proto__ = document.createTextNode("x");
confusedNode.setUserData("key", "data", null);
confusedNode.setUserData("key", "data", null);
}
</script>
</head>
<body onload="boom();">
<iframe src="data:text/html,1" id="f"></iframe>
</body>
</html>

View File

@ -119,4 +119,5 @@ load xhr_empty_datauri.html
load 815477.html
load 815500.html
load 816253.html
load 822691.html
load 822723.html

View File

@ -1941,8 +1941,10 @@ public:
int32_t aScreenX, int32_t aScreenY, int32_t aClientX,
int32_t aClientY, int32_t aRadiusX, int32_t aRadiusY,
float aRotationAngle, float aForce);
already_AddRefed<nsIDOMTouchList> CreateTouchList();
already_AddRefed<nsIDOMTouchList>
CreateTouchList(nsIDOMTouch* aTouch);
CreateTouchList(nsIDOMTouch* aTouch,
const mozilla::dom::Sequence<nsRefPtr<nsIDOMTouch> >& aTouches);
already_AddRefed<nsIDOMTouchList>
CreateTouchList(const mozilla::dom::Sequence<nsRefPtr<nsIDOMTouch> >& aTouches);

View File

@ -1874,86 +1874,86 @@ extern const nsIID kThisPtrOffsetsSID;
NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID)
#define NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(_final) \
NS_IMETHOD GetNodeName(nsAString& aNodeName) _final \
#define NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(...) \
NS_IMETHOD GetNodeName(nsAString& aNodeName) __VA_ARGS__ \
{ \
nsINode::GetNodeName(aNodeName); \
return NS_OK; \
} \
NS_IMETHOD GetNodeValue(nsAString& aNodeValue) _final \
NS_IMETHOD GetNodeValue(nsAString& aNodeValue) __VA_ARGS__ \
{ \
nsINode::GetNodeValue(aNodeValue); \
return NS_OK; \
} \
NS_IMETHOD SetNodeValue(const nsAString& aNodeValue) _final \
NS_IMETHOD SetNodeValue(const nsAString& aNodeValue) __VA_ARGS__ \
{ \
mozilla::ErrorResult rv; \
nsINode::SetNodeValue(aNodeValue, rv); \
return rv.ErrorCode(); \
} \
NS_IMETHOD GetNodeType(uint16_t* aNodeType) _final \
NS_IMETHOD GetNodeType(uint16_t* aNodeType) __VA_ARGS__ \
{ \
*aNodeType = nsINode::NodeType(); \
return NS_OK; \
} \
NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) _final \
NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) __VA_ARGS__ \
{ \
return nsINode::GetParentNode(aParentNode); \
} \
NS_IMETHOD GetParentElement(nsIDOMElement** aParentElement) _final \
NS_IMETHOD GetParentElement(nsIDOMElement** aParentElement) __VA_ARGS__ \
{ \
return nsINode::GetParentElement(aParentElement); \
} \
NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) _final \
NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) __VA_ARGS__ \
{ \
return nsINode::GetChildNodes(aChildNodes); \
} \
NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) _final \
NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) __VA_ARGS__ \
{ \
return nsINode::GetFirstChild(aFirstChild); \
} \
NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) _final \
NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) __VA_ARGS__ \
{ \
return nsINode::GetLastChild(aLastChild); \
} \
NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) _final \
NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) __VA_ARGS__ \
{ \
return nsINode::GetPreviousSibling(aPreviousSibling); \
} \
NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) _final \
NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) __VA_ARGS__ \
{ \
return nsINode::GetNextSibling(aNextSibling); \
} \
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) _final \
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) __VA_ARGS__ \
{ \
return nsINode::GetAttributes(aAttributes); \
} \
NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) _final \
NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) __VA_ARGS__ \
{ \
return nsINode::GetOwnerDocument(aOwnerDocument); \
} \
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aResult) _final \
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aResult) __VA_ARGS__ \
{ \
return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aResult); \
} \
NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aResult) _final \
NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ \
{ \
return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aResult); \
} \
NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aResult) _final \
NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ \
{ \
return nsINode::RemoveChild(aOldChild, aResult); \
} \
NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aResult) _final \
NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aResult) __VA_ARGS__ \
{ \
return InsertBefore(aNewChild, nullptr, aResult); \
} \
NS_IMETHOD HasChildNodes(bool* aResult) _final \
NS_IMETHOD HasChildNodes(bool* aResult) __VA_ARGS__ \
{ \
*aResult = nsINode::HasChildNodes(); \
return NS_OK; \
} \
NS_IMETHOD CloneNode(bool aDeep, uint8_t aArgc, nsIDOMNode** aResult) _final \
NS_IMETHOD CloneNode(bool aDeep, uint8_t aArgc, nsIDOMNode** aResult) __VA_ARGS__ \
{ \
if (aArgc == 0) { \
aDeep = true; \
@ -1966,86 +1966,86 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID)
*aResult = clone.forget().get()->AsDOMNode(); \
return NS_OK; \
} \
NS_IMETHOD Normalize() _final \
NS_IMETHOD Normalize() __VA_ARGS__ \
{ \
nsINode::Normalize(); \
return NS_OK; \
} \
NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, bool* aResult) _final \
NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, bool* aResult) __VA_ARGS__ \
{ \
*aResult = nsINode::IsSupported(aFeature, aVersion); \
return NS_OK; \
} \
NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) _final \
NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) __VA_ARGS__ \
{ \
mozilla::ErrorResult rv; \
nsINode::GetNamespaceURI(aNamespaceURI, rv); \
return rv.ErrorCode(); \
} \
NS_IMETHOD GetPrefix(nsAString& aPrefix) _final \
NS_IMETHOD GetPrefix(nsAString& aPrefix) __VA_ARGS__ \
{ \
nsINode::GetPrefix(aPrefix); \
return NS_OK; \
} \
NS_IMETHOD GetLocalName(nsAString& aLocalName) _final \
NS_IMETHOD GetLocalName(nsAString& aLocalName) __VA_ARGS__ \
{ \
nsINode::GetLocalName(aLocalName); \
return NS_OK; \
} \
using nsINode::HasAttributes; \
NS_IMETHOD HasAttributes(bool* aResult) _final \
NS_IMETHOD HasAttributes(bool* aResult) __VA_ARGS__ \
{ \
*aResult = nsINode::HasAttributes(); \
return NS_OK; \
} \
NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) _final \
NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ \
{ \
nsINode::GetBaseURI(aBaseURI); \
return NS_OK; \
} \
NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) _final \
NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) __VA_ARGS__ \
{ \
return nsINode::CompareDocumentPosition(aOther, aResult); \
} \
NS_IMETHOD GetTextContent(nsAString& aTextContent) _final \
NS_IMETHOD GetTextContent(nsAString& aTextContent) __VA_ARGS__ \
{ \
nsINode::GetTextContent(aTextContent); \
return NS_OK; \
} \
NS_IMETHOD SetTextContent(const nsAString& aTextContent) _final \
NS_IMETHOD SetTextContent(const nsAString& aTextContent) __VA_ARGS__ \
{ \
mozilla::ErrorResult rv; \
nsINode::SetTextContent(aTextContent, rv); \
return rv.ErrorCode(); \
} \
NS_IMETHOD LookupPrefix(const nsAString& aNamespaceURI, nsAString& aResult) _final \
NS_IMETHOD LookupPrefix(const nsAString& aNamespaceURI, nsAString& aResult) __VA_ARGS__ \
{ \
nsINode::LookupPrefix(aNamespaceURI, aResult); \
return NS_OK; \
} \
NS_IMETHOD IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult) _final \
NS_IMETHOD IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult) __VA_ARGS__ \
{ \
*aResult = nsINode::IsDefaultNamespace(aNamespaceURI); \
return NS_OK; \
} \
NS_IMETHOD LookupNamespaceURI(const nsAString& aPrefix, nsAString& aResult) _final \
NS_IMETHOD LookupNamespaceURI(const nsAString& aPrefix, nsAString& aResult) __VA_ARGS__ \
{ \
nsINode::LookupNamespaceURI(aPrefix, aResult); \
return NS_OK; \
} \
NS_IMETHOD IsEqualNode(nsIDOMNode* aArg, bool* aResult) _final \
NS_IMETHOD IsEqualNode(nsIDOMNode* aArg, bool* aResult) __VA_ARGS__ \
{ \
return nsINode::IsEqualNode(aArg, aResult); \
} \
NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIDOMUserDataHandler* aHandler, nsIVariant** aResult) _final \
NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIDOMUserDataHandler* aHandler, nsIVariant** aResult) __VA_ARGS__ \
{ \
return nsINode::SetUserData(aKey, aData, aHandler, aResult); \
} \
NS_IMETHOD GetUserData(const nsAString& aKey, nsIVariant** aResult) _final \
NS_IMETHOD GetUserData(const nsAString& aKey, nsIVariant** aResult) __VA_ARGS__ \
{ \
return nsINode::GetUserData(aKey, aResult); \
} \
NS_IMETHOD Contains(nsIDOMNode* aOther, bool* aResult) _final \
NS_IMETHOD Contains(nsIDOMNode* aOther, bool* aResult) __VA_ARGS__ \
{ \
return nsINode::Contains(aOther, aResult); \
}

View File

@ -125,7 +125,8 @@ protected:
}
// Start at 1 or we'll loop forever.
CheckedUint32 bufferLen = NS_MAX<uint32_t>(mDataBufferLen, 1);
CheckedUint32 bufferLen =
NS_MAX<uint32_t>(static_cast<uint32_t>(mDataBufferLen), 1);
while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize)
bufferLen *= 2;

View File

@ -615,8 +615,7 @@ nsDOMMemoryFile::DataOwner::sDataOwners;
/* static */ bool
nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerSizeOf,
"memory-file-data");
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf)
class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
: public nsIMemoryMultiReporter
@ -651,7 +650,7 @@ class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
for (DataOwner *owner = DataOwner::sDataOwners->getFirst();
owner; owner = owner->getNext()) {
size_t size = DOMMemoryFileDataOwnerSizeOf(owner->mData);
size_t size = DOMMemoryFileDataOwnerMallocSizeOf(owner->mData);
if (size < LARGE_OBJECT_MIN_SIZE) {
smallObjectsTotal += size;

View File

@ -8676,10 +8676,21 @@ nsDocument::CreateTouchList(nsIVariant* aPoints,
}
already_AddRefed<nsIDOMTouchList>
nsIDocument::CreateTouchList(nsIDOMTouch* aTouch)
nsIDocument::CreateTouchList()
{
nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList();
return retval.forget();
}
already_AddRefed<nsIDOMTouchList>
nsIDocument::CreateTouchList(nsIDOMTouch* aTouch,
const Sequence<nsRefPtr<nsIDOMTouch> >& aTouches)
{
nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList();
retval->Append(aTouch);
for (uint32_t i = 0; i < aTouches.Length(); ++i) {
retval->Append(aTouches[i]);
}
return retval.forget();
}

View File

@ -2014,6 +2014,16 @@ GK_ATOM(Clear, "Clear")
GK_ATOM(VolumeUp, "VolumeUp")
GK_ATOM(VolumeDown, "VolumeDown")
GK_ATOM(Menu, "Menu")
GK_ATOM(New, "New")
GK_ATOM(Open, "Open")
GK_ATOM(Close, "Close")
GK_ATOM(Save, "Save")
GK_ATOM(Find, "Find")
GK_ATOM(Help, "Help")
GK_ATOM(Print, "Print")
GK_ATOM(SendMail, "SendMail")
GK_ATOM(ForwardMail, "ForwardMail")
GK_ATOM(ReplyToMail, "ReplyToMail")
// Smooth scroll events origins
GK_ATOM(mouseWheel, "mouseWheel") // For discrete wheel events (e.g. not OSX magic mouse)

View File

@ -698,6 +698,7 @@ nsINode::SetUserData(JSContext* aCx, const nsAString& aKey, JS::Value aData,
}
JS::Value result;
JSAutoCompartment ac(aCx, GetWrapper());
aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), oldData,
&result);
return result;
@ -712,6 +713,7 @@ nsINode::GetUserData(JSContext* aCx, const nsAString& aKey, ErrorResult& aError)
}
JS::Value result;
JSAutoCompartment ac(aCx, GetWrapper());
aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), data,
&result);
return result;

View File

@ -142,8 +142,6 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest,
"Unknown request");
}
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
LOOP_OVER_OBSERVERS(Notify(aRequest, aType, aData));
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {

View File

@ -8,13 +8,14 @@ topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
FAIL_ON_WARNINGS = 1
include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkconcvs_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS = 1
endif # !_MSC_VER
EXPORTS_NAMESPACES = mozilla/dom

View File

@ -140,7 +140,7 @@ WebGLMemoryMultiReporterWrapper::~WebGLMemoryMultiReporterWrapper()
NS_UnregisterMemoryMultiReporter(mReporter);
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOfFun, "webgl-buffer")
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf)
int64_t
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
@ -152,13 +152,13 @@ WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
buffer = buffer->getNext())
{
if (buffer->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
result += buffer->SizeOfIncludingThis(WebGLBufferMallocSizeOfFun);
result += buffer->SizeOfIncludingThis(WebGLBufferMallocSizeOf);
}
}
return result;
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOfFun, "webgl-shader")
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf)
int64_t
WebGLMemoryMultiReporterWrapper::GetShaderSize() {
@ -169,7 +169,7 @@ WebGLMemoryMultiReporterWrapper::GetShaderSize() {
shader;
shader = shader->getNext())
{
result += shader->SizeOfIncludingThis(WebGLShaderMallocSizeOfFun);
result += shader->SizeOfIncludingThis(WebGLShaderMallocSizeOf);
}
}
return result;

View File

@ -13,7 +13,9 @@ include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkconevents_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS = 1
endif # !_MSC_VER
EXPORTS = \
nsEventStateManager.h \

View File

@ -0,0 +1,155 @@
/* -*- 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 "mozilla/dom/HTMLTitleElement.h"
#include "mozilla/dom/HTMLTitleElementBinding.h"
#include "mozilla/ErrorResult.h"
#include "nsStyleConsts.h"
#include "nsIDocument.h"
#include "nsContentUtils.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(Title)
namespace mozilla {
namespace dom {
HTMLTitleElement::HTMLTitleElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
{
SetIsDOMBinding();
AddMutationObserver(this);
}
HTMLTitleElement::~HTMLTitleElement()
{
}
NS_IMPL_ADDREF_INHERITED(HTMLTitleElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLTitleElement, Element)
} // namespace dom
} // namespace mozilla
DOMCI_NODE_DATA(HTMLTitleElement, mozilla::dom::HTMLTitleElement)
namespace mozilla {
namespace dom {
// QueryInterface implementation for HTMLTitleElement
NS_INTERFACE_TABLE_HEAD(HTMLTitleElement)
NS_HTML_CONTENT_INTERFACE_TABLE2(HTMLTitleElement,
nsIDOMHTMLTitleElement,
nsIMutationObserver)
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLTitleElement,
nsGenericHTMLElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTitleElement)
NS_IMPL_ELEMENT_CLONE(HTMLTitleElement)
JSObject*
HTMLTitleElement::WrapNode(JSContext* cx, JSObject* scope, bool* triedToWrap)
{
return HTMLTitleElementBinding::Wrap(cx, scope, this, triedToWrap);
}
NS_IMETHODIMP
HTMLTitleElement::GetText(nsAString& aTitle)
{
nsContentUtils::GetNodeTextContent(this, false, aTitle);
return NS_OK;
}
NS_IMETHODIMP
HTMLTitleElement::SetText(const nsAString& aTitle)
{
return nsContentUtils::SetNodeTextContent(this, aTitle, true);
}
void
HTMLTitleElement::CharacterDataChanged(nsIDocument *aDocument,
nsIContent *aContent,
CharacterDataChangeInfo *aInfo)
{
SendTitleChangeEvent(false);
}
void
HTMLTitleElement::ContentAppended(nsIDocument *aDocument,
nsIContent *aContainer,
nsIContent *aFirstNewContent,
int32_t aNewIndexInContainer)
{
SendTitleChangeEvent(false);
}
void
HTMLTitleElement::ContentInserted(nsIDocument *aDocument,
nsIContent *aContainer,
nsIContent *aChild,
int32_t aIndexInContainer)
{
SendTitleChangeEvent(false);
}
void
HTMLTitleElement::ContentRemoved(nsIDocument *aDocument,
nsIContent *aContainer,
nsIContent *aChild,
int32_t aIndexInContainer,
nsIContent *aPreviousSibling)
{
SendTitleChangeEvent(false);
}
nsresult
HTMLTitleElement::BindToTree(nsIDocument *aDocument,
nsIContent *aParent,
nsIContent *aBindingParent,
bool aCompileEventHandlers)
{
// Let this fall through.
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
SendTitleChangeEvent(true);
return NS_OK;
}
void
HTMLTitleElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
SendTitleChangeEvent(false);
// Let this fall through.
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
void
HTMLTitleElement::DoneAddingChildren(bool aHaveNotified)
{
if (!aHaveNotified) {
SendTitleChangeEvent(false);
}
}
void
HTMLTitleElement::SendTitleChangeEvent(bool aBound)
{
nsIDocument* doc = GetCurrentDoc();
if (doc) {
doc->NotifyPossibleTitleChange(aBound);
}
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,85 @@
/* -*- 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/. */
#ifndef mozilla_dom_HTMLTITLEElement_h_
#define mozilla_dom_HTMLTITLEElement_h_
#include "mozilla/Attributes.h"
#include "nsIDOMHTMLTitleElement.h"
#include "nsGenericHTMLElement.h"
#include "nsStubMutationObserver.h"
namespace mozilla {
class ErrorResult;
namespace dom {
class HTMLTitleElement : public nsGenericHTMLElement,
public nsIDOMHTMLTitleElement,
public nsStubMutationObserver
{
public:
using Element::GetText;
using Element::SetText;
HTMLTitleElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~HTMLTitleElement();
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMNode
NS_FORWARD_NSIDOMNODE_TO_NSINODE
// nsIDOMElement
NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
// nsIDOMHTMLElement
NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
// nsIDOMHTMLTitleElement
NS_DECL_NSIDOMHTMLTITLEELEMENT
//HTMLTitleElement
//The xpcom GetTextContent() never fails so we just use that.
void SetText(const nsAString& aText, ErrorResult& aError)
{
aError = SetText(aText);
}
// nsIMutationObserver
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
nsIContent *aBindingParent,
bool aCompileEventHandlers);
virtual void UnbindFromTree(bool aDeep = true,
bool aNullParent = true);
virtual void DoneAddingChildren(bool aHaveNotified);
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
protected:
virtual JSObject* WrapNode(JSContext* cx, JSObject* scope, bool* triedToWrap)
MOZ_OVERRIDE MOZ_FINAL;
private:
void SendTitleChangeEvent(bool aBound);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_HTMLTitleElement_h_

View File

@ -13,7 +13,9 @@ include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkconhtmlcon_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS = 1
endif # !_MSC_VER
EXPORTS = \
@ -35,6 +37,7 @@ EXPORTS_mozilla/dom = \
HTMLFrameSetElement.h \
HTMLHeadingElement.h \
HTMLLabelElement.h \
HTMLTitleElement.h \
HTMLUnknownElement.h
CPPSRCS = \
@ -95,7 +98,7 @@ CPPSRCS = \
nsHTMLTableRowElement.cpp \
nsHTMLTableSectionElement.cpp \
nsHTMLTextAreaElement.cpp \
nsHTMLTitleElement.cpp \
HTMLTitleElement.cpp \
HTMLUnknownElement.cpp \
nsDOMValidityState.cpp \
nsIConstraintValidation.cpp \

View File

@ -1,189 +0,0 @@
/* -*- 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 "nsIDOMHTMLTitleElement.h"
#include "nsIDOMEventTarget.h"
#include "nsGenericHTMLElement.h"
#include "nsStyleConsts.h"
#include "nsIDocument.h"
#include "nsContentUtils.h"
#include "nsStubMutationObserver.h"
using namespace mozilla::dom;
class nsHTMLTitleElement : public nsGenericHTMLElement,
public nsIDOMHTMLTitleElement,
public nsStubMutationObserver
{
public:
using Element::GetText;
using Element::SetText;
nsHTMLTitleElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~nsHTMLTitleElement();
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMNode
NS_FORWARD_NSIDOMNODE_TO_NSINODE
// nsIDOMElement
NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
// nsIDOMHTMLElement
NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC
// nsIDOMHTMLTitleElement
NS_DECL_NSIDOMHTMLTITLEELEMENT
// nsIMutationObserver
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
nsIContent *aBindingParent,
bool aCompileEventHandlers);
virtual void UnbindFromTree(bool aDeep = true,
bool aNullParent = true);
virtual void DoneAddingChildren(bool aHaveNotified);
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
private:
void SendTitleChangeEvent(bool aBound);
};
NS_IMPL_NS_NEW_HTML_ELEMENT(Title)
nsHTMLTitleElement::nsHTMLTitleElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
{
AddMutationObserver(this);
}
nsHTMLTitleElement::~nsHTMLTitleElement()
{
}
NS_IMPL_ADDREF_INHERITED(nsHTMLTitleElement, Element)
NS_IMPL_RELEASE_INHERITED(nsHTMLTitleElement, Element)
DOMCI_NODE_DATA(HTMLTitleElement, nsHTMLTitleElement)
// QueryInterface implementation for nsHTMLTitleElement
NS_INTERFACE_TABLE_HEAD(nsHTMLTitleElement)
NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLTitleElement,
nsIDOMHTMLTitleElement,
nsIMutationObserver)
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLTitleElement,
nsGenericHTMLElement)
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLTitleElement)
NS_IMPL_ELEMENT_CLONE(nsHTMLTitleElement)
NS_IMETHODIMP
nsHTMLTitleElement::GetText(nsAString& aTitle)
{
nsContentUtils::GetNodeTextContent(this, false, aTitle);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTitleElement::SetText(const nsAString& aTitle)
{
return nsContentUtils::SetNodeTextContent(this, aTitle, true);
}
void
nsHTMLTitleElement::CharacterDataChanged(nsIDocument *aDocument,
nsIContent *aContent,
CharacterDataChangeInfo *aInfo)
{
SendTitleChangeEvent(false);
}
void
nsHTMLTitleElement::ContentAppended(nsIDocument *aDocument,
nsIContent *aContainer,
nsIContent *aFirstNewContent,
int32_t aNewIndexInContainer)
{
SendTitleChangeEvent(false);
}
void
nsHTMLTitleElement::ContentInserted(nsIDocument *aDocument,
nsIContent *aContainer,
nsIContent *aChild,
int32_t aIndexInContainer)
{
SendTitleChangeEvent(false);
}
void
nsHTMLTitleElement::ContentRemoved(nsIDocument *aDocument,
nsIContent *aContainer,
nsIContent *aChild,
int32_t aIndexInContainer,
nsIContent *aPreviousSibling)
{
SendTitleChangeEvent(false);
}
nsresult
nsHTMLTitleElement::BindToTree(nsIDocument *aDocument,
nsIContent *aParent,
nsIContent *aBindingParent,
bool aCompileEventHandlers)
{
// Let this fall through.
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
SendTitleChangeEvent(true);
return NS_OK;
}
void
nsHTMLTitleElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
SendTitleChangeEvent(false);
// Let this fall through.
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
void
nsHTMLTitleElement::DoneAddingChildren(bool aHaveNotified)
{
if (!aHaveNotified) {
SendTitleChangeEvent(false);
}
}
void
nsHTMLTitleElement::SendTitleChangeEvent(bool aBound)
{
nsIDocument* doc = GetCurrentDoc();
if (doc) {
doc->NotifyPossibleTitleChange(aBound);
}
}

View File

@ -13,7 +13,9 @@ include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkconhtmldoc_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS = 1
endif # !_MSC_VER
CPPSRCS = \
nsHTMLContentSink.cpp \

View File

@ -13,7 +13,9 @@ include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkcontentmathml_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS = 1
endif # !_MSC_VER
CPPSRCS = \
nsMathMLElement.cpp \

View File

@ -6,13 +6,15 @@ DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkconmedia_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
EXPORTS = \
AbstractMediaDecoder.h \

View File

@ -228,6 +228,12 @@ static inline bool IsCurrentThread(nsIThread* aThread) {
return NS_GetCurrentThread() == aThread;
}
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
// GetTickCount() and conflicts with MediaDecoder::GetCurrentTime implementation.
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
class MediaDecoder : public nsIObserver,
public AbstractMediaDecoder
{

View File

@ -215,6 +215,7 @@ protected:
void AppendFromInternal(MediaSegmentBase<C, Chunk>* aSource)
{
static_cast<C*>(this)->CheckCompatible(*static_cast<C*>(aSource));
MOZ_ASSERT(aSource->mDuration >= 0);
mDuration += aSource->mDuration;
aSource->mDuration = 0;
if (!mChunks.IsEmpty() && !aSource->mChunks.IsEmpty() &&
@ -248,6 +249,7 @@ protected:
Chunk* AppendChunk(TrackTicks aDuration)
{
MOZ_ASSERT(aDuration >= 0);
Chunk* c = mChunks.AppendElement();
c->mDuration = aDuration;
mDuration += aDuration;

View File

@ -802,21 +802,19 @@ MediaStreamGraphImpl::UpdateCurrentTime()
// Calculate blocked time and fire Blocked/Unblocked events
GraphTime blockedTime = 0;
GraphTime t = prevCurrentTime;
// Save current blocked status
bool wasBlocked = stream->mBlocked.GetAt(prevCurrentTime);
while (t < nextCurrentTime) {
GraphTime end;
bool blocked = stream->mBlocked.GetAt(t, &end);
if (blocked) {
blockedTime += NS_MIN(end, nextCurrentTime) - t;
}
if (blocked != wasBlocked) {
if (blocked != stream->mNotifiedBlocked) {
for (uint32_t j = 0; j < stream->mListeners.Length(); ++j) {
MediaStreamListener* l = stream->mListeners[j];
l->NotifyBlockingChanged(this,
blocked ? MediaStreamListener::BLOCKED : MediaStreamListener::UNBLOCKED);
}
wasBlocked = blocked;
stream->mNotifiedBlocked = blocked;
}
t = end;
}
@ -1941,7 +1939,7 @@ MediaStream::AddListenerImpl(already_AddRefed<MediaStreamListener> aListener)
{
MediaStreamListener* listener = *mListeners.AppendElement() = aListener;
listener->NotifyBlockingChanged(GraphImpl(),
mBlocked.GetAt(GraphImpl()->mCurrentTime) ? MediaStreamListener::BLOCKED : MediaStreamListener::UNBLOCKED);
mNotifiedBlocked ? MediaStreamListener::BLOCKED : MediaStreamListener::UNBLOCKED);
if (mNotifiedFinished) {
listener->NotifyFinished(GraphImpl());
}

View File

@ -261,6 +261,7 @@ public:
, mGraphUpdateIndices(0)
, mFinished(false)
, mNotifiedFinished(false)
, mNotifiedBlocked(false)
, mWrapper(aWrapper)
, mMainThreadCurrentTime(0)
, mMainThreadFinished(false)
@ -457,6 +458,11 @@ protected:
* and fired NotifyFinished notifications.
*/
bool mNotifiedFinished;
/**
* When true, the last NotifyBlockingChanged delivered to the listeners
* indicated that the stream is blocked.
*/
bool mNotifiedBlocked;
// Temporary data for ordering streams by dependency graph
bool mHasBeenOrdered;

View File

@ -6,13 +6,15 @@ DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkconogg_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
EXPORTS += \

View File

@ -7,13 +7,15 @@ DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkconraw_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
EXPORTS += \
RawDecoder.h \

View File

@ -6,13 +6,15 @@ DEPTH := @DEPTH@
topsrcdir := @top_srcdir@
srcdir := @srcdir@
VPATH := @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
MODULE := content
LIBRARY_NAME := gkconwebaudio_s
LIBXUL_LIBRARY := 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
CPPSRCS := \
AudioBuffer.cpp \

View File

@ -7,10 +7,13 @@ topsrcdir := @top_srcdir@
srcdir := @srcdir@
VPATH := @srcdir@
relativesrcdir := @relativesrcdir@
FAIL_ON_WARNINGS = 1
include $(DEPTH)/config/autoconf.mk
ifndef _MSC_VER
FAIL_ON_WARNINGS = 1
endif # !_MSC_VER
LOCAL_INCLUDES := -I$(srcdir)/..
CPP_UNIT_TESTS := \

View File

@ -28,6 +28,12 @@ enum MediaEngineState {
kReleased
};
// We only support 1 audio and 1 video track for now.
enum {
kVideoTrack = 1,
kAudioTrack = 2
};
class MediaEngine
{
public:
@ -74,10 +80,14 @@ public:
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile) = 0;
/* Called when the stream wants more data */
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime) = 0;
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,
TrackID aId,
StreamTime aDesiredTime,
TrackTicks &aLastEndTime) = 0;
/* Stop the device and release the corresponding MediaStream */
virtual nsresult Stop() = 0;
virtual nsresult Stop(SourceMediaStream *aSource, TrackID aID) = 0;
/* Return false if device is currently allocated or started */
bool IsAvailable() {

View File

@ -168,7 +168,7 @@ MediaEngineDefaultVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
}
nsresult
MediaEngineDefaultVideoSource::Stop()
MediaEngineDefaultVideoSource::Stop(SourceMediaStream *aSource, TrackID aID)
{
if (mState != kStarted) {
return NS_ERROR_FAILURE;
@ -180,8 +180,8 @@ MediaEngineDefaultVideoSource::Stop()
mTimer->Cancel();
mTimer = NULL;
mSource->EndTrack(mTrackID);
mSource->Finish();
aSource->EndTrack(aID);
aSource->Finish();
mState = kStopped;
return NS_OK;
@ -353,7 +353,7 @@ MediaEngineDefaultAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
}
nsresult
MediaEngineDefaultAudioSource::Stop()
MediaEngineDefaultAudioSource::Stop(SourceMediaStream *aSource, TrackID aID)
{
if (mState != kStarted) {
return NS_ERROR_FAILURE;
@ -365,8 +365,8 @@ MediaEngineDefaultAudioSource::Stop()
mTimer->Cancel();
mTimer = NULL;
mSource->EndTrack(mTrackID);
mSource->Finish();
aSource->EndTrack(aID);
aSource->Finish();
mState = kStopped;
return NS_OK;

View File

@ -42,9 +42,14 @@ public:
virtual nsresult Allocate();
virtual nsresult Deallocate();
virtual nsresult Start(SourceMediaStream*, TrackID);
virtual nsresult Stop();
virtual nsresult Stop(SourceMediaStream*, TrackID);
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,
TrackID aId,
StreamTime aDesiredTime,
TrackTicks &aLastEndTime) {}
NS_DECL_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
@ -79,9 +84,14 @@ public:
virtual nsresult Allocate();
virtual nsresult Deallocate();
virtual nsresult Start(SourceMediaStream*, TrackID);
virtual nsresult Stop();
virtual nsresult Stop(SourceMediaStream*, TrackID);
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,
TrackID aId,
StreamTime aDesiredTime,
TrackTicks &aLastEndTime) {}
NS_DECL_ISUPPORTS
NS_DECL_NSITIMERCALLBACK

View File

@ -88,9 +88,13 @@ public:
virtual nsresult Allocate();
virtual nsresult Deallocate();
virtual nsresult Start(SourceMediaStream*, TrackID);
virtual nsresult Stop();
virtual nsresult Stop(SourceMediaStream*, TrackID);
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,
TrackID aId,
StreamTime aDesiredTime,
TrackTicks &aLastEndTime);
NS_DECL_ISUPPORTS
@ -136,7 +140,7 @@ private:
TrackTicks mLastEndTime;
mozilla::ReentrantMonitor mMonitor; // Monitor for processing WebRTC frames.
SourceMediaStream* mSource;
nsTArray<SourceMediaStream *> mSources; // When this goes empty, we shut down HW
int mFps; // Track rate (30 fps by default)
int mMinFps; // Min rate we want to accept
@ -184,9 +188,13 @@ public:
virtual nsresult Allocate();
virtual nsresult Deallocate();
virtual nsresult Start(SourceMediaStream*, TrackID);
virtual nsresult Stop();
virtual nsresult Stop(SourceMediaStream*, TrackID);
virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile);
virtual void NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime);
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream *aSource,
TrackID aId,
StreamTime aDesiredTime,
TrackTicks &aLastEndTime);
// VoEMediaProcess.
void Process(const int channel, const webrtc::ProcessingTypes type,
@ -208,6 +216,7 @@ private:
webrtc::VoENetwork* mVoENetwork;
mozilla::ReentrantMonitor mMonitor;
nsTArray<SourceMediaStream *> mSources; // When this goes empty, we shut down HW
int mCapIndex;
int mChannel;
@ -217,7 +226,6 @@ private:
nsString mDeviceName;
nsString mDeviceUUID;
SourceMediaStream* mSource;
NullTransport *mNullTransport;
};

View File

@ -49,52 +49,60 @@ MediaEngineWebRTCAudioSource::GetUUID(nsAString& aUUID)
nsresult
MediaEngineWebRTCAudioSource::Allocate()
{
if (mState != kReleased) {
return NS_ERROR_FAILURE;
if (mState == kReleased && mInitDone) {
webrtc::VoEHardware* ptrVoEHw = webrtc::VoEHardware::GetInterface(mVoiceEngine);
int res = ptrVoEHw->SetRecordingDevice(mCapIndex);
ptrVoEHw->Release();
if (res) {
return NS_ERROR_FAILURE;
}
mState = kAllocated;
LOG(("Audio device %d allocated", mCapIndex));
} else if (mSources.IsEmpty()) {
LOG(("Audio device %d reallocated", mCapIndex));
} else {
LOG(("Audio device %d allocated shared", mCapIndex));
}
webrtc::VoEHardware* ptrVoEHw = webrtc::VoEHardware::GetInterface(mVoiceEngine);
int res = ptrVoEHw->SetRecordingDevice(mCapIndex);
ptrVoEHw->Release();
if (res) {
return NS_ERROR_FAILURE;
}
LOG(("Audio device %d allocated", mCapIndex));
mState = kAllocated;
return NS_OK;
}
nsresult
MediaEngineWebRTCAudioSource::Deallocate()
{
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}
if (mSources.IsEmpty()) {
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}
mState = kReleased;
mState = kReleased;
LOG(("Audio device %d deallocated", mCapIndex));
} else {
LOG(("Audio device %d deallocated but still in use", mCapIndex));
}
return NS_OK;
}
nsresult
MediaEngineWebRTCAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
{
if (!mInitDone || mState != kAllocated) {
return NS_ERROR_FAILURE;
}
if (!aStream) {
if (!mInitDone || !aStream) {
return NS_ERROR_FAILURE;
}
mSource = aStream;
mSources.AppendElement(aStream);
AudioSegment* segment = new AudioSegment();
segment->Init(CHANNELS);
mSource->AddTrack(aID, SAMPLE_FREQUENCY, 0, segment);
mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
aStream->AddTrack(aID, SAMPLE_FREQUENCY, 0, segment);
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
LOG(("Initial audio"));
mTrackID = aID;
if (mState == kStarted) {
return NS_OK;
}
mState = kStarted;
if (mVoEBase->StartReceive(mChannel)) {
return NS_ERROR_FAILURE;
}
@ -105,13 +113,19 @@ MediaEngineWebRTCAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
// Attach external media processor, so this::Process will be called.
mVoERender->RegisterExternalMediaProcessing(mChannel, webrtc::kRecordingPerChannel, *this);
mState = kStarted;
return NS_OK;
}
nsresult
MediaEngineWebRTCAudioSource::Stop()
MediaEngineWebRTCAudioSource::Stop(SourceMediaStream *aSource, TrackID aID)
{
if (!mSources.RemoveElement(aSource)) {
// Already stopped - this is allowed
return NS_OK;
}
if (!mSources.IsEmpty()) {
return NS_OK;
}
if (mState != kStarted) {
return NS_ERROR_FAILURE;
}
@ -119,6 +133,12 @@ MediaEngineWebRTCAudioSource::Stop()
return NS_ERROR_FAILURE;
}
{
ReentrantMonitorAutoEnter enter(mMonitor);
mState = kStopped;
aSource->EndTrack(aID);
}
mVoERender->DeRegisterExternalMediaProcessing(mChannel, webrtc::kRecordingPerChannel);
if (mVoEBase->StopSend(mChannel)) {
@ -127,27 +147,22 @@ MediaEngineWebRTCAudioSource::Stop()
if (mVoEBase->StopReceive(mChannel)) {
return NS_ERROR_FAILURE;
}
{
ReentrantMonitorAutoEnter enter(mMonitor);
mState = kStopped;
mSource->EndTrack(mTrackID);
}
return NS_OK;
}
void
MediaEngineWebRTCAudioSource::NotifyPull(MediaStreamGraph* aGraph,
StreamTime aDesiredTime)
SourceMediaStream *aSource,
TrackID aID,
StreamTime aDesiredTime,
TrackTicks &aLastEndTime)
{
// Ignore - we push audio data
#ifdef DEBUG
static TrackTicks mLastEndTime = 0;
TrackTicks target = TimeToTicksRoundUp(SAMPLE_FREQUENCY, aDesiredTime);
TrackTicks delta = target - mLastEndTime;
LOG(("Audio:NotifyPull: target %lu, delta %lu",(uint32_t) target, (uint32_t) delta));
mLastEndTime = target;
TrackTicks delta = target - aLastEndTime;
LOG(("Audio: NotifyPull: aDesiredTime %ld, target %ld, delta %ld",(int64_t) aDesiredTime, (int64_t) target, (int64_t) delta));
aLastEndTime = target;
#endif
}
@ -235,10 +250,13 @@ MediaEngineWebRTCAudioSource::Shutdown()
}
if (mState == kStarted) {
Stop();
while (!mSources.IsEmpty()) {
Stop(mSources[0], kAudioTrack); // XXX change to support multiple tracks
}
MOZ_ASSERT(mState == kStopped);
}
if (mState == kAllocated) {
if (mState == kAllocated || mState == kStopped) {
Deallocate();
}
@ -269,17 +287,22 @@ MediaEngineWebRTCAudioSource::Process(const int channel,
if (mState != kStarted)
return;
nsRefPtr<SharedBuffer> buffer = SharedBuffer::Create(length * sizeof(sample));
uint32_t len = mSources.Length();
for (uint32_t i = 0; i < len; i++) {
nsRefPtr<SharedBuffer> buffer = SharedBuffer::Create(length * sizeof(sample));
sample* dest = static_cast<sample*>(buffer->Data());
memcpy(dest, audio10ms, length * sizeof(sample));
sample* dest = static_cast<sample*>(buffer->Data());
memcpy(dest, audio10ms, length * sizeof(sample));
AudioSegment segment;
segment.Init(CHANNELS);
segment.AppendFrames(
buffer.forget(), length, 0, length, AUDIO_FORMAT_S16
);
mSource->AppendToTrack(mTrackID, &segment);
AudioSegment segment;
segment.Init(CHANNELS);
segment.AppendFrames(buffer.forget(), length, 0, length, AUDIO_FORMAT_S16);
SourceMediaStream *source = mSources[i];
if (source) {
source->AppendToTrack(mTrackID, &segment);
}
}
return;
}

View File

@ -12,8 +12,10 @@ namespace mozilla {
#ifdef PR_LOGGING
extern PRLogModuleInfo* GetMediaManagerLog();
#define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
#define LOGFRAME(msg) PR_LOG(GetMediaManagerLog(), 6, msg)
#else
#define LOG(msg)
#define LOGFRAME(msg)
#endif
/**
@ -77,9 +79,9 @@ MediaEngineWebRTCVideoSource::DeliverFrame(
videoImage->SetData(data);
#ifdef LOG_ALL_FRAMES
#ifdef DEBUG
static uint32_t frame_num = 0;
LOG(("frame %d; timestamp %u, render_time %lu", frame_num++, time_stamp, render_time));
LOGFRAME(("frame %d; timestamp %u, render_time %lu", frame_num++, time_stamp, render_time));
#endif
// we don't touch anything in 'this' until here (except for snapshot,
@ -97,7 +99,10 @@ MediaEngineWebRTCVideoSource::DeliverFrame(
// this means that no *real* frame can be inserted during this period.
void
MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph,
StreamTime aDesiredTime)
SourceMediaStream *aSource,
TrackID aID,
StreamTime aDesiredTime,
TrackTicks &aLastEndTime)
{
VideoSegment segment;
@ -108,14 +113,17 @@ MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph,
// Note: we're not giving up mImage here
nsRefPtr<layers::Image> image = mImage;
TrackTicks target = TimeToTicksRoundUp(USECS_PER_S, aDesiredTime);
TrackTicks delta = target - mLastEndTime;
#ifdef LOG_ALL_FRAMES
LOG(("NotifyPull, target = %lu, delta = %lu", (uint64_t) target, (uint64_t) delta));
#endif
// NULL images are allowed
segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight));
mSource->AppendToTrack(mTrackID, &(segment));
mLastEndTime = target;
TrackTicks delta = target - aLastEndTime;
LOGFRAME(("NotifyPull, desired = %ld, target = %ld, delta = %ld %s", (int64_t) aDesiredTime,
(int64_t) target, (int64_t) delta, image ? "" : "<null>"));
// Don't append if we've already provided a frame that supposedly goes past the current aDesiredTime
// Doing so means a negative delta and thus messes up handling of the graph
if (delta > 0) {
// NULL images are allowed
segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight));
aSource->AppendToTrack(aID, &(segment));
aLastEndTime = target;
}
}
void
@ -189,32 +197,42 @@ MediaEngineWebRTCVideoSource::GetUUID(nsAString& aUUID)
nsresult
MediaEngineWebRTCVideoSource::Allocate()
{
if (mState != kReleased) {
return NS_ERROR_FAILURE;
}
LOG((__FUNCTION__));
if (!mCapabilityChosen) {
// XXX these should come from constraints
ChooseCapability(mWidth, mHeight, mMinFps);
}
if (mViECapture->AllocateCaptureDevice(mUniqueId, KMaxUniqueIdLength, mCaptureIndex)) {
return NS_ERROR_FAILURE;
if (mState == kReleased && mInitDone) {
if (mViECapture->AllocateCaptureDevice(mUniqueId, KMaxUniqueIdLength, mCaptureIndex)) {
return NS_ERROR_FAILURE;
}
mState = kAllocated;
LOG(("Video device %d allocated", mCaptureIndex));
} else if (mSources.IsEmpty()) {
LOG(("Video device %d reallocated", mCaptureIndex));
} else {
LOG(("Video device %d allocated shared", mCaptureIndex));
}
mState = kAllocated;
return NS_OK;
}
nsresult
MediaEngineWebRTCVideoSource::Deallocate()
{
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}
LOG((__FUNCTION__));
if (mSources.IsEmpty()) {
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}
mViECapture->ReleaseCaptureDevice(mCaptureIndex);
mState = kReleased;
mViECapture->ReleaseCaptureDevice(mCaptureIndex);
mState = kReleased;
LOG(("Video device %d deallocated", mCaptureIndex));
} else {
LOG(("Video device %d deallocated but still in use", mCaptureIndex));
}
return NS_OK;
}
@ -230,29 +248,24 @@ MediaEngineWebRTCVideoSource::GetOptions()
nsresult
MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
{
LOG((__FUNCTION__));
int error = 0;
if (!mInitDone || mState != kAllocated) {
if (!mInitDone || !aStream) {
return NS_ERROR_FAILURE;
}
if (!aStream) {
return NS_ERROR_FAILURE;
}
mSources.AppendElement(aStream);
aStream->AddTrack(aID, USECS_PER_S, 0, new VideoSegment());
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
if (mState == kStarted) {
return NS_OK;
}
mSource = aStream;
mTrackID = aID;
mState = kStarted;
mImageContainer = layers::LayerManager::CreateImageContainer();
mSource->AddTrack(aID, USECS_PER_S, 0, new VideoSegment());
mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
mLastEndTime = 0;
mState = kStarted;
error = mViERender->AddRenderer(mCaptureIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
if (error == -1) {
return NS_ERROR_FAILURE;
@ -271,8 +284,17 @@ MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
}
nsresult
MediaEngineWebRTCVideoSource::Stop()
MediaEngineWebRTCVideoSource::Stop(SourceMediaStream *aSource, TrackID aID)
{
LOG((__FUNCTION__));
if (!mSources.RemoveElement(aSource)) {
// Already stopped - this is allowed
return NS_OK;
}
if (!mSources.IsEmpty()) {
return NS_OK;
}
if (mState != kStarted) {
return NS_ERROR_FAILURE;
}
@ -280,7 +302,10 @@ MediaEngineWebRTCVideoSource::Stop()
{
ReentrantMonitorAutoEnter enter(mMonitor);
mState = kStopped;
mSource->EndTrack(mTrackID);
aSource->EndTrack(aID);
// Drop any cached image so we don't start with a stale image on next
// usage
mImage = nullptr;
}
mViERender->StopRender(mCaptureIndex);
@ -394,6 +419,7 @@ MediaEngineWebRTCVideoSource::Init()
mDeviceName[0] = '\0'; // paranoia
mUniqueId[0] = '\0';
LOG((__FUNCTION__));
if (mVideoEngine == NULL) {
return;
}
@ -423,22 +449,20 @@ MediaEngineWebRTCVideoSource::Init()
void
MediaEngineWebRTCVideoSource::Shutdown()
{
bool continueShutdown = false;
LOG((__FUNCTION__));
if (!mInitDone) {
return;
}
if (mState == kStarted) {
mViERender->StopRender(mCaptureIndex);
mViERender->RemoveRenderer(mCaptureIndex);
continueShutdown = true;
while (!mSources.IsEmpty()) {
Stop(mSources[0], kVideoTrack); // XXX change to support multiple tracks
}
MOZ_ASSERT(mState == kStopped);
}
if (mState == kAllocated || continueShutdown) {
mViECapture->StopCapture(mCaptureIndex);
mViECapture->ReleaseCaptureDevice(mCaptureIndex);
continueShutdown = false;
if (mState == kAllocated || mState == kStopped) {
Deallocate();
}
mViECapture->Release();

View File

@ -29,8 +29,6 @@ which makes Windows Media Foundation unavailable.
#include <propvarutil.h>
#include <wmcodecdsp.h>
#pragma comment(lib,"uuid.lib")
#pragma comment(lib,"mfuuid.lib")
namespace mozilla {
namespace wmf {

View File

@ -13,7 +13,9 @@ include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkconsmil_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS = 1
endif # !_MSC_VER
EXPORTS = \
nsISMILAnimationElement.h \

View File

@ -13,7 +13,9 @@ include $(DEPTH)/config/autoconf.mk
MODULE = content
LIBRARY_NAME = gkcontentsvg_s
LIBXUL_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS = 1
endif # !_MSC_VER
CPPSRCS = \
DOMSVGAnimatedLengthList.cpp \

View File

@ -1759,7 +1759,8 @@ this.DOMApplicationRegistry = {
let requestChannel = NetUtil.newChannel(aManifest.fullPackagePath())
.QueryInterface(Ci.nsIHttpChannel);
if (app.packageEtag) {
requestChannel.setRequestHeader("If-None-Match", app.packageEtag);
debug('Add If-None-Match header: ' + app.packageEtag);
requestChannel.setRequestHeader("If-None-Match", app.packageEtag, false);
}
AppDownloadManager.add(aApp.manifestURL,
@ -1834,7 +1835,17 @@ this.DOMApplicationRegistry = {
let listener = Cc["@mozilla.org/network/simple-stream-listener;1"]
.createInstance(Ci.nsISimpleStreamListener);
listener.init(bufferedOutputStream, {
onStartRequest: function(aRequest, aContext) { },
onStartRequest: function(aRequest, aContext) {
// early check for ETag header
try {
requestChannel.getResponseHeader("Etag");
} catch (e) {
// in https://bugzilla.mozilla.org/show_bug.cgi?id=825218
// we might do something cleaner to have a proper user error
debug("We found no ETag Header, canceling the request");
requestChannel.cancel(Cr.NS_BINDING_ABORTED);
}
},
onStopRequest: function(aRequest, aContext, aStatusCode) {
debug("onStopRequest " + aStatusCode);
bufferedOutputStream.close();
@ -1861,10 +1872,6 @@ this.DOMApplicationRegistry = {
return;
}
// Save the new Etag for the package.
app.packageEtag = requestChannel.getResponseHeader("Etag");
debug("Package etag=" + app.packageEtag);
if (!Components.isSuccessCode(aStatusCode)) {
cleanup("NETWORK_ERROR");
return;
@ -1931,6 +1938,17 @@ this.DOMApplicationRegistry = {
throw "INVALID_SECURITY_LEVEL";
}
aApp.appStatus = AppsUtils.getAppManifestStatus(manifest);
// Save the new Etag for the package.
try {
app.packageEtag = requestChannel.getResponseHeader("Etag");
debug("Package etag=" + app.packageEtag);
} catch (e) {
// in https://bugzilla.mozilla.org/show_bug.cgi?id=825218
// we'll fail gracefully in this case
// for now, just going on
app.packageEtag = null;
debug("Can't find an etag, this should not happen");
}
if (aOnSuccess) {
aOnSuccess(id, manifest);

View File

@ -25,7 +25,9 @@ XPIDL_MODULE = dom_audiochannel
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORT_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
EXPORTS_NAMESPACES = \
mozilla/dom \

View File

@ -7,7 +7,6 @@ DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
@ -15,6 +14,9 @@ MODULE = dom
LIBRARY_NAME = jsdombase_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
DIRS = \
test \

View File

@ -4423,7 +4423,7 @@ nsDOMClassInfo::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, uint32_t flags,
JSObject **objp, bool *_retval)
{
if (id == sConstructor_id && !(flags & JSRESOLVE_ASSIGNING)) {
if (id == sConstructor_id) {
return ResolveConstructor(cx, obj, objp);
}
@ -4907,8 +4907,8 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj,
JSHandleId id, unsigned flags,
JSMutableHandleObject objp)
{
if ((flags & JSRESOLVE_ASSIGNING) || !JSID_IS_STRING(id)) {
// Nothing to do if we're assigning or resolving a non-string property.
if (!JSID_IS_STRING(id)) {
// Nothing to do if we're resolving a non-string property.
return JS_TRUE;
}
@ -6732,13 +6732,11 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
}
if (!(flags & JSRESOLVE_ASSIGNING)) {
// We want this code to be before the child frame lookup code
// below so that a child frame named 'constructor' doesn't
// shadow the window's constructor property.
if (sConstructor_id == id) {
return ResolveConstructor(cx, obj, objp);
}
// We want this code to be before the child frame lookup code
// below so that a child frame named 'constructor' doesn't
// shadow the window's constructor property.
if (sConstructor_id == id) {
return ResolveConstructor(cx, obj, objp);
}
if (!my_context || !my_context->IsContextInitialized()) {
@ -6783,7 +6781,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
if (sTop_id == id && !(flags & JSRESOLVE_ASSIGNING)) {
if (sTop_id == id) {
nsCOMPtr<nsIDOMWindow> top;
rv = win->GetScriptableTop(getter_AddRefs(top));
NS_ENSURE_SUCCESS(rv, rv);
@ -7194,7 +7192,7 @@ nsNavigatorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, uint32_t flags,
JSObject **objp, bool *_retval)
{
if (!JSID_IS_STRING(id) || (flags & JSRESOLVE_ASSIGNING)) {
if (!JSID_IS_STRING(id)) {
return NS_OK;
}
@ -8388,12 +8386,6 @@ JSBool
nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
unsigned flags, JSMutableHandleObject objp)
{
if (flags & JSRESOLVE_ASSIGNING) {
// Nothing to do here if we're assigning
return JS_TRUE;
}
js::RootedValue v(cx);
if (sItem_id == id || sNamedItem_id == id) {

View File

@ -9827,12 +9827,6 @@ nsGlobalWindow::RescheduleTimeout(nsTimeout* aTimeout, const TimeStamp& now,
// Reschedule the OS timer. Don't bother returning any error codes if
// this fails since the callers of this method don't care about them.
// Make sure to cast the unsigned PR_USEC_PER_MSEC to signed
// PRTime to make the division do the right thing on 64-bit
// platforms whether delay is positive or negative (which we
// know is always positive here, but cast anyways for
// consistency).
nsresult rv = aTimeout->InitTimer(TimerCallback, delay.ToMilliseconds());
if (NS_FAILED(rv)) {

View File

@ -148,7 +148,8 @@ struct nsTimeout : mozilla::LinkedListElement<nsTimeout>
nsrefcnt AddRef();
nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) {
return mTimer->InitWithFuncCallback(aFunc, this, delay,
return mTimer->InitWithFuncCallback(aFunc, this,
static_cast<uint32_t>(delay),
nsITimer::TYPE_ONE_SHOT);
}

View File

@ -177,8 +177,7 @@ static nsJSContext *sContextList = nullptr;
static nsScriptNameSpaceManager *gNameSpaceManager;
static nsIMemoryReporter *gReporter;
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ScriptNameSpaceManagerMallocSizeOf,
"script-namespace-manager")
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ScriptNameSpaceManagerMallocSizeOf)
static int64_t
GetScriptNameSpaceManagerSize()
@ -3064,10 +3063,21 @@ DoMergingCC(bool aForced)
}
static void
FinishAnyIncrementalGC()
{
if (sCCLockedOut) {
// We're in the middle of an incremental GC, so finish it.
js::PrepareForIncrementalGC(nsJSRuntime::sRuntime);
js::FinishIncrementalGC(nsJSRuntime::sRuntime, js::gcreason::CC_FORCED);
}
}
static void
FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless)
{
PRTime startTime = PR_Now();
FinishAnyIncrementalGC();
nsCycleCollector_forgetSkippable(aRemoveChildless);
sPreviousSuspectedCount = nsCycleCollector_suspectedCount();
++sCleanupsSinceLastGC;
@ -3083,6 +3093,14 @@ FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless)
++sForgetSkippableBeforeCC;
}
MOZ_ALWAYS_INLINE
static uint32_t
TimeBetween(PRTime start, PRTime end)
{
MOZ_ASSERT(end >= start);
return (uint32_t)(end - start) / PR_USEC_PER_MSEC;
}
//static
void
nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
@ -3093,33 +3111,40 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
return;
}
if (sCCLockedOut) {
// We're in the middle of an incremental GC; finish it first
js::PrepareForIncrementalGC(nsJSRuntime::sRuntime);
js::FinishIncrementalGC(nsJSRuntime::sRuntime, js::gcreason::CC_FORCED);
}
SAMPLE_LABEL("GC", "CycleCollectNow");
KillCCTimer();
SAMPLE_LABEL("CC", "CycleCollectNow");
PRTime start = PR_Now();
uint32_t suspected = nsCycleCollector_suspectedCount();
// Before we begin the cycle collection, make sure there is no active GC.
bool finishedIGC = sCCLockedOut;
FinishAnyIncrementalGC();
PRTime endGCTime = PR_Now();
uint32_t gcDuration = TimeBetween(start, endGCTime);
// nsCycleCollector_forgetSkippable may mark some gray js to black.
KillCCTimer();
uint32_t suspected = nsCycleCollector_suspectedCount();
bool ranSyncForgetSkippable = false;
// Run forgetSkippable synchronously to reduce the size of the CC graph. This
// is particularly useful if we recently finished a GC.
if (sCleanupsSinceLastGC < 2 && aExtraForgetSkippableCalls >= 0) {
while (sCleanupsSinceLastGC < 2) {
FireForgetSkippable(nsCycleCollector_suspectedCount(), false);
ranSyncForgetSkippable = true;
}
}
for (int32_t i = 0; i < aExtraForgetSkippableCalls; ++i) {
FireForgetSkippable(nsCycleCollector_suspectedCount(), false);
ranSyncForgetSkippable = true;
}
bool mergingCC = DoMergingCC(aForced);
PRTime endSkippableTime = PR_Now();
uint32_t skippableDuration = TimeBetween(endGCTime, endSkippableTime);
// Prepare to actually run the CC.
bool mergingCC = DoMergingCC(aForced);
nsCycleCollectorResults ccResults;
nsCycleCollector_collect(mergingCC, &ccResults, aListener);
sCCollectedWaitingForGC += ccResults.mFreedRefCounted + ccResults.mFreedGCed;
@ -3130,13 +3155,19 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
PokeGC(js::gcreason::CC_WAITING);
}
PRTime now = PR_Now();
PRTime endCCTime = PR_Now();
// Log information about the CC via telemetry, JSON and the console.
uint32_t ccNowDuration = TimeBetween(start, endCCTime);
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FINISH_IGC, finishedIGC);
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_SYNC_SKIPPABLE, ranSyncForgetSkippable);
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FULL, ccNowDuration);
if (sLastCCEndTime) {
uint32_t timeBetween = (uint32_t)(start - sLastCCEndTime) / PR_USEC_PER_SEC;
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_TIME_BETWEEN, timeBetween);
}
sLastCCEndTime = now;
sLastCCEndTime = endCCTime;
Telemetry::Accumulate(Telemetry::FORGET_SKIPPABLE_MAX,
sMaxForgetSkippableTime / PR_USEC_PER_MSEC);
@ -3159,11 +3190,11 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
}
NS_NAMED_MULTILINE_LITERAL_STRING(kFmt,
NS_LL("CC(T+%.1f) duration: %llums, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu waiting for GC)%s\n")
NS_LL("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, removed: %lu"));
NS_LL("CC(T+%.1f) duration: %lums, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu waiting for GC)%s\n")
NS_LL("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, sync: %lu ms, removed: %lu"));
nsString msg;
msg.Adopt(nsTextFormatter::smprintf(kFmt.get(), double(delta) / PR_USEC_PER_SEC,
(now - start) / PR_USEC_PER_MSEC, suspected,
ccNowDuration, suspected,
ccResults.mVisitedRefCounted, ccResults.mVisitedGCed, mergeMsg.get(),
ccResults.mFreedRefCounted, ccResults.mFreedGCed,
sCCollectedWaitingForGC, gcMsg.get(),
@ -3173,7 +3204,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
(sTotalForgetSkippableTime / cleanups) /
PR_USEC_PER_MSEC,
sTotalForgetSkippableTime / PR_USEC_PER_MSEC,
sRemovedPurples));
skippableDuration, sRemovedPurples));
nsCOMPtr<nsIConsoleService> cs =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (cs) {
@ -3185,6 +3216,8 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
NS_NAMED_MULTILINE_LITERAL_STRING(kJSONFmt,
NS_LL("{ \"timestamp\": %llu, ")
NS_LL("\"duration\": %llu, ")
NS_LL("\"finish_gc_duration\": %llu, ")
NS_LL("\"sync_skippable_duration\": %llu, ")
NS_LL("\"suspected\": %lu, ")
NS_LL("\"visited\": { ")
NS_LL("\"RCed\": %lu, ")
@ -3203,8 +3236,9 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
NS_LL("\"removed\": %lu } ")
NS_LL("}"));
nsString json;
json.Adopt(nsTextFormatter::smprintf(kJSONFmt.get(),
now, (now - start) / PR_USEC_PER_MSEC, suspected,
json.Adopt(nsTextFormatter::smprintf(kJSONFmt.get(), endCCTime,
ccNowDuration, gcDuration, skippableDuration,
suspected,
ccResults.mVisitedRefCounted, ccResults.mVisitedGCed,
ccResults.mFreedRefCounted, ccResults.mFreedGCed,
sCCollectedWaitingForGC,
@ -3221,6 +3255,8 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
observerService->NotifyObservers(nullptr, "cycle-collection-statistics", json.get());
}
}
// Update global state to indicate we have just run a cycle collection.
sMinForgetSkippableTime = UINT32_MAX;
sMaxForgetSkippableTime = 0;
sTotalForgetSkippableTime = 0;
@ -3289,10 +3325,6 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
if (now - sCCLockedOutTime < NS_MAX_CC_LOCKEDOUT_TIME) {
return;
}
// Finish the current incremental GC
js::PrepareForIncrementalGC(nsJSRuntime::sRuntime);
js::FinishIncrementalGC(nsJSRuntime::sRuntime, js::gcreason::CC_FORCED);
}
++sCCTimerFireCount;
@ -3313,12 +3345,13 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
}
} else {
// We are in the final timer fire and still meet the conditions for
// triggering a CC.
// triggering a CC. Let CycleCollectNow finish the current IGC, if any,
// because that will allow us to include the GC time in the CC pause.
nsJSContext::CycleCollectNow(nullptr, 0, false);
}
} else if ((sPreviousSuspectedCount + 100) <= suspected) {
// Only do a forget skippable if there are more than a few new objects.
FireForgetSkippable(suspected, false);
// Only do a forget skippable if there are more than a few new objects.
FireForgetSkippable(suspected, false);
}
if (isLateTimerFire) {

View File

@ -105,7 +105,7 @@ AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
}
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMStyleMallocSizeOf, "windows")
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WindowsMallocSizeOf)
// The key is the window ID.
typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;
@ -166,7 +166,7 @@ CollectWindowReports(nsGlobalWindow *aWindow,
} \
} while (0)
nsWindowSizes windowSizes(DOMStyleMallocSizeOf);
nsWindowSizes windowSizes(WindowsMallocSizeOf);
aWindow->SizeOfIncludingThis(&windowSizes);
REPORT("/dom/other", windowSizes.mDOMOther,

View File

@ -19,6 +19,7 @@ MOCHITEST_FILES = \
test_gsp-qualified.html \
test_nondomexception.html \
test_screen_orientation.html \
test_window_constructor.html \
test_window_enumeration.html \
test_writable-replaceable.html \
$(NULL)

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=824217
-->
<head>
<meta charset="UTF-8">
<title>Test for Bug 824217</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=622491">Mozilla Bug 824217</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<iframe name="constructor" src="about:blank"></iframe>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
function run()
{
// Ideally we'd test that this property lives on the right place in the
// [[Prototype]] chain, with the right attributes there, but we don't
// implement this right yet, so just test the value's what's expected.
is(window.constructor, Window,
"should have gotten Window, not the constructor frame");
SimpleTest.finish();
}
window.addEventListener("load", run, false);
</script>
</pre>
</body>
</html>

View File

@ -368,15 +368,19 @@ DefineUnforgeableAttributes(JSContext* cx, JSObject* obj,
bool
DefineWebIDLBindingPropertiesOnXPCProto(JSContext* cx, JSObject* proto, const NativeProperties* properties);
// If *vp is an object and *vp and obj are not in the same compartment, wrap *vp
// into the compartment of obj (typically by replacing it with an Xray or
// If *vp is a gcthing and is not in the compartment of cx, wrap *vp
// into the compartment of cx (typically by replacing it with an Xray or
// cross-compartment wrapper around the original object).
inline bool
MaybeWrapValue(JSContext* cx, JSObject* obj, JS::Value* vp)
MaybeWrapValue(JSContext* cx, JS::Value* vp)
{
if (vp->isObject() &&
js::GetObjectCompartment(&vp->toObject()) != js::GetContextCompartment(cx)) {
return JS_WrapValue(cx, vp);
if (vp->isGCThing()) {
void* gcthing = vp->toGCThing();
// Might be null if vp.isNull() :(
if (gcthing &&
js::GetGCThingCompartment(gcthing) != js::GetContextCompartment(cx)) {
return JS_WrapValue(cx, vp);
}
}
return true;

View File

@ -297,6 +297,10 @@ DOMInterfaces = {
'resultNotAddRefed': [ 'gain' ],
}],
'HTMLBodyElement': {
'hasInstanceInterface': 'nsIDOMHTMLBodyElement',
},
'HTMLCollection': {
'nativeType': 'nsIHTMLCollection',
'resultNotAddRefed': [ 'item' ]
@ -308,6 +312,10 @@ DOMInterfaces = {
]
},
'HTMLDivElement': {
'hasInstanceInterface': 'nsIDOMHTMLDivElement',
},
'HTMLDocument': {
'nativeType': 'nsHTMLDocument',
'register': False,
@ -328,10 +336,19 @@ DOMInterfaces = {
]
},
'HTMLFrameSetElement': {
'hasInstanceInterface': 'nsIDOMHTMLFrameSetElement',
},
'HTMLHeadingElement': {
'hasInstanceInterface': 'nsIDOMHTMLHeadingElement',
},
'HTMLLabelElement': {
'resultNotAddRefed': [
'form', 'control'
]
],
'hasInstanceInterface': 'nsIDOMHTMLLabelElement',
},
'HTMLOptionsCollection': {

View File

@ -3212,7 +3212,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
if not callWrapValue:
tail = successCode
else:
tail = ("if (!MaybeWrapValue(cx, ${obj}, ${jsvalPtr})) {\n" +
tail = ("if (!MaybeWrapValue(cx, ${jsvalPtr})) {\n" +
("%s\n" % exceptionCodeIndented.define()) +
"}\n" +
successCode)
@ -3899,7 +3899,7 @@ class CGMethodCall(CGThing):
# We can't handle unions at the distinguishing index.
if distinguishingType(sig).isUnion():
raise TypeError("No support for unions as distinguishing "
"arguments yet: %s",
"arguments yet: %s" %
distinguishingArgument(sig).location)
# We don't support variadics as the distinguishingArgument yet.
# If you want to add support, consider this case:
@ -3917,7 +3917,7 @@ class CGMethodCall(CGThing):
# double-check.
if distinguishingArgument(sig).variadic:
raise TypeError("No support for variadics as distinguishing "
"arguments yet: %s",
"arguments yet: %s" %
distinguishingArgument(sig).location)
# Convert all our arguments up to the distinguishing index.
@ -6811,7 +6811,7 @@ class CGBindingRoot(CGThing):
components = nativeType.split('::')
className = components[-1]
# JSObject is a struct, not a class
declare = CGClassForwardDeclare(className, className is "JSObject")
declare = CGClassForwardDeclare(className, className == "JSObject")
if len(components) > 1:
declare = CGNamespace.build(components[:-1],
CGWrapper(declare, declarePre='\n',

View File

@ -2001,6 +2001,14 @@ BluetoothDBusService::SetProperty(BluetoothObjectType aType,
{
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
if (!IsReady()) {
BluetoothValue v;
nsString errorStr;
errorStr.AssignLiteral("Bluetooth service is not ready yet!");
DispatchBluetoothReply(aRunnable, v, errorStr);
return NS_OK;
}
MOZ_ASSERT(aType < ArrayLength(sBluetoothDBusIfaces));
const char* interface = sBluetoothDBusIfaces[aType];

View File

@ -0,0 +1,6 @@
[DEFAULT]
b2g = true
browser = false
qemu = true
[test_sim_contacts.js]

View File

@ -0,0 +1,59 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
SpecialPowers.addPermission("contacts-read", true, document);
let mozContacts = window.navigator.mozContacts;
ok(mozContacts);
function testImportSimContacts() {
let request = mozContacts.getSimContacts("ADN");
request.onsuccess = function onsuccess() {
let simContacts = request.result;
// These SIM contacts are harded in external/qemu/telephony/sim_card.c
is(simContacts.length, 4);
is(simContacts[0].name, "Mozilla");
is(simContacts[0].tel[0].value, "15555218201");
is(simContacts[1].name, "Saßê黃");
is(simContacts[1].tel[0].value, "15555218202");
is(simContacts[2].name, "Fire 火");
is(simContacts[2].tel[0].value, "15555218203");
is(simContacts[3].name, "Huang 黃");
is(simContacts[3].tel[0].value, "15555218204");
runNextTest();
};
request.onerror = function onerror() {
ok(false, "Cannot get Sim Contacts");
runNextTest();
};
};
let tests = [
testImportSimContacts,
];
function runNextTest() {
let test = tests.pop();
if (!test) {
cleanUp();
return;
}
test();
}
function cleanUp() {
SpecialPowers.removePermission("contacts-read", document);
finish();
}
runNextTest();

View File

@ -14,7 +14,9 @@ LIBRARY_NAME = domdevicestorage_s
XPIDL_MODULE = dom_devicestorage
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
include $(topsrcdir)/dom/dom-config.mk

View File

@ -6,7 +6,6 @@ DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
@ -15,6 +14,9 @@ LIBRARY_NAME = domfile_s
XPIDL_MODULE = dom_file
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
include $(topsrcdir)/dom/dom-config.mk

View File

@ -6,7 +6,6 @@ DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
@ -15,6 +14,9 @@ LIBRARY_NAME = dom_indexeddb_s
XPIDL_MODULE = dom_indexeddb
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
EXPORTS_NAMESPACES = mozilla/dom/indexedDB

View File

@ -80,6 +80,7 @@
#include "StructuredCloneUtils.h"
#include "TabParent.h"
#include "URIUtils.h"
#include "nsGeolocation.h"
#ifdef ANDROID
# include "gfxAndroidPlatform.h"
@ -1969,6 +1970,15 @@ ContentParent::RecvRemoveGeolocationListener()
return true;
}
bool
ContentParent::RecvSetGeolocationHigherAccuracy(const bool& aEnable)
{
nsRefPtr<nsGeolocationService> geoSvc =
nsGeolocationService::GetGeolocationService();
geoSvc->SetHigherAccuracy(aEnable);
return true;
}
NS_IMETHODIMP
ContentParent::HandleEvent(nsIDOMGeoPosition* postion)
{

View File

@ -302,6 +302,7 @@ private:
virtual bool RecvAddGeolocationListener();
virtual bool RecvRemoveGeolocationListener();
virtual bool RecvSetGeolocationHigherAccuracy(const bool& aEnable);
virtual bool RecvConsoleMessage(const nsString& aMessage);
virtual bool RecvScriptError(const nsString& aMessage,

View File

@ -14,7 +14,9 @@ LIBRARY_NAME = domipc_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
EXPORT_LIBRARY = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
TEST_DIRS += tests
@ -81,6 +83,7 @@ LOCAL_INCLUDES += \
-I$(topsrcdir)/uriloader/exthandler \
-I$(srcdir)/../../netwerk/base/src \
-I$(srcdir)/../src/base \
-I$(srcdir)/../src/geolocation \
-I$(srcdir)/../src/storage \
-I$(srcdir)/../../xpcom/base \
-I$(topsrcdir)/dom/indexedDB \

View File

@ -397,6 +397,7 @@ parent:
AddGeolocationListener();
RemoveGeolocationListener();
SetGeolocationHigherAccuracy(bool enable);
ConsoleMessage(nsString message);
ScriptError(nsString message, nsString sourceName, nsString sourceLine,

View File

@ -15,7 +15,9 @@ XPIDL_MODULE = dom_media
LIBRARY_NAME = dom_media_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
include $(topsrcdir)/dom/dom-config.mk

View File

@ -670,22 +670,18 @@ public:
new nsTArray<nsCOMPtr<nsIMediaDevice> >;
/**
* We only display available devices in the UI for now. We can easily
* change this later, when we implement a more sophisticated UI that
* lets the user revoke a device currently held by another tab (or
* we decide to provide a stream from a device already allocated).
* We're allowing multiple tabs to access the same camera for parity
* with Chrome. See bug 811757 for some of the issues surrounding
* this decision. To disallow, we'd filter by IsAvailable() as we used
* to.
*/
for (i = 0; i < videoCount; i++) {
MediaEngineVideoSource *vSource = videoSources[i];
if (vSource->IsAvailable()) {
devices->AppendElement(new MediaDevice(vSource));
}
devices->AppendElement(new MediaDevice(vSource));
}
for (i = 0; i < audioCount; i++) {
MediaEngineAudioSource *aSource = audioSources[i];
if (aSource->IsAvailable()) {
devices->AppendElement(new MediaDevice(aSource));
}
devices->AppendElement(new MediaDevice(aSource));
}
NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(
@ -1103,4 +1099,17 @@ MediaManager::GetActiveMediaCaptureWindows(nsISupportsArray **aArray)
return NS_OK;
}
void
GetUserMediaCallbackMediaStreamListener::Invalidate()
{
nsRefPtr<MediaOperationRunnable> runnable;
// We can't take a chance on blocking here, so proxy this to another
// thread.
// Pass a ref to us (which is threadsafe) so it can query us for the
// source stream info.
runnable = new MediaOperationRunnable(MEDIA_STOP,
this, mAudioSource, mVideoSource);
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
}
} // namespace mozilla

View File

@ -27,12 +27,6 @@ extern PRLogModuleInfo* GetMediaManagerLog();
#define MM_LOG(msg)
#endif
// We only support 1 audio and 1 video track for now.
enum {
kVideoTrack = 1,
kAudioTrack = 2
};
class GetUserMediaNotificationEvent: public nsRunnable
{
public:
@ -67,13 +61,90 @@ class GetUserMediaNotificationEvent: public nsRunnable
GetUserMediaStatus mStatus;
};
/**
* This class is an implementation of MediaStreamListener. This is used
* to Start() and Stop() the underlying MediaEngineSource when MediaStreams
* are assigned and deassigned in content.
*/
class GetUserMediaCallbackMediaStreamListener : public MediaStreamListener
{
public:
GetUserMediaCallbackMediaStreamListener(nsIThread *aThread,
nsDOMMediaStream* aStream,
MediaEngineSource* aAudioSource,
MediaEngineSource* aVideoSource)
: mMediaThread(aThread)
, mAudioSource(aAudioSource)
, mVideoSource(aVideoSource)
, mStream(aStream)
, mSourceStream(aStream->GetStream()->AsSourceStream())
, mLastEndTimeAudio(0)
, mLastEndTimeVideo(0) { MOZ_ASSERT(mSourceStream); }
~GetUserMediaCallbackMediaStreamListener()
{
// In theory this could be released from the MediaStreamGraph thread (RemoveListener)
if (mStream) {
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
nsDOMMediaStream *stream;
mStream.forget(&stream);
// Releases directly if on MainThread already
NS_ProxyRelease(mainThread, stream, false);
}
}
SourceMediaStream *GetSourceStream()
{
return mStream->GetStream()->AsSourceStream();
}
void
Invalidate(); // implement in .cpp to avoid circular dependency with MediaOperationRunnable
void
Remove()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
// Caller holds strong reference to us, so no death grip required
mStream->GetStream()->RemoveListener(this);
}
// Proxy NotifyPull() to sources
void
NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime)
{
// Currently audio sources ignore NotifyPull, but they could
// watch it especially for fake audio.
if (mAudioSource) {
mAudioSource->NotifyPull(aGraph, mSourceStream, kAudioTrack, aDesiredTime, mLastEndTimeAudio);
}
if (mVideoSource) {
mVideoSource->NotifyPull(aGraph, mSourceStream, kVideoTrack, aDesiredTime, mLastEndTimeVideo);
}
}
void
NotifyFinished(MediaStreamGraph* aGraph)
{
Invalidate();
// XXX right now this calls Finish, which isn't ideal but doesn't hurt
}
private:
nsCOMPtr<nsIThread> mMediaThread;
nsRefPtr<MediaEngineSource> mAudioSource;
nsRefPtr<MediaEngineSource> mVideoSource;
nsRefPtr<nsDOMMediaStream> mStream;
SourceMediaStream *mSourceStream; // mStream controls ownership
TrackTicks mLastEndTimeAudio;
TrackTicks mLastEndTimeVideo;
};
typedef enum {
MEDIA_START,
MEDIA_STOP
} MediaOperation;
class GetUserMediaCallbackMediaStreamListener;
// Generic class for running long media operations like Start off the main
// thread, and then (because nsDOMMediaStreams aren't threadsafe),
// ProxyReleases mStream since it's cycle collected.
@ -91,14 +162,14 @@ public:
{}
MediaOperationRunnable(MediaOperation aType,
SourceMediaStream* aStream,
GetUserMediaCallbackMediaStreamListener* aListener,
MediaEngineSource* aAudioSource,
MediaEngineSource* aVideoSource)
: mType(aType)
, mAudioSource(aAudioSource)
, mVideoSource(aVideoSource)
, mStream(nullptr)
, mSourceStream(aStream)
, mListener(aListener)
{}
~MediaOperationRunnable()
@ -116,27 +187,34 @@ public:
NS_IMETHOD
Run()
{
SourceMediaStream *source;
// No locking between these is required as all the callbacks for the
// same MediaStream will occur on the same thread.
if (mStream) {
mSourceStream = mStream->GetStream()->AsSourceStream();
source = mStream->GetStream()->AsSourceStream();
} else {
source = mListener->GetSourceStream();
}
MOZ_ASSERT(source);
if (!source) // paranoia
return NS_ERROR_FAILURE;
switch (mType) {
case MEDIA_START:
{
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
nsresult rv;
mSourceStream->SetPullEnabled(true);
source->SetPullEnabled(true);
if (mAudioSource) {
rv = mAudioSource->Start(mSourceStream, kAudioTrack);
rv = mAudioSource->Start(source, kAudioTrack);
if (NS_FAILED(rv)) {
MM_LOG(("Starting audio failed, rv=%d",rv));
}
}
if (mVideoSource) {
rv = mVideoSource->Start(mSourceStream, kVideoTrack);
rv = mVideoSource->Start(source, kVideoTrack);
if (NS_FAILED(rv)) {
MM_LOG(("Starting video failed, rv=%d",rv));
}
@ -155,15 +233,15 @@ public:
{
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
if (mAudioSource) {
mAudioSource->Stop();
mAudioSource->Stop(source, kAudioTrack);
mAudioSource->Deallocate();
}
if (mVideoSource) {
mVideoSource->Stop();
mVideoSource->Stop(source, kVideoTrack);
mVideoSource->Deallocate();
}
// Do this after stopping all tracks with EndTrack()
mSourceStream->Finish();
source->Finish();
nsRefPtr<GetUserMediaNotificationEvent> event =
new GetUserMediaNotificationEvent(GetUserMediaNotificationEvent::STOPPING);
@ -184,94 +262,7 @@ private:
nsRefPtr<MediaEngineSource> mAudioSource; // threadsafe
nsRefPtr<MediaEngineSource> mVideoSource; // threadsafe
nsRefPtr<nsDOMMediaStream> mStream; // not threadsafe
SourceMediaStream *mSourceStream;
};
/**
* This class is an implementation of MediaStreamListener. This is used
* to Start() and Stop() the underlying MediaEngineSource when MediaStreams
* are assigned and deassigned in content.
*/
class GetUserMediaCallbackMediaStreamListener : public MediaStreamListener
{
public:
GetUserMediaCallbackMediaStreamListener(nsIThread *aThread,
nsDOMMediaStream* aStream,
MediaEngineSource* aAudioSource,
MediaEngineSource* aVideoSource)
: mMediaThread(aThread)
, mAudioSource(aAudioSource)
, mVideoSource(aVideoSource)
, mStream(aStream) {}
~GetUserMediaCallbackMediaStreamListener()
{
// In theory this could be released from the MediaStreamGraph thread (RemoveListener)
if (mStream) {
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
nsDOMMediaStream *stream;
mStream.forget(&stream);
// Releases directly if on MainThread already
NS_ProxyRelease(mainThread, stream, false);
}
}
void
Invalidate()
{
nsRefPtr<MediaOperationRunnable> runnable;
// We can't take a chance on blocking here, so proxy this to another
// thread.
// XXX FIX! I'm cheating and passing a raw pointer to the sourcestream
// which is valid as long as the mStream pointer here is.
// Solutions (see bug 825235):
// a) if on MainThread, pass mStream and let it addref
// (MediaOperation will need to ProxyRelease however)
// b) if on MediaStreamGraph thread, dispatch a runnable to MainThread
// to call Invalidate() (with a strong ref to this listener)
runnable = new MediaOperationRunnable(MEDIA_STOP,
mStream->GetStream()->AsSourceStream(),
mAudioSource, mVideoSource);
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
return;
}
void
Remove()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
// Caller holds strong reference to us, so no death grip required
mStream->GetStream()->RemoveListener(this);
}
// Proxy NotifyPull() to sources
void
NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime)
{
// Currently audio sources ignore NotifyPull, but they could
// watch it especially for fake audio.
if (mAudioSource) {
mAudioSource->NotifyPull(aGraph, aDesiredTime);
}
if (mVideoSource) {
mVideoSource->NotifyPull(aGraph, aDesiredTime);
}
}
void
NotifyFinished(MediaStreamGraph* aGraph)
{
Invalidate();
// XXX right now this calls Finish, which isn't ideal but doesn't hurt
}
private:
nsCOMPtr<nsIThread> mMediaThread;
nsRefPtr<MediaEngineSource> mAudioSource;
nsRefPtr<MediaEngineSource> mVideoSource;
nsRefPtr<nsDOMMediaStream> mStream;
nsRefPtr<GetUserMediaCallbackMediaStreamListener> mListener; // threadsafe
};
typedef nsTArray<nsRefPtr<GetUserMediaCallbackMediaStreamListener> > StreamListeners;

View File

@ -53,8 +53,6 @@ function MediaStreamPlayback(mediaElement, mediaStream) {
is(self.mediaElement.paused, false,
"Media element should be playing");
is(self.mediaElement.ended, false,
"Media element should not have ended");
is(self.mediaElement.duration, Number.POSITIVE_INFINITY,
"Duration should be infinity");
@ -69,14 +67,6 @@ function MediaStreamPlayback(mediaElement, mediaStream) {
"Seekable length shall be zero");
is(self.mediaElement.buffered.length, 0,
"Buffered length shall be zero");
is(self.mediaElement.played.length, 1, "Played length shall be one");
if(self.mediaElement.played.length > 0) {
is(self.mediaElement.played.start(0), 0,
"Played start shall be zero");
is(self.mediaElement.played.end(0), self.mediaElement.currentTime,
"End shall be current time");
}
is(self.mediaElement.seeking, false,
"MediaElement is not seekable with MediaStream");

View File

@ -12,7 +12,9 @@ include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = dom_network_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
EXTRA_COMPONENTS = \
TCPSocket.js \

View File

@ -71,7 +71,9 @@ else
# android_npapi.h extends the NPNVariable and NPPVariable enums
# using #defines, which results in Wswitch warnings in gcc-4.6.
# Therefore, enable FAIL_ON_WARNINGS only on non-Android platforms.
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
endif
ifeq ($(OS_ARCH),WINNT)

View File

@ -6,11 +6,13 @@ DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
MODULE = dom
ifndef _MSC_VER
FAIL_ON_WARNINGS := 1
endif # !_MSC_VER
EXPORTS_NAMESPACES = mozilla

Some files were not shown because too many files have changed in this diff Show More