зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team, a=merge
This commit is contained in:
Коммит
4376962c65
|
@ -533,11 +533,6 @@ public:
|
|||
*/
|
||||
virtual void SetSelected(bool aSelect);
|
||||
|
||||
/**
|
||||
* Extend selection to this accessible.
|
||||
*/
|
||||
void ExtendSelection() { };
|
||||
|
||||
/**
|
||||
* Select the accessible within its container.
|
||||
*/
|
||||
|
|
|
@ -192,10 +192,5 @@ OuterDocAccessible::RemoteChildDoc() const
|
|||
if (!tab)
|
||||
return nullptr;
|
||||
|
||||
if (DocAccessibleParent* doc = tab->GetTopLevelDocAccessible()) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false, "no top level tab document?");
|
||||
return nullptr;
|
||||
return tab->GetTopLevelDocAccessible();
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class Accessible;
|
|||
* Mozilla creates the implementations of nsIAccessible on demand.
|
||||
* See http://www.mozilla.org/projects/ui/accessibility for more information.
|
||||
*/
|
||||
[scriptable, uuid(66b110b0-c25a-4784-8623-f6ba40c7cfee)]
|
||||
[scriptable, uuid(de2869d9-563c-4943-996b-31a4daa4d097)]
|
||||
interface nsIAccessible : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -231,12 +231,6 @@ interface nsIAccessible : nsISupports
|
|||
*/
|
||||
void setSelected(in boolean isSelected);
|
||||
|
||||
/**
|
||||
* Extend the current selection from its current accessible anchor node
|
||||
* to this accessible
|
||||
*/
|
||||
void extendSelection();
|
||||
|
||||
/**
|
||||
* Select this accessible node only
|
||||
*/
|
||||
|
|
|
@ -1621,6 +1621,28 @@ DocAccessibleChild::RecvUnselectAll(const uint64_t& aID,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvTakeSelection(const uint64_t& aID)
|
||||
{
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (acc) {
|
||||
acc->TakeSelection();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvSetSelected(const uint64_t& aID, const bool& aSelect)
|
||||
{
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (acc) {
|
||||
acc->SetSelected(aSelect);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvDoAction(const uint64_t& aID,
|
||||
const uint8_t& aIndex,
|
||||
|
|
|
@ -401,6 +401,10 @@ public:
|
|||
virtual bool RecvUnselectAll(const uint64_t& aID,
|
||||
bool* aSuccess) override;
|
||||
|
||||
virtual bool RecvTakeSelection(const uint64_t& aID) override;
|
||||
virtual bool RecvSetSelected(const uint64_t& aID,
|
||||
const bool& aSelect) override;
|
||||
|
||||
virtual bool RecvDoAction(const uint64_t& aID,
|
||||
const uint8_t& aIndex,
|
||||
bool* aSuccess) override;
|
||||
|
|
|
@ -216,6 +216,9 @@ child:
|
|||
prio(high) sync SelectAll(uint64_t aID) returns(bool aSuccess);
|
||||
prio(high) sync UnselectAll(uint64_t aID) returns(bool aSuccess);
|
||||
|
||||
async TakeSelection(uint64_t aID);
|
||||
async SetSelected(uint64_t aID, bool aSelected);
|
||||
|
||||
prio(high) sync DoAction(uint64_t aID, uint8_t aIndex) returns(bool aSuccess);
|
||||
prio(high) sync ActionCount(uint64_t aID) returns(uint8_t aCount);
|
||||
prio(high) sync ActionDescriptionAt(uint64_t aID, uint8_t aIndex) returns(nsString aDescription);
|
||||
|
|
|
@ -906,6 +906,18 @@ ProxyAccessible::UnselectAll()
|
|||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::TakeSelection()
|
||||
{
|
||||
unused << mDoc->SendTakeSelection(mID);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyAccessible::SetSelected(bool aSelect)
|
||||
{
|
||||
unused << mDoc->SendSetSelected(mID, aSelect);
|
||||
}
|
||||
|
||||
bool
|
||||
ProxyAccessible::DoAction(uint8_t aIndex)
|
||||
{
|
||||
|
|
|
@ -309,6 +309,9 @@ public:
|
|||
bool SelectAll();
|
||||
bool UnselectAll();
|
||||
|
||||
void TakeSelection();
|
||||
void SetSelected(bool aSelect);
|
||||
|
||||
bool DoAction(uint8_t aIndex);
|
||||
uint8_t ActionCount();
|
||||
void ActionDescriptionAt(uint8_t aIndex, nsString& aDescription);
|
||||
|
|
|
@ -913,9 +913,6 @@ AccessibleWrap::accSelect(
|
|||
if (flagsSelect & SELFLAG_REMOVESELECTION)
|
||||
xpAccessible->SetSelected(false);
|
||||
|
||||
if (flagsSelect & SELFLAG_EXTENDSELECTION)
|
||||
xpAccessible->ExtendSelection();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -498,16 +498,6 @@ xpcAccessible::SetSelected(bool aSelect)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessible::ExtendSelection()
|
||||
{
|
||||
if (!Intl())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
Intl()->ExtendSelection();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessible::TakeSelection()
|
||||
{
|
||||
|
|
|
@ -73,7 +73,6 @@ public:
|
|||
final override;
|
||||
|
||||
NS_IMETHOD SetSelected(bool aSelect) final override;
|
||||
NS_IMETHOD ExtendSelection() final override;
|
||||
NS_IMETHOD TakeSelection() final override;
|
||||
NS_IMETHOD TakeFocus() final override;
|
||||
|
||||
|
|
|
@ -710,6 +710,9 @@ var settingsToObserve = {
|
|||
'ui.touch.radius.bottommm': {
|
||||
resetToPref: true
|
||||
},
|
||||
'ui.click_hold_context_menus.delay': {
|
||||
resetToPref: true
|
||||
},
|
||||
'wap.UAProf.tagname': 'x-wap-profile',
|
||||
'wap.UAProf.url': ''
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
|
@ -24,7 +24,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="25554535ee69d4c0c24a51f6a55bbabe5cb0a6b8"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>
|
||||
<!-- 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"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
|
@ -24,7 +24,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="25554535ee69d4c0c24a51f6a55bbabe5cb0a6b8"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>
|
||||
<!-- 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,11 +19,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="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="e8c6824471c8722340249166b8884c38bd4d8a26"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c72c9278ddc2f442d193474993d36e7f2cfb08c4"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="25554535ee69d4c0c24a51f6a55bbabe5cb0a6b8"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="25554535ee69d4c0c24a51f6a55bbabe5cb0a6b8"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>
|
||||
<!-- 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"/>
|
||||
|
@ -128,7 +128,7 @@
|
|||
<!-- Emulator specific things -->
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
|
||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="8d4018ebd33ac3f1a043b2d54bc578028656a659"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="2e752628276803d9f261c3c770cfaa8aef5a0c4f"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="b1f6e6797468ecce33acdb780a84cd0bbb751dd9"/>
|
||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/>
|
||||
<project name="platform_external_wpa_supplicant_8" path="external/wpa_supplicant_8" remote="b2g" revision="0c6a6547cd1fd302fa2b0f6e375654df36bf0ec4"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="aa763fa9180a222547824ae6b6064e4851c15a86"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="25554535ee69d4c0c24a51f6a55bbabe5cb0a6b8"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
|
||||
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
|
||||
|
|
|
@ -19,11 +19,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="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="e8c6824471c8722340249166b8884c38bd4d8a26"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c72c9278ddc2f442d193474993d36e7f2cfb08c4"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
|
@ -24,7 +24,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="25554535ee69d4c0c24a51f6a55bbabe5cb0a6b8"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>
|
||||
<!-- 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"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "df7683e4f7329c567deb487d11317578c6930246",
|
||||
"git_revision": "c64d6e345aa477f2a24b676e84a47020a00d015d",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "f228e30f97290c71151b622ae44190dd300f26b8",
|
||||
"revision": "1c6a621575bb216f8a1266624522c5241155e2e8",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
|
@ -24,7 +24,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="25554535ee69d4c0c24a51f6a55bbabe5cb0a6b8"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>
|
||||
<!-- 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"/>
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="25554535ee69d4c0c24a51f6a55bbabe5cb0a6b8"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="df7683e4f7329c567deb487d11317578c6930246"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c64d6e345aa477f2a24b676e84a47020a00d015d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
|
||||
|
@ -24,7 +24,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="25554535ee69d4c0c24a51f6a55bbabe5cb0a6b8"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
|
||||
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
|
||||
|
|
|
@ -635,8 +635,9 @@ Sanitizer.prototype = {
|
|||
let newWindow = existingWindow.openDialog("chrome://browser/content/", "_blank",
|
||||
features, defaultArgs);
|
||||
|
||||
let onFullScreen = null;
|
||||
if (AppConstants.platform == "macosx") {
|
||||
let onFullScreen = function(e) {
|
||||
onFullScreen = function(e) {
|
||||
newWindow.removeEventListener("fullscreen", onFullScreen);
|
||||
let docEl = newWindow.document.documentElement;
|
||||
let sizemode = docEl.getAttribute("sizemode");
|
||||
|
@ -658,7 +659,7 @@ Sanitizer.prototype = {
|
|||
// closes) and/or run too late (and not have a fully-formed window yet
|
||||
// in existence). See bug 1088137.
|
||||
let newWindowOpened = false;
|
||||
function onWindowOpened(subject, topic, data) {
|
||||
let onWindowOpened = function(subject, topic, data) {
|
||||
if (subject != newWindow)
|
||||
return;
|
||||
|
||||
|
@ -675,7 +676,7 @@ Sanitizer.prototype = {
|
|||
}
|
||||
|
||||
let numWindowsClosing = windowList.length;
|
||||
function onWindowClosed() {
|
||||
let onWindowClosed = function() {
|
||||
numWindowsClosing--;
|
||||
if (numWindowsClosing == 0) {
|
||||
Services.obs.removeObserver(onWindowClosed, "xul-window-destroyed");
|
||||
|
@ -686,9 +687,9 @@ Sanitizer.prototype = {
|
|||
}
|
||||
}
|
||||
}
|
||||
Services.obs.addObserver(onWindowOpened, "browser-delayed-startup-finished", false);
|
||||
Services.obs.addObserver(onWindowClosed, "xul-window-destroyed", false);
|
||||
});
|
||||
Services.obs.addObserver(onWindowOpened, "browser-delayed-startup-finished", false);
|
||||
Services.obs.addObserver(onWindowClosed, "xul-window-destroyed", false);
|
||||
|
||||
// Start the process of closing windows
|
||||
while (windowList.length) {
|
||||
|
|
|
@ -2621,11 +2621,11 @@ ContentPermissionPrompt.prototype = {
|
|||
},
|
||||
|
||||
_promptWebNotifications : function(aRequest) {
|
||||
var message = gBrowserBundle.GetStringFromName("webNotifications.showFromSite2");
|
||||
var message = gBrowserBundle.GetStringFromName("webNotifications.receiveFromSite");
|
||||
|
||||
var actions = [
|
||||
{
|
||||
stringId: "webNotifications.alwaysShow",
|
||||
stringId: "webNotifications.alwaysReceive",
|
||||
action: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
expireType: null,
|
||||
callback: function() {},
|
||||
|
|
|
@ -375,11 +375,11 @@ geolocation.neverShareLocation.accesskey=N
|
|||
geolocation.shareWithSite2=Would you like to share your location with this site?
|
||||
geolocation.shareWithFile2=Would you like to share your location with this file?
|
||||
|
||||
webNotifications.alwaysShow=Always Show Notifications
|
||||
webNotifications.alwaysShow.accesskey=A
|
||||
webNotifications.alwaysReceive=Always Receive Notifications
|
||||
webNotifications.alwaysReceive.accesskey=A
|
||||
webNotifications.neverShow=Always Block Notifications
|
||||
webNotifications.neverShow.accesskey=N
|
||||
webNotifications.showFromSite2=Would you like to show notifications from this site?
|
||||
webNotifications.receiveFromSite=Would you like to receive notifications from this site?
|
||||
|
||||
# Pointer lock UI
|
||||
|
||||
|
|
|
@ -2432,13 +2432,8 @@ class nsAsyncMessageToChild : public nsSameProcessAsyncMessageBase,
|
|||
public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToChild(JSContext* aCx,
|
||||
nsFrameLoader* aFrameLoader,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal)
|
||||
nsAsyncMessageToChild(JSContext* aCx, JS::Handle<JSObject*> aCpows, nsFrameLoader* aFrameLoader)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aCpows)
|
||||
, mFrameLoader(aFrameLoader)
|
||||
{
|
||||
}
|
||||
|
@ -2457,7 +2452,7 @@ public:
|
|||
nsRefPtr<nsFrameLoader> mFrameLoader;
|
||||
};
|
||||
|
||||
bool
|
||||
nsresult
|
||||
nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
|
@ -2469,27 +2464,37 @@ nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
|||
ClonedMessageData data;
|
||||
nsIContentParent* cp = tabParent->Manager();
|
||||
if (!BuildClonedMessageDataForParent(cp, aData, data)) {
|
||||
return false;
|
||||
MOZ_CRASH();
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||
jsipc::CPOWManager* mgr = cp->GetCPOWManager();
|
||||
if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
|
||||
return false;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
if (tabParent->SendAsyncMessage(nsString(aMessage), data, cpows,
|
||||
IPC::Principal(aPrincipal))) {
|
||||
return NS_OK;
|
||||
} else {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return tabParent->SendAsyncMessage(nsString(aMessage), data, cpows,
|
||||
IPC::Principal(aPrincipal));
|
||||
}
|
||||
|
||||
if (mChildMessageManager) {
|
||||
nsCOMPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage,
|
||||
aData, aCpows,
|
||||
aPrincipal);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
nsRefPtr<nsAsyncMessageToChild> ev = new nsAsyncMessageToChild(aCx, aCpows, this);
|
||||
nsresult rv = ev->Init(aCx, aMessage, aData, aPrincipal);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = NS_DispatchToCurrentThread(ev);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// We don't have any targets to send our asynchronous message to.
|
||||
return false;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -92,11 +92,11 @@ public:
|
|||
*/
|
||||
virtual bool DoLoadMessageManagerScript(const nsAString& aURL,
|
||||
bool aRunInGlobalScope) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
mozilla::dom::ipc::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
mozilla::dom::ipc::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual bool CheckPermission(const nsAString& aPermission) override;
|
||||
virtual bool CheckManifestURL(const nsAString& aManifestURL) override;
|
||||
virtual bool CheckAppHasPermission(const nsAString& aPermission) override;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "mozilla/CycleCollectedJSRuntime.h"
|
||||
#include "mozilla/IntentionalCrash.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/nsIContentParent.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
|
@ -809,8 +810,9 @@ nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows, aPrincipal)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv = mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows, aPrincipal);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1889,15 +1891,9 @@ class nsAsyncMessageToSameProcessChild : public nsSameProcessAsyncMessageBase,
|
|||
public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToSameProcessChild(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal)
|
||||
{
|
||||
}
|
||||
|
||||
nsAsyncMessageToSameProcessChild(JSContext* aCx, JS::Handle<JSObject*> aCpows)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aCpows)
|
||||
{ }
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsFrameMessageManager* ppm = nsFrameMessageManager::GetChildProcessManager();
|
||||
|
@ -1931,17 +1927,24 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new nsAsyncMessageToSameProcessChild(aCx, aMessage, aData, aCpows,
|
||||
aPrincipal);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
nsRefPtr<nsAsyncMessageToSameProcessChild> ev =
|
||||
new nsAsyncMessageToSameProcessChild(aCx, aCpows);
|
||||
|
||||
nsresult rv = ev->Init(aCx, aMessage, aData, aPrincipal);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = NS_DispatchToCurrentThread(ev);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool CheckPermission(const nsAString& aPermission) override
|
||||
|
@ -2014,29 +2017,32 @@ public:
|
|||
IPC::Principal(aPrincipal), aRetVal);
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
{
|
||||
mozilla::dom::ContentChild* cc =
|
||||
mozilla::dom::ContentChild::GetSingleton();
|
||||
if (!cc) {
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
ClonedMessageData data;
|
||||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||
return false;
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||
if (aCpows && !cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||
return false;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
if (!cc->SendAsyncMessage(PromiseFlatString(aMessage), data, cpows,
|
||||
IPC::Principal(aPrincipal))) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return cc->SendAsyncMessage(PromiseFlatString(aMessage), data, cpows,
|
||||
IPC::Principal(aPrincipal));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -2044,15 +2050,9 @@ class nsAsyncMessageToSameProcessParent : public nsSameProcessAsyncMessageBase,
|
|||
public SameProcessMessageQueue::Runnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToSameProcessParent(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal)
|
||||
{
|
||||
}
|
||||
|
||||
nsAsyncMessageToSameProcessParent(JSContext* aCx, JS::Handle<JSObject*> aCpows)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aCpows)
|
||||
{ }
|
||||
virtual nsresult HandleMessage() override
|
||||
{
|
||||
nsFrameMessageManager* ppm = nsFrameMessageManager::sSameProcessParentManager;
|
||||
|
@ -2096,7 +2096,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
|
@ -2104,9 +2104,14 @@ public:
|
|||
{
|
||||
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
|
||||
nsRefPtr<nsAsyncMessageToSameProcessParent> ev =
|
||||
new nsAsyncMessageToSameProcessParent(aCx, aMessage, aData, aCpows, aPrincipal);
|
||||
new nsAsyncMessageToSameProcessParent(aCx, aCpows);
|
||||
nsresult rv = ev->Init(aCx, aMessage, aData, aPrincipal);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
queue->Push(ev);
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -2202,23 +2207,28 @@ nsFrameMessageManager::MarkForCC()
|
|||
return true;
|
||||
}
|
||||
|
||||
nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: mRuntime(js::GetRuntime(aCx)),
|
||||
mMessage(aMessage),
|
||||
mCpows(aCx, aCpows),
|
||||
mPrincipal(aPrincipal)
|
||||
nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase(JSContext* aCx, JS::Handle<JSObject*> aCpows)
|
||||
: mRuntime(nullptr)
|
||||
, mCpows(aCx, aCpows)
|
||||
{ }
|
||||
|
||||
|
||||
nsresult
|
||||
nsSameProcessAsyncMessageBase::Init(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
if (!mData.Copy(aData)) {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncMessageOOM"),
|
||||
NS_ConvertUTF16toUTF8(aMessage));
|
||||
#endif
|
||||
NS_ABORT_OOM(aData.DataLength());
|
||||
Telemetry::Accumulate(Telemetry::IPC_SAME_PROCESS_MESSAGE_COPY_OOM_KB, aData.DataLength());
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mRuntime = js::GetRuntime(aCx);
|
||||
mMessage = aMessage;
|
||||
mPrincipal = aPrincipal;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2226,6 +2236,8 @@ nsSameProcessAsyncMessageBase::ReceiveMessage(nsISupports* aTarget,
|
|||
nsIFrameLoader* aTargetFrameLoader,
|
||||
nsFrameMessageManager* aManager)
|
||||
{
|
||||
// Make sure that we have called Init() and it has succeeded.
|
||||
MOZ_ASSERT(mRuntime);
|
||||
if (aManager) {
|
||||
SameProcessCpowHolder cpows(mRuntime, mCpows);
|
||||
|
||||
|
|
|
@ -73,13 +73,13 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual bool CheckPermission(const nsAString& aPermission)
|
||||
|
@ -317,28 +317,32 @@ private:
|
|||
|
||||
class MyAsyncMessage : public nsSameProcessAsyncMessageBase, public nsRunnable
|
||||
{
|
||||
// Initialize nsSameProcessAsyncMessageBase...
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
ReceiveMessage(..., ...);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
nsRefPtr<nsSameProcessAsyncMessageBase> ev = new MyAsyncMessage();
|
||||
nsresult rv = ev->Init(...);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_DispatchToMainThread(ev);
|
||||
}
|
||||
*/
|
||||
class nsSameProcessAsyncMessageBase
|
||||
{
|
||||
public:
|
||||
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
|
||||
|
||||
nsSameProcessAsyncMessageBase(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal);
|
||||
nsSameProcessAsyncMessageBase(JSContext* aCx, JS::Handle<JSObject*> aCpows);
|
||||
nsresult Init(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
void ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
|
||||
nsFrameMessageManager* aManager);
|
||||
|
||||
private:
|
||||
nsSameProcessAsyncMessageBase(const nsSameProcessAsyncMessageBase&);
|
||||
|
||||
|
|
|
@ -49,16 +49,10 @@ class nsAsyncMessageToParent : public nsSameProcessAsyncMessageBase,
|
|||
public SameProcessMessageQueue::Runnable
|
||||
{
|
||||
public:
|
||||
nsAsyncMessageToParent(JSContext* aCx,
|
||||
nsInProcessTabChildGlobal* aTabChild,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal),
|
||||
mTabChild(aTabChild)
|
||||
{
|
||||
}
|
||||
nsAsyncMessageToParent(JSContext* aCx, JS::Handle<JSObject*> aCpows, nsInProcessTabChildGlobal* aTabChild)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aCpows)
|
||||
, mTabChild(aTabChild)
|
||||
{ }
|
||||
|
||||
virtual nsresult HandleMessage() override
|
||||
{
|
||||
|
@ -69,7 +63,7 @@ public:
|
|||
nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
|
||||
};
|
||||
|
||||
bool
|
||||
nsresult
|
||||
nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
|
@ -78,9 +72,15 @@ nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
|
|||
{
|
||||
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
|
||||
nsRefPtr<nsAsyncMessageToParent> ev =
|
||||
new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows, aPrincipal);
|
||||
new nsAsyncMessageToParent(aCx, aCpows, this);
|
||||
|
||||
nsresult rv = ev->Init(aCx, aMessage, aData, aPrincipal);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
queue->Push(ev);
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
|
||||
|
|
|
@ -88,11 +88,11 @@ public:
|
|||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
|
||||
virtual nsresult PreHandleEvent(
|
||||
mozilla::EventChainPreVisitor& aVisitor) override;
|
||||
|
|
|
@ -189,11 +189,11 @@ nsScriptNameSpaceManager* GetNameSpaceManager();
|
|||
nsScriptNameSpaceManager* PeekNameSpaceManager();
|
||||
|
||||
// Runnable that's used to do async error reporting
|
||||
class AsyncErrorReporter : public nsRunnable
|
||||
class AsyncErrorReporter final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
// aWindow may be null if this error report is not associated with a window
|
||||
AsyncErrorReporter(JSRuntime* aRuntime, xpc::ErrorReport* aReport)
|
||||
explicit AsyncErrorReporter(xpc::ErrorReport* aReport)
|
||||
: mReport(aReport)
|
||||
{}
|
||||
|
||||
|
|
|
@ -1235,7 +1235,7 @@ bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
|
|||
mTarget->DrawSurface(snapshot, r, r);
|
||||
|
||||
// Restore the clips and transform
|
||||
for (uint32_t i = 0; i < CurrentState().clipsPushed.size(); i++) {
|
||||
for (uint32_t i = 0; i < CurrentState().clipsPushed.Length(); i++) {
|
||||
mTarget->PushClip(CurrentState().clipsPushed[i]);
|
||||
}
|
||||
|
||||
|
@ -1719,7 +1719,7 @@ CanvasRenderingContext2D::Restore()
|
|||
|
||||
TransformWillUpdate();
|
||||
|
||||
for (uint32_t i = 0; i < CurrentState().clipsPushed.size(); i++) {
|
||||
for (uint32_t i = 0; i < CurrentState().clipsPushed.Length(); i++) {
|
||||
mTarget->PopClip();
|
||||
}
|
||||
|
||||
|
@ -2864,7 +2864,7 @@ CanvasRenderingContext2D::Clip(const CanvasWindingRule& winding)
|
|||
}
|
||||
|
||||
mTarget->PushClip(mPath);
|
||||
CurrentState().clipsPushed.push_back(mPath);
|
||||
CurrentState().clipsPushed.AppendElement(mPath);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2879,7 +2879,7 @@ CanvasRenderingContext2D::Clip(const CanvasPath& path, const CanvasWindingRule&
|
|||
}
|
||||
|
||||
mTarget->PushClip(gfxpath);
|
||||
CurrentState().clipsPushed.push_back(gfxpath);
|
||||
CurrentState().clipsPushed.AppendElement(gfxpath);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -984,7 +984,7 @@ protected:
|
|||
return std::min(SIGMA_MAX, shadowBlur / 2.0f);
|
||||
}
|
||||
|
||||
std::vector<mozilla::RefPtr<mozilla::gfx::Path> > clipsPushed;
|
||||
nsTArray<mozilla::RefPtr<mozilla::gfx::Path> > clipsPushed;
|
||||
|
||||
nsRefPtr<gfxFontGroup> fontGroup;
|
||||
nsCOMPtr<nsIAtom> fontLanguage;
|
||||
|
|
|
@ -24,6 +24,7 @@ class WebGLVertexArrayObject;
|
|||
namespace dom {
|
||||
class OwningUnsignedLongOrUint32ArrayOrBoolean;
|
||||
class OwningWebGLBufferOrLongLong;
|
||||
class ArrayBufferViewOrSharedArrayBufferView;
|
||||
} // namespace dom
|
||||
|
||||
class WebGL2Context
|
||||
|
@ -51,8 +52,16 @@ public:
|
|||
|
||||
void CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
|
||||
GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
|
||||
|
||||
private:
|
||||
template<typename BufferT>
|
||||
void GetBufferSubDataT(GLenum target, GLintptr offset, const BufferT& data);
|
||||
|
||||
public:
|
||||
void GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData);
|
||||
void GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::SharedArrayBuffer& data);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -88,12 +97,12 @@ public:
|
|||
void TexImage3D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum format, GLenum type,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void TexSubImage3D(GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLenum type, const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
GLenum format, GLenum type, const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void TexSubImage3D(GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
|
@ -109,10 +118,10 @@ public:
|
|||
GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLsizei imageSize, const dom::ArrayBufferView& data);
|
||||
GLint border, GLsizei imageSize, const dom::ArrayBufferViewOrSharedArrayBufferView& data);
|
||||
void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLsizei imageSize, const dom::ArrayBufferView& data);
|
||||
GLenum format, GLsizei imageSize, const dom::ArrayBufferViewOrSharedArrayBufferView& data);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
|
|
@ -138,9 +138,12 @@ WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
|
|||
}
|
||||
}
|
||||
|
||||
// BufferT may be one of
|
||||
// const dom::ArrayBuffer&
|
||||
// const dom::SharedArrayBuffer&
|
||||
template<typename BufferT>
|
||||
void
|
||||
WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData)
|
||||
WebGL2Context::GetBufferSubDataT(GLenum target, GLintptr offset, const BufferT& data)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
@ -159,11 +162,6 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
|||
if (offset < 0)
|
||||
return ErrorInvalidValue("getBufferSubData: negative offset");
|
||||
|
||||
// If returnedData is null then an INVALID_VALUE error is
|
||||
// generated.
|
||||
if (maybeData.IsNull())
|
||||
return ErrorInvalidValue("getBufferSubData: returnedData is null");
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
WebGLBuffer* boundBuffer = bufferSlot.get();
|
||||
if (!boundBuffer)
|
||||
|
@ -171,7 +169,6 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
|||
|
||||
// If offset + returnedData.byteLength would extend beyond the end
|
||||
// of the buffer an INVALID_VALUE error is generated.
|
||||
const dom::ArrayBuffer& data = maybeData.Value();
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
CheckedInt<WebGLsizeiptr> neededByteLength = CheckedInt<WebGLsizeiptr>(offset) + data.Length();
|
||||
|
@ -225,4 +222,22 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
|||
}
|
||||
}
|
||||
|
||||
void WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData)
|
||||
{
|
||||
// If returnedData is null then an INVALID_VALUE error is
|
||||
// generated.
|
||||
if (maybeData.IsNull())
|
||||
return ErrorInvalidValue("getBufferSubData: returnedData is null");
|
||||
|
||||
const dom::ArrayBuffer& data = maybeData.Value();
|
||||
GetBufferSubDataT(target, offset, data);
|
||||
}
|
||||
|
||||
void WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
||||
const dom::SharedArrayBuffer& data)
|
||||
{
|
||||
GetBufferSubDataT(target, offset, data);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -39,7 +39,7 @@ void
|
|||
WebGL2Context::TexImage3D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv)
|
||||
{
|
||||
const char funcName[] = "texImage3D";
|
||||
|
@ -59,7 +59,7 @@ WebGL2Context::TexSubImage3D(GLenum rawTexImageTarget, GLint level,
|
|||
GLint xOffset, GLint yOffset, GLint zOffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv)
|
||||
{
|
||||
const char funcName[] = "texSubImage3D";
|
||||
|
@ -95,7 +95,7 @@ WebGL2Context::CopyTexSubImage3D(GLenum target, GLint level,
|
|||
void
|
||||
WebGL2Context::CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLsizei imageSize, const dom::ArrayBufferView& view)
|
||||
GLint border, GLsizei imageSize, const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
GenerateWarning("compressedTexImage3D: Not implemented.");
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ WebGL2Context::CompressedTexImage3D(GLenum target, GLint level, GLenum internalF
|
|||
void
|
||||
WebGL2Context::CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum unpackFormat, GLsizei imageSize, const dom::ArrayBufferView& view)
|
||||
GLenum unpackFormat, GLsizei imageSize, const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
GenerateWarning("compressedTexSubImage3D: Not implemented.");
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
|
||||
class nsIDocShell;
|
||||
|
||||
|
@ -100,6 +100,7 @@ class Element;
|
|||
class ImageData;
|
||||
class OwningHTMLCanvasElementOrOffscreenCanvas;
|
||||
struct WebGLContextAttributes;
|
||||
class ArrayBufferViewOrSharedArrayBufferView;
|
||||
template<typename> struct Nullable;
|
||||
} // namespace dom
|
||||
|
||||
|
@ -528,7 +529,7 @@ public:
|
|||
void PolygonOffset(GLfloat factor, GLfloat units);
|
||||
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void RenderbufferStorage(GLenum target, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height);
|
||||
|
@ -749,8 +750,8 @@ public:
|
|||
WebGLintptr offset, WebGLsizeiptr size);
|
||||
|
||||
private:
|
||||
void BufferDataUnchecked(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
|
||||
void BufferData(GLenum target, WebGLsizeiptr size, void* data, GLenum usage);
|
||||
template<typename BufferT>
|
||||
void BufferDataT(GLenum target, const BufferT& data, GLenum usage);
|
||||
|
||||
public:
|
||||
void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
|
||||
|
@ -758,16 +759,25 @@ public:
|
|||
GLenum usage);
|
||||
void BufferData(GLenum target, const dom::Nullable<dom::ArrayBuffer>& maybeData,
|
||||
GLenum usage);
|
||||
void BufferData(GLenum target, const dom::SharedArrayBuffer& data,
|
||||
GLenum usage);
|
||||
void BufferData(GLenum target, const dom::SharedArrayBufferView& data,
|
||||
GLenum usage);
|
||||
|
||||
private:
|
||||
void BufferSubDataUnchecked(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
|
||||
void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
|
||||
template<typename BufferT>
|
||||
void BufferSubDataT(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const BufferT& data);
|
||||
|
||||
public:
|
||||
void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::ArrayBufferView& data);
|
||||
void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData);
|
||||
void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::SharedArrayBuffer& data);
|
||||
void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::SharedArrayBufferView& data);
|
||||
already_AddRefed<WebGLBuffer> CreateBuffer();
|
||||
void DeleteBuffer(WebGLBuffer* buf);
|
||||
bool IsBuffer(WebGLBuffer* buf);
|
||||
|
@ -864,10 +874,10 @@ protected:
|
|||
public:
|
||||
void CompressedTexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
const dom::ArrayBufferView& view);
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
void CompressedTexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLsizei width, GLsizei height,
|
||||
GLenum unpackFormat, const dom::ArrayBufferView& view);
|
||||
GLenum unpackFormat, const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
void CopyTexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
|
@ -878,7 +888,7 @@ public:
|
|||
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv);
|
||||
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLenum unpackFormat, GLenum unpackType, dom::ImageData* imageData,
|
||||
|
@ -891,7 +901,7 @@ public:
|
|||
void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLsizei width, GLsizei height, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv);
|
||||
void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xOffset, GLint yOffset,
|
||||
GLenum unpackFormat, GLenum unpackType, dom::ImageData* imageData,
|
||||
|
@ -1634,6 +1644,11 @@ ValidateTexImageTarget(WebGLContext* webgl, GLenum rawTexImageTarget,
|
|||
// Returns x rounded to the next highest multiple of y.
|
||||
CheckedUint32 RoundedToNextMultipleOf(CheckedUint32 x, CheckedUint32 y);
|
||||
|
||||
void
|
||||
ComputeLengthAndData(const dom::ArrayBufferViewOrSharedArrayBufferView& view,
|
||||
void** const out_data, size_t* const out_length,
|
||||
js::Scalar::Type* const out_type);
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -182,25 +182,25 @@ WebGLContext::BufferData(GLenum target, WebGLsizeiptr size, GLenum usage)
|
|||
}
|
||||
}
|
||||
|
||||
// BufferT may be one of
|
||||
// const dom::ArrayBuffer&
|
||||
// const dom::SharedArrayBuffer&
|
||||
// const dom::ArrayBufferView&
|
||||
// const dom::SharedArrayBufferView&
|
||||
template<typename BufferT>
|
||||
void
|
||||
WebGLContext::BufferData(GLenum target,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData,
|
||||
GLenum usage)
|
||||
WebGLContext::BufferDataT(GLenum target,
|
||||
const BufferT& data,
|
||||
GLenum usage)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (maybeData.IsNull()) {
|
||||
// see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
|
||||
return ErrorInvalidValue("bufferData: null object passed");
|
||||
}
|
||||
|
||||
if (!ValidateBufferTarget(target, "bufferData"))
|
||||
return;
|
||||
|
||||
const WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
|
||||
const dom::ArrayBuffer& data = maybeData.Value();
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
// Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
|
||||
|
@ -231,20 +231,61 @@ WebGLContext::BufferData(GLenum target,
|
|||
return ErrorOutOfMemory("bufferData: out of memory");
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BufferData(GLenum target,
|
||||
const dom::SharedArrayBuffer& data,
|
||||
GLenum usage)
|
||||
{
|
||||
BufferDataT(target, data, usage);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BufferData(GLenum target,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData,
|
||||
GLenum usage)
|
||||
{
|
||||
if (maybeData.IsNull()) {
|
||||
// see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
|
||||
return ErrorInvalidValue("bufferData: null object passed");
|
||||
}
|
||||
BufferDataT(target, maybeData.Value(), usage);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& data,
|
||||
GLenum usage)
|
||||
{
|
||||
BufferDataT(target, data, usage);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BufferData(GLenum target, const dom::SharedArrayBufferView& data,
|
||||
GLenum usage)
|
||||
{
|
||||
BufferDataT(target, data, usage);
|
||||
}
|
||||
|
||||
// BufferT may be one of
|
||||
// const dom::ArrayBuffer&
|
||||
// const dom::SharedArrayBuffer&
|
||||
// const dom::ArrayBufferView&
|
||||
// const dom::SharedArrayBufferView&
|
||||
template<typename BufferT>
|
||||
void
|
||||
WebGLContext::BufferSubDataT(GLenum target,
|
||||
WebGLsizeiptr byteOffset,
|
||||
const BufferT& data)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateBufferTarget(target, "bufferData"))
|
||||
if (!ValidateBufferTarget(target, "bufferSubData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
|
||||
if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
|
||||
return;
|
||||
if (byteOffset < 0)
|
||||
return ErrorInvalidValue("bufferSubData: negative offset");
|
||||
|
||||
WebGLBuffer* boundBuffer = bufferSlot.get();
|
||||
if (!boundBuffer)
|
||||
|
@ -252,119 +293,60 @@ WebGLContext::BufferData(GLenum target, const dom::ArrayBufferView& data,
|
|||
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
// Careful: data.Length() could conceivably be any uint32_t, but GLsizeiptr
|
||||
// is like intptr_t.
|
||||
if (!CheckedInt<GLsizeiptr>(data.Length()).isValid())
|
||||
return ErrorOutOfMemory("bufferData: bad size");
|
||||
CheckedInt<WebGLsizeiptr> checked_neededByteLength =
|
||||
CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
|
||||
|
||||
InvalidateBufferFetching();
|
||||
MakeContextCurrent();
|
||||
|
||||
GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage);
|
||||
if (error) {
|
||||
GenerateWarning("bufferData generated error %s", ErrorName(error));
|
||||
if (!checked_neededByteLength.isValid()) {
|
||||
ErrorInvalidValue("bufferSubData: Integer overflow computing the needed"
|
||||
" byte length.");
|
||||
return;
|
||||
}
|
||||
|
||||
boundBuffer->SetByteLength(data.Length());
|
||||
if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length()))
|
||||
return ErrorOutOfMemory("bufferData: out of memory");
|
||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength()) {
|
||||
ErrorInvalidValue("bufferSubData: Not enough data. Operation requires"
|
||||
" %d bytes, but buffer only has %d bytes.",
|
||||
checked_neededByteLength.value(),
|
||||
boundBuffer->ByteLength());
|
||||
return;
|
||||
}
|
||||
|
||||
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(),
|
||||
data.Length());
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (maybeData.IsNull()) {
|
||||
// see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
|
||||
return;
|
||||
}
|
||||
BufferSubDataT(target, byteOffset, maybeData.Value());
|
||||
}
|
||||
|
||||
if (!ValidateBufferTarget(target, "bufferSubData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
|
||||
if (byteOffset < 0)
|
||||
return ErrorInvalidValue("bufferSubData: negative offset");
|
||||
|
||||
WebGLBuffer* boundBuffer = bufferSlot.get();
|
||||
if (!boundBuffer)
|
||||
return ErrorInvalidOperation("bufferData: no buffer bound!");
|
||||
|
||||
const dom::ArrayBuffer& data = maybeData.Value();
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
CheckedInt<WebGLsizeiptr> checked_neededByteLength =
|
||||
CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
|
||||
|
||||
if (!checked_neededByteLength.isValid()) {
|
||||
ErrorInvalidValue("bufferSubData: Integer overflow computing the needed"
|
||||
" byte length.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength()) {
|
||||
ErrorInvalidValue("bufferSubData: Not enough data. Operation requires"
|
||||
" %d bytes, but buffer only has %d bytes.",
|
||||
checked_neededByteLength.value(),
|
||||
boundBuffer->ByteLength());
|
||||
return;
|
||||
}
|
||||
|
||||
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(),
|
||||
data.Length());
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
|
||||
void
|
||||
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::SharedArrayBuffer& data)
|
||||
{
|
||||
BufferSubDataT(target, byteOffset, data);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::ArrayBufferView& data)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
BufferSubDataT(target, byteOffset, data);
|
||||
}
|
||||
|
||||
if (!ValidateBufferTarget(target, "bufferSubData"))
|
||||
return;
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>& bufferSlot = GetBufferSlotByTarget(target);
|
||||
|
||||
if (byteOffset < 0)
|
||||
return ErrorInvalidValue("bufferSubData: negative offset");
|
||||
|
||||
WebGLBuffer* boundBuffer = bufferSlot.get();
|
||||
if (!boundBuffer)
|
||||
return ErrorInvalidOperation("bufferSubData: no buffer bound!");
|
||||
|
||||
data.ComputeLengthAndData();
|
||||
|
||||
CheckedInt<WebGLsizeiptr> checked_neededByteLength =
|
||||
CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
|
||||
|
||||
if (!checked_neededByteLength.isValid()) {
|
||||
ErrorInvalidValue("bufferSubData: Integer overflow computing the needed"
|
||||
" byte length.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength()) {
|
||||
ErrorInvalidValue("bufferSubData: Not enough data. Operation requires"
|
||||
" %d bytes, but buffer only has %d bytes.",
|
||||
checked_neededByteLength.value(),
|
||||
boundBuffer->ByteLength());
|
||||
return;
|
||||
}
|
||||
|
||||
boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(),
|
||||
data.Length());
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
|
||||
void
|
||||
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::SharedArrayBufferView& data)
|
||||
{
|
||||
BufferSubDataT(target, byteOffset, data);
|
||||
}
|
||||
|
||||
already_AddRefed<WebGLBuffer>
|
||||
|
|
|
@ -1381,10 +1381,32 @@ IsFormatAndTypeUnpackable(GLenum format, GLenum type)
|
|||
}
|
||||
}
|
||||
|
||||
// This function is temporary, and will be removed once https://bugzilla.mozilla.org/show_bug.cgi?id=1176214 lands, which will
|
||||
// collapse the SharedArrayBufferView and ArrayBufferView into one.
|
||||
void
|
||||
ComputeLengthAndData(const dom::ArrayBufferViewOrSharedArrayBufferView& view,
|
||||
void** const out_data, size_t* const out_length,
|
||||
js::Scalar::Type* const out_type)
|
||||
{
|
||||
if (view.IsArrayBufferView()) {
|
||||
const dom::ArrayBufferView& pixbuf = view.GetAsArrayBufferView();
|
||||
pixbuf.ComputeLengthAndData();
|
||||
*out_length = pixbuf.Length();
|
||||
*out_data = pixbuf.Data();
|
||||
*out_type = JS_GetArrayBufferViewType(pixbuf.Obj());
|
||||
} else {
|
||||
const dom::SharedArrayBufferView& pixbuf = view.GetAsSharedArrayBufferView();
|
||||
pixbuf.ComputeLengthAndData();
|
||||
*out_length = pixbuf.Length();
|
||||
*out_data = pixbuf.Data();
|
||||
*out_type = JS_GetSharedArrayBufferViewType(pixbuf.Obj());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
|
||||
GLsizei height, GLenum format,
|
||||
GLenum type, const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
GLenum type, const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& pixels,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
|
@ -1460,8 +1482,13 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
|
|||
MOZ_CRASH("bad `type`");
|
||||
}
|
||||
|
||||
const dom::ArrayBufferView& pixbuf = pixels.Value();
|
||||
int dataType = pixbuf.Type();
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView &view = pixels.Value();
|
||||
// Compute length and data. Don't reenter after this point, lest the
|
||||
// precomputed go out of sync with the instant length/data.
|
||||
size_t dataByteLen;
|
||||
void* data;
|
||||
js::Scalar::Type dataType;
|
||||
ComputeLengthAndData(view, &data, &dataByteLen, &dataType);
|
||||
|
||||
// Check the pixels param type
|
||||
if (dataType != requiredDataType)
|
||||
|
@ -1479,15 +1506,9 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
|
|||
if (!checked_neededByteLength.isValid())
|
||||
return ErrorInvalidOperation("readPixels: integer overflow computing the needed buffer size");
|
||||
|
||||
// Compute length and data. Don't reenter after this point, lest the
|
||||
// precomputed go out of sync with the instant length/data.
|
||||
pixbuf.ComputeLengthAndData();
|
||||
|
||||
uint32_t dataByteLen = pixbuf.Length();
|
||||
if (checked_neededByteLength.value() > dataByteLen)
|
||||
return ErrorInvalidOperation("readPixels: buffer too small");
|
||||
|
||||
void* data = pixbuf.Data();
|
||||
if (!data) {
|
||||
ErrorOutOfMemory("readPixels: buffer storage is null. Did we run out of memory?");
|
||||
return rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
|
|
|
@ -298,7 +298,7 @@ void
|
|||
WebGLContext::TexImage2D(GLenum rawTexImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv)
|
||||
{
|
||||
TexImageTarget texImageTarget;
|
||||
|
@ -356,7 +356,7 @@ void
|
|||
WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLsizei width, GLsizei height,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult& out_rv)
|
||||
{
|
||||
TexImageTarget texImageTarget;
|
||||
|
@ -434,7 +434,7 @@ WebGLContext::CopyTexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xOf
|
|||
void
|
||||
WebGLContext::CompressedTexImage2D(GLenum rawTexImageTarget, GLint level,
|
||||
GLenum internalFormat, GLsizei width, GLsizei height,
|
||||
GLint border, const dom::ArrayBufferView& view)
|
||||
GLint border, const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
TexImageTarget texImageTarget;
|
||||
WebGLTexture* tex;
|
||||
|
@ -452,7 +452,7 @@ void
|
|||
WebGLContext::CompressedTexSubImage2D(GLenum rawTexImageTarget, GLint level,
|
||||
GLint xOffset, GLint yOffset, GLsizei width,
|
||||
GLsizei height, GLenum unpackFormat,
|
||||
const dom::ArrayBufferView& view)
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
TexImageTarget texImageTarget;
|
||||
WebGLTexture* tex;
|
||||
|
|
|
@ -24,6 +24,7 @@ class ErrorResult;
|
|||
namespace dom {
|
||||
class Element;
|
||||
class ImageData;
|
||||
class ArrayBufferViewOrSharedArrayBufferView;
|
||||
} // namespace dom
|
||||
|
||||
// Zero is not an integer power of two.
|
||||
|
@ -108,24 +109,24 @@ public:
|
|||
|
||||
void CompressedTexImage2D(TexImageTarget texImageTarget, GLint level,
|
||||
GLenum internalFormat, GLsizei width, GLsizei height,
|
||||
GLint border, const dom::ArrayBufferView& view);
|
||||
GLint border, const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
void CompressedTexImage3D(TexImageTarget texImageTarget, GLint level,
|
||||
GLenum internalFormat, GLsizei width, GLsizei height,
|
||||
GLsizei depth, GLint border, GLsizei imageSize,
|
||||
const dom::ArrayBufferView& view);
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
|
||||
void CompressedTexSubImage2D(TexImageTarget texImageTarget, GLint level,
|
||||
GLint xOffset, GLint yOffset, GLsizei width,
|
||||
GLsizei height, GLenum unpackFormat,
|
||||
const dom::ArrayBufferView& view);
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
void CompressedTexSubImage3D(TexImageTarget texImageTarget, GLint level,
|
||||
GLint xOffset, GLint yOffset, GLint zOffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum unpackFormat, GLsizei imageSize,
|
||||
const dom::ArrayBufferView& view);
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view);
|
||||
|
||||
|
||||
void CopyTexImage2D(TexImageTarget texImageTarget, GLint level, GLenum internalFormat,
|
||||
|
@ -144,7 +145,7 @@ public:
|
|||
void TexImage2D(TexImageTarget texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv);
|
||||
void TexImage2D(TexImageTarget texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLenum unpackFormat, GLenum unpackType, dom::ImageData* imageData,
|
||||
|
@ -156,7 +157,7 @@ public:
|
|||
void TexImage3D(TexImageTarget target, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth, GLint border,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv);
|
||||
|
||||
|
||||
|
@ -169,7 +170,7 @@ public:
|
|||
void TexSubImage2D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLsizei width, GLsizei height, GLenum unpackFormat,
|
||||
GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv);
|
||||
void TexSubImage2D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLenum unpackFormat, GLenum unpackType,
|
||||
|
@ -181,7 +182,7 @@ public:
|
|||
void TexSubImage3D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLint zOffset, GLsizei width, GLsizei height,
|
||||
GLsizei depth, GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv);
|
||||
void TexSubImage3D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLint zOffset, GLenum unpackFormat,
|
||||
|
|
|
@ -58,7 +58,7 @@ WebGLTexture::CompressedTexImage2D(TexImageTarget texImageTarget,
|
|||
GLint level,
|
||||
GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
const dom::ArrayBufferView& view)
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
const WebGLTexImageFunc func = WebGLTexImageFunc::CompTexImage;
|
||||
const WebGLTexDimensions dims = WebGLTexDimensions::Tex2D;
|
||||
|
@ -76,9 +76,11 @@ WebGLTexture::CompressedTexImage2D(TexImageTarget texImageTarget,
|
|||
return;
|
||||
}
|
||||
|
||||
view.ComputeLengthAndData();
|
||||
size_t byteLength;
|
||||
void* data;
|
||||
js::Scalar::Type dataType;
|
||||
ComputeLengthAndData(view, &data, &byteLength, &dataType);
|
||||
|
||||
uint32_t byteLength = view.Length();
|
||||
if (!mContext->ValidateCompTexImageDataSize(level, internalFormat, width, height, byteLength, func, dims)) {
|
||||
return;
|
||||
}
|
||||
|
@ -96,7 +98,7 @@ WebGLTexture::CompressedTexImage2D(TexImageTarget texImageTarget,
|
|||
|
||||
mContext->MakeContextCurrent();
|
||||
gl::GLContext* gl = mContext->gl;
|
||||
gl->fCompressedTexImage2D(texImageTarget.get(), level, internalFormat, width, height, border, byteLength, view.Data());
|
||||
gl->fCompressedTexImage2D(texImageTarget.get(), level, internalFormat, width, height, border, byteLength, data);
|
||||
|
||||
SetImageInfo(texImageTarget, level, width, height, 1, internalFormat,
|
||||
WebGLImageDataStatus::InitializedImageData);
|
||||
|
@ -106,7 +108,7 @@ void
|
|||
WebGLTexture::CompressedTexSubImage2D(TexImageTarget texImageTarget, GLint level, GLint xOffset,
|
||||
GLint yOffset, GLsizei width, GLsizei height,
|
||||
GLenum internalFormat,
|
||||
const dom::ArrayBufferView& view)
|
||||
const dom::ArrayBufferViewOrSharedArrayBufferView& view)
|
||||
{
|
||||
const WebGLTexImageFunc func = WebGLTexImageFunc::CompTexSubImage;
|
||||
const WebGLTexDimensions dims = WebGLTexDimensions::Tex2D;
|
||||
|
@ -131,9 +133,11 @@ WebGLTexture::CompressedTexSubImage2D(TexImageTarget texImageTarget, GLint level
|
|||
return mContext->ErrorInvalidOperation("compressedTexImage2D: internalFormat does not match the existing image");
|
||||
}
|
||||
|
||||
view.ComputeLengthAndData();
|
||||
size_t byteLength;
|
||||
void* data;
|
||||
js::Scalar::Type dataType;
|
||||
ComputeLengthAndData(view, &data, &byteLength, &dataType);
|
||||
|
||||
uint32_t byteLength = view.Length();
|
||||
if (!mContext->ValidateCompTexImageDataSize(level, internalFormat, width, height, byteLength, func, dims))
|
||||
return;
|
||||
|
||||
|
@ -161,7 +165,7 @@ WebGLTexture::CompressedTexSubImage2D(TexImageTarget texImageTarget, GLint level
|
|||
|
||||
mContext->MakeContextCurrent();
|
||||
gl::GLContext* gl = mContext->gl;
|
||||
gl->fCompressedTexSubImage2D(texImageTarget.get(), level, xOffset, yOffset, width, height, internalFormat, byteLength, view.Data());
|
||||
gl->fCompressedTexSubImage2D(texImageTarget.get(), level, xOffset, yOffset, width, height, internalFormat, byteLength, data);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -614,23 +618,19 @@ void
|
|||
WebGLTexture::TexImage2D(TexImageTarget texImageTarget, GLint level,
|
||||
GLenum internalFormat, GLsizei width,
|
||||
GLsizei height, GLint border, GLenum unpackFormat,
|
||||
GLenum unpackType, const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
GLenum unpackType, const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv)
|
||||
{
|
||||
void* data;
|
||||
uint32_t length;
|
||||
size_t length;
|
||||
js::Scalar::Type jsArrayType;
|
||||
if (maybeView.IsNull()) {
|
||||
data = nullptr;
|
||||
length = 0;
|
||||
jsArrayType = js::Scalar::MaxTypedArrayViewType;
|
||||
} else {
|
||||
const dom::ArrayBufferView& view = maybeView.Value();
|
||||
view.ComputeLengthAndData();
|
||||
|
||||
data = view.Data();
|
||||
length = view.Length();
|
||||
jsArrayType = view.Type();
|
||||
const auto& view = maybeView.Value();
|
||||
ComputeLengthAndData(view, &data, &length, &jsArrayType);
|
||||
}
|
||||
|
||||
const char funcName[] = "texImage2D";
|
||||
|
@ -850,14 +850,17 @@ WebGLTexture::TexSubImage2D(TexImageTarget texImageTarget, GLint level,
|
|||
GLint xOffset, GLint yOffset,
|
||||
GLsizei width, GLsizei height,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv)
|
||||
{
|
||||
if (maybeView.IsNull())
|
||||
return mContext->ErrorInvalidValue("texSubImage2D: pixels must not be null!");
|
||||
|
||||
const dom::ArrayBufferView& view = maybeView.Value();
|
||||
view.ComputeLengthAndData();
|
||||
const auto& view = maybeView.Value();
|
||||
size_t length;
|
||||
void* data;
|
||||
js::Scalar::Type jsArrayType;
|
||||
ComputeLengthAndData(view, &data, &length, &jsArrayType);
|
||||
|
||||
const char funcName[] = "texSubImage2D";
|
||||
if (!DoesTargetMatchDimensions(mContext, texImageTarget, 2, funcName))
|
||||
|
@ -865,7 +868,7 @@ WebGLTexture::TexSubImage2D(TexImageTarget texImageTarget, GLint level,
|
|||
|
||||
return TexSubImage2D_base(texImageTarget, level, xOffset, yOffset,
|
||||
width, height, 0, unpackFormat, unpackType,
|
||||
view.Data(), view.Length(), view.Type(),
|
||||
data, length, jsArrayType,
|
||||
WebGLTexelFormat::Auto, false);
|
||||
}
|
||||
|
||||
|
@ -1211,7 +1214,7 @@ void
|
|||
WebGLTexture::TexImage3D(TexImageTarget texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv)
|
||||
{
|
||||
void* data;
|
||||
|
@ -1222,12 +1225,8 @@ WebGLTexture::TexImage3D(TexImageTarget texImageTarget, GLint level, GLenum inte
|
|||
dataLength = 0;
|
||||
jsArrayType = js::Scalar::MaxTypedArrayViewType;
|
||||
} else {
|
||||
const dom::ArrayBufferView& view = maybeView.Value();
|
||||
view.ComputeLengthAndData();
|
||||
|
||||
data = view.Data();
|
||||
dataLength = view.Length();
|
||||
jsArrayType = view.Type();
|
||||
const auto& view = maybeView.Value();
|
||||
ComputeLengthAndData(view, &data, &dataLength, &jsArrayType);
|
||||
}
|
||||
|
||||
const char funcName[] = "texImage3D";
|
||||
|
@ -1318,14 +1317,17 @@ WebGLTexture::TexSubImage3D(TexImageTarget texImageTarget, GLint level,
|
|||
GLint xOffset, GLint yOffset, GLint zOffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum unpackFormat, GLenum unpackType,
|
||||
const dom::Nullable<dom::ArrayBufferView>& maybeView,
|
||||
const dom::Nullable<dom::ArrayBufferViewOrSharedArrayBufferView>& maybeView,
|
||||
ErrorResult* const out_rv)
|
||||
{
|
||||
if (maybeView.IsNull())
|
||||
return mContext->ErrorInvalidValue("texSubImage3D: pixels must not be null!");
|
||||
|
||||
const dom::ArrayBufferView& view = maybeView.Value();
|
||||
view.ComputeLengthAndData();
|
||||
const auto& view = maybeView.Value();
|
||||
void* data;
|
||||
size_t dataLength;
|
||||
js::Scalar::Type jsArrayType;
|
||||
ComputeLengthAndData(view, &data, &dataLength, &jsArrayType);
|
||||
|
||||
const char funcName[] = "texSubImage3D";
|
||||
if (!DoesTargetMatchDimensions(mContext, texImageTarget, 3, funcName))
|
||||
|
@ -1358,10 +1360,6 @@ WebGLTexture::TexSubImage3D(TexImageTarget texImageTarget, GLint level,
|
|||
return mContext->ErrorInvalidOperation("texSubImage3D: type differs from that of the existing image");
|
||||
}
|
||||
|
||||
js::Scalar::Type jsArrayType = view.Type();
|
||||
void* data = view.Data();
|
||||
size_t dataLength = view.Length();
|
||||
|
||||
if (!mContext->ValidateTexInputData(unpackType, jsArrayType, func, dims))
|
||||
return;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ skip-if = android_version == '10' || android_version == '18' #Android 2.3 and 4.
|
|||
[webgl-mochitest/test_noprog_draw.html]
|
||||
[webgl-mochitest/test_privileged_exts.html]
|
||||
[webgl-mochitest/test_renderer_strings.html]
|
||||
[webgl-mochitest/test_sab_with_webgl.html]
|
||||
[webgl-mochitest/test_texsubimage_float.html]
|
||||
[webgl-mochitest/test_uninit_data.html]
|
||||
[webgl-mochitest/test_webgl_available.html]
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<script src='/tests/SimpleTest/SimpleTest.js'></script>
|
||||
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id='c' width='200' height='200'></canvas>
|
||||
<canvas id='c2' width='200' height='200'></canvas>
|
||||
|
||||
<script>
|
||||
|
||||
var gl;
|
||||
|
||||
function RGBAToString(arr) {
|
||||
return '[' + arr[0].toPrecision(4) + ', ' +
|
||||
arr[1].toPrecision(4) + ', ' +
|
||||
arr[2].toPrecision(4) + ', ' +
|
||||
arr[3].toPrecision(4) + ']';
|
||||
}
|
||||
|
||||
function TestScreenColor(gl, r, g, b, a) {
|
||||
var arr = new SharedArrayBuffer(4);
|
||||
var view = new SharedUint8Array(arr);
|
||||
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, view);
|
||||
|
||||
var err = gl.getError();
|
||||
ok(err == 0, 'Should be no errors.');
|
||||
if (err)
|
||||
return;
|
||||
|
||||
var floatArr;
|
||||
floatArr = new Float32Array(4);
|
||||
floatArr[0] = view[0] / 255.0;
|
||||
floatArr[1] = view[1] / 255.0;
|
||||
floatArr[2] = view[2] / 255.0;
|
||||
floatArr[3] = view[3] / 255.0;
|
||||
|
||||
var testText = RGBAToString(floatArr);
|
||||
var refText = RGBAToString([r, g, b, a]);
|
||||
|
||||
var eps = 1.0 / 255.0;
|
||||
var isSame = (Math.abs(floatArr[0] - r) < eps &&
|
||||
Math.abs(floatArr[1] - g) < eps &&
|
||||
Math.abs(floatArr[2] - b) < eps &&
|
||||
Math.abs(floatArr[3] - a) < eps);
|
||||
|
||||
ok(isSame, 'Should be ' + refText + ', was ' + testText + ',');
|
||||
}
|
||||
|
||||
// Give ourselves a scope to return early from:
|
||||
(function() {
|
||||
var canvas = document.getElementById('c');
|
||||
var attribs = {
|
||||
antialias: false,
|
||||
depth: false,
|
||||
};
|
||||
gl = canvas.getContext('experimental-webgl', attribs);
|
||||
if (!gl) {
|
||||
todo(false, 'WebGL is unavailable.');
|
||||
return;
|
||||
}
|
||||
if (typeof SharedArrayBuffer === 'undefined') {
|
||||
todo(false, 'SharedArrayBuffer is unavailable.');
|
||||
return;
|
||||
}
|
||||
if (SharedFloat32Array === 'undefined') {
|
||||
todo(false, 'SharedFloat32Array is unavailable.');
|
||||
return;
|
||||
}
|
||||
|
||||
var vs = gl.createShader(gl.VERTEX_SHADER);
|
||||
gl.shaderSource(vs, "attribute vec2 aVertCoord; void main(void) { gl_Position = vec4(aVertCoord, 0.0, 1.0); }");
|
||||
gl.compileShader(vs);
|
||||
var fs = gl.createShader(gl.FRAGMENT_SHADER);
|
||||
gl.shaderSource(fs, "precision mediump float; uniform vec4 uFragColor; void main(void) { gl_FragColor = uFragColor; }");
|
||||
gl.compileShader(fs);
|
||||
var prog = gl.createProgram();
|
||||
gl.attachShader(prog, vs);
|
||||
gl.attachShader(prog, fs);
|
||||
gl.linkProgram(prog);
|
||||
|
||||
var success = gl.getProgramParameter(prog, gl.LINK_STATUS);
|
||||
if (!success) {
|
||||
console.log('Error linking program for \'' + vsId + '\' and \'' + fsId + '\'.');
|
||||
console.log('\nLink log: ' + gl.getProgramInfoLog(prog));
|
||||
console.log('\nVert shader log: ' + gl.getShaderInfoLog(vs));
|
||||
console.log('\nFrag shader log: ' + gl.getShaderInfoLog(fs));
|
||||
}
|
||||
ok(prog, 'Program should link.');
|
||||
if (!prog) {
|
||||
return;
|
||||
}
|
||||
|
||||
prog.aVertCoord = gl.getAttribLocation(prog, 'aVertCoord');
|
||||
prog.uFragColor = gl.getUniformLocation(prog, 'uFragColor');
|
||||
|
||||
gl.useProgram(prog);
|
||||
|
||||
// Test gl.bufferData(), gl.bufferSubData() and gl.readPixels() APIs with SAB as input.
|
||||
var arr = new SharedArrayBuffer(8*4);
|
||||
var view = new SharedFloat32Array(arr);
|
||||
view.set(new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]));
|
||||
var vb = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vb);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, arr, gl.STATIC_DRAW);
|
||||
ok(gl.getError() == 0, 'bufferData with SAB as input parameter works ok.');
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, arr);
|
||||
ok(gl.getError() == 0, 'bufferSubData with SAB as input parameter works ok.');
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
gl.clearColor(0, 0, 0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.uniform4f(prog.uFragColor, 0.2, 0.4, 0.6, 1.0);
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||||
var arr = new Uint8Array(4);
|
||||
TestScreenColor(gl, 0.2, 0.4, 0.6, 1.0);
|
||||
|
||||
// Test gl.texImage2D() and gl.texSubImage2D() APIs with SAB as input.
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
var width = 4;
|
||||
var height = 4;
|
||||
var numChannels = 4;
|
||||
var sab = new SharedArrayBuffer(width * height * numChannels);
|
||||
var data = new SharedUint8Array(sab);
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
data[i] = i;
|
||||
}
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
ok(gl.getError() == 0, 'texImage2D() with SAB as input parameter works ok.');
|
||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
ok(gl.getError() == 0, 'texSubImage2D() with SAB as input parameter works ok.');
|
||||
|
||||
ok(gl.getError() == 0, 'Should be no errors after test.');
|
||||
})();
|
||||
|
||||
// Test WebGL 2
|
||||
(function() {
|
||||
var canvas = document.getElementById('c2');
|
||||
var attribs = {
|
||||
antialias: false,
|
||||
depth: false,
|
||||
};
|
||||
gl = canvas.getContext('webgl2', attribs);
|
||||
if (!gl) {
|
||||
todo(false, 'WebGL 2 is unavailable.');
|
||||
return;
|
||||
}
|
||||
if (typeof SharedArrayBuffer === 'undefined') {
|
||||
todo(false, 'SharedArrayBuffer is unavailable.');
|
||||
return;
|
||||
}
|
||||
if (SharedFloat32Array === 'undefined') {
|
||||
todo(false, 'SharedFloat32Array is unavailable.');
|
||||
return;
|
||||
}
|
||||
|
||||
var arr = new SharedArrayBuffer(8*4);
|
||||
var view = new SharedFloat32Array(arr);
|
||||
view.set(new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]));
|
||||
var vb = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vb);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, arr, gl.STATIC_DRAW);
|
||||
|
||||
var arr2 = new SharedArrayBuffer(8*4);
|
||||
gl.getBufferSubData(gl.ARRAY_BUFFER, 0, arr2);
|
||||
var view2 = new SharedFloat32Array(arr2);
|
||||
var equal = true;
|
||||
for(var i = 0; i < 8; ++i) {
|
||||
if (view[i] != view2[i]) equal = false;
|
||||
}
|
||||
ok(equal, 'getBufferSubData with SAB as input parameter works ok.');
|
||||
|
||||
// Test gl.texImage3D() and gl.texSubImage3D() APIs with SAB as input.
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_3D, tex);
|
||||
var width = 4;
|
||||
var height = 4;
|
||||
var depth = 4;
|
||||
var numChannels = 4;
|
||||
var sab = new SharedArrayBuffer(width * height * depth* numChannels);
|
||||
var data = new SharedUint8Array(sab);
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
data[i] = i;
|
||||
}
|
||||
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, width, height, depth, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
ok(gl.getError() == 0, 'texImage3D() with SAB as input parameter works ok.');
|
||||
gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||
ok(gl.getError() == 0, 'texSubImage3D() with SAB as input parameter works ok.');
|
||||
|
||||
ok(gl.getError() == 0, 'Should be no errors after test.');
|
||||
})();
|
||||
|
||||
ok(true, 'TEST COMPLETE');
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -46,7 +46,7 @@ TextEncoder::Encode(JSContext* aCx,
|
|||
// Run the steps of the encoding algorithm.
|
||||
int32_t srcLen = aString.Length();
|
||||
int32_t maxLen;
|
||||
const char16_t* data = PromiseFlatString(aString).get();
|
||||
const char16_t* data = aString.BeginReading();
|
||||
nsresult rv = mEncoder->GetMaxLength(data, srcLen, &maxLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
|
|
|
@ -1277,7 +1277,7 @@ nsresult HTMLMediaElement::LoadResource()
|
|||
if (IsAutoplayEnabled()) {
|
||||
mJoinLatency.Start();
|
||||
}
|
||||
return FinishDecoderSetup(decoder, resource, nullptr, nullptr);
|
||||
return FinishDecoderSetup(decoder, resource, nullptr);
|
||||
}
|
||||
|
||||
// determine what security checks need to be performed in AsyncOpen2().
|
||||
|
@ -2777,7 +2777,7 @@ nsresult HTMLMediaElement::InitializeDecoderAsClone(MediaDecoder* aOriginal)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return FinishDecoderSetup(decoder, resource, nullptr, aOriginal);
|
||||
return FinishDecoderSetup(decoder, resource, nullptr);
|
||||
}
|
||||
|
||||
nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel,
|
||||
|
@ -2821,14 +2821,13 @@ nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel,
|
|||
}
|
||||
return NS_OK;
|
||||
} else {
|
||||
return FinishDecoderSetup(decoder, resource, aListener, nullptr);
|
||||
return FinishDecoderSetup(decoder, resource, aListener);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
|
||||
MediaResource* aStream,
|
||||
nsIStreamListener** aListener,
|
||||
MediaDecoder* aCloneDonor)
|
||||
nsIStreamListener** aListener)
|
||||
{
|
||||
ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_LOADING);
|
||||
|
||||
|
@ -2858,7 +2857,7 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
|
|||
// can affect how we feed data to MediaStreams
|
||||
NotifyDecoderPrincipalChanged();
|
||||
|
||||
nsresult rv = aDecoder->Load(aListener, aCloneDonor);
|
||||
nsresult rv = aDecoder->Load(aListener);
|
||||
if (NS_FAILED(rv)) {
|
||||
ShutdownDecoder();
|
||||
LOG(LogLevel::Debug, ("%p Failed to load for decoder %p", this, aDecoder));
|
||||
|
|
|
@ -651,7 +651,7 @@ public:
|
|||
* A public wrapper for FinishDecoderSetup()
|
||||
*/
|
||||
nsresult FinishDecoderSetup(MediaDecoder* aDecoder, MediaResource* aStream) {
|
||||
return FinishDecoderSetup(aDecoder, aStream, nullptr, nullptr);
|
||||
return FinishDecoderSetup(aDecoder, aStream, nullptr);
|
||||
}
|
||||
|
||||
// Returns true if the media element is being destroyed. Used in
|
||||
|
@ -811,8 +811,7 @@ protected:
|
|||
*/
|
||||
nsresult FinishDecoderSetup(MediaDecoder* aDecoder,
|
||||
MediaResource* aStream,
|
||||
nsIStreamListener **aListener,
|
||||
MediaDecoder* aCloneDonor);
|
||||
nsIStreamListener **aListener);
|
||||
|
||||
/**
|
||||
* Call this after setting up mLoadingSrc and mDecoder.
|
||||
|
|
|
@ -69,20 +69,14 @@ HTMLOptGroupElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
|||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
Element*
|
||||
HTMLOptGroupElement::GetSelect()
|
||||
{
|
||||
nsIContent* parent = this;
|
||||
while ((parent = parent->GetParent()) && parent->IsHTMLElement()) {
|
||||
if (parent->IsHTMLElement(nsGkAtoms::select)) {
|
||||
return parent;
|
||||
}
|
||||
if (!parent->IsHTMLElement(nsGkAtoms::optgroup)) {
|
||||
break;
|
||||
}
|
||||
Element* parent = nsINode::GetParentElement();
|
||||
if (!parent || !parent->IsHTMLElement(nsGkAtoms::select)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return parent;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -76,7 +76,7 @@ protected:
|
|||
* Get the select content element that contains this option
|
||||
* @param aSelectElement the select element [OUT]
|
||||
*/
|
||||
nsIContent* GetSelect();
|
||||
Element* GetSelect();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -226,7 +226,33 @@ HTMLSelectElement::InsertOptionsIntoList(nsIContent* aOptions,
|
|||
bool aNotify)
|
||||
{
|
||||
int32_t insertIndex = aListIndex;
|
||||
InsertOptionsIntoListRecurse(aOptions, &insertIndex, aDepth);
|
||||
|
||||
HTMLOptionElement* optElement = HTMLOptionElement::FromContent(aOptions);
|
||||
if (optElement) {
|
||||
mOptions->InsertOptionAt(optElement, insertIndex);
|
||||
insertIndex++;
|
||||
} else {
|
||||
// If it's at the top level, then we just found out there are non-options
|
||||
// at the top level, which will throw off the insert count
|
||||
if (aDepth == 0) {
|
||||
mNonOptionChildren++;
|
||||
}
|
||||
|
||||
// Deal with optgroups
|
||||
if (aOptions->IsHTMLElement(nsGkAtoms::optgroup)) {
|
||||
mOptGroupCount++;
|
||||
|
||||
for (nsIContent* child = aOptions->GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
optElement = HTMLOptionElement::FromContent(child);
|
||||
if (optElement) {
|
||||
mOptions->InsertOptionAt(optElement, insertIndex);
|
||||
insertIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with the selected list
|
||||
if (insertIndex - aListIndex) {
|
||||
|
@ -282,9 +308,40 @@ HTMLSelectElement::RemoveOptionsFromList(nsIContent* aOptions,
|
|||
bool aNotify)
|
||||
{
|
||||
int32_t numRemoved = 0;
|
||||
nsresult rv = RemoveOptionsFromListRecurse(aOptions, aListIndex, &numRemoved,
|
||||
aDepth);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
HTMLOptionElement* optElement = HTMLOptionElement::FromContent(aOptions);
|
||||
if (optElement) {
|
||||
if (mOptions->ItemAsOption(aListIndex) != optElement) {
|
||||
NS_ERROR("wrong option at index");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
mOptions->RemoveOptionAt(aListIndex);
|
||||
numRemoved++;
|
||||
} else {
|
||||
// Yay, one less artifact at the top level.
|
||||
if (aDepth == 0) {
|
||||
mNonOptionChildren--;
|
||||
}
|
||||
|
||||
// Recurse down deeper for options
|
||||
if (mOptGroupCount && aOptions->IsHTMLElement(nsGkAtoms::optgroup)) {
|
||||
mOptGroupCount--;
|
||||
|
||||
for (nsIContent* child = aOptions->GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
optElement = HTMLOptionElement::FromContent(child);
|
||||
if (optElement) {
|
||||
if (mOptions->ItemAsOption(aListIndex) != optElement) {
|
||||
NS_ERROR("wrong option at index");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
mOptions->RemoveOptionAt(aListIndex);
|
||||
numRemoved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numRemoved) {
|
||||
// Tell the widget we removed the options
|
||||
|
@ -324,91 +381,6 @@ HTMLSelectElement::RemoveOptionsFromList(nsIContent* aOptions,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the document is such that recursing over these options gets us
|
||||
// deeper than four levels, there is something terribly wrong with the
|
||||
// world.
|
||||
void
|
||||
HTMLSelectElement::InsertOptionsIntoListRecurse(nsIContent* aOptions,
|
||||
int32_t* aInsertIndex,
|
||||
int32_t aDepth)
|
||||
{
|
||||
// We *assume* here that someone's brain has not gone horribly
|
||||
// wrong by putting <option> inside of <option>. I'm sorry, I'm
|
||||
// just not going to look for an option inside of an option.
|
||||
// Sue me.
|
||||
|
||||
HTMLOptionElement* optElement = HTMLOptionElement::FromContent(aOptions);
|
||||
if (optElement) {
|
||||
mOptions->InsertOptionAt(optElement, *aInsertIndex);
|
||||
(*aInsertIndex)++;
|
||||
return;
|
||||
}
|
||||
|
||||
// If it's at the top level, then we just found out there are non-options
|
||||
// at the top level, which will throw off the insert count
|
||||
if (aDepth == 0) {
|
||||
mNonOptionChildren++;
|
||||
}
|
||||
|
||||
// Recurse down into optgroups
|
||||
if (aOptions->IsHTMLElement(nsGkAtoms::optgroup)) {
|
||||
mOptGroupCount++;
|
||||
|
||||
for (nsIContent* child = aOptions->GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
InsertOptionsIntoListRecurse(child, aInsertIndex, aDepth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the document is such that recursing over these options gets us deeper than
|
||||
// four levels, there is something terribly wrong with the world.
|
||||
nsresult
|
||||
HTMLSelectElement::RemoveOptionsFromListRecurse(nsIContent* aOptions,
|
||||
int32_t aRemoveIndex,
|
||||
int32_t* aNumRemoved,
|
||||
int32_t aDepth)
|
||||
{
|
||||
// We *assume* here that someone's brain has not gone horribly
|
||||
// wrong by putting <option> inside of <option>. I'm sorry, I'm
|
||||
// just not going to look for an option inside of an option.
|
||||
// Sue me.
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> optElement(do_QueryInterface(aOptions));
|
||||
if (optElement) {
|
||||
if (mOptions->ItemAsOption(aRemoveIndex) != optElement) {
|
||||
NS_ERROR("wrong option at index");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
mOptions->RemoveOptionAt(aRemoveIndex);
|
||||
(*aNumRemoved)++;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Yay, one less artifact at the top level.
|
||||
if (aDepth == 0) {
|
||||
mNonOptionChildren--;
|
||||
}
|
||||
|
||||
// Recurse down deeper for options
|
||||
if (mOptGroupCount && aOptions->IsHTMLElement(nsGkAtoms::optgroup)) {
|
||||
mOptGroupCount--;
|
||||
|
||||
for (nsIContent* child = aOptions->GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
nsresult rv = RemoveOptionsFromListRecurse(child,
|
||||
aRemoveIndex,
|
||||
aNumRemoved,
|
||||
aDepth + 1);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXXldb Doing the processing before the content nodes have been added
|
||||
// to the document (as the name of this function seems to require, and
|
||||
// as the callers do), is highly unusual. Passing around unparented
|
||||
|
@ -420,10 +392,10 @@ HTMLSelectElement::WillAddOptions(nsIContent* aOptions,
|
|||
int32_t aContentIndex,
|
||||
bool aNotify)
|
||||
{
|
||||
int32_t level = GetContentDepth(aParent);
|
||||
if (level == -1) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (this != aParent && this != aParent->GetParent()) {
|
||||
return NS_OK;
|
||||
}
|
||||
int32_t level = aParent == this ? 0 : 1;
|
||||
|
||||
// Get the index where the options will be inserted
|
||||
int32_t ind = -1;
|
||||
|
@ -462,11 +434,10 @@ HTMLSelectElement::WillRemoveOptions(nsIContent* aParent,
|
|||
int32_t aContentIndex,
|
||||
bool aNotify)
|
||||
{
|
||||
int32_t level = GetContentDepth(aParent);
|
||||
NS_ASSERTION(level >= 0, "getting notified by unexpected content");
|
||||
if (level == -1) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (this != aParent && this != aParent->GetParent()) {
|
||||
return NS_OK;
|
||||
}
|
||||
int32_t level = this == aParent ? 0 : 1;
|
||||
|
||||
// Get the index where the options will be removed
|
||||
nsIContent* currentKid = aParent->GetChildAt(aContentIndex);
|
||||
|
@ -489,24 +460,6 @@ HTMLSelectElement::WillRemoveOptions(nsIContent* aParent,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t
|
||||
HTMLSelectElement::GetContentDepth(nsIContent* aContent)
|
||||
{
|
||||
nsIContent* content = aContent;
|
||||
|
||||
int32_t retval = 0;
|
||||
while (content != this) {
|
||||
retval++;
|
||||
content = content->GetParent();
|
||||
if (!content) {
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int32_t
|
||||
HTMLSelectElement::GetOptionIndexAt(nsIContent* aOptions)
|
||||
{
|
||||
|
@ -528,9 +481,7 @@ HTMLSelectElement::GetOptionIndexAfter(nsIContent* aOptions)
|
|||
// in the parent.
|
||||
// - If it's not there, search for the first option after the parent.
|
||||
if (aOptions == this) {
|
||||
uint32_t len;
|
||||
GetLength(&len);
|
||||
return len;
|
||||
return Length();
|
||||
}
|
||||
|
||||
int32_t retval = -1;
|
||||
|
@ -558,8 +509,6 @@ HTMLSelectElement::GetFirstOptionIndex(nsIContent* aOptions)
|
|||
HTMLOptionElement* optElement = HTMLOptionElement::FromContent(aOptions);
|
||||
if (optElement) {
|
||||
GetOptionIndex(optElement, 0, true, &listIndex);
|
||||
// If you nested stuff under the option, you're just plain
|
||||
// screwed. *I'm* not going to aid and abet your evil deed.
|
||||
return listIndex;
|
||||
}
|
||||
|
||||
|
@ -1785,16 +1734,23 @@ HTMLSelectElement::DispatchContentReset()
|
|||
}
|
||||
|
||||
static void
|
||||
AddOptionsRecurse(nsIContent* aRoot, HTMLOptionsCollection* aArray)
|
||||
AddOptions(nsIContent* aRoot, HTMLOptionsCollection* aArray)
|
||||
{
|
||||
for (nsIContent* cur = aRoot->GetFirstChild();
|
||||
cur;
|
||||
cur = cur->GetNextSibling()) {
|
||||
HTMLOptionElement* opt = HTMLOptionElement::FromContent(cur);
|
||||
for (nsIContent* child = aRoot->GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
HTMLOptionElement* opt = HTMLOptionElement::FromContent(child);
|
||||
if (opt) {
|
||||
aArray->AppendOption(opt);
|
||||
} else if (cur->IsHTMLElement(nsGkAtoms::optgroup)) {
|
||||
AddOptionsRecurse(cur, aArray);
|
||||
} else if (child->IsHTMLElement(nsGkAtoms::optgroup)) {
|
||||
for (nsIContent* grandchild = child->GetFirstChild();
|
||||
grandchild;
|
||||
grandchild = grandchild->GetNextSibling()) {
|
||||
opt = HTMLOptionElement::FromContent(grandchild);
|
||||
if (opt) {
|
||||
aArray->AppendOption(opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1803,7 +1759,7 @@ void
|
|||
HTMLSelectElement::RebuildOptionsArray(bool aNotify)
|
||||
{
|
||||
mOptions->Clear();
|
||||
AddOptionsRecurse(this, mOptions);
|
||||
AddOptions(this, mOptions);
|
||||
FindSelectedIndex(0, aNotify);
|
||||
}
|
||||
|
||||
|
@ -1863,28 +1819,29 @@ HTMLSelectElement::GetValidationMessage(nsAString& aValidationMessage,
|
|||
|
||||
#ifdef DEBUG
|
||||
|
||||
static void
|
||||
VerifyOptionsRecurse(nsIContent* aRoot, int32_t& aIndex,
|
||||
HTMLOptionsCollection* aArray)
|
||||
{
|
||||
for (nsIContent* cur = aRoot->GetFirstChild();
|
||||
cur;
|
||||
cur = cur->GetNextSibling()) {
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> opt = do_QueryInterface(cur);
|
||||
if (opt) {
|
||||
NS_ASSERTION(opt == aArray->ItemAsOption(aIndex++),
|
||||
"Options collection broken");
|
||||
} else if (cur->IsHTMLElement(nsGkAtoms::optgroup)) {
|
||||
VerifyOptionsRecurse(cur, aIndex, aArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HTMLSelectElement::VerifyOptionsArray()
|
||||
{
|
||||
int32_t aIndex = 0;
|
||||
VerifyOptionsRecurse(this, aIndex, mOptions);
|
||||
int32_t index = 0;
|
||||
for (nsIContent* child = nsINode::GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
HTMLOptionElement* opt = HTMLOptionElement::FromContent(child);
|
||||
if (opt) {
|
||||
NS_ASSERTION(opt == mOptions->ItemAsOption(index++),
|
||||
"Options collection broken");
|
||||
} else if (child->IsHTMLElement(nsGkAtoms::optgroup)) {
|
||||
for (nsIContent* grandchild = child->GetFirstChild();
|
||||
grandchild;
|
||||
grandchild = grandchild->GetNextSibling()) {
|
||||
opt = HTMLOptionElement::FromContent(grandchild);
|
||||
if (opt) {
|
||||
NS_ASSERTION(opt == mOptions->ItemAsOption(index++),
|
||||
"Options collection broken");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -502,37 +502,11 @@ protected:
|
|||
int32_t aListIndex,
|
||||
int32_t aDepth,
|
||||
bool aNotify);
|
||||
/**
|
||||
* Insert option(s) into the options[] array (called by InsertOptionsIntoList)
|
||||
* @param aOptions the option or optgroup being added
|
||||
* @param aInsertIndex the index to start adding options into the list at
|
||||
* @param aDepth the depth of aOptions (1=direct child of select ...)
|
||||
*/
|
||||
void InsertOptionsIntoListRecurse(nsIContent* aOptions,
|
||||
int32_t* aInsertIndex,
|
||||
int32_t aDepth);
|
||||
/**
|
||||
* Remove option(s) from the options[] array (called by RemoveOptionsFromList)
|
||||
* @param aOptions the option or optgroup being added
|
||||
* @param aListIndex the index to start removing options from the list at
|
||||
* @param aNumRemoved the number removed so far [OUT]
|
||||
* @param aDepth the depth of aOptions (1=direct child of select ...)
|
||||
*/
|
||||
nsresult RemoveOptionsFromListRecurse(nsIContent* aOptions,
|
||||
int32_t aRemoveIndex,
|
||||
int32_t* aNumRemoved,
|
||||
int32_t aDepth);
|
||||
|
||||
// nsIConstraintValidation
|
||||
void UpdateBarredFromConstraintValidation();
|
||||
bool IsValueMissing();
|
||||
|
||||
/**
|
||||
* Find out how deep this content is from the select (1=direct child)
|
||||
* @param aContent the content to check
|
||||
* @return the depth
|
||||
*/
|
||||
int32_t GetContentDepth(nsIContent* aContent);
|
||||
/**
|
||||
* Get the index of the first option at, under or following the content in
|
||||
* the select, or length of options[] if none are found
|
||||
|
|
|
@ -19,7 +19,7 @@ function basicTest(aIcc) {
|
|||
// The emulator's hard coded mcc and mnc codes.
|
||||
// See it here {B2G_HOME}/external/qemu/telephony/android_modem.c#L2465.
|
||||
is(iccInfo.mcc, 310);
|
||||
is(iccInfo.mnc, 260);
|
||||
is(iccInfo.mnc, 410);
|
||||
// Phone number is hardcoded in MSISDN
|
||||
// See {B2G_HOME}/external/qemu/telephony/sim_card.c, in asimcard_io().
|
||||
is(iccInfo.msisdn, "15555215554");
|
||||
|
|
|
@ -6,16 +6,16 @@ MARIONETTE_HEAD_JS = "head.js";
|
|||
|
||||
const TEST_DATA = [
|
||||
// mvno type, mvno data, request success, expected result
|
||||
// Emulator's hard coded IMSI: 310260000000000
|
||||
["imsi", "3102600", true, true ],
|
||||
// Emulator's hard coded IMSI: 310410000000000
|
||||
["imsi", "3104100", true, true ],
|
||||
// x and X means skip the comparison.
|
||||
["imsi", "31026xx0", true, true ],
|
||||
["imsi", "310260x0x", true, true ],
|
||||
["imsi", "310260X00", true, true ],
|
||||
["imsi", "310260XX1", true, false ],
|
||||
["imsi", "31026012", true, false ],
|
||||
["imsi", "310260000000000", true, true ],
|
||||
["imsi", "310260000000000123", true, false ],
|
||||
["imsi", "31041xx0", true, true ],
|
||||
["imsi", "310410x0x", true, true ],
|
||||
["imsi", "310410X00", true, true ],
|
||||
["imsi", "310410XX1", true, false ],
|
||||
["imsi", "31041012", true, false ],
|
||||
["imsi", "310410000000000", true, true ],
|
||||
["imsi", "310410000000000123", true, false ],
|
||||
["imsi", "", false, "InvalidParameter"],
|
||||
// Emulator's hard coded SPN: Android
|
||||
["spn", "Android", true, true ],
|
||||
|
|
|
@ -4567,7 +4567,7 @@ ContentParent::DoLoadMessageManagerScript(const nsAString& aURL,
|
|||
return SendLoadProcessScript(nsString(aURL));
|
||||
}
|
||||
|
||||
bool
|
||||
nsresult
|
||||
ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aHelper,
|
||||
|
@ -4576,18 +4576,21 @@ ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
|||
{
|
||||
ClonedMessageData data;
|
||||
if (!BuildClonedMessageDataForParent(this, aHelper, data)) {
|
||||
return false;
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
InfallibleTArray<CpowEntry> cpows;
|
||||
jsipc::CPOWManager* mgr = GetCPOWManager();
|
||||
if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
|
||||
return false;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
if (IsReadyNuwaProcess()) {
|
||||
// Nuwa won't receive frame messages after it is frozen.
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
return SendAsyncMessage(nsString(aMessage), data, cpows, Principal(aPrincipal));
|
||||
if (!SendAsyncMessage(nsString(aMessage), data, cpows, Principal(aPrincipal))) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -206,11 +206,11 @@ public:
|
|||
*/
|
||||
virtual bool DoLoadMessageManagerScript(const nsAString& aURL,
|
||||
bool aRunInGlobalScope) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual bool CheckPermission(const nsAString& aPermission) override;
|
||||
virtual bool CheckManifestURL(const nsAString& aManifestURL) override;
|
||||
virtual bool CheckAppHasPermission(const nsAString& aPermission) override;
|
||||
|
|
|
@ -2921,7 +2921,7 @@ TabChild::DoSendBlockingMessage(JSContext* aCx,
|
|||
Principal(aPrincipal), aRetVal);
|
||||
}
|
||||
|
||||
bool
|
||||
nsresult
|
||||
TabChild::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
|
@ -2930,14 +2930,17 @@ TabChild::DoSendAsyncMessage(JSContext* aCx,
|
|||
{
|
||||
ClonedMessageData data;
|
||||
if (!BuildClonedMessageDataForChild(Manager(), aData, data)) {
|
||||
return false;
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
InfallibleTArray<CpowEntry> cpows;
|
||||
if (aCpows && !Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||
return false;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return SendAsyncMessage(PromiseFlatString(aMessage), data, cpows,
|
||||
Principal(aPrincipal));
|
||||
if (!SendAsyncMessage(PromiseFlatString(aMessage), data, cpows,
|
||||
Principal(aPrincipal))) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TabChild*
|
||||
|
|
|
@ -280,11 +280,11 @@ public:
|
|||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual bool DoUpdateZoomConstraints(const uint32_t& aPresShellId,
|
||||
const ViewID& aViewId,
|
||||
const Maybe<ZoomConstraints>& aConstraints) override;
|
||||
|
|
|
@ -1454,6 +1454,9 @@ TabParent::GetTopLevelDocAccessible() const
|
|||
return doc;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(docCount == 0, "If there isn't a top level accessible doc "
|
||||
"there shouldn't be an accessible doc at all!");
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -509,8 +509,7 @@ MediaDecoder::OpenResource(nsIStreamListener** aStreamListener)
|
|||
}
|
||||
|
||||
nsresult
|
||||
MediaDecoder::Load(nsIStreamListener** aStreamListener,
|
||||
MediaDecoder* aCloneDonor)
|
||||
MediaDecoder::Load(nsIStreamListener** aStreamListener)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mResource, "Can't load without a MediaResource");
|
||||
|
@ -521,18 +520,16 @@ MediaDecoder::Load(nsIStreamListener** aStreamListener,
|
|||
SetStateMachine(CreateStateMachine());
|
||||
NS_ENSURE_TRUE(GetStateMachine(), NS_ERROR_FAILURE);
|
||||
|
||||
return InitializeStateMachine(aCloneDonor);
|
||||
return InitializeStateMachine();
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaDecoder::InitializeStateMachine(MediaDecoder* aCloneDonor)
|
||||
MediaDecoder::InitializeStateMachine()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ASSERTION(mDecoderStateMachine, "Cannot initialize null state machine!");
|
||||
|
||||
MediaDecoder* cloneDonor = static_cast<MediaDecoder*>(aCloneDonor);
|
||||
nsresult rv = mDecoderStateMachine->Init(
|
||||
cloneDonor ? cloneDonor->mDecoderStateMachine.get() : nullptr);
|
||||
nsresult rv = mDecoderStateMachine->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If some parameters got set before the state machine got created,
|
||||
|
|
|
@ -323,8 +323,7 @@ public:
|
|||
// Start downloading the media. Decode the downloaded data up to the
|
||||
// point of the first frame of data.
|
||||
// This is called at most once per decoder, after Init().
|
||||
virtual nsresult Load(nsIStreamListener** aListener,
|
||||
MediaDecoder* aCloneDonor);
|
||||
virtual nsresult Load(nsIStreamListener** aListener);
|
||||
|
||||
// Called in |Load| to open mResource.
|
||||
nsresult OpenResource(nsIStreamListener** aStreamListener);
|
||||
|
@ -363,7 +362,7 @@ public:
|
|||
virtual nsresult Seek(double aTime, SeekTarget::Type aSeekType);
|
||||
|
||||
// Initialize state machine and schedule it.
|
||||
nsresult InitializeStateMachine(MediaDecoder* aCloneDonor);
|
||||
nsresult InitializeStateMachine();
|
||||
|
||||
// Start playback of a video. 'Load' must have previously been
|
||||
// called.
|
||||
|
|
|
@ -96,7 +96,28 @@ public:
|
|||
|
||||
// Release media resources they should be released in dormant state
|
||||
// The reader can be made usable again by calling ReadMetadata().
|
||||
virtual void ReleaseMediaResources() {};
|
||||
void ReleaseMediaResources()
|
||||
{
|
||||
if (OnTaskQueue()) {
|
||||
ReleaseMediaResourcesInternal();
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||
this, &MediaDecoderReader::ReleaseMediaResourcesInternal);
|
||||
OwnerThread()->Dispatch(r.forget());
|
||||
}
|
||||
|
||||
void DisableHardwareAcceleration()
|
||||
{
|
||||
if (OnTaskQueue()) {
|
||||
DisableHardwareAccelerationInternal();
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
|
||||
this, &MediaDecoderReader::DisableHardwareAccelerationInternal);
|
||||
OwnerThread()->Dispatch(r.forget());
|
||||
}
|
||||
|
||||
// Breaks reference-counted cycles. Called during shutdown.
|
||||
// WARNING: If you override this, you must call the base implementation
|
||||
// in your override.
|
||||
|
@ -243,6 +264,10 @@ public:
|
|||
virtual size_t SizeOfVideoQueueInFrames();
|
||||
virtual size_t SizeOfAudioQueueInFrames();
|
||||
|
||||
private:
|
||||
virtual void ReleaseMediaResourcesInternal() {}
|
||||
virtual void DisableHardwareAccelerationInternal() {}
|
||||
|
||||
protected:
|
||||
friend class TrackBuffer;
|
||||
virtual void NotifyDataArrivedInternal(uint32_t aLength, int64_t aOffset) { }
|
||||
|
@ -322,8 +347,6 @@ public:
|
|||
// decoding.
|
||||
virtual bool VideoIsHardwareAccelerated() const { return false; }
|
||||
|
||||
virtual void DisableHardwareAcceleration() {}
|
||||
|
||||
TimedMetadataEventSource& TimedMetadataEvent() {
|
||||
return mTimedMetadataEvent;
|
||||
}
|
||||
|
|
|
@ -1030,7 +1030,7 @@ bool MediaDecoderStateMachine::IsPlaying() const
|
|||
return mMediaSink->IsPlaying();
|
||||
}
|
||||
|
||||
nsresult MediaDecoderStateMachine::Init(MediaDecoderStateMachine* aCloneDonor)
|
||||
nsresult MediaDecoderStateMachine::Init()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsresult rv = mReader->Init();
|
||||
|
@ -1269,8 +1269,7 @@ MediaDecoderStateMachine::SetDormant(bool aDormant)
|
|||
// that run after ResetDecode are supposed to run with a clean slate. We rely
|
||||
// on that in other places (i.e. seeking), so it seems reasonable to rely on
|
||||
// it here as well.
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(mReader, &MediaDecoderReader::ReleaseMediaResources);
|
||||
DecodeTaskQueue()->Dispatch(r.forget());
|
||||
mReader->ReleaseMediaResources();
|
||||
} else if ((aDormant != true) && (mState == DECODER_STATE_DORMANT)) {
|
||||
ScheduleStateMachine();
|
||||
mDecodingFirstFrame = true;
|
||||
|
@ -2464,9 +2463,7 @@ MediaDecoderStateMachine::CheckFrameValidity(VideoData* aData)
|
|||
if (mReader->VideoIsHardwareAccelerated() &&
|
||||
frameStats.GetPresentedFrames() > 60 &&
|
||||
mCorruptFrames.mean() >= 2 /* 20% */) {
|
||||
nsCOMPtr<nsIRunnable> task =
|
||||
NS_NewRunnableMethod(mReader, &MediaDecoderReader::DisableHardwareAcceleration);
|
||||
DecodeTaskQueue()->Dispatch(task.forget());
|
||||
mReader->DisableHardwareAcceleration();
|
||||
mCorruptFrames.clear();
|
||||
gfxCriticalNote << "Too many dropped/corrupted frames, disabling DXVA";
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ public:
|
|||
MediaDecoderReader* aReader,
|
||||
bool aRealTime = false);
|
||||
|
||||
nsresult Init(MediaDecoderStateMachine* aCloneDonor);
|
||||
nsresult Init();
|
||||
|
||||
// Enumeration for the valid decoding states
|
||||
enum State {
|
||||
|
|
|
@ -534,7 +534,7 @@ MediaFormatReader::GetDecoderData(TrackType aTrack)
|
|||
}
|
||||
|
||||
void
|
||||
MediaFormatReader::DisableHardwareAcceleration()
|
||||
MediaFormatReader::DisableHardwareAccelerationInternal()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
if (HasVideo() && !mHardwareAccelerationDisabled) {
|
||||
|
@ -1569,8 +1569,9 @@ MediaFormatReader::GetBuffered()
|
|||
return intervals.Shift(media::TimeUnit::FromMicroseconds(-startTime));
|
||||
}
|
||||
|
||||
void MediaFormatReader::ReleaseMediaResources()
|
||||
void MediaFormatReader::ReleaseMediaResourcesInternal()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
// Before freeing a video codec, all video buffers needed to be released
|
||||
// even from graphics pipeline.
|
||||
VideoFrameContainer* container =
|
||||
|
|
|
@ -70,9 +70,6 @@ public:
|
|||
|
||||
virtual bool ForceZeroStartTime() const override;
|
||||
|
||||
// For Media Resource Management
|
||||
void ReleaseMediaResources() override;
|
||||
|
||||
nsresult ResetDecode() override;
|
||||
|
||||
nsRefPtr<ShutdownPromise> Shutdown() override;
|
||||
|
@ -81,8 +78,6 @@ public:
|
|||
|
||||
bool VideoIsHardwareAccelerated() const override;
|
||||
|
||||
void DisableHardwareAcceleration() override;
|
||||
|
||||
bool IsWaitForDataSupported() override { return true; }
|
||||
nsRefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType) override;
|
||||
|
||||
|
@ -436,6 +431,11 @@ private:
|
|||
#if defined(READER_DORMANT_HEURISTIC)
|
||||
const bool mDormantEnabled;
|
||||
#endif
|
||||
|
||||
private:
|
||||
// For Media Resource Management
|
||||
void ReleaseMediaResourcesInternal() override;
|
||||
void DisableHardwareAccelerationInternal() override;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -315,7 +315,7 @@ MediaKeySession::Close(ErrorResult& aRv)
|
|||
return promise.forget();
|
||||
}
|
||||
PromiseId pid = mKeys->StorePromise(promise);
|
||||
mKeys->GetCDMProxy()->CloseSession(mSessionId, mKeys->StorePromise(promise));
|
||||
mKeys->GetCDMProxy()->CloseSession(mSessionId, pid);
|
||||
|
||||
EME_LOG("MediaKeySession[%p,'%s'] Close() sent to CDM, promiseId=%d",
|
||||
this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid);
|
||||
|
|
|
@ -180,6 +180,13 @@ MediaKeys::StorePromise(DetailedPromise* aPromise)
|
|||
// promises are rejected in Shutdown().
|
||||
AddRef();
|
||||
|
||||
#ifdef DEBUG
|
||||
// We should not have already stored this promise!
|
||||
for (auto iter = mPromises.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
MOZ_ASSERT(iter.Data() != aPromise);
|
||||
}
|
||||
#endif
|
||||
|
||||
mPromises.Put(id, aPromise);
|
||||
return id;
|
||||
}
|
||||
|
@ -274,6 +281,7 @@ MediaKeys::ResolvePromise(PromiseId aId)
|
|||
} else {
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
}
|
||||
MOZ_ASSERT(!mPromises.Contains(aId));
|
||||
}
|
||||
|
||||
already_AddRefed<DetailedPromise>
|
||||
|
|
|
@ -599,21 +599,10 @@ GMPChild::GetGMPStorage()
|
|||
return mStorage;
|
||||
}
|
||||
|
||||
static MOZ_NEVER_INLINE void
|
||||
CrashForApiTimeout()
|
||||
{
|
||||
// Never inline so that crash reports are distinctive.
|
||||
MOZ_CRASH("Bug 1209385; GMP API actor failed to respond.");
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::RecvCrashPluginNow(const GMPCrashReason& aReason)
|
||||
GMPChild::RecvCrashPluginNow()
|
||||
{
|
||||
if (aReason == kGmpApiTimeout) {
|
||||
CrashForApiTimeout();
|
||||
} else {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
MOZ_CRASH();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ private:
|
|||
ProcessId aOtherPid) override;
|
||||
void GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild);
|
||||
|
||||
virtual bool RecvCrashPluginNow(const GMPCrashReason& aReason) override;
|
||||
virtual bool RecvCrashPluginNow() override;
|
||||
virtual bool RecvBeginAsyncShutdown() override;
|
||||
virtual bool RecvCloseActive() override;
|
||||
|
||||
|
|
|
@ -118,18 +118,6 @@ GMPContentParent::DecryptorDestroyed(GMPDecryptorParent* aSession)
|
|||
CloseIfUnused();
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::CrashPluginNow(GMPCrashReason aReason)
|
||||
{
|
||||
if (mParent) {
|
||||
mParent->Crash(aReason);
|
||||
} else {
|
||||
nsRefPtr<GeckoMediaPluginServiceChild> gmp(
|
||||
GeckoMediaPluginServiceChild::GetSingleton());
|
||||
gmp->CrashPluginNow(mPluginId, aReason);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GMPContentParent::CloseIfUnused()
|
||||
{
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "mozilla/gmp/PGMPContentParent.h"
|
||||
#include "GMPSharedMemManager.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "GMPUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
@ -62,8 +61,6 @@ public:
|
|||
return mPluginId;
|
||||
}
|
||||
|
||||
void CrashPluginNow(GMPCrashReason aReason);
|
||||
|
||||
private:
|
||||
~GMPContentParent();
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#include "gmp-audio-codec.h"
|
||||
#include "gmp-decryption.h"
|
||||
|
||||
#include "GMPUtils.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template <>
|
||||
|
@ -249,13 +247,6 @@ struct ParamTraits<GMPVideoCodec>
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::GMPCrashReason>
|
||||
: public ContiguousEnumSerializer<mozilla::GMPCrashReason,
|
||||
mozilla::kPrefChange,
|
||||
mozilla::kInvalid>
|
||||
{};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // GMPMessageUtils_h_
|
||||
|
|
|
@ -119,10 +119,10 @@ GMPParent::Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir)
|
|||
}
|
||||
|
||||
void
|
||||
GMPParent::Crash(GMPCrashReason aReason)
|
||||
GMPParent::Crash()
|
||||
{
|
||||
if (mState != GMPStateNotLoaded) {
|
||||
unused << SendCrashPluginNow(aReason);
|
||||
unused << SendCrashPluginNow();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "nsTArray.h"
|
||||
#include "nsIFile.h"
|
||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||
#include "GMPUtils.h"
|
||||
|
||||
class nsIThread;
|
||||
|
||||
|
@ -80,7 +79,7 @@ public:
|
|||
nsresult Init(GeckoMediaPluginServiceParent* aService, nsIFile* aPluginDir);
|
||||
nsresult CloneFrom(const GMPParent* aOther);
|
||||
|
||||
void Crash(GMPCrashReason aReason);
|
||||
void Crash();
|
||||
|
||||
nsresult LoadProcess();
|
||||
|
||||
|
|
|
@ -215,38 +215,6 @@ GeckoMediaPluginServiceChild::UpdateTrialCreateState(const nsAString& aKeySystem
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GeckoMediaPluginServiceChild::CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason)
|
||||
{
|
||||
if (NS_GetCurrentThread() != mGMPThread) {
|
||||
mGMPThread->Dispatch(NS_NewRunnableMethodWithArgs<uint32_t, GMPCrashReason>(
|
||||
this, &GeckoMediaPluginServiceChild::CrashPluginNow,
|
||||
aPluginId, aReason), NS_DISPATCH_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
class Callback : public GetServiceChildCallback
|
||||
{
|
||||
public:
|
||||
Callback(uint32_t aPluginId, GMPCrashReason aReason)
|
||||
: mPluginId(aPluginId)
|
||||
, mReason(aReason)
|
||||
{ }
|
||||
|
||||
virtual void Done(GMPServiceChild* aService) override
|
||||
{
|
||||
aService->SendCrashPluginNow(mPluginId, mReason);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t mPluginId;
|
||||
GMPCrashReason mReason;
|
||||
};
|
||||
|
||||
UniquePtr<GetServiceChildCallback> callback(new Callback(aPluginId, aReason));
|
||||
GetServiceChild(Move(callback));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginServiceChild::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "mozilla/ipc/Transport.h"
|
||||
#include "mozilla/gmp/PGMPServiceChild.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "GMPUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
@ -53,8 +52,6 @@ public:
|
|||
NS_IMETHOD UpdateTrialCreateState(const nsAString& aKeySystem,
|
||||
uint32_t aState) override;
|
||||
|
||||
void CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason);
|
||||
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
void SetServiceChild(UniquePtr<GMPServiceChild>&& aServiceChild);
|
||||
|
|
|
@ -84,7 +84,6 @@ NS_IMPL_ISUPPORTS_INHERITED(GeckoMediaPluginServiceParent,
|
|||
|
||||
static int32_t sMaxAsyncShutdownWaitMs = 0;
|
||||
static bool sHaveSetTimeoutPrefCache = false;
|
||||
static bool sKillHungPlugins = true;
|
||||
|
||||
GeckoMediaPluginServiceParent::GeckoMediaPluginServiceParent()
|
||||
: mShuttingDown(false)
|
||||
|
@ -100,9 +99,6 @@ GeckoMediaPluginServiceParent::GeckoMediaPluginServiceParent()
|
|||
Preferences::AddIntVarCache(&sMaxAsyncShutdownWaitMs,
|
||||
"media.gmp.async-shutdown-timeout",
|
||||
GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT);
|
||||
Preferences::AddBoolVarCache(&sKillHungPlugins,
|
||||
"media.gmp.kill-hung-plugins",
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -668,7 +664,7 @@ GeckoMediaPluginServiceParent::CrashPlugins()
|
|||
|
||||
MutexAutoLock lock(mMutex);
|
||||
for (size_t i = 0; i < mPlugins.Length(); i++) {
|
||||
mPlugins[i]->Crash(kPrefChange);
|
||||
mPlugins[i]->Crash();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1378,24 +1374,6 @@ GeckoMediaPluginServiceParent::UpdateTrialCreateState(const nsAString& aKeySyste
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
GeckoMediaPluginServiceParent::CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
if (aReason == kGmpApiTimeout && !sKillHungPlugins) {
|
||||
LOGD(("%s::%s(%u, %u) but killing hung plugins disabled.",
|
||||
__CLASS__, __FUNCTION__, aPluginId, aReason));
|
||||
return;
|
||||
}
|
||||
LOGD(("%s::%s(%u, %u)", __CLASS__, __FUNCTION__, aPluginId, aReason));
|
||||
MutexAutoLock lock(mMutex);
|
||||
for (const auto& plugin : mPlugins) {
|
||||
if (plugin->GetPluginId() == aPluginId) {
|
||||
plugin->Crash(aReason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ExtractHostName(const nsACString& aOrigin, nsACString& aOutData)
|
||||
{
|
||||
|
@ -1730,14 +1708,6 @@ GMPServiceParent::~GMPServiceParent()
|
|||
new DeleteTask<Transport>(GetTransport()));
|
||||
}
|
||||
|
||||
bool
|
||||
GMPServiceParent::RecvCrashPluginNow(const uint32_t& aPluginId,
|
||||
const GMPCrashReason& aReason)
|
||||
{
|
||||
mService->CrashPluginNow(aPluginId, aReason);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPServiceParent::RecvLoadGMP(const nsCString& aNodeId,
|
||||
const nsCString& aAPI,
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "GMPUtils.h"
|
||||
|
||||
template <class> struct already_AddRefed;
|
||||
|
||||
|
@ -58,8 +57,6 @@ public:
|
|||
void SetAsyncShutdownPluginState(GMPParent* aGMPParent, char aId, const nsCString& aState);
|
||||
#endif // MOZ_CRASHREPORTER
|
||||
|
||||
void CrashPluginNow(uint32_t aPluginId, GMPCrashReason aReason);
|
||||
|
||||
private:
|
||||
friend class GMPServiceParent;
|
||||
|
||||
|
@ -226,8 +223,6 @@ public:
|
|||
nsCString* aVersion);
|
||||
virtual bool RecvUpdateGMPTrialCreateState(const nsString& aKeySystem,
|
||||
const uint32_t& aState) override;
|
||||
virtual bool RecvCrashPluginNow(const uint32_t& aPluginId,
|
||||
const GMPCrashReason& aReason) override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
|
|
|
@ -37,12 +37,6 @@ SplitAt(const char* aDelims,
|
|||
nsCString
|
||||
ToBase64(const nsTArray<uint8_t>& aBytes);
|
||||
|
||||
enum GMPCrashReason {
|
||||
kPrefChange, // media.gmp.plugin.crash has been toggled.
|
||||
kGmpApiTimeout, // Some API did not respond.
|
||||
kInvalid,
|
||||
};
|
||||
|
||||
bool
|
||||
FileExists(nsIFile* aFile);
|
||||
|
||||
|
|
|
@ -188,7 +188,6 @@ GMPVideoDecoderParent::Reset()
|
|||
LOGD(("GMPVideoDecoderParent[%p]::ResetCompleteTimeout() timed out waiting for ResetComplete", self.get()));
|
||||
self->mResetCompleteTimeout = nullptr;
|
||||
LogToBrowserConsole(NS_LITERAL_STRING("GMPVideoDecoderParent timed out waiting for ResetComplete()"));
|
||||
self->mPlugin->CrashPluginNow(kGmpApiTimeout);
|
||||
});
|
||||
CancelResetCompleteTimeout();
|
||||
mResetCompleteTimeout = SimpleTimer::Create(task, 5000, mPlugin->GMPThread());
|
||||
|
|
|
@ -9,7 +9,6 @@ include protocol PGMPTimer;
|
|||
include protocol PGMPStorage;
|
||||
|
||||
using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
|
||||
using mozilla::GMPCrashReason from "GMPUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
@ -34,7 +33,7 @@ parent:
|
|||
|
||||
child:
|
||||
async BeginAsyncShutdown();
|
||||
async CrashPluginNow(GMPCrashReason aReason);
|
||||
async CrashPluginNow();
|
||||
intr StartPlugin();
|
||||
async SetNodeId(nsCString nodeId);
|
||||
async CloseActive();
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
include protocol PGMP;
|
||||
|
||||
using base::ProcessId from "base/process.h";
|
||||
using mozilla::GMPCrashReason from "GMPUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
@ -24,8 +23,6 @@ parent:
|
|||
returns (nsCString id);
|
||||
|
||||
async UpdateGMPTrialCreateState(nsString keySystem, uint32_t status);
|
||||
|
||||
async CrashPluginNow(uint32_t pluginId, GMPCrashReason aReason);
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
|
|
@ -51,7 +51,7 @@ MediaSourceDecoder::CreateStateMachine()
|
|||
}
|
||||
|
||||
nsresult
|
||||
MediaSourceDecoder::Load(nsIStreamListener**, MediaDecoder*)
|
||||
MediaSourceDecoder::Load(nsIStreamListener**)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!GetStateMachine());
|
||||
|
@ -61,7 +61,7 @@ MediaSourceDecoder::Load(nsIStreamListener**, MediaDecoder*)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = GetStateMachine()->Init(nullptr);
|
||||
nsresult rv = GetStateMachine()->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SetStateMachineParameters();
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
|
||||
virtual MediaDecoder* Clone() override;
|
||||
virtual MediaDecoderStateMachine* CreateStateMachine() override;
|
||||
virtual nsresult Load(nsIStreamListener**, MediaDecoder*) override;
|
||||
virtual nsresult Load(nsIStreamListener**) override;
|
||||
virtual media::TimeIntervals GetSeekable() override;
|
||||
media::TimeIntervals GetBuffered() override;
|
||||
|
||||
|
|
|
@ -284,8 +284,10 @@ MediaCodecReader::~MediaCodecReader()
|
|||
}
|
||||
|
||||
void
|
||||
MediaCodecReader::ReleaseMediaResources()
|
||||
MediaCodecReader::ReleaseMediaResourcesInternal()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
// Stop the mSource because we are in the dormant state and the stop function
|
||||
// will rewind the mSource to the beginning of the stream.
|
||||
if (mVideoTrack.mSource != nullptr && !mVideoTrack.mSourceIsStopped) {
|
||||
|
|
|
@ -60,9 +60,6 @@ public:
|
|||
MediaCodecReader(AbstractMediaDecoder* aDecoder);
|
||||
virtual ~MediaCodecReader();
|
||||
|
||||
// Release media resources they should be released in dormant state
|
||||
virtual void ReleaseMediaResources();
|
||||
|
||||
// Destroys the decoding state. The reader cannot be made usable again.
|
||||
// This is different from ReleaseMediaResources() as Shutdown() is
|
||||
// irreversible, whereas ReleaseMediaResources() is reversible.
|
||||
|
@ -436,6 +433,10 @@ private:
|
|||
nsTArray<ReleaseItem> mPendingReleaseItems;
|
||||
|
||||
NotifyDataArrivedFilter mFilter;
|
||||
|
||||
private:
|
||||
// Release media resources they should be released in dormant state
|
||||
virtual void ReleaseMediaResourcesInternal() override;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -170,8 +170,10 @@ MediaOmxReader::Shutdown()
|
|||
return p;
|
||||
}
|
||||
|
||||
void MediaOmxReader::ReleaseMediaResources()
|
||||
void MediaOmxReader::ReleaseMediaResourcesInternal()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
mMediaResourceRequest.DisconnectIfExists();
|
||||
mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
|
||||
|
|
|
@ -95,8 +95,6 @@ public:
|
|||
return mHasVideo;
|
||||
}
|
||||
|
||||
virtual void ReleaseMediaResources();
|
||||
|
||||
virtual nsRefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata() override;
|
||||
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
|
@ -118,6 +116,8 @@ private:
|
|||
class ProcessCachedDataTask;
|
||||
class NotifyDataArrivedRunnable;
|
||||
|
||||
virtual void ReleaseMediaResourcesInternal() override;
|
||||
|
||||
bool IsShutdown() {
|
||||
MutexAutoLock lock(mShutdownMutex);
|
||||
return mIsShutdown;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
||||
#undef LOG
|
||||
#undef LOG_ENABLED
|
||||
|
@ -142,6 +143,79 @@ private:
|
|||
int mResult;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(CamerasParent, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
CamerasParent::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t *aData)
|
||||
{
|
||||
MOZ_ASSERT(!strcmp(aTopic, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID));
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
MOZ_ASSERT(obs);
|
||||
obs->RemoveObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID);
|
||||
StopVideoCapture();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CamerasParent::DispatchToVideoCaptureThread(nsRunnable *event)
|
||||
{
|
||||
MonitorAutoLock lock(mThreadMonitor);
|
||||
|
||||
while(mChildIsAlive && mWebRTCAlive &&
|
||||
(!mVideoCaptureThread || !mVideoCaptureThread->IsRunning())) {
|
||||
mThreadMonitor.Wait();
|
||||
}
|
||||
if (!mVideoCaptureThread || !mVideoCaptureThread->IsRunning()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mVideoCaptureThread->message_loop()->PostTask(FROM_HERE,
|
||||
new RunnableTask(event));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CamerasParent::StopVideoCapture()
|
||||
{
|
||||
// We are called from the main thread (xpcom-shutdown) or
|
||||
// from PBackground (when the Actor shuts down).
|
||||
// Shut down the WebRTC stack (on the capture thread)
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self]() -> nsresult {
|
||||
MonitorAutoLock lock(self->mThreadMonitor);
|
||||
self->CloseEngines();
|
||||
self->mThreadMonitor.NotifyAll();
|
||||
return NS_OK;
|
||||
});
|
||||
DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
// Hold here until the WebRTC thread is gone. We need to dispatch
|
||||
// the thread deletion *now*, or there will be no more possibility
|
||||
// to get to the main thread.
|
||||
MonitorAutoLock lock(mThreadMonitor);
|
||||
while (mWebRTCAlive) {
|
||||
mThreadMonitor.Wait();
|
||||
}
|
||||
// After closing the WebRTC stack, clean up the
|
||||
// VideoCapture thread.
|
||||
if (self->mVideoCaptureThread) {
|
||||
base::Thread *thread = self->mVideoCaptureThread;
|
||||
self->mVideoCaptureThread = nullptr;
|
||||
nsRefPtr<nsRunnable> threadShutdown =
|
||||
media::NewRunnableFrom([thread]() -> nsresult {
|
||||
if (thread->IsRunning()) {
|
||||
thread->Stop();
|
||||
}
|
||||
delete thread;
|
||||
return NS_OK;
|
||||
});
|
||||
if (NS_FAILED(NS_DispatchToMainThread(threadShutdown))) {
|
||||
LOG(("Could not dispatch VideoCaptureThread destruction"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
CamerasParent::DeliverFrameOverIPC(CaptureEngine cap_engine,
|
||||
int cap_id,
|
||||
|
@ -235,6 +309,7 @@ CamerasParent::RecvReleaseFrame(mozilla::ipc::Shmem&& s) {
|
|||
bool
|
||||
CamerasParent::SetupEngine(CaptureEngine aCapEngine)
|
||||
{
|
||||
MOZ_ASSERT(mVideoCaptureThread->thread_id() == PlatformThread::CurrentId());
|
||||
EngineHelper *helper = &mEngines[aCapEngine];
|
||||
|
||||
// Already initialized
|
||||
|
@ -308,51 +383,57 @@ CamerasParent::SetupEngine(CaptureEngine aCapEngine)
|
|||
void
|
||||
CamerasParent::CloseEngines()
|
||||
{
|
||||
{
|
||||
MutexAutoLock lock(mCallbackMutex);
|
||||
// Stop the callers
|
||||
while (mCallbacks.Length()) {
|
||||
auto capEngine = mCallbacks[0]->mCapEngine;
|
||||
auto capNum = mCallbacks[0]->mCapturerId;
|
||||
LOG(("Forcing shutdown of engine %d, capturer %d", capEngine, capNum));
|
||||
{
|
||||
MutexAutoUnlock unlock(mCallbackMutex);
|
||||
RecvStopCapture(capEngine, capNum);
|
||||
RecvReleaseCaptureDevice(capEngine, capNum);
|
||||
}
|
||||
// The callbacks list might have changed while we released the lock,
|
||||
// but note that due to the loop construct this will not break us.
|
||||
if (!mWebRTCAlive) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mVideoCaptureThread->thread_id() == PlatformThread::CurrentId());
|
||||
|
||||
// Stop the callers
|
||||
while (mCallbacks.Length()) {
|
||||
auto capEngine = mCallbacks[0]->mCapEngine;
|
||||
auto capNum = mCallbacks[0]->mCapturerId;
|
||||
LOG(("Forcing shutdown of engine %d, capturer %d", capEngine, capNum));
|
||||
RecvStopCapture(capEngine, capNum);
|
||||
RecvReleaseCaptureDevice(capEngine, capNum);
|
||||
}
|
||||
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
if (mEngines[i].mEngineIsRunning) {
|
||||
LOG(("Being closed down while engine %d is running!", i));
|
||||
}
|
||||
if (mEngines[i].mPtrViERender) {
|
||||
mEngines[i].mPtrViERender->Release();
|
||||
mEngines[i].mPtrViERender = nullptr;
|
||||
}
|
||||
if (mEngines[i].mPtrViECapture) {
|
||||
mEngines[i].mPtrViECapture->Release();
|
||||
mEngines[i].mPtrViECapture = nullptr;
|
||||
}
|
||||
if(mEngines[i].mPtrViEBase) {
|
||||
mEngines[i].mPtrViEBase->Release();
|
||||
mEngines[i].mPtrViEBase = nullptr;
|
||||
}
|
||||
if (mEngines[i].mEngine) {
|
||||
mEngines[i].mEngine->SetTraceCallback(nullptr);
|
||||
webrtc::VideoEngine::Delete(mEngines[i].mEngine);
|
||||
mEngines[i].mEngine = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mEngineMutex);
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
if (mEngines[i].mEngineIsRunning) {
|
||||
LOG(("Being closed down while engine %d is running!", i));
|
||||
}
|
||||
if (mEngines[i].mPtrViERender) {
|
||||
mEngines[i].mPtrViERender->Release();
|
||||
mEngines[i].mPtrViERender = nullptr;
|
||||
}
|
||||
if (mEngines[i].mPtrViECapture) {
|
||||
mEngines[i].mPtrViECapture->Release();
|
||||
mEngines[i].mPtrViECapture = nullptr;
|
||||
}
|
||||
if(mEngines[i].mPtrViEBase) {
|
||||
mEngines[i].mPtrViEBase->Release();
|
||||
mEngines[i].mPtrViEBase = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
mWebRTCAlive = false;
|
||||
}
|
||||
|
||||
bool
|
||||
CamerasParent::EnsureInitialized(int aEngine)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
// We're shutting down, don't try to do new WebRTC ops.
|
||||
if (!mWebRTCAlive) {
|
||||
return false;
|
||||
}
|
||||
CaptureEngine capEngine = static_cast<CaptureEngine>(aEngine);
|
||||
if (!SetupEngine(capEngine)) {
|
||||
LOG(("CamerasParent failed to initialize engine"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -368,18 +449,12 @@ bool
|
|||
CamerasParent::RecvNumberOfCaptureDevices(const int& aCapEngine)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
if (!EnsureInitialized(aCapEngine)) {
|
||||
LOG(("RecvNumberOfCaptureDevices fails to initialize"));
|
||||
unused << SendReplyFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine]() -> nsresult {
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int num = -1;
|
||||
if (self->mEngines[aCapEngine].mPtrViECapture) {
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
num = self->mEngines[aCapEngine].mPtrViECapture->NumberOfCaptureDevices();
|
||||
}
|
||||
nsRefPtr<nsIRunnable> ipc_runnable =
|
||||
|
@ -400,8 +475,7 @@ CamerasParent::RecvNumberOfCaptureDevices(const int& aCapEngine)
|
|||
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
});
|
||||
mVideoCaptureThread->message_loop()->PostTask(FROM_HERE, new RunnableTask(webrtc_runnable));
|
||||
|
||||
DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -410,19 +484,13 @@ CamerasParent::RecvNumberOfCapabilities(const int& aCapEngine,
|
|||
const nsCString& unique_id)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
if (!EnsureInitialized(aCapEngine)) {
|
||||
LOG(("RecvNumberOfCapabilities fails to initialize"));
|
||||
unused << SendReplyFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(("Getting caps for %s", unique_id.get()));
|
||||
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, unique_id, aCapEngine]() -> nsresult {
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int num = -1;
|
||||
if (self->mEngines[aCapEngine].mPtrViECapture) {
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
num =
|
||||
self->mEngines[aCapEngine].mPtrViECapture->NumberOfCapabilities(
|
||||
unique_id.get(),
|
||||
|
@ -446,7 +514,7 @@ CamerasParent::RecvNumberOfCapabilities(const int& aCapEngine,
|
|||
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
});
|
||||
mVideoCaptureThread->message_loop()->PostTask(FROM_HERE, new RunnableTask(webrtc_runnable));
|
||||
DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -456,21 +524,14 @@ CamerasParent::RecvGetCaptureCapability(const int &aCapEngine,
|
|||
const int& num)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
if (!EnsureInitialized(aCapEngine)) {
|
||||
LOG(("Fails to initialize"));
|
||||
unused << SendReplyFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(("RecvGetCaptureCapability: %s %d", unique_id.get(), num));
|
||||
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, unique_id, aCapEngine, num]() -> nsresult {
|
||||
webrtc::CaptureCapability webrtcCaps;
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int error = -1;
|
||||
if (self->mEngines[aCapEngine].mPtrViECapture) {
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->GetCaptureCapability(
|
||||
unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, num, webrtcCaps);
|
||||
}
|
||||
|
@ -503,7 +564,7 @@ CamerasParent::RecvGetCaptureCapability(const int &aCapEngine,
|
|||
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
});
|
||||
mVideoCaptureThread->message_loop()->PostTask(FROM_HERE, new RunnableTask(webrtc_runnable));
|
||||
DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -512,13 +573,7 @@ CamerasParent::RecvGetCaptureDevice(const int& aCapEngine,
|
|||
const int& aListNumber)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
if (!EnsureInitialized(aCapEngine)) {
|
||||
LOG(("Fails to initialize"));
|
||||
unused << SendReplyFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(("RecvGetCaptureDevice"));
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, aListNumber]() -> nsresult {
|
||||
|
@ -526,20 +581,18 @@ CamerasParent::RecvGetCaptureDevice(const int& aCapEngine,
|
|||
char deviceUniqueId[MediaEngineSource::kMaxUniqueIdLength];
|
||||
nsCString name;
|
||||
nsCString uniqueId;
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int error = -1;
|
||||
if (self->mEngines[aCapEngine].mPtrViECapture) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->GetCaptureDevice(aListNumber,
|
||||
deviceName,
|
||||
sizeof(deviceName),
|
||||
deviceUniqueId,
|
||||
sizeof(deviceUniqueId));
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->GetCaptureDevice(aListNumber,
|
||||
deviceName,
|
||||
sizeof(deviceName),
|
||||
deviceUniqueId,
|
||||
sizeof(deviceUniqueId));
|
||||
}
|
||||
if (!error) {
|
||||
name.Assign(deviceName);
|
||||
uniqueId.Assign(deviceUniqueId);
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, error, name, uniqueId]() -> nsresult {
|
||||
if (self->IsShuttingDown()) {
|
||||
|
@ -558,7 +611,7 @@ CamerasParent::RecvGetCaptureDevice(const int& aCapEngine,
|
|||
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
});
|
||||
mVideoCaptureThread->message_loop()->PostTask(FROM_HERE, new RunnableTask(webrtc_runnable));
|
||||
DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -567,19 +620,13 @@ CamerasParent::RecvAllocateCaptureDevice(const int& aCapEngine,
|
|||
const nsCString& unique_id)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
if (!EnsureInitialized(aCapEngine)) {
|
||||
LOG(("Fails to initialize"));
|
||||
unused << SendReplyFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, unique_id]() -> nsresult {
|
||||
int numdev = -1;
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int error = -1;
|
||||
if (self->mEngines[aCapEngine].mPtrViECapture) {
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->AllocateCaptureDevice(
|
||||
unique_id.get(), MediaEngineSource::kMaxUniqueIdLength, numdev);
|
||||
}
|
||||
|
@ -600,7 +647,7 @@ CamerasParent::RecvAllocateCaptureDevice(const int& aCapEngine,
|
|||
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
});
|
||||
mVideoCaptureThread->message_loop()->PostTask(FROM_HERE, new RunnableTask(webrtc_runnable));
|
||||
DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -609,19 +656,13 @@ CamerasParent::RecvReleaseCaptureDevice(const int& aCapEngine,
|
|||
const int& numdev)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
if (!EnsureInitialized(aCapEngine)) {
|
||||
LOG(("Fails to initialize"));
|
||||
unused << SendReplyFailure();
|
||||
return false;
|
||||
}
|
||||
LOG(("RecvReleaseCamera device nr %d", numdev));
|
||||
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, numdev]() -> nsresult {
|
||||
LOG(("RecvReleaseCamera device nr %d", numdev));
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
int error = -1;
|
||||
if (self->mEngines[aCapEngine].mPtrViECapture) {
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
error = self->mEngines[aCapEngine].mPtrViECapture->ReleaseCaptureDevice(numdev);
|
||||
}
|
||||
nsRefPtr<nsIRunnable> ipc_runnable =
|
||||
|
@ -641,12 +682,7 @@ CamerasParent::RecvReleaseCaptureDevice(const int& aCapEngine,
|
|||
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
});
|
||||
#ifndef XP_MACOSX
|
||||
mVideoCaptureThread->message_loop()->PostTask(FROM_HERE, new RunnableTask(webrtc_runnable));
|
||||
#else
|
||||
// Mac OS X hangs on shutdown if we don't do this on the main thread.
|
||||
NS_DispatchToMainThread(webrtc_runnable);
|
||||
#endif
|
||||
DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -656,11 +692,6 @@ CamerasParent::RecvStartCapture(const int& aCapEngine,
|
|||
const CaptureCapability& ipcCaps)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
if (!EnsureInitialized(aCapEngine)) {
|
||||
LOG(("Failure to initialize"));
|
||||
unused << SendReplyFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
|
@ -668,23 +699,15 @@ CamerasParent::RecvStartCapture(const int& aCapEngine,
|
|||
CallbackHelper** cbh;
|
||||
webrtc::ExternalRenderer* render;
|
||||
EngineHelper* helper = nullptr;
|
||||
int error;
|
||||
{
|
||||
MutexAutoLock lockCallback(self->mCallbackMutex);
|
||||
int error = -1;
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
cbh = self->mCallbacks.AppendElement(
|
||||
new CallbackHelper(static_cast<CaptureEngine>(aCapEngine), capnum, self));
|
||||
render = static_cast<webrtc::ExternalRenderer*>(*cbh);
|
||||
}
|
||||
{
|
||||
MutexAutoLock lockEngine(self->mEngineMutex);
|
||||
if (self->mEngines[aCapEngine].mPtrViECapture) {
|
||||
helper = &self->mEngines[aCapEngine];
|
||||
error =
|
||||
helper->mPtrViERender->AddRenderer(capnum, webrtc::kVideoI420, render);
|
||||
} else {
|
||||
error = -1;
|
||||
}
|
||||
|
||||
helper = &self->mEngines[aCapEngine];
|
||||
error =
|
||||
helper->mPtrViERender->AddRenderer(capnum, webrtc::kVideoI420, render);
|
||||
if (!error) {
|
||||
error = helper->mPtrViERender->StartRender(capnum);
|
||||
}
|
||||
|
@ -705,7 +728,6 @@ CamerasParent::RecvStartCapture(const int& aCapEngine,
|
|||
helper->mEngineIsRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, error]() -> nsresult {
|
||||
if (self->IsShuttingDown()) {
|
||||
|
@ -722,7 +744,7 @@ CamerasParent::RecvStartCapture(const int& aCapEngine,
|
|||
self->mPBackgroundThread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
});
|
||||
mVideoCaptureThread->message_loop()->PostTask(FROM_HERE, new RunnableTask(webrtc_runnable));
|
||||
DispatchToVideoCaptureThread(webrtc_runnable);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -731,40 +753,32 @@ CamerasParent::RecvStopCapture(const int& aCapEngine,
|
|||
const int& capnum)
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
if (!EnsureInitialized(aCapEngine)) {
|
||||
LOG(("Failure to initialize"));
|
||||
unused << SendReplyFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> webrtc_runnable =
|
||||
media::NewRunnableFrom([self, aCapEngine, capnum]() -> nsresult {
|
||||
{
|
||||
MutexAutoLock lock(self->mEngineMutex);
|
||||
// We only need to check mPtrViECapture as all other engines are guaranteed
|
||||
// to be nulled under the same lock.
|
||||
if (self->mEngines[aCapEngine].mPtrViECapture) {
|
||||
self->mEngines[aCapEngine].mPtrViECapture->StopCapture(capnum);
|
||||
self->mEngines[aCapEngine].mPtrViERender->StopRender(capnum);
|
||||
self->mEngines[aCapEngine].mPtrViERender->RemoveRenderer(capnum);
|
||||
self->mEngines[aCapEngine].mEngineIsRunning = false;
|
||||
}
|
||||
}
|
||||
MutexAutoLock lock(self->mCallbackMutex);
|
||||
for (unsigned int i = 0; i < self->mCallbacks.Length(); i++) {
|
||||
if (self->mCallbacks[i]->mCapEngine == aCapEngine
|
||||
&& self->mCallbacks[i]->mCapturerId == capnum) {
|
||||
delete self->mCallbacks[i];
|
||||
self->mCallbacks.RemoveElementAt(i);
|
||||
break;
|
||||
if (self->EnsureInitialized(aCapEngine)) {
|
||||
self->mEngines[aCapEngine].mPtrViECapture->StopCapture(capnum);
|
||||
self->mEngines[aCapEngine].mPtrViERender->StopRender(capnum);
|
||||
self->mEngines[aCapEngine].mPtrViERender->RemoveRenderer(capnum);
|
||||
self->mEngines[aCapEngine].mEngineIsRunning = false;
|
||||
|
||||
for (size_t i = 0; i < self->mCallbacks.Length(); i++) {
|
||||
if (self->mCallbacks[i]->mCapEngine == aCapEngine
|
||||
&& self->mCallbacks[i]->mCapturerId == capnum) {
|
||||
delete self->mCallbacks[i];
|
||||
self->mCallbacks.RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
});
|
||||
|
||||
mVideoCaptureThread->message_loop()->PostTask(FROM_HERE, new RunnableTask(webrtc_runnable));
|
||||
return SendReplySuccess();
|
||||
if (NS_SUCCEEDED(DispatchToVideoCaptureThread(webrtc_runnable))) {
|
||||
return SendReplySuccess();
|
||||
} else {
|
||||
return SendReplyFailure();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -788,49 +802,24 @@ CamerasParent::RecvAllDone()
|
|||
return Send__delete__(this);
|
||||
}
|
||||
|
||||
void CamerasParent::DoShutdown()
|
||||
{
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
CloseEngines();
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mEngineMutex);
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
if (mEngines[i].mEngine) {
|
||||
mEngines[i].mEngine->SetTraceCallback(nullptr);
|
||||
webrtc::VideoEngine::Delete(mEngines[i].mEngine);
|
||||
mEngines[i].mEngine = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mPBackgroundThread = nullptr;
|
||||
|
||||
if (mVideoCaptureThread) {
|
||||
if (mVideoCaptureThread->IsRunning()) {
|
||||
mVideoCaptureThread->Stop();
|
||||
}
|
||||
delete mVideoCaptureThread;
|
||||
mVideoCaptureThread = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CamerasParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
// No more IPC from here
|
||||
LOG((__PRETTY_FUNCTION__));
|
||||
StopIPC();
|
||||
CloseEngines();
|
||||
// Shut down WebRTC (if we're not in full shutdown, else this
|
||||
// will already have happened)
|
||||
StopVideoCapture();
|
||||
}
|
||||
|
||||
CamerasParent::CamerasParent()
|
||||
: mCallbackMutex("CamerasParent.mCallbackMutex"),
|
||||
mEngineMutex("CamerasParent.mEngineMutex"),
|
||||
mShmemPool(CaptureEngine::MaxEngine),
|
||||
: mShmemPool(CaptureEngine::MaxEngine),
|
||||
mThreadMonitor("CamerasParent::mThreadMonitor"),
|
||||
mVideoCaptureThread(nullptr),
|
||||
mChildIsAlive(true),
|
||||
mDestroyed(false)
|
||||
mDestroyed(false),
|
||||
mWebRTCAlive(true)
|
||||
{
|
||||
if (!gCamerasParentLog) {
|
||||
gCamerasParentLog = PR_NewLogModule("CamerasParent");
|
||||
|
@ -841,16 +830,37 @@ CamerasParent::CamerasParent()
|
|||
MOZ_ASSERT(mPBackgroundThread != nullptr, "GetCurrentThread failed");
|
||||
|
||||
LOG(("Spinning up WebRTC Cameras Thread"));
|
||||
mVideoCaptureThread = new base::Thread("VideoCapture");
|
||||
base::Thread::Options options;
|
||||
|
||||
nsRefPtr<CamerasParent> self(this);
|
||||
nsRefPtr<nsRunnable> threadStart =
|
||||
media::NewRunnableFrom([self]() -> nsresult {
|
||||
// Register thread shutdown observer
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (NS_WARN_IF(!obs)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsresult rv =
|
||||
obs->AddObserver(self, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
// Start the thread
|
||||
MonitorAutoLock lock(self->mThreadMonitor);
|
||||
self->mVideoCaptureThread = new base::Thread("VideoCapture");
|
||||
base::Thread::Options options;
|
||||
#if defined(_WIN32)
|
||||
options.message_loop_type = MessageLoop::TYPE_MOZILLA_NONMAINUITHREAD;
|
||||
options.message_loop_type = MessageLoop::TYPE_MOZILLA_NONMAINUITHREAD;
|
||||
#else
|
||||
options.message_loop_type = MessageLoop::TYPE_MOZILLA_NONMAINTHREAD;
|
||||
|
||||
options.message_loop_type = MessageLoop::TYPE_MOZILLA_NONMAINTHREAD;
|
||||
#endif
|
||||
if (!mVideoCaptureThread->StartWithOptions(options)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
if (!self->mVideoCaptureThread->StartWithOptions(options)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
self->mThreadMonitor.NotifyAll();
|
||||
return NS_OK;
|
||||
});
|
||||
NS_DispatchToMainThread(threadStart);
|
||||
|
||||
MOZ_COUNT_CTOR(CamerasParent);
|
||||
}
|
||||
|
@ -860,7 +870,15 @@ CamerasParent::~CamerasParent()
|
|||
LOG(("~CamerasParent: %p", this));
|
||||
|
||||
MOZ_COUNT_DTOR(CamerasParent);
|
||||
DoShutdown();
|
||||
#ifdef DEBUG
|
||||
// Verify we have shut down the webrtc engines, this is
|
||||
// supposed to happen in ActorDestroy.
|
||||
// That runnable takes a ref to us, so it must have finished
|
||||
// by the time we get here.
|
||||
for (int i = 0; i < CaptureEngine::MaxEngine; i++) {
|
||||
MOZ_ASSERT(!mEngines[i].mEngine);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
already_AddRefed<CamerasParent>
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
#ifndef mozilla_CamerasParent_h
|
||||
#define mozilla_CamerasParent_h
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/camera/PCamerasParent.h"
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "mozilla/ShmemPool.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
// conflicts with #include of scoped_ptr.h
|
||||
#undef FF
|
||||
|
@ -73,9 +75,11 @@ public:
|
|||
bool mEngineIsRunning;
|
||||
};
|
||||
|
||||
class CamerasParent : public PCamerasParent
|
||||
class CamerasParent : public PCamerasParent,
|
||||
public nsIObserver
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CamerasParent);
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
public:
|
||||
static already_AddRefed<CamerasParent> Create();
|
||||
|
@ -94,7 +98,9 @@ public:
|
|||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
nsIThread* GetBackgroundThread() { return mPBackgroundThread; };
|
||||
bool IsShuttingDown() { return !mChildIsAlive || mDestroyed; };
|
||||
bool IsShuttingDown() { return !mChildIsAlive
|
||||
|| mDestroyed
|
||||
|| !mWebRTCAlive; };
|
||||
ShmemBuffer GetBuffer(size_t aSize);
|
||||
|
||||
// helper to forward to the PBackground thread
|
||||
|
@ -116,15 +122,12 @@ protected:
|
|||
bool SetupEngine(CaptureEngine aCapEngine);
|
||||
void CloseEngines();
|
||||
bool EnsureInitialized(int aEngine);
|
||||
void DoShutdown();
|
||||
void StopIPC();
|
||||
void StopVideoCapture();
|
||||
nsresult DispatchToVideoCaptureThread(nsRunnable *event);
|
||||
|
||||
EngineHelper mEngines[CaptureEngine::MaxEngine];
|
||||
nsTArray<CallbackHelper*> mCallbacks;
|
||||
// Protects the callback arrays
|
||||
Mutex mCallbackMutex;
|
||||
// Protects the engines array
|
||||
Mutex mEngineMutex;
|
||||
|
||||
// image buffers
|
||||
mozilla::ShmemPool mShmemPool;
|
||||
|
@ -132,12 +135,18 @@ protected:
|
|||
// PBackground parent thread
|
||||
nsCOMPtr<nsIThread> mPBackgroundThread;
|
||||
|
||||
// Monitors creation of the thread below
|
||||
Monitor mThreadMonitor;
|
||||
|
||||
// video processing thread - where webrtc.org capturer code runs
|
||||
base::Thread* mVideoCaptureThread;
|
||||
|
||||
// Shutdown handling
|
||||
bool mChildIsAlive;
|
||||
bool mDestroyed;
|
||||
// Above 2 are PBackground only, but this is potentially
|
||||
// read cross-thread.
|
||||
mozilla::Atomic<bool> mWebRTCAlive;
|
||||
};
|
||||
|
||||
PCamerasParent* CreateCamerasParent();
|
||||
|
|
|
@ -68,19 +68,19 @@ public:
|
|||
Pledge& operator = (const Pledge&) = delete;
|
||||
|
||||
template<typename OnSuccessType>
|
||||
void Then(OnSuccessType aOnSuccess)
|
||||
void Then(OnSuccessType&& aOnSuccess)
|
||||
{
|
||||
Then(aOnSuccess, [](ErrorType&){});
|
||||
Then(Forward<OnSuccessType>(aOnSuccess), [](ErrorType&){});
|
||||
}
|
||||
|
||||
template<typename OnSuccessType, typename OnFailureType>
|
||||
void Then(OnSuccessType aOnSuccess, OnFailureType aOnFailure)
|
||||
void Then(OnSuccessType&& aOnSuccess, OnFailureType&& aOnFailure)
|
||||
{
|
||||
class Functors : public FunctorsBase
|
||||
{
|
||||
public:
|
||||
Functors(OnSuccessType& aOnSuccess, OnFailureType& aOnFailure)
|
||||
: mOnSuccess(aOnSuccess), mOnFailure(aOnFailure) {}
|
||||
Functors(OnSuccessType&& aOnSuccess, OnFailureType&& aOnFailure)
|
||||
: mOnSuccess(Move(aOnSuccess)), mOnFailure(Move(aOnFailure)) {}
|
||||
|
||||
void Succeed(ValueType& result)
|
||||
{
|
||||
|
@ -94,8 +94,8 @@ public:
|
|||
OnSuccessType mOnSuccess;
|
||||
OnFailureType mOnFailure;
|
||||
};
|
||||
mFunctors = new Functors(aOnSuccess, aOnFailure);
|
||||
|
||||
mFunctors = new Functors(Forward<OnSuccessType>(aOnSuccess),
|
||||
Forward<OnFailureType>(aOnFailure));
|
||||
if (mDone) {
|
||||
if (!mRejected) {
|
||||
mFunctors->Succeed(mValue);
|
||||
|
@ -186,7 +186,7 @@ template<typename OnRunType>
|
|||
class LambdaRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit LambdaRunnable(OnRunType& aOnRun) : mOnRun(aOnRun) {}
|
||||
explicit LambdaRunnable(OnRunType&& aOnRun) : mOnRun(Move(aOnRun)) {}
|
||||
private:
|
||||
NS_IMETHODIMP
|
||||
Run()
|
||||
|
@ -198,16 +198,16 @@ private:
|
|||
|
||||
template<typename OnRunType>
|
||||
LambdaRunnable<OnRunType>*
|
||||
NewRunnableFrom(OnRunType aOnRun)
|
||||
NewRunnableFrom(OnRunType&& aOnRun)
|
||||
{
|
||||
return new LambdaRunnable<OnRunType>(aOnRun);
|
||||
return new LambdaRunnable<OnRunType>(Forward<OnRunType>(aOnRun));
|
||||
}
|
||||
|
||||
template<typename OnRunType>
|
||||
class LambdaTask : public Task
|
||||
{
|
||||
public:
|
||||
explicit LambdaTask(OnRunType& aOnRun) : mOnRun(aOnRun) {}
|
||||
explicit LambdaTask(OnRunType&& aOnRun) : mOnRun(Move(aOnRun)) {}
|
||||
private:
|
||||
void
|
||||
Run()
|
||||
|
@ -219,9 +219,9 @@ private:
|
|||
|
||||
template<typename OnRunType>
|
||||
LambdaTask<OnRunType>*
|
||||
NewTaskFrom(OnRunType aOnRun)
|
||||
NewTaskFrom(OnRunType&& aOnRun)
|
||||
{
|
||||
return new LambdaTask<OnRunType>(aOnRun);
|
||||
return new LambdaTask<OnRunType>(Forward<OnRunType>(aOnRun));
|
||||
}
|
||||
|
||||
/* media::CoatCheck - There and back again. Park an object in exchange for an id.
|
||||
|
|
|
@ -277,6 +277,19 @@ function SetupEME(test, token, params)
|
|||
{
|
||||
var v = document.createElement("video");
|
||||
v.crossOrigin = test.crossOrigin || false;
|
||||
v.sessions = [];
|
||||
|
||||
v.closeSessions = function() {
|
||||
return Promise.all(v.sessions.map(s => s.close().then(() => s.closed))).then(
|
||||
() => {
|
||||
v.setMediaKeys(null);
|
||||
if (v.parentNode) {
|
||||
v.parentNode.removeChild(v);
|
||||
}
|
||||
v.onerror = null;
|
||||
v.src = null;
|
||||
});
|
||||
};
|
||||
|
||||
// Log events dispatched to make debugging easier...
|
||||
[ "canplay", "canplaythrough", "ended", "error", "loadeddata",
|
||||
|
@ -311,6 +324,7 @@ function SetupEME(test, token, params)
|
|||
if (params && params.onsessioncreated) {
|
||||
params.onsessioncreated(session);
|
||||
}
|
||||
v.sessions.push(session);
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
session.addEventListener("message", UpdateSessionFunc(test, token, sessionType, resolve, reject));
|
||||
|
|
|
@ -95,7 +95,7 @@ function startTest(test, token)
|
|||
ok(keyIdsReceived[kid], TimeStamp(token) + " key with id " + kid + " was usable as expected");
|
||||
}
|
||||
|
||||
manager.finished(token);
|
||||
v.closeSessions().then(() => manager.finished(token));
|
||||
});
|
||||
|
||||
LoadTest(test, v, token)
|
||||
|
|
|
@ -7,7 +7,7 @@ MARIONETTE_HEAD_JS = "head.js";
|
|||
// Start tests
|
||||
startTestCommon(function() {
|
||||
// The emulator's hard coded operatoer's mcc and mnc codes.
|
||||
is(mobileConnection.lastKnownNetwork, "310-260");
|
||||
is(mobileConnection.lastKnownNetwork, "310-410");
|
||||
// The emulator's hard coded icc's mcc, mnc codes and spn.
|
||||
is(mobileConnection.lastKnownHomeNetwork, "310-260-Android");
|
||||
is(mobileConnection.lastKnownHomeNetwork, "310-410-Android");
|
||||
}, ["mobilenetwork"]);
|
||||
|
|
|
@ -9,7 +9,7 @@ function isHomeNetwork(network) {
|
|||
is(network.longName, "Android");
|
||||
is(network.shortName, "Android");
|
||||
is(network.mcc, "310");
|
||||
is(network.mnc, "260");
|
||||
is(network.mnc, "410");
|
||||
}
|
||||
|
||||
function isRoamingNetwork(network) {
|
||||
|
@ -42,7 +42,7 @@ function testGetNetworks() {
|
|||
return getNetworks()
|
||||
.then(function resolve(aNetworks) {
|
||||
// The emulator RIL server should always return 2 networks:
|
||||
// {"longName":"Android","shortName":"Android","mcc":310,"mnc":260,"state":"available"}
|
||||
// {"longName":"Android","shortName":"Android","mcc":310,"mnc":410,"state":"available"}
|
||||
// {"longName":"TelKila","shortName":"TelKila","mcc":310,"mnc":295,"state":"available"}
|
||||
is(aNetworks.length, 2);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ function check(aLongName, aShortName) {
|
|||
is(network.longName, aLongName, "network.longName");
|
||||
is(network.shortName, aShortName, "network.shortName");
|
||||
is(network.mcc, "310", "network.mcc");
|
||||
is(network.mnc, "260", "network.mnc");
|
||||
is(network.mnc, "410", "network.mnc");
|
||||
}
|
||||
|
||||
function test(aLongName, aShortName) {
|
||||
|
|
|
@ -948,9 +948,20 @@ NetworkStatsDB.prototype = {
|
|||
let request = aStore.openCursor(range).onsuccess = function(event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor){
|
||||
data.push({ rxBytes: cursor.value.rxBytes,
|
||||
txBytes: cursor.value.txBytes,
|
||||
date: new Date(cursor.value.timestamp + offset) });
|
||||
// We use rxTotalBytes/txTotalBytes instead of rxBytes/txBytes for
|
||||
// the first (oldest) sample. The rx/txTotalBytes fields record
|
||||
// accumulative usage amount, which means even if old samples were
|
||||
// expired and removed from the Database, we can still obtain the
|
||||
// correct network usage.
|
||||
if (data.length == 0) {
|
||||
data.push({ rxBytes: cursor.value.rxTotalBytes,
|
||||
txBytes: cursor.value.txTotalBytes,
|
||||
date: new Date(cursor.value.timestamp + offset) });
|
||||
} else {
|
||||
data.push({ rxBytes: cursor.value.rxBytes,
|
||||
txBytes: cursor.value.txBytes,
|
||||
date: new Date(cursor.value.timestamp + offset) });
|
||||
}
|
||||
cursor.continue();
|
||||
return;
|
||||
}
|
||||
|
@ -981,9 +992,20 @@ NetworkStatsDB.prototype = {
|
|||
foundData.rxBytes += cursor.value.rxBytes;
|
||||
foundData.txBytes += cursor.value.txBytes;
|
||||
} else {
|
||||
data.push({ rxBytes: cursor.value.rxBytes,
|
||||
txBytes: cursor.value.txBytes,
|
||||
date: new Date(cursor.value.timestamp + offset) });
|
||||
// We use rxTotalBytes/txTotalBytes instead of rxBytes/txBytes
|
||||
// for the first (oldest) sample. The rx/txTotalBytes fields
|
||||
// record accumulative usage amount, which means even if old
|
||||
// samples were expired and removed from the Database, we can
|
||||
// still obtain the correct network usage.
|
||||
if (data.length == 0) {
|
||||
data.push({ rxBytes: cursor.value.rxTotalBytes,
|
||||
txBytes: cursor.value.txTotalBytes,
|
||||
date: new Date(cursor.value.timestamp + offset) });
|
||||
} else {
|
||||
data.push({ rxBytes: cursor.value.rxBytes,
|
||||
txBytes: cursor.value.txBytes,
|
||||
date: new Date(cursor.value.timestamp + offset) });
|
||||
}
|
||||
}
|
||||
cursor.continue();
|
||||
return;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче