mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Merge mozilla-central into build-system
This commit is contained in:
commit
4951adbb99
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1460,6 +1460,9 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
|
||||
case eTextLeafType:
|
||||
newAcc = new TextLeafAccessibleWrap(aContent, document);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return newAcc.forget();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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 \
|
||||
|
56
accessible/tests/mochitest/name/test_svg.html
Normal file
56
accessible/tests/mochitest/name/test_svg.html
Normal 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>
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
let gTests;
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(2);
|
||||
gTests = runTest();
|
||||
moveAlong();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ function test() {
|
||||
"The checkbox should not be disabled");
|
||||
|
||||
win.close();
|
||||
callback();
|
||||
executeSoon(callback);
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
21
content/base/crashtests/822691.html
Normal file
21
content/base/crashtests/822691.html
Normal 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>
|
@ -119,4 +119,5 @@ load xhr_empty_datauri.html
|
||||
load 815477.html
|
||||
load 815500.html
|
||||
load 816253.html
|
||||
load 822691.html
|
||||
load 822723.html
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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); \
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 \
|
||||
|
155
content/html/content/src/HTMLTitleElement.cpp
Normal file
155
content/html/content/src/HTMLTitleElement.cpp
Normal 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
|
85
content/html/content/src/HTMLTitleElement.h
Normal file
85
content/html/content/src/HTMLTitleElement.h
Normal 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_
|
@ -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 \
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 += \
|
||||
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
@ -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 := \
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
@ -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) {
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
36
dom/base/test/test_window_constructor.html
Normal file
36
dom/base/test/test_window_constructor.html
Normal 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>
|
@ -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;
|
||||
|
@ -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': {
|
||||
|
@ -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',
|
||||
|
@ -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];
|
||||
|
||||
|
6
dom/contacts/tests/marionette/manifest.ini
Normal file
6
dom/contacts/tests/marionette/manifest.ini
Normal file
@ -0,0 +1,6 @@
|
||||
[DEFAULT]
|
||||
b2g = true
|
||||
browser = false
|
||||
qemu = true
|
||||
|
||||
[test_sim_contacts.js]
|
59
dom/contacts/tests/marionette/test_sim_contacts.js
Normal file
59
dom/contacts/tests/marionette/test_sim_contacts.js
Normal 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();
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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 \
|
||||
|
@ -397,6 +397,7 @@ parent:
|
||||
|
||||
AddGeolocationListener();
|
||||
RemoveGeolocationListener();
|
||||
SetGeolocationHigherAccuracy(bool enable);
|
||||
|
||||
ConsoleMessage(nsString message);
|
||||
ScriptError(nsString message, nsString sourceName, nsString sourceLine,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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 \
|
||||
|
@ -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)
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user