This commit is contained in:
Wes Kocher 2015-10-14 15:02:05 -07:00
Родитель f8d9dac2f5 57f74f6d6c
Коммит 4376962c65
157 изменённых файлов: 1838 добавлений и 1184 удалений

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

@ -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;

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