This commit is contained in:
Wes Kocher 2015-01-28 18:45:04 -08:00
Родитель 3140732c81 a4cef467eb
Коммит 6922db3c44
140 изменённых файлов: 3223 добавлений и 2093 удалений

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

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 917322 - Due to removing nsICompositionStringSynthesizer.idl
Bug 1123384 - Needs a clobber for some reason.

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

@ -110,24 +110,6 @@ Accessible::Accessible(nsIContent* aContent, DocAccessible* aDoc) :
mIndexOfEmbeddedChild(-1), mRoleMapEntry(nullptr)
{
mBits.groupInfo = nullptr;
#ifdef NS_DEBUG_X
{
nsCOMPtr<nsIPresShell> shell(do_QueryReferent(aShell));
printf(">>> %p Created Acc - DOM: %p PS: %p",
(void*)static_cast<nsIAccessible*>(this), (void*)aNode,
(void*)shell.get());
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
if (content) {
printf(" Con: %s@%p",
NS_ConvertUTF16toUTF8(content->NodeInfo()->QualifiedName()).get(),
(void *)content.get());
nsAutoString buf;
Name(buf);
printf(" Name:[%s]", NS_ConvertUTF16toUTF8(buf).get());
}
printf("\n");
}
#endif
}
Accessible::~Accessible()

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

@ -51,7 +51,7 @@ DocAccessibleParent::RecvShowEvent(const ShowEventData& aData)
}
#endif
return consumed;
return consumed != 0;
}
uint32_t

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

@ -1,5 +1,5 @@
[DEFAULT]
run-if = toolkit == "gonk"
skip-if = toolkit != "gonk"
support-files =
permission_handler_chrome.js
SandboxPromptTest.html

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d6a27295acb0a25926bf6290dd2532a7f9027864"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d6a27295acb0a25926bf6290dd2532a7f9027864"/>

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

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "782d371263911a526870263bffcb419b52c7c88a",
"git_revision": "9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "8c97eed028b3ad9580854e6c12f80e3046440e45",
"revision": "255eba2ffe784601984ce72cd6acfc452c4f28f1",
"repo_path": "integration/gaia-central"
}

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>

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

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d6a27295acb0a25926bf6290dd2532a7f9027864"/>

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

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="782d371263911a526870263bffcb419b52c7c88a"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="9d2378a9ef092ab1fc15c3a9f7fc4171aab59d57"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -217,7 +217,7 @@ skip-if = e10s # Bug 940195 - XULBrowserWindow.isBusy is false as a remote tab s
[browser_bug565575.js]
skip-if = e10s
[browser_bug565667.js]
run-if = toolkit == "cocoa"
skip-if = toolkit != "cocoa"
[browser_bug567306.js]
skip-if = e10s # Bug XXX - Needs some massaging to run in e10s
[browser_bug575561.js]
@ -297,7 +297,7 @@ skip-if = os == "mac" || e10s # bug 967013; e10s: bug 1094761 - test hits the ne
[browser_ctrlTab.js]
[browser_customize_popupNotification.js]
[browser_datareporting_notification.js]
run-if = datareporting
skip-if = !datareporting
[browser_devedition.js]
[browser_devices_get_user_media.js]
skip-if = buildapp == 'mulet' || (os == "linux" && debug) || e10s # linux: bug 976544; e10s: bug 1071623

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

@ -48,6 +48,10 @@ support-files =
browser_739531_sample.html
browser_911547_sample.html
browser_911547_sample.html^headers^
restore_redirect_http.html
restore_redirect_http.html^headers^
restore_redirect_js.html
restore_redirect_target.html
#NB: the following are disabled
# browser_464620_a.html
@ -85,6 +89,7 @@ skip-if = buildapp == 'mulet'
[browser_merge_closed_tabs.js]
[browser_pageStyle.js]
[browser_privatetabs.js]
[browser_restore_redirect.js]
[browser_scrollPositions.js]
[browser_sessionHistory.js]
# Disabled because of bug 1077581

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

@ -0,0 +1,69 @@
"use strict";
const BASE = "http://example.com/browser/browser/components/sessionstore/test/";
const TARGET = BASE + "restore_redirect_target.html";
/**
* Ensure that a http redirect leaves a working tab.
*/
add_task(function check_http_redirect() {
let state = {
entries: [{ url: BASE + "restore_redirect_http.html" }]
};
// Open a new tab to restore into.
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
yield promiseTabState(tab, state);
info("Restored tab");
TabState.flush(browser);
let data = TabState.collect(tab);
is(data.entries.length, 1, "Should be one entry in session history");
is(data.entries[0].url, TARGET, "Should be the right session history entry");
ok(!("__SS_data" in browser), "Temporary restore data should have been cleared");
// Cleanup.
gBrowser.removeTab(tab);
});
/**
* Ensure that a js redirect leaves a working tab.
*/
add_task(function check_js_redirect() {
let state = {
entries: [{ url: BASE + "restore_redirect_js.html" }]
};
let loadPromise = new Promise(resolve => {
function listener(msg) {
if (msg.data.url.endsWith("restore_redirect_target.html")) {
window.messageManager.removeMessageListener("ss-test:loadEvent", listener);
resolve();
}
}
window.messageManager.addMessageListener("ss-test:loadEvent", listener);
});
// Open a new tab to restore into.
let tab = gBrowser.addTab("about:blank");
let browser = tab.linkedBrowser;
yield promiseTabState(tab, state);
info("Restored tab");
yield loadPromise;
TabState.flush(browser);
let data = TabState.collect(tab);
is(data.entries.length, 1, "Should be one entry in session history");
is(data.entries[0].url, TARGET, "Should be the right session history entry");
ok(!("__SS_data" in browser), "Temporary restore data should have been cleared");
// Cleanup.
gBrowser.removeTab(tab);
});

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

@ -261,5 +261,5 @@ addMessageListener("ss-test:run", function({data, objects}) {
addEventListener("load", function(event) {
let subframe = event.target != content.document;
sendAsyncMessage("ss-test:loadEvent", {subframe: subframe});
sendAsyncMessage("ss-test:loadEvent", {subframe: subframe, url: event.target.documentURI});
}, true);

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

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

@ -0,0 +1,2 @@
HTTP 302 Moved Temporarily
Location: restore_redirect_target.html

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

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<script>
var newLocation = window.location.toString().replace("restore_redirect_js.html", "restore_redirect_target.html");
window.location.replace(newLocation);
</script>
</head>
</html>

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

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>Test page</title>
</head>
<body>Test page</body>
</html>

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

@ -2048,7 +2048,7 @@ Scope.prototype = {
let parentView = self.ownerView;
let topView;
while (topView = parentView.ownerView) {
while ((topView = parentView.ownerView)) {
parentView = topView;
}
return parentView;

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

@ -250,7 +250,7 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s (expectUncaug
[browser_webconsole_bug_621644_jsterm_dollar.js]
[browser_webconsole_bug_622303_persistent_filters.js]
[browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js]
run-if = os == "win"
skip-if = os != "win"
[browser_webconsole_bug_630733_response_redirect_headers.js]
[browser_webconsole_bug_632275_getters_document_width.js]
[browser_webconsole_bug_632347_iterators_generators.js]
@ -287,7 +287,7 @@ skip-if = buildapp == 'mulet' || e10s # Bug 1042253 - webconsole e10s tests (exp
[browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js]
skip-if = buildapp == 'mulet'
[browser_webconsole_bug_804845_ctrl_key_nav.js]
run-if = os == "mac"
skip-if = os != "mac"
[browser_webconsole_bug_817834_add_edited_input_to_history.js]
[browser_webconsole_bug_837351_securityerrors.js]
skip-if = buildapp == 'mulet'

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

@ -26,8 +26,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryPing",
"resource://gre/modules/TelemetryPing.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetrySession",
"resource://gre/modules/TelemetrySession.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryLog",
"resource://gre/modules/TelemetryLog.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils",
@ -323,7 +323,7 @@ Experiments.Policy.prototype = {
},
telemetryPayload: function () {
return TelemetryPing.getPayload();
return TelemetrySession.getPayload();
},
/**

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

@ -5,6 +5,7 @@
Cu.import("resource:///modules/experiments/Experiments.jsm");
Cu.import("resource://gre/modules/TelemetrySession.jsm", this);
const FILE_MANIFEST = "experiments.manifest";
const SEC_IN_ONE_DAY = 24 * 60 * 60;
@ -51,6 +52,7 @@ function run_test() {
add_task(function* test_setup() {
createAppInfo();
gProfileDir = do_get_profile();
yield TelemetrySession.setup();
gPolicy = new Experiments.Policy();
gReporter = yield getReporter("json_payload_simple");
@ -308,3 +310,7 @@ add_task(function* test_times() {
}
}
});
add_task(function* test_shutdown() {
yield TelemetrySession.shutdown();
});

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

@ -103,8 +103,8 @@ add_task(function* test_setup() {
// Test basic starting and stopping of experiments.
add_task(function* test_telemetryBasics() {
// Check TelemetryLog instead of TelemetryPing.getPayload().log because
// TelemetryPing gets Experiments.instance() and side-effects log entries.
// Check TelemetryLog instead of TelemetrySession.getPayload().log because
// TelemetrySession gets Experiments.instance() and side-effects log entries.
const OBSERVER_TOPIC = "experiments-changed";
let observerFireCount = 0;

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

@ -5,15 +5,21 @@
"use strict";
Cu.import("resource://gre/modules/TelemetrySession.jsm", this);
function test() {
runTests();
}
function getTelemetryPayload() {
return Cu.import("resource://gre/modules/TelemetryPing.jsm", {}).
TelemetryPing.getPayload();
return TelemetrySession.getPayload();
}
gTests.push({
desc: "Setup",
run: () => { yield TelemetrySession.setup(); }
});
gTests.push({
desc: "Test browser-ui telemetry",
run: function testBrowserUITelemetry() {
@ -63,4 +69,9 @@ gTests.push({
is(simpleMeasurements.UITelemetry["metro-tabs"]["currTabCount"], 1);
is(simpleMeasurements.UITelemetry["metro-tabs"]["maxTabCount"], 3);
}
});
});
gTests.push({
desc: "Shutdown",
run: () => { yield TelemetrySession.shutdown(); }
});

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

@ -15,5 +15,4 @@ skip-if = e10s # Bug 666804 - Support NetworkPrioritizer in e10s
[browser_SignInToWebsite.js]
skip-if = e10s # Bug 941426 - SignIntoWebsite.jsm not e10s friendly
[browser_taskbar_preview.js]
run-if = os == "win"
skip-if = e10s # Bug 666808 - AeroPeek support for e10s
skip-if = os != win || e10s # Bug 666808 - AeroPeek support for e10s

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

@ -227,9 +227,6 @@ public:
void ActivateUpdateHitRegion();
void DeactivateUpdateHitRegion();
// Properly retrieves documentSize of any subdocument type.
nsresult GetWindowDimensions(nsIntRect& aRect);
private:
void SetOwnerContent(mozilla::dom::Element* aContent);
@ -285,6 +282,9 @@ private:
nsresult MaybeCreateDocShell();
nsresult EnsureMessageManager();
// Properly retrieves documentSize of any subdocument type.
nsresult GetWindowDimensions(nsIntRect& aRect);
// Updates the subdocument position and size. This gets called only
// when we have our own in-process DocShell.
void UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame);

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

@ -1,6 +1,5 @@
[DEFAULT]
run-if = buildapp == "browser"
skip-if = e10s
skip-if = (buildapp != "browser") || e10s
support-files =
head.js
browser_forgetThisSiteAdd.html

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

@ -85,7 +85,7 @@ struct FrameScriptInfo
bool runInGlobalScope;
};
prio(normal upto urgent) intr protocol PBrowser
prio(normal upto urgent) sync protocol PBrowser
{
manager PContent or PContentBridge;

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

@ -341,7 +341,7 @@ union OptionalContentId
void_t;
};
prio(normal upto urgent) intr protocol PContent
prio(normal upto urgent) sync protocol PContent
{
parent spawns PPluginModule;

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

@ -28,7 +28,7 @@ namespace dom {
* allocate the PContentBridgeChild. This protocol allows these processes to
* share PBrowsers and send messages to each other.
*/
prio(normal upto urgent) intr protocol PContentBridge
prio(normal upto urgent) sync protocol PContentBridge
{
bridges PContent, PContent;

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

@ -76,7 +76,6 @@
#include "nsICancelable.h"
#include "gfxPrefs.h"
#include "nsILoginManagerPrompter.h"
#include "nsPIWindowRoot.h"
#include <algorithm>
using namespace mozilla::dom;
@ -317,27 +316,7 @@ TabParent::RemoveTabParentFromTable(uint64_t aLayersId)
void
TabParent::SetOwnerElement(Element* aElement)
{
// If we held previous content then unregister for its events.
if (mFrameElement && mFrameElement->OwnerDoc()->GetWindow()) {
nsCOMPtr<nsPIDOMWindow> window = mFrameElement->OwnerDoc()->GetWindow();
nsCOMPtr<EventTarget> eventTarget = window->GetTopWindowRoot();
if (eventTarget) {
eventTarget->RemoveEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"),
this, false);
}
}
// Update to the new content, and register to listen for events from it.
mFrameElement = aElement;
if (mFrameElement && mFrameElement->OwnerDoc()->GetWindow()) {
nsCOMPtr<nsPIDOMWindow> window = mFrameElement->OwnerDoc()->GetWindow();
nsCOMPtr<EventTarget> eventTarget = window->GetTopWindowRoot();
if (eventTarget) {
eventTarget->AddEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"),
this, false, false);
}
}
TryCacheDPIAndScale();
}
@ -373,8 +352,6 @@ TabParent::Destroy()
return;
}
SetOwnerElement(nullptr);
// If this fails, it's most likely due to a content-process crash,
// and auto-cleanup will kick in. Otherwise, the child side will
// destroy itself and send back __delete__().
@ -823,9 +800,8 @@ TabParent::UpdateDimensions(const nsIntRect& rect, const nsIntSize& size,
mRect = rect;
mDimensions = size;
mOrientation = orientation;
mChromeDisp = aChromeDisp;
unused << SendUpdateDimensions(mRect, mDimensions, mOrientation, mChromeDisp);
unused << SendUpdateDimensions(mRect, mDimensions, mOrientation, aChromeDisp);
}
}
@ -2574,27 +2550,6 @@ TabParent::DeallocPPluginWidgetParent(mozilla::plugins::PPluginWidgetParent* aAc
return true;
}
nsresult
TabParent::HandleEvent(nsIDOMEvent* aEvent)
{
nsAutoString eventType;
aEvent->GetType(eventType);
if (eventType.EqualsLiteral("MozUpdateWindowPos")) {
// This event is sent when the widget moved. Therefore we only update
// the position.
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
return NS_OK;
}
nsIntRect windowDims;
NS_ENSURE_SUCCESS(frameLoader->GetWindowDimensions(windowDims), NS_ERROR_FAILURE);
UpdateDimensions(windowDims, mDimensions, mChromeDisp);
return NS_OK;
}
return NS_OK;
}
class FakeChannel MOZ_FINAL : public nsIChannel,
public nsIAuthPromptCallback,
public nsIInterfaceRequestor,

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

@ -22,7 +22,6 @@
#include "Units.h"
#include "WritingModes.h"
#include "js/TypeDecls.h"
#include "nsIDOMEventListener.h"
class nsFrameLoader;
class nsIContent;
@ -58,8 +57,7 @@ class nsIContentParent;
class Element;
struct StructuredCloneData;
class TabParent : public PBrowserParent
, public nsIDOMEventListener
class TabParent : public PBrowserParent
, public nsITabParent
, public nsIAuthPromptProvider
, public nsISecureBrowserUI
@ -100,9 +98,6 @@ public:
mBrowserDOMWindow = aBrowserDOMWindow;
}
// nsIDOMEventListener interfaces
NS_DECL_NSIDOMEVENTLISTENER
already_AddRefed<nsILoadContext> GetLoadContext();
nsIXULBrowserWindow* GetXULBrowserWindow();
@ -430,7 +425,6 @@ protected:
nsIntRect mRect;
nsIntSize mDimensions;
ScreenOrientation mOrientation;
nsIntPoint mChromeDisp;
float mDPI;
CSSToLayoutDeviceScale mDefaultScale;
bool mShown;

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

@ -5,7 +5,7 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet' || e10s
# This test is only supposed to run in the main process.
skip-if = buildapp == 'b2g' || buildapp == 'mulet' || e10s
[test_NuwaProcessCreation.html]
run-if = toolkit == 'gonk'
skip-if = toolkit != 'gonk'
[test_NuwaProcessDeadlock.html]
run-if = toolkit == 'gonk'
[test_child_docshell.html]

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

@ -15,14 +15,20 @@ namespace dom {
MediaStreamTrack::MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID)
: mStream(aStream), mTrackID(aTrackID), mEnded(false), mEnabled(true)
{
memset(&mID, 0, sizeof(mID));
nsresult rv;
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
nsID uuid;
memset(&uuid, 0, sizeof(uuid));
if (uuidgen) {
uuidgen->GenerateUUIDInPlace(&mID);
uuidgen->GenerateUUIDInPlace(&uuid);
}
char chars[NSID_LENGTH];
uuid.ToProvidedString(chars);
mID = NS_ConvertASCIItoUTF16(chars);
}
MediaStreamTrack::~MediaStreamTrack()
@ -38,11 +44,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaStreamTrack)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
void
MediaStreamTrack::GetId(nsAString& aID)
MediaStreamTrack::GetId(nsAString& aID) const
{
char chars[NSID_LENGTH];
mID.ToProvidedString(chars);
aID = NS_ConvertASCIItoUTF16(chars);
aID = mID;
}
void

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

@ -44,7 +44,7 @@ public:
// WebIDL
virtual void GetKind(nsAString& aKind) = 0;
void GetId(nsAString& aID);
void GetId(nsAString& aID) const;
void GetLabel(nsAString& aLabel) { aLabel.Truncate(); }
bool Enabled() { return mEnabled; }
void SetEnabled(bool aEnabled);
@ -53,12 +53,16 @@ public:
// Notifications from the MediaStreamGraph
void NotifyEnded() { mEnded = true; }
// Webrtc allows the remote side to name tracks whatever it wants, and we
// need to surface this to content.
void AssignId(const nsAString& aID) { mID = aID; }
protected:
virtual ~MediaStreamTrack();
nsRefPtr<DOMMediaStream> mStream;
TrackID mTrackID;
nsID mID;
nsString mID;
bool mEnded;
bool mEnabled;
};

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

@ -37,9 +37,6 @@ static const int MAX_VOUCHER_LENGTH = 500000;
#if defined(XP_WIN)
#define TARGET_SANDBOX_EXPORTS
#include "mozilla/sandboxTarget.h"
#elif defined (XP_LINUX)
#include "mozilla/Sandbox.h"
#include "mozilla/SandboxInfo.h"
#elif defined(XP_MACOSX)
#include "mozilla/Sandbox.h"
#endif

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

@ -775,6 +775,15 @@ class CreateGMPParentTask : public nsRunnable {
public:
NS_IMETHOD Run() {
MOZ_ASSERT(NS_IsMainThread());
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
if (!SandboxInfo::Get().CanSandboxMedia()) {
if (!Preferences::GetBool("media.gmp.insecure.allow")) {
NS_WARNING("Denying media plugin load due to lack of sandboxing.");
return NS_ERROR_NOT_AVAILABLE;
}
NS_WARNING("Loading media plugin despite lack of sandboxing.");
}
#endif
mParent = new GMPParent();
return NS_OK;
}
@ -832,7 +841,7 @@ GeckoMediaPluginService::AddOnGMPThread(const nsAString& aDirectory)
MOZ_ASSERT(mainThread);
mozilla::SyncRunnable::DispatchToThread(mainThread, task);
nsRefPtr<GMPParent> gmp = task->GetParent();
rv = gmp->Init(this, directory);
rv = gmp ? gmp->Init(this, directory) : NS_ERROR_NOT_AVAILABLE;
if (NS_FAILED(rv)) {
NS_WARNING("Can't Create GMPParent");
return;

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

@ -32,15 +32,10 @@ function theTest() {
});
test.setMediaConstraints([{
audio: true,
peerIdentity: id2
}, {
video: true,
peerIdentity: id2
}], [{
audio: true,
fake: true,
peerIdentity: id1
}, {
video: true,
fake: true,
peerIdentity: id1

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

@ -132,12 +132,16 @@ skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabl
[test_peerConnection_toJSON.html]
skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
# multistream is not ready quite yet (bug 1056650)
# [test_peerConnection_twoAudioStreams.html]
# [test_peerConnection_twoAudioVideoStreams.html]
# [test_peerConnection_twoAudioVideoStreamsCombined.html]
# [test_peerConnection_twoVideoStreams.html]
# [test_peerConnection_addSecondAudioStream.html]
[test_peerConnection_twoAudioStreams.html]
skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
[test_peerConnection_twoAudioVideoStreams.html]
skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078)
[test_peerConnection_twoAudioVideoStreamsCombined.html]
skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078)
[test_peerConnection_twoVideoStreams.html]
skip-if = (toolkit == 'gonk' || (e10s && debug)) # b2g (Bug 1059867) or fd exhaustion on e10s debug intermittent (Bug 1126078)
# Renegotiation is not yet supported (bug 1017888)
#[test_peerConnection_addSecondAudioStream.html]
# Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
[test_zmedia_cleanup.html]

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

@ -1689,7 +1689,7 @@ PeerConnectionWrapper.prototype = {
}
}
var element = createMediaElement(type, this.label + '_' + side);
var element = createMediaElement(type, this.label + '_' + side + this.streams.length);
this.mediaCheckers.push(new MediaElementChecker(element));
element.mozSrcObject = stream;
element.play();
@ -2321,6 +2321,27 @@ PeerConnectionWrapper.prototype = {
},
checkMsids : function PCW_checkMsids() {
function _checkMsids(desc, streams, sdpLabel) {
streams.forEach(function(stream) {
stream.getTracks().forEach(function(track) {
// TODO(bug 1089798): Once DOMMediaStream has an id field, we
// should be verifying that the SDP contains
// a=msid:<stream-id> <track-id>
ok(desc.sdp.match(new RegExp("a=msid:[^ ]+ " + track.id)),
sdpLabel + " SDP contains track id " + track.id );
});
});
}
_checkMsids(this.localDescription,
this._pc.getLocalStreams(),
"local");
_checkMsids(this.remoteDescription,
this._pc.getRemoteStreams(),
"remote");
},
verifySdp : function PCW_verifySdp(desc, expectedType, offerConstraintsList,
offerOptions, trickleIceCallback) {
info("Examining this SessionDescription: " + JSON.stringify(desc));

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

@ -492,6 +492,20 @@ var commandsPeerConnection = [
});
}
],
[
'PC_LOCAL_CHECK_MSID',
function (test) {
test.pcLocal.checkMsids();
test.next();
}
],
[
'PC_REMOTE_CHECK_MSID',
function (test) {
test.pcRemote.checkMsids();
test.next();
}
],
[
'PC_LOCAL_CHECK_STATS',
function (test) {

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

@ -80,16 +80,18 @@ protected:
// mMonitor protects mImage access/changes, and transitions of mState
// from kStarted to kStopped (which are combined with EndTrack() and
// image changes). Note that mSources is not accessed from other threads
// for video and is not protected.
// image changes).
// mMonitor also protects mSources[] access/changes.
// mSources[] is accessed from webrtc threads.
// All the mMonitor accesses are from the child classes.
Monitor mMonitor; // Monitor for processing Camera frames.
nsTArray<SourceMediaStream*> mSources; // When this goes empty, we shut down HW
nsRefPtr<layers::Image> mImage;
nsRefPtr<layers::ImageContainer> mImageContainer;
int mWidth, mHeight; // protected with mMonitor on Gonk due to different threading
// end of data protected by mMonitor
nsTArray<SourceMediaStream*> mSources; // When this goes empty, we shut down HW
bool mInitDone;
bool mHasDirectListeners;

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

@ -138,7 +138,12 @@ nsresult
MediaEngineGonkVideoSource::Deallocate()
{
LOG((__FUNCTION__));
if (mSources.IsEmpty()) {
bool empty;
{
MonitorAutoLock lock(mMonitor);
empty = mSources.IsEmpty();
}
if (empty) {
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
@ -171,7 +176,10 @@ MediaEngineGonkVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
return NS_ERROR_FAILURE;
}
mSources.AppendElement(aStream);
{
MonitorAutoLock lock(mMonitor);
mSources.AppendElement(aStream);
}
aStream->AddTrack(aID, 0, new VideoSegment());
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
@ -239,12 +247,16 @@ nsresult
MediaEngineGonkVideoSource::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;
{
MonitorAutoLock lock(mMonitor);
if (!mSources.RemoveElement(aSource)) {
// Already stopped - this is allowed
return NS_OK;
}
if (!mSources.IsEmpty()) {
return NS_OK;
}
}
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
@ -295,8 +307,19 @@ MediaEngineGonkVideoSource::Shutdown()
ReentrantMonitorAutoEnter sync(mCallbackMonitor);
if (mState == kStarted) {
while (!mSources.IsEmpty()) {
Stop(mSources[0], kVideoTrack); // XXX change to support multiple tracks
SourceMediaStream *source;
bool empty;
while (1) {
{
MonitorAutoLock lock(mMonitor);
empty = mSources.IsEmpty();
if (empty) {
break;
}
source = mSources[0];
}
Stop(source, kVideoTrack); // XXX change to support multiple tracks
}
MOZ_ASSERT(mState == kStopped);
}

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

@ -280,10 +280,15 @@ MediaEngineWebRTCAudioSource::Allocate(const AudioTrackConstraintsN &aConstraint
LOG(("Audio device is not initalized"));
return NS_ERROR_FAILURE;
}
} else if (mSources.IsEmpty()) {
LOG(("Audio device %d reallocated", mCapIndex));
} else {
LOG(("Audio device %d allocated shared", mCapIndex));
#ifdef PR_LOGGING
MonitorAutoLock lock(mMonitor);
if (mSources.IsEmpty()) {
LOG(("Audio device %d reallocated", mCapIndex));
} else {
LOG(("Audio device %d allocated shared", mCapIndex));
}
#endif
}
return NS_OK;
}
@ -291,7 +296,13 @@ MediaEngineWebRTCAudioSource::Allocate(const AudioTrackConstraintsN &aConstraint
nsresult
MediaEngineWebRTCAudioSource::Deallocate()
{
if (mSources.IsEmpty()) {
bool empty;
{
MonitorAutoLock lock(mMonitor);
empty = mSources.IsEmpty();
}
if (empty) {
// If empty, no callbacks to deliver data should be occuring
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}
@ -488,8 +499,19 @@ MediaEngineWebRTCAudioSource::Shutdown()
}
if (mState == kStarted) {
while (!mSources.IsEmpty()) {
Stop(mSources[0], kAudioTrack); // XXX change to support multiple tracks
SourceMediaStream *source;
bool empty;
while (1) {
{
MonitorAutoLock lock(mMonitor);
empty = mSources.IsEmpty();
if (empty) {
break;
}
source = mSources[0];
}
Stop(source, kAudioTrack); // XXX change to support multiple tracks
}
MOZ_ASSERT(mState == kStopped);
}

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

@ -338,10 +338,15 @@ MediaEngineWebRTCVideoSource::Allocate(const VideoTrackConstraintsN &aConstraint
}
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));
#ifdef PR_LOGGING
MonitorAutoLock lock(mMonitor);
if (mSources.IsEmpty()) {
LOG(("Video device %d reallocated", mCaptureIndex));
} else {
LOG(("Video device %d allocated shared", mCaptureIndex));
}
#endif
}
return NS_OK;
@ -351,7 +356,13 @@ nsresult
MediaEngineWebRTCVideoSource::Deallocate()
{
LOG((__FUNCTION__));
if (mSources.IsEmpty()) {
bool empty;
{
MonitorAutoLock lock(mMonitor);
empty = mSources.IsEmpty();
}
if (empty) {
// If empty, no callbacks to deliver data should be occuring
if (mState != kStopped && mState != kAllocated) {
return NS_ERROR_FAILURE;
}
@ -392,7 +403,10 @@ MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
return NS_ERROR_FAILURE;
}
mSources.AppendElement(aStream);
{
MonitorAutoLock lock(mMonitor);
mSources.AppendElement(aStream);
}
aStream->AddTrack(aID, 0, new VideoSegment());
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
@ -426,22 +440,23 @@ nsresult
MediaEngineWebRTCVideoSource::Stop(SourceMediaStream *aSource, TrackID aID)
{
LOG((__FUNCTION__));
if (!mSources.RemoveElement(aSource)) {
// Already stopped - this is allowed
return NS_OK;
}
aSource->EndTrack(aID);
if (!mSources.IsEmpty()) {
return NS_OK;
}
if (mState != kStarted) {
return NS_ERROR_FAILURE;
}
{
MonitorAutoLock lock(mMonitor);
if (!mSources.RemoveElement(aSource)) {
// Already stopped - this is allowed
return NS_OK;
}
aSource->EndTrack(aID);
if (!mSources.IsEmpty()) {
return NS_OK;
}
if (mState != kStarted) {
return NS_ERROR_FAILURE;
}
mState = kStopped;
// Drop any cached image so we don't start with a stale image on next
// usage
@ -501,8 +516,19 @@ MediaEngineWebRTCVideoSource::Shutdown()
return;
}
if (mState == kStarted) {
while (!mSources.IsEmpty()) {
Stop(mSources[0], kVideoTrack); // XXX change to support multiple tracks
SourceMediaStream *source;
bool empty;
while (1) {
{
MonitorAutoLock lock(mMonitor);
empty = mSources.IsEmpty();
if (empty) {
break;
}
source = mSources[0];
}
Stop(source, kVideoTrack); // XXX change to support multiple tracks
}
MOZ_ASSERT(mState == kStopped);
}

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

@ -789,6 +789,7 @@ NPBool nsPluginInstanceOwner::ConvertPointPuppet(PuppetWidget *widget,
tabContentBounds.ScaleInverseRoundOut(scaleFactor);
int32_t windowH = tabContentBounds.height + int(chromeSize.y);
// This is actually relative to window-chrome.
nsPoint pluginPosition = AsNsPoint(pluginFrame->GetScreenRect().TopLeft());
// Convert (sourceX, sourceY) to 'real' (not PuppetWidget) screen space.
@ -798,8 +799,8 @@ NPBool nsPluginInstanceOwner::ConvertPointPuppet(PuppetWidget *widget,
nsPoint screenPoint;
switch (sourceSpace) {
case NPCoordinateSpacePlugin:
screenPoint = sourcePoint + pluginPosition +
pluginFrame->GetContentRectRelativeToSelf().TopLeft() / nsPresContext::AppUnitsPerCSSPixel();
screenPoint = sourcePoint + pluginFrame->GetContentRectRelativeToSelf().TopLeft() +
chromeSize + pluginPosition + windowPosition;
break;
case NPCoordinateSpaceWindow:
screenPoint = nsPoint(sourcePoint.x, windowH-sourcePoint.y) +
@ -822,8 +823,8 @@ NPBool nsPluginInstanceOwner::ConvertPointPuppet(PuppetWidget *widget,
nsPoint destPoint;
switch (destSpace) {
case NPCoordinateSpacePlugin:
destPoint = screenPoint - pluginPosition -
pluginFrame->GetContentRectRelativeToSelf().TopLeft() / nsPresContext::AppUnitsPerCSSPixel();
destPoint = screenPoint - pluginFrame->GetContentRectRelativeToSelf().TopLeft() -
chromeSize - pluginPosition - windowPosition;
break;
case NPCoordinateSpaceWindow:
destPoint = screenPoint - windowPosition;

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

@ -2,8 +2,8 @@
* 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_plugins_PluginWidgetParent_h
#define mozilla_plugins_PluginWidgetParent_h
#ifndef mozilla_plugins_PluginWidgetChild_h
#define mozilla_plugins_PluginWidgetChild_h
#include "mozilla/plugins/PPluginWidgetChild.h"
@ -27,5 +27,5 @@ public:
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_PluginWidgetParent_h
#endif // mozilla_plugins_PluginWidgetChild_h

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

@ -4,7 +4,7 @@ skip-if = e10s
[test_bug957893.html]
[test_bug957899.html]
[test_wakelock_not_exposed.html]
run-if = appname != "b2g" && buildapp != "mulet"
skip-if = appname == "b2g" || buildapp == "mulet"
[test_power_basics.html]
[test_power_set_cpusleepallowed.html]
skip-if = toolkit != "gonk"

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

@ -29,11 +29,13 @@
#include "TiledLayerBuffer.h"
#include "mozilla/dom/WindowBinding.h" // for Overfill Callback
#include "FrameLayerBuilder.h" // for FrameLayerbuilder
#include "gfxPrefs.h"
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidBridge.h"
#include "LayerMetricsWrapper.h"
#endif
#ifdef XP_WIN
#include "gfxWindowsPlatform.h"
#endif
namespace mozilla {
namespace layers {
@ -741,7 +743,16 @@ ClientLayerManager::GetBackendName(nsAString& aName)
case LayersBackend::LAYERS_OPENGL: aName.AssignLiteral("OpenGL"); return;
case LayersBackend::LAYERS_D3D9: aName.AssignLiteral("Direct3D 9"); return;
case LayersBackend::LAYERS_D3D10: aName.AssignLiteral("Direct3D 10"); return;
case LayersBackend::LAYERS_D3D11: aName.AssignLiteral("Direct3D 11"); return;
case LayersBackend::LAYERS_D3D11: {
#ifdef XP_WIN
if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
aName.AssignLiteral("Direct3D 11 WARP");
} else {
aName.AssignLiteral("Direct3D 11");
}
#endif
return;
}
default: NS_RUNTIMEABORT("Invalid backend");
}
}

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

@ -228,7 +228,6 @@ CompositorVsyncObserver::CompositorVsyncObserver(CompositorParent* aCompositorPa
CompositorVsyncObserver::~CompositorVsyncObserver()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
MOZ_ASSERT(!mIsObservingVsync);
// The CompositorVsyncDispatcher is cleaned up before this in the nsBaseWidget, which stops vsync listeners
mCompositorParent = nullptr;

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

@ -4,7 +4,7 @@ tail =
skip-if = toolkit == 'gonk'
[test_bug22310.js]
run-if = toolkit == "windows" || toolkit == "cocoa"
skip-if = toolkit != "windows" && toolkit != "cocoa"
[test_bug371611.js]
[test_bug374040.js]

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

@ -218,6 +218,12 @@ class IPDLType(Type):
lesser.priorityRange[1] > greater.priorityRange[1]):
return False
# Protocols that use intr semantics are not allowed to use
# message priorities.
if (greater.isInterrupt() and
lesser.priorityRange != (NORMAL_PRIORITY, NORMAL_PRIORITY)):
return False
if lesser.isAsync():
return True
elif lesser.isSync() and not greater.isAsync():

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

@ -279,7 +279,8 @@ class JitProfilingFrameIterator
inline JitFrameLayout *framePtr();
inline JSScript *frameScript();
bool tryInitWithPC(void *pc);
bool tryInitWithTable(JitcodeGlobalTable *table, void *pc, JSRuntime *rt);
bool tryInitWithTable(JitcodeGlobalTable *table, void *pc, JSRuntime *rt,
bool forLastCallSite);
public:
JitProfilingFrameIterator(JSRuntime *rt,

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

@ -2780,15 +2780,12 @@ JitProfilingFrameIterator::JitProfilingFrameIterator(
// Profiler sampling must NOT be suppressed if we are here.
MOZ_ASSERT(rt->isProfilerSamplingEnabled());
// Since the frame is on stack, and is a jit frame, it MUST have Baseline jitcode.
MOZ_ASSERT(frameScript()->hasBaselineScript());
// Try initializing with sampler pc
if (tryInitWithPC(state.pc))
return;
// Try initializing with sampler pc using native=>bytecode table.
if (tryInitWithTable(table, state.pc, rt))
if (tryInitWithTable(table, state.pc, rt, /* forLastCallSite = */ false))
return;
// Try initializing with lastProfilingCallSite pc
@ -2797,15 +2794,24 @@ JitProfilingFrameIterator::JitProfilingFrameIterator(
return;
// Try initializing with lastProfilingCallSite pc using native=>bytecode table.
if (tryInitWithTable(table, lastCallSite, rt))
if (tryInitWithTable(table, lastCallSite, rt, /* forLastCallSite = */ true))
return;
}
// In some rare cases (e.g. baseline eval frame), the callee script may
// not have a baselineScript. Treat this is an empty frame-sequence and
// move on.
if (!frameScript()->hasBaselineScript()) {
type_ = JitFrame_Entry;
fp_ = nullptr;
returnAddressToFp_ = nullptr;
return;
}
// If nothing matches, for now just assume we are at the start of the last frame's
// baseline jit code.
type_ = JitFrame_BaselineJS;
returnAddressToFp_ = frameScript()->baselineScript()->method()->raw();
//++(*this);
}
template <typename FrameType, typename ReturnType=CommonFrameLayout*>
@ -2862,7 +2868,7 @@ JitProfilingFrameIterator::tryInitWithPC(void *pc)
}
// Check for containment in Baseline jitcode second.
if (callee->baselineScript()->method()->containsNativePC(pc)) {
if (callee->hasBaselineScript() && callee->baselineScript()->method()->containsNativePC(pc)) {
type_ = JitFrame_BaselineJS;
returnAddressToFp_ = pc;
return true;
@ -2872,7 +2878,8 @@ JitProfilingFrameIterator::tryInitWithPC(void *pc)
}
bool
JitProfilingFrameIterator::tryInitWithTable(JitcodeGlobalTable *table, void *pc, JSRuntime *rt)
JitProfilingFrameIterator::tryInitWithTable(JitcodeGlobalTable *table, void *pc, JSRuntime *rt,
bool forLastCallSite)
{
if (!pc)
return false;
@ -2896,7 +2903,7 @@ JitProfilingFrameIterator::tryInitWithTable(JitcodeGlobalTable *table, void *pc,
if (entry.isBaseline()) {
// If looked-up callee doesn't match frame callee, don't accept lastProfilingCallSite
if (entry.baselineEntry().script() != callee)
if (forLastCallSite && entry.baselineEntry().script() != callee)
return false;
type_ = JitFrame_BaselineJS;

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

@ -2384,6 +2384,20 @@ print_iso_string(char* buf, size_t size, double utctime)
int(msFromTime(utctime)));
}
static void
print_iso_extended_string(char* buf, size_t size, double utctime)
{
MOZ_ASSERT(TimeClip(utctime) == utctime);
JS_snprintf(buf, size, "%+.6d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ",
int(YearFromTime(utctime)),
int(MonthFromTime(utctime)) + 1,
int(DateFromTime(utctime)),
int(HourFromTime(utctime)),
int(MinFromTime(utctime)),
int(SecFromTime(utctime)),
int(msFromTime(utctime)));
}
/* ES5 B.2.6. */
MOZ_ALWAYS_INLINE bool
date_toGMTString_impl(JSContext *cx, CallArgs args)
@ -2403,7 +2417,6 @@ date_toGMTString_impl(JSContext *cx, CallArgs args)
return true;
}
/* ES5 15.9.5.43. */
static bool
date_toGMTString(JSContext *cx, unsigned argc, Value *vp)
{
@ -2411,6 +2424,7 @@ date_toGMTString(JSContext *cx, unsigned argc, Value *vp)
return CallNonGenericMethod<IsDate, date_toGMTString_impl>(cx, args);
}
/* ES6 draft 2015-01-15 20.3.4.36. */
MOZ_ALWAYS_INLINE bool
date_toISOString_impl(JSContext *cx, CallArgs args)
{
@ -2421,7 +2435,11 @@ date_toISOString_impl(JSContext *cx, CallArgs args)
}
char buf[100];
print_iso_string(buf, sizeof buf, utctime);
int year = int(YearFromTime(utctime));
if (year < 0 || year > 9999)
print_iso_extended_string(buf, sizeof buf, utctime);
else
print_iso_string(buf, sizeof buf, utctime);
JSString *str = JS_NewStringCopyZ(cx, buf);
if (!str)

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

@ -1287,10 +1287,12 @@ void
GCRuntime::finish()
{
/*
* Wait until the background finalization stops and the helper thread
* shuts down before we forcefully release any remaining GC memory.
* Wait until the background finalization and allocation stops and the
* helper thread shuts down before we forcefully release any remaining GC
* memory.
*/
helperState.finish();
allocTask.cancel(GCParallelTask::CancelAndWait);
#ifdef JS_GC_ZEAL
/* Free memory associated with GC verification. */
@ -2957,10 +2959,11 @@ GCRuntime::refillFreeListFromMainThread(JSContext *cx, AllocKind thingKind)
return thing;
// Even if allocateFromArena failed due to OOM, a background
// finalization task may be running (freeing more memory); wait for it
// to finish, then try to allocate again in case it freed up the memory
// we need.
rt->gc.waitBackgroundSweepEnd();
// finalization or allocation task may be running freeing more memory
// or adding more available memory to our free pool; wait for them to
// finish, then try to allocate again in case they made more memory
// available.
rt->gc.waitBackgroundSweepOrAllocEnd();
thing = arenas->allocateFromArena(zone, thingKind, maybeStartBGAlloc);
if (MOZ_LIKELY(thing))

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

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

@ -0,0 +1,53 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
//-----------------------------------------------------------------------------
var BUGNUMBER = 730831;
var summary = 'Date.prototype.toISOString returns an invalid ISO-8601 string';
print(BUGNUMBER + ": " + summary);
function iso(t) {
return new Date(t).toISOString();
}
function utc(year, month, day, hour, minute, second, millis) {
var date = new Date(0);
date.setUTCFullYear(year, month - 1, day);
date.setUTCHours(hour, minute, second, millis);
return date.getTime();
}
// Values around maximum date for simple iso format.
var maxDateSimple = utc(9999, 12, 31, 23, 59, 59, 999);
assertEq(iso(maxDateSimple - 1), "9999-12-31T23:59:59.998Z");
assertEq(iso(maxDateSimple ), "9999-12-31T23:59:59.999Z");
assertEq(iso(maxDateSimple + 1), "+010000-01-01T00:00:00.000Z");
// Values around minimum date for simple iso format.
var minDateSimple = utc(0, 1, 1, 0, 0, 0, 0);
assertEq(iso(minDateSimple - 1), "-000001-12-31T23:59:59.999Z");
assertEq(iso(minDateSimple ), "0000-01-01T00:00:00.000Z");
assertEq(iso(minDateSimple + 1), "0000-01-01T00:00:00.001Z");
// Values around maximum date for extended iso format.
var maxDateExtended = utc(+275760, 9, 13, 0, 0, 0, 0);
assertEq(maxDateExtended, +8.64e15);
assertEq(iso(maxDateExtended - 1), "+275760-09-12T23:59:59.999Z");
assertEq(iso(maxDateExtended ), "+275760-09-13T00:00:00.000Z");
assertThrowsInstanceOf(() => iso(maxDateExtended + 1), RangeError);
// Values around minimum date for extended iso format.
var minDateExtended = utc(-271821, 4, 20, 0, 0, 0, 0);
assertEq(minDateExtended, -8.64e15);
assertThrowsInstanceOf(() => iso(minDateExtended - 1), RangeError);
assertEq(iso(minDateExtended ), "-271821-04-20T00:00:00.000Z");
assertEq(iso(minDateExtended + 1), "-271821-04-20T00:00:00.001Z");
if (typeof reportCompare === "function")
reportCompare(true, true);

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

@ -41,8 +41,10 @@ XPCWrappedNativeScope::ClearInterpositionsObserver::Observe(nsISupports *subject
// may themselves be involved in cycles. We need to drop these strong
// references before the cycle collector shuts down. Otherwise we'll
// leak. This observer always runs before CC shutdown.
if (gInterpositionMap)
if (gInterpositionMap) {
delete gInterpositionMap;
gInterpositionMap = nullptr;
}
nsContentUtils::UnregisterShutdownObserver(this);
return NS_OK;

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

@ -78,6 +78,7 @@ SelectionCarets::SelectionCarets(nsIPresShell* aPresShell)
, mCaretCenterToDownPointOffsetY(0)
, mDragMode(NONE)
, mAsyncPanZoomEnabled(false)
, mInAsyncPanZoomGesture(false)
, mEndCaretVisible(false)
, mStartCaretVisible(false)
, mSelectionVisibleInScrollFrames(true)
@ -1183,6 +1184,7 @@ DispatchScrollViewChangeEvent(nsIPresShell *aPresShell, const dom::ScrollState a
void
SelectionCarets::AsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos)
{
mInAsyncPanZoomGesture = true;
SetVisibility(false);
SELECTIONCARETS_LOG("Dispatch scroll started with position x=%d, y=%d",
@ -1193,6 +1195,7 @@ SelectionCarets::AsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos)
void
SelectionCarets::AsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos)
{
mInAsyncPanZoomGesture = false;
SELECTIONCARETS_LOG("Update selection carets after APZ is stopped!");
UpdateSelectionCarets();
@ -1209,12 +1212,20 @@ SelectionCarets::AsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos)
void
SelectionCarets::ScrollPositionChanged()
{
if (!mAsyncPanZoomEnabled && mVisible) {
SetVisibility(false);
//TODO: handling scrolling for selection bubble when APZ is off
if (mVisible) {
if (!mAsyncPanZoomEnabled) {
SetVisibility(false);
//TODO: handling scrolling for selection bubble when APZ is off
SELECTIONCARETS_LOG("Launch scroll end detector");
LaunchScrollEndDetector();
SELECTIONCARETS_LOG("Launch scroll end detector");
LaunchScrollEndDetector();
} else {
if (!mInAsyncPanZoomGesture) {
UpdateSelectionCarets();
DispatchSelectionStateChangedEvent(GetSelection(),
SelectionState::Updateposition);
}
}
}
}

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

@ -260,6 +260,8 @@ private:
// True if AsyncPanZoom is enabled
bool mAsyncPanZoomEnabled;
// True if AsyncPanZoom is started
bool mInAsyncPanZoomGesture;
bool mEndCaretVisible;
bool mStartCaretVisible;

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

@ -236,6 +236,9 @@ JsepSessionImpl::AddOfferMSectionsByType(SdpMediaSection::MediaType mediatype,
AddLocalSsrcs(*track->mTrack,
&sdp->GetMediaSection(*track->mAssignedMLine));
AddLocalIds(*track->mTrack,
&sdp->GetMediaSection(*track->mAssignedMLine));
}
while (offerToReceive.isSome() && added < *offerToReceive) {
@ -268,6 +271,133 @@ JsepSessionImpl::SetupBundle(Sdp* sdp) const
}
}
void
JsepSessionImpl::SetupMsidSemantic(const std::vector<std::string>& msids,
Sdp* sdp) const
{
if (!msids.empty()) {
UniquePtr<SdpMsidSemanticAttributeList> msidSemantics(
new SdpMsidSemanticAttributeList);
msidSemantics->PushEntry("WMS", msids);
sdp->GetAttributeList().SetAttribute(msidSemantics.release());
}
}
nsresult
JsepSessionImpl::GetIdsFromMsid(const Sdp& sdp,
const SdpMediaSection& msection,
std::string* streamId,
std::string* trackId)
{
if (!sdp.GetAttributeList().HasAttribute(
SdpAttribute::kMsidSemanticAttribute)) {
return NS_ERROR_NOT_AVAILABLE;
}
auto& msidSemantics = sdp.GetAttributeList().GetMsidSemantic().mMsidSemantics;
std::vector<SdpMsidAttributeList::Msid> allMsids;
nsresult rv = GetMsids(msection, &allMsids);
NS_ENSURE_SUCCESS(rv, rv);
bool allMsidsAreWebrtc = false;
std::set<std::string> webrtcMsids;
for (auto i = msidSemantics.begin(); i != msidSemantics.end(); ++i) {
if (i->semantic == "WMS") {
for (auto j = i->msids.begin(); j != i->msids.end(); ++j) {
if (*j == "*") {
allMsidsAreWebrtc = true;
} else {
webrtcMsids.insert(*j);
}
}
break;
}
}
bool found = false;
for (auto i = allMsids.begin(); i != allMsids.end(); ++i) {
if (allMsidsAreWebrtc || webrtcMsids.count(i->identifier)) {
// For now, we assume that there is exactly one streamId/trackId pair
// per m-section. Later on, we'll add handling for multiple remote tracks
// per m-section.
if (!found) {
*streamId = i->identifier;
*trackId = i->appdata;
found = true;
} else if ((*streamId != i->identifier) || (*trackId != i->appdata)) {
// Bail if there are multiple stream/track ids for now
JSEP_SET_ERROR("Found multiple different webrtc msids in m-section "
<< msection.GetLevel() << ". The behavior here is "
"undefined.");
return NS_ERROR_INVALID_ARG;
}
}
}
if (!found) {
return NS_ERROR_NOT_AVAILABLE;
}
return NS_OK;
}
nsresult
JsepSessionImpl::GetMsids(
const SdpMediaSection& msection,
std::vector<SdpMsidAttributeList::Msid>* msids)
{
if (msection.GetAttributeList().HasAttribute(SdpAttribute::kMsidAttribute)) {
*msids = msection.GetAttributeList().GetMsid().mMsids;
}
// Can we find some additional msids in ssrc attributes?
// (Chrome does not put plain-old msid attributes in its SDP)
if (msection.GetAttributeList().HasAttribute(SdpAttribute::kSsrcAttribute)) {
auto& ssrcs = msection.GetAttributeList().GetSsrc().mSsrcs;
for (auto i = ssrcs.begin(); i != ssrcs.end(); ++i) {
if (i->attribute.find("msid:") == 0) {
// Would be nice if SdpSsrcAttributeList could parse out the contained
// attribute, but at least the parse here is simple.
size_t streamIdStart = i->attribute.find_first_not_of(" \t", 5);
// We do not assume the appdata token is here, since this is not
// necessarily a webrtc msid
if (streamIdStart == std::string::npos) {
JSEP_SET_ERROR("Malformed source-level msid attribute: "
<< i->attribute);
return NS_ERROR_INVALID_ARG;
}
size_t streamIdEnd = i->attribute.find_first_of(" \t", streamIdStart);
if (streamIdEnd == std::string::npos) {
streamIdEnd = i->attribute.size();
}
size_t trackIdStart =
i->attribute.find_first_not_of(" \t", streamIdEnd);
if (trackIdStart == std::string::npos) {
trackIdStart = i->attribute.size();
}
size_t trackIdEnd = i->attribute.find_first_of(" \t", trackIdStart);
if (trackIdEnd == std::string::npos) {
trackIdEnd = i->attribute.size();
}
size_t streamIdSize = streamIdEnd - streamIdStart;
size_t trackIdSize = trackIdEnd - trackIdStart;
msids->push_back({i->attribute.substr(streamIdStart, streamIdSize),
i->attribute.substr(trackIdStart, trackIdSize)});
}
}
}
return NS_OK;
}
nsresult
JsepSessionImpl::CreateOffer(const JsepOfferOptions& options,
std::string* offer)
@ -395,6 +525,24 @@ JsepSessionImpl::AddLocalSsrcs(const JsepTrack& track,
}
}
void
JsepSessionImpl::AddLocalIds(const JsepTrack& track,
SdpMediaSection* msection) const
{
if (track.GetMediaType() == SdpMediaSection::kApplication) {
return;
}
UniquePtr<SdpMsidAttributeList> msids(new SdpMsidAttributeList);
if (msection->GetAttributeList().HasAttribute(SdpAttribute::kMsidAttribute)) {
msids->mMsids = msection->GetAttributeList().GetMsid().mMsids;
}
msids->PushEntry(track.GetStreamId(), track.GetTrackId());
msection->GetAttributeList().SetAttribute(msids.release());
}
JsepCodecDescription*
JsepSessionImpl::FindMatchingCodec(const std::string& fmt,
const SdpMediaSection& msection) const
@ -663,6 +811,8 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options,
AddLocalSsrcs(*track->mTrack, msection);
AddLocalIds(*track->mTrack, msection);
localDirection = SdpDirectionAttribute::kSendonly;
track->mAssignedMLine = Some(mlineIndex);
found = true;
@ -1363,6 +1513,8 @@ JsepSessionImpl::ParseSdp(const std::string& sdp, UniquePtr<Sdp>* parsedp)
return NS_ERROR_INVALID_ARG;
}
std::set<std::string> trackIds;
for (size_t i = 0; i < parsed->GetMediaSectionCount(); ++i) {
if (parsed->GetMediaSection(i).GetPort() == 0) {
// Disabled, let this stuff slide.
@ -1404,6 +1556,26 @@ JsepSessionImpl::ParseSdp(const std::string& sdp, UniquePtr<Sdp>* parsedp)
return NS_ERROR_INVALID_ARG;
}
}
std::string streamId;
std::string trackId;
nsresult rv = GetIdsFromMsid(*parsed,
parsed->GetMediaSection(i),
&streamId,
&trackId);
if (NS_SUCCEEDED(rv)) {
if (trackIds.count(trackId)) {
JSEP_SET_ERROR("track id:" << trackId
<< " appears in more than one m-section at level " << i);
return NS_ERROR_INVALID_ARG;
}
trackIds.insert(trackId);
} else if (rv != NS_ERROR_NOT_AVAILABLE) {
// Error has already been set
return rv;
}
}
*parsedp = Move(parsed);
@ -1462,7 +1634,7 @@ JsepSessionImpl::SetRemoteTracksFromDescription(const Sdp& remoteDescription)
// TODO(bug 1017888): Suppress new track creation on renegotiation
// of existing tracks.
if (direction & SdpDirectionAttribute::kSendFlag) {
nsresult rv = CreateReceivingTrack(i, msection);
nsresult rv = CreateReceivingTrack(i, remoteDescription, msection);
NS_ENSURE_SUCCESS(rv, rv);
}
}
@ -1521,20 +1693,31 @@ JsepSessionImpl::ValidateLocalDescription(const Sdp& description)
nsresult
JsepSessionImpl::CreateReceivingTrack(size_t mline,
const Sdp& sdp,
const SdpMediaSection& msection)
{
std::string streamId;
std::string trackId;
// Generate random track ids.
// TODO(bug 1095218): Pull track and stream IDs out of SDP if available.
if (!mUuidGen->Generate(&trackId)) {
JSEP_SET_ERROR("Failed to generate UUID for JsepTrack");
return NS_ERROR_FAILURE;
nsresult rv = GetIdsFromMsid(sdp, msection, &streamId, &trackId);
if (NS_FAILED(rv)) {
if (rv != NS_ERROR_NOT_AVAILABLE) {
// Malformed ssrc attribute, probably
return rv;
}
streamId = mDefaultRemoteStreamId;
// Generate random track ids.
if (!mUuidGen->Generate(&trackId)) {
JSEP_SET_ERROR("Failed to generate UUID for JsepTrack");
return NS_ERROR_FAILURE;
}
}
JsepTrack* remote = new JsepTrack(msection.GetMediaType(),
mDefaultRemoteStreamId,
streamId,
trackId,
JsepTrack::kJsepTrackReceiving);
@ -1590,6 +1773,12 @@ JsepSessionImpl::CreateGenericSDP(UniquePtr<Sdp>* sdpp)
iceOpts->PushEntry("trickle");
sdp->GetAttributeList().SetAttribute(iceOpts);
// This assumes content doesn't add a bunch of msid attributes with a
// different semantic in mind.
std::vector<std::string> msids;
msids.push_back("*");
SetupMsidSemantic(msids, sdp.get());
*sdpp = Move(sdp);
return NS_OK;
}

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

@ -210,6 +210,7 @@ private:
void AddExtmap(SdpMediaSection* msection) const;
void AddMid(const std::string& mid, SdpMediaSection* msection) const;
void AddLocalSsrcs(const JsepTrack& track, SdpMediaSection* msection) const;
void AddLocalIds(const JsepTrack& track, SdpMediaSection* msection) const;
JsepCodecDescription* FindMatchingCodec(
const std::string& pt,
const SdpMediaSection& msection) const;
@ -231,7 +232,9 @@ private:
nsresult ValidateLocalDescription(const Sdp& description);
nsresult SetRemoteTracksFromDescription(const Sdp& remoteDescription);
// Non-const because we use our Uuid generator
nsresult CreateReceivingTrack(size_t mline, const SdpMediaSection& msection);
nsresult CreateReceivingTrack(size_t mline,
const Sdp& sdp,
const SdpMediaSection& msection);
nsresult HandleNegotiatedSession(const UniquePtr<Sdp>& local,
const UniquePtr<Sdp>& remote);
nsresult DetermineSendingDirection(SdpDirectionAttribute::Direction offer,
@ -244,6 +247,13 @@ private:
Maybe<size_t> offerToReceive,
Sdp* sdp);
void SetupBundle(Sdp* sdp) const;
void SetupMsidSemantic(const std::vector<std::string>& msids, Sdp* sdp) const;
nsresult GetIdsFromMsid(const Sdp& sdp,
const SdpMediaSection& msection,
std::string* streamId,
std::string* trackId);
nsresult GetMsids(const SdpMediaSection& msection,
std::vector<SdpMsidAttributeList::Msid>* msids);
nsresult CreateOfferMSection(SdpMediaSection::MediaType type,
SdpDirectionAttribute::Direction direction,
SdpMediaSection::Protocol proto,

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

@ -547,17 +547,13 @@ nsresult MediaPipelineTransmit::Init() {
return MediaPipeline::Init();
}
void MediaPipelineTransmit::AttachToTrack(TrackID track_id) {
char track_id_string[11];
void MediaPipelineTransmit::AttachToTrack(const std::string& track_id) {
ASSERT_ON_THREAD(main_thread_);
// We can replace this when we are allowed to do streams or std::to_string
PR_snprintf(track_id_string, sizeof(track_id_string), "%d", track_id);
description_ = pc_ + "| ";
description_ += conduit_->type() == MediaSessionConduit::AUDIO ?
"Transmit audio[" : "Transmit video[";
description_ += track_id_string;
description_ += track_id;
description_ += "]";
// TODO(ekr@rtfm.com): Check for errors
@ -613,10 +609,11 @@ nsresult MediaPipelineTransmit::TransportReady_s(TransportInfo &info) {
}
nsresult MediaPipelineTransmit::ReplaceTrack(DOMMediaStream *domstream,
TrackID track_id) {
const std::string& track_id) {
// MainThread, checked in calls we make
MOZ_MTLOG(ML_DEBUG, "Reattaching pipeline to stream "
<< static_cast<void *>(domstream->GetStream()) << " conduit type=" <<
MOZ_MTLOG(ML_DEBUG, "Reattaching pipeline " << description_ << " to stream "
<< static_cast<void *>(domstream->GetStream())
<< " track " << track_id << " conduit type=" <<
(conduit_->type() == MediaSessionConduit::AUDIO ?"audio":"video"));
if (domstream_) { // may be excessive paranoia
@ -624,7 +621,7 @@ nsresult MediaPipelineTransmit::ReplaceTrack(DOMMediaStream *domstream,
}
domstream_ = domstream; // Detach clears it
stream_ = domstream->GetStream();
//track_id_ = track_id; not threadsafe to change this; and we don't need to
track_id_ = track_id;
AttachToTrack(track_id);
return NS_OK;
}
@ -1165,15 +1162,11 @@ void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk(
#endif
nsresult MediaPipelineReceiveAudio::Init() {
char track_id_string[11];
ASSERT_ON_THREAD(main_thread_);
MOZ_MTLOG(ML_DEBUG, __FUNCTION__);
// We can replace this when we are allowed to do streams or std::to_string
PR_snprintf(track_id_string, sizeof(track_id_string), "%d", track_id_);
description_ = pc_ + "| Receive audio[";
description_ += track_id_string;
description_ += track_id_;
description_ += "]";
listener_->AddSelf(new AudioSegment());
@ -1336,15 +1329,11 @@ NotifyPull(MediaStreamGraph* graph, StreamTime desired_time) {
}
nsresult MediaPipelineReceiveVideo::Init() {
char track_id_string[11];
ASSERT_ON_THREAD(main_thread_);
MOZ_MTLOG(ML_DEBUG, __FUNCTION__);
// We can replace this when we are allowed to do streams or std::to_string
PR_snprintf(track_id_string, sizeof(track_id_string), "%d", track_id_);
description_ = pc_ + "| Receive video[";
description_ += track_id_string;
description_ += track_id_;
description_ += "]";
#ifdef MOZILLA_INTERNAL_API

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

@ -77,7 +77,7 @@ class MediaPipeline : public sigslot::has_slots<> {
nsCOMPtr<nsIEventTarget> main_thread,
nsCOMPtr<nsIEventTarget> sts_thread,
MediaStream *stream,
TrackID track_id,
const std::string& track_id,
int level,
RefPtr<MediaSessionConduit> conduit,
RefPtr<TransportFlow> rtp_transport,
@ -130,9 +130,9 @@ class MediaPipeline : public sigslot::has_slots<> {
nsAutoPtr<MediaPipelineFilter> filter);
virtual Direction direction() const { return direction_; }
virtual TrackID trackid() const { return track_id_; }
virtual const std::string& trackid() const { return track_id_; }
virtual int level() const { return level_; }
virtual bool IsVideo() const { return false; }
virtual bool IsVideo() const = 0;
bool IsDoingRtcpMux() const {
return (rtp_.type_ == MUX);
@ -233,10 +233,10 @@ class MediaPipeline : public sigslot::has_slots<> {
// Written on the main thread.
// Used on STS and MediaStreamGraph threads.
// May be changed by rtpSender.replaceTrack()
TrackID track_id_; // The track on the stream.
std::string track_id_; // The track on the stream.
// Written and used as with the stream_;
// Not used outside initialization in MediaPipelineTransmit
int level_; // The m-line index (starting at 1, to match convention)
int level_; // The m-line index (starting at 0, to match convention)
RefPtr<MediaSessionConduit> conduit_; // Our conduit. Written on the main
// thread. Read on STS thread.
@ -352,6 +352,7 @@ public:
nsCOMPtr<nsIEventTarget> main_thread,
nsCOMPtr<nsIEventTarget> sts_thread,
DOMMediaStream *domstream,
const std::string& track_id,
int level,
bool is_video,
RefPtr<MediaSessionConduit> conduit,
@ -359,7 +360,7 @@ public:
RefPtr<TransportFlow> rtcp_transport,
nsAutoPtr<MediaPipelineFilter> filter) :
MediaPipeline(pc, TRANSMIT, main_thread, sts_thread,
domstream->GetStream(), TRACK_INVALID, level,
domstream->GetStream(), track_id, level,
conduit, rtp_transport, rtcp_transport, filter),
listener_(new PipelineListener(conduit)),
domstream_(domstream),
@ -369,7 +370,7 @@ public:
// Initialize (stuff here may fail)
virtual nsresult Init() MOZ_OVERRIDE;
virtual void AttachToTrack(TrackID track_id);
virtual void AttachToTrack(const std::string& track_id);
// Index used to refer to this before we know the TrackID
// Note: unlike MediaPipeline::trackid(), this is threadsafe
@ -403,7 +404,7 @@ public:
// track to be part of a different stream (since we don't support
// multiple tracks of a type in a stream yet). bug 1056650
virtual nsresult ReplaceTrack(DOMMediaStream *domstream,
TrackID track_id);
const std::string& track_id);
// Separate class to allow ref counting
@ -518,7 +519,7 @@ class MediaPipelineReceive : public MediaPipeline {
nsCOMPtr<nsIEventTarget> main_thread,
nsCOMPtr<nsIEventTarget> sts_thread,
MediaStream *stream,
TrackID track_id,
const std::string& track_id,
int level,
RefPtr<MediaSessionConduit> conduit,
RefPtr<TransportFlow> rtp_transport,
@ -547,17 +548,23 @@ class MediaPipelineReceiveAudio : public MediaPipelineReceive {
nsCOMPtr<nsIEventTarget> main_thread,
nsCOMPtr<nsIEventTarget> sts_thread,
MediaStream *stream,
TrackID track_id,
// This comes from an msid attribute. Everywhere
// but MediaStreamGraph uses this.
const std::string& media_stream_track_id,
// This is an integer identifier that is only
// unique within a single DOMMediaStream, which is
// used by MediaStreamGraph
TrackID numeric_track_id,
int level,
RefPtr<AudioSessionConduit> conduit,
RefPtr<TransportFlow> rtp_transport,
RefPtr<TransportFlow> rtcp_transport,
nsAutoPtr<MediaPipelineFilter> filter) :
MediaPipelineReceive(pc, main_thread, sts_thread,
stream, track_id, level, conduit, rtp_transport,
rtcp_transport, filter),
stream, media_stream_track_id, level, conduit,
rtp_transport, rtcp_transport, filter),
listener_(new PipelineListener(stream->AsSourceStream(),
track_id, conduit)) {
numeric_track_id, conduit)) {
}
virtual void DetachMediaStream() MOZ_OVERRIDE {
@ -568,6 +575,7 @@ class MediaPipelineReceiveAudio : public MediaPipelineReceive {
}
virtual nsresult Init() MOZ_OVERRIDE;
virtual bool IsVideo() const MOZ_OVERRIDE { return false; }
private:
// Separate class to allow ref counting
@ -610,17 +618,24 @@ class MediaPipelineReceiveVideo : public MediaPipelineReceive {
nsCOMPtr<nsIEventTarget> main_thread,
nsCOMPtr<nsIEventTarget> sts_thread,
MediaStream *stream,
TrackID track_id,
// This comes from an msid attribute. Everywhere
// but MediaStreamGraph uses this.
const std::string& media_stream_track_id,
// This is an integer identifier that is only
// unique within a single DOMMediaStream, which is
// used by MediaStreamGraph
TrackID numeric_track_id,
int level,
RefPtr<VideoSessionConduit> conduit,
RefPtr<TransportFlow> rtp_transport,
RefPtr<TransportFlow> rtcp_transport,
nsAutoPtr<MediaPipelineFilter> filter) :
MediaPipelineReceive(pc, main_thread, sts_thread,
stream, track_id, level, conduit, rtp_transport,
rtcp_transport, filter),
stream, media_stream_track_id, level, conduit,
rtp_transport, rtcp_transport, filter),
renderer_(new PipelineRenderer(this)),
listener_(new PipelineListener(stream->AsSourceStream(), track_id)) {
listener_(new PipelineListener(stream->AsSourceStream(),
numeric_track_id)) {
}
// Called on the main thread.
@ -638,6 +653,7 @@ class MediaPipelineReceiveVideo : public MediaPipelineReceive {
}
virtual nsresult Init() MOZ_OVERRIDE;
virtual bool IsVideo() const MOZ_OVERRIDE { return true; }
private:
class PipelineRenderer : public VideoRenderer {

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

@ -16,6 +16,7 @@
#include "signaling/src/jsep/JsepTransport.h"
#ifdef MOZILLA_INTERNAL_API
#include "MediaStreamTrack.h"
#include "nsIPrincipal.h"
#include "nsIDocument.h"
#include "mozilla/Preferences.h"
@ -338,14 +339,18 @@ MediaPipelineFactory::CreateMediaPipelineReceiving(
}
}
// We need to choose a numeric track id for MediaStreamGraph to use. Must be
// unique within the MediaStream, so level + 1 should be fine (cannot use 0).
TrackID numericTrackId = aTrackPair.mLevel + 1;
if (aTrack.GetMediaType() == SdpMediaSection::kAudio) {
pipeline = new MediaPipelineReceiveAudio(
mPC->GetHandle(),
mPC->GetMainThread().get(),
mPC->GetSTSThread(),
stream->GetMediaStream()->GetStream(),
// Use the level + 1 as the track id. 0 is forbidden
aTrackPair.mLevel + 1,
aTrack.GetTrackId(),
numericTrackId,
aTrackPair.mLevel,
static_cast<AudioSessionConduit*>(aConduit.get()), // Ugly downcast.
aRtpFlow,
@ -358,8 +363,8 @@ MediaPipelineFactory::CreateMediaPipelineReceiving(
mPC->GetMainThread().get(),
mPC->GetSTSThread(),
stream->GetMediaStream()->GetStream(),
// Use the level + 1 as the track id. 0 is forbidden
aTrackPair.mLevel + 1,
aTrack.GetTrackId(),
numericTrackId,
aTrackPair.mLevel,
static_cast<VideoSessionConduit*>(aConduit.get()), // Ugly downcast.
aRtpFlow,
@ -377,7 +382,15 @@ MediaPipelineFactory::CreateMediaPipelineReceiving(
return rv;
}
stream->StorePipeline(aTrackPair.mLevel, SdpMediaSection::kVideo, pipeline);
rv = stream->StorePipeline(aTrack.GetTrackId(),
RefPtr<MediaPipeline>(pipeline));
if (NS_FAILED(rv)) {
MOZ_MTLOG(ML_ERROR, "Couldn't store receiving pipeline " <<
static_cast<unsigned>(rv));
return rv;
}
stream->SyncPipeline(pipeline);
return NS_OK;
}
@ -415,10 +428,17 @@ MediaPipelineFactory::CreateMediaPipelineSending(
// Now we have all the pieces, create the pipeline
RefPtr<MediaPipelineTransmit> pipeline = new MediaPipelineTransmit(
mPC->GetHandle(), mPC->GetMainThread().get(), mPC->GetSTSThread(),
stream->GetMediaStream(), aTrackPair.mLevel,
aTrack.GetMediaType() == SdpMediaSection::kVideo, aConduit, aRtpFlow,
aRtcpFlow, filter);
mPC->GetHandle(),
mPC->GetMainThread().get(),
mPC->GetSTSThread(),
stream->GetMediaStream(),
aTrack.GetTrackId(),
aTrackPair.mLevel,
aTrack.GetMediaType() == SdpMediaSection::kVideo,
aConduit,
aRtpFlow,
aRtcpFlow,
filter);
#ifdef MOZILLA_INTERNAL_API
// implement checking for peerIdentity (where failure == black/silence)
@ -438,7 +458,13 @@ MediaPipelineFactory::CreateMediaPipelineSending(
return rv;
}
stream->StorePipeline(aTrackPair.mLevel, pipeline);
rv = stream->StorePipeline(aTrack.GetTrackId(),
RefPtr<MediaPipeline>(pipeline));
if (NS_FAILED(rv)) {
MOZ_MTLOG(ML_ERROR, "Couldn't store receiving pipeline " <<
static_cast<unsigned>(rv));
return rv;
}
return NS_OK;
}

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

@ -178,10 +178,18 @@ private:
class TracksAvailableCallback : public DOMMediaStream::OnTracksAvailableCallback
{
public:
TracksAvailableCallback(DOMMediaStream::TrackTypeHints aTrackTypeHints,
TracksAvailableCallback(const std::list<std::string>& audioTrackIds,
const std::list<std::string>& videoTrackIds,
const std::set<std::string>& preexistingTrackIds,
nsRefPtr<PeerConnectionObserver> aObserver)
: DOMMediaStream::OnTracksAvailableCallback(aTrackTypeHints)
, mObserver(aObserver) {}
: DOMMediaStream::OnTracksAvailableCallback(
// Once DOMMediaStream can handle more than one of each, this will change.
(audioTrackIds.empty() ? 0 : DOMMediaStream::HINT_CONTENTS_AUDIO) |
(videoTrackIds.empty() ? 0 : DOMMediaStream::HINT_CONTENTS_VIDEO))
, mObserver(aObserver)
, mAudioTrackIds(audioTrackIds)
, mVideoTrackIds(videoTrackIds)
, mPreexistingTrackIds(preexistingTrackIds) {}
virtual void NotifyTracksAvailable(DOMMediaStream* aStream) MOZ_OVERRIDE
{
@ -197,22 +205,68 @@ public:
nsTArray<nsRefPtr<MediaStreamTrack>> tracks;
aStream->GetTracks(tracks);
for (uint32_t i = 0; i < tracks.Length(); i++) {
for (size_t i = 0; i < tracks.Length(); i++) {
if (mPreexistingTrackIds.count(
PeerConnectionImpl::GetTrackId(*tracks[i]))) {
continue;
}
AssignNextIdToTrack(tracks[i]);
JSErrorResult rv;
mObserver->OnAddTrack(*tracks[i], rv);
CSFLogInfo(logTag, "Calling OnAddTrack(%s)",
PeerConnectionImpl::GetTrackId(*tracks[i]).c_str());
if (rv.Failed()) {
CSFLogError(logTag, ": OnAddTrack(%d) failed! Error: %u", i,
static_cast<uint32_t>(rv.ErrorCode()));
CSFLogError(logTag, ": OnAddTrack(%u) failed! Error: %u",
static_cast<unsigned>(i),
static_cast<unsigned>(rv.ErrorCode()));
}
}
JSErrorResult rv;
CSFLogInfo(logTag, "Calling OnAddStream");
mObserver->OnAddStream(*aStream, rv);
if (rv.Failed()) {
CSFLogError(logTag, ": OnAddStream() failed! Error: %u", static_cast<uint32_t>(rv.ErrorCode()));
CSFLogError(logTag, ": OnAddStream() failed! Error: %u",
static_cast<unsigned>(rv.ErrorCode()));
}
if (!mAudioTrackIds.empty() || !mVideoTrackIds.empty()) {
CSFLogError(logTag, "Failed to assign %u audio and %u video tracks!",
static_cast<unsigned>(mAudioTrackIds.size()),
static_cast<unsigned>(mVideoTrackIds.size()));
}
}
void AssignNextIdToTrack(MediaStreamTrack* track)
{
std::list<std::string>* trackIds;
if (track->AsAudioStreamTrack()) {
trackIds = &mAudioTrackIds;
} else if (track->AsVideoStreamTrack()) {
trackIds = &mVideoTrackIds;
} else {
MOZ_ASSERT(false, "Track is neither an AudioStreamTrack nor "
"VideoStreamTrack");
return;
}
if (trackIds->empty()) {
MOZ_ASSERT(false, "Too many new MediaStreamTracks were created");
return;
}
track->AssignId(NS_ConvertUTF8toUTF16(trackIds->front().c_str()));
trackIds->pop_front();
}
private:
nsRefPtr<PeerConnectionObserver> mObserver;
std::list<std::string> mAudioTrackIds;
std::list<std::string> mVideoTrackIds;
const std::set<std::string> mPreexistingTrackIds;
};
#endif
@ -1592,15 +1646,11 @@ PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP)
} else {
// Add the tracks. This code is pretty complicated because the tracks
// come in arbitrary orders and we want to group them by streamId.
// We go through all the tracks and then for each track that represents
// a new stream id, go through the rest of the tracks and deal with
// them at once.
size_t numTracks = mJsepSession->GetRemoteTrackCount();
MOZ_ASSERT(numTracks <= 3);
bool hasAudio = false;
bool hasVideo = false;
std::set<std::string> streamsToNotify;
// Group tracks by stream id
std::map<std::string, std::vector<RefPtr<JsepTrack>>> tracksByStreamId;
for (size_t i = 0; i < numTracks; ++i) {
RefPtr<JsepTrack> track;
nrv = mJsepSession->GetRemoteTrack(i, &track);
@ -1616,10 +1666,17 @@ PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP)
continue;
}
tracksByStreamId[track->GetStreamId()].push_back(track);
}
for (auto i = tracksByStreamId.begin(); i != tracksByStreamId.end(); ++i) {
std::string streamId = i->first;
std::vector<RefPtr<JsepTrack>>& tracks = i->second;
nsRefPtr<RemoteSourceStreamInfo> info =
mMedia->GetRemoteStreamById(track->GetStreamId());
mMedia->GetRemoteStreamById(streamId);
if (!info) {
nsresult nrv = CreateRemoteSourceStreamInfo(&info, track->GetStreamId());
nsresult nrv = CreateRemoteSourceStreamInfo(&info, streamId);
if (NS_FAILED(nrv)) {
pco->OnSetRemoteDescriptionError(
kInternalError,
@ -1638,31 +1695,35 @@ PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP)
}
}
streamsToNotify.insert(track->GetStreamId());
// TODO(bug 1017888): Only get new tracks for renegotiation
std::list<std::string> newAudioTrackIds;
std::list<std::string> newVideoTrackIds;
// TODO(bug 1017888): Fill in for renegotiation
std::set<std::string> preexistingTrackIds;
for (auto j = tracks.begin(); j != tracks.end(); ++j) {
RefPtr<JsepTrack> track = *j;
if (track->GetMediaType() == SdpMediaSection::kAudio) {
info->AddTrack(track->GetTrackId());
newAudioTrackIds.push_back(track->GetTrackId());
} else if (track->GetMediaType() == SdpMediaSection::kVideo) {
info->AddTrack(track->GetTrackId());
newVideoTrackIds.push_back(track->GetTrackId());
} else {
MOZ_ASSERT(false);
continue;
}
if (track->GetMediaType() == mozilla::SdpMediaSection::kAudio) {
MOZ_ASSERT(!hasAudio);
(void)hasAudio;
hasAudio = true;
info->mTrackTypeHints |= DOMMediaStream::HINT_CONTENTS_AUDIO;
} else if (track->GetMediaType() == mozilla::SdpMediaSection::kVideo) {
MOZ_ASSERT(!hasVideo);
(void)hasVideo;
hasVideo = true;
info->mTrackTypeHints |= DOMMediaStream::HINT_CONTENTS_VIDEO;
}
}
for (auto i = streamsToNotify.begin(); i != streamsToNotify.end(); ++i) {
// Now that the streams are all set up, notify about track availability.
// TODO(bug 1017888): Suppress on renegotiation when no change.
nsRefPtr<RemoteSourceStreamInfo> info =
mMedia->GetRemoteStreamById(*i);
MOZ_ASSERT(info);
#ifdef MOZILLA_INTERNAL_API
TracksAvailableCallback* tracksAvailableCallback =
new TracksAvailableCallback(info->mTrackTypeHints, pco);
new TracksAvailableCallback(newAudioTrackIds,
newVideoTrackIds,
preexistingTrackIds,
pco);
info->GetMediaStream()->OnTracksAvailable(tracksAvailableCallback);
#else
pco->OnAddStream(info->GetMediaStream(), jrv);
@ -1873,6 +1934,18 @@ PeerConnectionImpl::PrincipalChanged(DOMMediaStream* aMediaStream) {
}
#endif
std::string
PeerConnectionImpl::GetTrackId(const MediaStreamTrack& aTrack)
{
#ifdef MOZILLA_INTERNAL_API
nsString wideTrackId;
aTrack.GetId(wideTrackId);
return NS_ConvertUTF16toUTF8(wideTrackId).get();
#else
return aTrack.GetId();
#endif
}
nsresult
PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
const Sequence<OwningNonNull<DOMMediaStream>>& aStreams)
@ -1894,48 +1967,28 @@ PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
CSFLogError(logTag, "%s: Track is not in stream", __FUNCTION__);
return NS_ERROR_FAILURE;
}
uint32_t hints = aMediaStream.GetHintContents() &
((aTrack.AsAudioStreamTrack()? DOMMediaStream::HINT_CONTENTS_AUDIO : 0) |
(aTrack.AsVideoStreamTrack()? DOMMediaStream::HINT_CONTENTS_VIDEO : 0));
// XXX Remove this check once addStream has an error callback
// available and/or we have plumbing to handle multiple
// local audio streams. bug 1056650
if ((hints & DOMMediaStream::HINT_CONTENTS_AUDIO) &&
mNumAudioStreams > 0) {
CSFLogError(logTag, "%s: Only one local audio stream is supported for now",
__FUNCTION__);
return NS_ERROR_FAILURE;
}
// XXX Remove this check once addStream has an error callback
// available and/or we have plumbing to handle multiple
// local video streams. bug 1056650
if ((hints & DOMMediaStream::HINT_CONTENTS_VIDEO) &&
mNumVideoStreams > 0) {
CSFLogError(logTag, "%s: Only one local video stream is supported for now",
__FUNCTION__);
return NS_ERROR_FAILURE;
}
uint32_t num = mMedia->LocalStreamsLength();
std::string streamId;
// TODO(bug 1089798): These ids should really come from the MS.
nsresult res = mMedia->AddStream(&aMediaStream, hints, &streamId);
std::string trackId = PeerConnectionImpl::GetTrackId(aTrack);
// TODO(bug 1089798): streamId should really come from the MS.
nsresult res = mMedia->AddTrack(&aMediaStream, &streamId, trackId);
if (NS_FAILED(res)) {
return res;
}
CSFLogDebug(logTag, "Added track (%s) to stream %p",
trackId.c_str(), &aMediaStream);
if (num != mMedia->LocalStreamsLength()) {
aMediaStream.AddPrincipalChangeObserver(this);
}
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
if (aTrack.AsAudioStreamTrack()) {
res = mJsepSession->AddTrack(new JsepTrack(
mozilla::SdpMediaSection::kAudio,
streamId,
"audio_track_id",
trackId,
JsepTrack::kJsepTrackSending));
if (NS_FAILED(res)) {
std::string errorString = mJsepSession->GetLastError();
@ -1946,11 +1999,19 @@ PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
mNumAudioStreams++;
}
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
if (aTrack.AsVideoStreamTrack()) {
#ifdef MOZILLA_INTERNAL_API
if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
// Before this code was moved, this would silently ignore just like it
// does now. Is this actually what we want to do?
return NS_OK;
}
#endif
res = mJsepSession->AddTrack(new JsepTrack(
mozilla::SdpMediaSection::kVideo,
streamId,
"video_track_id",
trackId,
JsepTrack::kJsepTrackSending));
if (NS_FAILED(res)) {
std::string errorString = mJsepSession->GetLastError();
@ -1975,6 +2036,15 @@ PeerConnectionImpl::ReplaceTrack(MediaStreamTrack& aThisTrack,
DOMMediaStream& aStream) {
PC_AUTO_ENTER_API_CALL(true);
JSErrorResult jrv;
nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
if (!pco) {
return NS_ERROR_UNEXPECTED;
}
std::string origTrackId = PeerConnectionImpl::GetTrackId(aThisTrack);
std::string newTrackId = PeerConnectionImpl::GetTrackId(aWithTrack);
// TODO: Do an aStream.HasTrack() check on both track args someday.
//
// The proposed API will be that both tracks must already be in the same
@ -1982,9 +2052,15 @@ PeerConnectionImpl::ReplaceTrack(MediaStreamTrack& aThisTrack,
// track per type, we allow replacement with an outside track not already
// in the same stream. This works because sync happens receiver-side and
// timestamps are tied to capture.
//
// Since a track may be replaced more than once, the track being replaced
// may not be in the stream either, so we check neither arg right now.
if (!aStream.HasTrack(aThisTrack)) {
CSFLogError(logTag, "Track to replace (%s) is not in stream",
origTrackId.c_str());
pco->OnReplaceTrackError(kInvalidMediastreamTrack,
ObString("Track to replace is not in stream"),
jrv);
return NS_OK;
}
// XXX This MUST be addressed when we add multiple tracks of a type!!
// This is needed because the track IDs used by MSG are from TrackUnion
@ -1995,41 +2071,38 @@ PeerConnectionImpl::ReplaceTrack(MediaStreamTrack& aThisTrack,
// TrackUnionStream's TrackID's, this value won't currently match what is used in
// MediaPipelineTransmit. Bug 1056652
// TrackID thisID = aThisTrack.GetTrackID();
TrackID withID = aWithTrack.GetTrackID();
//
bool success = false;
for(uint32_t i = 0; i < media()->LocalStreamsLength(); ++i) {
LocalSourceStreamInfo *info = media()->GetLocalStreamByIndex(i);
// XXX use type instead of TrackID - bug 1056650
int pipeline = info->HasTrackType(&aStream, !!(aThisTrack.AsVideoStreamTrack()));
if (pipeline >= 0) {
// XXX GetStream() will likely be invalid once a track can be in more than one
info->ReplaceTrack(pipeline, aWithTrack.GetStream(), withID);
success = true;
break;
}
}
if (!success) {
return NS_ERROR_FAILURE;
nsRefPtr<LocalSourceStreamInfo> info =
media()->GetLocalStreamByDomStream(aStream);
if (!info || !info->HasTrack(origTrackId)) {
CSFLogError(logTag, "Track to replace (%s) was never added",
origTrackId.c_str());
pco->OnReplaceTrackError(kInvalidMediastreamTrack,
ObString("Track to replace was never added"),
jrv);
return NS_OK;
}
nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
if (!pco) {
return NS_ERROR_UNEXPECTED;
}
JSErrorResult rv;
if (success) {
pco->OnReplaceTrackSuccess(rv);
} else {
nsresult rv =
info->ReplaceTrack(origTrackId, aWithTrack.GetStream(), newTrackId);
if (NS_FAILED(rv)) {
CSFLogError(logTag, "Failed to replace track (%s)",
origTrackId.c_str());
pco->OnReplaceTrackError(kInternalError,
ObString("Failed to replace track"),
rv);
jrv);
return NS_OK;
}
if (rv.Failed()) {
pco->OnReplaceTrackSuccess(jrv);
if (jrv.Failed()) {
CSFLogError(logTag, "Error firing replaceTrack callback");
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
@ -2674,16 +2747,19 @@ PeerConnectionImpl::BuildStatsQuery_m(
// Gather up pipelines from mMedia so they may be inspected on STS
std::string trackId;
if (aSelector) {
trackId = PeerConnectionImpl::GetTrackId(*aSelector);
}
for (int i = 0, len = mMedia->LocalStreamsLength(); i < len; i++) {
auto& pipelines = mMedia->GetLocalStreamByIndex(i)->GetPipelines();
if (aSelector) {
if (mMedia->GetLocalStreamByIndex(i)->GetMediaStream()->
HasTrack(*aSelector)) {
// XXX use type instead of TrackID - bug 1056650
for (auto it = pipelines.begin(); it != pipelines.end(); ++it) {
if (it->second->IsVideo() == !!aSelector->AsVideoStreamTrack()) {
query->pipelines.AppendElement(it->second);
}
auto it = pipelines.find(trackId);
if (it != pipelines.end()) {
query->pipelines.AppendElement(it->second);
}
}
} else {
@ -2698,10 +2774,9 @@ PeerConnectionImpl::BuildStatsQuery_m(
if (aSelector) {
if (mMedia->GetRemoteStreamByIndex(i)->
GetMediaStream()->HasTrack(*aSelector)) {
for (auto it = pipelines.begin(); it != pipelines.end(); ++it) {
if (it->second->trackid() == aSelector->GetTrackID()) {
query->pipelines.AppendElement(it->second);
}
auto it = pipelines.find(trackId);
if (it != pipelines.end()) {
query->pipelines.AppendElement(it->second);
}
}
} else {
@ -2842,7 +2917,7 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) {
NS_LITERAL_STRING("audio") : NS_LITERAL_STRING("video");
nsString idstr = mediaType;
idstr.AppendLiteral("_");
idstr.AppendInt(mp.trackid());
idstr.AppendInt(mp.level());
// Gather pipeline stats.
switch (mp.direction()) {

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

@ -601,6 +601,8 @@ public:
virtual void PrincipalChanged(DOMMediaStream* aMediaStream) MOZ_OVERRIDE;
#endif
static std::string GetTrackId(const dom::MediaStreamTrack& track);
private:
virtual ~PeerConnectionImpl();
PeerConnectionImpl(const PeerConnectionImpl&rhs);

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

@ -43,144 +43,46 @@ using namespace mozilla::dom;
namespace mozilla {
static const char* logTag = "PeerConnectionMedia";
static const mozilla::TrackID TRACK_AUDIO = 0;
static const mozilla::TrackID TRACK_VIDEO = 1;
/* If the ExpectAudio hint is on we will add a track at the default first
* audio track ID (0)
* FIX - Do we need to iterate over the tracks instead of taking these hints?
*/
void
LocalSourceStreamInfo::ExpectAudio(const mozilla::TrackID aID)
{
mAudioTracks.AppendElement(aID);
}
void
LocalSourceStreamInfo::RemoveAudio(const mozilla::TrackID aID)
{
mAudioTracks.RemoveElement(aID);
}
// If the ExpectVideo hint is on we will add a track at the default first
// video track ID (1).
void
LocalSourceStreamInfo::ExpectVideo(const mozilla::TrackID aID)
{
mVideoTracks.AppendElement(aID);
}
void
LocalSourceStreamInfo::RemoveVideo(const mozilla::TrackID aID)
{
mVideoTracks.RemoveElement(aID);
}
unsigned
LocalSourceStreamInfo::AudioTrackCount()
{
return mAudioTracks.Length();
}
unsigned
LocalSourceStreamInfo::VideoTrackCount()
{
return mVideoTracks.Length();
}
void LocalSourceStreamInfo::DetachTransport_s()
{
ASSERT_ON_THREAD(mParent->GetSTSThread());
// walk through all the MediaPipelines and call the shutdown
// functions for transport. Must be on the STS thread.
for (std::map<int, mozilla::RefPtr<mozilla::MediaPipeline> >::iterator it =
mPipelines.begin(); it != mPipelines.end();
++it) {
it->second->ShutdownTransport_s();
}
}
void LocalSourceStreamInfo::DetachMedia_m()
{
ASSERT_ON_THREAD(mParent->GetMainThread());
// walk through all the MediaPipelines and call the shutdown
// functions. Must be on the main thread.
for (std::map<int, mozilla::RefPtr<mozilla::MediaPipeline> >::iterator it =
mPipelines.begin(); it != mPipelines.end();
++it) {
it->second->ShutdownMedia_m();
}
mAudioTracks.Clear();
mVideoTracks.Clear();
mMediaStream = nullptr;
}
#if 0
// XXX bug 1056652 makes this not very useful for transmit streams
// NOTE: index is != the trackid in the MediaStream
int LocalSourceStreamInfo::HasTrack(DOMMediaStream* aStream, TrackID aTrack)
{
if (aStream != mMediaStream) {
return -1;
}
for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) {
if (it->second->trackid_locked() == aTrack) {
return it->first;
}
}
return -1;
}
#endif
// NOTE: index is != the trackid in the MediaStream
int LocalSourceStreamInfo::HasTrackType(DOMMediaStream* aStream, bool aIsVideo)
{
if (aStream != mMediaStream) {
return -1;
}
for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) {
if (it->second->IsVideo() == aIsVideo) {
return it->first;
}
}
return -1;
}
// XXX revisit once we support multiple tracks of a type - bug 1056650
nsresult LocalSourceStreamInfo::ReplaceTrack(int aMLine,
nsresult LocalSourceStreamInfo::ReplaceTrack(const std::string& oldTrackId,
DOMMediaStream* aNewStream,
TrackID aNewTrack)
const std::string& newTrackId)
{
// Note aMLine != aOldTrack!
mozilla::RefPtr<mozilla::MediaPipeline> pipeline = mPipelines[aMLine];
MOZ_ASSERT(pipeline);
if (NS_SUCCEEDED(static_cast<mozilla::MediaPipelineTransmit*>(pipeline.get())->ReplaceTrack(aNewStream, aNewTrack))) {
return NS_OK;
mozilla::RefPtr<mozilla::MediaPipeline> pipeline = mPipelines[oldTrackId];
if (!pipeline || !mTracks.count(oldTrackId)) {
CSFLogError(logTag, "Failed to find track id %s", oldTrackId.c_str());
return NS_ERROR_NOT_AVAILABLE;
}
return NS_ERROR_FAILURE;
nsresult rv =
static_cast<mozilla::MediaPipelineTransmit*>(pipeline.get())->ReplaceTrack(
aNewStream, newTrackId);
NS_ENSURE_SUCCESS(rv, rv);
mTracks.erase(oldTrackId);
mTracks.insert(newTrackId);
return NS_OK;
}
void RemoteSourceStreamInfo::DetachTransport_s()
void SourceStreamInfo::DetachTransport_s()
{
ASSERT_ON_THREAD(mParent->GetSTSThread());
// walk through all the MediaPipelines and call the shutdown
// transport functions. Must be on the STS thread.
for (std::map<int, mozilla::RefPtr<mozilla::MediaPipeline> >::iterator it =
mPipelines.begin(); it != mPipelines.end();
++it) {
for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) {
it->second->ShutdownTransport_s();
}
}
void RemoteSourceStreamInfo::DetachMedia_m()
void SourceStreamInfo::DetachMedia_m()
{
ASSERT_ON_THREAD(mParent->GetMainThread());
// walk through all the MediaPipelines and call the shutdown
// media functions. Must be on the main thread.
for (std::map<int, mozilla::RefPtr<mozilla::MediaPipeline> >::iterator it =
mPipelines.begin(); it != mPipelines.end();
++it) {
for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) {
it->second->ShutdownMedia_m();
}
mMediaStream = nullptr;
@ -663,9 +565,9 @@ PeerConnectionMedia::UpdateIceMediaStream_s(size_t aMLine,
}
nsresult
PeerConnectionMedia::AddStream(DOMMediaStream* aMediaStream,
uint32_t hints,
std::string *stream_id)
PeerConnectionMedia::AddTrack(DOMMediaStream* aMediaStream,
std::string* streamId,
const std::string& trackId)
{
ASSERT_ON_THREAD(mMainThread);
@ -676,38 +578,9 @@ PeerConnectionMedia::AddStream(DOMMediaStream* aMediaStream,
CSFLogDebug(logTag, "%s: MediaStream: %p", __FUNCTION__, aMediaStream);
// Adding tracks here based on nsDOMMediaStream expectation settings
#ifdef MOZILLA_INTERNAL_API
if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
hints &= ~(DOMMediaStream::HINT_CONTENTS_VIDEO);
}
#endif
nsRefPtr<LocalSourceStreamInfo> localSourceStream =
GetLocalStreamByDomStream(*aMediaStream);
if (!(hints & (DOMMediaStream::HINT_CONTENTS_AUDIO |
DOMMediaStream::HINT_CONTENTS_VIDEO))) {
CSFLogDebug(logTag, "Empty Stream !!");
return NS_OK;
}
// Now see if we already have this stream or another stream with
// tracks of the same type, since we only allow one track of each type.
// TODO(ekr@rtfm.com): remove this when multiple of each stream
// is allowed bug 1056650
nsRefPtr<LocalSourceStreamInfo> localSourceStream = nullptr;
for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) {
auto& lss = mLocalSourceStreams[u];
if (((hints & DOMMediaStream::HINT_CONTENTS_AUDIO) && lss->AudioTrackCount()) ||
((hints & DOMMediaStream::HINT_CONTENTS_VIDEO) && lss->VideoTrackCount())) {
CSFLogError(logTag, "Only one stream of any given type allowed");
return NS_ERROR_FAILURE;
}
if (aMediaStream == lss->GetMediaStream()) {
localSourceStream = lss;
*stream_id = lss->GetId();
break;
}
}
if (!localSourceStream) {
std::string id;
if (!mUuidGen->Generate(&id)) {
@ -717,50 +590,38 @@ PeerConnectionMedia::AddStream(DOMMediaStream* aMediaStream,
localSourceStream = new LocalSourceStreamInfo(aMediaStream, this, id);
mLocalSourceStreams.AppendElement(localSourceStream);
*stream_id = id;
}
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
localSourceStream->ExpectAudio(TRACK_AUDIO);
}
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
localSourceStream->ExpectVideo(TRACK_VIDEO);
}
localSourceStream->AddTrack(trackId);
*streamId = localSourceStream->GetId();
return NS_OK;
}
nsresult
PeerConnectionMedia::RemoveStream(DOMMediaStream* aMediaStream,
uint32_t hints,
uint32_t *stream_id)
PeerConnectionMedia::RemoveTrack(DOMMediaStream* aMediaStream,
const std::string& trackId)
{
MOZ_ASSERT(aMediaStream);
ASSERT_ON_THREAD(mMainThread);
CSFLogDebug(logTag, "%s: MediaStream: %p",
__FUNCTION__, aMediaStream);
CSFLogDebug(logTag, "%s: MediaStream: %p", __FUNCTION__, aMediaStream);
for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) {
nsRefPtr<LocalSourceStreamInfo> localSourceStream = mLocalSourceStreams[u];
if (localSourceStream->GetMediaStream() == aMediaStream) {
*stream_id = u;
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
localSourceStream->RemoveAudio(TRACK_AUDIO);
}
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
localSourceStream->RemoveAudio(TRACK_VIDEO);
}
if (!(localSourceStream->AudioTrackCount() +
localSourceStream->VideoTrackCount())) {
mLocalSourceStreams.RemoveElementAt(u);
}
return NS_OK;
size_t i;
for (i = 0; i < mLocalSourceStreams.Length(); ++i) {
if (mLocalSourceStreams[i]->GetMediaStream() == aMediaStream) {
break;
}
}
return NS_ERROR_ILLEGAL_VALUE;
if (i == mLocalSourceStreams.Length()) {
return NS_ERROR_ILLEGAL_VALUE;
}
mLocalSourceStreams[i]->RemoveTrack(trackId);
if (!(mLocalSourceStreams[i]->GetTrackCount())) {
mLocalSourceStreams.RemoveElementAt(i);
}
return NS_OK;
}
void
@ -860,6 +721,33 @@ PeerConnectionMedia::GetLocalStreamById(const std::string& id)
return nullptr;
}
LocalSourceStreamInfo*
PeerConnectionMedia::GetLocalStreamByDomStream(const DOMMediaStream& stream)
{
ASSERT_ON_THREAD(mMainThread);
for (size_t i = 0; i < mLocalSourceStreams.Length(); ++i) {
if (&stream == mLocalSourceStreams[i]->GetMediaStream()) {
return mLocalSourceStreams[i];
}
}
return nullptr;
}
RemoteSourceStreamInfo*
PeerConnectionMedia::GetRemoteStreamByDomStream(const DOMMediaStream& stream)
{
ASSERT_ON_THREAD(mMainThread);
for (size_t i = 0; i < mRemoteSourceStreams.Length(); ++i) {
if (&stream == mRemoteSourceStreams[i]->GetMediaStream()) {
return mRemoteSourceStreams[i];
}
}
MOZ_ASSERT(false);
return nullptr;
}
RemoteSourceStreamInfo*
PeerConnectionMedia::GetRemoteStreamByIndex(size_t aIndex)
{
@ -905,19 +793,19 @@ UpdateFilterFromRemoteDescription_s(
bool
PeerConnectionMedia::UpdateFilterFromRemoteDescription_m(
int aMLine,
const std::string& trackId,
nsAutoPtr<mozilla::MediaPipelineFilter> filter)
{
ASSERT_ON_THREAD(mMainThread);
RefPtr<mozilla::MediaPipeline> receive;
for (size_t i = 0; !receive && i < mRemoteSourceStreams.Length(); ++i) {
receive = mRemoteSourceStreams[i]->GetPipelineByLevel_m(aMLine);
receive = mRemoteSourceStreams[i]->GetPipelineByTrackId_m(trackId);
}
RefPtr<mozilla::MediaPipeline> transmit;
for (size_t i = 0; !transmit && i < mLocalSourceStreams.Length(); ++i) {
transmit = mLocalSourceStreams[i]->GetPipelineByLevel_m(aMLine);
transmit = mLocalSourceStreams[i]->GetPipelineByTrackId_m(trackId);
}
if (receive && transmit) {
@ -935,8 +823,8 @@ PeerConnectionMedia::UpdateFilterFromRemoteDescription_m(
NS_DISPATCH_NORMAL);
return true;
} else {
CSFLogWarn(logTag, "Could not locate level %d to update filter",
static_cast<int>(aMLine));
CSFLogWarn(logTag, "Could not locate track %s to update filter",
trackId.c_str());
}
return false;
}
@ -951,27 +839,6 @@ PeerConnectionMedia::AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo)
return NS_OK;
}
nsresult
PeerConnectionMedia::AddRemoteStreamHint(int aIndex, bool aIsVideo)
{
if (aIndex < 0 ||
static_cast<unsigned int>(aIndex) >= mRemoteSourceStreams.Length()) {
return NS_ERROR_ILLEGAL_VALUE;
}
RemoteSourceStreamInfo *pInfo = mRemoteSourceStreams.ElementAt(aIndex);
MOZ_ASSERT(pInfo);
if (aIsVideo) {
pInfo->mTrackTypeHints |= DOMMediaStream::HINT_CONTENTS_VIDEO;
} else {
pInfo->mTrackTypeHints |= DOMMediaStream::HINT_CONTENTS_AUDIO;
}
return NS_OK;
}
void
PeerConnectionMedia::IceGatheringStateChange_s(NrIceCtx* ctx,
NrIceCtx::GatheringState state)
@ -1235,7 +1102,7 @@ PeerConnectionMedia::AnyCodecHasPluginID(uint64_t aPluginID)
}
bool
LocalSourceStreamInfo::AnyCodecHasPluginID(uint64_t aPluginID)
SourceStreamInfo::AnyCodecHasPluginID(uint64_t aPluginID)
{
// Scan the videoConduits for this plugin ID
for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) {
@ -1246,70 +1113,50 @@ LocalSourceStreamInfo::AnyCodecHasPluginID(uint64_t aPluginID)
return false;
}
bool
RemoteSourceStreamInfo::AnyCodecHasPluginID(uint64_t aPluginID)
nsresult
SourceStreamInfo::StorePipeline(
const std::string& trackId,
const mozilla::RefPtr<mozilla::MediaPipeline>& aPipeline)
{
// Scan the videoConduits for this plugin ID
for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) {
if (it->second->Conduit()->CodecPluginID() == aPluginID) {
return true;
}
}
return false;
}
void
LocalSourceStreamInfo::StorePipeline(
int aMLine, mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline)
{
MOZ_ASSERT(mPipelines.find(aMLine) == mPipelines.end());
if (mPipelines.find(aMLine) != mPipelines.end()) {
MOZ_ASSERT(mPipelines.find(trackId) == mPipelines.end());
if (mPipelines.find(trackId) != mPipelines.end()) {
CSFLogError(logTag, "%s: Storing duplicate track", __FUNCTION__);
return;
return NS_ERROR_FAILURE;
}
//TODO: Revisit once we start supporting multiple streams or multiple tracks
// of same type bug 1056650
mPipelines[aMLine] = aPipeline;
mPipelines[trackId] = aPipeline;
return NS_OK;
}
void
RemoteSourceStreamInfo::StorePipeline(
int aMLine, bool aIsVideo,
RemoteSourceStreamInfo::SyncPipeline(
mozilla::RefPtr<mozilla::MediaPipelineReceive> aPipeline)
{
MOZ_ASSERT(mPipelines.find(aMLine) == mPipelines.end());
if (mPipelines.find(aMLine) != mPipelines.end()) {
CSFLogError(logTag, "%s: Request to store duplicate track %d", __FUNCTION__, aMLine);
return;
}
CSFLogDebug(logTag, "%s track %d %s = %p", __FUNCTION__, aMLine, aIsVideo ? "video" : "audio",
aPipeline.get());
// See if we have both audio and video here, and if so cross the streams and sync them
// XXX Needs to be adjusted when we support multiple streams of the same type bug 1056650
for (std::map<int, bool>::iterator it = mTypes.begin(); it != mTypes.end(); ++it) {
if (it->second != aIsVideo) {
// See if we have both audio and video here, and if so cross the streams and
// sync them
// TODO: Do we need to prevent multiple syncs if there is more than one audio
// or video track in a single media stream? What are we supposed to do in this
// case?
for (auto i = mPipelines.begin(); i != mPipelines.end(); ++i) {
if (i->second->IsVideo() != aPipeline->IsVideo()) {
// Ok, we have one video, one non-video - cross the streams!
mozilla::WebrtcAudioConduit *audio_conduit = static_cast<mozilla::WebrtcAudioConduit*>
(aIsVideo ?
mPipelines[it->first]->Conduit() :
aPipeline->Conduit());
mozilla::WebrtcVideoConduit *video_conduit = static_cast<mozilla::WebrtcVideoConduit*>
(aIsVideo ?
aPipeline->Conduit() :
mPipelines[it->first]->Conduit());
mozilla::WebrtcAudioConduit *audio_conduit =
static_cast<mozilla::WebrtcAudioConduit*>(aPipeline->IsVideo() ?
i->second->Conduit() :
aPipeline->Conduit());
mozilla::WebrtcVideoConduit *video_conduit =
static_cast<mozilla::WebrtcVideoConduit*>(aPipeline->IsVideo() ?
aPipeline->Conduit() :
i->second->Conduit());
video_conduit->SyncTo(audio_conduit);
CSFLogDebug(logTag, "Syncing %p to %p, %d to %d", video_conduit, audio_conduit,
aMLine, it->first);
CSFLogDebug(logTag, "Syncing %p to %p, %s to %s",
video_conduit, audio_conduit,
i->first.c_str(), aPipeline->trackid().c_str());
}
}
//TODO: Revisit once we start supporting multiple streams or multiple tracks
// of same type bug 1056650
mPipelines[aMLine] = aPipeline;
//TODO: move to attribute on Pipeline
mTypes[aMLine] = aIsVideo;
}
RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int aMLine) {
RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByTrackId_m(
const std::string& trackId) {
ASSERT_ON_THREAD(mParent->GetMainThread());
// Refuse to hand out references if we're tearing down.
@ -1318,10 +1165,8 @@ RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int aMLine) {
// RefPtr<MediaPipeline>, since that reference won't be the last one
// standing)
if (mMediaStream) {
for (auto p = mPipelines.begin(); p != mPipelines.end(); ++p) {
if (p->second->level() == aMLine) {
return p->second;
}
if (mPipelines.count(trackId)) {
return mPipelines[trackId];
}
}

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

@ -198,18 +198,38 @@ public:
return mMediaStream;
}
nsresult StorePipeline(
const std::string& trackId,
const mozilla::RefPtr<mozilla::MediaPipeline>& aPipeline);
void AddTrack(const std::string& trackId) { mTracks.insert(trackId); }
void RemoveTrack(const std::string& trackId) { mTracks.erase(trackId); }
bool HasTrack(const std::string& trackId) const
{
return !!mTracks.count(trackId);
}
size_t GetTrackCount() const { return mTracks.size(); }
// This method exists for stats and the unittests.
// It allows visibility into the pipelines and flows.
const std::map<mozilla::TrackID, mozilla::RefPtr<mozilla::MediaPipeline>>&
const std::map<std::string, mozilla::RefPtr<mozilla::MediaPipeline>>&
GetPipelines() const { return mPipelines; }
mozilla::RefPtr<mozilla::MediaPipeline> GetPipelineByLevel_m(int aMLine);
mozilla::RefPtr<mozilla::MediaPipeline> GetPipelineByTrackId_m(
const std::string& trackId);
const std::string& GetId() const { return mId; }
void DetachTransport_s();
void DetachMedia_m();
bool AnyCodecHasPluginID(uint64_t aPluginID);
protected:
std::map<mozilla::TrackID, mozilla::RefPtr<mozilla::MediaPipeline>> mPipelines;
nsRefPtr<DOMMediaStream> mMediaStream;
PeerConnectionMedia *mParent;
const std::string mId;
// These get set up before we generate our local description, the pipelines
// are set up once offer/answer completes.
std::set<std::string> mTracks;
// Indexed by track id, might contain pipelines for removed tracks
std::map<std::string, mozilla::RefPtr<mozilla::MediaPipeline>> mPipelines;
};
// TODO(ekr@rtfm.com): Refactor {Local,Remote}SourceStreamInfo
@ -224,40 +244,19 @@ public:
const std::string& aId)
: SourceStreamInfo(aMediaStream, aParent, aId) {}
// Returns the mPipelines index for the track or -1.
#if 0
int HasTrack(DOMMediaStream* aStream, mozilla::TrackID aMLine);
#endif
int HasTrackType(DOMMediaStream* aStream, bool aIsVideo);
// XXX NOTE: does not change mMediaStream, even if it replaces the last track
// in a LocalSourceStreamInfo. Revise when we have support for multiple tracks
// of a type.
// Note aMLine != aOldTrack! It's the result of HasTrackType()
nsresult ReplaceTrack(int aMLine, DOMMediaStream* aNewStream, mozilla::TrackID aNewTrack);
void StorePipeline(int aMLine,
mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline);
nsresult ReplaceTrack(const std::string& oldTrackId,
DOMMediaStream* aNewStream,
const std::string& aNewTrack);
#ifdef MOZILLA_INTERNAL_API
void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal,
const mozilla::PeerIdentity* aSinkIdentity);
#endif
void ExpectAudio(const mozilla::TrackID);
void ExpectVideo(const mozilla::TrackID);
void RemoveAudio(const mozilla::TrackID);
void RemoveVideo(const mozilla::TrackID);
unsigned AudioTrackCount();
unsigned VideoTrackCount();
void DetachTransport_s();
void DetachMedia_m();
bool AnyCodecHasPluginID(uint64_t aPluginID);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LocalSourceStreamInfo)
private:
nsTArray<mozilla::TrackID> mAudioTracks;
nsTArray<mozilla::TrackID> mVideoTracks;
};
class RemoteSourceStreamInfo : public SourceStreamInfo {
@ -266,28 +265,17 @@ class RemoteSourceStreamInfo : public SourceStreamInfo {
RemoteSourceStreamInfo(already_AddRefed<DOMMediaStream> aMediaStream,
PeerConnectionMedia *aParent,
const std::string& aId)
: SourceStreamInfo(aMediaStream, aParent, aId),
mTrackTypeHints(0) {
: SourceStreamInfo(aMediaStream, aParent, aId)
{
}
void StorePipeline(int aMLine, bool aIsVideo,
mozilla::RefPtr<mozilla::MediaPipelineReceive> aPipeline);
void DetachTransport_s();
void DetachMedia_m();
void SyncPipeline(RefPtr<MediaPipelineReceive> aPipeline);
#ifdef MOZILLA_INTERNAL_API
void UpdatePrincipal_m(nsIPrincipal* aPrincipal);
#endif
bool AnyCodecHasPluginID(uint64_t aPluginID);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteSourceStreamInfo)
public:
DOMMediaStream::TrackTypeHints mTrackTypeHints;
private:
std::map<int, bool> mTypes;
};
class PeerConnectionMedia : public sigslot::has_slots<> {
@ -333,14 +321,18 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
// Handle complete media pipelines.
nsresult UpdateMediaPipelines(const mozilla::JsepSession& session);
// Add a stream (main thread only)
nsresult AddStream(DOMMediaStream* aMediaStream, uint32_t hints,
std::string* stream_id);
// Add a track (main thread only)
// TODO(bug 1089798): Once DOMMediaStream has an id field, use it instead of
// letting PCMedia choose a streamId
nsresult AddTrack(DOMMediaStream* aMediaStream,
std::string* streamId,
const std::string& trackId);
// Remove a stream (main thread only)
nsresult RemoveStream(DOMMediaStream* aMediaStream,
uint32_t hints,
uint32_t *stream_id);
// Remove a track (main thread only)
// TODO(bug 1089798): Once DOMMediaStream has an id field, use it instead of
// passing |aMediaStream|
nsresult RemoveTrack(DOMMediaStream* aMediaStream,
const std::string& trackId);
// Get a specific local stream
uint32_t LocalStreamsLength()
@ -349,6 +341,8 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
}
LocalSourceStreamInfo* GetLocalStreamByIndex(int index);
LocalSourceStreamInfo* GetLocalStreamById(const std::string& id);
LocalSourceStreamInfo* GetLocalStreamByDomStream(
const DOMMediaStream& stream);
// Get a specific remote stream
uint32_t RemoteStreamsLength()
@ -358,14 +352,16 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
RemoteSourceStreamInfo* GetRemoteStreamByIndex(size_t index);
RemoteSourceStreamInfo* GetRemoteStreamById(const std::string& id);
RemoteSourceStreamInfo* GetRemoteStreamByDomStream(
const DOMMediaStream& stream);
bool UpdateFilterFromRemoteDescription_m(
int aMLine,
const std::string& trackId,
nsAutoPtr<mozilla::MediaPipelineFilter> filter);
// Add a remote stream.
nsresult AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo);
nsresult AddRemoteStreamHint(int aIndex, bool aIsVideo);
#ifdef MOZILLA_INTERNAL_API
// In cases where the peer isn't yet identified, we disable the pipeline (not

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

@ -164,6 +164,18 @@ SdpMsidAttributeList::Serialize(std::ostream& os) const
}
}
void
SdpMsidSemanticAttributeList::Serialize(std::ostream& os) const
{
for (auto i = mMsidSemantics.begin(); i != mMsidSemantics.end(); ++i) {
os << "a=" << mType << ":" << i->semantic;
for (auto j = i->msids.begin(); j != i->msids.end(); ++j) {
os << " " << *j;
}
os << CRLF;
}
}
void
SdpRemoteCandidatesAttribute::Serialize(std::ostream& os) const
{

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

@ -630,6 +630,36 @@ public:
std::vector<Msid> mMsids;
};
///////////////////////////////////////////////////////////////////////////
// a=msid-semantic, draft-ietf-mmusic-msid
//-------------------------------------------------------------------------
// msid-semantic-attr = "msid-semantic:" msid-semantic msid-list
// msid-semantic = token ; see RFC 4566
// msid-list = *(" " msid-id) / " *"
class SdpMsidSemanticAttributeList : public SdpAttribute
{
public:
SdpMsidSemanticAttributeList() : SdpAttribute(kMsidSemanticAttribute) {}
struct MsidSemantic
{
// TODO: Once we have some more of these, we might want to make an enum
std::string semantic;
std::vector<std::string> msids;
};
void
PushEntry(const std::string& semantic, const std::vector<std::string>& msids)
{
MsidSemantic value = {semantic, msids};
mMsidSemantics.push_back(value);
}
virtual void Serialize(std::ostream& os) const MOZ_OVERRIDE;
std::vector<MsidSemantic> mMsidSemantics;
};
///////////////////////////////////////////////////////////////////////////
// a=remote-candiate, RFC5245
//-------------------------------------------------------------------------

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

@ -70,7 +70,7 @@ public:
virtual const std::string& GetLabel() const = 0;
virtual unsigned int GetMaxptime() const = 0;
virtual const std::string& GetMid() const = 0;
virtual const std::string& GetMsidSemantic() const = 0;
virtual const SdpMsidSemanticAttributeList& GetMsidSemantic() const = 0;
virtual unsigned int GetPtime() const = 0;
// This is "special", because it's multiple things

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

@ -108,8 +108,6 @@ SipccSdpAttributeList::LoadSimpleStrings(sdp_t* sdp, uint16_t level,
errorHolder);
LoadSimpleString(sdp, level, SDP_ATTR_IDENTITY,
SdpAttribute::kIdentityAttribute, errorHolder);
LoadSimpleString(sdp, level, SDP_ATTR_MSID_SEMANTIC,
SdpAttribute::kMsidSemanticAttribute, errorHolder);
}
void
@ -547,6 +545,38 @@ SipccSdpAttributeList::LoadGroups(sdp_t* sdp, uint16_t level,
return true;
}
bool
SipccSdpAttributeList::LoadMsidSemantics(sdp_t* sdp, uint16_t level,
SdpErrorHolder& errorHolder)
{
auto msidSemantics = MakeUnique<SdpMsidSemanticAttributeList>();
for (uint16_t i = 1; i < UINT16_MAX; ++i) {
sdp_attr_t* attr = sdp_find_attr(sdp, level, 0, SDP_ATTR_MSID_SEMANTIC, i);
if (!attr) {
break;
}
sdp_msid_semantic_t* msid_semantic = &(attr->attr.msid_semantic);
std::vector<std::string> msids;
for (size_t i = 0; i < SDP_MAX_MEDIA_STREAMS; ++i) {
if (!msid_semantic->msids[i]) {
break;
}
msids.push_back(msid_semantic->msids[i]);
}
msidSemantics->PushEntry(msid_semantic->semantic, msids);
}
if (!msidSemantics->mMsidSemantics.empty()) {
SetAttribute(msidSemantics.release());
}
return true;
}
void
SipccSdpAttributeList::LoadFmtp(sdp_t* sdp, uint16_t level)
{
@ -829,6 +859,10 @@ SipccSdpAttributeList::Load(sdp_t* sdp, uint16_t level,
if (!LoadGroups(sdp, level, errorHolder)) {
return false;
}
if (!LoadMsidSemantics(sdp, level, errorHolder)) {
return false;
}
} else {
sdp_media_e mtype = sdp_get_media_type(sdp, level);
if (mtype == SDP_MEDIA_APPLICATION) {
@ -1045,14 +1079,14 @@ SipccSdpAttributeList::GetMsid() const
return *static_cast<const SdpMsidAttributeList*>(attr);
}
const std::string&
const SdpMsidSemanticAttributeList&
SipccSdpAttributeList::GetMsidSemantic() const
{
if (!HasAttribute(SdpAttribute::kMsidSemanticAttribute)) {
return kEmptyString;
MOZ_CRASH();
}
const SdpAttribute* attr = GetAttribute(SdpAttribute::kMsidSemanticAttribute);
return static_cast<const SdpStringAttribute*>(attr)->mValue;
return *static_cast<const SdpMsidSemanticAttributeList*>(attr);
}
uint32_t

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

@ -69,7 +69,8 @@ public:
virtual const std::string& GetLabel() const MOZ_OVERRIDE;
virtual unsigned int GetMaxptime() const MOZ_OVERRIDE;
virtual const std::string& GetMid() const MOZ_OVERRIDE;
virtual const std::string& GetMsidSemantic() const MOZ_OVERRIDE;
virtual const SdpMsidSemanticAttributeList& GetMsidSemantic()
const MOZ_OVERRIDE;
virtual unsigned int GetPtime() const MOZ_OVERRIDE;
virtual SdpDirectionAttribute::Direction GetDirection() const MOZ_OVERRIDE;
@ -105,6 +106,9 @@ private:
void LoadSetup(sdp_t* sdp, uint16_t level);
void LoadSsrc(sdp_t* sdp, uint16_t level);
bool LoadGroups(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
bool LoadMsidSemantics(sdp_t* sdp,
uint16_t level,
SdpErrorHolder& errorHolder);
void LoadFmtp(sdp_t* sdp, uint16_t level);
void LoadMsids(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);
void LoadExtmap(sdp_t* sdp, uint16_t level, SdpErrorHolder& errorHolder);

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

@ -556,7 +556,7 @@ typedef enum sdp_srtp_crypto_suite_t_ {
/* Max number of stream ids that can be grouped together */
#define SDP_MAX_GROUP_STREAM_ID 10
#define SDP_MAX_MEDIA_STREAMS 32
#define SDP_MAGIC_NUM 0xabcdabcd
@ -838,9 +838,14 @@ typedef struct sdp_stream_data {
char x_confid[SDP_MAX_STRING_LEN+1];
sdp_group_attr_e group_attr; /* FID or LS */
uint16_t num_group_id;
char * group_ids[SDP_MAX_GROUP_STREAM_ID];
char * group_ids[SDP_MAX_MEDIA_STREAMS];
} sdp_stream_data_t;
typedef struct sdp_msid_semantic {
char semantic[SDP_MAX_STRING_LEN+1];
char * msids[SDP_MAX_MEDIA_STREAMS];
} sdp_msid_semantic_t;
/*
* a=source-filter:<filter-mode> <filter-spec>
* <filter-spec> = <nettype> <addrtype> <dest-addr> <src_addr><src_addr>...
@ -1009,6 +1014,7 @@ typedef struct sdp_attr {
sdp_srtp_crypto_context_t srtp_context;
sdp_mptime_t mptime;
sdp_stream_data_t stream_data;
sdp_msid_semantic_t msid_semantic;
char unknown[SDP_MAX_STRING_LEN+1];
sdp_source_filter_t source_filter;
sdp_fmtp_fb_t rtcp_fb;

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

@ -4101,7 +4101,7 @@ sdp_result_e sdp_parse_attr_group (sdp_t *sdp_p, sdp_attr_t *attr_p,
*/
attr_p->attr.stream_data.num_group_id =0;
for (i=0; i<SDP_MAX_GROUP_STREAM_ID; i++) {
for (i=0; i<SDP_MAX_MEDIA_STREAMS; i++) {
ptr = sdp_getnextstrtok(ptr, tmp, sizeof(tmp), " \t", &result);
if (result != SDP_SUCCESS) {
@ -5315,6 +5315,82 @@ sdp_result_e sdp_build_attr_msid(sdp_t *sdp_p,
return SDP_SUCCESS;
}
sdp_result_e sdp_parse_attr_msid_semantic(sdp_t *sdp_p,
sdp_attr_t *attr_p,
const char *ptr)
{
sdp_result_e result;
int i;
ptr = sdp_getnextstrtok(ptr,
attr_p->attr.msid_semantic.semantic,
sizeof(attr_p->attr.msid_semantic.semantic),
" \t",
&result);
if (result != SDP_SUCCESS) {
sdp_parse_error(sdp_p, "%s Warning: Bad msid-semantic attribute; "
"missing semantic",
sdp_p->debug_str);
sdp_p->conf_p->num_invalid_param++;
return SDP_INVALID_PARAMETER;
}
for (i = 0; i < SDP_MAX_MEDIA_STREAMS; ++i) {
/* msid-id can be up to 64 characters long, plus null terminator */
char temp[65];
ptr = sdp_getnextstrtok(ptr, temp, sizeof(temp), " \t", &result);
if (result != SDP_SUCCESS) {
break;
}
attr_p->attr.msid_semantic.msids[i] = cpr_strdup(temp);
}
if ((result != SDP_SUCCESS) && (result != SDP_EMPTY_TOKEN)) {
sdp_parse_error(sdp_p, "%s Warning: Bad msid-semantic attribute",
sdp_p->debug_str);
sdp_p->conf_p->num_invalid_param++;
return SDP_INVALID_PARAMETER;
}
if (sdp_p->debug_flag[SDP_DEBUG_TRACE]) {
SDP_PRINT("%s Parsed a=msid-semantic, %s", sdp_p->debug_str,
attr_p->attr.msid_semantic.semantic);
for (i = 0; i < SDP_MAX_MEDIA_STREAMS; ++i) {
if (!attr_p->attr.msid_semantic.msids[i]) {
break;
}
SDP_PRINT("%s ... msid %s", sdp_p->debug_str,
attr_p->attr.msid_semantic.msids[i]);
}
}
return SDP_SUCCESS;
}
sdp_result_e sdp_build_attr_msid_semantic(sdp_t *sdp_p,
sdp_attr_t *attr_p,
flex_string *fs)
{
int i;
flex_string_sprintf(fs, "a=msid-semantic:%s",
attr_p->attr.msid_semantic.semantic);
for (i = 0; i < SDP_MAX_MEDIA_STREAMS; ++i) {
if (!attr_p->attr.msid_semantic.msids[i]) {
break;
}
flex_string_sprintf(fs, " %s",
attr_p->attr.msid_semantic.msids[i]);
}
flex_string_sprintf(fs, "\r\n");
return SDP_SUCCESS;
}
sdp_result_e sdp_parse_attr_ssrc(sdp_t *sdp_p,
sdp_attr_t *attr_p,
const char *ptr)

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

@ -605,6 +605,20 @@ void sdp_copy_attr_fields (sdp_attr_t *src_attr_p, sdp_attr_t *dst_attr_p)
}
break;
case SDP_ATTR_MSID_SEMANTIC:
sstrncpy(dst_attr_p->attr.msid_semantic.semantic,
src_attr_p->attr.msid_semantic.semantic,
SDP_MAX_STRING_LEN+1);
for (i=0; i < SDP_MAX_MEDIA_STREAMS; ++i) {
if (!src_attr_p->attr.msid_semantic.msids[i]) {
break;
}
dst_attr_p->attr.msid_semantic.msids[i] =
cpr_strdup(src_attr_p->attr.msid_semantic.msids[i]);
}
break;
case SDP_ATTR_SOURCE_FILTER:
dst_attr_p->attr.source_filter.mode =
src_attr_p->attr.source_filter.mode;
@ -1176,6 +1190,10 @@ void sdp_free_attr (sdp_attr_t *attr_p)
for (i = 0; i < attr_p->attr.stream_data.num_group_id; i++) {
SDP_FREE(attr_p->attr.stream_data.group_ids[i]);
}
} else if (attr_p->type == SDP_ATTR_MSID_SEMANTIC) {
for (i = 0; i < SDP_MAX_MEDIA_STREAMS; ++i) {
SDP_FREE(attr_p->attr.msid_semantic.msids[i]);
}
}
/* Now free the actual attribute memory. */
@ -1658,7 +1676,6 @@ static boolean sdp_attr_is_simple_string(sdp_attr_e attr_type) {
(attr_type != SDP_ATTR_X_CONFID) &&
(attr_type != SDP_ATTR_LABEL) &&
(attr_type != SDP_ATTR_IDENTITY) &&
(attr_type != SDP_ATTR_MSID_SEMANTIC) &&
(attr_type != SDP_ATTR_ICE_OPTIONS)) {
return FALSE;
}
@ -10305,7 +10322,7 @@ sdp_result_e sdp_set_group_num_id (void *sdp_ptr, uint16_t level,
}
sdp_p->conf_p->num_invalid_param++;
return (SDP_INVALID_PARAMETER);
} else if ((group_num_id == 0) || (group_num_id > SDP_MAX_GROUP_STREAM_ID)){
} else if ((group_num_id == 0) || (group_num_id > SDP_MAX_MEDIA_STREAMS)){
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
CSFLogError(logTag, "%s Number of group id value provided - %u is invalid",
sdp_p->debug_str, (unsigned)group_num_id);
@ -10388,7 +10405,7 @@ sdp_result_e sdp_set_group_id (void *sdp_ptr, uint16_t level,
return (SDP_INVALID_PARAMETER);
} else {
num_group_id = attr_p->attr.stream_data.num_group_id;
if (num_group_id == SDP_MAX_GROUP_STREAM_ID) {
if (num_group_id == SDP_MAX_MEDIA_STREAMS) {
if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
CSFLogError(logTag, "%s Max number of Group Ids already defined "
"for this group line %u", sdp_p->debug_str, (unsigned)level);

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

@ -185,7 +185,7 @@ const sdp_attrarray_t sdp_attr[SDP_MAX_ATTR_TYPES] =
{"msid", sizeof("msid"),
sdp_parse_attr_msid, sdp_build_attr_msid},
{"msid-semantic", sizeof("msid-semantic"),
sdp_parse_attr_simple_string, sdp_build_attr_simple_string},
sdp_parse_attr_msid_semantic, sdp_build_attr_msid_semantic},
{"bundle-only", sizeof("bundle-only"),
sdp_parse_attr_simple_flag, sdp_build_attr_simple_flag},
{"end-of-candidates", sizeof("end-of-candidates"),

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

@ -80,6 +80,12 @@ extern sdp_result_e sdp_parse_attr_msid(sdp_t *sdp_p, sdp_attr_t *attr_p,
const char *ptr);
extern sdp_result_e sdp_build_attr_msid(sdp_t *sdp_p, sdp_attr_t *attr_p,
flex_string *fs);
extern sdp_result_e sdp_parse_attr_msid_semantic(sdp_t *sdp_p,
sdp_attr_t *attr_p,
const char *ptr);
extern sdp_result_e sdp_build_attr_msid_semantic(sdp_t *sdp_p,
sdp_attr_t *attr_p,
flex_string *fs);
extern sdp_result_e sdp_parse_attr_ssrc(sdp_t *sdp_p, sdp_attr_t *attr_p,
const char *ptr);
extern sdp_result_e sdp_build_attr_ssrc(sdp_t *sdp_p, sdp_attr_t *attr_p,

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

@ -6,6 +6,8 @@
#define FAKE_MEDIA_STREAM_H_
#include <set>
#include <string>
#include <sstream>
#include "nsNetCID.h"
#include "nsITimer.h"
@ -13,6 +15,7 @@
#include "nsIComponentManager.h"
#include "nsIComponentRegistrar.h"
#include "nsISupportsImpl.h"
#include "nsServiceManagerUtils.h"
// #includes from MediaStream.h
#include "mozilla/Mutex.h"
@ -220,8 +223,16 @@ class Fake_MediaStreamTrack
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Fake_MediaStreamTrack)
explicit Fake_MediaStreamTrack(bool aIsVideo) : mIsVideo (aIsVideo) {}
explicit Fake_MediaStreamTrack(bool aIsVideo) : mIsVideo (aIsVideo)
{
static size_t counter = 0;
std::ostringstream os;
os << counter++;
mID = os.str();
}
mozilla::TrackID GetTrackID() { return mIsVideo ? 1 : 0; }
std::string GetId() const { return mID; }
void AssignId(const std::string& id) { mID = id; }
Fake_DOMMediaStream *GetStream() { return nullptr; }
const Fake_MediaStreamTrack* AsVideoStreamTrack() const
{
@ -235,6 +246,7 @@ private:
~Fake_MediaStreamTrack() {}
const bool mIsVideo;
std::string mID;
};
class Fake_DOMMediaStream : public nsISupports

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

@ -246,6 +246,20 @@ protected:
if (checkFlags & CHECK_TRACKS) {
// Check that the transports exist.
ASSERT_EQ(types.size(), mSessionOff.GetTransportCount());
for (size_t i = 0; i < types.size(); ++i) {
RefPtr<JsepTrack> ltrack;
ASSERT_EQ(NS_OK, mSessionOff.GetLocalTrack(i, &ltrack));
ASSERT_NE("", ltrack->GetStreamId());
ASSERT_NE("", ltrack->GetTrackId());
if (ltrack->GetMediaType() != SdpMediaSection::kApplication) {
std::string msidAttr("a=msid:");
msidAttr += ltrack->GetStreamId();
msidAttr += " ";
msidAttr += ltrack->GetTrackId();
ASSERT_NE(std::string::npos, offer.find(msidAttr))
<< "Did not find " << msidAttr << " in offer";
}
}
}
}
@ -265,6 +279,16 @@ protected:
RefPtr<JsepTrack> rtrack;
ASSERT_EQ(NS_OK, mSessionAns.GetRemoteTrack(i, &rtrack));
ASSERT_EQ(types[i], rtrack->GetMediaType());
ASSERT_NE("", rtrack->GetStreamId());
ASSERT_NE("", rtrack->GetTrackId());
if (rtrack->GetMediaType() != SdpMediaSection::kApplication) {
std::string msidAttr("a=msid:");
msidAttr += rtrack->GetStreamId();
msidAttr += " ";
msidAttr += rtrack->GetTrackId();
ASSERT_NE(std::string::npos, offer.find(msidAttr))
<< "Did not find " << msidAttr << " in offer";
}
}
}
}
@ -287,6 +311,21 @@ protected:
ASSERT_EQ(types[i], pair->mSending->GetMediaType());
ASSERT_TRUE(pair->mReceiving);
ASSERT_EQ(types[i], pair->mReceiving->GetMediaType());
ASSERT_NE("", pair->mSending->GetStreamId());
ASSERT_NE("", pair->mSending->GetTrackId());
// These might have been in the SDP, or might have been randomly
// chosen by JsepSessionImpl
ASSERT_NE("", pair->mReceiving->GetStreamId());
ASSERT_NE("", pair->mReceiving->GetTrackId());
if (pair->mReceiving->GetMediaType() != SdpMediaSection::kApplication) {
std::string msidAttr("a=msid:");
msidAttr += pair->mSending->GetStreamId();
msidAttr += " ";
msidAttr += pair->mSending->GetTrackId();
ASSERT_NE(std::string::npos, answer.find(msidAttr))
<< "Did not find " << msidAttr << " in offer";
}
}
}
DumpTrackPairs(mSessionOff);
@ -302,14 +341,29 @@ protected:
if (checkFlags & CHECK_TRACKS) {
// Verify that the right stuff is in the tracks.
ASSERT_EQ(types.size(), mSessionAns.GetNegotiatedTrackPairCount());
ASSERT_EQ(types.size(), mSessionOff.GetNegotiatedTrackPairCount());
for (size_t i = 0; i < types.size(); ++i) {
const JsepTrackPair* pair;
ASSERT_EQ(NS_OK, mSessionAns.GetNegotiatedTrackPair(i, &pair));
ASSERT_EQ(NS_OK, mSessionOff.GetNegotiatedTrackPair(i, &pair));
ASSERT_TRUE(pair->mSending);
ASSERT_EQ(types[i], pair->mSending->GetMediaType());
ASSERT_TRUE(pair->mReceiving);
ASSERT_EQ(types[i], pair->mReceiving->GetMediaType());
ASSERT_NE("", pair->mSending->GetStreamId());
ASSERT_NE("", pair->mSending->GetTrackId());
// These might have been in the SDP, or might have been randomly
// chosen by JsepSessionImpl
ASSERT_NE("", pair->mReceiving->GetStreamId());
ASSERT_NE("", pair->mReceiving->GetTrackId());
if (pair->mReceiving->GetMediaType() != SdpMediaSection::kApplication) {
std::string msidAttr("a=msid:");
msidAttr += pair->mReceiving->GetStreamId();
msidAttr += " ";
msidAttr += pair->mReceiving->GetTrackId();
ASSERT_NE(std::string::npos, answer.find(msidAttr))
<< "Did not find " << msidAttr << " in offer";
}
}
}
DumpTrackPairs(mSessionAns);

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

@ -270,6 +270,7 @@ class TestAgentSend : public TestAgent {
nullptr,
test_utils->sts_target(),
audio_,
"audio_track_fake_uuid",
1,
false,
audio_conduit_,
@ -319,7 +320,7 @@ class TestAgentReceive : public TestAgent {
test_pc,
nullptr,
test_utils->sts_target(),
audio_->GetStream(), 1, 1,
audio_->GetStream(), "audio_track_fake_uuid", 1, 1,
static_cast<mozilla::AudioSessionConduit *>(audio_conduit_.get()),
audio_rtp_transport_.flow_,
audio_rtcp_transport_.flow_,

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

@ -1126,7 +1126,8 @@ const std::string kBasicAudioVideoOffer =
"a=ice-pwd:e4cc12a910f106a0a744719425510e17" CRLF
"a=ice-lite" CRLF
"a=ice-options:trickle foo" CRLF
"a=msid-semantic:WMS plus" CRLF
"a=msid-semantic:WMS stream streama" CRLF
"a=msid-semantic:foo stream" CRLF
"a=fingerprint:sha-256 DF:2E:AC:8A:FD:0A:8E:99:BF:5D:E8:3C:E7:FA:FB:08:3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C" CRLF
"a=identity:blahblahblah foo;bar" CRLF
"a=group:BUNDLE first second" CRLF
@ -1149,7 +1150,7 @@ const std::string kBasicAudioVideoOffer =
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level" CRLF
"a=setup:actpass" CRLF
"a=rtcp-mux" CRLF
"a=msid:track stream" CRLF
"a=msid:stream track" CRLF
"a=candidate:0 1 UDP 2130379007 10.0.0.36 62453 typ host" CRLF
"a=candidate:2 1 UDP 1694236671 24.6.134.204 62453 typ srflx raddr 10.0.0.36 rport 62453" CRLF
"a=candidate:3 1 UDP 100401151 162.222.183.171 49761 typ relay raddr 162.222.183.171 rport 49761" CRLF
@ -1171,8 +1172,8 @@ const std::string kBasicAudioVideoOffer =
"a=rtcp-fb:120 ccm fir" CRLF
"a=setup:active" CRLF
"a=rtcp-mux" CRLF
"a=msid:tracka streama" CRLF
"a=msid:trackb streamb" CRLF
"a=msid:streama tracka" CRLF
"a=msid:streamb trackb" CRLF
"a=candidate:0 1 UDP 2130379007 10.0.0.36 59530 typ host" CRLF
"a=candidate:0 2 UDP 2130379006 10.0.0.36 64378 typ host" CRLF
"a=candidate:2 2 UDP 1694236670 24.6.134.204 64378 typ srflx raddr 10.0.0.36 rport 64378" CRLF
@ -1426,7 +1427,7 @@ const std::string kH264AudioVideoOffer =
"a=ice-ufrag:4a799b2e" CRLF
"a=ice-pwd:e4cc12a910f106a0a744719425510e17" CRLF
"a=ice-lite" CRLF
"a=msid-semantic:WMS plus" CRLF
"a=msid-semantic:WMS stream streama" CRLF
"a=fingerprint:sha-256 DF:2E:AC:8A:FD:0A:8E:99:BF:5D:E8:3C:E7:FA:FB:08:3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C" CRLF
"a=group:BUNDLE first second" CRLF
"a=group:BUNDLE third" CRLF
@ -1448,7 +1449,7 @@ const std::string kH264AudioVideoOffer =
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level" CRLF
"a=setup:actpass" CRLF
"a=rtcp-mux" CRLF
"a=msid:track stream" CRLF
"a=msid:stream track" CRLF
"a=candidate:0 1 UDP 2130379007 10.0.0.36 62453 typ host" CRLF
"a=candidate:2 1 UDP 1694236671 24.6.134.204 62453 typ srflx raddr 10.0.0.36 rport 62453" CRLF
"a=candidate:3 1 UDP 100401151 162.222.183.171 49761 typ relay raddr 162.222.183.171 rport 49761" CRLF
@ -1469,8 +1470,8 @@ const std::string kH264AudioVideoOffer =
"a=recvonly" CRLF
"a=setup:active" CRLF
"a=rtcp-mux" CRLF
"a=msid:tracka streama" CRLF
"a=msid:trackb streamb" CRLF
"a=msid:streama tracka" CRLF
"a=msid:streamb trackb" CRLF
"a=candidate:0 1 UDP 2130379007 10.0.0.36 59530 typ host" CRLF
"a=candidate:0 2 UDP 2130379006 10.0.0.36 64378 typ host" CRLF
"a=candidate:2 2 UDP 1694236670 24.6.134.204 64378 typ srflx raddr 10.0.0.36 rport 64378" CRLF
@ -1672,22 +1673,29 @@ TEST_P(NewSdpTest, CheckMsid) {
ParseSdp(kBasicAudioVideoOffer);
ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
SdpAttribute::kMsidSemanticAttribute));
// note that we lose the extra pieces here
// it's not worth it to save them until they mean something
ASSERT_EQ("WMS", mSdp->GetAttributeList().GetMsidSemantic());
auto semantics = mSdp->GetAttributeList().GetMsidSemantic().mMsidSemantics;
ASSERT_EQ(2U, semantics.size());
ASSERT_EQ("WMS", semantics[0].semantic);
ASSERT_EQ(2U, semantics[0].msids.size());
ASSERT_EQ("stream", semantics[0].msids[0]);
ASSERT_EQ("streama", semantics[0].msids[1]);
ASSERT_EQ("foo", semantics[1].semantic);
ASSERT_EQ(1U, semantics[1].msids.size());
ASSERT_EQ("stream", semantics[1].msids[0]);
const SdpMsidAttributeList& msids1 =
mSdp->GetMediaSection(0).GetAttributeList().GetMsid();
ASSERT_EQ(1U, msids1.mMsids.size());
ASSERT_EQ("track", msids1.mMsids[0].identifier);
ASSERT_EQ("stream", msids1.mMsids[0].appdata);
ASSERT_EQ("stream", msids1.mMsids[0].identifier);
ASSERT_EQ("track", msids1.mMsids[0].appdata);
const SdpMsidAttributeList& msids2 =
mSdp->GetMediaSection(1).GetAttributeList().GetMsid();
ASSERT_EQ(2U, msids2.mMsids.size());
ASSERT_EQ("tracka", msids2.mMsids[0].identifier);
ASSERT_EQ("streama", msids2.mMsids[0].appdata);
ASSERT_EQ("trackb", msids2.mMsids[1].identifier);
ASSERT_EQ("streamb", msids2.mMsids[1].appdata);
ASSERT_EQ("streama", msids2.mMsids[0].identifier);
ASSERT_EQ("tracka", msids2.mMsids[0].appdata);
ASSERT_EQ("streamb", msids2.mMsids[1].identifier);
ASSERT_EQ("trackb", msids2.mMsids[1].appdata);
const SdpMsidAttributeList& msids3 =
mSdp->GetMediaSection(2).GetAttributeList().GetMsid();
ASSERT_EQ(1U, msids3.mMsids.size());

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

@ -1327,8 +1327,14 @@ class SignalingAgent {
}
}
// Right now we have no convenient way for this unit-test to learn the track
// ids of the tracks, so they can be queried later. We could either expose
// the JsepSessionImpl in some way, or we could parse the identifiers out of
// the SDP. For now, we just specify audio/video, since a given DOMMediaStream
// can have only one of each anyway. Once this is fixed, we will need to
// pass a real track id if we want to test that case.
mozilla::RefPtr<mozilla::MediaPipeline> GetMediaPipeline(
bool local, size_t stream, int track) {
bool local, size_t stream, bool video) {
SourceStreamInfo* streamInfo;
if (local) {
mozilla::SyncRunnable::DispatchToThread(
@ -1348,11 +1354,16 @@ class SignalingAgent {
const auto &pipelines = streamInfo->GetPipelines();
auto it = pipelines.find(track);
return (it == pipelines.end())? nullptr : it->second;
for (auto i = pipelines.begin(); i != pipelines.end(); ++i) {
if (i->second->IsVideo() == video) {
std::cout << "Got MediaPipeline " << i->second->trackid();
return i->second;
}
}
return nullptr;
}
void CheckMediaPipeline(int stream, int track, uint32_t flags,
void CheckMediaPipeline(int stream, bool video, uint32_t flags,
VideoSessionConduit::FrameRequestType frameRequestMethod =
VideoSessionConduit::FrameRequestNone) {
@ -1361,13 +1372,13 @@ class SignalingAgent {
<< ((flags & PIPELINE_SEND) ? "sending " : "receiving ")
<< ((flags & PIPELINE_VIDEO) ? "video" : "audio")
<< " pipeline (stream " << stream
<< ", track " << track << "); expect "
<< ", track " << video << "); expect "
<< ((flags & PIPELINE_RTCP_MUX) ? "MUX, " : "no MUX, ")
<< ((flags & PIPELINE_RTCP_NACK) ? "NACK." : "no NACK.")
<< std::endl;
mozilla::RefPtr<mozilla::MediaPipeline> pipeline =
GetMediaPipeline((flags & PIPELINE_LOCAL), stream, track);
GetMediaPipeline((flags & PIPELINE_LOCAL), stream, video);
ASSERT_TRUE(pipeline);
ASSERT_EQ(pipeline->IsDoingRtcpMux(), !!(flags & PIPELINE_RTCP_MUX));
// We cannot yet test send/recv with video.
@ -1938,12 +1949,12 @@ public:
a2_->CloseReceiveStreams();
// Check caller video settings for remote pipeline
a1_->CheckMediaPipeline(0, 1, (fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
a1_->CheckMediaPipeline(0, true, (fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
PIPELINE_VIDEO | rtcpFbFlags, frameRequestMethod);
// Check caller video settings for remote pipeline
// (Should use pli and nack, regardless of what was in the offer)
a2_->CheckMediaPipeline(0, 1,
a2_->CheckMediaPipeline(0, true,
(fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
PIPELINE_VIDEO |
PIPELINE_SEND |
@ -1978,12 +1989,12 @@ public:
a2_->CloseReceiveStreams();
// Check callee video settings for remote pipeline
a2_->CheckMediaPipeline(0, 1, (fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
a2_->CheckMediaPipeline(0, true, (fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
PIPELINE_VIDEO | rtcpFbFlags, frameRequestMethod);
// Check caller video settings for remote pipeline
// (Should use pli and nack, regardless of what was in the offer)
a1_->CheckMediaPipeline(0, 1,
a1_->CheckMediaPipeline(0, true,
(fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
PIPELINE_VIDEO |
PIPELINE_SEND |
@ -2559,12 +2570,12 @@ TEST_P(SignalingTest, FullCall)
// Check the low-level media pipeline
// for RTP and RTCP flows
// The first Local pipeline gets stored at 0
a1_->CheckMediaPipeline(0, 0, fRtcpMux ?
a1_->CheckMediaPipeline(0, false, fRtcpMux ?
PIPELINE_LOCAL | PIPELINE_RTCP_MUX | PIPELINE_SEND :
PIPELINE_LOCAL | PIPELINE_SEND);
// The first Remote pipeline gets stored at 0
a2_->CheckMediaPipeline(0, 0, (fRtcpMux ? PIPELINE_RTCP_MUX : 0));
a2_->CheckMediaPipeline(0, false, (fRtcpMux ? PIPELINE_RTCP_MUX : 0));
}
TEST_P(SignalingTest, FullCallAudioOnly)
@ -3397,10 +3408,8 @@ TEST_P(SignalingTest, AudioOnlyCalleeNoRtcpMux)
// Check the low-level media pipeline
// for RTP and RTCP flows
// The first Local pipeline gets stored at 0
a1_->CheckMediaPipeline(0, 0, PIPELINE_LOCAL | PIPELINE_SEND);
// The first Remote pipeline gets stored at 1
a2_->CheckMediaPipeline(0, 0, 0);
a1_->CheckMediaPipeline(0, false, PIPELINE_LOCAL | PIPELINE_SEND);
a2_->CheckMediaPipeline(0, false, 0);
}
@ -3537,18 +3546,18 @@ TEST_P(SignalingTest, FullCallAudioNoMuxVideoMux)
// Check the low-level media pipeline
// for RTP and RTCP flows
// The first Local pipeline gets stored at 0
a1_->CheckMediaPipeline(0, 0, PIPELINE_LOCAL | PIPELINE_SEND);
a1_->CheckMediaPipeline(0, false, PIPELINE_LOCAL | PIPELINE_SEND);
// Now check video mux.
a1_->CheckMediaPipeline(0, 1,
a1_->CheckMediaPipeline(0, true,
PIPELINE_LOCAL | (fRtcpMux ? PIPELINE_RTCP_MUX : 0) | PIPELINE_SEND |
PIPELINE_VIDEO);
// The first Remote pipeline gets stored at 0
a2_->CheckMediaPipeline(0, 0, 0);
a2_->CheckMediaPipeline(0, false, 0);
// Now check video mux.
a2_->CheckMediaPipeline(0, 1, (fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
a2_->CheckMediaPipeline(0, true, (fRtcpMux ? PIPELINE_RTCP_MUX : 0) |
PIPELINE_VIDEO | PIPELINE_RTCP_NACK, VideoSessionConduit::FrameRequestPli);
}

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

@ -4541,3 +4541,10 @@ pref("reader.font_type", "sans-serif");
// Whether or not the user has interacted with the reader mode toolbar.
// This is used to show a first-launch tip in reader mode.
pref("reader.has_used_toolbar", false);
#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
// Whether to allow, on a Linux system that doesn't support the necessary sandboxing
// features, loading Gecko Media Plugins unsandboxed. However, EME CDMs will not be
// loaded without sandboxing even if this pref is changed.
pref("media.gmp.insecure.allow", false);
#endif

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

@ -292,7 +292,7 @@ nsBaseChannel::ClassifyURI()
if (mLoadFlags & LOAD_CLASSIFY_URI) {
nsRefPtr<nsChannelClassifier> classifier = new nsChannelClassifier();
if (classifier) {
classifier->Start(this);
classifier->Start(this, false);
} else {
Cancel(NS_ERROR_OUT_OF_MEMORY);
}

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

@ -211,10 +211,14 @@ nsChannelClassifier::NotifyTrackingProtectionDisabled(nsIChannel *aChannel)
}
void
nsChannelClassifier::Start(nsIChannel *aChannel)
nsChannelClassifier::Start(nsIChannel *aChannel, bool aContinueBeginConnect)
{
mChannel = aChannel;
nsresult rv = StartInternal(aChannel);
if (aContinueBeginConnect) {
mChannelInternal = do_QueryInterface(aChannel);
}
nsresult rv = StartInternal();
if (NS_FAILED(rv)) {
// If we aren't getting a callback for any reason, assume a good verdict and
// make sure we resume the channel if necessary.
@ -223,7 +227,7 @@ nsChannelClassifier::Start(nsIChannel *aChannel)
}
nsresult
nsChannelClassifier::StartInternal(nsIChannel *aChannel)
nsChannelClassifier::StartInternal()
{
// Should only be called in the parent process.
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
@ -231,18 +235,18 @@ nsChannelClassifier::StartInternal(nsIChannel *aChannel)
// Don't bother to run the classifier on a load that has already failed.
// (this might happen after a redirect)
nsresult status;
aChannel->GetStatus(&status);
mChannel->GetStatus(&status);
if (NS_FAILED(status))
return status;
// Don't bother to run the classifier on a cached load that was
// previously classified as good.
if (HasBeenClassified(aChannel)) {
if (HasBeenClassified(mChannel)) {
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIURI> uri;
nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
// Don't bother checking certain types of URIs.
@ -285,13 +289,13 @@ nsChannelClassifier::StartInternal(nsIChannel *aChannel)
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> principal;
rv = securityManager->GetChannelResultPrincipal(aChannel,
rv = securityManager->GetChannelResultPrincipal(mChannel,
getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
bool expectCallback;
bool trackingProtectionEnabled = false;
(void)ShouldEnableTrackingProtection(aChannel, &trackingProtectionEnabled);
(void)ShouldEnableTrackingProtection(mChannel, &trackingProtectionEnabled);
rv = uriClassifier->Classify(principal, trackingProtectionEnabled, this,
&expectCallback);
@ -302,7 +306,7 @@ nsChannelClassifier::StartInternal(nsIChannel *aChannel)
if (expectCallback) {
// Suspend the channel, it will be resumed when we get the classifier
// callback.
rv = aChannel->Suspend();
rv = mChannel->Suspend();
if (NS_FAILED(rv)) {
// Some channels (including nsJSChannel) fail on Suspend. This
// shouldn't be fatal, but will prevent malware from being
@ -460,7 +464,7 @@ nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode)
// Should only be called in the parent process.
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
LOG(("nsChannelClassifier[%p]:OnClassifyComplete", this));
LOG(("nsChannelClassifier[%p]:OnClassifyComplete %d", this, aErrorCode));
if (mSuspendedChannel) {
MarkEntryClassified(aErrorCode);
@ -488,14 +492,14 @@ nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode)
"OnClassifyComplete", this, mChannel.get()));
mChannel->Resume();
}
nsresult rv;
nsCOMPtr<nsIHttpChannelInternal> channel = do_QueryInterface(mChannel, &rv);
// Even if we have cancelled the channel, we need to call
// Even if we have cancelled the channel, we may need to call
// ContinueBeginConnect so that we abort appropriately.
if (NS_SUCCEEDED(rv)) {
channel->ContinueBeginConnect();
if (mChannelInternal) {
mChannelInternal->ContinueBeginConnect();
}
mChannel = nullptr;
mChannelInternal = nullptr;
return NS_OK;
}

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

@ -10,7 +10,7 @@
#include "mozilla/Attributes.h"
class nsIChannel;
class nsIHttpChannelInternal;
class nsChannelClassifier MOZ_FINAL : public nsIURIClassifierCallback
{
@ -21,10 +21,10 @@ public:
NS_DECL_NSIURICLASSIFIERCALLBACK
// Calls nsIURIClassifier.Classify with the principal of the given channel,
// and cancels the channel on a bad verdict. If aChannel is
// nsIHttpChannelInternal, nsChannelClassifier must call
// ContinueBeginConnect once Start has successfully returned.
void Start(nsIChannel *aChannel);
// and cancels the channel on a bad verdict. If callContinueBeginConnect is true,
// and aChannel is an nsIHttpChannelInternal, nsChannelClassifier must call
// nsIHttpChannelInternal.ContinueBeginConnect once Start has returned.
void Start(nsIChannel *aChannel, bool aContinueBeginConnect);
// Whether or not tracking protection should be enabled on this channel.
nsresult ShouldEnableTrackingProtection(nsIChannel *aChannel, bool *result);
@ -34,6 +34,7 @@ private:
// True if the channel has been suspended.
bool mSuspendedChannel;
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIHttpChannelInternal> mChannelInternal;
~nsChannelClassifier() {}
// Caches good classifications for the channel principal.
@ -42,7 +43,7 @@ private:
// Helper function so that we ensure we call ContinueBeginConnect once
// Start is called. Returns NS_OK if and only if we will get a callback
// from the classifier service.
nsresult StartInternal(nsIChannel *aChannel);
nsresult StartInternal();
public:
// If we are blocking tracking content, update the corresponding flag in

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

@ -5,6 +5,14 @@
pref("security.tls.version.min", 1);
pref("security.tls.version.max", 3);
pref("security.tls.version.fallback-limit", 3);
# Do not add a site without filing a corresponding evangelism bug.
# bug 1095507, www.kredodirect.com.ua
# bug 1111354, web3.secureinternetbank.com
# bug 1112110, cmypage.kuronekoyamato.co.jp
# bug 1115883, www.timewarnercable.com and wayfarer.timewarnercable.com
# bug 1126652, www.animate-onlineshop.jp
# bug 1126654, www.gamers-onlineshop.jp
pref("security.tls.insecure_fallback_hosts", "www.kredodirect.com.ua,web3.secureinternetbank.com,cmypage.kuronekoyamato.co.jp,www.timewarnercable.com,wayfarer.timewarnercable.com,www.animate-onlineshop.jp,www.gamers-onlineshop.jp");
pref("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref", false);
pref("security.ssl.renego_unrestricted_hosts", "");

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

@ -97,6 +97,7 @@ NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo *ci,
, mCapsToClear(0)
, mRequestHead(nullptr)
, mIsDone(false)
, mClaimed(false)
, mCallbacks(callbacks)
, mConnectionInfo(ci)
{
@ -126,6 +127,16 @@ NullHttpTransaction::~NullHttpTransaction()
delete mRequestHead;
}
bool
NullHttpTransaction::Claim()
{
if (mClaimed) {
return false;
}
mClaimed = true;
return true;
}
void
NullHttpTransaction::SetConnection(nsAHttpConnection *conn)
{

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

@ -38,8 +38,11 @@ public:
nsIInterfaceRequestor *callbacks,
uint32_t caps);
bool Claim();
// Overload of nsAHttpTransaction methods
bool IsNullTransaction() MOZ_OVERRIDE MOZ_FINAL { return true; }
NullHttpTransaction *QueryNullTransaction() MOZ_OVERRIDE MOZ_FINAL { return this; }
bool ResponseTimeoutEnabled() const MOZ_OVERRIDE MOZ_FINAL {return true; }
PRIntervalTime ResponseTimeout() MOZ_OVERRIDE MOZ_FINAL
{
@ -62,6 +65,7 @@ private:
uint32_t mCapsToClear;
nsHttpRequestHead *mRequestHead;
bool mIsDone;
bool mClaimed;
protected:
nsRefPtr<nsAHttpConnection> mConnection;

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

@ -750,6 +750,15 @@ TLSFilterTransaction::IsNullTransaction()
return mTransaction->IsNullTransaction();
}
NullHttpTransaction *
TLSFilterTransaction::QueryNullTransaction()
{
if (!mTransaction) {
return nullptr;
}
return mTransaction->QueryNullTransaction();
}
nsHttpTransaction *
TLSFilterTransaction::QueryHttpTransaction()
{

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

@ -85,6 +85,7 @@ struct PRSocketOptionData;
namespace mozilla { namespace net {
class nsHttpRequestHead;
class NullHttpTransaction;
class TLSFilterTransaction;
class NudgeTunnelCallback : public nsISupports
@ -127,6 +128,7 @@ public:
// nsAHttpTransaction overloads
nsHttpPipeline *QueryPipeline() MOZ_OVERRIDE;
bool IsNullTransaction() MOZ_OVERRIDE;
NullHttpTransaction *QueryNullTransaction() MOZ_OVERRIDE;
nsHttpTransaction *QueryHttpTransaction() MOZ_OVERRIDE;
SpdyConnectTransaction *QuerySpdyConnectTransaction() MOZ_OVERRIDE;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше