mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to fx-team. a=merge
This commit is contained in:
commit
b5a94e6300
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
|
@ -19,13 +19,13 @@
|
||||
<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="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
|
||||
|
@ -19,13 +19,13 @@
|
||||
<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="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "c175a29477e68e70142687587844423a75dcf4cc",
|
||||
"revision": "23fc9f3f470e238bacb1a6b8ca978db4e63e0b55",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,11 +17,11 @@
|
||||
<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="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
|
||||
|
@ -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="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -17,12 +17,12 @@
|
||||
<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="b77e0d56d197e0ee02d801a25c784130d888c9db"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="69ac77cfa938fae2763ac426a80ca6e5feb6ad25"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8aee09c106f479f36c57b2a29af72d455e359211"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f59d8671fff36da22236a4b270b93195889b7ff1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3e48bfe5f59bd54597d8304c42391a7849b8361f"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
|
@ -1790,6 +1790,7 @@ pref("print.enable_e10s_testing", true);
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// Enable e10s add-on interposition by default.
|
||||
pref("extensions.interposition.enabled", true);
|
||||
pref("extensions.interposition.prefetching", true);
|
||||
#endif
|
||||
|
||||
pref("browser.defaultbrowser.notificationbar", false);
|
||||
|
@ -838,6 +838,7 @@ nsDocShell::nsDocShell():
|
||||
mAllowKeywordFixup(false),
|
||||
mIsOffScreenBrowser(false),
|
||||
mIsActive(true),
|
||||
mIsPrerendered(false),
|
||||
mIsAppTab(false),
|
||||
mUseGlobalHistory(false),
|
||||
mInPrivateBrowsing(false),
|
||||
@ -3386,6 +3387,11 @@ nsDocShell::SetDocLoaderParent(nsDocLoader * aParent)
|
||||
{
|
||||
SetIsActive(value);
|
||||
}
|
||||
if (NS_SUCCEEDED(parentAsDocShell->GetIsPrerendered(&value))) {
|
||||
if (value) {
|
||||
SetIsPrerendered(true);
|
||||
}
|
||||
}
|
||||
if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))) {
|
||||
value = false;
|
||||
}
|
||||
@ -6052,6 +6058,22 @@ nsDocShell::GetIsActive(bool *aIsActive)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetIsPrerendered(bool aPrerendered)
|
||||
{
|
||||
MOZ_ASSERT(!aPrerendered || !mIsPrerendered,
|
||||
"SetIsPrerendered(true) called on already prerendered docshell");
|
||||
mIsPrerendered = aPrerendered;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsPrerendered(bool *aIsPrerendered)
|
||||
{
|
||||
*aIsPrerendered = mIsPrerendered;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetIsAppTab(bool aIsAppTab)
|
||||
{
|
||||
@ -8553,8 +8575,8 @@ nsDocShell::RestoreFromHistory()
|
||||
|
||||
// this.AddChild(child) calls child.SetDocLoaderParent(this), meaning
|
||||
// that the child inherits our state. Among other things, this means
|
||||
// that the child inherits our mIsActive and mInPrivateBrowsing, which
|
||||
// is what we want.
|
||||
// that the child inherits our mIsActive, mIsPrerendered and mInPrivateBrowsing,
|
||||
// which is what we want.
|
||||
AddChild(childItem);
|
||||
|
||||
childShell->SetAllowPlugins(allowPlugins);
|
||||
|
@ -877,6 +877,7 @@ protected:
|
||||
bool mAllowKeywordFixup;
|
||||
bool mIsOffScreenBrowser;
|
||||
bool mIsActive;
|
||||
bool mIsPrerendered;
|
||||
bool mIsAppTab;
|
||||
bool mUseGlobalHistory;
|
||||
bool mInPrivateBrowsing;
|
||||
|
@ -54,7 +54,7 @@ interface nsITabParent;
|
||||
|
||||
typedef unsigned long nsLoadFlags;
|
||||
|
||||
[scriptable, builtinclass, uuid(c2756385-bc54-417b-9ae4-c5a40053a2a3)]
|
||||
[scriptable, builtinclass, uuid(fef3bae1-6673-4c49-9f5a-fcc075926730)]
|
||||
interface nsIDocShell : nsIDocShellTreeItem
|
||||
{
|
||||
/**
|
||||
@ -619,6 +619,13 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
*/
|
||||
attribute boolean isActive;
|
||||
|
||||
/**
|
||||
* Puts the docshell in prerendering mode. noscript because we want only
|
||||
* native code to be able to put a docshell in prerendering.
|
||||
*/
|
||||
[noscript] void SetIsPrerendered(in boolean prerendered);
|
||||
readonly attribute boolean isPrerendered;
|
||||
|
||||
/**
|
||||
* The ID of the docshell in the session history.
|
||||
*/
|
||||
|
@ -60,14 +60,8 @@ AnimationTimeline::FastForward(const TimeStamp& aTimeStamp)
|
||||
return;
|
||||
}
|
||||
|
||||
// Bug 1113413: If the refresh driver has just been restored from test
|
||||
// control it's possible that aTimeStamp could be before the most recent
|
||||
// refresh.
|
||||
if (refreshDriver &&
|
||||
aTimeStamp < refreshDriver->MostRecentRefresh()) {
|
||||
mFastForwardTime = refreshDriver->MostRecentRefresh();
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(!refreshDriver || aTimeStamp >= refreshDriver->MostRecentRefresh(),
|
||||
"aTimeStamp must be >= the refresh driver time");
|
||||
|
||||
// FIXME: For all animations attached to this timeline, we should mark
|
||||
// their target elements as needing restyling. Otherwise, tasks that run
|
||||
|
@ -67,4 +67,36 @@ async_test(function(t) {
|
||||
}, 'ready promise is rejected when a transition is cancelled by updating'
|
||||
+ ' transition-property');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
|
||||
// Set up pending transition
|
||||
div.style.marginLeft = '0px';
|
||||
window.getComputedStyle(div).marginLeft;
|
||||
div.style.transition = 'margin-left 100s';
|
||||
div.style.marginLeft = '100px';
|
||||
window.getComputedStyle(div).marginLeft;
|
||||
|
||||
var player = div.getAnimationPlayers()[0];
|
||||
assert_equals(player.playState, 'pending', 'Player is initially pending');
|
||||
|
||||
// Set up listeners on ready promise
|
||||
player.ready.then(t.step_func(function() {
|
||||
assert_unreached('ready promise was fulfilled');
|
||||
})).catch(t.step_func(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'ready promise is rejected with AbortError');
|
||||
assert_equals(player.playState, 'idle',
|
||||
'Player is idle after transition was cancelled');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
|
||||
// Now update the transition to animate to something not-interpolable
|
||||
div.style.marginLeft = 'auto';
|
||||
window.getComputedStyle(div).marginLeft;
|
||||
|
||||
}, 'ready promise is rejected when a transition is cancelled by changing'
|
||||
+ ' the transition property to something not interpolable');
|
||||
|
||||
</script>
|
||||
|
@ -7,7 +7,7 @@ skip-if = buildapp == 'mulet'
|
||||
[css-animations/test_animations-dynamic-changes.html]
|
||||
[css-animations/test_animation-effect-name.html]
|
||||
[css-animations/test_animation-pausing.html]
|
||||
skip-if = os == "mac" && os_version == "10.8" # disabled until bug 1112480 lands
|
||||
skip-if = os == "win" || (os == "mac" && os_version == "10.8") # disabled until bug 1112480 lands
|
||||
[css-animations/test_animation-player-playstate.html]
|
||||
[css-animations/test_animation-player-ready.html]
|
||||
[css-animations/test_animation-target.html]
|
||||
|
@ -407,7 +407,13 @@ this.PermissionsTable = { geolocation: {
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"nfc": {
|
||||
"audio-capture:3gpp": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"nfc": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: ALLOW_ACTION,
|
||||
|
@ -201,11 +201,7 @@ EventSource::Init(nsISupports* aOwner,
|
||||
|
||||
// The conditional here is historical and not necessarily sane.
|
||||
if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) {
|
||||
const char *filename;
|
||||
if (nsJSUtils::GetCallingLocation(cx, &filename, &mScriptLine)) {
|
||||
mScriptFile.AssignASCII(filename);
|
||||
}
|
||||
|
||||
nsJSUtils::GetCallingLocation(cx, mScriptFile, &mScriptLine);
|
||||
mInnerWindowID = nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx);
|
||||
}
|
||||
|
||||
|
@ -83,8 +83,11 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, aProxy));
|
||||
if (HasPropertyOnPrototype(aCx, aProxy, aId)) {
|
||||
bool hasOnPrototype;
|
||||
if (!HasPropertyOnPrototype(aCx, aProxy, aId, &hasOnPrototype)) {
|
||||
return false;
|
||||
}
|
||||
if (hasOnPrototype) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -94,6 +97,7 @@ WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
|
||||
}
|
||||
|
||||
// Grab the DOM window.
|
||||
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, aProxy));
|
||||
nsGlobalWindow* win = xpc::WindowOrNull(global);
|
||||
if (win->Length() > 0) {
|
||||
nsCOMPtr<nsIDOMWindow> childWin = win->GetChildWindow(str);
|
||||
|
@ -3364,12 +3364,7 @@ nsContentUtils::ReportToConsoleNonLocalized(const nsAString& aErrorText,
|
||||
if (!aLineNumber) {
|
||||
JSContext *cx = GetCurrentJSContext();
|
||||
if (cx) {
|
||||
const char* filename;
|
||||
uint32_t lineno;
|
||||
if (nsJSUtils::GetCallingLocation(cx, &filename, &lineno)) {
|
||||
spec = filename;
|
||||
aLineNumber = lineno;
|
||||
}
|
||||
nsJSUtils::GetCallingLocation(cx, spec, &aLineNumber);
|
||||
}
|
||||
}
|
||||
if (spec.IsEmpty() && aURI)
|
||||
|
@ -112,6 +112,9 @@ nsElementFrameLoaderOwner::EnsureFrameLoader()
|
||||
// Strangely enough, this method doesn't actually ensure that the
|
||||
// frameloader exists. It's more of a best-effort kind of thing.
|
||||
mFrameLoader = nsFrameLoader::Create(thisElement, mNetworkCreated);
|
||||
if (mIsPrerendered) {
|
||||
mFrameLoader->SetIsPrerendered();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -135,6 +138,14 @@ nsElementFrameLoaderOwner::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsElementFrameLoaderOwner::SetIsPrerendered()
|
||||
{
|
||||
MOZ_ASSERT(!mFrameLoader, "Please call SetIsPrerendered before frameLoader is created");
|
||||
mIsPrerendered = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsElementFrameLoaderOwner::LoadSrc()
|
||||
{
|
||||
|
@ -33,6 +33,7 @@ class nsElementFrameLoaderOwner : public nsIFrameLoaderOwner
|
||||
public:
|
||||
explicit nsElementFrameLoaderOwner(mozilla::dom::FromParser aFromParser)
|
||||
: mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK)
|
||||
, mIsPrerendered(false)
|
||||
, mBrowserFrameListenersRegistered(false)
|
||||
, mFrameLoaderCreationDisallowed(false)
|
||||
{
|
||||
@ -70,6 +71,7 @@ protected:
|
||||
*/
|
||||
bool mNetworkCreated;
|
||||
|
||||
bool mIsPrerendered;
|
||||
bool mBrowserFrameListenersRegistered;
|
||||
bool mFrameLoaderCreationDisallowed;
|
||||
};
|
||||
|
@ -154,6 +154,7 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, bool aNetworkCreated)
|
||||
: mOwnerContent(aOwner)
|
||||
, mAppIdSentToPermissionManager(nsIScriptSecurityManager::NO_APP_ID)
|
||||
, mDetachedSubdocViews(nullptr)
|
||||
, mIsPrerendered(false)
|
||||
, mDepthTooGreat(false)
|
||||
, mIsTopLevelContent(false)
|
||||
, mDestroyCalled(false)
|
||||
@ -295,6 +296,15 @@ nsFrameLoader::LoadURI(nsIURI* aURI)
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::SetIsPrerendered()
|
||||
{
|
||||
MOZ_ASSERT(!mDocShell, "Please call SetIsPrerendered before docShell is created");
|
||||
mIsPrerendered = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameLoader::ReallyStartLoading()
|
||||
{
|
||||
@ -1613,6 +1623,11 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
|
||||
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
|
||||
|
||||
if (mIsPrerendered) {
|
||||
nsresult rv = mDocShell->SetIsPrerendered(true);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// Apply sandbox flags even if our owner is not an iframe, as this copies
|
||||
// flags from our owning content's owning document.
|
||||
uint32_t sandboxFlags = 0;
|
||||
|
@ -331,6 +331,7 @@ private:
|
||||
// a reframe, so that we know not to restore the presentation.
|
||||
nsCOMPtr<nsIDocument> mContainerDocWhileDetached;
|
||||
|
||||
bool mIsPrerendered : 1;
|
||||
bool mDepthTooGreat : 1;
|
||||
bool mIsTopLevelContent : 1;
|
||||
bool mDestroyCalled : 1;
|
||||
|
@ -951,6 +951,7 @@ GK_ATOM(precedingSibling, "preceding-sibling")
|
||||
GK_ATOM(predicate, "predicate")
|
||||
GK_ATOM(prefix, "prefix")
|
||||
GK_ATOM(preload, "preload")
|
||||
GK_ATOM(prerendered, "prerendered")
|
||||
GK_ATOM(preserve, "preserve")
|
||||
GK_ATOM(preserveSpace, "preserve-space")
|
||||
GK_ATOM(preventdefault, "preventdefault")
|
||||
|
@ -1118,6 +1118,8 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
mCanSkipCCGeneration(0),
|
||||
mVRDevicesInitialized(false)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsLayoutStatics::AddRef();
|
||||
|
||||
// Initialize the PRCList (this).
|
||||
@ -1218,10 +1220,23 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsGlobalWindow::AssertIsOnMainThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsGlobalWindow::Init()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
CallGetService(NS_ENTROPYCOLLECTOR_CONTRACTID, &gEntropyCollector);
|
||||
NS_ASSERTION(gEntropyCollector,
|
||||
"gEntropyCollector should have been initialized!");
|
||||
@ -1245,6 +1260,8 @@ DisconnectEventTargetObjects(nsPtrHashKey<DOMEventTargetHelper>* aKey,
|
||||
|
||||
nsGlobalWindow::~nsGlobalWindow()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
mEventTargetObjects.EnumerateEntries(DisconnectEventTargetObjects, nullptr);
|
||||
mEventTargetObjects.Clear();
|
||||
|
||||
@ -1363,6 +1380,8 @@ nsGlobalWindow::RemoveEventTargetObject(DOMEventTargetHelper* aObject)
|
||||
void
|
||||
nsGlobalWindow::ShutDown()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (gDumpFile && gDumpFile != stdout) {
|
||||
fclose(gDumpFile);
|
||||
}
|
||||
|
@ -334,6 +334,14 @@ public:
|
||||
typedef mozilla::TimeDuration TimeDuration;
|
||||
typedef nsDataHashtable<nsUint64HashKey, nsGlobalWindow*> WindowByIdTable;
|
||||
|
||||
static void
|
||||
AssertIsOnMainThread()
|
||||
#ifdef DEBUG
|
||||
;
|
||||
#else
|
||||
{ }
|
||||
#endif
|
||||
|
||||
// public methods
|
||||
nsPIDOMWindow* GetPrivateParent();
|
||||
|
||||
@ -670,6 +678,8 @@ public:
|
||||
}
|
||||
|
||||
static nsGlobalWindow* GetOuterWindowWithId(uint64_t aWindowID) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!sWindowsById) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -679,6 +689,8 @@ public:
|
||||
}
|
||||
|
||||
static nsGlobalWindow* GetInnerWindowWithId(uint64_t aInnerWindowID) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!sWindowsById) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -688,6 +700,8 @@ public:
|
||||
}
|
||||
|
||||
static WindowByIdTable* GetWindowsTable() {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
return sWindowsById;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ interface nsIDOMElement;
|
||||
interface nsITabParent;
|
||||
interface nsILoadContext;
|
||||
|
||||
[scriptable, builtinclass, uuid(7600aa92-88dc-491c-896d-0564159b6a66)]
|
||||
[scriptable, builtinclass, uuid(28b6b043-46ec-412f-9be9-db22938b0d6d)]
|
||||
interface nsIFrameLoader : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -49,6 +49,11 @@ interface nsIFrameLoader : nsISupports
|
||||
*/
|
||||
void loadURI(in nsIURI aURI);
|
||||
|
||||
/**
|
||||
* Puts the frameloader in prerendering mode.
|
||||
*/
|
||||
void setIsPrerendered();
|
||||
|
||||
/**
|
||||
* Destroy the frame loader and everything inside it. This will
|
||||
* clear the weak owner content reference.
|
||||
@ -192,7 +197,7 @@ class nsFrameLoader;
|
||||
|
||||
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
|
||||
|
||||
[scriptable, uuid(5879040e-83e9-40e3-b2bb-5ddf43b76e47)]
|
||||
[scriptable, uuid(c4abebcf-55f3-47d4-af15-151311971255)]
|
||||
interface nsIFrameLoaderOwner : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -201,6 +206,11 @@ interface nsIFrameLoaderOwner : nsISupports
|
||||
readonly attribute nsIFrameLoader frameLoader;
|
||||
[noscript, notxpcom] alreadyAddRefed_nsFrameLoader GetFrameLoader();
|
||||
|
||||
/**
|
||||
* Puts the FrameLoaderOwner in prerendering mode.
|
||||
*/
|
||||
void setIsPrerendered();
|
||||
|
||||
/**
|
||||
* Swap frame loaders with the given nsIFrameLoaderOwner. This may
|
||||
* only be posible in a very limited range of circumstances, or
|
||||
|
@ -173,11 +173,8 @@ CheckCSPForEval(JSContext* aCx, nsGlobalWindow* aWindow, ErrorResult& aError)
|
||||
|
||||
// Get the calling location.
|
||||
uint32_t lineNum = 0;
|
||||
const char *fileName;
|
||||
nsAutoString fileNameString;
|
||||
if (nsJSUtils::GetCallingLocation(aCx, &fileName, &lineNum)) {
|
||||
AppendUTF8toUTF16(fileName, fileNameString);
|
||||
} else {
|
||||
if (!nsJSUtils::GetCallingLocation(aCx, fileNameString, &lineNum)) {
|
||||
fileNameString.AssignLiteral("unknown");
|
||||
}
|
||||
|
||||
@ -233,10 +230,7 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
|
||||
}
|
||||
|
||||
// Get the calling location.
|
||||
const char *filename;
|
||||
if (nsJSUtils::GetCallingLocation(aCx, &filename, &mLineNo)) {
|
||||
mFileName.Assign(filename);
|
||||
}
|
||||
nsJSUtils::GetCallingLocation(aCx, mFileName, &mLineNo);
|
||||
}
|
||||
|
||||
nsJSScriptTimeoutHandler::~nsJSScriptTimeoutHandler()
|
||||
@ -353,10 +347,7 @@ nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, bool *aIsInterval,
|
||||
AssignJSFlatString(mExpr, expr);
|
||||
|
||||
// Get the calling location.
|
||||
const char *filename;
|
||||
if (nsJSUtils::GetCallingLocation(cx, &filename, &mLineNo)) {
|
||||
mFileName.Assign(filename);
|
||||
}
|
||||
nsJSUtils::GetCallingLocation(cx, mFileName, &mLineNo);
|
||||
} else if (funobj) {
|
||||
*aAllowEval = true;
|
||||
|
||||
|
@ -34,19 +34,28 @@
|
||||
using namespace mozilla::dom;
|
||||
|
||||
bool
|
||||
nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
|
||||
nsJSUtils::GetCallingLocation(JSContext* aContext, nsACString& aFilename,
|
||||
uint32_t* aLineno)
|
||||
{
|
||||
JS::AutoFilename filename;
|
||||
unsigned lineno = 0;
|
||||
|
||||
if (!JS::DescribeScriptedCaller(aContext, &filename, &lineno)) {
|
||||
if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*aFilename = filename.get();
|
||||
*aLineno = lineno;
|
||||
aFilename.Assign(filename.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsJSUtils::GetCallingLocation(JSContext* aContext, nsAString& aFilename,
|
||||
uint32_t* aLineno)
|
||||
{
|
||||
JS::AutoFilename filename;
|
||||
if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aFilename.Assign(NS_ConvertUTF8toUTF16(filename.get()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,9 @@ class Element;
|
||||
class nsJSUtils
|
||||
{
|
||||
public:
|
||||
static bool GetCallingLocation(JSContext* aContext, const char* *aFilename,
|
||||
static bool GetCallingLocation(JSContext* aContext, nsACString& aFilename,
|
||||
uint32_t* aLineno);
|
||||
static bool GetCallingLocation(JSContext* aContext, nsAString& aFilename,
|
||||
uint32_t* aLineno);
|
||||
|
||||
static nsIScriptGlobalObject *GetStaticScriptGlobal(JSObject* aObj);
|
||||
|
@ -324,6 +324,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
||||
// if aDeep is true, deal with aNode's children (and recurse into their
|
||||
// attributes and children).
|
||||
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
AutoJSContext cx;
|
||||
nsresult rv;
|
||||
|
||||
|
@ -1199,6 +1199,12 @@ nsObjectLoadingContent::GetFrameLoader()
|
||||
return loader.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::SetIsPrerendered()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherLoader)
|
||||
{
|
||||
|
@ -366,6 +366,10 @@ nsresult TestPaths() {
|
||||
"connect-src http://www.example.com/foo;sessionid=12,34" },
|
||||
{ "connect-src http://test.com/pathIncludingAz19-._~!$&'()*+=:@",
|
||||
"connect-src http://test.com/pathincludingaz19-._~!$&'()*+=:@" },
|
||||
{ "script-src http://www.example.com:88/.js",
|
||||
"script-src http://www.example.com:88/.js" },
|
||||
{ "script-src https://foo.com/_abc/abc_/_/_a_b_c_",
|
||||
"script-src https://foo.com/_abc/abc_/_/_a_b_c_" }
|
||||
};
|
||||
|
||||
uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
|
||||
@ -490,8 +494,6 @@ nsresult TestPoliciesWithInvalidSrc() {
|
||||
"script-src 'none'" },
|
||||
{ "script-src http://www.example.com:88//path-1",
|
||||
"script-src 'none'" },
|
||||
{ "script-src http://www.example.com:88/.js",
|
||||
"script-src 'none'" },
|
||||
{ "script-src http://www.example.com:88.js",
|
||||
"script-src 'none'" },
|
||||
{ "script-src http://www.example.com:*.js",
|
||||
|
@ -92,7 +92,10 @@ public:
|
||||
protected:
|
||||
JS::Rooted<JSObject*> mGlobalJSObject;
|
||||
JSContext* mCx;
|
||||
mutable nsISupports* mGlobalObject;
|
||||
mutable nsISupports* MOZ_UNSAFE_REF("Valid because GlobalObject is a stack "
|
||||
"class, and mGlobalObject points to the "
|
||||
"global, so it won't be destroyed as long "
|
||||
"as GlobalObject lives on the stack") mGlobalObject;
|
||||
};
|
||||
|
||||
// Class for representing optional arguments.
|
||||
|
@ -1613,7 +1613,7 @@ NativePropertyHooks sWorkerNativePropertyHooks = {
|
||||
bool
|
||||
GetPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id, bool* found,
|
||||
JS::Value* vp)
|
||||
JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
if (!js::GetObjectProto(cx, proxy, &proto)) {
|
||||
@ -1624,33 +1624,31 @@ GetPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasProp;
|
||||
if (!JS_HasPropertyById(cx, proto, id, &hasProp)) {
|
||||
if (!JS_HasPropertyById(cx, proto, id, found)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*found = hasProp;
|
||||
if (!hasProp || !vp) {
|
||||
if (!*found) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
if (!JS_ForwardGetPropertyTo(cx, proto, id, proxy, &value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*vp = value;
|
||||
return true;
|
||||
return JS_ForwardGetPropertyTo(cx, proto, id, proxy, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
HasPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id)
|
||||
JS::Handle<jsid> id, bool* has)
|
||||
{
|
||||
bool found;
|
||||
// We ignore an error from GetPropertyOnPrototype. We pass nullptr
|
||||
// for vp so that GetPropertyOnPrototype won't actually do a get.
|
||||
return !GetPropertyOnPrototype(cx, proxy, id, &found, nullptr) || found;
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
if (!js::GetObjectProto(cx, proxy, &proto)) {
|
||||
return false;
|
||||
}
|
||||
if (!proto) {
|
||||
*has = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return JS_HasPropertyById(cx, proto, id, has);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1670,7 +1668,16 @@ AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shadowPrototypeProperties || !HasPropertyOnPrototype(cx, proxy, id)) {
|
||||
bool shouldAppend = shadowPrototypeProperties;
|
||||
if (!shouldAppend) {
|
||||
bool has;
|
||||
if (!HasPropertyOnPrototype(cx, proxy, id, &has)) {
|
||||
return false;
|
||||
}
|
||||
shouldAppend = !has;
|
||||
}
|
||||
|
||||
if (shouldAppend) {
|
||||
if (!props.append(id)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1810,16 +1810,15 @@ ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
|
||||
bool
|
||||
ThrowConstructorWithoutNew(JSContext* cx, const char* name);
|
||||
|
||||
// vp is allowed to be null; in that case no get will be attempted,
|
||||
// and *found will simply indicate whether the property exists.
|
||||
bool
|
||||
GetPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id, bool* found,
|
||||
JS::Value* vp);
|
||||
JS::MutableHandle<JS::Value> vp);
|
||||
|
||||
//
|
||||
bool
|
||||
HasPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id);
|
||||
JS::Handle<jsid> id, bool* has);
|
||||
|
||||
|
||||
// Append the property names in "names" to "props". If
|
||||
|
@ -10104,15 +10104,41 @@ class CGDOMJSProxyHandler_getOwnPropDescriptor(ClassMethod):
|
||||
"return true;\n" % (readonly, enumerable))
|
||||
templateValues = {'jsvalRef': 'desc.value()', 'jsvalHandle': 'desc.value()',
|
||||
'obj': 'proxy', 'successCode': fillDescriptor}
|
||||
condition = "!HasPropertyOnPrototype(cx, proxy, id)"
|
||||
|
||||
computeCondition = dedent("""
|
||||
bool hasOnProto;
|
||||
if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
|
||||
return false;
|
||||
}
|
||||
callNamedGetter = !hasOnProto;
|
||||
""")
|
||||
if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
condition = "(!isXray || %s)" % condition
|
||||
condition = "!ignoreNamedProps && " + condition
|
||||
computeCondition = fill("""
|
||||
if (!isXray) {
|
||||
callNamedGetter = true;
|
||||
} else {
|
||||
$*{hasOnProto}
|
||||
}
|
||||
""",
|
||||
hasOnProto=computeCondition)
|
||||
|
||||
outerCondition = "!ignoreNamedProps"
|
||||
if self.descriptor.supportsIndexedProperties():
|
||||
condition = "!IsArrayIndex(index) && " + condition
|
||||
namedGet = (CGIfWrapper(CGProxyNamedGetter(self.descriptor, templateValues),
|
||||
condition).define() +
|
||||
"\n")
|
||||
outerCondition = "!IsArrayIndex(index) && " + outerCondition
|
||||
|
||||
namedGet = fill("""
|
||||
bool callNamedGetter = false;
|
||||
if (${outerCondition}) {
|
||||
$*{computeCondition}
|
||||
}
|
||||
if (callNamedGetter) {
|
||||
$*{namedGetCode}
|
||||
}
|
||||
""",
|
||||
outerCondition=outerCondition,
|
||||
computeCondition=computeCondition,
|
||||
namedGetCode=CGProxyNamedGetter(self.descriptor, templateValues).define())
|
||||
namedGet += "\n"
|
||||
else:
|
||||
namedGet = ""
|
||||
|
||||
@ -10345,8 +10371,16 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
|
||||
""",
|
||||
namedBody=namedBody)
|
||||
if not self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
delete = CGIfWrapper(CGGeneric(delete),
|
||||
"!HasPropertyOnPrototype(cx, proxy, id)").define()
|
||||
delete = fill("""
|
||||
bool hasOnProto;
|
||||
if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
|
||||
return false;
|
||||
}
|
||||
if (!hasOnProto) {
|
||||
$*{delete}
|
||||
}
|
||||
""",
|
||||
delete=delete)
|
||||
|
||||
delete += dedent("""
|
||||
|
||||
@ -10485,8 +10519,17 @@ class CGDOMJSProxyHandler_hasOwn(ClassMethod):
|
||||
""",
|
||||
presenceChecker=CGProxyNamedPresenceChecker(self.descriptor, foundVar="found").define())
|
||||
if not self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
named = CGIfWrapper(CGGeneric(named + "return true;\n"),
|
||||
"!HasPropertyOnPrototype(cx, proxy, id)").define()
|
||||
named = fill("""
|
||||
bool hasOnProto;
|
||||
if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
|
||||
return false;
|
||||
}
|
||||
if (!hasOnProto) {
|
||||
$*{protoLacksProperty}
|
||||
return true;
|
||||
}
|
||||
""",
|
||||
protoLacksProperty=named)
|
||||
named += "*bp = false;\n"
|
||||
else:
|
||||
named += "\n"
|
||||
@ -10593,7 +10636,7 @@ class CGDOMJSProxyHandler_get(ClassMethod):
|
||||
|
||||
getOnPrototype = dedent("""
|
||||
bool foundOnPrototype;
|
||||
if (!GetPropertyOnPrototype(cx, proxy, id, &foundOnPrototype, vp.address())) {
|
||||
if (!GetPropertyOnPrototype(cx, proxy, id, &foundOnPrototype, vp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -146,15 +146,22 @@ static const double THRESHOLD_LOW_PLAYBACKRATE_AUDIO = 0.5;
|
||||
// start playing afterward, so we need to stay alive.
|
||||
// 4) If autoplay could start playback in this element (if we got enough data),
|
||||
// then we need to stay alive.
|
||||
// 5) if the element is currently loading and not suspended,
|
||||
// script might be waiting for progress events or a 'suspend' event,
|
||||
// so we need to stay alive. If we're already suspended then (all other
|
||||
// conditions being met) it's OK to just disappear without firing any more
|
||||
// events, since we have the freedom to remain suspended indefinitely. Note
|
||||
// 5) if the element is currently loading, not suspended, and its source is
|
||||
// not a MediaSource, then script might be waiting for progress events or a
|
||||
// 'stalled' or 'suspend' event, so we need to stay alive.
|
||||
// If we're already suspended then (all other conditions being met),
|
||||
// it's OK to just disappear without firing any more events,
|
||||
// since we have the freedom to remain suspended indefinitely. Note
|
||||
// that we could use this 'suspended' loophole to garbage-collect a suspended
|
||||
// element in case 4 even if it had 'autoplay' set, but we choose not to.
|
||||
// If someone throws away all references to a loading 'autoplay' element
|
||||
// sound should still eventually play.
|
||||
// 6) If the source is a MediaSource, most loading events will not fire unless
|
||||
// appendBuffer() is called on a SourceBuffer, in which case something is
|
||||
// already referencing the SourceBuffer, which keeps the associated media
|
||||
// element alive. Further, a MediaSource will never time out the resource
|
||||
// fetch, and so should not keep the media element alive if it is
|
||||
// unreferenced. A pending 'stalled' event keeps the media element alive.
|
||||
//
|
||||
// Media elements owned by inactive documents (i.e. documents not contained in any
|
||||
// document viewer) should never hold a self-reference because none of the
|
||||
@ -684,7 +691,7 @@ void HTMLMediaElement::AbortExistingLoads()
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("emptied"));
|
||||
}
|
||||
|
||||
// We may have changed mPaused, mAutoplaying, mNetworkState and other
|
||||
// We may have changed mPaused, mAutoplaying, and other
|
||||
// things which can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
|
||||
@ -699,7 +706,6 @@ void HTMLMediaElement::NoSupportedMediaSourceError()
|
||||
mError = new MediaError(this, nsIDOMMediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE);
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("error"));
|
||||
// This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
|
||||
ChangeDelayLoadStatus(false);
|
||||
}
|
||||
|
||||
@ -814,7 +820,6 @@ void HTMLMediaElement::SelectResource()
|
||||
// The media element has neither a src attribute nor any source
|
||||
// element children, abort the load.
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY);
|
||||
// This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
|
||||
ChangeDelayLoadStatus(false);
|
||||
return;
|
||||
}
|
||||
@ -822,8 +827,6 @@ void HTMLMediaElement::SelectResource()
|
||||
ChangeDelayLoadStatus(true);
|
||||
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_LOADING);
|
||||
// Load event was delayed, and still is, so no need to call
|
||||
// AddRemoveSelfReference, since it must still be held
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("loadstart"));
|
||||
|
||||
// Delay setting mIsRunningSeletResource until after UpdatePreloadAction
|
||||
@ -2133,7 +2136,6 @@ HTMLMediaElement::ResetConnectionState()
|
||||
FireTimeUpdate(false);
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("ended"));
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY);
|
||||
AddRemoveSelfReference();
|
||||
ChangeDelayLoadStatus(false);
|
||||
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING);
|
||||
}
|
||||
@ -2858,7 +2860,6 @@ void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream)
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
|
||||
AddRemoveSelfReference();
|
||||
// FirstFrameLoaded() will be called when the stream has current data.
|
||||
}
|
||||
|
||||
@ -3010,7 +3011,6 @@ void HTMLMediaElement::Error(uint16_t aErrorCode)
|
||||
} else {
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
|
||||
}
|
||||
AddRemoveSelfReference();
|
||||
ChangeDelayLoadStatus(false);
|
||||
}
|
||||
|
||||
@ -3084,7 +3084,6 @@ void HTMLMediaElement::DownloadSuspended()
|
||||
}
|
||||
if (mBegun) {
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE);
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3092,7 +3091,6 @@ void HTMLMediaElement::DownloadResumed(bool aForceNetworkLoading)
|
||||
{
|
||||
if (mBegun || aForceNetworkLoading) {
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_LOADING);
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3145,6 +3143,8 @@ void HTMLMediaElement::CheckProgress(bool aHaveNewProgress)
|
||||
// is more progress.
|
||||
StopProgress();
|
||||
}
|
||||
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
|
||||
/* static */
|
||||
@ -3358,6 +3358,9 @@ void HTMLMediaElement::ChangeNetworkState(nsMediaNetworkState aState)
|
||||
// Fire 'suspend' event when entering NETWORK_IDLE and no error presented.
|
||||
DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
|
||||
}
|
||||
|
||||
// Changing mNetworkState affects AddRemoveSelfReference().
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
|
||||
bool HTMLMediaElement::CanActivateAutoplay()
|
||||
@ -3628,7 +3631,8 @@ void HTMLMediaElement::AddRemoveSelfReference()
|
||||
(!mPaused && mSrcStream && !mSrcStream->IsFinished()) ||
|
||||
(mDecoder && mDecoder->IsSeeking()) ||
|
||||
CanActivateAutoplay() ||
|
||||
mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING);
|
||||
(mMediaSource ? mProgressTimer :
|
||||
mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING));
|
||||
|
||||
if (needSelfReference != mHasSelfReference) {
|
||||
mHasSelfReference = needSelfReference;
|
||||
|
@ -94,6 +94,18 @@ ASSERT_ICC_CONTACT_TYPE_EQUALITY(Sdn, CARD_CONTACT_TYPE_SDN);
|
||||
|
||||
#undef ASSERT_ICC_CONTACT_TYPE_EQUALITY
|
||||
|
||||
/**
|
||||
* Enum IccMvnoType
|
||||
*/
|
||||
#define ASSERT_ICC_MVNO_TYPE_EQUALITY(webidlState, xpidlState) \
|
||||
ASSERT_EQUALITY(IccMvnoType, webidlState, xpidlState)
|
||||
|
||||
ASSERT_ICC_MVNO_TYPE_EQUALITY(Imsi, CARD_MVNO_TYPE_IMSI);
|
||||
ASSERT_ICC_MVNO_TYPE_EQUALITY(Spn, CARD_MVNO_TYPE_SPN);
|
||||
ASSERT_ICC_MVNO_TYPE_EQUALITY(Gid, CARD_MVNO_TYPE_GID);
|
||||
|
||||
#undef ASSERT_ICC_MVNO_TYPE_EQUALITY
|
||||
|
||||
#undef ASSERT_EQUALITY
|
||||
|
||||
} // namespace icc
|
||||
|
@ -384,8 +384,7 @@ Icc::UpdateContact(const JSContext* aCx, IccContactType aContactType,
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
Icc::MatchMvno(const nsAString& aMvnoType,
|
||||
const nsAString& aMvnoData,
|
||||
Icc::MatchMvno(IccMvnoType aMvnoType, const nsAString& aMvnoData,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mProvider) {
|
||||
@ -395,8 +394,8 @@ Icc::MatchMvno(const nsAString& aMvnoType,
|
||||
|
||||
nsRefPtr<nsIDOMDOMRequest> request;
|
||||
nsresult rv = mProvider->MatchMvno(mClientId, GetOwner(),
|
||||
aMvnoType, aMvnoData,
|
||||
getter_AddRefs(request));
|
||||
static_cast<uint32_t>(aMvnoType),
|
||||
aMvnoData, getter_AddRefs(request));
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
MatchMvno(const nsAString& aMvnoType, const nsAString& aMatchData,
|
||||
MatchMvno(IccMvnoType aMvnoType, const nsAString& aMatchData,
|
||||
ErrorResult& aRv);
|
||||
|
||||
IMPL_EVENT_HANDLER(iccinfochange)
|
||||
|
@ -17,10 +17,48 @@ interface nsIIccListener : nsISupports
|
||||
void notifyIccInfoChanged();
|
||||
};
|
||||
|
||||
[scriptable, uuid(6136acab-b50e-494a-a86d-df392a032897)]
|
||||
interface nsIIccChannelCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
* Callback function to notify on successfully opening a logical channel.
|
||||
*
|
||||
* @param channel
|
||||
* The Channel Number/Handle that is successfully opened.
|
||||
*/
|
||||
void notifyOpenChannelSuccess(in long channel);
|
||||
|
||||
/**
|
||||
* Callback function to notify on successfully closing the logical channel.
|
||||
*
|
||||
*/
|
||||
void notifyCloseChannelSuccess();
|
||||
|
||||
/**
|
||||
* Callback function to notify the status of 'iccExchangeAPDU' command.
|
||||
*
|
||||
* @param sw1
|
||||
* Response's First Status Byte
|
||||
* @param sw2
|
||||
* Response's Second Status Byte
|
||||
* @param data
|
||||
* Response's data
|
||||
*/
|
||||
void notifyExchangeAPDUResponse(in octet sw1,
|
||||
in octet sw2,
|
||||
in DOMString data);
|
||||
|
||||
/**
|
||||
* Callback function to notify error
|
||||
*
|
||||
*/
|
||||
void notifyError(in DOMString error);
|
||||
};
|
||||
|
||||
/**
|
||||
* XPCOM component (in the content process) that provides the ICC information.
|
||||
*/
|
||||
[scriptable, uuid(937213c3-f64e-4f58-b4e0-3010f219d0c3)]
|
||||
[scriptable, uuid(bf985ee1-14c9-43c6-a471-8ab52fb24b0d)]
|
||||
interface nsIIccProvider : nsISupports
|
||||
{
|
||||
// MUST match enum IccCardState in MozIcc.webidl!
|
||||
@ -85,6 +123,11 @@ interface nsIIccProvider : nsISupports
|
||||
const unsigned long CARD_CONTACT_TYPE_FDN = 1;
|
||||
const unsigned long CARD_CONTACT_TYPE_SDN = 2;
|
||||
|
||||
// MUST match with enum IccMvnoType in MozIcc.webidl
|
||||
const unsigned long CARD_MVNO_TYPE_IMSI = 0;
|
||||
const unsigned long CARD_MVNO_TYPE_SPN = 1;
|
||||
const unsigned long CARD_MVNO_TYPE_GID = 2;
|
||||
|
||||
/**
|
||||
* Called when a content process registers receiving unsolicited messages from
|
||||
* RadioInterfaceLayer in the chrome process. Only a content process that has
|
||||
@ -161,27 +204,39 @@ interface nsIIccProvider : nsISupports
|
||||
in jsval contact,
|
||||
in DOMString pin2);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Secure Card Icc communication channel
|
||||
*/
|
||||
nsIDOMDOMRequest iccOpenChannel(in unsigned long clientId,
|
||||
in nsIDOMWindow window,
|
||||
in DOMString aid);
|
||||
void iccOpenChannel(in unsigned long clientId,
|
||||
in DOMString aid,
|
||||
in nsIIccChannelCallback callback);
|
||||
|
||||
nsIDOMDOMRequest iccExchangeAPDU(in unsigned long clientId,
|
||||
in nsIDOMWindow window,
|
||||
in long channel,
|
||||
in jsval apdu);
|
||||
/**
|
||||
* Exchange Command APDU (C-APDU) with SIM on the given logical channel.
|
||||
* Note that 'P3' parameter could be Le/Lc depending on command APDU case.
|
||||
* For Case 1 scenario (when only command header is present), the value
|
||||
* of 'P3' should be set to '-1' explicitly.
|
||||
* Refer to 3G TS 31.101 , 10.2 'Command APDU Structure' for all the cases.
|
||||
*/
|
||||
void iccExchangeAPDU(in unsigned long clientId,
|
||||
in long channel,
|
||||
in octet cla,
|
||||
in octet ins,
|
||||
in octet p1,
|
||||
in octet p2,
|
||||
in short p3,
|
||||
in DOMString data,
|
||||
in nsIIccChannelCallback callback);
|
||||
|
||||
nsIDOMDOMRequest iccCloseChannel(in unsigned long clientId,
|
||||
in nsIDOMWindow window,
|
||||
in long channel);
|
||||
void iccCloseChannel(in unsigned long clientId,
|
||||
in long channel,
|
||||
in nsIIccChannelCallback callback);
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
nsIDOMDOMRequest matchMvno(in unsigned long clientId,
|
||||
in nsIDOMWindow window,
|
||||
in DOMString mvnoType,
|
||||
in unsigned long mvnoType,
|
||||
in DOMString mvnoData);
|
||||
};
|
||||
|
@ -168,16 +168,7 @@ IDBRequest::CaptureCaller(nsAString& aFilename, uint32_t* aLineNo)
|
||||
MOZ_ASSERT(aLineNo);
|
||||
|
||||
ThreadsafeAutoJSContext cx;
|
||||
|
||||
const char* filename = nullptr;
|
||||
uint32_t lineNo = 0;
|
||||
if (!nsJSUtils::GetCallingLocation(cx, &filename, &lineNo)) {
|
||||
*aLineNo = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
aFilename.Assign(NS_ConvertUTF8toUTF16(filename));
|
||||
*aLineNo = lineNo;
|
||||
nsJSUtils::GetCallingLocation(cx, aFilename, aLineNo);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "mozilla/dom/VideoStreamTrack.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsProxyRelease.h"
|
||||
@ -545,6 +546,33 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
bool Check3gppPermission()
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = mRecorder->GetOwner()->GetExtantDoc();
|
||||
if (!doc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t appStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
doc->NodePrincipal()->GetAppStatus(&appStatus);
|
||||
|
||||
// Certified applications can always assign AUDIO_3GPP
|
||||
if (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> pm =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||
|
||||
if (!pm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t perm = nsIPermissionManager::DENY_ACTION;
|
||||
pm->TestExactPermissionFromPrincipal(doc->NodePrincipal(), "audio-capture:3gpp", &perm);
|
||||
return perm == nsIPermissionManager::ALLOW_ACTION;
|
||||
}
|
||||
|
||||
void InitEncoder(uint8_t aTrackTypes)
|
||||
{
|
||||
LOG(PR_LOG_DEBUG, ("Session.InitEncoder %p", this));
|
||||
@ -553,14 +581,8 @@ private:
|
||||
// Allocate encoder and bind with union stream.
|
||||
// At this stage, the API doesn't allow UA to choose the output mimeType format.
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = mRecorder->GetOwner()->GetExtantDoc();
|
||||
uint16_t appStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
if (doc) {
|
||||
doc->NodePrincipal()->GetAppStatus(&appStatus);
|
||||
}
|
||||
// Only allow certificated application can assign AUDIO_3GPP
|
||||
if (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED &&
|
||||
mRecorder->mMimeType.EqualsLiteral(AUDIO_3GPP)) {
|
||||
// Make sure the application has permission to assign AUDIO_3GPP
|
||||
if (mRecorder->mMimeType.EqualsLiteral(AUDIO_3GPP) && Check3gppPermission()) {
|
||||
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(AUDIO_3GPP), aTrackTypes);
|
||||
} else {
|
||||
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""), aTrackTypes);
|
||||
|
@ -148,6 +148,8 @@ private:
|
||||
// Register MediaRecorder into Document to listen the activity changes.
|
||||
void RegisterActivityObserver();
|
||||
void UnRegisterActivityObserver();
|
||||
|
||||
bool Check3gppPermission();
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -220,6 +220,13 @@ nsresult RtspTrackBuffer::ReadBuffer(uint8_t* aToBuffer, uint32_t aToBufferSize,
|
||||
// 3. No data in this buffer
|
||||
// 4. mIsStarted is not set
|
||||
while (1) {
|
||||
// Make sure the track buffer is started.
|
||||
// It could be stopped when RTSP connection is disconnected.
|
||||
if (!mIsStarted) {
|
||||
RTSPMLOG("ReadBuffer: mIsStarted is false");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Do not read from buffer if we are still in the playout delay duration.
|
||||
if (mDuringPlayoutDelay) {
|
||||
monitor.Wait();
|
||||
@ -261,10 +268,6 @@ nsresult RtspTrackBuffer::ReadBuffer(uint8_t* aToBuffer, uint32_t aToBufferSize,
|
||||
mConsumerIdx = (mConsumerIdx + 1) % BUFFER_SLOT_NUM;
|
||||
RTSPMLOG("BUFFER_SLOT_INVALID move forward");
|
||||
} else {
|
||||
// No data, and disconnected.
|
||||
if (!mIsStarted) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// No data, the decode thread is blocked here until we receive
|
||||
// OnMediaDataAvailable. The OnMediaDataAvailable will call WriteBuffer()
|
||||
// to wake up the decode thread.
|
||||
@ -616,6 +619,11 @@ RtspMediaResource::ReadFrameFromTrack(uint8_t* aBuffer, uint32_t aBufferSize,
|
||||
"ReadTrack index > mTrackBuffer");
|
||||
MOZ_ASSERT(aBuffer);
|
||||
|
||||
if (!mIsConnected) {
|
||||
RTSPMLOG("ReadFrameFromTrack: RTSP not connected");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return mTrackBuffer[aTrackIdx]->ReadBuffer(aBuffer, aBufferSize, aBytes,
|
||||
aTime, aFrameSize);
|
||||
}
|
||||
@ -769,6 +777,7 @@ RtspMediaResource::OnDisconnected(uint8_t aTrackIdx, nsresult aReason)
|
||||
aReason == NS_ERROR_NET_TIMEOUT) {
|
||||
// Report error code to Decoder.
|
||||
RTSPMLOG("Error in OnDisconnected 0x%x", aReason);
|
||||
mIsConnected = false;
|
||||
mDecoder->NetworkError();
|
||||
} else {
|
||||
// Resetting the decoder and media element when the connection
|
||||
|
@ -312,9 +312,12 @@ MediaSource::Attach(MediaSourceDecoder* aDecoder)
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MSE_DEBUG("MediaSource(%p)::Attach(aDecoder=%p) owner=%p", this, aDecoder, aDecoder->GetOwner());
|
||||
MOZ_ASSERT(aDecoder);
|
||||
MOZ_ASSERT(aDecoder->GetOwner());
|
||||
if (mReadyState != MediaSourceReadyState::Closed) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(!mMediaElement);
|
||||
mMediaElement = aDecoder->GetOwner()->GetMediaElement();
|
||||
MOZ_ASSERT(!mDecoder);
|
||||
mDecoder = aDecoder;
|
||||
mDecoder->AttachMediaSource(this);
|
||||
@ -335,6 +338,7 @@ MediaSource::Detach()
|
||||
}
|
||||
mDecoder->DetachMediaSource();
|
||||
mDecoder = nullptr;
|
||||
mMediaElement = nullptr;
|
||||
mFirstSourceBufferInitialized = false;
|
||||
SetReadyState(MediaSourceReadyState::Closed);
|
||||
if (mActiveSourceBuffers) {
|
||||
@ -487,6 +491,7 @@ MediaSource::WrapObject(JSContext* aCx)
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaSource, DOMEventTargetHelper,
|
||||
mMediaElement,
|
||||
mSourceBuffers, mActiveSourceBuffers)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(MediaSource, DOMEventTargetHelper)
|
||||
|
@ -128,6 +128,9 @@ private:
|
||||
nsRefPtr<SourceBufferList> mActiveSourceBuffers;
|
||||
|
||||
nsRefPtr<MediaSourceDecoder> mDecoder;
|
||||
// Ensures the media element remains alive to dispatch progress and
|
||||
// durationchanged events.
|
||||
nsRefPtr<HTMLMediaElement> mMediaElement;
|
||||
|
||||
nsRefPtr<nsIPrincipal> mPrincipal;
|
||||
|
||||
|
230
dom/media/tests/mochitest/dataChannel.js
Normal file
230
dom/media/tests/mochitest/dataChannel.js
Normal file
@ -0,0 +1,230 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function addInitialDataChannel(chain) {
|
||||
chain.insertBefore('PC_LOCAL_CREATE_OFFER', [
|
||||
['PC_LOCAL_CREATE_DATA_CHANNEL',
|
||||
function (test) {
|
||||
var channel = test.pcLocal.createDataChannel({});
|
||||
|
||||
is(channel.binaryType, "blob", channel + " is of binary type 'blob'");
|
||||
is(channel.readyState, "connecting", channel + " is in state: 'connecting'");
|
||||
|
||||
is(test.pcLocal.signalingState, STABLE,
|
||||
"Create datachannel does not change signaling state");
|
||||
|
||||
test.next();
|
||||
}
|
||||
]
|
||||
]);
|
||||
chain.insertAfter('PC_REMOTE_CREATE_ANSWER', [
|
||||
[
|
||||
'PC_LOCAL_SETUP_DATA_CHANNEL_CALLBACK',
|
||||
function (test) {
|
||||
test.waitForInitialDataChannel(test.pcLocal, function () {
|
||||
ok(true, test.pcLocal + " dataChannels[0] switched to 'open'");
|
||||
},
|
||||
// At this point a timeout failure will be of no value
|
||||
null);
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SETUP_DATA_CHANNEL_CALLBACK',
|
||||
function (test) {
|
||||
test.waitForInitialDataChannel(test.pcRemote, function () {
|
||||
ok(true, test.pcRemote + " dataChannels[0] switched to 'open'");
|
||||
},
|
||||
// At this point a timeout failure will be of no value
|
||||
null);
|
||||
test.next();
|
||||
}
|
||||
]
|
||||
]);
|
||||
chain.insertBefore('PC_LOCAL_CHECK_MEDIA_TRACKS', [
|
||||
[
|
||||
'PC_LOCAL_VERIFY_DATA_CHANNEL_STATE',
|
||||
function (test) {
|
||||
test.waitForInitialDataChannel(test.pcLocal, function() {
|
||||
test.next();
|
||||
}, function() {
|
||||
ok(false, test.pcLocal + " initial dataChannels[0] failed to switch to 'open'");
|
||||
//TODO: use stopAndExit() once bug 1019323 has landed
|
||||
unexpectedEventAndFinish(this, 'timeout')
|
||||
// to prevent test framework timeouts
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_VERIFY_DATA_CHANNEL_STATE',
|
||||
function (test) {
|
||||
test.waitForInitialDataChannel(test.pcRemote, function() {
|
||||
test.next();
|
||||
}, function() {
|
||||
ok(false, test.pcRemote + " initial dataChannels[0] failed to switch to 'open'");
|
||||
//TODO: use stopAndExit() once bug 1019323 has landed
|
||||
unexpectedEventAndFinish(this, 'timeout');
|
||||
// to prevent test framework timeouts
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
]
|
||||
]);
|
||||
chain.removeAfter('PC_REMOTE_CHECK_ICE_CONNECTIONS');
|
||||
chain.append([
|
||||
[
|
||||
'SEND_MESSAGE',
|
||||
function (test) {
|
||||
var message = "Lorem ipsum dolor sit amet";
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(data, message, "Message correctly transmitted from pcLocal to pcRemote.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_BLOB',
|
||||
function (test) {
|
||||
var contents = ["At vero eos et accusam et justo duo dolores et ea rebum."];
|
||||
var blob = new Blob(contents, { "type" : "text/plain" });
|
||||
|
||||
test.send(blob, function (channel, data) {
|
||||
ok(data instanceof Blob, "Received data is of instance Blob");
|
||||
is(data.size, blob.size, "Received data has the correct size.");
|
||||
|
||||
getBlobContent(data, function (recv_contents) {
|
||||
is(recv_contents, contents, "Received data has the correct content.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'CREATE_SECOND_DATA_CHANNEL',
|
||||
function (test) {
|
||||
test.createDataChannel({ }, function (sourceChannel, targetChannel) {
|
||||
is(sourceChannel.readyState, "open", sourceChannel + " is in state: 'open'");
|
||||
is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
|
||||
|
||||
is(targetChannel.binaryType, "blob", targetChannel + " is of binary type 'blob'");
|
||||
is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL',
|
||||
function (test) {
|
||||
var channels = test.pcRemote.dataChannels;
|
||||
var message = "Lorem ipsum dolor sit amet";
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(channels.indexOf(channel), channels.length - 1, "Last channel used");
|
||||
is(data, message, "Received message has the correct content.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_THROUGH_FIRST_CHANNEL',
|
||||
function (test) {
|
||||
var message = "Message through 1st channel";
|
||||
var options = {
|
||||
sourceChannel: test.pcLocal.dataChannels[0],
|
||||
targetChannel: test.pcRemote.dataChannels[0]
|
||||
};
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(test.pcRemote.dataChannels.indexOf(channel), 0, "1st channel used");
|
||||
is(data, message, "Received message has the correct content.");
|
||||
|
||||
test.next();
|
||||
}, options);
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_BACK_THROUGH_FIRST_CHANNEL',
|
||||
function (test) {
|
||||
var message = "Return a message also through 1st channel";
|
||||
var options = {
|
||||
sourceChannel: test.pcRemote.dataChannels[0],
|
||||
targetChannel: test.pcLocal.dataChannels[0]
|
||||
};
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(test.pcLocal.dataChannels.indexOf(channel), 0, "1st channel used");
|
||||
is(data, message, "Return message has the correct content.");
|
||||
|
||||
test.next();
|
||||
}, options);
|
||||
}
|
||||
],
|
||||
[
|
||||
'CREATE_NEGOTIATED_DATA_CHANNEL',
|
||||
function (test) {
|
||||
var options = {negotiated:true, id: 5, protocol:"foo/bar", ordered:false,
|
||||
maxRetransmits:500};
|
||||
test.createDataChannel(options, function (sourceChannel2, targetChannel2) {
|
||||
is(sourceChannel2.readyState, "open", sourceChannel2 + " is in state: 'open'");
|
||||
is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
|
||||
|
||||
is(targetChannel2.binaryType, "blob", targetChannel2 + " is of binary type 'blob'");
|
||||
is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
|
||||
|
||||
if (options.id != undefined) {
|
||||
is(sourceChannel2.id, options.id, sourceChannel2 + " id is:" + sourceChannel2.id);
|
||||
}
|
||||
else {
|
||||
options.id = sourceChannel2.id;
|
||||
}
|
||||
var reliable = !options.ordered ? false : (options.maxRetransmits || options.maxRetransmitTime);
|
||||
is(sourceChannel2.protocol, options.protocol, sourceChannel2 + " protocol is:" + sourceChannel2.protocol);
|
||||
is(sourceChannel2.reliable, reliable, sourceChannel2 + " reliable is:" + sourceChannel2.reliable);
|
||||
/*
|
||||
These aren't exposed by IDL yet
|
||||
is(sourceChannel2.ordered, options.ordered, sourceChannel2 + " ordered is:" + sourceChannel2.ordered);
|
||||
is(sourceChannel2.maxRetransmits, options.maxRetransmits, sourceChannel2 + " maxRetransmits is:" +
|
||||
sourceChannel2.maxRetransmits);
|
||||
is(sourceChannel2.maxRetransmitTime, options.maxRetransmitTime, sourceChannel2 + " maxRetransmitTime is:" +
|
||||
sourceChannel2.maxRetransmitTime);
|
||||
*/
|
||||
|
||||
is(targetChannel2.id, options.id, targetChannel2 + " id is:" + targetChannel2.id);
|
||||
is(targetChannel2.protocol, options.protocol, targetChannel2 + " protocol is:" + targetChannel2.protocol);
|
||||
is(targetChannel2.reliable, reliable, targetChannel2 + " reliable is:" + targetChannel2.reliable);
|
||||
/*
|
||||
These aren't exposed by IDL yet
|
||||
is(targetChannel2.ordered, options.ordered, targetChannel2 + " ordered is:" + targetChannel2.ordered);
|
||||
is(targetChannel2.maxRetransmits, options.maxRetransmits, targetChannel2 + " maxRetransmits is:" +
|
||||
targetChannel2.maxRetransmits);
|
||||
is(targetChannel2.maxRetransmitTime, options.maxRetransmitTime, targetChannel2 + " maxRetransmitTime is:" +
|
||||
targetChannel2.maxRetransmitTime);
|
||||
*/
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL2',
|
||||
function (test) {
|
||||
var channels = test.pcRemote.dataChannels;
|
||||
var message = "Lorem ipsum dolor sit amet";
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(channels.indexOf(channel), channels.length - 1, "Last channel used");
|
||||
is(data, message, "Received message has the correct content.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
]
|
||||
]);
|
||||
}
|
@ -4,6 +4,7 @@ skip-if = (os == 'win' && strictContentSandbox) || android_version == '10'
|
||||
support-files =
|
||||
head.js
|
||||
constraints.js
|
||||
dataChannel.js
|
||||
mediaStreamPlayback.js
|
||||
nonTrickleIce.js
|
||||
pc.js
|
||||
|
@ -584,7 +584,7 @@ function PeerConnectionTest(options) {
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when the peer connection has been closed successfully
|
||||
*/
|
||||
PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
|
||||
PeerConnectionTest.prototype.closePC = function PCT_closePC(onSuccess) {
|
||||
info("Closing peer connections");
|
||||
|
||||
var self = this;
|
||||
@ -655,6 +655,316 @@ PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
|
||||
closeEverything();
|
||||
};
|
||||
|
||||
/**
|
||||
* Close the open data channels, followed by the underlying peer connection
|
||||
*
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when all connections have been closed
|
||||
*/
|
||||
PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
|
||||
var self = this;
|
||||
var pendingDcClose = []
|
||||
var closeTimeout = null;
|
||||
|
||||
info("PeerConnectionTest.close() called");
|
||||
|
||||
function _closePeerConnection() {
|
||||
info("Now closing PeerConnection");
|
||||
self.closePC.call(self, onSuccess);
|
||||
}
|
||||
|
||||
function _closePeerConnectionCallback(index) {
|
||||
info("_closePeerConnection called with index " + index);
|
||||
var pos = pendingDcClose.indexOf(index);
|
||||
if (pos != -1) {
|
||||
pendingDcClose.splice(pos, 1);
|
||||
}
|
||||
else {
|
||||
info("_closePeerConnection index " + index + " is missing from pendingDcClose: " + pendingDcClose);
|
||||
}
|
||||
if (pendingDcClose.length === 0) {
|
||||
clearTimeout(closeTimeout);
|
||||
_closePeerConnection();
|
||||
}
|
||||
}
|
||||
|
||||
var myDataChannels = null;
|
||||
if (self.pcLocal) {
|
||||
myDataChannels = self.pcLocal.dataChannels;
|
||||
}
|
||||
else if (self.pcRemote) {
|
||||
myDataChannels = self.pcRemote.dataChannels;
|
||||
}
|
||||
var length = myDataChannels.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var dataChannel = myDataChannels[i];
|
||||
if (dataChannel.readyState !== "closed") {
|
||||
pendingDcClose.push(i);
|
||||
self.closeDataChannels(i, _closePeerConnectionCallback);
|
||||
}
|
||||
}
|
||||
if (pendingDcClose.length === 0) {
|
||||
_closePeerConnection();
|
||||
}
|
||||
else {
|
||||
closeTimeout = setTimeout(function() {
|
||||
ok(false, "Failed to properly close data channels: " +
|
||||
pendingDcClose);
|
||||
_closePeerConnection();
|
||||
}, 60000);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Close the specified data channels
|
||||
*
|
||||
* @param {Number} index
|
||||
* Index of the data channels to close on both sides
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when the data channels has been closed
|
||||
*/
|
||||
PeerConnectionTest.prototype.closeDataChannels = function PCT_closeDataChannels(index, onSuccess) {
|
||||
info("closeDataChannels called with index: " + index);
|
||||
var localChannel = null;
|
||||
if (this.pcLocal) {
|
||||
localChannel = this.pcLocal.dataChannels[index];
|
||||
}
|
||||
var remoteChannel = null;
|
||||
if (this.pcRemote) {
|
||||
remoteChannel = this.pcRemote.dataChannels[index];
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var wait = false;
|
||||
var pollingMode = false;
|
||||
var everythingClosed = false;
|
||||
var verifyInterval = null;
|
||||
var remoteCloseTimer = null;
|
||||
|
||||
function _allChannelsAreClosed() {
|
||||
var ret = null;
|
||||
if (localChannel) {
|
||||
ret = (localChannel.readyState === "closed");
|
||||
}
|
||||
if (remoteChannel) {
|
||||
if (ret !== null) {
|
||||
ret = (ret && (remoteChannel.readyState === "closed"));
|
||||
}
|
||||
else {
|
||||
ret = (remoteChannel.readyState === "closed");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function verifyClosedChannels() {
|
||||
if (everythingClosed) {
|
||||
// safety protection against events firing late
|
||||
return;
|
||||
}
|
||||
if (_allChannelsAreClosed()) {
|
||||
ok(true, "DataChannel(s) have reached 'closed' state for data channel " + index);
|
||||
if (remoteCloseTimer !== null) {
|
||||
clearTimeout(remoteCloseTimer);
|
||||
}
|
||||
if (verifyInterval !== null) {
|
||||
clearInterval(verifyInterval);
|
||||
}
|
||||
everythingClosed = true;
|
||||
onSuccess(index);
|
||||
}
|
||||
else {
|
||||
info("Still waiting for DataChannel closure");
|
||||
}
|
||||
}
|
||||
|
||||
if ((localChannel) && (localChannel.readyState !== "closed")) {
|
||||
// in case of steeplechase there is no far end, so we can only poll
|
||||
if (remoteChannel) {
|
||||
remoteChannel.onclose = function () {
|
||||
is(remoteChannel.readyState, "closed", "remoteChannel is in state 'closed'");
|
||||
verifyClosedChannels();
|
||||
};
|
||||
}
|
||||
else {
|
||||
pollingMode = true;
|
||||
verifyInterval = setInterval(verifyClosedChannels, 1000);
|
||||
}
|
||||
|
||||
localChannel.close();
|
||||
wait = true;
|
||||
}
|
||||
if ((remoteChannel) && (remoteChannel.readyState !== "closed")) {
|
||||
if (localChannel) {
|
||||
localChannel.onclose = function () {
|
||||
is(localChannel.readyState, "closed", "localChannel is in state 'closed'");
|
||||
verifyClosedChannels();
|
||||
};
|
||||
|
||||
// Apparently we are running a local test which has both ends of the
|
||||
// data channel locally available, so by default lets wait for the
|
||||
// remoteChannel.onclose handler from above to confirm closure on both
|
||||
// ends.
|
||||
remoteCloseTimer = setTimeout(function() {
|
||||
todo(false, "localChannel.close() did not resulted in close signal on remote side");
|
||||
remoteChannel.close();
|
||||
verifyClosedChannels();
|
||||
}, 30000);
|
||||
}
|
||||
else {
|
||||
pollingMode = true;
|
||||
verifyTimer = setInterval(verifyClosedChannels, 1000);
|
||||
|
||||
remoteChannel.close();
|
||||
}
|
||||
|
||||
wait = true;
|
||||
}
|
||||
|
||||
if (!wait) {
|
||||
onSuccess(index);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wait for the initial data channel to get into the open state
|
||||
*
|
||||
* @param {PeerConnectionWrapper} peer
|
||||
* The peer connection wrapper to run the command on
|
||||
* @param {Function} onSuccess
|
||||
* Callback when the creation was successful
|
||||
*/
|
||||
PeerConnectionTest.prototype.waitForInitialDataChannel =
|
||||
function PCT_waitForInitialDataChannel(peer, onSuccess, onFailure) {
|
||||
var dcConnectionTimeout = null;
|
||||
var dcOpened = false;
|
||||
|
||||
function dataChannelConnected(channel) {
|
||||
// in case the switch statement below had called onSuccess already we
|
||||
// don't want to call it again
|
||||
if (!dcOpened) {
|
||||
clearTimeout(dcConnectionTimeout);
|
||||
is(channel.readyState, "open", peer + " dataChannels[0] switched to state: 'open'");
|
||||
dcOpened = true;
|
||||
onSuccess();
|
||||
} else {
|
||||
info("dataChannelConnected() called, but data channel was open already");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: drno: convert dataChannels into an object and make
|
||||
// registerDataChannelOpenEvent a generic function
|
||||
if (peer == this.pcLocal) {
|
||||
peer.dataChannels[0].onopen = dataChannelConnected;
|
||||
} else {
|
||||
peer.registerDataChannelOpenEvents(dataChannelConnected);
|
||||
}
|
||||
|
||||
if (peer.dataChannels.length >= 1) {
|
||||
// snapshot of the live value as it might change during test execution
|
||||
const readyState = peer.dataChannels[0].readyState;
|
||||
switch (readyState) {
|
||||
case "open": {
|
||||
is(readyState, "open", peer + " dataChannels[0] is already in state: 'open'");
|
||||
dcOpened = true;
|
||||
onSuccess();
|
||||
break;
|
||||
}
|
||||
case "connecting": {
|
||||
is(readyState, "connecting", peer + " dataChannels[0] is in state: 'connecting'");
|
||||
if (onFailure) {
|
||||
dcConnectionTimeout = setTimeout(function () {
|
||||
is(peer.dataChannels[0].readyState, "open", peer + " timed out while waiting for dataChannels[0] to open");
|
||||
onFailure();
|
||||
}, 60000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ok(false, "dataChannels[0] is in unexpected state " + readyState);
|
||||
if (onFailure) {
|
||||
onFailure()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Send data (message or blob) to the other peer
|
||||
*
|
||||
* @param {String|Blob} data
|
||||
* Data to send to the other peer. For Blobs the MIME type will be lost.
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when data has been sent
|
||||
* @param {Object} [options={ }]
|
||||
* Options to specify the data channels to be used
|
||||
* @param {DataChannelWrapper} [options.sourceChannel=pcLocal.dataChannels[length - 1]]
|
||||
* Data channel to use for sending the message
|
||||
* @param {DataChannelWrapper} [options.targetChannel=pcRemote.dataChannels[length - 1]]
|
||||
* Data channel to use for receiving the message
|
||||
*/
|
||||
PeerConnectionTest.prototype.send = function PCT_send(data, onSuccess, options) {
|
||||
options = options || { };
|
||||
var source = options.sourceChannel ||
|
||||
this.pcLocal.dataChannels[this.pcLocal.dataChannels.length - 1];
|
||||
var target = options.targetChannel ||
|
||||
this.pcRemote.dataChannels[this.pcRemote.dataChannels.length - 1];
|
||||
|
||||
// Register event handler for the target channel
|
||||
target.onmessage = function (recv_data) {
|
||||
onSuccess(target, recv_data);
|
||||
};
|
||||
|
||||
source.send(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a data channel
|
||||
*
|
||||
* @param {Dict} options
|
||||
* Options for the data channel (see nsIPeerConnection)
|
||||
* @param {Function} onSuccess
|
||||
* Callback when the creation was successful
|
||||
*/
|
||||
PeerConnectionTest.prototype.createDataChannel = function DCT_createDataChannel(options, onSuccess) {
|
||||
var localChannel = null;
|
||||
var remoteChannel = null;
|
||||
var self = this;
|
||||
|
||||
// Method to synchronize all asynchronous events.
|
||||
function check_next_test() {
|
||||
if (localChannel && remoteChannel) {
|
||||
onSuccess(localChannel, remoteChannel);
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.negotiated) {
|
||||
// Register handlers for the remote peer
|
||||
this.pcRemote.registerDataChannelOpenEvents(function (channel) {
|
||||
remoteChannel = channel;
|
||||
check_next_test();
|
||||
});
|
||||
}
|
||||
|
||||
// Create the datachannel and handle the local 'onopen' event
|
||||
this.pcLocal.createDataChannel(options, function (channel) {
|
||||
localChannel = channel;
|
||||
|
||||
if (options.negotiated) {
|
||||
// externally negotiated - we need to open from both ends
|
||||
options.id = options.id || channel.id; // allow for no id to let the impl choose
|
||||
self.pcRemote.createDataChannel(options, function (channel) {
|
||||
remoteChannel = channel;
|
||||
check_next_test();
|
||||
});
|
||||
} else {
|
||||
check_next_test();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes the next command.
|
||||
*/
|
||||
@ -995,372 +1305,6 @@ PCT_getSignalingMessage(messageType, onMessage) {
|
||||
this.registerSignalingCallback(messageType, onMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class handles tests for data channels.
|
||||
*
|
||||
* @constructor
|
||||
* @param {object} [options={}]
|
||||
* Optional options for the peer connection test
|
||||
* @param {object} [options.commands=commandsDataChannel]
|
||||
* Commands to run for the test
|
||||
* @param {object} [options.config_local=undefined]
|
||||
* Configuration for the local peer connection instance
|
||||
* @param {object} [options.config_remote=undefined]
|
||||
* Configuration for the remote peer connection instance. If not defined
|
||||
* the configuration from the local instance will be used
|
||||
*/
|
||||
function DataChannelTest(options) {
|
||||
options = options || { };
|
||||
options.commands = options.commands || commandsDataChannel;
|
||||
|
||||
PeerConnectionTest.call(this, options);
|
||||
}
|
||||
|
||||
DataChannelTest.prototype = Object.create(PeerConnectionTest.prototype, {
|
||||
close : {
|
||||
/**
|
||||
* Close the open data channels, followed by the underlying peer connection
|
||||
*
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when all connections have been closed
|
||||
*/
|
||||
value : function DCT_close(onSuccess) {
|
||||
var self = this;
|
||||
var pendingDcClose = []
|
||||
var closeTimeout = null;
|
||||
|
||||
info("DataChannelTest.close() called");
|
||||
|
||||
function _closePeerConnection() {
|
||||
info("DataChannelTest closing PeerConnection");
|
||||
PeerConnectionTest.prototype.close.call(self, onSuccess);
|
||||
}
|
||||
|
||||
function _closePeerConnectionCallback(index) {
|
||||
info("_closePeerConnection called with index " + index);
|
||||
var pos = pendingDcClose.indexOf(index);
|
||||
if (pos != -1) {
|
||||
pendingDcClose.splice(pos, 1);
|
||||
}
|
||||
else {
|
||||
info("_closePeerConnection index " + index + " is missing from pendingDcClose: " + pendingDcClose);
|
||||
}
|
||||
if (pendingDcClose.length === 0) {
|
||||
clearTimeout(closeTimeout);
|
||||
_closePeerConnection();
|
||||
}
|
||||
}
|
||||
|
||||
var myDataChannels = null;
|
||||
if (self.pcLocal) {
|
||||
myDataChannels = self.pcLocal.dataChannels;
|
||||
}
|
||||
else if (self.pcRemote) {
|
||||
myDataChannels = self.pcRemote.dataChannels;
|
||||
}
|
||||
var length = myDataChannels.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var dataChannel = myDataChannels[i];
|
||||
if (dataChannel.readyState !== "closed") {
|
||||
pendingDcClose.push(i);
|
||||
self.closeDataChannels(i, _closePeerConnectionCallback);
|
||||
}
|
||||
}
|
||||
if (pendingDcClose.length === 0) {
|
||||
_closePeerConnection();
|
||||
}
|
||||
else {
|
||||
closeTimeout = setTimeout(function() {
|
||||
ok(false, "Failed to properly close data channels: " +
|
||||
pendingDcClose);
|
||||
_closePeerConnection();
|
||||
}, 60000);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
closeDataChannels : {
|
||||
/**
|
||||
* Close the specified data channels
|
||||
*
|
||||
* @param {Number} index
|
||||
* Index of the data channels to close on both sides
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when the data channels has been closed
|
||||
*/
|
||||
value : function DCT_closeDataChannels(index, onSuccess) {
|
||||
info("_closeDataChannels called with index: " + index);
|
||||
var localChannel = null;
|
||||
if (this.pcLocal) {
|
||||
localChannel = this.pcLocal.dataChannels[index];
|
||||
}
|
||||
var remoteChannel = null;
|
||||
if (this.pcRemote) {
|
||||
remoteChannel = this.pcRemote.dataChannels[index];
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var wait = false;
|
||||
var pollingMode = false;
|
||||
var everythingClosed = false;
|
||||
var verifyInterval = null;
|
||||
var remoteCloseTimer = null;
|
||||
|
||||
function _allChannelsAreClosed() {
|
||||
var ret = null;
|
||||
if (localChannel) {
|
||||
ret = (localChannel.readyState === "closed");
|
||||
}
|
||||
if (remoteChannel) {
|
||||
if (ret !== null) {
|
||||
ret = (ret && (remoteChannel.readyState === "closed"));
|
||||
}
|
||||
else {
|
||||
ret = (remoteChannel.readyState === "closed");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function verifyClosedChannels() {
|
||||
if (everythingClosed) {
|
||||
// safety protection against events firing late
|
||||
return;
|
||||
}
|
||||
if (_allChannelsAreClosed) {
|
||||
ok(true, "DataChannel(s) have reached 'closed' state for data channel " + index);
|
||||
if (remoteCloseTimer !== null) {
|
||||
clearTimeout(remoteCloseTimer);
|
||||
}
|
||||
if (verifyInterval !== null) {
|
||||
clearInterval(verifyInterval);
|
||||
}
|
||||
everythingClosed = true;
|
||||
onSuccess(index);
|
||||
}
|
||||
else {
|
||||
info("Still waiting for DataChannel closure");
|
||||
}
|
||||
}
|
||||
|
||||
if ((localChannel) && (localChannel.readyState !== "closed")) {
|
||||
// in case of steeplechase there is no far end, so we can only poll
|
||||
if (remoteChannel) {
|
||||
remoteChannel.onclose = function () {
|
||||
is(remoteChannel.readyState, "closed", "remoteChannel is in state 'closed'");
|
||||
verifyClosedChannels();
|
||||
};
|
||||
}
|
||||
else {
|
||||
pollingMode = true;
|
||||
verifyInterval = setInterval(verifyClosedChannels, 1000);
|
||||
}
|
||||
|
||||
localChannel.close();
|
||||
wait = true;
|
||||
}
|
||||
if ((remoteChannel) && (remoteChannel.readyState !== "closed")) {
|
||||
if (localChannel) {
|
||||
localChannel.onclose = function () {
|
||||
is(localChannel.readyState, "closed", "localChannel is in state 'closed'");
|
||||
verifyClosedChannels();
|
||||
};
|
||||
|
||||
// Apparently we are running a local test which has both ends of the
|
||||
// data channel locally available, so by default lets wait for the
|
||||
// remoteChannel.onclose handler from above to confirm closure on both
|
||||
// ends.
|
||||
remoteCloseTimer = setTimeout(function() {
|
||||
todo(false, "localChannel.close() did not resulted in close signal on remote side");
|
||||
remoteChannel.close();
|
||||
verifyClosedChannels();
|
||||
}, 30000);
|
||||
}
|
||||
else {
|
||||
pollingMode = true;
|
||||
verifyTimer = setInterval(verifyClosedChannels, 1000);
|
||||
|
||||
remoteChannel.close();
|
||||
}
|
||||
|
||||
wait = true;
|
||||
}
|
||||
|
||||
if (!wait) {
|
||||
onSuccess(index);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
createDataChannel : {
|
||||
/**
|
||||
* Create a data channel
|
||||
*
|
||||
* @param {Dict} options
|
||||
* Options for the data channel (see nsIPeerConnection)
|
||||
* @param {Function} onSuccess
|
||||
* Callback when the creation was successful
|
||||
*/
|
||||
value : function DCT_createDataChannel(options, onSuccess) {
|
||||
var localChannel = null;
|
||||
var remoteChannel = null;
|
||||
var self = this;
|
||||
|
||||
// Method to synchronize all asynchronous events.
|
||||
function check_next_test() {
|
||||
if (localChannel && remoteChannel) {
|
||||
onSuccess(localChannel, remoteChannel);
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.negotiated) {
|
||||
// Register handlers for the remote peer
|
||||
this.pcRemote.registerDataChannelOpenEvents(function (channel) {
|
||||
remoteChannel = channel;
|
||||
check_next_test();
|
||||
});
|
||||
}
|
||||
|
||||
// Create the datachannel and handle the local 'onopen' event
|
||||
this.pcLocal.createDataChannel(options, function (channel) {
|
||||
localChannel = channel;
|
||||
|
||||
if (options.negotiated) {
|
||||
// externally negotiated - we need to open from both ends
|
||||
options.id = options.id || channel.id; // allow for no id to let the impl choose
|
||||
self.pcRemote.createDataChannel(options, function (channel) {
|
||||
remoteChannel = channel;
|
||||
check_next_test();
|
||||
});
|
||||
} else {
|
||||
check_next_test();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
send : {
|
||||
/**
|
||||
* Send data (message or blob) to the other peer
|
||||
*
|
||||
* @param {String|Blob} data
|
||||
* Data to send to the other peer. For Blobs the MIME type will be lost.
|
||||
* @param {Function} onSuccess
|
||||
* Callback to execute when data has been sent
|
||||
* @param {Object} [options={ }]
|
||||
* Options to specify the data channels to be used
|
||||
* @param {DataChannelWrapper} [options.sourceChannel=pcLocal.dataChannels[length - 1]]
|
||||
* Data channel to use for sending the message
|
||||
* @param {DataChannelWrapper} [options.targetChannel=pcRemote.dataChannels[length - 1]]
|
||||
* Data channel to use for receiving the message
|
||||
*/
|
||||
value : function DCT_send(data, onSuccess, options) {
|
||||
options = options || { };
|
||||
var source = options.sourceChannel ||
|
||||
this.pcLocal.dataChannels[this.pcLocal.dataChannels.length - 1];
|
||||
var target = options.targetChannel ||
|
||||
this.pcRemote.dataChannels[this.pcRemote.dataChannels.length - 1];
|
||||
|
||||
// Register event handler for the target channel
|
||||
target.onmessage = function (recv_data) {
|
||||
onSuccess(target, recv_data);
|
||||
};
|
||||
|
||||
source.send(data);
|
||||
}
|
||||
},
|
||||
|
||||
createOffer : {
|
||||
value : function DCT_createOffer(peer, onSuccess) {
|
||||
PeerConnectionTest.prototype.createOffer.call(this, peer, onSuccess);
|
||||
}
|
||||
},
|
||||
|
||||
setLocalDescription : {
|
||||
/**
|
||||
* Sets the local description for the specified peer connection instance
|
||||
* and automatically handles the failure case.
|
||||
*
|
||||
* @param {PeerConnectionWrapper} peer
|
||||
The peer connection wrapper to run the command on
|
||||
* @param {mozRTCSessionDescription} desc
|
||||
* Session description for the local description request
|
||||
* @param {function} onSuccess
|
||||
* Callback to execute if the local description was set successfully
|
||||
*/
|
||||
value : function DCT_setLocalDescription(peer, desc, state, onSuccess) {
|
||||
PeerConnectionTest.prototype.setLocalDescription.call(this, peer,
|
||||
desc, state, onSuccess);
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
waitForInitialDataChannel : {
|
||||
/**
|
||||
* Wait for the initial data channel to get into the open state
|
||||
*
|
||||
* @param {PeerConnectionWrapper} peer
|
||||
* The peer connection wrapper to run the command on
|
||||
* @param {Function} onSuccess
|
||||
* Callback when the creation was successful
|
||||
*/
|
||||
value : function DCT_waitForInitialDataChannel(peer, onSuccess, onFailure) {
|
||||
var dcConnectionTimeout = null;
|
||||
var dcOpened = false;
|
||||
|
||||
function dataChannelConnected(channel) {
|
||||
// in case the switch statement below had called onSuccess already we
|
||||
// don't want to call it again
|
||||
if (!dcOpened) {
|
||||
clearTimeout(dcConnectionTimeout);
|
||||
is(channel.readyState, "open", peer + " dataChannels[0] switched to state: 'open'");
|
||||
dcOpened = true;
|
||||
onSuccess();
|
||||
} else {
|
||||
info("dataChannelConnected() called, but data channel was open already");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: drno: convert dataChannels into an object and make
|
||||
// registerDataChannelOpenEvent a generic function
|
||||
if (peer == this.pcLocal) {
|
||||
peer.dataChannels[0].onopen = dataChannelConnected;
|
||||
} else {
|
||||
peer.registerDataChannelOpenEvents(dataChannelConnected);
|
||||
}
|
||||
|
||||
if (peer.dataChannels.length >= 1) {
|
||||
// snapshot of the live value as it might change during test execution
|
||||
const readyState = peer.dataChannels[0].readyState;
|
||||
switch (readyState) {
|
||||
case "open": {
|
||||
is(readyState, "open", peer + " dataChannels[0] is already in state: 'open'");
|
||||
dcOpened = true;
|
||||
onSuccess();
|
||||
break;
|
||||
}
|
||||
case "connecting": {
|
||||
is(readyState, "connecting", peer + " dataChannels[0] is in state: 'connecting'");
|
||||
if (onFailure) {
|
||||
dcConnectionTimeout = setTimeout(function () {
|
||||
is(peer.dataChannels[0].readyState, "open", peer + " timed out while waiting for dataChannels[0] to open");
|
||||
onFailure();
|
||||
}, 60000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ok(false, "dataChannels[0] is in unexpected state " + readyState);
|
||||
if (onFailure) {
|
||||
onFailure()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* This class acts as a wrapper around a DataChannel instance.
|
||||
@ -2574,6 +2518,7 @@ PeerConnectionWrapper.prototype = {
|
||||
"Spec and MapClass variant of RTCStatsReport enumeration agree");
|
||||
var nin = numTracks(this._pc.getRemoteStreams());
|
||||
var nout = numTracks(this._pc.getLocalStreams());
|
||||
var ndata = this.dataChannels.length;
|
||||
|
||||
// TODO(Bug 957145): Restore stronger inboundrtp test once Bug 948249 is fixed
|
||||
//is(toNum(counters["inboundrtp"]), nin, "Have " + nin + " inboundrtp stat(s)");
|
||||
@ -2584,7 +2529,7 @@ PeerConnectionWrapper.prototype = {
|
||||
var numLocalCandidates = toNum(counters.localcandidate);
|
||||
var numRemoteCandidates = toNum(counters.remotecandidate);
|
||||
// If there are no tracks, there will be no stats either.
|
||||
if (nin + nout > 0) {
|
||||
if (nin + nout + ndata > 0) {
|
||||
ok(numLocalCandidates, "Have localcandidate stat(s)");
|
||||
ok(numRemoteCandidates, "Have remotecandidate stat(s)");
|
||||
} else {
|
||||
@ -2648,7 +2593,7 @@ PeerConnectionWrapper.prototype = {
|
||||
* The SDP answer to check for SDP bundle support
|
||||
*/
|
||||
checkStatsIceConnections : function PCW_checkStatsIceConnections(stats,
|
||||
offerConstraintsList, offerOptions, numDataTracks, answer) {
|
||||
offerConstraintsList, offerOptions, answer) {
|
||||
var numIceConnections = 0;
|
||||
Object.keys(stats).forEach(function(key) {
|
||||
if ((stats[key].type === "candidatepair") && stats[key].selected) {
|
||||
@ -2669,6 +2614,8 @@ PeerConnectionWrapper.prototype = {
|
||||
this.countVideoTracksInMediaConstraint(offerConstraintsList) ||
|
||||
this.videoInOfferOptions(offerOptions);
|
||||
|
||||
var numDataTracks = this.dataChannels.length;
|
||||
|
||||
var numAudioVideoDataTracks = numAudioTracks + numVideoTracks + numDataTracks;
|
||||
info("expected audio + video + data tracks: " + numAudioVideoDataTracks);
|
||||
is(numAudioVideoDataTracks, numIceConnections, "stats ICE connections matches expected A/V tracks");
|
||||
|
@ -535,7 +535,6 @@ var commandsPeerConnection = [
|
||||
test.pcLocal.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
0,
|
||||
test.originalAnswer);
|
||||
test.next();
|
||||
});
|
||||
@ -548,7 +547,6 @@ var commandsPeerConnection = [
|
||||
test.pcRemote.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
0,
|
||||
test.originalAnswer);
|
||||
test.next();
|
||||
});
|
||||
@ -724,626 +722,3 @@ var commandsPeerConnection = [
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Default list of commands to execute for a Datachannel test.
|
||||
*/
|
||||
var commandsDataChannel = [
|
||||
[
|
||||
'PC_LOCAL_SETUP_ICE_LOGGER',
|
||||
function (test) {
|
||||
test.pcLocal.logIceConnectionState();
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SETUP_ICE_LOGGER',
|
||||
function (test) {
|
||||
test.pcRemote.logIceConnectionState();
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SETUP_SIGNALING_LOGGER',
|
||||
function (test) {
|
||||
test.pcLocal.logSignalingState();
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SETUP_SIGNALING_LOGGER',
|
||||
function (test) {
|
||||
test.pcRemote.logSignalingState();
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_GUM',
|
||||
function (test) {
|
||||
test.pcLocal.getAllUserMedia(test.pcLocal.constraints, function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_INITIAL_SIGNALINGSTATE',
|
||||
function (test) {
|
||||
is(test.pcLocal.signalingState, STABLE,
|
||||
"Initial local signalingState is stable");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_INITIAL_ICE_STATE',
|
||||
function (test) {
|
||||
is(test.pcLocal.iceConnectionState, ICE_NEW,
|
||||
"Initial local ICE connection state is 'new'");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_GUM',
|
||||
function (test) {
|
||||
test.pcRemote.getAllUserMedia(test.pcRemote.constraints, function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_INITIAL_SIGNALINGSTATE',
|
||||
function (test) {
|
||||
is(test.pcRemote.signalingState, STABLE,
|
||||
"Initial remote signalingState is stable");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CHECK_INITIAL_ICE_STATE',
|
||||
function (test) {
|
||||
is(test.pcRemote.iceConnectionState, ICE_NEW,
|
||||
"Initial remote ICE connection state is 'new'");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SETUP_ICE_HANDLER',
|
||||
function (test) {
|
||||
test.pcLocal.setupIceCandidateHandler(test);
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SETUP_ICE_HANDLER',
|
||||
function (test) {
|
||||
test.pcRemote.setupIceCandidateHandler(test);
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_DATA_CHANNEL',
|
||||
function (test) {
|
||||
var channel = test.pcLocal.createDataChannel({});
|
||||
|
||||
is(channel.binaryType, "blob", channel + " is of binary type 'blob'");
|
||||
is(channel.readyState, "connecting", channel + " is in state: 'connecting'");
|
||||
|
||||
is(test.pcLocal.signalingState, STABLE,
|
||||
"Create datachannel does not change signaling state");
|
||||
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CREATE_OFFER',
|
||||
function (test) {
|
||||
test.createOffer(test.pcLocal, function (offer) {
|
||||
is(test.pcLocal.signalingState, STABLE,
|
||||
"Local create offer does not change signaling state");
|
||||
ok(offer.sdp.contains("m=application"),
|
||||
"m=application is contained in the SDP");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_STEEPLECHASE_SIGNAL_OFFER',
|
||||
function (test) {
|
||||
if (test.steeplechase) {
|
||||
send_message({"type": "offer",
|
||||
"offer": test.originalOffer,
|
||||
"offer_constraints": test.pcLocal.constraints,
|
||||
"offer_options": test.pcLocal.offerOptions});
|
||||
test._local_offer = test.originalOffer;
|
||||
test._offer_constraints = test.pcLocal.constraints;
|
||||
test._offer_options = test.pcLocal.offerOptions;
|
||||
}
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcLocal, test.originalOffer, HAVE_LOCAL_OFFER,
|
||||
function () {
|
||||
is(test.pcLocal.signalingState, HAVE_LOCAL_OFFER,
|
||||
"signalingState after local setLocalDescription is 'have-local-offer'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_GET_OFFER',
|
||||
function (test) {
|
||||
if (!test.steeplechase) {
|
||||
test._local_offer = test.originalOffer;
|
||||
test._offer_constraints = test.pcLocal.constraints;
|
||||
test._offer_options = test.pcLocal.offerOptions;
|
||||
test.next();
|
||||
} else {
|
||||
test.getSignalingMessage("offer", function (message) {
|
||||
ok("offer" in message, "Got an offer message");
|
||||
test._local_offer = new mozRTCSessionDescription(message.offer);
|
||||
test._offer_constraints = message.offer_constraints;
|
||||
test._offer_options = message.offer_options;
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcRemote, test._local_offer, HAVE_REMOTE_OFFER,
|
||||
function () {
|
||||
is(test.pcRemote.signalingState, HAVE_REMOTE_OFFER,
|
||||
"signalingState after remote setRemoteDescription is 'have-remote-offer'");
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SANE_LOCAL_SDP',
|
||||
function (test) {
|
||||
test.pcLocal.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
function(trickle) {
|
||||
test.pcLocal.localRequiresTrickleIce = trickle;
|
||||
});
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SANE_REMOTE_SDP',
|
||||
function (test) {
|
||||
test.pcRemote.verifySdp(test._local_offer, "offer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
function (trickle) {
|
||||
test.pcRemote.remoteRequiresTrickleIce = trickle;
|
||||
});
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CREATE_ANSWER',
|
||||
function (test) {
|
||||
test.createAnswer(test.pcRemote, function (answer) {
|
||||
is(test.pcRemote.signalingState, HAVE_REMOTE_OFFER,
|
||||
"Remote createAnswer does not change signaling state");
|
||||
ok(answer.sdp.contains("m=application"),
|
||||
"m=application is contained in the SDP");
|
||||
if (test.steeplechase) {
|
||||
send_message({"type":"answer",
|
||||
"answer": test.originalAnswer,
|
||||
"answer_constraints": test.pcRemote.constraints});
|
||||
test._remote_answer = test.pcRemote._last_answer;
|
||||
test._answer_constraints = test.pcRemote.constraints;
|
||||
}
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SETUP_DATA_CHANNEL_CALLBACK',
|
||||
function (test) {
|
||||
test.waitForInitialDataChannel(test.pcLocal, function () {
|
||||
ok(true, test.pcLocal + " dataChannels[0] switched to 'open'");
|
||||
},
|
||||
// At this point a timeout failure will be of no value
|
||||
null);
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SETUP_DATA_CHANNEL_CALLBACK',
|
||||
function (test) {
|
||||
test.waitForInitialDataChannel(test.pcRemote, function () {
|
||||
ok(true, test.pcRemote + " dataChannels[0] switched to 'open'");
|
||||
},
|
||||
// At this point a timeout failure will be of no value
|
||||
null);
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SET_LOCAL_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setLocalDescription(test.pcRemote, test.originalAnswer, STABLE,
|
||||
function () {
|
||||
is(test.pcRemote.signalingState, STABLE,
|
||||
"signalingState after remote setLocalDescription is 'stable'");
|
||||
test.next();
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_GET_ANSWER',
|
||||
function (test) {
|
||||
if (!test.steeplechase) {
|
||||
test._remote_answer = test.originalAnswer;
|
||||
test._answer_constraints = test.pcRemote.constraints;
|
||||
test.next();
|
||||
} else {
|
||||
test.getSignalingMessage("answer", function (message) {
|
||||
ok("answer" in message, "Got an answer message");
|
||||
test._remote_answer = new mozRTCSessionDescription(message.answer);
|
||||
test._answer_constraints = message.answer_constraints;
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SET_REMOTE_DESCRIPTION',
|
||||
function (test) {
|
||||
test.setRemoteDescription(test.pcLocal, test._remote_answer, STABLE,
|
||||
function () {
|
||||
is(test.pcLocal.signalingState, STABLE,
|
||||
"signalingState after local setRemoteDescription is 'stable'");
|
||||
test.next();
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_SANE_LOCAL_SDP',
|
||||
function (test) {
|
||||
test.pcRemote.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
function (trickle) {
|
||||
test.pcRemote.localRequiresTrickleIce = trickle;
|
||||
});
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_SANE_REMOTE_SDP',
|
||||
function (test) {
|
||||
test.pcLocal.verifySdp(test._remote_answer, "answer",
|
||||
test._offer_constraints, test._offer_options,
|
||||
function (trickle) {
|
||||
test.pcLocal.remoteRequiresTrickleIce = trickle;
|
||||
});
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_WAIT_FOR_ICE_CONNECTED',
|
||||
function (test) {
|
||||
var myTest = test;
|
||||
var myPc = myTest.pcLocal;
|
||||
|
||||
function onIceConnectedSuccess () {
|
||||
info("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog);
|
||||
ok(true, "pc_local: ICE switched to 'connected' state");
|
||||
myTest.next();
|
||||
};
|
||||
function onIceConnectedFailed () {
|
||||
dumpSdp(myTest);
|
||||
ok(false, "pc_local: ICE failed to switch to 'connected' state: " + myPc.iceConnectionState);
|
||||
myTest.next();
|
||||
};
|
||||
|
||||
if (myPc.isIceConnected()) {
|
||||
info("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog);
|
||||
ok(true, "pc_local: ICE is in connected state");
|
||||
myTest.next();
|
||||
} else if (myPc.isIceConnectionPending()) {
|
||||
myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed);
|
||||
} else {
|
||||
dumpSdp(myTest);
|
||||
ok(false, "pc_local: ICE is already in bad state: " + myPc.iceConnectionState);
|
||||
myTest.next();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_VERIFY_ICE_GATHERING',
|
||||
function (test) {
|
||||
if (test.pcLocal.localRequiresTrickleIce) {
|
||||
ok(test.pcLocal._local_ice_candidates.length > 0, "Received local trickle ICE candidates");
|
||||
}
|
||||
isnot(test.pcLocal._pc.iceGatheringState, GATH_NEW, "ICE gathering state is not 'new'");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_WAIT_FOR_ICE_CONNECTED',
|
||||
function (test) {
|
||||
var myTest = test;
|
||||
var myPc = myTest.pcRemote;
|
||||
|
||||
function onIceConnectedSuccess () {
|
||||
info("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog);
|
||||
ok(true, "pc_remote: ICE switched to 'connected' state");
|
||||
myTest.next();
|
||||
};
|
||||
function onIceConnectedFailed () {
|
||||
dumpSdp(myTest);
|
||||
ok(false, "pc_remote: ICE failed to switch to 'connected' state: " + myPc.iceConnectionState);
|
||||
myTest.next();
|
||||
};
|
||||
|
||||
if (myPc.isIceConnected()) {
|
||||
info("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog);
|
||||
ok(true, "pc_remote: ICE is in connected state");
|
||||
myTest.next();
|
||||
} else if (myPc.isIceConnectionPending()) {
|
||||
myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed);
|
||||
} else {
|
||||
dumpSdp(myTest);
|
||||
ok(false, "pc_remote: ICE is already in bad state: " + myPc.iceConnectionState);
|
||||
myTest.next();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_VERIFY_ICE_GATHERING',
|
||||
function (test) {
|
||||
if (test.pcRemote.localRequiresTrickleIce) {
|
||||
ok(test.pcRemote._local_ice_candidates.length > 0, "Received local trickle ICE candidates");
|
||||
}
|
||||
isnot(test.pcRemote._pc.iceGatheringState, GATH_NEW, "ICE gathering state is not 'new'");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_VERIFY_DATA_CHANNEL_STATE',
|
||||
function (test) {
|
||||
test.waitForInitialDataChannel(test.pcLocal, function() {
|
||||
test.next();
|
||||
}, function() {
|
||||
ok(false, test.pcLocal + " initial dataChannels[0] failed to switch to 'open'");
|
||||
//TODO: use stopAndExit() once bug 1019323 has landed
|
||||
unexpectedEventAndFinish(this, 'timeout')
|
||||
// to prevent test framework timeouts
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_VERIFY_DATA_CHANNEL_STATE',
|
||||
function (test) {
|
||||
test.waitForInitialDataChannel(test.pcRemote, function() {
|
||||
test.next();
|
||||
}, function() {
|
||||
ok(false, test.pcRemote + " initial dataChannels[0] failed to switch to 'open'");
|
||||
//TODO: use stopAndExit() once bug 1019323 has landed
|
||||
unexpectedEventAndFinish(this, 'timeout');
|
||||
// to prevent test framework timeouts
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_MEDIA_TRACKS',
|
||||
function (test) {
|
||||
test.pcLocal.checkMediaTracks(test._answer_constraints, function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CHECK_MEDIA_TRACKS',
|
||||
function (test) {
|
||||
test.pcRemote.checkMediaTracks(test._offer_constraints, function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_MEDIA_FLOW_PRESENT',
|
||||
function (test) {
|
||||
test.pcLocal.checkMediaFlowPresent(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT',
|
||||
function (test) {
|
||||
test.pcRemote.checkMediaFlowPresent(function () {
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_LOCAL_CHECK_ICE_CONNECTIONS',
|
||||
function (test) {
|
||||
test.pcLocal.getStats(null, function(stats) {
|
||||
test.pcLocal.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
1,
|
||||
test.originalAnswer);
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'PC_REMOTE_CHECK_ICE_CONNECTIONS',
|
||||
function (test) {
|
||||
test.pcRemote.getStats(null, function(stats) {
|
||||
test.pcRemote.checkStatsIceConnections(stats,
|
||||
test._offer_constraints,
|
||||
test._offer_options,
|
||||
1,
|
||||
test.originalAnswer);
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE',
|
||||
function (test) {
|
||||
var message = "Lorem ipsum dolor sit amet";
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(data, message, "Message correctly transmitted from pcLocal to pcRemote.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_BLOB',
|
||||
function (test) {
|
||||
var contents = ["At vero eos et accusam et justo duo dolores et ea rebum."];
|
||||
var blob = new Blob(contents, { "type" : "text/plain" });
|
||||
|
||||
test.send(blob, function (channel, data) {
|
||||
ok(data instanceof Blob, "Received data is of instance Blob");
|
||||
is(data.size, blob.size, "Received data has the correct size.");
|
||||
|
||||
getBlobContent(data, function (recv_contents) {
|
||||
is(recv_contents, contents, "Received data has the correct content.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'CREATE_SECOND_DATA_CHANNEL',
|
||||
function (test) {
|
||||
test.createDataChannel({ }, function (sourceChannel, targetChannel) {
|
||||
is(sourceChannel.readyState, "open", sourceChannel + " is in state: 'open'");
|
||||
is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
|
||||
|
||||
is(targetChannel.binaryType, "blob", targetChannel + " is of binary type 'blob'");
|
||||
is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL',
|
||||
function (test) {
|
||||
var channels = test.pcRemote.dataChannels;
|
||||
var message = "Lorem ipsum dolor sit amet";
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(channels.indexOf(channel), channels.length - 1, "Last channel used");
|
||||
is(data, message, "Received message has the correct content.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_THROUGH_FIRST_CHANNEL',
|
||||
function (test) {
|
||||
var message = "Message through 1st channel";
|
||||
var options = {
|
||||
sourceChannel: test.pcLocal.dataChannels[0],
|
||||
targetChannel: test.pcRemote.dataChannels[0]
|
||||
};
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(test.pcRemote.dataChannels.indexOf(channel), 0, "1st channel used");
|
||||
is(data, message, "Received message has the correct content.");
|
||||
|
||||
test.next();
|
||||
}, options);
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_BACK_THROUGH_FIRST_CHANNEL',
|
||||
function (test) {
|
||||
var message = "Return a message also through 1st channel";
|
||||
var options = {
|
||||
sourceChannel: test.pcRemote.dataChannels[0],
|
||||
targetChannel: test.pcLocal.dataChannels[0]
|
||||
};
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(test.pcLocal.dataChannels.indexOf(channel), 0, "1st channel used");
|
||||
is(data, message, "Return message has the correct content.");
|
||||
|
||||
test.next();
|
||||
}, options);
|
||||
}
|
||||
],
|
||||
[
|
||||
'CREATE_NEGOTIATED_DATA_CHANNEL',
|
||||
function (test) {
|
||||
var options = {negotiated:true, id: 5, protocol:"foo/bar", ordered:false,
|
||||
maxRetransmits:500};
|
||||
test.createDataChannel(options, function (sourceChannel2, targetChannel2) {
|
||||
is(sourceChannel2.readyState, "open", sourceChannel2 + " is in state: 'open'");
|
||||
is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
|
||||
|
||||
is(targetChannel2.binaryType, "blob", targetChannel2 + " is of binary type 'blob'");
|
||||
is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
|
||||
|
||||
if (options.id != undefined) {
|
||||
is(sourceChannel2.id, options.id, sourceChannel2 + " id is:" + sourceChannel2.id);
|
||||
}
|
||||
else {
|
||||
options.id = sourceChannel2.id;
|
||||
}
|
||||
var reliable = !options.ordered ? false : (options.maxRetransmits || options.maxRetransmitTime);
|
||||
is(sourceChannel2.protocol, options.protocol, sourceChannel2 + " protocol is:" + sourceChannel2.protocol);
|
||||
is(sourceChannel2.reliable, reliable, sourceChannel2 + " reliable is:" + sourceChannel2.reliable);
|
||||
/*
|
||||
These aren't exposed by IDL yet
|
||||
is(sourceChannel2.ordered, options.ordered, sourceChannel2 + " ordered is:" + sourceChannel2.ordered);
|
||||
is(sourceChannel2.maxRetransmits, options.maxRetransmits, sourceChannel2 + " maxRetransmits is:" +
|
||||
sourceChannel2.maxRetransmits);
|
||||
is(sourceChannel2.maxRetransmitTime, options.maxRetransmitTime, sourceChannel2 + " maxRetransmitTime is:" +
|
||||
sourceChannel2.maxRetransmitTime);
|
||||
*/
|
||||
|
||||
is(targetChannel2.id, options.id, targetChannel2 + " id is:" + targetChannel2.id);
|
||||
is(targetChannel2.protocol, options.protocol, targetChannel2 + " protocol is:" + targetChannel2.protocol);
|
||||
is(targetChannel2.reliable, reliable, targetChannel2 + " reliable is:" + targetChannel2.reliable);
|
||||
/*
|
||||
These aren't exposed by IDL yet
|
||||
is(targetChannel2.ordered, options.ordered, targetChannel2 + " ordered is:" + targetChannel2.ordered);
|
||||
is(targetChannel2.maxRetransmits, options.maxRetransmits, targetChannel2 + " maxRetransmits is:" +
|
||||
targetChannel2.maxRetransmits);
|
||||
is(targetChannel2.maxRetransmitTime, options.maxRetransmitTime, targetChannel2 + " maxRetransmitTime is:" +
|
||||
targetChannel2.maxRetransmitTime);
|
||||
*/
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL2',
|
||||
function (test) {
|
||||
var channels = test.pcRemote.dataChannels;
|
||||
var message = "Lorem ipsum dolor sit amet";
|
||||
|
||||
test.send(message, function (channel, data) {
|
||||
is(channels.indexOf(channel), channels.length - 1, "Last channel used");
|
||||
is(data, message, "Received message has the correct content.");
|
||||
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="dataChannel.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
@ -17,8 +18,9 @@
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function () {
|
||||
test = new DataChannelTest();
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
addInitialDataChannel(test.chain);
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.run();
|
||||
});
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="dataChannel.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
@ -17,8 +18,9 @@
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function () {
|
||||
test = new DataChannelTest();
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
addInitialDataChannel(test.chain);
|
||||
test.setMediaConstraints([{audio: true}, {video: true}],
|
||||
[{audio: true}, {video: true}]);
|
||||
test.run();
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="dataChannel.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
@ -17,8 +18,9 @@
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function () {
|
||||
test = new DataChannelTest();
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
addInitialDataChannel(test.chain);
|
||||
test.setMediaConstraints([{audio: true, video: true}],
|
||||
[{audio: true, video: true}]);
|
||||
test.run();
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="dataChannel.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
@ -11,8 +12,6 @@
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
SimpleTest.requestFlakyTimeout("untriaged");
|
||||
|
||||
createHTML({
|
||||
bug: "1016476",
|
||||
title: "Basic data channel audio/video connection without bundle"
|
||||
@ -20,9 +19,8 @@
|
||||
|
||||
var test;
|
||||
runNetworkTest(function () {
|
||||
test = new DataChannelTest();
|
||||
test.setMediaConstraints([{audio: true}, {video: true}],
|
||||
[{audio: true}, {video: true}]);
|
||||
test = new PeerConnectionTest();
|
||||
addInitialDataChannel(test.chain);
|
||||
test.chain.insertAfter("PC_LOCAL_CREATE_OFFER",
|
||||
[[
|
||||
'PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER',
|
||||
@ -35,6 +33,8 @@
|
||||
}
|
||||
]]
|
||||
);
|
||||
test.setMediaConstraints([{audio: true}, {video: true}],
|
||||
[{audio: true}, {video: true}]);
|
||||
test.run();
|
||||
});
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="dataChannel.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
@ -17,8 +18,9 @@
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function () {
|
||||
test = new DataChannelTest();
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
addInitialDataChannel(test.chain);
|
||||
test.run();
|
||||
});
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="dataChannel.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
@ -17,8 +18,9 @@
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function () {
|
||||
test = new DataChannelTest();
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
addInitialDataChannel(test.chain);
|
||||
test.setMediaConstraints([{video: true}], [{video: true}]);
|
||||
test.run();
|
||||
});
|
||||
|
@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="dataChannel.js"></script>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
<script type="application/javascript" src="templates.js"></script>
|
||||
@ -17,8 +18,9 @@
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function () {
|
||||
test = new DataChannelTest();
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
addInitialDataChannel(test.chain);
|
||||
var sld = test.chain.remove("PC_REMOTE_SET_LOCAL_DESCRIPTION");
|
||||
test.chain.insertAfter("PC_LOCAL_SET_REMOTE_DESCRIPTION", sld);
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
|
@ -192,6 +192,10 @@ MozNFCTagImpl.prototype = {
|
||||
return callback.promise;
|
||||
},
|
||||
|
||||
notifyLost: function notifyLost() {
|
||||
this.isLost = true;
|
||||
},
|
||||
|
||||
classID: Components.ID("{4e1e2e90-3137-11e3-aa6e-0800200c9a66}"),
|
||||
contractID: "@mozilla.org/nfc/tag;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
@ -244,6 +248,10 @@ MozNFCPeerImpl.prototype = {
|
||||
return callback.promise;
|
||||
},
|
||||
|
||||
notifyLost: function notifyLost() {
|
||||
this.isLost = true;
|
||||
},
|
||||
|
||||
classID: Components.ID("{c1b2bcf0-35eb-11e3-aa6e-0800200c9a66}"),
|
||||
contractID: "@mozilla.org/nfc/peer;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
@ -432,7 +440,7 @@ MozNFCImpl.prototype = {
|
||||
this, /* useCapture */false);
|
||||
}
|
||||
|
||||
this.nfcTag.isLost = true;
|
||||
this.nfcTag.notifyLost();
|
||||
this.nfcTag = null;
|
||||
|
||||
debug("fire ontaglost " + sessionToken);
|
||||
@ -491,7 +499,7 @@ MozNFCImpl.prototype = {
|
||||
this, /* useCapture */false);
|
||||
}
|
||||
|
||||
this.nfcPeer.isLost = true;
|
||||
this.nfcPeer.notifyLost();
|
||||
this.nfcPeer = null;
|
||||
|
||||
debug("fire onpeerlost");
|
||||
|
@ -260,7 +260,7 @@ anp_audio_newTrack(uint32_t sampleRate, // sampling rate in Hz
|
||||
|
||||
if (autoFrame.CheckForException() || obj == nullptr) {
|
||||
jenv->DeleteGlobalRef(s->at_class);
|
||||
free(s);
|
||||
delete s;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ anp_audio_newTrack(uint32_t sampleRate, // sampling rate in Hz
|
||||
|
||||
if (autoFrame.CheckForException() || state == STATE_UNINITIALIZED) {
|
||||
jenv->DeleteGlobalRef(s->at_class);
|
||||
free(s);
|
||||
delete s;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -310,7 +310,7 @@ anp_audio_start(ANPAudioTrack* s)
|
||||
|
||||
if (autoFrame.CheckForException()) {
|
||||
jenv->DeleteGlobalRef(s->at_class);
|
||||
free(s);
|
||||
delete s;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,10 @@ BrowserStreamChild::StreamConstructed(
|
||||
&mStream, seekable, stype);
|
||||
if (rv != NPERR_NO_ERROR) {
|
||||
mState = DELETING;
|
||||
mStreamNotify = nullptr;
|
||||
if (mStreamNotify) {
|
||||
mStreamNotify->SetAssociatedStream(nullptr);
|
||||
mStreamNotify = nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mState = ALIVE;
|
||||
|
@ -2440,7 +2440,6 @@ StreamNotifyChild::ActorDestroy(ActorDestroyReason why)
|
||||
void
|
||||
StreamNotifyChild::SetAssociatedStream(BrowserStreamChild* bs)
|
||||
{
|
||||
NS_ASSERTION(bs, "Shouldn't be null");
|
||||
NS_ASSERTION(!mBrowserStream, "Two streams for one streamnotify?");
|
||||
|
||||
mBrowserStream = bs;
|
||||
|
@ -35,8 +35,9 @@
|
||||
#include "nsPluginTags.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "PluginHangUIParent.h"
|
||||
#include "mozilla/widget/AudioSession.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "PluginHangUIParent.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
@ -2481,7 +2482,7 @@ PluginModuleChromeParent::InitializeInjector()
|
||||
return;
|
||||
|
||||
TimeStamp th32Start = TimeStamp::Now();
|
||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
nsAutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
|
||||
if (INVALID_HANDLE_VALUE == snapshot)
|
||||
return;
|
||||
TimeStamp th32End = TimeStamp::Now();
|
||||
|
@ -444,7 +444,7 @@ nsCSPParser::path(nsCSPHostSrc* aCspHost)
|
||||
}
|
||||
// path can begin with "/" but not "//"
|
||||
// see http://tools.ietf.org/html/rfc3986#section-3.3
|
||||
if (!hostChar()) {
|
||||
if (peek(SLASH)) {
|
||||
const char16_t* params[] = { mCurToken.get() };
|
||||
logWarningErrorToConsole(nsIScriptError::warningFlag, "couldntParseInvalidSource",
|
||||
params, ArrayLength(params));
|
||||
|
@ -122,6 +122,7 @@ static bool gPending = false;
|
||||
static nsTArray<nsCString> gReason;
|
||||
static NetworkParams *gWifiTetheringParms = 0;
|
||||
|
||||
static nsTArray<CommandChain*> gCommandChainQueue;
|
||||
|
||||
const CommandFunc NetworkUtils::sWifiEnableChain[] = {
|
||||
NetworkUtils::clearWifiTetherParms,
|
||||
@ -385,6 +386,18 @@ static void postMessage(NetworkParams& aOptions, NetworkResultOptions& aResult)
|
||||
(*(gNetworkUtils->getMessageCallback()))(aResult);
|
||||
}
|
||||
|
||||
void NetworkUtils::runNextQueuedCommandChain()
|
||||
{
|
||||
if (gCommandChainQueue.IsEmpty()) {
|
||||
NU_DBG("No command chain left in the queue. Done!");
|
||||
return;
|
||||
}
|
||||
NU_DBG("Process the queued command chain.");
|
||||
CommandChain* nextChain = gCommandChainQueue[0];
|
||||
NetworkResultOptions newResult;
|
||||
next(nextChain, false, newResult);
|
||||
}
|
||||
|
||||
void NetworkUtils::next(CommandChain* aChain, bool aError, NetworkResultOptions& aResult)
|
||||
{
|
||||
if (aError) {
|
||||
@ -394,11 +407,15 @@ void NetworkUtils::next(CommandChain* aChain, bool aError, NetworkResultOptions&
|
||||
(*onError)(aChain->getParams(), aResult);
|
||||
}
|
||||
delete aChain;
|
||||
gCommandChainQueue.RemoveElementAt(0);
|
||||
runNextQueuedCommandChain();
|
||||
return;
|
||||
}
|
||||
CommandFunc f = aChain->getNextCommand();
|
||||
if (!f) {
|
||||
delete aChain;
|
||||
gCommandChainQueue.RemoveElementAt(0);
|
||||
runNextQueuedCommandChain();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -809,13 +826,16 @@ void NetworkUtils::startTethering(CommandChain* aChain,
|
||||
if (aResult.mResultReason.Find("started") != kNotFound) {
|
||||
snprintf(command, MAX_COMMAND_SIZE - 1, "%s", DUMMY_COMMAND);
|
||||
} else {
|
||||
snprintf(command, MAX_COMMAND_SIZE - 1, "tether start %s %s", GET_CHAR(mWifiStartIp), GET_CHAR(mWifiEndIp));
|
||||
|
||||
// If usbStartIp/usbEndIp is not valid, don't append them since
|
||||
// the trailing white spaces will be parsed to extra empty args
|
||||
// See: http://androidxref.com/4.3_r2.1/xref/system/core/libsysutils/src/FrameworkListener.cpp#78
|
||||
if (!GET_FIELD(mUsbStartIp).IsEmpty() && !GET_FIELD(mUsbEndIp).IsEmpty()) {
|
||||
snprintf(command, MAX_COMMAND_SIZE - 1, "%s %s %s", command, GET_CHAR(mUsbStartIp), GET_CHAR(mUsbEndIp));
|
||||
snprintf(command, MAX_COMMAND_SIZE - 1, "tether start %s %s %s %s",
|
||||
GET_CHAR(mWifiStartIp), GET_CHAR(mWifiEndIp),
|
||||
GET_CHAR(mUsbStartIp), GET_CHAR(mUsbEndIp));
|
||||
} else {
|
||||
snprintf(command, MAX_COMMAND_SIZE - 1, "tether start %s %s",
|
||||
GET_CHAR(mWifiStartIp), GET_CHAR(mWifiEndIp));
|
||||
}
|
||||
}
|
||||
|
||||
@ -937,11 +957,29 @@ void NetworkUtils::setInterfaceDns(CommandChain* aChain,
|
||||
#define ASSIGN_FIELD(prop) aResult.prop = aChain->getParams().prop;
|
||||
#define ASSIGN_FIELD_VALUE(prop, value) aResult.prop = value;
|
||||
|
||||
#define RUN_CHAIN(param, cmds, err) \
|
||||
uint32_t size = sizeof(cmds) / sizeof(CommandFunc); \
|
||||
CommandChain* chain = new CommandChain(param, cmds, size, err); \
|
||||
NetworkResultOptions result; \
|
||||
next(chain, false, result);
|
||||
template<size_t N>
|
||||
void NetworkUtils::runChain(const NetworkParams& aParams,
|
||||
const CommandFunc (&aCmds)[N],
|
||||
ErrorCallback aError)
|
||||
{
|
||||
CommandChain* chain = new CommandChain(aParams, aCmds, N, aError);
|
||||
gCommandChainQueue.AppendElement(chain);
|
||||
|
||||
if (gCommandChainQueue.Length() > 1) {
|
||||
NU_DBG("%d command chains are queued. Wait!", gCommandChainQueue.Length());
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkResultOptions result;
|
||||
NetworkUtils::next(gCommandChainQueue[0], false, result);
|
||||
}
|
||||
|
||||
// Called to clean up the command chain and process the queued command chain if any.
|
||||
void NetworkUtils::finalizeSuccess(CommandChain* aChain,
|
||||
NetworkResultOptions& aResult)
|
||||
{
|
||||
next(aChain, false, aResult);
|
||||
}
|
||||
|
||||
void NetworkUtils::wifiTetheringFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
|
||||
{
|
||||
@ -951,7 +989,7 @@ void NetworkUtils::wifiTetheringFail(NetworkParams& aOptions, NetworkResultOptio
|
||||
// If one of the stages fails, we try roll back to ensure
|
||||
// we don't leave the network systems in limbo.
|
||||
ASSIGN_FIELD_VALUE(mEnable, false)
|
||||
RUN_CHAIN(aOptions, sWifiFailChain, nullptr)
|
||||
runChain(aOptions, sWifiFailChain, nullptr);
|
||||
}
|
||||
|
||||
void NetworkUtils::wifiTetheringSuccess(CommandChain* aChain,
|
||||
@ -965,6 +1003,7 @@ void NetworkUtils::wifiTetheringSuccess(CommandChain* aChain,
|
||||
gWifiTetheringParms = new NetworkParams(aChain->getParams());
|
||||
}
|
||||
postMessage(aChain->getParams(), aResult);
|
||||
finalizeSuccess(aChain, aResult);
|
||||
}
|
||||
|
||||
void NetworkUtils::usbTetheringFail(NetworkParams& aOptions,
|
||||
@ -977,7 +1016,7 @@ void NetworkUtils::usbTetheringFail(NetworkParams& aOptions,
|
||||
// This parameter is used to disable ipforwarding.
|
||||
{
|
||||
aOptions.mEnable = false;
|
||||
RUN_CHAIN(aOptions, sUSBFailChain, nullptr)
|
||||
runChain(aOptions, sUSBFailChain, nullptr);
|
||||
}
|
||||
|
||||
// Disable usb rndis function.
|
||||
@ -995,6 +1034,7 @@ void NetworkUtils::usbTetheringSuccess(CommandChain* aChain,
|
||||
{
|
||||
ASSIGN_FIELD(mEnable)
|
||||
postMessage(aChain->getParams(), aResult);
|
||||
finalizeSuccess(aChain, aResult);
|
||||
}
|
||||
|
||||
void NetworkUtils::networkInterfaceAlarmFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
|
||||
@ -1009,6 +1049,7 @@ void NetworkUtils::networkInterfaceAlarmSuccess(CommandChain* aChain,
|
||||
// TODO : error is not used , and it is conflict with boolean type error.
|
||||
// params.error = parseFloat(params.resultReason);
|
||||
postMessage(aChain->getParams(), aResult);
|
||||
finalizeSuccess(aChain, aResult);
|
||||
}
|
||||
|
||||
void NetworkUtils::updateUpStreamFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
|
||||
@ -1023,6 +1064,7 @@ void NetworkUtils::updateUpStreamSuccess(CommandChain* aChain,
|
||||
ASSIGN_FIELD(mCurExternalIfname)
|
||||
ASSIGN_FIELD(mCurInternalIfname)
|
||||
postMessage(aChain->getParams(), aResult);
|
||||
finalizeSuccess(aChain, aResult);
|
||||
}
|
||||
|
||||
void NetworkUtils::setDhcpServerFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
|
||||
@ -1035,6 +1077,7 @@ void NetworkUtils::setDhcpServerSuccess(CommandChain* aChain, CommandCallback aC
|
||||
{
|
||||
aResult.mSuccess = true;
|
||||
postMessage(aChain->getParams(), aResult);
|
||||
finalizeSuccess(aChain, aResult);
|
||||
}
|
||||
|
||||
void NetworkUtils::wifiOperationModeFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
|
||||
@ -1047,6 +1090,7 @@ void NetworkUtils::wifiOperationModeSuccess(CommandChain* aChain,
|
||||
NetworkResultOptions& aResult)
|
||||
{
|
||||
postMessage(aChain->getParams(), aResult);
|
||||
finalizeSuccess(aChain, aResult);
|
||||
}
|
||||
|
||||
void NetworkUtils::setDnsFail(NetworkParams& aOptions, NetworkResultOptions& aResult)
|
||||
@ -1188,7 +1232,7 @@ void NetworkUtils::onNetdMessage(NetdCommand* aCommand)
|
||||
|
||||
if (!strcmp(reason, linkdownReason)) {
|
||||
NU_DBG("Wifi link down, restarting tethering.");
|
||||
RUN_CHAIN(*gWifiTetheringParms, sWifiRetryChain, wifiTetheringFail)
|
||||
runChain(*gWifiTetheringParms, sWifiRetryChain, wifiTetheringFail);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1242,9 +1286,9 @@ CommandResult NetworkUtils::setDhcpServer(NetworkParams& aOptions)
|
||||
aOptions.mPrefix = aOptions.mMaskLength;
|
||||
aOptions.mLink = NS_ConvertUTF8toUTF16("up");
|
||||
|
||||
RUN_CHAIN(aOptions, sStartDhcpServerChain, setDhcpServerFail)
|
||||
runChain(aOptions, sStartDhcpServerChain, setDhcpServerFail);
|
||||
} else {
|
||||
RUN_CHAIN(aOptions, sStopDhcpServerChain, setDhcpServerFail)
|
||||
runChain(aOptions, sStopDhcpServerChain, setDhcpServerFail);
|
||||
}
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
@ -1283,7 +1327,7 @@ CommandResult NetworkUtils::setDNS(NetworkParams& aOptions)
|
||||
|
||||
// DNS needs to be set through netd since JellyBean (4.3).
|
||||
if (SDK_VERSION >= 18) {
|
||||
RUN_CHAIN(aOptions, sSetDnsChain, setDnsFail)
|
||||
runChain(aOptions, sSetDnsChain, setDnsFail);
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
|
||||
@ -1600,21 +1644,21 @@ CommandResult NetworkUtils::removeSecondaryRoute(NetworkParams& aOptions)
|
||||
CommandResult NetworkUtils::setNetworkInterfaceAlarm(NetworkParams& aOptions)
|
||||
{
|
||||
NU_DBG("setNetworkInterfaceAlarms: %s", GET_CHAR(mIfname));
|
||||
RUN_CHAIN(aOptions, sNetworkInterfaceSetAlarmChain, networkInterfaceAlarmFail);
|
||||
runChain(aOptions, sNetworkInterfaceSetAlarmChain, networkInterfaceAlarmFail);
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
|
||||
CommandResult NetworkUtils::enableNetworkInterfaceAlarm(NetworkParams& aOptions)
|
||||
{
|
||||
NU_DBG("enableNetworkInterfaceAlarm: %s", GET_CHAR(mIfname));
|
||||
RUN_CHAIN(aOptions, sNetworkInterfaceEnableAlarmChain, networkInterfaceAlarmFail);
|
||||
runChain(aOptions, sNetworkInterfaceEnableAlarmChain, networkInterfaceAlarmFail);
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
|
||||
CommandResult NetworkUtils::disableNetworkInterfaceAlarm(NetworkParams& aOptions)
|
||||
{
|
||||
NU_DBG("disableNetworkInterfaceAlarms: %s", GET_CHAR(mIfname));
|
||||
RUN_CHAIN(aOptions, sNetworkInterfaceDisableAlarmChain, networkInterfaceAlarmFail);
|
||||
runChain(aOptions, sNetworkInterfaceDisableAlarmChain, networkInterfaceAlarmFail);
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
|
||||
@ -1624,7 +1668,7 @@ CommandResult NetworkUtils::disableNetworkInterfaceAlarm(NetworkParams& aOptions
|
||||
CommandResult NetworkUtils::setWifiOperationMode(NetworkParams& aOptions)
|
||||
{
|
||||
NU_DBG("setWifiOperationMode: %s %s", GET_CHAR(mIfname), GET_CHAR(mMode));
|
||||
RUN_CHAIN(aOptions, sWifiOperationModeChain, wifiOperationModeFail);
|
||||
runChain(aOptions, sWifiOperationModeChain, wifiOperationModeFail);
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
|
||||
@ -1654,11 +1698,11 @@ CommandResult NetworkUtils::setWifiTethering(NetworkParams& aOptions)
|
||||
if (enable) {
|
||||
NU_DBG("Starting Wifi Tethering on %s <-> %s",
|
||||
GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
|
||||
RUN_CHAIN(aOptions, sWifiEnableChain, wifiTetheringFail)
|
||||
runChain(aOptions, sWifiEnableChain, wifiTetheringFail);
|
||||
} else {
|
||||
NU_DBG("Stopping Wifi Tethering on %s <-> %s",
|
||||
GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
|
||||
RUN_CHAIN(aOptions, sWifiDisableChain, wifiTetheringFail)
|
||||
runChain(aOptions, sWifiDisableChain, wifiTetheringFail);
|
||||
}
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
@ -1686,11 +1730,11 @@ CommandResult NetworkUtils::setUSBTethering(NetworkParams& aOptions)
|
||||
if (enable) {
|
||||
NU_DBG("Starting USB Tethering on %s <-> %s",
|
||||
GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
|
||||
RUN_CHAIN(aOptions, sUSBEnableChain, usbTetheringFail)
|
||||
runChain(aOptions, sUSBEnableChain, usbTetheringFail);
|
||||
} else {
|
||||
NU_DBG("Stopping USB Tethering on %s <-> %s",
|
||||
GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
|
||||
RUN_CHAIN(aOptions, sUSBDisableChain, usbTetheringFail)
|
||||
runChain(aOptions, sUSBDisableChain, usbTetheringFail);
|
||||
}
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
@ -1800,7 +1844,7 @@ CommandResult NetworkUtils::enableUsbRndis(NetworkParams& aOptions)
|
||||
*/
|
||||
CommandResult NetworkUtils::updateUpStream(NetworkParams& aOptions)
|
||||
{
|
||||
RUN_CHAIN(aOptions, sUpdateUpStreamChain, updateUpStreamFail)
|
||||
runChain(aOptions, sUpdateUpStreamChain, updateUpStreamFail);
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
|
||||
|
@ -360,6 +360,15 @@ private:
|
||||
inline bool isComplete(uint32_t code);
|
||||
inline bool isProceeding(uint32_t code);
|
||||
void Shutdown();
|
||||
static void runNextQueuedCommandChain();
|
||||
static void finalizeSuccess(CommandChain* aChain,
|
||||
mozilla::dom::NetworkResultOptions& aResult);
|
||||
|
||||
template<size_t N>
|
||||
static void runChain(const NetworkParams& aParams,
|
||||
const CommandFunc (&aCmds)[N],
|
||||
ErrorCallback aError);
|
||||
|
||||
/**
|
||||
* Callback function to send netd result to main thread.
|
||||
*/
|
||||
|
@ -62,6 +62,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsISyncMessageSender");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "UUIDGenerator",
|
||||
"@mozilla.org/uuid-generator;1",
|
||||
"nsIUUIDGenerator");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gNumRadioInterfaces", function() {
|
||||
let appInfo = Cc["@mozilla.org/xre/app-info;1"];
|
||||
let isParentProcess = !appInfo || appInfo.getService(Ci.nsIXULRuntime)
|
||||
@ -410,14 +414,9 @@ RILContentHelper.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
iccOpenChannel: function(clientId, window, aid) {
|
||||
if (window == null) {
|
||||
throw Components.Exception("Can't get window object",
|
||||
Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
let request = Services.DOMRequest.createRequest(window);
|
||||
let requestId = this.getRequestId(request);
|
||||
iccOpenChannel: function(clientId, aid, callback) {
|
||||
let requestId = UUIDGenerator.generateUUID().toString();
|
||||
this._addIccChannelCallback(requestId, callback);
|
||||
|
||||
cpmm.sendAsyncMessage("RIL:IccOpenChannel", {
|
||||
clientId: clientId,
|
||||
@ -426,17 +425,24 @@ RILContentHelper.prototype = {
|
||||
aid: aid
|
||||
}
|
||||
});
|
||||
return request;
|
||||
},
|
||||
|
||||
iccExchangeAPDU: function(clientId, window, channel, apdu) {
|
||||
if (window == null) {
|
||||
throw Components.Exception("Can't get window object",
|
||||
Cr.NS_ERROR_UNEXPECTED);
|
||||
iccExchangeAPDU: function(clientId, channel, cla, ins, p1, p2, p3, data, callback) {
|
||||
let requestId = UUIDGenerator.generateUUID().toString();
|
||||
this._addIccChannelCallback(requestId, callback);
|
||||
|
||||
if (!data) {
|
||||
if (DEBUG) debug('data is not set , p3 : ' + p3);
|
||||
}
|
||||
|
||||
let request = Services.DOMRequest.createRequest(window);
|
||||
let requestId = this.getRequestId(request);
|
||||
let apdu = {
|
||||
cla: cla,
|
||||
command: ins,
|
||||
p1: p1,
|
||||
p2: p2,
|
||||
p3: p3,
|
||||
data: data
|
||||
};
|
||||
|
||||
//Potentially you need serialization here and can't pass the jsval through
|
||||
cpmm.sendAsyncMessage("RIL:IccExchangeAPDU", {
|
||||
@ -447,17 +453,11 @@ RILContentHelper.prototype = {
|
||||
apdu: apdu
|
||||
}
|
||||
});
|
||||
return request;
|
||||
},
|
||||
|
||||
iccCloseChannel: function(clientId, window, channel) {
|
||||
if (window == null) {
|
||||
throw Components.Exception("Can't get window object",
|
||||
Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
let request = Services.DOMRequest.createRequest(window);
|
||||
let requestId = this.getRequestId(request);
|
||||
iccCloseChannel: function(clientId, channel, callback) {
|
||||
let requestId = UUIDGenerator.generateUUID().toString();
|
||||
this._addIccChannelCallback(requestId, callback);
|
||||
|
||||
cpmm.sendAsyncMessage("RIL:IccCloseChannel", {
|
||||
clientId: clientId,
|
||||
@ -466,7 +466,6 @@ RILContentHelper.prototype = {
|
||||
channel: channel
|
||||
}
|
||||
});
|
||||
return request;
|
||||
},
|
||||
|
||||
readContacts: function(clientId, window, contactType) {
|
||||
@ -572,6 +571,22 @@ RILContentHelper.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_addIccChannelCallback: function(requestId, channelCb) {
|
||||
let cbInterfaces = this._iccChannelCallback;
|
||||
if (!cbInterfaces[requestId] && channelCb) {
|
||||
cbInterfaces[requestId] = channelCb;
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) debug("Unable to add channelCbInterface for requestId : " + requestId);
|
||||
},
|
||||
|
||||
_getIccChannelCallback: function(requestId) {
|
||||
let cb = this._iccChannelCallback[requestId];
|
||||
delete this._iccChannelCallback[requestId];
|
||||
return cb;
|
||||
},
|
||||
|
||||
registerIccMsg: function(clientId, listener) {
|
||||
if (DEBUG) debug("Registering for ICC related messages");
|
||||
this.registerListener("_iccListeners", clientId, listener);
|
||||
@ -740,11 +755,10 @@ RILContentHelper.prototype = {
|
||||
this._deliverEvent(clientId, "_iccListeners", "notifyStkSessionEnd", null);
|
||||
break;
|
||||
case "RIL:IccOpenChannel":
|
||||
this.handleSimpleRequest(data.requestId, data.errorMsg,
|
||||
data.channel);
|
||||
this.handleIccOpenChannel(data);
|
||||
break;
|
||||
case "RIL:IccCloseChannel":
|
||||
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
|
||||
this.handleIccCloseChannel(data);
|
||||
break;
|
||||
case "RIL:IccExchangeAPDU":
|
||||
this.handleIccExchangeAPDU(data);
|
||||
@ -769,13 +783,38 @@ RILContentHelper.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
handleIccExchangeAPDU: function(message) {
|
||||
if (message.errorMsg) {
|
||||
this.fireRequestError(message.requestId, message.errorMsg);
|
||||
} else {
|
||||
var result = [message.sw1, message.sw2, message.simResponse];
|
||||
this.fireRequestSuccess(message.requestId, result);
|
||||
handleIccOpenChannel: function(message) {
|
||||
let requestId = message.requestId;
|
||||
let callback = this._getIccChannelCallback(requestId);
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
return !message.errorMsg ? callback.notifyOpenChannelSuccess(message.channel) :
|
||||
callback.notifyError(message.errorMsg);
|
||||
},
|
||||
|
||||
handleIccCloseChannel: function(message) {
|
||||
let requestId = message.requestId;
|
||||
let callback = this._getIccChannelCallback(requestId);
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
return !message.errorMsg ? callback.notifyCloseChannelSuccess() :
|
||||
callback.notifyError(message.errorMsg);
|
||||
},
|
||||
|
||||
handleIccExchangeAPDU: function(message) {
|
||||
let requestId = message.requestId;
|
||||
let callback = this._getIccChannelCallback(requestId);
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
return !message.errorMsg ?
|
||||
callback.notifyExchangeAPDUResponse(message.sw1, message.sw2, message.simResponse) :
|
||||
callback.notifyError(message.errorMsg);
|
||||
},
|
||||
|
||||
handleReadIccContacts: function(message) {
|
||||
|
@ -1993,20 +1993,20 @@ RadioInterface.prototype = {
|
||||
matchMvno: function(target, message) {
|
||||
if (DEBUG) this.debug("matchMvno: " + JSON.stringify(message));
|
||||
|
||||
if (!message || !message.mvnoType || !message.mvnoData) {
|
||||
if (!message || !message.mvnoData) {
|
||||
message.errorMsg = RIL.GECKO_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!message.errorMsg) {
|
||||
switch (message.mvnoType) {
|
||||
case "imsi":
|
||||
case RIL.GECKO_CARDMVNO_TYPE_IMSI:
|
||||
if (!this.rilContext.imsi) {
|
||||
message.errorMsg = RIL.GECKO_ERROR_GENERIC_FAILURE;
|
||||
break;
|
||||
}
|
||||
message.result = this.isImsiMatches(message.mvnoData);
|
||||
break;
|
||||
case "spn":
|
||||
case RIL.GECKO_CARDMVNO_TYPE_SPN:
|
||||
let spn = this.rilContext.iccInfo && this.rilContext.iccInfo.spn;
|
||||
if (!spn) {
|
||||
message.errorMsg = RIL.GECKO_ERROR_GENERIC_FAILURE;
|
||||
@ -2014,7 +2014,7 @@ RadioInterface.prototype = {
|
||||
}
|
||||
message.result = spn == message.mvnoData;
|
||||
break;
|
||||
case "gid":
|
||||
case RIL.GECKO_CARDMVNO_TYPE_GID:
|
||||
this.workerMessenger.send("getGID1", null, (function(response) {
|
||||
let gid = response.gid1;
|
||||
let mvnoDataLength = message.mvnoData.length;
|
||||
|
@ -1316,6 +1316,7 @@ this.GECKO_ICC_SERVICES = {
|
||||
},
|
||||
// @see 3GPP2 C.S0023-D 3.4.18 (RUIM).
|
||||
ruim: {
|
||||
FDN: 3,
|
||||
ENHANCED_PHONEBOOK: 6,
|
||||
SPN: 17,
|
||||
SDN: 18
|
||||
@ -2645,6 +2646,11 @@ this.GECKO_CARDCONTACT_TYPE_ADN = 0;
|
||||
this.GECKO_CARDCONTACT_TYPE_FDN = 1;
|
||||
this.GECKO_CARDCONTACT_TYPE_SDN = 2;
|
||||
|
||||
// See nsIIccProvider::CARD_MVNO_TYPE_*
|
||||
this.GECKO_CARDMVNO_TYPE_IMSI = 0;
|
||||
this.GECKO_CARDMVNO_TYPE_SPN = 1;
|
||||
this.GECKO_CARDMVNO_TYPE_GID = 2;
|
||||
|
||||
// See ril.h RIL_PersoSubstate
|
||||
this.PERSONSUBSTATE = {};
|
||||
PERSONSUBSTATE[CARD_PERSOSUBSTATE_UNKNOWN] = GECKO_CARDSTATE_UNKNOWN;
|
||||
|
@ -1687,7 +1687,7 @@ RilObject.prototype = {
|
||||
*/
|
||||
hangUpAll: function() {
|
||||
for (let callIndex in this.currentCalls) {
|
||||
this.hangUp({callIndex: callIndex});
|
||||
this.hangUpCall({callIndex: callIndex});
|
||||
}
|
||||
},
|
||||
|
||||
@ -1697,9 +1697,14 @@ RilObject.prototype = {
|
||||
* @param callIndex
|
||||
* Call index (1-based) as reported by REQUEST_GET_CURRENT_CALLS.
|
||||
*/
|
||||
hangUp: function(options) {
|
||||
hangUpCall: function(options) {
|
||||
let call = this.currentCalls[options.callIndex];
|
||||
if (!call) {
|
||||
// |hangUpCall()| is used to remove a call from the current call list,
|
||||
// so we consider it as an successful case when hanging up a call that
|
||||
// doesn't exist in the current call list.
|
||||
options.success = true;
|
||||
this.sendChromeMessage(options);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1781,6 +1786,9 @@ RilObject.prototype = {
|
||||
answerCall: function(options) {
|
||||
let call = this.currentCalls[options.callIndex];
|
||||
if (!call) {
|
||||
options.success = false;
|
||||
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
|
||||
this.sendChromeMessage(options);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1791,13 +1799,19 @@ RilObject.prototype = {
|
||||
switch (call.state) {
|
||||
case CALL_STATE_INCOMING:
|
||||
this.telephonyRequestQueue.push(REQUEST_ANSWER, () => {
|
||||
this.context.Buf.simpleRequest(REQUEST_ANSWER);
|
||||
this.context.Buf.simpleRequest(REQUEST_ANSWER, options);
|
||||
});
|
||||
break;
|
||||
case CALL_STATE_WAITING:
|
||||
// Answer the waiting (second) call, and hold the first call.
|
||||
this.switchActiveCall(options);
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) this.context.debug("AnswerCall: Invalid call state");
|
||||
|
||||
options.success = false;
|
||||
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
|
||||
this.sendChromeMessage(options);
|
||||
}
|
||||
},
|
||||
|
||||
@ -1808,12 +1822,13 @@ RilObject.prototype = {
|
||||
* Call index of the call to reject.
|
||||
*/
|
||||
rejectCall: function(options) {
|
||||
// Check for races. Since we dispatched the incoming/waiting call
|
||||
// notification the incoming/waiting call may have changed. The main
|
||||
// thread thinks that it is rejecting the call with the given index,
|
||||
// so only reject if that is still incoming/waiting.
|
||||
let call = this.currentCalls[options.callIndex];
|
||||
if (!call) {
|
||||
// |hangUpCall()| is used to remove an imcoming call from the current
|
||||
// call list, so we consider it as an successful case when rejecting
|
||||
// a call that doesn't exist in the current call list.
|
||||
options.success = true;
|
||||
this.sendChromeMessage(options);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1825,6 +1840,10 @@ RilObject.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for races. Since we dispatched the incoming/waiting call
|
||||
// notification the incoming/waiting call may have changed. The main
|
||||
// thread thinks that it is rejecting the call with the given index,
|
||||
// so only reject if that is still incoming/waiting.
|
||||
switch (call.state) {
|
||||
case CALL_STATE_INCOMING:
|
||||
this.udub(options);
|
||||
@ -1833,6 +1852,12 @@ RilObject.prototype = {
|
||||
// Reject the waiting (second) call, and remain the first call.
|
||||
this.hangUpBackground(options);
|
||||
break;
|
||||
default:
|
||||
if (DEBUG) this.context.debug("RejectCall: Invalid call state");
|
||||
|
||||
options.success = false;
|
||||
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
|
||||
this.sendChromeMessage(options);
|
||||
}
|
||||
},
|
||||
|
||||
@ -1921,7 +1946,7 @@ RilObject.prototype = {
|
||||
}
|
||||
|
||||
options.callIndex = 1;
|
||||
this.hangUp(options);
|
||||
this.hangUpCall(options);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5487,6 +5512,10 @@ RilObject.prototype[REQUEST_GET_IMSI] = function REQUEST_GET_IMSI(length, option
|
||||
this.sendChromeMessage(options);
|
||||
};
|
||||
RilObject.prototype[REQUEST_HANGUP] = function REQUEST_HANGUP(length, options) {
|
||||
if (options.rilMessageType == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
options.success = (options.rilRequestError === 0);
|
||||
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
||||
this.sendChromeMessage(options);
|
||||
@ -5514,6 +5543,11 @@ RilObject.prototype[REQUEST_CONFERENCE] = function REQUEST_CONFERENCE(length, op
|
||||
this.sendChromeMessage(options);
|
||||
};
|
||||
RilObject.prototype[REQUEST_UDUB] = function REQUEST_UDUB(length, options) {
|
||||
options.success = (options.rilRequestError === 0);
|
||||
if (!options.success) {
|
||||
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
||||
}
|
||||
this.sendChromeMessage(options);
|
||||
};
|
||||
RilObject.prototype[REQUEST_LAST_CALL_FAIL_CAUSE] = function REQUEST_LAST_CALL_FAIL_CAUSE(length, options) {
|
||||
let Buf = this.context.Buf;
|
||||
@ -5968,6 +6002,11 @@ RilObject.prototype[REQUEST_GET_IMEISV] = function REQUEST_GET_IMEISV(length, op
|
||||
this.IMEISV = this.context.Buf.readString();
|
||||
};
|
||||
RilObject.prototype[REQUEST_ANSWER] = function REQUEST_ANSWER(length, options) {
|
||||
options.success = (options.rilRequestError === 0);
|
||||
if (!options.success) {
|
||||
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
||||
}
|
||||
this.sendChromeMessage(options);
|
||||
};
|
||||
RilObject.prototype[REQUEST_DEACTIVATE_DATA_CALL] = function REQUEST_DEACTIVATE_DATA_CALL(length, options) {
|
||||
if (options.rilRequestError) {
|
||||
@ -15232,6 +15271,7 @@ ICCContactHelperObject.prototype = {
|
||||
*/
|
||||
readICCContacts: function(appType, contactType, onsuccess, onerror) {
|
||||
let ICCRecordHelper = this.context.ICCRecordHelper;
|
||||
let ICCUtilsHelper = this.context.ICCUtilsHelper;
|
||||
|
||||
switch (contactType) {
|
||||
case GECKO_CARDCONTACT_TYPE_ADN:
|
||||
@ -15242,10 +15282,13 @@ ICCContactHelperObject.prototype = {
|
||||
}
|
||||
break;
|
||||
case GECKO_CARDCONTACT_TYPE_FDN:
|
||||
if (!ICCUtilsHelper.isICCServiceAvailable("FDN")) {
|
||||
onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
|
||||
break;
|
||||
}
|
||||
ICCRecordHelper.readADNLike(ICC_EF_FDN, onsuccess, onerror);
|
||||
break;
|
||||
case GECKO_CARDCONTACT_TYPE_SDN:
|
||||
let ICCUtilsHelper = this.context.ICCUtilsHelper;
|
||||
if (!ICCUtilsHelper.isICCServiceAvailable("SDN")) {
|
||||
onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
|
||||
break;
|
||||
@ -15372,6 +15415,7 @@ ICCContactHelperObject.prototype = {
|
||||
*/
|
||||
updateICCContact: function(appType, contactType, contact, pin2, onsuccess, onerror) {
|
||||
let ICCRecordHelper = this.context.ICCRecordHelper;
|
||||
let ICCUtilsHelper = this.context.ICCUtilsHelper;
|
||||
|
||||
switch (contactType) {
|
||||
case GECKO_CARDCONTACT_TYPE_ADN:
|
||||
@ -15386,6 +15430,10 @@ ICCContactHelperObject.prototype = {
|
||||
onerror(GECKO_ERROR_SIM_PIN2);
|
||||
return;
|
||||
}
|
||||
if (!ICCUtilsHelper.isICCServiceAvailable("FDN")) {
|
||||
onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
|
||||
break;
|
||||
}
|
||||
ICCRecordHelper.updateADNLike(ICC_EF_FDN, contact, pin2, onsuccess, onerror);
|
||||
break;
|
||||
default:
|
||||
|
@ -130,8 +130,12 @@ add_test(function test_read_icc_contacts() {
|
||||
ril.appType = aSimType;
|
||||
ril._isCdma = (aSimType === CARD_APPTYPE_RUIM);
|
||||
ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ?
|
||||
[0x0, 0x0C, 0x0, 0x0, 0x0]:
|
||||
[0x0, 0x00, 0x0, 0x0, 0x0];
|
||||
[0x20, 0x0C, 0x0, 0x0, 0x0]:
|
||||
[0x20, 0x00, 0x0, 0x0, 0x0];
|
||||
|
||||
ril.iccInfoPrivate.sst = (aSimType === CARD_APPTYPE_SIM)?
|
||||
[0x20, 0x0, 0x0, 0x0, 0x0]:
|
||||
[0x2, 0x0, 0x0, 0x0, 0x0];
|
||||
|
||||
// Override some functions to test.
|
||||
contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) {
|
||||
@ -242,8 +246,11 @@ add_test(function test_update_icc_contact() {
|
||||
function do_test(aSimType, aContactType, aContact, aPin2, aFileType, aHaveIapIndex, aEnhancedPhoneBook) {
|
||||
ril.appType = aSimType;
|
||||
ril._isCdma = (aSimType === CARD_APPTYPE_RUIM);
|
||||
ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x0, 0x0C, 0x0, 0x0, 0x0]
|
||||
: [0x0, 0x00, 0x0, 0x0, 0x0];
|
||||
ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x20, 0x0C, 0x0, 0x0, 0x0]
|
||||
: [0x20, 0x00, 0x0, 0x0, 0x0];
|
||||
ril.iccInfoPrivate.sst = (aSimType === CARD_APPTYPE_SIM)?
|
||||
[0x20, 0x0, 0x0, 0x0, 0x0]:
|
||||
[0x2, 0x0, 0x0, 0x0, 0x0];
|
||||
|
||||
recordHelper.readPBR = function(onsuccess, onerror) {
|
||||
if (aFileType === ICC_USIM_TYPE1_TAG) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "TelephonyCall.h"
|
||||
#include "mozilla/dom/CallEvent.h"
|
||||
#include "mozilla/dom/TelephonyCallBinding.h"
|
||||
#include "mozilla/dom/telephony/TelephonyCallback.h"
|
||||
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
|
||||
@ -14,6 +15,7 @@
|
||||
#include "TelephonyCallGroup.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::telephony;
|
||||
using mozilla::ErrorResult;
|
||||
|
||||
// static
|
||||
@ -226,100 +228,140 @@ TelephonyCall::GetGroup() const
|
||||
return group.forget();
|
||||
}
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
TelephonyCall::Answer(ErrorResult& aRv)
|
||||
{
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_INCOMING) {
|
||||
NS_WARNING("Answer on non-incoming call ignored!");
|
||||
return;
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult rv = mTelephony->Service()->AnswerCall(mServiceId, mCallIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_INCOMING) {
|
||||
NS_WARNING("Answer on non-incoming call is rejected!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||
aRv = mTelephony->Service()->AnswerCall(mServiceId, mCallIndex, callback);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
ChangeStateInternal(nsITelephonyService::CALL_STATE_CONNECTING, true);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
TelephonyCall::HangUp(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
if (mCallState == nsITelephonyService::CALL_STATE_DISCONNECTING ||
|
||||
mCallState == nsITelephonyService::CALL_STATE_DISCONNECTED) {
|
||||
NS_WARNING("HangUp on previously disconnected call ignored!");
|
||||
return;
|
||||
NS_WARNING("HangUp on previously disconnected call is rejected!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsresult rv = mCallState == nsITelephonyService::CALL_STATE_INCOMING ?
|
||||
mTelephony->Service()->RejectCall(mServiceId, mCallIndex) :
|
||||
mTelephony->Service()->HangUp(mServiceId, mCallIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||
aRv = mCallState == nsITelephonyService::CALL_STATE_INCOMING ?
|
||||
mTelephony->Service()->RejectCall(mServiceId, mCallIndex, callback) :
|
||||
mTelephony->Service()->HangUpCall(mServiceId, mCallIndex, callback);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
ChangeStateInternal(nsITelephonyService::CALL_STATE_DISCONNECTING, true);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
TelephonyCall::Hold(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_CONNECTED) {
|
||||
NS_WARNING("Hold non-connected call ignored!");
|
||||
return;
|
||||
NS_WARNING("Hold non-connected call is rejected!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (mGroup) {
|
||||
NS_WARNING("Hold a call in conference ignored!");
|
||||
return;
|
||||
NS_WARNING("Hold a call in conference is rejected!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (!mSwitchable) {
|
||||
NS_WARNING("Hold a non-switchable call ignored!");
|
||||
return;
|
||||
NS_WARNING("Hold a non-switchable call is rejected!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsresult rv = mTelephony->Service()->HoldCall(mServiceId, mCallIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||
aRv = mTelephony->Service()->HoldCall(mServiceId, mCallIndex, callback);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
if (mSecondId) {
|
||||
// No state transition when we switch two numbers within one TelephonyCall
|
||||
// object. Otherwise, the state here will be inconsistent with the backend
|
||||
// RIL and will never be right.
|
||||
return;
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
ChangeStateInternal(nsITelephonyService::CALL_STATE_HOLDING, true);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
TelephonyCall::Resume(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
if (mCallState != nsITelephonyService::CALL_STATE_HELD) {
|
||||
NS_WARNING("Resume non-held call ignored!");
|
||||
return;
|
||||
NS_WARNING("Resume non-held call is rejected!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (mGroup) {
|
||||
NS_WARNING("Resume a call in conference ignored!");
|
||||
return;
|
||||
NS_WARNING("Resume a call in conference is rejected!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (!mSwitchable) {
|
||||
NS_WARNING("Resume a non-switchable call ignored!");
|
||||
return;
|
||||
NS_WARNING("Resume a non-switchable call is rejected!");
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsresult rv = mTelephony->Service()->ResumeCall(mServiceId, mCallIndex);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
|
||||
aRv = mTelephony->Service()->ResumeCall(mServiceId, mCallIndex, callback);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
ChangeStateInternal(nsITelephonyService::CALL_STATE_RESUMING, true);
|
||||
return promise.forget();
|
||||
}
|
||||
|
@ -7,11 +7,10 @@
|
||||
#ifndef mozilla_dom_telephony_telephonycall_h__
|
||||
#define mozilla_dom_telephony_telephonycall_h__
|
||||
|
||||
#include "mozilla/dom/telephony/TelephonyCommon.h"
|
||||
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
|
||||
#include "TelephonyCallId.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/TelephonyCallId.h"
|
||||
#include "mozilla/dom/telephony/TelephonyCommon.h"
|
||||
|
||||
class nsPIDOMWindow;
|
||||
|
||||
@ -91,16 +90,16 @@ public:
|
||||
already_AddRefed<TelephonyCallGroup>
|
||||
GetGroup() const;
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
Answer(ErrorResult& aRv);
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
HangUp(ErrorResult& aRv);
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
Hold(ErrorResult& aRv);
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
Resume(ErrorResult& aRv);
|
||||
|
||||
IMPL_EVENT_HANDLER(statechange)
|
||||
|
@ -497,7 +497,7 @@ TelephonyService.prototype = {
|
||||
} else if (aNumber === "1") {
|
||||
this._sendToRilWorker(aClientId, "hangUpForeground", null, mmiCallback);
|
||||
} else if (aNumber[0] === "1" && aNumber.length === 2) {
|
||||
this._sendToRilWorker(aClientId, "hangUp",
|
||||
this._sendToRilWorker(aClientId, "hangUpCall",
|
||||
{ callIndex: parseInt(aNumber[1]) }, mmiCallback);
|
||||
} else if (aNumber === "2") {
|
||||
this._sendToRilWorker(aClientId, "switchActiveCall", null, mmiCallback);
|
||||
@ -589,7 +589,9 @@ TelephonyService.prototype = {
|
||||
if (activeCall.isConference) {
|
||||
this.holdConference(aClientId);
|
||||
} else {
|
||||
this.holdCall(aClientId, activeCall.callIndex);
|
||||
this.holdCall(aClientId, activeCall.callIndex,
|
||||
{ notifySuccess: function () {},
|
||||
notifyError: function (errorMsg) {} });
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -879,14 +881,19 @@ TelephonyService.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
hangUp: function(aClientId, aCallIndex) {
|
||||
let parentId = this._currentCalls[aClientId][aCallIndex].parentId;
|
||||
if (parentId) {
|
||||
// Should release both, child and parent, together. Since RIL holds only
|
||||
// the parent call, we send 'parentId' to RIL.
|
||||
this.hangUp(aClientId, parentId);
|
||||
/**
|
||||
* The default callback handler for call operations.
|
||||
*
|
||||
* @param aCallback
|
||||
* An callback object including notifySuccess() and notifyError(aMsg)
|
||||
* @param aResponse
|
||||
* The response from ril_worker.
|
||||
*/
|
||||
_defaultCallbackHandler: function(aCallback, aResponse) {
|
||||
if (!aResponse.success) {
|
||||
aCallback.notifyError(aResponse.errorMsg);
|
||||
} else {
|
||||
this._sendToRilWorker(aClientId, "hangUp", { callIndex: aCallIndex });
|
||||
aCallback.notifySuccess();
|
||||
}
|
||||
},
|
||||
|
||||
@ -898,34 +905,48 @@ TelephonyService.prototype = {
|
||||
this._sendToRilWorker(aClientId, "stopTone");
|
||||
},
|
||||
|
||||
answerCall: function(aClientId, aCallIndex) {
|
||||
this._sendToRilWorker(aClientId, "answerCall", { callIndex: aCallIndex });
|
||||
answerCall: function(aClientId, aCallIndex, aCallback) {
|
||||
this._sendToRilWorker(aClientId, "answerCall", { callIndex: aCallIndex },
|
||||
this._defaultCallbackHandler.bind(this, aCallback));
|
||||
},
|
||||
|
||||
rejectCall: function(aClientId, aCallIndex) {
|
||||
this._sendToRilWorker(aClientId, "rejectCall", { callIndex: aCallIndex });
|
||||
rejectCall: function(aClientId, aCallIndex, aCallback) {
|
||||
this._sendToRilWorker(aClientId, "rejectCall", { callIndex: aCallIndex },
|
||||
this._defaultCallbackHandler.bind(this, aCallback));
|
||||
},
|
||||
|
||||
holdCall: function(aClientId, aCallIndex) {
|
||||
hangUpCall: function(aClientId, aCallIndex, aCallback) {
|
||||
let parentId = this._currentCalls[aClientId][aCallIndex].parentId;
|
||||
if (parentId) {
|
||||
// Should release both, child and parent, together. Since RIL holds only
|
||||
// the parent call, we send 'parentId' to RIL.
|
||||
this.hangUpCall(aClientId, parentId, aCallback);
|
||||
} else {
|
||||
this._sendToRilWorker(aClientId, "hangUpCall", { callIndex: aCallIndex },
|
||||
this._defaultCallbackHandler.bind(this, aCallback));
|
||||
}
|
||||
},
|
||||
|
||||
holdCall: function(aClientId, aCallIndex, aCallback) {
|
||||
let call = this._currentCalls[aClientId][aCallIndex];
|
||||
if (!call || !call.isSwitchable) {
|
||||
// TODO: Bug 975949 - [B2G] Telephony should throw exceptions when some
|
||||
// operations aren't allowed instead of simply ignoring them.
|
||||
aCallback.notifyError(RIL.GECKO_ERROR_GENERIC_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendToRilWorker(aClientId, "holdCall", { callIndex: aCallIndex });
|
||||
this._sendToRilWorker(aClientId, "holdCall", { callIndex: aCallIndex },
|
||||
this._defaultCallbackHandler.bind(this, aCallback));
|
||||
},
|
||||
|
||||
resumeCall: function(aClientId, aCallIndex) {
|
||||
resumeCall: function(aClientId, aCallIndex, aCallback) {
|
||||
let call = this._currentCalls[aClientId][aCallIndex];
|
||||
if (!call || !call.isSwitchable) {
|
||||
// TODO: Bug 975949 - [B2G] Telephony should throw exceptions when some
|
||||
// operations aren't allowed instead of simply ignoring them.
|
||||
aCallback.notifyError(RIL.GECKO_ERROR_GENERIC_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
this._sendToRilWorker(aClientId, "resumeCall", { callIndex: aCallIndex });
|
||||
this._sendToRilWorker(aClientId, "resumeCall", { callIndex: aCallIndex },
|
||||
this._defaultCallbackHandler.bind(this, aCallback));
|
||||
},
|
||||
|
||||
conferenceCall: function(aClientId) {
|
||||
|
@ -35,12 +35,47 @@ struct HangUpConferenceRequest
|
||||
uint32_t clientId;
|
||||
};
|
||||
|
||||
struct AnswerCallRequest
|
||||
{
|
||||
uint32_t clientId;
|
||||
uint32_t callIndex;
|
||||
};
|
||||
|
||||
struct HangUpCallRequest
|
||||
{
|
||||
uint32_t clientId;
|
||||
uint32_t callIndex;
|
||||
};
|
||||
|
||||
struct RejectCallRequest
|
||||
{
|
||||
uint32_t clientId;
|
||||
uint32_t callIndex;
|
||||
};
|
||||
|
||||
struct HoldCallRequest
|
||||
{
|
||||
uint32_t clientId;
|
||||
uint32_t callIndex;
|
||||
};
|
||||
|
||||
struct ResumeCallRequest
|
||||
{
|
||||
uint32_t clientId;
|
||||
uint32_t callIndex;
|
||||
};
|
||||
|
||||
union IPCTelephonyRequest
|
||||
{
|
||||
EnumerateCallsRequest;
|
||||
DialRequest;
|
||||
USSDRequest;
|
||||
HangUpConferenceRequest;
|
||||
AnswerCallRequest;
|
||||
HangUpCallRequest;
|
||||
RejectCallRequest;
|
||||
HoldCallRequest;
|
||||
ResumeCallRequest;
|
||||
};
|
||||
|
||||
sync protocol PTelephony {
|
||||
@ -76,16 +111,6 @@ parent:
|
||||
|
||||
UnregisterListener();
|
||||
|
||||
HangUpCall(uint32_t aClientId, uint32_t aCallIndex);
|
||||
|
||||
AnswerCall(uint32_t aClientId, uint32_t aCallIndex);
|
||||
|
||||
RejectCall(uint32_t aClientId, uint32_t aCallIndex);
|
||||
|
||||
HoldCall(uint32_t aClientId, uint32_t aCallIndex);
|
||||
|
||||
ResumeCall(uint32_t aClientId, uint32_t aCallIndex);
|
||||
|
||||
ConferenceCall(uint32_t aClientId);
|
||||
|
||||
SeparateCall(uint32_t aClientId, uint32_t aCallIndex);
|
||||
|
@ -171,63 +171,63 @@ TelephonyIPCService::Dial(uint32_t aClientId, const nsAString& aNumber,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::HangUp(uint32_t aClientId, uint32_t aCallIndex)
|
||||
TelephonyIPCService::AnswerCall(uint32_t aClientId, uint32_t aCallIndex,
|
||||
nsITelephonyCallback *aCallback)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyService used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendHangUpCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
return SendRequest(nullptr, aCallback, AnswerCallRequest(aClientId, aCallIndex));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::AnswerCall(uint32_t aClientId, uint32_t aCallIndex)
|
||||
TelephonyIPCService::HangUpCall(uint32_t aClientId, uint32_t aCallIndex,
|
||||
nsITelephonyCallback *aCallback)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyService used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendAnswerCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
return SendRequest(nullptr, aCallback, HangUpCallRequest(aClientId, aCallIndex));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::RejectCall(uint32_t aClientId, uint32_t aCallIndex)
|
||||
TelephonyIPCService::RejectCall(uint32_t aClientId, uint32_t aCallIndex,
|
||||
nsITelephonyCallback *aCallback)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyService used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendRejectCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
return SendRequest(nullptr, aCallback, RejectCallRequest(aClientId, aCallIndex));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::HoldCall(uint32_t aClientId, uint32_t aCallIndex)
|
||||
TelephonyIPCService::HoldCall(uint32_t aClientId, uint32_t aCallIndex,
|
||||
nsITelephonyCallback *aCallback)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyService used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendHoldCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
return SendRequest(nullptr, aCallback, HoldCallRequest(aClientId, aCallIndex));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::ResumeCall(uint32_t aClientId, uint32_t aCallIndex)
|
||||
TelephonyIPCService::ResumeCall(uint32_t aClientId, uint32_t aCallIndex,
|
||||
nsITelephonyCallback *aCallback)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyService used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendResumeCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
return SendRequest(nullptr, aCallback, ResumeCallRequest(aClientId, aCallIndex));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -37,16 +37,71 @@ TelephonyParent::RecvPTelephonyRequestConstructor(PTelephonyRequestParent* aActo
|
||||
const IPCTelephonyRequest& aRequest)
|
||||
{
|
||||
TelephonyRequestParent* actor = static_cast<TelephonyRequestParent*>(aActor);
|
||||
nsCOMPtr<nsITelephonyService> service = do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
|
||||
if (!service) {
|
||||
return NS_SUCCEEDED(actor->NotifyError(NS_LITERAL_STRING("InvalidStateError")));
|
||||
}
|
||||
|
||||
switch (aRequest.type()) {
|
||||
case IPCTelephonyRequest::TEnumerateCallsRequest:
|
||||
return actor->DoRequest(aRequest.get_EnumerateCallsRequest());
|
||||
case IPCTelephonyRequest::TDialRequest:
|
||||
return actor->DoRequest(aRequest.get_DialRequest());
|
||||
case IPCTelephonyRequest::TUSSDRequest:
|
||||
return actor->DoRequest(aRequest.get_USSDRequest());
|
||||
case IPCTelephonyRequest::THangUpConferenceRequest:
|
||||
return actor->DoRequest(aRequest.get_HangUpConferenceRequest());
|
||||
case IPCTelephonyRequest::TEnumerateCallsRequest: {
|
||||
nsresult rv = service->EnumerateCalls(actor);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_SUCCEEDED(EnumerateCallStateComplete());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
case IPCTelephonyRequest::TDialRequest: {
|
||||
const DialRequest& request = aRequest.get_DialRequest();
|
||||
service->Dial(request.clientId(), request.number(),
|
||||
request.isEmergency(), actor);
|
||||
return true;
|
||||
}
|
||||
|
||||
case IPCTelephonyRequest::TUSSDRequest: {
|
||||
const USSDRequest& request = aRequest.get_USSDRequest();
|
||||
service->SendUSSD(request.clientId(), request.ussd(), actor);
|
||||
return true;
|
||||
}
|
||||
|
||||
case IPCTelephonyRequest::THangUpConferenceRequest: {
|
||||
const HangUpConferenceRequest& request = aRequest.get_HangUpConferenceRequest();
|
||||
service->HangUpConference(request.clientId(), actor);
|
||||
return true;
|
||||
}
|
||||
|
||||
case IPCTelephonyRequest::TAnswerCallRequest: {
|
||||
const AnswerCallRequest& request = aRequest.get_AnswerCallRequest();
|
||||
service->AnswerCall(request.clientId(), request.callIndex(), actor);
|
||||
return true;
|
||||
}
|
||||
|
||||
case IPCTelephonyRequest::THangUpCallRequest: {
|
||||
const HangUpCallRequest& request = aRequest.get_HangUpCallRequest();
|
||||
service->HangUpCall(request.clientId(), request.callIndex(), actor);
|
||||
return true;
|
||||
}
|
||||
|
||||
case IPCTelephonyRequest::TRejectCallRequest: {
|
||||
const RejectCallRequest& request = aRequest.get_RejectCallRequest();
|
||||
service->RejectCall(request.clientId(), request.callIndex(), actor);
|
||||
return true;
|
||||
}
|
||||
|
||||
case IPCTelephonyRequest::THoldCallRequest: {
|
||||
const HoldCallRequest& request = aRequest.get_HoldCallRequest();
|
||||
service->HoldCall(request.clientId(), request.callIndex(), actor);
|
||||
return true;
|
||||
}
|
||||
|
||||
case IPCTelephonyRequest::TResumeCallRequest: {
|
||||
const ResumeCallRequest& request = aRequest.get_ResumeCallRequest();
|
||||
service->ResumeCall(request.clientId(), request.callIndex(), actor);
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unknown type!");
|
||||
}
|
||||
@ -105,66 +160,6 @@ TelephonyParent::RecvUnregisterListener()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyParent::RecvHangUpCall(const uint32_t& aClientId,
|
||||
const uint32_t& aCallIndex)
|
||||
{
|
||||
nsCOMPtr<nsITelephonyService> service =
|
||||
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(service, true);
|
||||
|
||||
service->HangUp(aClientId, aCallIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyParent::RecvAnswerCall(const uint32_t& aClientId,
|
||||
const uint32_t& aCallIndex)
|
||||
{
|
||||
nsCOMPtr<nsITelephonyService> service =
|
||||
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(service, true);
|
||||
|
||||
service->AnswerCall(aClientId, aCallIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyParent::RecvRejectCall(const uint32_t& aClientId,
|
||||
const uint32_t& aCallIndex)
|
||||
{
|
||||
nsCOMPtr<nsITelephonyService> service =
|
||||
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(service, true);
|
||||
|
||||
service->RejectCall(aClientId, aCallIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyParent::RecvHoldCall(const uint32_t& aClientId,
|
||||
const uint32_t& aCallIndex)
|
||||
{
|
||||
nsCOMPtr<nsITelephonyService> service =
|
||||
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(service, true);
|
||||
|
||||
service->HoldCall(aClientId, aCallIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyParent::RecvResumeCall(const uint32_t& aClientId,
|
||||
const uint32_t& aCallIndex)
|
||||
{
|
||||
nsCOMPtr<nsITelephonyService> service =
|
||||
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(service, true);
|
||||
|
||||
service->ResumeCall(aClientId, aCallIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyParent::RecvConferenceCall(const uint32_t& aClientId)
|
||||
{
|
||||
@ -406,67 +401,6 @@ TelephonyRequestParent::ActorDestroy(ActorDestroyReason why)
|
||||
mActorDestroyed = true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyRequestParent::DoRequest(const EnumerateCallsRequest& aRequest)
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsITelephonyService> service =
|
||||
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
if (service) {
|
||||
rv = service->EnumerateCalls(this);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_SUCCEEDED(EnumerateCallStateComplete());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyRequestParent::DoRequest(const DialRequest& aRequest)
|
||||
{
|
||||
nsCOMPtr<nsITelephonyService> service =
|
||||
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
if (service) {
|
||||
service->Dial(aRequest.clientId(), aRequest.number(),
|
||||
aRequest.isEmergency(), this);
|
||||
} else {
|
||||
return NS_SUCCEEDED(NotifyError(NS_LITERAL_STRING("InvalidStateError")));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyRequestParent::DoRequest(const USSDRequest& aRequest)
|
||||
{
|
||||
nsCOMPtr<nsITelephonyService> service =
|
||||
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
if (service) {
|
||||
service->SendUSSD(aRequest.clientId(), aRequest.ussd(), this);
|
||||
} else {
|
||||
return NS_SUCCEEDED(NotifyError(NS_LITERAL_STRING("InvalidStateError")));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyRequestParent::DoRequest(const HangUpConferenceRequest& aRequest)
|
||||
{
|
||||
nsCOMPtr<nsITelephonyService> service =
|
||||
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
|
||||
if (service) {
|
||||
service->HangUpConference(aRequest.clientId(), this);
|
||||
} else {
|
||||
return NS_SUCCEEDED(NotifyError(NS_LITERAL_STRING("InvalidStateError")));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
TelephonyRequestParent::SendResponse(const IPCTelephonyResponse& aResponse)
|
||||
{
|
||||
|
@ -46,21 +46,6 @@ protected:
|
||||
virtual bool
|
||||
RecvUnregisterListener() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvHangUpCall(const uint32_t& aClientId, const uint32_t& aCallIndex) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvAnswerCall(const uint32_t& aClientId, const uint32_t& aCallIndex) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvRejectCall(const uint32_t& aClientId, const uint32_t& aCallIndex) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvHoldCall(const uint32_t& aClientId, const uint32_t& aCallIndex) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvResumeCall(const uint32_t& aClientId, const uint32_t& aCallIndex) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvConferenceCall(const uint32_t& aClientId) MOZ_OVERRIDE;
|
||||
|
||||
@ -120,18 +105,6 @@ protected:
|
||||
|
||||
private:
|
||||
bool mActorDestroyed;
|
||||
|
||||
bool
|
||||
DoRequest(const EnumerateCallsRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const DialRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const USSDRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const HangUpConferenceRequest& aRequest);
|
||||
};
|
||||
|
||||
END_TELEPHONY_NAMESPACE
|
||||
|
@ -10,7 +10,7 @@
|
||||
"@mozilla.org/telephony/gonktelephonyservice;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(cbbe66d8-865b-11e4-94f1-ab441e55905b)]
|
||||
[scriptable, uuid(aec05f05-0ca5-470b-8230-cdee0209eafd)]
|
||||
interface nsIGonkTelephonyService : nsITelephonyService
|
||||
{
|
||||
void notifyAudioStateChanged(in unsigned long clientId, in short state);
|
||||
|
@ -251,7 +251,7 @@ interface nsITelephonyDialCallback : nsITelephonyCallback
|
||||
* XPCOM component (in the content process) that provides the telephony
|
||||
* information.
|
||||
*/
|
||||
[scriptable, uuid(6fa2d94b-80ee-4085-b6a0-535811ba9bb6)]
|
||||
[scriptable, uuid(fd797bcc-54e2-4e4a-9ec7-3b72862d0d78)]
|
||||
interface nsITelephonyService : nsISupports
|
||||
{
|
||||
const unsigned short CALL_STATE_UNKNOWN = 0;
|
||||
@ -295,15 +295,25 @@ interface nsITelephonyService : nsISupports
|
||||
*/
|
||||
void dial(in unsigned long clientId, in DOMString number,
|
||||
in boolean isEmergency, in nsITelephonyDialCallback callback);
|
||||
void hangUp(in unsigned long clientId, in unsigned long callIndex);
|
||||
|
||||
void startTone(in unsigned long clientId, in DOMString dtmfChar);
|
||||
void stopTone(in unsigned long clientId);
|
||||
|
||||
void answerCall(in unsigned long clientId, in unsigned long callIndex);
|
||||
void rejectCall(in unsigned long clientId, in unsigned long callIndex);
|
||||
void holdCall(in unsigned long clientId, in unsigned long callIndex);
|
||||
void resumeCall(in unsigned long clientId, in unsigned long callIndex);
|
||||
void answerCall(in unsigned long clientId,
|
||||
in unsigned long callIndex,
|
||||
in nsITelephonyCallback callback);
|
||||
void rejectCall(in unsigned long clientId,
|
||||
in unsigned long callIndex,
|
||||
in nsITelephonyCallback callback);
|
||||
void hangUpCall(in unsigned long clientId,
|
||||
in unsigned long callIndex,
|
||||
in nsITelephonyCallback callback);
|
||||
void holdCall(in unsigned long clientId,
|
||||
in unsigned long callIndex,
|
||||
in nsITelephonyCallback callback);
|
||||
void resumeCall(in unsigned long clientId,
|
||||
in unsigned long callIndex,
|
||||
in nsITelephonyCallback callback);
|
||||
|
||||
void conferenceCall(in unsigned long clientId);
|
||||
void separateCall(in unsigned long clientId, in unsigned long callIndex);
|
||||
|
@ -520,7 +520,8 @@ let emulator = (function() {
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
call.answer();
|
||||
promise = call.answer();
|
||||
promises.push(promise);
|
||||
|
||||
return Promise.all(promises).then(() => call);
|
||||
}
|
||||
@ -535,12 +536,16 @@ let emulator = (function() {
|
||||
function hold(call) {
|
||||
log("Putting the call on hold.");
|
||||
|
||||
let promises = [];
|
||||
|
||||
let promise = waitForNamedStateEvent(call, "holding")
|
||||
.then(() => waitForNamedStateEvent(call, "held"));
|
||||
promises.push(promise);
|
||||
|
||||
call.hold();
|
||||
promise = call.hold();
|
||||
promises.push(promise);
|
||||
|
||||
return promise;
|
||||
return Promise.all(promises).then(() => call);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -553,12 +558,16 @@ let emulator = (function() {
|
||||
function resume(call) {
|
||||
log("Resuming the held call.");
|
||||
|
||||
let promises = [];
|
||||
|
||||
let promise = waitForNamedStateEvent(call, "resuming")
|
||||
.then(() => waitForNamedStateEvent(call, "connected"));
|
||||
promises.push(promise);
|
||||
|
||||
call.resume();
|
||||
promise = call.resume();
|
||||
promises.push(promise);
|
||||
|
||||
return promise;
|
||||
return Promise.all(promises).then(() => call);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -571,12 +580,16 @@ let emulator = (function() {
|
||||
function hangUp(call) {
|
||||
log("Local hanging up the call: " + call.id.number);
|
||||
|
||||
let promises = [];
|
||||
|
||||
let promise = waitForNamedStateEvent(call, "disconnecting")
|
||||
.then(() => waitForNamedStateEvent(call, "disconnected"));
|
||||
promises.push(promise);
|
||||
|
||||
call.hangUp();
|
||||
promise = call.hangUp();
|
||||
promises.push(promise);
|
||||
|
||||
return promise;
|
||||
return Promise.all(promises).then(() => call);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,9 +15,11 @@ function incoming() {
|
||||
}
|
||||
|
||||
function connecting() {
|
||||
let promise = gWaitForNamedStateEvent(inCall, "connecting");
|
||||
inCall.answer();
|
||||
return promise;
|
||||
let promises = [
|
||||
gWaitForNamedStateEvent(inCall, "connecting"),
|
||||
inCall.answer()
|
||||
];
|
||||
return Promise.all(promises).then(() => inCall);
|
||||
}
|
||||
|
||||
function hangUp() {
|
||||
|
@ -18,12 +18,13 @@ function checkUnexpected(msg, call, event1, event2, actionCallback) {
|
||||
|
||||
call.addEventListener(event1, error1);
|
||||
call.addEventListener(event2, error2);
|
||||
actionCallback();
|
||||
|
||||
return gDelay(2000).then(() => {
|
||||
call.removeEventListener(event1, error1);
|
||||
call.removeEventListener(event2, error2);
|
||||
});
|
||||
return actionCallback().then(
|
||||
() => ok(false, msg + "should be rejected."),
|
||||
() => gDelay(2000).then(() => {
|
||||
call.removeEventListener(event1, error1);
|
||||
call.removeEventListener(event2, error2);
|
||||
}));
|
||||
}
|
||||
|
||||
startTest(function() {
|
||||
|
@ -9,6 +9,7 @@ support-files =
|
||||
[test_custom_element_callback_innerhtml.html]
|
||||
[test_custom_element_clone_callbacks.html]
|
||||
[test_custom_element_clone_callbacks_extended.html]
|
||||
[test_custom_element_import_node_created_callback.html]
|
||||
[test_nested_content_element.html]
|
||||
[test_dest_insertion_points.html]
|
||||
[test_dest_insertion_points_shadow.html]
|
||||
|
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1093680
|
||||
-->
|
||||
<head>
|
||||
<title>Test created callback order for imported custom element.</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<template id="template"><x-foo><span></span></x-foo></template>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1093680">Bug 1093680</a>
|
||||
<script>
|
||||
|
||||
var fooProtoCreatedCallbackCalled = false;
|
||||
var fooProto = Object.create(HTMLElement.prototype);
|
||||
fooProto.createdCallback = function() {
|
||||
ok(this.firstElementChild, "When the created callback is called, the element should already have a child because the callback should only be called after cloning all the contents.");
|
||||
fooProtoCreatedCallbackCalled = true;
|
||||
};
|
||||
|
||||
document.registerElement("x-foo", { prototype: fooProto });
|
||||
|
||||
var template = document.getElementById("template");
|
||||
|
||||
// Importing node will implicityly clone the conent in the main document.
|
||||
var adoptedFoo = document.importNode(template.content, true);
|
||||
|
||||
ok(fooProtoCreatedCallbackCalled, "Created callback should be called after importing custom element into document");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#the-applet-element
|
||||
[NeedResolve]
|
||||
[NeedResolve, UnsafeInPrerendering]
|
||||
interface HTMLAppletElement : HTMLElement {
|
||||
[Pure, SetterThrows]
|
||||
attribute DOMString align;
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#the-object-element
|
||||
[NeedResolve]
|
||||
[NeedResolve, UnsafeInPrerendering]
|
||||
interface HTMLObjectElement : HTMLElement {
|
||||
[Pure, SetterThrows]
|
||||
attribute DOMString data;
|
||||
|
@ -82,6 +82,13 @@ enum IccContactType
|
||||
"sdn" // Service Dialling Number.
|
||||
};
|
||||
|
||||
enum IccMvnoType
|
||||
{
|
||||
"imsi",
|
||||
"spn",
|
||||
"gid"
|
||||
};
|
||||
|
||||
dictionary IccUnlockCardLockOptions
|
||||
{
|
||||
required IccLockType lockType;
|
||||
@ -315,17 +322,13 @@ interface MozIcc : EventTarget
|
||||
*
|
||||
* @param mvnoType
|
||||
* Mvno type to use to compare the match data.
|
||||
* Currently, we only support 'imsi'.
|
||||
* @param matchData
|
||||
* Data to be compared with ICC's field.
|
||||
*
|
||||
* @return a DOMRequest.
|
||||
* The request's result will be a boolean indicating the matching
|
||||
* result.
|
||||
*
|
||||
* TODO: change param mvnoType to WebIDL enum after Bug 864489 -
|
||||
* B2G RIL: use ipdl as IPC in MozIccManager
|
||||
*/
|
||||
[Throws]
|
||||
DOMRequest matchMvno(DOMString mvnoType, DOMString matchData);
|
||||
DOMRequest matchMvno(IccMvnoType mvnoType, DOMString matchData);
|
||||
};
|
||||
|
@ -73,7 +73,8 @@ interface MozNFCManager {
|
||||
NavigatorProperty="mozNfc",
|
||||
Func="Navigator::HasNFCSupport",
|
||||
CheckPermissions="nfc nfc-share",
|
||||
AvailableIn="PrivilegedApps"]
|
||||
AvailableIn="PrivilegedApps",
|
||||
UnsafeInPrerendering]
|
||||
interface MozNFC : EventTarget {
|
||||
/**
|
||||
* Indicate if NFC is enabled.
|
||||
|
@ -10,6 +10,11 @@
|
||||
|
||||
[JSImplementation="@mozilla.org/nfc/peer;1", AvailableIn="PrivilegedApps"]
|
||||
interface MozNFCPeer {
|
||||
/**
|
||||
* Indicate if this peer is already lost.
|
||||
*/
|
||||
readonly attribute boolean isLost;
|
||||
|
||||
/**
|
||||
* Send NDEF data to peer device.
|
||||
*/
|
||||
@ -28,8 +33,6 @@ partial interface MozNFCPeer {
|
||||
[ChromeOnly]
|
||||
attribute DOMString session;
|
||||
|
||||
/**
|
||||
* Indicate if this peer is already lost.
|
||||
*/
|
||||
readonly attribute boolean isLost;
|
||||
[ChromeOnly]
|
||||
void notifyLost();
|
||||
};
|
||||
|
@ -8,28 +8,31 @@
|
||||
* Copyright © 2013 Deutsche Telekom, Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The enumeration of NFC Tag technologies.
|
||||
*/
|
||||
enum NFCTechType {
|
||||
"NFC_A",
|
||||
"NFC_B",
|
||||
"NFC_F",
|
||||
"NFC_V",
|
||||
"NFC_ISO_DEP",
|
||||
"MIFARE_CLASSIC",
|
||||
"MIFARE_ULTRALIGHT",
|
||||
"NFC_BARCODE"
|
||||
"NFC-A", // NFCForum-TS-DigitalProtocol-1.1 NFC-A.
|
||||
"NFC-B", // NFCForum-TS-DigitalProtocol-1.1 NFC-B.
|
||||
"NFC-F", // NFCForum-TS-DigitalProtocol-1.1 NFC-F.
|
||||
"NFC-V", // ISO 15693.
|
||||
"ISO-DEP", // NFCForum-TS-DigitalProtocol-1.1 ISO-DEP.
|
||||
"MIFARE-Classic", // MIFARE Classic from NXP.
|
||||
"MIFARE-Ultralight", // MIFARE Ultralight from NXP.
|
||||
"NFC-Barcode" // NFC Barcode from Kovio.
|
||||
};
|
||||
|
||||
/**
|
||||
* The enumeration of the types of the tag, the type of a tag could be either
|
||||
* one of those types defined in NFC Forum (type1 ~ type 4), or it could be a
|
||||
* NXP-specific tag, like Mifare Classic.
|
||||
* one of those types defined in NFC Forum Tag Types (Type1 ~ Type 4), or it
|
||||
* could be a NXP-specific tag, like MIFARE Classic.
|
||||
*/
|
||||
enum NFCTagType {
|
||||
"type1",
|
||||
"type2",
|
||||
"type3",
|
||||
"type4",
|
||||
"mifare_classic"
|
||||
"Type1",
|
||||
"Type2",
|
||||
"Type3",
|
||||
"Type4",
|
||||
"MIFARE-Classic"
|
||||
};
|
||||
|
||||
[JSImplementation="@mozilla.org/nfc/tag;1", AvailableIn="PrivilegedApps"]
|
||||
@ -69,6 +72,11 @@ interface MozNFCTag {
|
||||
*/
|
||||
readonly attribute boolean? canBeMadeReadOnly;
|
||||
|
||||
/**
|
||||
* Indicate if this tag is already lost.
|
||||
*/
|
||||
readonly attribute boolean isLost;
|
||||
|
||||
/**
|
||||
* Read current NDEF data on the tag.
|
||||
*/
|
||||
@ -99,8 +107,6 @@ partial interface MozNFCTag {
|
||||
[ChromeOnly]
|
||||
attribute DOMString session;
|
||||
|
||||
/**
|
||||
* Indicate if this tag is already lost.
|
||||
*/
|
||||
readonly attribute boolean isLost;
|
||||
[ChromeOnly]
|
||||
void notifyLost();
|
||||
};
|
||||
|
@ -126,7 +126,8 @@ dictionary IPConfiguration {
|
||||
|
||||
[JSImplementation="@mozilla.org/wifimanager;1",
|
||||
NavigatorProperty="mozWifiManager",
|
||||
Func="Navigator::HasWifiManagerSupport"]
|
||||
Func="Navigator::HasWifiManagerSupport",
|
||||
UnsafeInPrerendering]
|
||||
interface MozWifiManager : EventTarget {
|
||||
/**
|
||||
* Turn on/off wifi functionality.
|
||||
|
@ -193,7 +193,7 @@ partial interface Navigator {
|
||||
readonly attribute boolean cookieEnabled;
|
||||
[Throws]
|
||||
readonly attribute DOMString buildID;
|
||||
[Throws, CheckPermissions="power"]
|
||||
[Throws, CheckPermissions="power", UnsafeInPrerendering]
|
||||
readonly attribute MozPowerManager mozPower;
|
||||
|
||||
// WebKit/Blink/Trident/Presto support this.
|
||||
@ -240,7 +240,7 @@ partial interface Navigator {
|
||||
*
|
||||
* @param aTopic resource name
|
||||
*/
|
||||
[Throws, Pref="dom.wakelock.enabled", Func="Navigator::HasWakeLockSupport"]
|
||||
[Throws, Pref="dom.wakelock.enabled", Func="Navigator::HasWakeLockSupport", UnsafeInPrerendering]
|
||||
MozWakeLock requestWakeLock(DOMString aTopic);
|
||||
};
|
||||
|
||||
@ -344,7 +344,7 @@ partial interface Navigator {
|
||||
#ifdef MOZ_TIME_MANAGER
|
||||
// nsIDOMMozNavigatorTime
|
||||
partial interface Navigator {
|
||||
[Throws, CheckPermissions="time"]
|
||||
[Throws, CheckPermissions="time", UnsafeInPrerendering]
|
||||
readonly attribute MozTimeManager mozTime;
|
||||
};
|
||||
#endif // MOZ_TIME_MANAGER
|
||||
|
@ -33,14 +33,14 @@ interface TelephonyCall : EventTarget {
|
||||
|
||||
readonly attribute TelephonyCallGroup? group;
|
||||
|
||||
[Throws]
|
||||
void answer();
|
||||
[Throws]
|
||||
void hangUp();
|
||||
[Throws]
|
||||
void hold();
|
||||
[Throws]
|
||||
void resume();
|
||||
[NewObject, Throws]
|
||||
Promise<void> answer();
|
||||
[NewObject, Throws]
|
||||
Promise<void> hangUp();
|
||||
[NewObject, Throws]
|
||||
Promise<void> hold();
|
||||
[NewObject, Throws]
|
||||
Promise<void> resume();
|
||||
|
||||
attribute EventHandler onstatechange;
|
||||
attribute EventHandler ondialing;
|
||||
|
@ -122,6 +122,9 @@ interface MozFrameLoaderOwner {
|
||||
[ChromeOnly]
|
||||
readonly attribute MozFrameLoader? frameLoader;
|
||||
|
||||
[ChromeOnly]
|
||||
void setIsPrerendered();
|
||||
|
||||
[ChromeOnly, Throws]
|
||||
void swapFrameLoaders(XULElement aOtherOwner);
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user