зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team a=merge
This commit is contained in:
Коммит
6922db3c44
2
CLOBBER
2
CLOBBER
|
@ -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, <rack));
|
||||
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;
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче