зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team. a=merge
This commit is contained in:
Коммит
284bc45ed8
|
@ -6,14 +6,14 @@
|
|||
|
||||
GeckoSharedLibrary('AccessibleMarshal', linkage=None)
|
||||
|
||||
GENERATED_SOURCES += [
|
||||
'dlldata.c',
|
||||
'ISimpleDOMDocument_i.c',
|
||||
'ISimpleDOMDocument_p.c',
|
||||
'ISimpleDOMNode_i.c',
|
||||
'ISimpleDOMNode_p.c',
|
||||
'ISimpleDOMText_i.c',
|
||||
'ISimpleDOMText_p.c',
|
||||
SOURCES += [
|
||||
'!dlldata.c',
|
||||
'!ISimpleDOMDocument_i.c',
|
||||
'!ISimpleDOMDocument_p.c',
|
||||
'!ISimpleDOMNode_i.c',
|
||||
'!ISimpleDOMNode_p.c',
|
||||
'!ISimpleDOMText_i.c',
|
||||
'!ISimpleDOMText_p.c',
|
||||
]
|
||||
|
||||
DEFINES['REGISTER_PROXY_DLL'] = True
|
||||
|
|
|
@ -20,8 +20,8 @@ UNIFIED_SOURCES += [
|
|||
'xpcAccessibleValue.cpp',
|
||||
]
|
||||
|
||||
GENERATED_SOURCES += [
|
||||
'xpcAccEvents.cpp',
|
||||
SOURCES += [
|
||||
'!xpcAccEvents.cpp',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d31f6f08740a46e5315c9279b8f987c9d1fce486"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="04c307a8a8439adf38c0f14d065275f571a7b486"/>
|
||||
<!-- 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="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d31f6f08740a46e5315c9279b8f987c9d1fce486"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="04c307a8a8439adf38c0f14d065275f571a7b486"/>
|
||||
<!-- 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,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>
|
||||
|
|
|
@ -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="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d31f6f08740a46e5315c9279b8f987c9d1fce486"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="04c307a8a8439adf38c0f14d065275f571a7b486"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d31f6f08740a46e5315c9279b8f987c9d1fce486"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="04c307a8a8439adf38c0f14d065275f571a7b486"/>
|
||||
<!-- 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"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d31f6f08740a46e5315c9279b8f987c9d1fce486"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="04c307a8a8439adf38c0f14d065275f571a7b486"/>
|
||||
<!-- 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,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d31f6f08740a46e5315c9279b8f987c9d1fce486"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="04c307a8a8439adf38c0f14d065275f571a7b486"/>
|
||||
<!-- 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": "05380df3158fa39e1dde1687c0bf11a71f8c6868",
|
||||
"git_revision": "e7d268074ee3c9eeb191c2205c0e35992fb3915d",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "fc4f5dfe591a45cb03ae221489f41b56f38c883a",
|
||||
"revision": "f7c817ea239637d874d7099f2ccaafc6c3766389",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -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="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d31f6f08740a46e5315c9279b8f987c9d1fce486"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="04c307a8a8439adf38c0f14d065275f571a7b486"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="05380df3158fa39e1dde1687c0bf11a71f8c6868"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e7d268074ee3c9eeb191c2205c0e35992fb3915d"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<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="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d31f6f08740a46e5315c9279b8f987c9d1fce486"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="04c307a8a8439adf38c0f14d065275f571a7b486"/>
|
||||
<!-- 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"/>
|
||||
|
|
|
@ -820,7 +820,6 @@
|
|||
; [Personal Security Manager]
|
||||
;
|
||||
@BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
|
||||
@RESPATH@/components/pipboot.xpt
|
||||
@RESPATH@/components/pipnss.xpt
|
||||
@RESPATH@/components/pippki.xpt
|
||||
@BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@
|
||||
|
|
|
@ -1697,7 +1697,7 @@ pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
|
|||
pref("shumway.disabled", true);
|
||||
#else
|
||||
pref("shumway.disabled", false);
|
||||
pref("shumway.swf.whitelist", "http://g-ecx.images-amazon.com/*/AiryBasicRenderer*.swf,http://z-ecx.images-amazon.com/*/AiryFlashlsRenderer._TTW_.swf,http://ia.media-imdb.com/*/AiryFlashlsRenderer._TTW_.swf");
|
||||
pref("shumway.swf.whitelist", "http://www.areweflashyet.com/*.swf");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ var FullScreen = {
|
|||
break;
|
||||
}
|
||||
case "DOMFullscreen:NewOrigin": {
|
||||
this.showWarning(aMessage.data.origin);
|
||||
this.showWarning(aMessage.data.originNoSuffix);
|
||||
break;
|
||||
}
|
||||
case "DOMFullscreen:Exited": {
|
||||
|
|
|
@ -625,7 +625,7 @@ let DOMFullscreenHandler = {
|
|||
case "MozDOMFullscreen:NewOrigin": {
|
||||
this._fullscreenDoc = aEvent.target;
|
||||
sendAsyncMessage("DOMFullscreen:NewOrigin", {
|
||||
origin: this._fullscreenDoc.nodePrincipal.origin,
|
||||
originNoSuffix: this._fullscreenDoc.nodePrincipal.originNoSuffix,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -800,7 +800,6 @@
|
|||
#endif
|
||||
@RESPATH@/chrome/pippki@JAREXT@
|
||||
@RESPATH@/chrome/pippki.manifest
|
||||
@RESPATH@/components/pipboot.xpt
|
||||
@RESPATH@/components/pipnss.xpt
|
||||
@RESPATH@/components/pippki.xpt
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ SEARCH_PATHS = [
|
|||
'testing/web-platform',
|
||||
'testing/web-platform/harness',
|
||||
'testing/marionette/client',
|
||||
'testing/marionette/client/marionette/runner/mixins/browsermob-proxy-py',
|
||||
'testing/marionette/transport',
|
||||
'testing/marionette/driver',
|
||||
'testing/luciddream',
|
||||
|
|
|
@ -13,8 +13,8 @@ elif CONFIG['TARGET_CPU'].startswith('arm'):
|
|||
else:
|
||||
cpu = CONFIG['TARGET_CPU']
|
||||
|
||||
GENERATED_SOURCES += [
|
||||
"%s.c" % cpu,
|
||||
SOURCES += [
|
||||
"!%s.c" % cpu,
|
||||
]
|
||||
|
||||
NO_PGO = True
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
marionette_transport.pth:testing/marionette/transport
|
||||
marionette_driver.pth:testing/marionette/driver
|
||||
browsermobproxy.pth:testing/marionette/client/marionette/runner/mixins/browsermob-proxy-py
|
||||
marionette.pth:testing/marionette/client
|
||||
blessings.pth:python/blessings
|
||||
configobj.pth:python/configobj
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "BluetoothDaemonConnector.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/un.h>
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
*/
|
||||
|
||||
#include "BluetoothUnixSocketConnector.h"
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/l2cap.h>
|
||||
#include <bluetooth/rfcomm.h>
|
||||
#include <bluetooth/sco.h>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
|
||||
#define mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include "BluetoothCommon.h"
|
||||
#include "mozilla/ipc/UnixSocketConnector.h"
|
||||
|
||||
|
|
|
@ -965,7 +965,7 @@ BrowserElementChild.prototype = {
|
|||
|
||||
_mozFullscreenOriginChange: function(e) {
|
||||
sendAsyncMsg("fullscreen-origin-change", {
|
||||
origin: e.target.nodePrincipal.origin
|
||||
originNoSuffix: e.target.nodePrincipal.originNoSuffix
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -946,7 +946,7 @@ BrowserElementParent.prototype = {
|
|||
|
||||
_fullscreenOriginChange: function(data) {
|
||||
Services.obs.notifyObservers(
|
||||
this._frameElement, "fullscreen-origin-change", data.json.origin);
|
||||
this._frameElement, "fullscreen-origin-change", data.json.originNoSuffix);
|
||||
},
|
||||
|
||||
_exitedDomFullscreen: function(data) {
|
||||
|
|
|
@ -6,6 +6,7 @@ include protocol PCache;
|
|||
include protocol PCachePushStream;
|
||||
include protocol PCacheStreamControl;
|
||||
include InputStreamParams;
|
||||
include ChannelInfo;
|
||||
|
||||
using HeadersGuardEnum from "mozilla/dom/cache/IPCUtils.h";
|
||||
using RequestCredentials from "mozilla/dom/cache/IPCUtils.h";
|
||||
|
@ -81,7 +82,7 @@ struct CacheResponse
|
|||
HeadersEntry[] headers;
|
||||
HeadersGuardEnum headersGuard;
|
||||
CacheReadStreamOrVoid body;
|
||||
nsCString securityInfo;
|
||||
IPCChannelInfo channelInfo;
|
||||
};
|
||||
|
||||
union CacheResponseOrVoid
|
||||
|
|
|
@ -175,8 +175,8 @@ static nsresult DeleteEntries(mozIStorageConnection* aConn,
|
|||
nsTArray<nsID>& aDeletedBodyIdListOut,
|
||||
nsTArray<IdCount>& aDeletedSecurityIdListOut,
|
||||
uint32_t aPos=0, int32_t aLen=-1);
|
||||
static nsresult InsertSecurity(mozIStorageConnection* aConn,
|
||||
const nsACString& aData, int32_t *aIdOut);
|
||||
static nsresult InsertSecurityInfo(mozIStorageConnection* aConn,
|
||||
const nsACString& aData, int32_t *aIdOut);
|
||||
static nsresult DeleteSecurityInfo(mozIStorageConnection* aConn, int32_t aId,
|
||||
int32_t aCount);
|
||||
static nsresult DeleteSecurityInfoList(mozIStorageConnection* aConn,
|
||||
|
@ -1194,8 +1194,8 @@ DeleteEntries(mozIStorageConnection* aConn,
|
|||
}
|
||||
|
||||
nsresult
|
||||
InsertSecurity(mozIStorageConnection* aConn, const nsACString& aData,
|
||||
int32_t *aIdOut)
|
||||
InsertSecurityInfo(mozIStorageConnection* aConn, const nsACString& aData,
|
||||
int32_t *aIdOut)
|
||||
{
|
||||
MOZ_ASSERT(aConn);
|
||||
MOZ_ASSERT(aIdOut);
|
||||
|
@ -1394,8 +1394,10 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
nsresult rv = NS_OK;
|
||||
int32_t securityId = -1;
|
||||
|
||||
if (!aResponse.securityInfo().IsEmpty()) {
|
||||
rv = InsertSecurity(aConn, aResponse.securityInfo(), &securityId);
|
||||
if (!aResponse.channelInfo().securityInfo().IsEmpty()) {
|
||||
rv = InsertSecurityInfo(aConn,
|
||||
aResponse.channelInfo().securityInfo(),
|
||||
&securityId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
}
|
||||
|
||||
|
@ -1511,7 +1513,7 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
rv = BindId(state, NS_LITERAL_CSTRING("response_body_id"), aResponseBodyId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
if (aResponse.securityInfo().IsEmpty()) {
|
||||
if (aResponse.channelInfo().securityInfo().IsEmpty()) {
|
||||
rv = state->BindNullByName(NS_LITERAL_CSTRING("response_security_info_id"));
|
||||
} else {
|
||||
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_security_info_id"),
|
||||
|
@ -1657,7 +1659,7 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
|||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
}
|
||||
|
||||
rv = state->GetBlobAsUTF8String(6, aSavedResponseOut->mValue.securityInfo());
|
||||
rv = state->GetBlobAsUTF8String(6, aSavedResponseOut->mValue.channelInfo().securityInfo());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
|
|
|
@ -224,7 +224,7 @@ TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut,
|
|||
}
|
||||
ToHeadersEntryList(aOut.headers(), headers);
|
||||
aOut.headersGuard() = headers->Guard();
|
||||
aOut.securityInfo() = aIn.GetSecurityInfo();
|
||||
aOut.channelInfo() = aIn.GetChannelInfo().AsIPCChannelInfo();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -290,7 +290,7 @@ TypeUtils::ToResponse(const CacheResponse& aIn)
|
|||
ir->Headers()->Fill(*internalHeaders, result);
|
||||
MOZ_ASSERT(!result.Failed());
|
||||
|
||||
ir->SetSecurityInfo(aIn.securityInfo());
|
||||
ir->InitChannelInfo(aIn.channelInfo());
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body());
|
||||
ir->SetBody(stream);
|
||||
|
|
|
@ -128,6 +128,14 @@ WebGLContext::InitWebGL2()
|
|||
missingList.push_back(kRequiredFeatures[i]);
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// On OSX, GL core profile is used. This requires texture swizzle
|
||||
// support to emulate legacy texture formats: ALPHA, LUMINANCE,
|
||||
// and LUMINANCE_ALPHA.
|
||||
if (!gl->IsSupported(gl::GLFeature::texture_swizzle))
|
||||
missingList.push_back(gl::GLFeature::texture_swizzle);
|
||||
#endif
|
||||
|
||||
if (missingList.size()) {
|
||||
nsAutoCString exts;
|
||||
for (auto itr = missingList.begin(); itr != missingList.end(); ++itr) {
|
||||
|
|
|
@ -3198,6 +3198,9 @@ GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
|
|||
|
||||
gl->fTexImage2D(texImageTarget.get(), level, driverInternalFormat, width, height, border, driverFormat, driverType, data);
|
||||
|
||||
if (effectiveInternalFormat != driverInternalFormat)
|
||||
SetLegacyTextureSwizzle(gl, texImageTarget.get(), internalformat.get());
|
||||
|
||||
GLenum error = LOCAL_GL_NO_ERROR;
|
||||
if (sizeMayChange) {
|
||||
error = GetAndFlushUnderlyingGLErrors();
|
||||
|
|
|
@ -249,7 +249,7 @@ DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
|
|||
// in some cases we must pass a different value. On ES, they are equal by definition
|
||||
// as it is an error to pass internalformat!=format.
|
||||
GLenum driverInternalFormat = driverFormat;
|
||||
if (!gl->IsGLES()) {
|
||||
if (gl->IsCompatibilityProfile()) {
|
||||
// Cases where desktop OpenGL requires a tweak to 'format'
|
||||
if (driverFormat == LOCAL_GL_SRGB)
|
||||
driverFormat = LOCAL_GL_RGB;
|
||||
|
@ -284,11 +284,66 @@ DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
|
|||
}
|
||||
}
|
||||
|
||||
// OpenGL core profile removed texture formats ALPHA, LUMINANCE and LUMINANCE_ALPHA
|
||||
if (gl->IsCoreProfile()) {
|
||||
switch (driverFormat) {
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
driverInternalFormat = driverFormat = LOCAL_GL_RED;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
driverInternalFormat = driverFormat = LOCAL_GL_RG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*out_driverInternalFormat = driverInternalFormat;
|
||||
*out_driverFormat = driverFormat;
|
||||
*out_driverType = driverType;
|
||||
}
|
||||
|
||||
// Map R to A
|
||||
static const GLenum kLegacyAlphaSwizzle[4] = {
|
||||
LOCAL_GL_ZERO, LOCAL_GL_ZERO, LOCAL_GL_ZERO, LOCAL_GL_RED
|
||||
};
|
||||
// Map R to RGB
|
||||
static const GLenum kLegacyLuminanceSwizzle[4] = {
|
||||
LOCAL_GL_RED, LOCAL_GL_RED, LOCAL_GL_RED, LOCAL_GL_ONE
|
||||
};
|
||||
// Map R to RGB, G to A
|
||||
static const GLenum kLegacyLuminanceAlphaSwizzle[4] = {
|
||||
LOCAL_GL_RED, LOCAL_GL_RED, LOCAL_GL_RED, LOCAL_GL_GREEN
|
||||
};
|
||||
|
||||
void
|
||||
SetLegacyTextureSwizzle(gl::GLContext* gl, GLenum target, GLenum internalformat)
|
||||
{
|
||||
if (!gl->IsCoreProfile())
|
||||
return;
|
||||
|
||||
/* Only support swizzling on core profiles. */
|
||||
// Bug 1159117: Fix this.
|
||||
// MOZ_RELEASE_ASSERT(gl->IsSupported(gl::GLFeature::texture_swizzle));
|
||||
|
||||
switch (internalformat) {
|
||||
case LOCAL_GL_ALPHA:
|
||||
gl->fTexParameteriv(target, LOCAL_GL_TEXTURE_SWIZZLE_RGBA,
|
||||
(GLint*) kLegacyAlphaSwizzle);
|
||||
break;
|
||||
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
gl->fTexParameteriv(target, LOCAL_GL_TEXTURE_SWIZZLE_RGBA,
|
||||
(GLint*) kLegacyLuminanceSwizzle);
|
||||
break;
|
||||
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
gl->fTexParameteriv(target, LOCAL_GL_TEXTURE_SWIZZLE_RGBA,
|
||||
(GLint*) kLegacyLuminanceAlphaSwizzle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bits per texel for format & type combination.
|
||||
* Assumes that format & type are a valid combination as checked with
|
||||
|
|
|
@ -38,6 +38,8 @@ TexType TypeFromInternalFormat(TexInternalFormat internalformat);
|
|||
TexInternalFormat
|
||||
UnsizedInternalFormatFromInternalFormat(TexInternalFormat internalformat);
|
||||
|
||||
void SetLegacyTextureSwizzle(gl::GLContext* gl, GLenum target, GLenum internalformat);
|
||||
|
||||
size_t GetBitsPerTexel(TexInternalFormat effectiveinternalformat);
|
||||
|
||||
// For use with the different texture calls, i.e.
|
||||
|
|
|
@ -38,3 +38,5 @@ skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests
|
|||
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
|
||||
[webgl-mochitest/test_webgl2_invalidate_framebuffer.html]
|
||||
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
|
||||
[webgl-mochitest/test_webgl2_alpha_luminance.html]
|
||||
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>WebGL2 test: Alpha and Luminance Textures</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<script src="driver-info.js"></script>
|
||||
<script src="webgl-util.js"></script>
|
||||
<script id="vs" type="x-shader/x-vertex">
|
||||
#version 300 es
|
||||
in vec2 aTexCoord;
|
||||
out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
vec2 pos = vec2(2.0)*aTexCoord - vec2(1.0);
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
vTexCoord = aTexCoord;
|
||||
}
|
||||
</script>
|
||||
<script id="fs-alpha" type="x-shader/x-fragment">
|
||||
#version 300 es
|
||||
precision mediump float;
|
||||
in vec2 vTexCoord;
|
||||
|
||||
out vec4 oFragColor;
|
||||
|
||||
uniform sampler2D uTex;
|
||||
|
||||
bool compare(in vec4 test, in float ref) {
|
||||
float lo = (ref - 0.1) / 255.0;
|
||||
float hi = (ref + 0.1) / 255.0;
|
||||
|
||||
return (test.rgb == vec3(0) &&
|
||||
lo < test.a && test.a < hi);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 tex = texture(uTex, vTexCoord);
|
||||
|
||||
oFragColor = compare(tex, 128) ? vec4(0.0, 1.0, 0.0, 1.0)
|
||||
: vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script id="fs-lum" type="x-shader/x-fragment">
|
||||
#version 300 es
|
||||
precision mediump float;
|
||||
in vec2 vTexCoord;
|
||||
|
||||
out vec4 oFragColor;
|
||||
|
||||
uniform sampler2D uTex;
|
||||
|
||||
bool compare(vec4 test, float ref) {
|
||||
float lo = (ref - 0.1) / 255.0;
|
||||
float hi = (ref + 0.1) / 255.0;
|
||||
|
||||
return (lo < test.r && test.r < hi &&
|
||||
lo < test.g && test.g < hi &&
|
||||
lo < test.b && test.b < hi &&
|
||||
test.a == 1);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 tex = texture(uTex, vTexCoord);
|
||||
|
||||
oFragColor = compare(tex, 128) ? vec4(0.0, 1.0, 0.0, 1.0)
|
||||
: vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script id="fs-lumalpha" type="x-shader/x-fragment">
|
||||
#version 300 es
|
||||
precision mediump float;
|
||||
in vec2 vTexCoord;
|
||||
|
||||
out vec4 oFragColor;
|
||||
|
||||
uniform sampler2D uTex;
|
||||
|
||||
bool compare(in vec4 test, in float ref) {
|
||||
float lo = (ref - 0.1) / 255.0;
|
||||
float hi = (ref + 0.1) / 255.0;
|
||||
|
||||
return (lo < test.r && test.r < hi &&
|
||||
lo < test.g && test.g < hi &&
|
||||
lo < test.b && test.b < hi &&
|
||||
lo < test.a && test.a < hi);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 tex = texture(uTex, vTexCoord);
|
||||
|
||||
oFragColor = compare(tex, 128) ? vec4(0.0, 1.0, 0.0, 1.0)
|
||||
: vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
<body>
|
||||
<canvas id="c" width="32" height="32"></canvas>
|
||||
<script>
|
||||
WebGLUtil.withWebGL2('c', function(gl) {
|
||||
|
||||
function testPixel(x, y, refData, func, infoString) {
|
||||
var pixel = new Uint8Array(4);
|
||||
gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
|
||||
|
||||
var pixelMatches = (pixel[0] == refData[0] &&
|
||||
pixel[1] == refData[1] &&
|
||||
pixel[2] == refData[2] &&
|
||||
pixel[3] == refData[3]);
|
||||
func(pixelMatches, infoString);
|
||||
}
|
||||
|
||||
function testTexture(details) {
|
||||
var prog = WebGLUtil.createProgramByIds(gl, 'vs', details.frag);
|
||||
if (!prog) {
|
||||
ok(false, 'Program linking should succeed.');
|
||||
return false;
|
||||
}
|
||||
|
||||
prog.aTexCoord = gl.getAttribLocation(prog, "aTexCoord");
|
||||
ok(prog.aTexCoord >= 0, '`aTexCoord` should be valid.');
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, details.format, 2, 2, 0,
|
||||
details.format, gl.UNSIGNED_BYTE, details.pixels);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
|
||||
gl.useProgram(prog);
|
||||
gl.vertexAttribPointer(prog.aTexCoord, 2, gl.FLOAT, false, 0, 0);
|
||||
gl.enableVertexAttribArray(prog.aTexCoord);
|
||||
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
testPixel(0, 0, [0, 255, 0, 255], ok, 'Should be green after drawing.');
|
||||
return true;
|
||||
}
|
||||
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
|
||||
var vertData = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertData);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0, 0, 1, 0, 0, 1, 1, 1 ]), gl.STATIC_DRAW);
|
||||
|
||||
gl.clearColor(0, 0, 1, 1);
|
||||
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
||||
|
||||
var details = [
|
||||
{ frag: 'fs-alpha', format: gl.ALPHA, pixels: new Uint8Array([ 128, 128, 128, 128 ]) },
|
||||
{ frag: 'fs-lum', format: gl.LUMINANCE, pixels: new Uint8Array([ 128, 128, 128, 128 ]) },
|
||||
{ frag: 'fs-lumalpha', format: gl.LUMINANCE_ALPHA, pixels: new Uint8Array([ 128, 128, 128, 128, 128, 128, 128, 128 ]) }
|
||||
];
|
||||
|
||||
for (var i = 0; i < details.length; i++) {
|
||||
if (!testTexture(details[i])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ok(true, 'Test complete.');
|
||||
}, function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
|
@ -26,7 +26,7 @@ include('/ipc/chromium/chromium-config.mozbuild')
|
|||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/security/manager/ssl/src',
|
||||
'/security/manager/ssl',
|
||||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ChannelInfo.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsSerializationHelper.h"
|
||||
#include "mozilla/net/HttpBaseChannel.h"
|
||||
#include "mozilla/ipc/ChannelInfo.h"
|
||||
#include "nsIJARChannel.h"
|
||||
#include "nsJARChannel.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
void
|
||||
ChannelInfo::InitFromChannel(nsIChannel* aChannel)
|
||||
{
|
||||
MOZ_ASSERT(!mInited, "Cannot initialize the object twice");
|
||||
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
aChannel->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
if (securityInfo) {
|
||||
SetSecurityInfo(securityInfo);
|
||||
}
|
||||
|
||||
mInited = true;
|
||||
}
|
||||
|
||||
void
|
||||
ChannelInfo::InitFromIPCChannelInfo(const ipc::IPCChannelInfo& aChannelInfo)
|
||||
{
|
||||
MOZ_ASSERT(!mInited, "Cannot initialize the object twice");
|
||||
|
||||
mSecurityInfo = aChannelInfo.securityInfo();
|
||||
|
||||
mInited = true;
|
||||
}
|
||||
|
||||
void
|
||||
ChannelInfo::SetSecurityInfo(nsISupports* aSecurityInfo)
|
||||
{
|
||||
MOZ_ASSERT(mSecurityInfo.IsEmpty(), "security info should only be set once");
|
||||
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(aSecurityInfo);
|
||||
if (!serializable) {
|
||||
NS_WARNING("A non-serializable object was passed to InternalResponse::SetSecurityInfo");
|
||||
return;
|
||||
}
|
||||
NS_SerializeToString(serializable, mSecurityInfo);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ChannelInfo::ResurrectInfoOnChannel(nsIChannel* aChannel)
|
||||
{
|
||||
MOZ_ASSERT(mInited);
|
||||
|
||||
if (!mSecurityInfo.IsEmpty()) {
|
||||
nsCOMPtr<nsISupports> infoObj;
|
||||
nsresult rv = NS_DeserializeObject(mSecurityInfo, getter_AddRefs(infoObj));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel =
|
||||
do_QueryInterface(aChannel);
|
||||
if (httpChannel) {
|
||||
net::HttpBaseChannel* httpBaseChannel =
|
||||
static_cast<net::HttpBaseChannel*>(httpChannel.get());
|
||||
rv = httpBaseChannel->OverrideSecurityInfo(infoObj);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIJARChannel> jarChannel =
|
||||
do_QueryInterface(aChannel);
|
||||
if (NS_WARN_IF(!jarChannel)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
static_cast<nsJARChannel*>(jarChannel.get())->
|
||||
OverrideSecurityInfo(infoObj);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ipc::IPCChannelInfo
|
||||
ChannelInfo::AsIPCChannelInfo() const
|
||||
{
|
||||
// This may be called when mInited is false, for example if we try to store
|
||||
// a synthesized Response object into the Cache. Uninitialized and empty
|
||||
// ChannelInfo objects are indistinguishable at the IPC level, so this is
|
||||
// fine.
|
||||
|
||||
IPCChannelInfo ipcInfo;
|
||||
|
||||
ipcInfo.securityInfo() = mSecurityInfo;
|
||||
|
||||
return ipcInfo;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ChannelInfo_h
|
||||
#define mozilla_dom_ChannelInfo_h
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
class nsIChannel;
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class IPCChannelInfo;
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
|
||||
// This class represents the information related to a Response that we
|
||||
// retrieve from the corresponding channel that is used to perform the fetch.
|
||||
//
|
||||
// When adding new members to this object, the following code needs to be
|
||||
// updated:
|
||||
// * IPCChannelInfo
|
||||
// * InitFromChannel and InitFromIPCChannelInfo members
|
||||
// * ResurrectInfoOnChannel member
|
||||
// * AsIPCChannelInfo member
|
||||
// * constructors and assignment operators for this class.
|
||||
// * DOM Cache schema code (in dom/cache/DBSchema.cpp) to ensure that the newly
|
||||
// added member is saved into the DB and loaded from it properly.
|
||||
//
|
||||
// Care must be taken when initializing this object, or when calling
|
||||
// ResurrectInfoOnChannel(). This object cannot be initialized twice, and
|
||||
// ResurrectInfoOnChannel() cannot be called on it before it has been
|
||||
// initialized. There are assertions ensuring these invariants.
|
||||
class ChannelInfo final
|
||||
{
|
||||
public:
|
||||
typedef mozilla::ipc::IPCChannelInfo IPCChannelInfo;
|
||||
|
||||
ChannelInfo()
|
||||
: mInited(false)
|
||||
{
|
||||
}
|
||||
|
||||
ChannelInfo(const ChannelInfo& aRHS)
|
||||
: mSecurityInfo(aRHS.mSecurityInfo)
|
||||
, mInited(aRHS.mInited)
|
||||
{
|
||||
}
|
||||
|
||||
ChannelInfo&
|
||||
operator=(const ChannelInfo& aRHS)
|
||||
{
|
||||
mSecurityInfo = aRHS.mSecurityInfo;
|
||||
mInited = aRHS.mInited;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void InitFromChannel(nsIChannel* aChannel);
|
||||
void InitFromIPCChannelInfo(const IPCChannelInfo& aChannelInfo);
|
||||
|
||||
// This restores every possible information stored from a previous channel
|
||||
// object on a new one.
|
||||
nsresult ResurrectInfoOnChannel(nsIChannel* aChannel);
|
||||
|
||||
bool IsInitialized() const
|
||||
{
|
||||
return mInited;
|
||||
}
|
||||
|
||||
IPCChannelInfo AsIPCChannelInfo() const;
|
||||
|
||||
private:
|
||||
void SetSecurityInfo(nsISupports* aSecurityInfo);
|
||||
|
||||
private:
|
||||
nsCString mSecurityInfo;
|
||||
bool mInited;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ChannelInfo_h
|
|
@ -0,0 +1,14 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
struct IPCChannelInfo
|
||||
{
|
||||
nsCString securityInfo;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
|
@ -706,12 +706,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
|||
}
|
||||
response->SetBody(pipeInputStream);
|
||||
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
rv = channel->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
if (securityInfo) {
|
||||
response->SetSecurityInfo(securityInfo);
|
||||
}
|
||||
response->InitChannelInfo(channel);
|
||||
|
||||
// Resolves fetch() promise which may trigger code running in a worker. Make
|
||||
// sure the Response is fully initialized before calling this.
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsSerializationHelper.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -75,24 +74,5 @@ InternalResponse::CORSResponse()
|
|||
return cors.forget();
|
||||
}
|
||||
|
||||
void
|
||||
InternalResponse::SetSecurityInfo(nsISupports* aSecurityInfo)
|
||||
{
|
||||
MOZ_ASSERT(mSecurityInfo.IsEmpty(), "security info should only be set once");
|
||||
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(aSecurityInfo);
|
||||
if (!serializable) {
|
||||
NS_WARNING("A non-serializable object was passed to InternalResponse::SetSecurityInfo");
|
||||
return;
|
||||
}
|
||||
NS_SerializeToString(serializable, mSecurityInfo);
|
||||
}
|
||||
|
||||
void
|
||||
InternalResponse::SetSecurityInfo(const nsCString& aSecurityInfo)
|
||||
{
|
||||
MOZ_ASSERT(mSecurityInfo.IsEmpty(), "security info should only be set once");
|
||||
mSecurityInfo = aSecurityInfo;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "nsISupportsImpl.h"
|
||||
|
||||
#include "mozilla/dom/ResponseBinding.h"
|
||||
#include "mozilla/dom/ChannelInfo.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -48,7 +49,7 @@ public:
|
|||
response->mTerminationReason = mTerminationReason;
|
||||
response->mURL = mURL;
|
||||
response->mFinalURL = mFinalURL;
|
||||
response->mSecurityInfo = mSecurityInfo;
|
||||
response->mChannelInfo = mChannelInfo;
|
||||
response->mWrappedResponse = this;
|
||||
return response.forget();
|
||||
}
|
||||
|
@ -156,17 +157,29 @@ public:
|
|||
mBody = aBody;
|
||||
}
|
||||
|
||||
const nsCString&
|
||||
GetSecurityInfo() const
|
||||
void
|
||||
InitChannelInfo(nsIChannel* aChannel)
|
||||
{
|
||||
return mSecurityInfo;
|
||||
mChannelInfo.InitFromChannel(aChannel);
|
||||
}
|
||||
|
||||
void
|
||||
SetSecurityInfo(nsISupports* aSecurityInfo);
|
||||
InitChannelInfo(const mozilla::ipc::IPCChannelInfo& aChannelInfo)
|
||||
{
|
||||
mChannelInfo.InitFromIPCChannelInfo(aChannelInfo);
|
||||
}
|
||||
|
||||
void
|
||||
SetSecurityInfo(const nsCString& aSecurityInfo);
|
||||
InitChannelInfo(const ChannelInfo& aChannelInfo)
|
||||
{
|
||||
mChannelInfo = aChannelInfo;
|
||||
}
|
||||
|
||||
const ChannelInfo&
|
||||
GetChannelInfo() const
|
||||
{
|
||||
return mChannelInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
~InternalResponse()
|
||||
|
@ -185,7 +198,7 @@ private:
|
|||
copy->mTerminationReason = mTerminationReason;
|
||||
copy->mURL = mURL;
|
||||
copy->mFinalURL = mFinalURL;
|
||||
copy->mSecurityInfo = mSecurityInfo;
|
||||
copy->mChannelInfo = mChannelInfo;
|
||||
return copy.forget();
|
||||
}
|
||||
|
||||
|
@ -197,7 +210,7 @@ private:
|
|||
const nsCString mStatusText;
|
||||
nsRefPtr<InternalHeaders> mHeaders;
|
||||
nsCOMPtr<nsIInputStream> mBody;
|
||||
nsCString mSecurityInfo;
|
||||
ChannelInfo mChannelInfo;
|
||||
|
||||
// For filtered responses.
|
||||
// Cache, and SW interception should always serialize/access the underlying
|
||||
|
|
|
@ -78,10 +78,16 @@ public:
|
|||
return mInternalResponse->Headers();
|
||||
}
|
||||
|
||||
const nsCString&
|
||||
GetSecurityInfo() const
|
||||
void
|
||||
InitChannelInfo(nsIChannel* aChannel)
|
||||
{
|
||||
return mInternalResponse->GetSecurityInfo();
|
||||
mInternalResponse->InitChannelInfo(aChannel);
|
||||
}
|
||||
|
||||
const ChannelInfo&
|
||||
GetChannelInfo() const
|
||||
{
|
||||
return mInternalResponse->GetChannelInfo();
|
||||
}
|
||||
|
||||
Headers* Headers_();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'ChannelInfo.h',
|
||||
'Fetch.h',
|
||||
'FetchDriver.h',
|
||||
'Headers.h',
|
||||
|
@ -16,6 +17,7 @@ EXPORTS.mozilla.dom += [
|
|||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'ChannelInfo.cpp',
|
||||
'Fetch.cpp',
|
||||
'FetchDriver.cpp',
|
||||
'Headers.cpp',
|
||||
|
@ -26,11 +28,23 @@ UNIFIED_SOURCES += [
|
|||
'Response.cpp',
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'ChannelInfo.ipdlh',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../workers',
|
||||
# For nsJARChannel.h
|
||||
'/modules/libjar',
|
||||
# For HttpBaseChannel.h dependencies
|
||||
'/netwerk/base',
|
||||
# For nsDataHandler.h
|
||||
'/netwerk/protocol/data',
|
||||
# For HttpBaseChannel.h
|
||||
'/netwerk/protocol/http',
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
|
|
@ -2791,12 +2791,6 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
|
|||
mDecoder->SetMinimizePrerollUntilPlaybackStarts();
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
|
||||
OutputMediaStream* ms = &mOutputStreams[i];
|
||||
aDecoder->AddOutputStream(ms->mStream->GetStream()->AsProcessedStream(),
|
||||
ms->mFinishWhenEnded);
|
||||
}
|
||||
|
||||
// Update decoder principal before we start decoding, since it
|
||||
// can affect how we feed data to MediaStreams
|
||||
NotifyDecoderPrincipalChanged();
|
||||
|
@ -2808,6 +2802,12 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
|
|||
return rv;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
|
||||
OutputMediaStream* ms = &mOutputStreams[i];
|
||||
aDecoder->AddOutputStream(ms->mStream->GetStream()->AsProcessedStream(),
|
||||
ms->mFinishWhenEnded);
|
||||
}
|
||||
|
||||
#ifdef MOZ_EME
|
||||
if (mMediaKeys) {
|
||||
mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy());
|
||||
|
|
|
@ -155,26 +155,6 @@ parent:
|
|||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (OwningSerializedStructuredCloneBuffer[] retval);
|
||||
|
||||
/**
|
||||
* The IME sequence number (seqno) parameter is used to make sure
|
||||
* that a notification is discarded if it arrives at the chrome process
|
||||
* too late. If the notification is late and we accept it, we will have
|
||||
* an out-of-date view of the content process, which means events that we
|
||||
* dispatch based on this out-of-date view will be wrong also.
|
||||
* (see Bug 599550 and Bug 591047 comments 44, 50, and 54)
|
||||
*
|
||||
* Chrome increments seqno and includes it in each IME event sent to
|
||||
* content, and content sends its current seqno back to chrome with each
|
||||
* notification. A notification is up-to-date only if the content
|
||||
* seqno is the same as the current chrome seqno, meaning no additional
|
||||
* event was sent to content before the notification was received
|
||||
*
|
||||
* On blur, chrome returns the current seqno to content, and content
|
||||
* uses it to discard subsequent events until the content seqno and
|
||||
* chrome seqno-on-blur match again. These events, meant for the blurred
|
||||
* textfield, are discarded to prevent events going to the wrong target
|
||||
*/
|
||||
|
||||
/**
|
||||
* Notifies chrome that there is a focus change involving an editable
|
||||
* object (input, textarea, document, contentEditable. etc.)
|
||||
|
@ -182,10 +162,9 @@ parent:
|
|||
* focus PR_TRUE if editable object is receiving focus
|
||||
* PR_FALSE if losing focus
|
||||
* preference Native widget preference for IME updates
|
||||
* seqno Current seqno value on the chrome side
|
||||
*/
|
||||
prio(urgent) sync NotifyIMEFocus(bool focus)
|
||||
returns (nsIMEUpdatePreference preference, uint32_t seqno);
|
||||
returns (nsIMEUpdatePreference preference);
|
||||
|
||||
/**
|
||||
* Notifies chrome that there has been a change in text content
|
||||
|
@ -221,13 +200,12 @@ parent:
|
|||
* Notifies chrome that there has been a change in selection
|
||||
* Only called when NotifyIMEFocus returns PR_TRUE for mWantUpdates
|
||||
*
|
||||
* seqno Current seqno value on the content side
|
||||
* anchor Offset where the selection started
|
||||
* focus Offset where the caret is
|
||||
* writingMode CSS writing-mode in effect at the focus
|
||||
* causedByComposition true if the change is caused by composition
|
||||
*/
|
||||
prio(urgent) async NotifyIMESelection(uint32_t seqno, uint32_t anchor,
|
||||
prio(urgent) async NotifyIMESelection(uint32_t anchor,
|
||||
uint32_t focus,
|
||||
WritingMode writingMode,
|
||||
bool causedByComposition);
|
||||
|
|
|
@ -143,6 +143,19 @@ private:
|
|||
TabChild *mTabChild;
|
||||
};
|
||||
|
||||
static bool
|
||||
UsingCompositorLRU()
|
||||
{
|
||||
static bool sHavePrefs = false;
|
||||
static uint32_t sCompositorLRUSize = 0;
|
||||
if (!sHavePrefs) {
|
||||
sHavePrefs = true;
|
||||
Preferences::AddUintVarCache(&sCompositorLRUSize,
|
||||
"layers.compositor-lru-size", 0);
|
||||
}
|
||||
return sCompositorLRUSize != 0;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(TabChild::DelayedFireContextMenuEvent,
|
||||
nsITimerCallback)
|
||||
|
||||
|
@ -2987,7 +3000,9 @@ void
|
|||
TabChild::MakeVisible()
|
||||
{
|
||||
CompositorChild* compositor = CompositorChild::Get();
|
||||
compositor->SendNotifyVisible(mLayersId);
|
||||
if (UsingCompositorLRU()) {
|
||||
compositor->SendNotifyVisible(mLayersId);
|
||||
}
|
||||
|
||||
if (mWidget) {
|
||||
mWidget->Show(true);
|
||||
|
@ -2998,7 +3013,14 @@ void
|
|||
TabChild::MakeHidden()
|
||||
{
|
||||
CompositorChild* compositor = CompositorChild::Get();
|
||||
compositor->SendNotifyHidden(mLayersId);
|
||||
if (UsingCompositorLRU()) {
|
||||
compositor->SendNotifyHidden(mLayersId);
|
||||
} else {
|
||||
// Clear cached resources directly. This avoids one extra IPC
|
||||
// round-trip from CompositorChild to CompositorParent when
|
||||
// CompositorLRU is not used.
|
||||
compositor->RecvClearCachedResources(mLayersId);
|
||||
}
|
||||
|
||||
if (mWidget) {
|
||||
mWidget->Show(false);
|
||||
|
|
|
@ -264,7 +264,6 @@ TabParent::TabParent(nsIContentParent* aManager,
|
|||
, mIMECompositionEnding(false)
|
||||
, mIMEEventCountAfterEnding(0)
|
||||
, mIMECompositionStart(0)
|
||||
, mIMESeqno(0)
|
||||
, mIMECompositionRectOffset(0)
|
||||
, mRect(0, 0, 0, 0)
|
||||
, mDimensions(0, 0)
|
||||
|
@ -1847,11 +1846,8 @@ TabParent::RecvHideTooltip()
|
|||
|
||||
bool
|
||||
TabParent::RecvNotifyIMEFocus(const bool& aFocus,
|
||||
nsIMEUpdatePreference* aPreference,
|
||||
uint32_t* aSeqno)
|
||||
nsIMEUpdatePreference* aPreference)
|
||||
{
|
||||
*aSeqno = mIMESeqno;
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget) {
|
||||
*aPreference = nsIMEUpdatePreference();
|
||||
|
@ -1922,8 +1918,7 @@ TabParent::RecvNotifyIMESelectedCompositionRect(
|
|||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvNotifyIMESelection(const uint32_t& aSeqno,
|
||||
const uint32_t& aAnchor,
|
||||
TabParent::RecvNotifyIMESelection(const uint32_t& aAnchor,
|
||||
const uint32_t& aFocus,
|
||||
const mozilla::WritingMode& aWritingMode,
|
||||
const bool& aCausedByComposition)
|
||||
|
@ -1932,29 +1927,27 @@ TabParent::RecvNotifyIMESelection(const uint32_t& aSeqno,
|
|||
if (!widget)
|
||||
return true;
|
||||
|
||||
if (aSeqno == mIMESeqno) {
|
||||
mIMESelectionAnchor = aAnchor;
|
||||
mIMESelectionFocus = aFocus;
|
||||
mWritingMode = aWritingMode;
|
||||
const nsIMEUpdatePreference updatePreference =
|
||||
widget->GetIMEUpdatePreference();
|
||||
if (updatePreference.WantSelectionChange() &&
|
||||
(updatePreference.WantChangesCausedByComposition() ||
|
||||
!aCausedByComposition)) {
|
||||
IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
|
||||
notification.mSelectionChangeData.mOffset =
|
||||
std::min(mIMESelectionAnchor, mIMESelectionFocus);
|
||||
notification.mSelectionChangeData.mLength =
|
||||
mIMESelectionAnchor > mIMESelectionFocus ?
|
||||
mIMESelectionAnchor - mIMESelectionFocus :
|
||||
mIMESelectionFocus - mIMESelectionAnchor;
|
||||
notification.mSelectionChangeData.mReversed =
|
||||
mIMESelectionFocus < mIMESelectionAnchor;
|
||||
notification.mSelectionChangeData.SetWritingMode(mWritingMode);
|
||||
notification.mSelectionChangeData.mCausedByComposition =
|
||||
aCausedByComposition;
|
||||
widget->NotifyIME(notification);
|
||||
}
|
||||
mIMESelectionAnchor = aAnchor;
|
||||
mIMESelectionFocus = aFocus;
|
||||
mWritingMode = aWritingMode;
|
||||
const nsIMEUpdatePreference updatePreference =
|
||||
widget->GetIMEUpdatePreference();
|
||||
if (updatePreference.WantSelectionChange() &&
|
||||
(updatePreference.WantChangesCausedByComposition() ||
|
||||
!aCausedByComposition)) {
|
||||
IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
|
||||
notification.mSelectionChangeData.mOffset =
|
||||
std::min(mIMESelectionAnchor, mIMESelectionFocus);
|
||||
notification.mSelectionChangeData.mLength =
|
||||
mIMESelectionAnchor > mIMESelectionFocus ?
|
||||
mIMESelectionAnchor - mIMESelectionFocus :
|
||||
mIMESelectionFocus - mIMESelectionAnchor;
|
||||
notification.mSelectionChangeData.mReversed =
|
||||
mIMESelectionFocus < mIMESelectionAnchor;
|
||||
notification.mSelectionChangeData.SetWritingMode(mWritingMode);
|
||||
notification.mSelectionChangeData.mCausedByComposition =
|
||||
aCausedByComposition;
|
||||
widget->NotifyIME(notification);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2298,7 +2291,6 @@ TabParent::SendCompositionEvent(WidgetCompositionEvent& event)
|
|||
mIMEEventCountAfterEnding++;
|
||||
return true;
|
||||
}
|
||||
event.mSeqno = ++mIMESeqno;
|
||||
return PBrowserParent::SendCompositionEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2328,7 +2320,6 @@ TabParent::SendCompositionChangeEvent(WidgetCompositionEvent& event)
|
|||
mIMECompositionStart + event.mData.Length();
|
||||
mIMEComposing = !event.CausesDOMCompositionEndEvent();
|
||||
|
||||
event.mSeqno = ++mIMESeqno;
|
||||
return PBrowserParent::SendCompositionEvent(event);
|
||||
}
|
||||
|
||||
|
@ -2340,7 +2331,6 @@ TabParent::SendSelectionEvent(WidgetSelectionEvent& event)
|
|||
}
|
||||
mIMESelectionAnchor = event.mOffset + (event.mReversed ? event.mLength : 0);
|
||||
mIMESelectionFocus = event.mOffset + (!event.mReversed ? event.mLength : 0);
|
||||
event.mSeqno = ++mIMESeqno;
|
||||
return PBrowserParent::SendSelectionEvent(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -161,8 +161,8 @@ public:
|
|||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal) override;
|
||||
virtual bool RecvNotifyIMEFocus(const bool& aFocus,
|
||||
nsIMEUpdatePreference* aPreference,
|
||||
uint32_t* aSeqno) override;
|
||||
nsIMEUpdatePreference* aPreference)
|
||||
override;
|
||||
virtual bool RecvNotifyIMETextChange(const uint32_t& aStart,
|
||||
const uint32_t& aEnd,
|
||||
const uint32_t& aNewEnd,
|
||||
|
@ -172,8 +172,7 @@ public:
|
|||
InfallibleTArray<LayoutDeviceIntRect>&& aRects,
|
||||
const uint32_t& aCaretOffset,
|
||||
const LayoutDeviceIntRect& aCaretRect) override;
|
||||
virtual bool RecvNotifyIMESelection(const uint32_t& aSeqno,
|
||||
const uint32_t& aAnchor,
|
||||
virtual bool RecvNotifyIMESelection(const uint32_t& aAnchor,
|
||||
const uint32_t& aFocus,
|
||||
const mozilla::WritingMode& aWritingMode,
|
||||
const bool& aCausedByComposition) override;
|
||||
|
@ -482,7 +481,6 @@ protected:
|
|||
// Compositions in almost all cases are small enough for nsAutoString
|
||||
nsAutoString mIMECompositionText;
|
||||
uint32_t mIMECompositionStart;
|
||||
uint32_t mIMESeqno;
|
||||
|
||||
uint32_t mIMECompositionRectOffset;
|
||||
InfallibleTArray<LayoutDeviceIntRect> mIMECompositionRects;
|
||||
|
|
|
@ -86,6 +86,8 @@ DecodedStreamData::DecodedStreamData(int64_t aInitialTime,
|
|||
{
|
||||
mListener = new DecodedStreamGraphListener(mStream);
|
||||
mStream->AddListener(mListener);
|
||||
// Block the stream until the initialization is done.
|
||||
mStream->ChangeExplicitBlockerCount(1);
|
||||
}
|
||||
|
||||
DecodedStreamData::~DecodedStreamData()
|
||||
|
@ -179,7 +181,7 @@ DecodedStream::DecodedStream(ReentrantMonitor& aMonitor)
|
|||
}
|
||||
|
||||
DecodedStreamData*
|
||||
DecodedStream::GetData()
|
||||
DecodedStream::GetData() const
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
return mData.get();
|
||||
|
@ -221,13 +223,19 @@ DecodedStream::DestroyData()
|
|||
}
|
||||
|
||||
void
|
||||
DecodedStream::RecreateData(int64_t aInitialTime, SourceMediaStream* aStream)
|
||||
DecodedStream::RecreateData(int64_t aInitialTime, MediaStreamGraph* aGraph)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
MOZ_ASSERT(!mData);
|
||||
MOZ_ASSERT((aGraph && !mData && OutputStreams().IsEmpty()) || // first time
|
||||
(!aGraph && mData)); // 2nd time and later
|
||||
|
||||
mData.reset(new DecodedStreamData(aInitialTime, aStream));
|
||||
if (!aGraph) {
|
||||
aGraph = mData->mStream->Graph();
|
||||
}
|
||||
auto source = aGraph->CreateSourceStream(nullptr);
|
||||
DestroyData();
|
||||
mData.reset(new DecodedStreamData(aInitialTime, source));
|
||||
|
||||
// Note that the delay between removing ports in DestroyDecodedStream
|
||||
// and adding new ones won't cause a glitch since all graph operations
|
||||
|
@ -248,7 +256,7 @@ DecodedStream::OutputStreams()
|
|||
}
|
||||
|
||||
ReentrantMonitor&
|
||||
DecodedStream::GetReentrantMonitor()
|
||||
DecodedStream::GetReentrantMonitor() const
|
||||
{
|
||||
return mMonitor;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ class DecodedStream;
|
|||
class DecodedStreamGraphListener;
|
||||
class OutputStreamListener;
|
||||
class ReentrantMonitor;
|
||||
class MediaStreamGraph;
|
||||
|
||||
namespace layers {
|
||||
class Image;
|
||||
|
@ -92,11 +93,11 @@ public:
|
|||
class DecodedStream {
|
||||
public:
|
||||
explicit DecodedStream(ReentrantMonitor& aMonitor);
|
||||
DecodedStreamData* GetData();
|
||||
DecodedStreamData* GetData() const;
|
||||
void DestroyData();
|
||||
void RecreateData(int64_t aInitialTime, SourceMediaStream* aStream);
|
||||
void RecreateData(int64_t aInitialTime, MediaStreamGraph* aGraph);
|
||||
nsTArray<OutputStreamData>& OutputStreams();
|
||||
ReentrantMonitor& GetReentrantMonitor();
|
||||
ReentrantMonitor& GetReentrantMonitor() const;
|
||||
void Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
|
||||
|
||||
private:
|
||||
|
|
|
@ -289,89 +289,12 @@ void MediaDecoder::SetVolume(double aVolume)
|
|||
mVolume = aVolume;
|
||||
}
|
||||
|
||||
void MediaDecoder::UpdateDecodedStream()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
if (GetDecodedStream()) {
|
||||
bool blockForPlayState = mPlayState != PLAY_STATE_PLAYING || mLogicallySeeking;
|
||||
if (GetDecodedStream()->mHaveBlockedForPlayState != blockForPlayState) {
|
||||
GetDecodedStream()->mStream->ChangeExplicitBlockerCount(blockForPlayState ? 1 : -1);
|
||||
GetDecodedStream()->mHaveBlockedForPlayState = blockForPlayState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoder::UpdateStreamBlockingForStateMachinePlaying()
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
if (!GetDecodedStream()) {
|
||||
return;
|
||||
}
|
||||
bool blockForStateMachineNotPlaying =
|
||||
mDecoderStateMachine && !mDecoderStateMachine->IsPlaying();
|
||||
if (blockForStateMachineNotPlaying != GetDecodedStream()->mHaveBlockedForStateMachineNotPlaying) {
|
||||
GetDecodedStream()->mHaveBlockedForStateMachineNotPlaying = blockForStateMachineNotPlaying;
|
||||
int32_t delta = blockForStateMachineNotPlaying ? 1 : -1;
|
||||
if (NS_IsMainThread()) {
|
||||
GetDecodedStream()->mStream->ChangeExplicitBlockerCount(delta);
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewRunnableMethodWithArg<int32_t>(GetDecodedStream()->mStream.get(),
|
||||
&MediaStream::ChangeExplicitBlockerCount, delta);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoder::RecreateDecodedStream(int64_t aStartTimeUSecs,
|
||||
MediaStreamGraph* aGraph)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
DECODER_LOG("RecreateDecodedStream aStartTimeUSecs=%lld!", aStartTimeUSecs);
|
||||
|
||||
if (!aGraph) {
|
||||
aGraph = GetDecodedStream()->mStream->Graph();
|
||||
}
|
||||
|
||||
mDecodedStream.DestroyData();
|
||||
mDecodedStream.RecreateData(aStartTimeUSecs, aGraph->CreateSourceStream(nullptr));
|
||||
|
||||
UpdateStreamBlockingForStateMachinePlaying();
|
||||
|
||||
GetDecodedStream()->mHaveBlockedForPlayState = mPlayState != PLAY_STATE_PLAYING;
|
||||
if (GetDecodedStream()->mHaveBlockedForPlayState) {
|
||||
GetDecodedStream()->mStream->ChangeExplicitBlockerCount(1);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream,
|
||||
bool aFinishWhenEnded)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
DECODER_LOG("AddOutputStream aStream=%p!", aStream);
|
||||
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
if (mDecoderStateMachine) {
|
||||
mDecoderStateMachine->DispatchAudioCaptured();
|
||||
}
|
||||
if (!GetDecodedStream()) {
|
||||
RecreateDecodedStream(mLogicalPosition, aStream->Graph());
|
||||
}
|
||||
mDecodedStream.Connect(aStream, aFinishWhenEnded);
|
||||
}
|
||||
|
||||
// This can be called before Load(), in which case our mDecoderStateMachine
|
||||
// won't have been created yet and we can rely on Load() to schedule it
|
||||
// once it is created.
|
||||
if (mDecoderStateMachine) {
|
||||
// Make sure the state machine thread runs so that any buffered data
|
||||
// is fed into our stream.
|
||||
ScheduleStateMachine();
|
||||
}
|
||||
MOZ_ASSERT(mDecoderStateMachine, "Must be called after Load().");
|
||||
mDecoderStateMachine->AddOutputStream(aStream, aFinishWhenEnded);
|
||||
}
|
||||
|
||||
double MediaDecoder::GetDuration()
|
||||
|
@ -420,7 +343,6 @@ MediaDecoder::MediaDecoder() :
|
|||
mMediaSeekable(true),
|
||||
mSameOriginMedia(false),
|
||||
mReentrantMonitor("media.decoder"),
|
||||
mDecodedStream(mReentrantMonitor),
|
||||
mPlayState(AbstractThread::MainThread(), PLAY_STATE_LOADING,
|
||||
"MediaDecoder::mPlayState (Canonical)"),
|
||||
mNextState(AbstractThread::MainThread(), PLAY_STATE_PAUSED,
|
||||
|
@ -508,12 +430,6 @@ void MediaDecoder::Shutdown()
|
|||
MediaDecoder::~MediaDecoder()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
{
|
||||
// Don't destroy the decoded stream until destructor in order to keep the
|
||||
// invariant that the decoded stream is always available in capture mode.
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mDecodedStream.DestroyData();
|
||||
}
|
||||
MediaMemoryTracker::RemoveMediaDecoder(this);
|
||||
UnpinForSeek();
|
||||
MOZ_COUNT_DTOR(MediaDecoder);
|
||||
|
@ -573,9 +489,6 @@ void MediaDecoder::SetStateMachineParameters()
|
|||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mDecoderStateMachine->SetDuration(mDuration);
|
||||
if (GetDecodedStream()) {
|
||||
mDecoderStateMachine->DispatchAudioCaptured();
|
||||
}
|
||||
if (mMinimizePreroll) {
|
||||
mDecoderStateMachine->DispatchMinimizePrerollUntilPlaybackStarts();
|
||||
}
|
||||
|
@ -646,7 +559,6 @@ nsresult MediaDecoder::Seek(double aTime, SeekTarget::Type aSeekType)
|
|||
mWasEndedWhenEnteredDormant = false;
|
||||
|
||||
mLogicallySeeking = true;
|
||||
UpdateDecodedStream();
|
||||
SeekTarget target = SeekTarget(timeUsecs, aSeekType);
|
||||
CallSeek(target);
|
||||
|
||||
|
@ -1066,7 +978,6 @@ void MediaDecoder::OnSeekResolved(SeekResolveValue aVal)
|
|||
ChangeState(PLAY_STATE_ENDED);
|
||||
}
|
||||
mLogicallySeeking = false;
|
||||
UpdateDecodedStream();
|
||||
}
|
||||
|
||||
UpdateLogicalPosition(aVal.mEventVisibility);
|
||||
|
@ -1112,8 +1023,6 @@ void MediaDecoder::ChangeState(PlayState aState)
|
|||
gPlayStateStr[mPlayState], gPlayStateStr[aState]);
|
||||
mPlayState = aState;
|
||||
|
||||
UpdateDecodedStream();
|
||||
|
||||
if (mPlayState == PLAY_STATE_PLAYING) {
|
||||
ConstructMediaTracks();
|
||||
} else if (IsEnded()) {
|
||||
|
|
|
@ -395,28 +395,6 @@ public:
|
|||
// replaying after the input as ended. In the latter case, the new source is
|
||||
// not connected to streams created by captureStreamUntilEnded.
|
||||
|
||||
void UpdateDecodedStream();
|
||||
|
||||
/**
|
||||
* Recreates mDecodedStream. Call this to create mDecodedStream at first,
|
||||
* and when seeking, to ensure a new stream is set up with fresh buffers.
|
||||
* aStartTimeUSecs is relative to the state machine's mStartTime.
|
||||
* Decoder monitor must be held.
|
||||
*/
|
||||
void RecreateDecodedStream(int64_t aStartTimeUSecs,
|
||||
MediaStreamGraph* aGraph = nullptr);
|
||||
/**
|
||||
* Call this when mDecoderStateMachine or mDecoderStateMachine->IsPlaying() changes.
|
||||
* Decoder monitor must be held.
|
||||
*/
|
||||
void UpdateStreamBlockingForStateMachinePlaying();
|
||||
|
||||
DecodedStreamData* GetDecodedStream()
|
||||
{
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
return mDecodedStream.GetData();
|
||||
}
|
||||
|
||||
// Add an output stream. All decoder output will be sent to the stream.
|
||||
// The stream is initially blocked. The decoder is responsible for unblocking
|
||||
// it while it is playing back.
|
||||
|
@ -1016,13 +994,6 @@ private:
|
|||
#endif
|
||||
|
||||
protected:
|
||||
// The SourceMediaStream we are using to feed the mOutputStreams. This stream
|
||||
// is never exposed outside the decoder.
|
||||
// Only written on the main thread while holding the monitor. Therefore it
|
||||
// can be read on any thread while holding the monitor, or on the main thread
|
||||
// without holding the monitor.
|
||||
DecodedStream mDecodedStream;
|
||||
|
||||
// Set to one of the valid play states.
|
||||
// This can only be changed on the main thread while holding the decoder
|
||||
// monitor. Thus, it can be safely read while holding the decoder monitor
|
||||
|
|
|
@ -177,7 +177,7 @@ public:
|
|||
// with tag metadata from the file.
|
||||
// Returns NS_OK on success, or NS_ERROR_FAILURE on failure.
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) = 0;
|
||||
MetadataTags** aTags) { MOZ_CRASH(); }
|
||||
|
||||
// Fills aInfo with the latest cached data required to present the media,
|
||||
// ReadUpdatedMetadata will always be called once ReadMetadata has succeeded.
|
||||
|
|
|
@ -240,7 +240,8 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
mDecodingFrozenAtStateDecoding(false),
|
||||
mSentLoadedMetadataEvent(false),
|
||||
mSentFirstFrameLoadedEvent(false),
|
||||
mSentPlaybackEndedEvent(false)
|
||||
mSentPlaybackEndedEvent(false),
|
||||
mDecodedStream(mDecoder->GetReentrantMonitor())
|
||||
{
|
||||
MOZ_COUNT_CTOR(MediaDecoderStateMachine);
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
|
@ -308,6 +309,8 @@ MediaDecoderStateMachine::InitializationTask()
|
|||
mWatchManager.Watch(mPreservesPitch, &MediaDecoderStateMachine::PreservesPitchChanged);
|
||||
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
|
||||
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged);
|
||||
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::UpdateStreamBlockingForPlayState);
|
||||
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::UpdateStreamBlockingForPlayState);
|
||||
}
|
||||
|
||||
bool MediaDecoderStateMachine::HasFutureAudio()
|
||||
|
@ -422,13 +425,26 @@ static bool ZeroDurationAtLastChunk(VideoSegment& aInput)
|
|||
return lastVideoStratTime == aInput.GetDuration();
|
||||
}
|
||||
|
||||
static void
|
||||
UpdateStreamBlocking(MediaStream* aStream, bool aBlocking)
|
||||
{
|
||||
int32_t delta = aBlocking ? 1 : -1;
|
||||
if (NS_IsMainThread()) {
|
||||
aStream->ChangeExplicitBlockerCount(delta);
|
||||
} else {
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<int32_t>(
|
||||
aStream, &MediaStream::ChangeExplicitBlockerCount, delta);
|
||||
AbstractThread::MainThread()->Dispatch(r.forget());
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::SendStreamData()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
MOZ_ASSERT(!mAudioSink, "Should've been stopped in RunStateMachine()");
|
||||
|
||||
DecodedStreamData* stream = mDecoder->GetDecodedStream();
|
||||
DecodedStreamData* stream = GetDecodedStream();
|
||||
|
||||
bool finished =
|
||||
(!mInfo.HasAudio() || AudioQueue().IsFinished()) &&
|
||||
|
@ -463,6 +479,12 @@ void MediaDecoderStateMachine::SendStreamData()
|
|||
}
|
||||
mediaStream->FinishAddTracks();
|
||||
stream->mStreamInitialized = true;
|
||||
|
||||
// Make sure stream blocking is updated before sending stream data so we
|
||||
// don't 'leak' data when the stream is supposed to be blocked.
|
||||
UpdateStreamBlockingForPlayState();
|
||||
UpdateStreamBlockingForStateMachinePlaying();
|
||||
UpdateStreamBlocking(mediaStream, false);
|
||||
}
|
||||
|
||||
if (mInfo.HasAudio()) {
|
||||
|
@ -616,7 +638,7 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs)
|
|||
return true;
|
||||
}
|
||||
|
||||
DecodedStreamData* stream = mDecoder->GetDecodedStream();
|
||||
DecodedStreamData* stream = GetDecodedStream();
|
||||
|
||||
if (stream && stream->mStreamInitialized && !stream->mHaveSentFinishAudio) {
|
||||
MOZ_ASSERT(mInfo.HasAudio());
|
||||
|
@ -640,7 +662,7 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedVideo()
|
|||
return false;
|
||||
}
|
||||
|
||||
DecodedStreamData* stream = mDecoder->GetDecodedStream();
|
||||
DecodedStreamData* stream = GetDecodedStream();
|
||||
|
||||
if (stream && stream->mStreamInitialized && !stream->mHaveSentFinishVideo) {
|
||||
MOZ_ASSERT(mInfo.HasVideo());
|
||||
|
@ -1271,7 +1293,7 @@ void MediaDecoderStateMachine::StopPlayback()
|
|||
// so it can pause audio playback.
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
NS_ASSERTION(!IsPlaying(), "Should report not playing at end of StopPlayback()");
|
||||
mDecoder->UpdateStreamBlockingForStateMachinePlaying();
|
||||
UpdateStreamBlockingForStateMachinePlaying();
|
||||
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
|
@ -1309,7 +1331,7 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
|
|||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
mDecoder->GetReentrantMonitor().NotifyAll();
|
||||
mDecoder->UpdateStreamBlockingForStateMachinePlaying();
|
||||
UpdateStreamBlockingForStateMachinePlaying();
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
|
||||
|
@ -1905,8 +1927,8 @@ MediaDecoderStateMachine::InitiateSeek()
|
|||
// as far as fast-seek is concerned. It also fix the problem where stream
|
||||
// clock seems to go backwards during seeking.
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethodWithArgs<int64_t, MediaStreamGraph*>(mDecoder,
|
||||
&MediaDecoder::RecreateDecodedStream,
|
||||
NS_NewRunnableMethodWithArgs<int64_t, MediaStreamGraph*>(this,
|
||||
&MediaDecoderStateMachine::RecreateDecodedStream,
|
||||
seekTime - mStartTime,
|
||||
nullptr);
|
||||
AbstractThread::MainThread()->Dispatch(event.forget());
|
||||
|
@ -2717,7 +2739,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
|||
// end of the media, and so that we update the readyState.
|
||||
if (VideoQueue().GetSize() > 0 ||
|
||||
(HasAudio() && !mAudioCompleted) ||
|
||||
(mAudioCaptured && !mDecoder->GetDecodedStream()->IsFinished()))
|
||||
(mAudioCaptured && !GetDecodedStream()->IsFinished()))
|
||||
{
|
||||
AdvanceFrame();
|
||||
NS_ASSERTION(mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
|
||||
|
@ -2898,7 +2920,7 @@ int64_t MediaDecoderStateMachine::GetClock() const
|
|||
clock_time = mPlayDuration + mStartTime;
|
||||
} else {
|
||||
if (mAudioCaptured) {
|
||||
clock_time = mStartTime + mDecoder->GetDecodedStream()->GetClock();
|
||||
clock_time = mStartTime + GetDecodedStream()->GetClock();
|
||||
} else if (HasAudio() && !mAudioCompleted) {
|
||||
clock_time = GetAudioClock();
|
||||
} else {
|
||||
|
@ -3487,6 +3509,83 @@ uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
|
|||
: std::max<uint32_t>(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE);
|
||||
}
|
||||
|
||||
DecodedStreamData* MediaDecoderStateMachine::GetDecodedStream() const
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
return mDecodedStream.GetData();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::DispatchAudioCaptured()
|
||||
{
|
||||
nsRefPtr<MediaDecoderStateMachine> self = this;
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
|
||||
{
|
||||
MOZ_ASSERT(self->OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor());
|
||||
if (!self->mAudioCaptured) {
|
||||
self->mAudioCaptured = true;
|
||||
self->ScheduleStateMachine();
|
||||
}
|
||||
});
|
||||
TaskQueue()->Dispatch(r.forget());
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
|
||||
bool aFinishWhenEnded)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
DECODER_LOG("AddOutputStream aStream=%p!", aStream);
|
||||
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
if (!GetDecodedStream()) {
|
||||
RecreateDecodedStream(mCurrentPosition.ReadOnWrongThread(), aStream->Graph());
|
||||
}
|
||||
mDecodedStream.Connect(aStream, aFinishWhenEnded);
|
||||
DispatchAudioCaptured();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::UpdateStreamBlockingForPlayState()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
|
||||
auto stream = GetDecodedStream();
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool blocking = mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
|
||||
mLogicallySeeking;
|
||||
if (blocking != stream->mHaveBlockedForPlayState) {
|
||||
stream->mHaveBlockedForPlayState = blocking;
|
||||
UpdateStreamBlocking(stream->mStream, blocking);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::UpdateStreamBlockingForStateMachinePlaying()
|
||||
{
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
||||
auto stream = GetDecodedStream();
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool blocking = !IsPlaying();
|
||||
if (blocking != stream->mHaveBlockedForStateMachineNotPlaying) {
|
||||
stream->mHaveBlockedForStateMachineNotPlaying = blocking;
|
||||
UpdateStreamBlocking(stream->mStream, blocking);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::RecreateDecodedStream(int64_t aInitialTime,
|
||||
MediaStreamGraph* aGraph)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
DECODER_LOG("RecreateDecodedStream aInitialTime=%lld!", aInitialTime);
|
||||
mDecodedStream.RecreateData(aInitialTime, aGraph);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
// avoid redefined macro in unified build
|
||||
|
|
|
@ -92,13 +92,13 @@ hardware (via AudioStream).
|
|||
#include "mozilla/RollingMean.h"
|
||||
#include "MediaTimer.h"
|
||||
#include "StateMirroring.h"
|
||||
#include "DecodedStream.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class AudioSegment;
|
||||
class MediaTaskQueue;
|
||||
class AudioSink;
|
||||
class DecodedStreamData;
|
||||
|
||||
/*
|
||||
The state machine class. This manages the decoding and seeking in the
|
||||
|
@ -145,20 +145,9 @@ public:
|
|||
return mState;
|
||||
}
|
||||
|
||||
void DispatchAudioCaptured()
|
||||
{
|
||||
nsRefPtr<MediaDecoderStateMachine> self = this;
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
|
||||
{
|
||||
MOZ_ASSERT(self->OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor());
|
||||
if (!self->mAudioCaptured) {
|
||||
self->mAudioCaptured = true;
|
||||
self->ScheduleStateMachine();
|
||||
}
|
||||
});
|
||||
TaskQueue()->Dispatch(r.forget());
|
||||
}
|
||||
DecodedStreamData* GetDecodedStream() const;
|
||||
|
||||
void AddOutputStream(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
|
||||
|
||||
// Check if the decoder needs to become dormant state.
|
||||
bool IsDormantNeeded();
|
||||
|
@ -171,6 +160,21 @@ private:
|
|||
// constructor immediately after the task queue is created.
|
||||
void InitializationTask();
|
||||
|
||||
void DispatchAudioCaptured();
|
||||
|
||||
// Update blocking state of mDecodedStream when mPlayState or
|
||||
// mLogicallySeeking change. Decoder monitor must be held.
|
||||
void UpdateStreamBlockingForPlayState();
|
||||
|
||||
// Call this IsPlaying() changes. Decoder monitor must be held.
|
||||
void UpdateStreamBlockingForStateMachinePlaying();
|
||||
|
||||
// Recreates mDecodedStream. Call this to create mDecodedStream at first,
|
||||
// and when seeking, to ensure a new stream is set up with fresh buffers.
|
||||
// aInitialTime is relative to mStartTime.
|
||||
// Decoder monitor must be held.
|
||||
void RecreateDecodedStream(int64_t aInitialTime, MediaStreamGraph* aGraph);
|
||||
|
||||
void Shutdown();
|
||||
public:
|
||||
|
||||
|
@ -353,6 +357,10 @@ public:
|
|||
if (mReader) {
|
||||
mReader->BreakCycles();
|
||||
}
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mDecodedStream.DestroyData();
|
||||
}
|
||||
mDecoder = nullptr;
|
||||
}
|
||||
|
||||
|
@ -1284,6 +1292,13 @@ protected:
|
|||
bool mSentFirstFrameLoadedEvent;
|
||||
|
||||
bool mSentPlaybackEndedEvent;
|
||||
|
||||
// The SourceMediaStream we are using to feed the mOutputStreams. This stream
|
||||
// is never exposed outside the decoder.
|
||||
// Only written on the main thread while holding the monitor. Therefore it
|
||||
// can be read on any thread while holding the monitor, or on the main thread
|
||||
// without holding the monitor.
|
||||
DecodedStream mDecodedStream;
|
||||
};
|
||||
|
||||
} // namespace mozilla;
|
||||
|
|
|
@ -55,13 +55,6 @@ public:
|
|||
}
|
||||
|
||||
virtual nsRefPtr<MetadataPromise> AsyncReadMetadata() override;
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) override
|
||||
{
|
||||
// Unused as we provide AsyncReadMetadataAPI.
|
||||
// However we must implement it as it's pure virtual.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
virtual void ReadUpdatedMetadata(MediaInfo* aInfo) override;
|
||||
|
||||
|
|
|
@ -28,12 +28,12 @@ SOURCES += [
|
|||
# If WebRTC isn't being built, we need to compile the DirectShow base classes so that
|
||||
# they're available at link time.
|
||||
if not CONFIG['MOZ_WEBRTC']:
|
||||
SOURCES += [ '%s/%s' % (TOPSRCDIR, p) for p in [
|
||||
'media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.cpp',
|
||||
'media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseInputPin.cpp',
|
||||
'media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.cpp',
|
||||
'media/webrtc/trunk/webrtc/modules/video_capture/windows/MediaType.cpp',
|
||||
]]
|
||||
SOURCES += [
|
||||
'/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.cpp',
|
||||
'/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseInputPin.cpp',
|
||||
'/media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.cpp',
|
||||
'/media/webrtc/trunk/webrtc/modules/video_capture/windows/MediaType.cpp',
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ bool
|
|||
MediaOmxCommonDecoder::CheckDecoderCanOffloadAudio()
|
||||
{
|
||||
return (mCanOffloadAudio && !mFallbackToStateMachine &&
|
||||
!GetDecodedStream() && mPlaybackRate == 1.0);
|
||||
!(GetStateMachine() && GetStateMachine()->GetDecodedStream()) &&
|
||||
mPlaybackRate == 1.0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -24,6 +24,8 @@ class AbstractMediaDecoder;
|
|||
class MediaOmxCommonReader : public MediaDecoderReader
|
||||
{
|
||||
public:
|
||||
typedef MediaPromise<bool /* aIgnored */, bool /* aIgnored */, /* IsExclusive = */ true> MediaResourcePromise;
|
||||
|
||||
MediaOmxCommonReader(AbstractMediaDecoder* aDecoder);
|
||||
|
||||
void SetAudioChannel(dom::AudioChannel aAudioChannel) {
|
||||
|
|
|
@ -134,7 +134,6 @@ MediaOmxReader::MediaOmxReader(AbstractMediaDecoder *aDecoder)
|
|||
, mSkipCount(0)
|
||||
, mIsShutdown(false)
|
||||
, mMP3FrameParser(-1)
|
||||
, mIsWaitingResources(false)
|
||||
{
|
||||
if (!gMediaDecoderLog) {
|
||||
gMediaDecoderLog = PR_NewLogModule("MediaDecoder");
|
||||
|
@ -187,22 +186,11 @@ MediaOmxReader::Shutdown()
|
|||
return p;
|
||||
}
|
||||
|
||||
bool MediaOmxReader::IsWaitingMediaResources()
|
||||
{
|
||||
return mIsWaitingResources;
|
||||
}
|
||||
|
||||
void MediaOmxReader::UpdateIsWaitingMediaResources()
|
||||
{
|
||||
if (mOmxDecoder.get()) {
|
||||
mIsWaitingResources = mOmxDecoder->IsWaitingMediaResources();
|
||||
} else {
|
||||
mIsWaitingResources = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MediaOmxReader::ReleaseMediaResources()
|
||||
{
|
||||
mMediaResourceRequest.DisconnectIfExists();
|
||||
mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
|
||||
ResetDecode();
|
||||
// Before freeing a video codec, all video buffers needed to be released
|
||||
// even from graphics pipeline.
|
||||
|
@ -237,23 +225,17 @@ nsresult MediaOmxReader::InitOmxDecoder()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void MediaOmxReader::PreReadMetadata()
|
||||
{
|
||||
UpdateIsWaitingMediaResources();
|
||||
}
|
||||
|
||||
nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags)
|
||||
nsRefPtr<MediaDecoderReader::MetadataPromise>
|
||||
MediaOmxReader::AsyncReadMetadata()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
EnsureActive();
|
||||
|
||||
*aTags = nullptr;
|
||||
|
||||
// Initialize the internal OMX Decoder.
|
||||
nsresult rv = InitOmxDecoder();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
return MediaDecoderReader::MetadataPromise::CreateAndReject(
|
||||
ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
}
|
||||
|
||||
bool isMP3 = mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
|
||||
|
@ -265,22 +247,33 @@ nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
|
|||
ProcessCachedData(0, true);
|
||||
}
|
||||
|
||||
if (!mOmxDecoder->AllocateMediaResources()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// Bug 1050667, both MediaDecoderStateMachine and MediaOmxReader
|
||||
// relies on IsWaitingMediaResources() function. And the waiting state will be
|
||||
// changed by binder thread, so we store the waiting state in a cache value to
|
||||
// make them in consistent state.
|
||||
UpdateIsWaitingMediaResources();
|
||||
if (IsWaitingMediaResources()) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsRefPtr<MediaDecoderReader::MetadataPromise> p = mMetadataPromise.Ensure(__func__);
|
||||
|
||||
nsRefPtr<MediaOmxReader> self = this;
|
||||
mMediaResourceRequest.Begin(mOmxDecoder->AllocateMediaResources()
|
||||
->RefableThen(GetTaskQueue(), __func__,
|
||||
[self] (bool) -> void {
|
||||
self->mMediaResourceRequest.Complete();
|
||||
self->HandleResourceAllocated();
|
||||
}, [self] (bool) -> void {
|
||||
self->mMediaResourceRequest.Complete();
|
||||
self->mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
}));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void MediaOmxReader::HandleResourceAllocated()
|
||||
{
|
||||
EnsureActive();
|
||||
|
||||
// After resources are available, set the metadata.
|
||||
if (!mOmxDecoder->EnsureMetadata()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
bool isMP3 = mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
|
||||
if (isMP3 && mMP3FrameParser.IsMP3()) {
|
||||
// Check if the MP3 frame parser found a duration.
|
||||
mLastParserDuration = mMP3FrameParser.GetDuration();
|
||||
|
@ -312,7 +305,8 @@ nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
|
|||
nsIntSize displaySize(displayWidth, displayHeight);
|
||||
nsIntSize frameSize(width, height);
|
||||
if (!IsValidVideoRegion(frameSize, pictureRect, displaySize)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
// Video track's frame sizes will not overflow. Activate the video track.
|
||||
|
@ -336,13 +330,15 @@ nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
|
|||
mInfo.mAudio.mRate = sampleRate;
|
||||
}
|
||||
|
||||
*aInfo = mInfo;
|
||||
nsRefPtr<MetadataHolder> metadata = new MetadataHolder();
|
||||
metadata->mInfo = mInfo;
|
||||
metadata->mTags = nullptr;
|
||||
|
||||
#ifdef MOZ_AUDIO_OFFLOAD
|
||||
CheckAudioOffload();
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
mMetadataPromise.Resolve(metadata, __func__);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsMimeTypes.h"
|
||||
#include "MP3FrameParser.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
#include <ui/GraphicBuffer.h>
|
||||
#include <stagefright/MediaSource.h>
|
||||
|
||||
|
@ -26,6 +27,8 @@ class AbstractMediaDecoder;
|
|||
|
||||
class MediaOmxReader : public MediaOmxCommonReader
|
||||
{
|
||||
typedef MediaOmxCommonReader::MediaResourcePromise MediaResourcePromise;
|
||||
|
||||
// This mutex is held when accessing the mIsShutdown variable, which is
|
||||
// modified on the decode task queue and read on main and IO threads.
|
||||
Mutex mShutdownMutex;
|
||||
|
@ -41,15 +44,13 @@ class MediaOmxReader : public MediaOmxCommonReader
|
|||
// If mIsShutdown is false, and mShutdownMutex is held, then
|
||||
// AbstractMediaDecoder::mDecoder will be non-null.
|
||||
bool mIsShutdown;
|
||||
MediaPromiseHolder<MediaDecoderReader::MetadataPromise> mMetadataPromise;
|
||||
MediaPromiseConsumerHolder<MediaResourcePromise> mMediaResourceRequest;
|
||||
protected:
|
||||
android::sp<android::OmxDecoder> mOmxDecoder;
|
||||
android::sp<android::MediaExtractor> mExtractor;
|
||||
MP3FrameParser mMP3FrameParser;
|
||||
|
||||
// A cache value updated by UpdateIsWaitingMediaResources(), makes the
|
||||
// "waiting resources state" is synchronous to StateMachine.
|
||||
bool mIsWaitingResources;
|
||||
|
||||
// Called by ReadMetadata() during MediaDecoderStateMachine::DecodeMetadata()
|
||||
// on decode thread. It create and initialize the OMX decoder including
|
||||
// setting up custom extractor. The extractor provide the essential
|
||||
|
@ -60,10 +61,7 @@ protected:
|
|||
// to activate the decoder automatically.
|
||||
virtual void EnsureActive();
|
||||
|
||||
// Check the underlying HW resources are available and store the result in
|
||||
// mIsWaitingResources. The result might be changed by binder thread,
|
||||
// Can only called by ReadMetadata.
|
||||
void UpdateIsWaitingMediaResources();
|
||||
virtual void HandleResourceAllocated();
|
||||
|
||||
public:
|
||||
MediaOmxReader(AbstractMediaDecoder* aDecoder);
|
||||
|
@ -87,15 +85,11 @@ public:
|
|||
return mHasVideo;
|
||||
}
|
||||
|
||||
// Return mIsWaitingResources.
|
||||
virtual bool IsWaitingMediaResources() override;
|
||||
|
||||
virtual bool IsDormantNeeded() { return true;}
|
||||
virtual void ReleaseMediaResources();
|
||||
|
||||
virtual void PreReadMetadata() override;
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual nsRefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata() override;
|
||||
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aEndTime) override;
|
||||
|
||||
|
|
|
@ -94,19 +94,25 @@ MediaResourceManagerClient::State OMXCodecProxy::getState()
|
|||
return mState;
|
||||
}
|
||||
|
||||
void OMXCodecProxy::setEventListener(const wp<OMXCodecProxy::EventListener>& listener)
|
||||
void OMXCodecProxy::setListener(const wp<CodecResourceListener>& listener)
|
||||
{
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
mEventListener = listener;
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
void OMXCodecProxy::notifyStatusChangedLocked()
|
||||
void OMXCodecProxy::notifyResourceReserved()
|
||||
{
|
||||
if (mEventListener != nullptr) {
|
||||
sp<EventListener> listener = mEventListener.promote();
|
||||
if (listener != nullptr) {
|
||||
listener->statusChanged();
|
||||
}
|
||||
sp<CodecResourceListener> listener = mListener.promote();
|
||||
if (listener != nullptr) {
|
||||
listener->codecReserved();
|
||||
}
|
||||
}
|
||||
|
||||
void OMXCodecProxy::notifyResourceCanceled()
|
||||
{
|
||||
sp<CodecResourceListener> listener = mListener.promote();
|
||||
if (listener != nullptr) {
|
||||
listener->codecCanceled();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,12 +135,6 @@ void OMXCodecProxy::requestResource()
|
|||
mManagerService->requestMediaResource(mClient, IMediaResourceManagerService::HW_VIDEO_DECODER, true /* will wait */);
|
||||
}
|
||||
|
||||
bool OMXCodecProxy::IsWaitingResources()
|
||||
{
|
||||
Mutex::Autolock autoLock(mLock);
|
||||
return mState == MediaResourceManagerClient::CLIENT_STATE_WAIT_FOR_RESOURCE;
|
||||
}
|
||||
|
||||
// called on Binder ipc thread
|
||||
void OMXCodecProxy::statusChanged(int event)
|
||||
{
|
||||
|
@ -146,13 +146,14 @@ void OMXCodecProxy::statusChanged(int event)
|
|||
|
||||
mState = (MediaResourceManagerClient::State) event;
|
||||
if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
|
||||
notifyResourceCanceled();
|
||||
return;
|
||||
}
|
||||
|
||||
const char *mime;
|
||||
if (!mSrcMeta->findCString(kKeyMIMEType, &mime)) {
|
||||
mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
|
||||
notifyStatusChangedLocked();
|
||||
notifyResourceCanceled();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -161,7 +162,7 @@ void OMXCodecProxy::statusChanged(int event)
|
|||
mOMXCodec = OMXCodec::Create(mOMX, mSrcMeta, mIsEncoder, mSource, mComponentName, mFlags, mNativeWindow);
|
||||
if (mOMXCodec == nullptr) {
|
||||
mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
|
||||
notifyStatusChangedLocked();
|
||||
notifyResourceCanceled();
|
||||
return;
|
||||
}
|
||||
// Check if this video is sized such that we're comfortable
|
||||
|
@ -182,7 +183,7 @@ void OMXCodecProxy::statusChanged(int event)
|
|||
width, height, maxWidth, maxHeight);
|
||||
mOMXCodec.clear();
|
||||
mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
|
||||
notifyStatusChangedLocked();
|
||||
notifyResourceCanceled();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -190,11 +191,11 @@ void OMXCodecProxy::statusChanged(int event)
|
|||
NS_WARNING("Couldn't start OMX video source");
|
||||
mOMXCodec.clear();
|
||||
mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
|
||||
notifyStatusChangedLocked();
|
||||
notifyResourceCanceled();
|
||||
return;
|
||||
}
|
||||
}
|
||||
notifyStatusChangedLocked();
|
||||
notifyResourceReserved();
|
||||
}
|
||||
|
||||
status_t OMXCodecProxy::start(MetaData *params)
|
||||
|
|
|
@ -23,8 +23,19 @@ class OMXCodecProxy : public MediaSource,
|
|||
public MediaResourceManagerClient::EventListener
|
||||
{
|
||||
public:
|
||||
struct EventListener : public virtual RefBase {
|
||||
virtual void statusChanged() = 0;
|
||||
/* Codec resource notification listener.
|
||||
* All functions are called on the Binder thread.
|
||||
*/
|
||||
struct CodecResourceListener : public virtual RefBase {
|
||||
/* The codec resource is reserved and can be granted.
|
||||
* The client can allocate the requested resource.
|
||||
*/
|
||||
virtual void codecReserved() = 0;
|
||||
/* The codec resource is not reserved any more.
|
||||
* The client should release the resource as soon as possible if the
|
||||
* resource is still being held.
|
||||
*/
|
||||
virtual void codecCanceled() = 0;
|
||||
};
|
||||
|
||||
static sp<OMXCodecProxy> Create(
|
||||
|
@ -37,10 +48,9 @@ public:
|
|||
|
||||
MediaResourceManagerClient::State getState();
|
||||
|
||||
void setEventListener(const wp<EventListener>& listener);
|
||||
void setListener(const wp<CodecResourceListener>& listener);
|
||||
|
||||
void requestResource();
|
||||
bool IsWaitingResources();
|
||||
|
||||
// MediaResourceManagerClient::EventListener
|
||||
virtual void statusChanged(int event);
|
||||
|
@ -68,6 +78,9 @@ protected:
|
|||
|
||||
virtual ~OMXCodecProxy();
|
||||
|
||||
void notifyResourceReserved();
|
||||
void notifyResourceCanceled();
|
||||
|
||||
void notifyStatusChangedLocked();
|
||||
|
||||
private:
|
||||
|
@ -91,7 +104,8 @@ private:
|
|||
MediaResourceManagerClient::State mState;
|
||||
|
||||
sp<IMediaResourceManagerService> mManagerService;
|
||||
wp<OMXCodecProxy::EventListener> mEventListener;
|
||||
// Codec Resource Notification Listener
|
||||
wp<CodecResourceListener> mListener;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
|
|
@ -91,12 +91,13 @@ OmxDecoder::~OmxDecoder()
|
|||
mLooper->stop();
|
||||
}
|
||||
|
||||
void OmxDecoder::statusChanged()
|
||||
void OmxDecoder::codecReserved()
|
||||
{
|
||||
sp<AMessage> notify =
|
||||
new AMessage(kNotifyStatusChanged, mReflector->id());
|
||||
// post AMessage to OmxDecoder via ALooper.
|
||||
notify->post();
|
||||
mMediaResourcePromise.ResolveIfExists(true, __func__);
|
||||
}
|
||||
void OmxDecoder::codecCanceled()
|
||||
{
|
||||
mMediaResourcePromise.RejectIfExists(true, __func__);
|
||||
}
|
||||
|
||||
static sp<IOMX> sOMX = nullptr;
|
||||
|
@ -213,14 +214,6 @@ bool OmxDecoder::EnsureMetadata() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OmxDecoder::IsWaitingMediaResources()
|
||||
{
|
||||
if (mVideoSource.get()) {
|
||||
return mVideoSource->IsWaitingResources();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isInEmulator()
|
||||
{
|
||||
char propQemu[PROPERTY_VALUE_MAX];
|
||||
|
@ -228,8 +221,10 @@ static bool isInEmulator()
|
|||
return !strncmp(propQemu, "1", 1);
|
||||
}
|
||||
|
||||
bool OmxDecoder::AllocateMediaResources()
|
||||
nsRefPtr<mozilla::MediaOmxCommonReader::MediaResourcePromise> OmxDecoder::AllocateMediaResources()
|
||||
{
|
||||
nsRefPtr<MediaResourcePromise> p = mMediaResourcePromise.Ensure(__func__);
|
||||
|
||||
if ((mVideoTrack != nullptr) && (mVideoSource == nullptr)) {
|
||||
// OMXClient::connect() always returns OK and abort's fatally if
|
||||
// it can't connect.
|
||||
|
@ -280,10 +275,11 @@ bool OmxDecoder::AllocateMediaResources()
|
|||
mNativeWindowClient);
|
||||
if (mVideoSource == nullptr) {
|
||||
NS_WARNING("Couldn't create OMX video source");
|
||||
return false;
|
||||
mMediaResourcePromise.Reject(true, __func__);
|
||||
return p;
|
||||
} else {
|
||||
sp<OMXCodecProxy::EventListener> listener = this;
|
||||
mVideoSource->setEventListener(listener);
|
||||
sp<OMXCodecProxy::CodecResourceListener> listener = this;
|
||||
mVideoSource->setListener(listener);
|
||||
mVideoSource->requestResource();
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +295,8 @@ bool OmxDecoder::AllocateMediaResources()
|
|||
const char *audioMime = nullptr;
|
||||
sp<MetaData> meta = mAudioTrack->getFormat();
|
||||
if (!meta->findCString(kKeyMIMEType, &audioMime)) {
|
||||
return false;
|
||||
mMediaResourcePromise.Reject(true, __func__);
|
||||
return p;
|
||||
}
|
||||
if (!strcasecmp(audioMime, "audio/raw")) {
|
||||
mAudioSource = mAudioTrack;
|
||||
|
@ -325,20 +322,28 @@ bool OmxDecoder::AllocateMediaResources()
|
|||
flags);
|
||||
if (mAudioSource == nullptr) {
|
||||
NS_WARNING("Couldn't create OMX audio source");
|
||||
return false;
|
||||
mMediaResourcePromise.Reject(true, __func__);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
if (mAudioSource->start() != OK) {
|
||||
NS_WARNING("Couldn't start OMX audio source");
|
||||
mAudioSource.clear();
|
||||
return false;
|
||||
mMediaResourcePromise.Reject(true, __func__);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if (!mVideoSource.get()) {
|
||||
// No resource allocation wait.
|
||||
mMediaResourcePromise.Resolve(true, __func__);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void OmxDecoder::ReleaseMediaResources() {
|
||||
mMediaResourcePromise.RejectIfExists(true, __func__);
|
||||
|
||||
ReleaseVideoBuffer();
|
||||
ReleaseAudioBuffer();
|
||||
|
||||
|
@ -825,15 +830,6 @@ void OmxDecoder::onMessageReceived(const sp<AMessage> &msg)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kNotifyStatusChanged:
|
||||
{
|
||||
// Our decode may have acquired the hardware resource that it needs
|
||||
// to start. Notify the state machine to resume loading metadata.
|
||||
mDecoder->NotifyWaitingForResourcesStatusChanged();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
TRESPASS();
|
||||
break;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/layers/FenceUtils.h"
|
||||
#include "MP3FrameParser.h"
|
||||
#include "MPAPI.h"
|
||||
#include "MediaOmxCommonReader.h"
|
||||
#include "MediaResource.h"
|
||||
#include "AbstractMediaDecoder.h"
|
||||
#include "OMXCodecProxy.h"
|
||||
|
@ -20,7 +21,7 @@ class OmxDecoder;
|
|||
|
||||
namespace android {
|
||||
|
||||
class OmxDecoder : public OMXCodecProxy::EventListener {
|
||||
class OmxDecoder : public OMXCodecProxy::CodecResourceListener {
|
||||
typedef MPAPI::AudioFrame AudioFrame;
|
||||
typedef MPAPI::VideoFrame VideoFrame;
|
||||
typedef mozilla::MP3FrameParser MP3FrameParser;
|
||||
|
@ -28,6 +29,7 @@ class OmxDecoder : public OMXCodecProxy::EventListener {
|
|||
typedef mozilla::AbstractMediaDecoder AbstractMediaDecoder;
|
||||
typedef mozilla::layers::FenceHandle FenceHandle;
|
||||
typedef mozilla::layers::TextureClient TextureClient;
|
||||
typedef mozilla::MediaOmxCommonReader::MediaResourcePromise MediaResourcePromise;
|
||||
|
||||
enum {
|
||||
kPreferSoftwareCodecs = 1,
|
||||
|
@ -37,7 +39,6 @@ class OmxDecoder : public OMXCodecProxy::EventListener {
|
|||
|
||||
enum {
|
||||
kNotifyPostReleaseVideoBuffer = 'noti',
|
||||
kNotifyStatusChanged = 'stat'
|
||||
};
|
||||
|
||||
AbstractMediaDecoder *mDecoder;
|
||||
|
@ -120,6 +121,8 @@ class OmxDecoder : public OMXCodecProxy::EventListener {
|
|||
// 'true' if a read from the audio stream was done while reading the metadata
|
||||
bool mAudioMetadataRead;
|
||||
|
||||
mozilla::MediaPromiseHolder<MediaResourcePromise> mMediaResourcePromise;
|
||||
|
||||
void ReleaseVideoBuffer();
|
||||
void ReleaseAudioBuffer();
|
||||
// Call with mSeekLock held.
|
||||
|
@ -141,8 +144,9 @@ public:
|
|||
OmxDecoder(MediaResource *aResource, AbstractMediaDecoder *aDecoder);
|
||||
~OmxDecoder();
|
||||
|
||||
// MediaResourceManagerClient::EventListener
|
||||
virtual void statusChanged();
|
||||
// OMXCodecProxy::CodecResourceListener
|
||||
virtual void codecReserved();
|
||||
virtual void codecCanceled();
|
||||
|
||||
// The MediaExtractor provides essential information for creating OMXCodec
|
||||
// instance. Such as video/audio codec, we can retrieve them through the
|
||||
|
@ -158,11 +162,7 @@ public:
|
|||
// mDurationUs and video/audio metadata.
|
||||
bool EnsureMetadata();
|
||||
|
||||
// Only called by MediaOmxDecoder, do not call this function arbitrarily.
|
||||
// See bug 1050667.
|
||||
bool IsWaitingMediaResources();
|
||||
|
||||
bool AllocateMediaResources();
|
||||
nsRefPtr<MediaResourcePromise> AllocateMediaResources();
|
||||
void ReleaseMediaResources();
|
||||
bool SetVideoFormat();
|
||||
bool SetAudioFormat();
|
||||
|
|
|
@ -86,22 +86,27 @@ void RtspOmxReader::EnsureActive() {
|
|||
MediaOmxReader::EnsureActive();
|
||||
}
|
||||
|
||||
nsresult RtspOmxReader::ReadMetadata(MediaInfo *aInfo, MetadataTags **aTags)
|
||||
nsRefPtr<MediaDecoderReader::MetadataPromise>
|
||||
RtspOmxReader::AsyncReadMetadata()
|
||||
{
|
||||
// Send a PLAY command to the RTSP server before reading metadata.
|
||||
// Because we might need some decoded samples to ensure we have configuration.
|
||||
mRtspResource->DisablePlayoutDelay();
|
||||
EnsureActive();
|
||||
nsresult rv = MediaOmxReader::ReadMetadata(aInfo, aTags);
|
||||
|
||||
if (rv == NS_OK && !IsWaitingMediaResources()) {
|
||||
mRtspResource->EnablePlayoutDelay();
|
||||
} else if (IsWaitingMediaResources()) {
|
||||
// Send a PAUSE to the RTSP server because the underlying media resource is
|
||||
// not ready.
|
||||
SetIdle();
|
||||
}
|
||||
return rv;
|
||||
nsRefPtr<MediaDecoderReader::MetadataPromise> p =
|
||||
MediaOmxReader::AsyncReadMetadata();
|
||||
|
||||
// Send a PAUSE to the RTSP server because the underlying media resource is
|
||||
// not ready.
|
||||
SetIdle();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void RtspOmxReader::HandleResourceAllocated()
|
||||
{
|
||||
MediaOmxReader::HandleResourceAllocated();
|
||||
mRtspResource->EnablePlayoutDelay();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -66,8 +66,10 @@ public:
|
|||
|
||||
virtual void SetIdle() override;
|
||||
|
||||
virtual nsresult ReadMetadata(MediaInfo *aInfo, MetadataTags **aTags)
|
||||
final override;
|
||||
virtual nsRefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata()
|
||||
override;
|
||||
|
||||
virtual void HandleResourceAllocated() override;
|
||||
|
||||
private:
|
||||
// A pointer to RtspMediaResource for calling the Rtsp specific function.
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_CONTEXT = "chrome";
|
||||
|
||||
let XPCOMUtils = Cu.import("resource://gre/modules/XPCOMUtils.jsm").XPCOMUtils;
|
||||
let Promise = Cu.import("resource://gre/modules/Promise.jsm").Promise;
|
||||
|
||||
let mobileConnectionService =
|
||||
Cc["@mozilla.org/mobileconnection/gonkmobileconnectionservice;1"]
|
||||
.getService(Ci.nsIMobileConnectionService);
|
||||
ok(mobileConnectionService,
|
||||
"mobileConnectionService.constructor is " + mobileConnectionService.constructor);
|
||||
|
||||
let _pendingEmulatorShellCmdCount = 0;
|
||||
|
||||
/**
|
||||
* Send emulator shell command with safe guard.
|
||||
*
|
||||
* We should only call |finish()| after all emulator shell command transactions
|
||||
* end, so here comes with the pending counter. Resolve when the emulator
|
||||
* shell gives response. Never reject.
|
||||
*
|
||||
* Fulfill params:
|
||||
* result -- an array of emulator shell response lines.
|
||||
*
|
||||
* @param aCommands
|
||||
* A string array commands to be passed to emulator through adb shell.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function runEmulatorShellCmdSafe(aCommands) {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
++_pendingEmulatorShellCmdCount;
|
||||
runEmulatorShell(aCommands, function(aResult) {
|
||||
--_pendingEmulatorShellCmdCount;
|
||||
|
||||
ok(true, "Emulator shell response: " + JSON.stringify(aResult));
|
||||
aResolve(aResult);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nsIMobileConnection by clientId
|
||||
*
|
||||
* @param aClient [optional]
|
||||
* A numeric DSDS client id. Default: 0.
|
||||
*
|
||||
* @return A nsIMobileConnection.
|
||||
*/
|
||||
function getMobileConnection(aClientId = 0) {
|
||||
let mobileConnection = mobileConnectionService.getItemByServiceId(0);
|
||||
ok(mobileConnection,
|
||||
"mobileConnection.constructor is " + mobileConnection.constructor);
|
||||
return mobileConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Neighboring Cell Ids.
|
||||
*
|
||||
* Fulfill params:
|
||||
* An array of nsINeighboringCellInfo.
|
||||
* Reject params:
|
||||
* 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure'
|
||||
*
|
||||
* @param aClient [optional]
|
||||
* A numeric DSDS client id. Default: 0.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function getNeighboringCellIds(aClientId = 0) {
|
||||
let mobileConnection = getMobileConnection(aClientId);
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
ok(true, "getNeighboringCellIds");
|
||||
mobileConnection.getNeighboringCellIds({
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINeighboringCellIdsCallback]),
|
||||
notifyGetNeighboringCellIds: function(aCount, aResults) {
|
||||
aResolve(aResults);
|
||||
},
|
||||
notifyGetNeighboringCellIdsFailed: function(aErrorMsg) {
|
||||
aReject(aErrorMsg);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cell Info List.
|
||||
*
|
||||
* Fulfill params:
|
||||
* An array of nsICellInfo.
|
||||
* Reject params:
|
||||
* 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure'
|
||||
*
|
||||
* @param aClient [optional]
|
||||
* A numeric DSDS client id. Default: 0.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function getCellInfoList(aClientId = 0) {
|
||||
let mobileConnection = getMobileConnection(aClientId);
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
ok(true, "getCellInfoList");
|
||||
mobileConnection.getCellInfoList({
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICellInfoListCallback]),
|
||||
notifyGetCellInfoList: function(aCount, aResults) {
|
||||
aResolve(aResults);
|
||||
},
|
||||
notifyGetCellInfoListFailed: function(aErrorMsg) {
|
||||
aReject(aErrorMsg);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for pending emulator transactions and call |finish()|.
|
||||
*/
|
||||
function cleanUp() {
|
||||
// Use ok here so that we have at least one test run.
|
||||
ok(true, ":: CLEANING UP ::");
|
||||
|
||||
waitFor(finish, function() {
|
||||
return _pendingEmulatorShellCmdCount === 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test routine helper.
|
||||
*
|
||||
* This helper does nothing but clean-ups.
|
||||
*
|
||||
* @param aTestCaseMain
|
||||
* A function that takes no parameter.
|
||||
*/
|
||||
function startTestBase(aTestCaseMain) {
|
||||
return Promise.resolve()
|
||||
.then(aTestCaseMain)
|
||||
.catch((aException) => {
|
||||
ok(false, "promise rejects during test: " + aException);
|
||||
})
|
||||
.then(cleanUp);
|
||||
}
|
|
@ -35,3 +35,4 @@ disabled = Bug 979137
|
|||
[test_mobile_clir.js]
|
||||
[test_mobile_clir_radio_off.js]
|
||||
[test_mobile_neighboring_cell_ids.js]
|
||||
[test_mobile_cell_Info_list.js]
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = "head_chrome.js";
|
||||
|
||||
function getAndroidVersion() {
|
||||
return runEmulatorShellCmdSafe(["getprop", "ro.build.version.sdk"])
|
||||
.then(aResults => aResults[0]);
|
||||
}
|
||||
|
||||
// Start test.
|
||||
startTestBase(function() {
|
||||
return getAndroidVersion().
|
||||
then((aVersion) => {
|
||||
if (aVersion < "19") {
|
||||
// Only emulator-kk supports REQUEST_GET_CELL_INFO_LIST, so we skip this
|
||||
// test if in older android version.
|
||||
log("Skip test: AndroidVersion: " + aVersion);
|
||||
return;
|
||||
}
|
||||
|
||||
return getCellInfoList()
|
||||
.then((aResults) => {
|
||||
// Cell Info are hard-coded in hardware/ril/reference-ril/reference-ril.c.
|
||||
is(aResults.length, 1, "Check number of cell Info");
|
||||
|
||||
let cell = aResults[0];
|
||||
is(cell.type, Ci.nsICellInfo.CELL_INFO_TYPE_GSM, "Check cell.type");
|
||||
is(cell.registered, true, "Check cell.registered");
|
||||
|
||||
ok(cell instanceof Ci.nsIGsmCellInfo,
|
||||
"cell.constructor is " + cell.constructor);
|
||||
|
||||
// The data hard-coded in hardware/ril/reference-ril/reference-ril.c
|
||||
// isn't correct (missing timeStampType), so we skip to check other
|
||||
// attributes first until we fix it.
|
||||
});
|
||||
});
|
||||
});
|
|
@ -2,37 +2,17 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 30000;
|
||||
// This test must run in chrome context.
|
||||
MARIONETTE_CONTEXT = "chrome";
|
||||
MARIONETTE_HEAD_JS = "head_chrome.js";
|
||||
|
||||
let Promise = Cu.import("resource://gre/modules/Promise.jsm").Promise;
|
||||
|
||||
let service = Cc["@mozilla.org/mobileconnection/mobileconnectionservice;1"]
|
||||
.getService(Ci.nsIMobileConnectionService);
|
||||
ok(service, "service.constructor is " + service.constructor);
|
||||
|
||||
let mobileConnection = service.getItemByServiceId(0);
|
||||
ok(mobileConnection, "mobileConnection.constructor is " + mobileConnection.constrctor);
|
||||
|
||||
function testGetNeighboringCellIds() {
|
||||
log("Test getting mobile neighboring cell ids");
|
||||
let deferred = Promise.defer();
|
||||
|
||||
mobileConnection.getNeighboringCellIds({
|
||||
notifyGetNeighboringCellIds: function(aResult) {
|
||||
deferred.resolve(aResult);
|
||||
},
|
||||
notifyGetNeighboringCellIdsFailed: function(aError) {
|
||||
deferred.reject(aError);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Start tests
|
||||
testGetNeighboringCellIds()
|
||||
.then(function resolve(aResult) {
|
||||
ok(false, "getNeighboringCellIds should not success");
|
||||
}, function reject(aError) {
|
||||
is(aError, "RequestNotSupported", "failed to getNeighboringCellIds");
|
||||
}).then(finish);
|
||||
// Start test.
|
||||
startTestBase(function() {
|
||||
// Emulator doesn't support REQUEST_GET_NEIGHBORING_CELL_IDS, so we expect to
|
||||
// get an 'RequestNotSupported' error here.
|
||||
return getNeighboringCellIds()
|
||||
.then(() => {
|
||||
ok(false, "should not success");
|
||||
}, (aErrorMsg) => {
|
||||
is(aErrorMsg, "RequestNotSupported",
|
||||
"Failed to getNeighboringCellIds: " + aErrorMsg);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1663,6 +1663,10 @@ nsPluginHost::GetSpecialType(const nsACString & aMIMEType)
|
|||
return eSpecialType_PDF;
|
||||
}
|
||||
|
||||
if (aMIMEType.LowerCaseEqualsASCII("application/vnd.unity")) {
|
||||
return eSpecialType_Unity;
|
||||
}
|
||||
|
||||
// Java registers variants of its MIME with parameters, e.g.
|
||||
// application/x-java-vm;version=1.3
|
||||
const nsACString &noParam = Substring(aMIMEType, 0, aMIMEType.FindChar(';'));
|
||||
|
|
|
@ -202,7 +202,9 @@ public:
|
|||
// Native widget quirks
|
||||
eSpecialType_PDF,
|
||||
// Native widget quirks
|
||||
eSpecialType_RealPlayer };
|
||||
eSpecialType_RealPlayer,
|
||||
// Native widget quirks
|
||||
eSpecialType_Unity };
|
||||
static SpecialType GetSpecialType(const nsACString & aMIMEType);
|
||||
|
||||
static nsresult PostPluginUnloadEvent(PRLibrary* aLibrary);
|
||||
|
|
|
@ -32,6 +32,7 @@ using mozilla::gfx::SharedDIBSurface;
|
|||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "ImageContainer.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -148,6 +149,8 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
|||
, mWinlessPopupSurrogateHWND(0)
|
||||
, mWinlessThrottleOldWndProc(0)
|
||||
, mWinlessHiddenMsgHWND(0)
|
||||
, mUnityGetMessageHook(NULL)
|
||||
, mUnitySendMessageHook(NULL)
|
||||
#endif // OS_WIN
|
||||
, mAsyncCallMutex("PluginInstanceChild::mAsyncCallMutex")
|
||||
#if defined(MOZ_WIDGET_COCOA)
|
||||
|
@ -194,6 +197,9 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
|||
#endif // OS_WIN
|
||||
#if defined(OS_WIN)
|
||||
InitPopupMenuHook();
|
||||
if (GetQuirks() & PluginModuleChild::QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
|
||||
SetUnityHooks();
|
||||
}
|
||||
#endif // OS_WIN
|
||||
}
|
||||
|
||||
|
@ -201,6 +207,9 @@ PluginInstanceChild::~PluginInstanceChild()
|
|||
{
|
||||
#if defined(OS_WIN)
|
||||
NS_ASSERTION(!mPluginWindowHWND, "Destroying PluginInstanceChild without NPP_Destroy?");
|
||||
if (GetQuirks() & PluginModuleChild::QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
|
||||
ClearUnityHooks();
|
||||
}
|
||||
#endif
|
||||
#if defined(MOZ_WIDGET_COCOA)
|
||||
if (mShColorSpace) {
|
||||
|
@ -1702,6 +1711,139 @@ PluginInstanceChild::HookSetWindowLongPtr()
|
|||
#endif
|
||||
}
|
||||
|
||||
class SetCaptureHookData
|
||||
{
|
||||
public:
|
||||
explicit SetCaptureHookData(HWND aHwnd)
|
||||
: mHwnd(aHwnd)
|
||||
, mHaveRect(false)
|
||||
{
|
||||
MOZ_ASSERT(aHwnd);
|
||||
mHaveRect = !!GetClientRect(aHwnd, &mCaptureRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if capture was released
|
||||
*/
|
||||
bool HandleMouseMsg(const MSG& aMsg)
|
||||
{
|
||||
// If the window belongs to Unity, the mouse button is up, and the mouse
|
||||
// has moved outside the client rect of the Unity window, release capture.
|
||||
if (aMsg.hwnd != mHwnd || !mHaveRect) {
|
||||
return false;
|
||||
}
|
||||
if (aMsg.message != WM_MOUSEMOVE && aMsg.message != WM_LBUTTONUP) {
|
||||
return false;
|
||||
}
|
||||
if ((aMsg.message == WM_MOUSEMOVE && (aMsg.wParam & MK_LBUTTON))) {
|
||||
return false;
|
||||
}
|
||||
POINT pt = { GET_X_LPARAM(aMsg.lParam), GET_Y_LPARAM(aMsg.lParam) };
|
||||
if (PtInRect(&mCaptureRect, pt)) {
|
||||
return false;
|
||||
}
|
||||
return !!ReleaseCapture();
|
||||
}
|
||||
|
||||
bool IsUnityLosingCapture(const CWPSTRUCT& aInfo) const
|
||||
{
|
||||
return aInfo.message == WM_CAPTURECHANGED &&
|
||||
aInfo.hwnd == mHwnd;
|
||||
}
|
||||
|
||||
private:
|
||||
HWND mHwnd;
|
||||
bool mHaveRect;
|
||||
RECT mCaptureRect;
|
||||
};
|
||||
|
||||
static StaticAutoPtr<SetCaptureHookData> sSetCaptureHookData;
|
||||
typedef HWND (WINAPI* User32SetCapture)(HWND);
|
||||
static User32SetCapture sUser32SetCaptureHookStub = nullptr;
|
||||
|
||||
HWND WINAPI
|
||||
PluginInstanceChild::SetCaptureHook(HWND aHwnd)
|
||||
{
|
||||
// Don't do anything unless aHwnd belongs to Unity
|
||||
wchar_t className[256] = {0};
|
||||
int numChars = GetClassNameW(aHwnd, className, ArrayLength(className));
|
||||
NS_NAMED_LITERAL_STRING(unityClassName, "Unity.WebPlayer");
|
||||
if (numChars == unityClassName.Length() && unityClassName == className) {
|
||||
sSetCaptureHookData = new SetCaptureHookData(aHwnd);
|
||||
}
|
||||
return sUser32SetCaptureHookStub(aHwnd);
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::SetUnityHooks()
|
||||
{
|
||||
if (!(GetQuirks() & PluginModuleChild::QUIRK_UNITY_FIXUP_MOUSE_CAPTURE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sUser32Intercept.Init("user32.dll");
|
||||
if (!sUser32SetCaptureHookStub) {
|
||||
sUser32Intercept.AddHook("SetCapture",
|
||||
reinterpret_cast<intptr_t>(SetCaptureHook),
|
||||
(void**) &sUser32SetCaptureHookStub);
|
||||
}
|
||||
if (!mUnityGetMessageHook) {
|
||||
mUnityGetMessageHook = SetWindowsHookEx(WH_GETMESSAGE,
|
||||
&UnityGetMessageHookProc, NULL,
|
||||
GetCurrentThreadId());
|
||||
}
|
||||
if (!mUnitySendMessageHook) {
|
||||
mUnitySendMessageHook = SetWindowsHookEx(WH_CALLWNDPROC,
|
||||
&UnitySendMessageHookProc,
|
||||
NULL, GetCurrentThreadId());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::ClearUnityHooks()
|
||||
{
|
||||
if (mUnityGetMessageHook) {
|
||||
UnhookWindowsHookEx(mUnityGetMessageHook);
|
||||
mUnityGetMessageHook = NULL;
|
||||
}
|
||||
if (mUnitySendMessageHook) {
|
||||
UnhookWindowsHookEx(mUnitySendMessageHook);
|
||||
mUnitySendMessageHook = NULL;
|
||||
}
|
||||
sSetCaptureHookData = nullptr;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
PluginInstanceChild::UnityGetMessageHookProc(int aCode, WPARAM aWparam,
|
||||
LPARAM aLParam)
|
||||
{
|
||||
if (aCode >= 0) {
|
||||
MSG* info = reinterpret_cast<MSG*>(aLParam);
|
||||
MOZ_ASSERT(info);
|
||||
if (sSetCaptureHookData && sSetCaptureHookData->HandleMouseMsg(*info)) {
|
||||
sSetCaptureHookData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return CallNextHookEx(0, aCode, aWparam, aLParam);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
PluginInstanceChild::UnitySendMessageHookProc(int aCode, WPARAM aWparam,
|
||||
LPARAM aLParam)
|
||||
{
|
||||
if (aCode >= 0) {
|
||||
CWPSTRUCT* info = reinterpret_cast<CWPSTRUCT*>(aLParam);
|
||||
MOZ_ASSERT(info);
|
||||
if (sSetCaptureHookData &&
|
||||
sSetCaptureHookData->IsUnityLosingCapture(*info)) {
|
||||
sSetCaptureHookData = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return CallNextHookEx(0, aCode, aWparam, aLParam);
|
||||
}
|
||||
|
||||
/* windowless track popup menu helpers */
|
||||
|
||||
BOOL
|
||||
|
|
|
@ -287,6 +287,8 @@ private:
|
|||
void SetupFlashMsgThrottle();
|
||||
void UnhookWinlessFlashThrottle();
|
||||
void HookSetWindowLongPtr();
|
||||
void SetUnityHooks();
|
||||
void ClearUnityHooks();
|
||||
static inline bool SetWindowLongHookCheck(HWND hWnd,
|
||||
int nIndex,
|
||||
LONG_PTR newLong);
|
||||
|
@ -306,6 +308,9 @@ private:
|
|||
int nReserved,
|
||||
HWND hWnd,
|
||||
CONST RECT *prcRect);
|
||||
static HWND WINAPI SetCaptureHook(HWND aHwnd);
|
||||
static LRESULT CALLBACK UnityGetMessageHookProc(int aCode, WPARAM aWparam, LPARAM aLParam);
|
||||
static LRESULT CALLBACK UnitySendMessageHookProc(int aCode, WPARAM aWparam, LPARAM aLParam);
|
||||
static BOOL CALLBACK EnumThreadWindowsCallback(HWND hWnd,
|
||||
LPARAM aParam);
|
||||
static LRESULT CALLBACK WinlessHiddenFlashWndProc(HWND hWnd,
|
||||
|
@ -397,6 +402,8 @@ private:
|
|||
nsIntPoint mPluginSize;
|
||||
WNDPROC mWinlessThrottleOldWndProc;
|
||||
HWND mWinlessHiddenMsgHWND;
|
||||
HHOOK mUnityGetMessageHook;
|
||||
HHOOK mUnitySendMessageHook;
|
||||
#endif
|
||||
|
||||
friend class ChildAsyncCall;
|
||||
|
|
|
@ -2153,6 +2153,12 @@ PluginModuleChild::InitQuirksModes(const nsCString& aMimeType)
|
|||
mQuirks |= QUIRK_ALLOW_OFFLINE_RENDERER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OS_WIN
|
||||
if (specialType == nsPluginHost::eSpecialType_Unity) {
|
||||
mQuirks |= QUIRK_UNITY_FIXUP_MOUSE_CAPTURE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -286,6 +286,8 @@ public:
|
|||
// NPN_GetValue(NPNVdocumentOrigin) call before trying to dereference
|
||||
// its char* output.
|
||||
QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN = 1 << 11,
|
||||
// Win: Addresses a Unity bug with mouse capture.
|
||||
QUIRK_UNITY_FIXUP_MOUSE_CAPTURE = 1 << 12,
|
||||
};
|
||||
|
||||
int GetQuirks() { return mQuirks; }
|
||||
|
|
|
@ -37,6 +37,7 @@ struct RunnableMethodTraits<PluginProcessParent>
|
|||
PluginProcessParent::PluginProcessParent(const std::string& aPluginFilePath) :
|
||||
GeckoChildProcessHost(GeckoProcessType_Plugin),
|
||||
mPluginFilePath(aPluginFilePath),
|
||||
mTaskFactory(this),
|
||||
mMainMsgLoop(MessageLoop::current()),
|
||||
mRunCompleteTaskImmediately(false)
|
||||
{
|
||||
|
@ -215,7 +216,7 @@ PluginProcessParent::OnChannelConnected(int32_t peer_pid)
|
|||
GeckoChildProcessHost::OnChannelConnected(peer_pid);
|
||||
if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) {
|
||||
mLaunchCompleteTask->SetLaunchSucceeded();
|
||||
mMainMsgLoop->PostTask(FROM_HERE, NewRunnableMethod(this,
|
||||
mMainMsgLoop->PostTask(FROM_HERE, mTaskFactory.NewRunnableMethod(
|
||||
&PluginProcessParent::RunLaunchCompleteTask));
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +226,7 @@ PluginProcessParent::OnChannelError()
|
|||
{
|
||||
GeckoChildProcessHost::OnChannelError();
|
||||
if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) {
|
||||
mMainMsgLoop->PostTask(FROM_HERE, NewRunnableMethod(this,
|
||||
mMainMsgLoop->PostTask(FROM_HERE, mTaskFactory.NewRunnableMethod(
|
||||
&PluginProcessParent::RunLaunchCompleteTask));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "chrome/common/child_process_host.h"
|
||||
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
#include "mozilla/plugins/TaskFactory.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIRunnable.h"
|
||||
|
@ -80,6 +81,7 @@ private:
|
|||
void RunLaunchCompleteTask();
|
||||
|
||||
std::string mPluginFilePath;
|
||||
TaskFactory<PluginProcessParent> mTaskFactory;
|
||||
UniquePtr<LaunchCompleteTask> mLaunchCompleteTask;
|
||||
MessageLoop* mMainMsgLoop;
|
||||
bool mRunCompleteTaskImmediately;
|
||||
|
|
|
@ -68,10 +68,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
|||
]
|
||||
|
||||
if CONFIG['MOZ_ENABLE_QT']:
|
||||
GENERATED_SOURCES += [
|
||||
'moc_NestedLoopTimer.cpp',
|
||||
]
|
||||
SOURCES += [
|
||||
'!moc_NestedLoopTimer.cpp',
|
||||
'NestedLoopTimer.cpp',
|
||||
'PluginHelperQt.cpp',
|
||||
]
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
|
||||
SharedLibrary('nptestjava')
|
||||
|
||||
relative_path = '..'
|
||||
relative_path = 'javaplugin'
|
||||
include('../testplugin.mozbuild')
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
|
||||
SharedLibrary('npsecondtest')
|
||||
|
||||
relative_path = '..'
|
||||
relative_path = 'secondplugin'
|
||||
include('../testplugin.mozbuild')
|
||||
|
|
|
@ -6,35 +6,35 @@
|
|||
|
||||
DIST_INSTALL = False
|
||||
|
||||
UNIFIED_SOURCES += [ '%s/%s' % (relative_path, p) for p in [
|
||||
UNIFIED_SOURCES += [
|
||||
'nptest.cpp',
|
||||
'nptest_utils.cpp',
|
||||
]]
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nptest_name.cpp',
|
||||
'%s/nptest_name.cpp' % relative_path,
|
||||
]
|
||||
|
||||
toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
||||
if toolkit == 'cocoa':
|
||||
UNIFIED_SOURCES += [
|
||||
relative_path + '/nptest_macosx.mm'
|
||||
'nptest_macosx.mm'
|
||||
]
|
||||
elif toolkit in ('gtk2', 'gtk3'):
|
||||
UNIFIED_SOURCES += [
|
||||
relative_path + '/nptest_gtk2.cpp',
|
||||
'nptest_gtk2.cpp',
|
||||
]
|
||||
elif toolkit == 'android':
|
||||
UNIFIED_SOURCES += [
|
||||
relative_path + '/nptest_droid.cpp',
|
||||
'nptest_droid.cpp',
|
||||
]
|
||||
elif toolkit == 'qt':
|
||||
UNIFIED_SOURCES += [
|
||||
relative_path + '/nptest_qt.cpp',
|
||||
'nptest_qt.cpp',
|
||||
]
|
||||
elif toolkit == 'windows':
|
||||
UNIFIED_SOURCES += [
|
||||
relative_path + '/nptest_windows.cpp',
|
||||
'nptest_windows.cpp',
|
||||
]
|
||||
OS_LIBS += [
|
||||
'msimg32',
|
||||
|
|
|
@ -5616,7 +5616,6 @@ RilObject.prototype[REQUEST_VOICE_RADIO_TECH] = function REQUEST_VOICE_RADIO_TEC
|
|||
let radioTech = this.context.Buf.readInt32List();
|
||||
this._processRadioTech(radioTech[0]);
|
||||
};
|
||||
RilObject.prototype[REQUEST_GET_CELL_INFO_LIST] = null;
|
||||
RilObject.prototype[REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE] = null;
|
||||
RilObject.prototype[REQUEST_SET_INITIAL_ATTACH_APN] = null;
|
||||
RilObject.prototype[REQUEST_IMS_REGISTRATION_STATE] = null;
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if CONFIG['MOZ_ENABLE_QT5GEOPOSITION']:
|
||||
GENERATED_SOURCES += [
|
||||
'moc_QTMLocationProvider.cpp',
|
||||
]
|
||||
SOURCES += [
|
||||
'!moc_QTMLocationProvider.cpp',
|
||||
'QTMLocationProvider.cpp',
|
||||
]
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "nsIIOService.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsIStreamLoader.h"
|
||||
#include "nsIStreamListenerTee.h"
|
||||
#include "nsIThreadRetargetableRequest.h"
|
||||
|
@ -422,7 +421,7 @@ private:
|
|||
bool mFailed;
|
||||
nsCOMPtr<nsIInputStreamPump> mPump;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
nsCString mSecurityInfo;
|
||||
ChannelInfo mChannelInfo;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(CacheScriptLoader, nsIStreamLoaderObserver)
|
||||
|
@ -589,19 +588,9 @@ private:
|
|||
new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
|
||||
ir->SetBody(mReader);
|
||||
|
||||
// Set the security info of the channel on the response so that it's
|
||||
// Set the channel info of the channel on the response so that it's
|
||||
// saved in the cache.
|
||||
nsCOMPtr<nsISupports> infoObj;
|
||||
channel->GetSecurityInfo(getter_AddRefs(infoObj));
|
||||
if (infoObj) {
|
||||
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(infoObj);
|
||||
if (serializable) {
|
||||
ir->SetSecurityInfo(serializable);
|
||||
MOZ_ASSERT(!ir->GetSecurityInfo().IsEmpty());
|
||||
} else {
|
||||
NS_WARNING("A non-serializable object was obtained from nsIChannel::GetSecurityInfo()!");
|
||||
}
|
||||
}
|
||||
ir->InitChannelInfo(channel);
|
||||
|
||||
nsRefPtr<Response> response = new Response(mCacheCreator->Global(), ir);
|
||||
|
||||
|
@ -965,18 +954,9 @@ private:
|
|||
// Take care of the base URI first.
|
||||
mWorkerPrivate->SetBaseURI(finalURI);
|
||||
|
||||
// Store the security info if needed.
|
||||
// Store the channel info if needed.
|
||||
if (mWorkerPrivate->IsServiceWorker()) {
|
||||
nsCOMPtr<nsISupports> infoObj;
|
||||
channel->GetSecurityInfo(getter_AddRefs(infoObj));
|
||||
if (infoObj) {
|
||||
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(infoObj);
|
||||
if (serializable) {
|
||||
mWorkerPrivate->SetSecurityInfo(serializable);
|
||||
} else {
|
||||
NS_WARNING("A non-serializable object was obtained from nsIChannel::GetSecurityInfo()!");
|
||||
}
|
||||
}
|
||||
mWorkerPrivate->InitChannelInfo(channel);
|
||||
}
|
||||
|
||||
// Now to figure out which principal to give this worker.
|
||||
|
@ -1047,7 +1027,8 @@ private:
|
|||
|
||||
void
|
||||
DataReceivedFromCache(uint32_t aIndex, const uint8_t* aString,
|
||||
uint32_t aStringLen, const nsCString& aSecurityInfo)
|
||||
uint32_t aStringLen,
|
||||
const ChannelInfo& aChannelInfo)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aIndex < mLoadInfos.Length());
|
||||
|
@ -1075,7 +1056,7 @@ private:
|
|||
MOZ_ASSERT(principal);
|
||||
nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup();
|
||||
MOZ_ASSERT(loadGroup);
|
||||
mWorkerPrivate->SetSecurityInfo(aSecurityInfo);
|
||||
mWorkerPrivate->InitChannelInfo(aChannelInfo);
|
||||
// Needed to initialize the principal info. This is fine because
|
||||
// the cache principal cannot change, unlike the channel principal.
|
||||
mWorkerPrivate->SetPrincipal(principal, loadGroup);
|
||||
|
@ -1429,11 +1410,11 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx,
|
|||
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
response->GetBody(getter_AddRefs(inputStream));
|
||||
mSecurityInfo = response->GetSecurityInfo();
|
||||
mChannelInfo = response->GetChannelInfo();
|
||||
|
||||
if (!inputStream) {
|
||||
mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached;
|
||||
mRunnable->DataReceivedFromCache(mIndex, (uint8_t*)"", 0, mSecurityInfo);
|
||||
mRunnable->DataReceivedFromCache(mIndex, (uint8_t*)"", 0, mChannelInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1489,7 +1470,7 @@ CacheScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aCont
|
|||
|
||||
mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached;
|
||||
|
||||
mRunnable->DataReceivedFromCache(mIndex, aString, aStringLen, mSecurityInfo);
|
||||
mRunnable->DataReceivedFromCache(mIndex, aString, aStringLen, mChannelInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,14 +98,14 @@ class FinishResponse final : public nsRunnable
|
|||
{
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel;
|
||||
nsRefPtr<InternalResponse> mInternalResponse;
|
||||
nsCString mWorkerSecurityInfo;
|
||||
ChannelInfo mWorkerChannelInfo;
|
||||
public:
|
||||
FinishResponse(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||
InternalResponse* aInternalResponse,
|
||||
const nsCString& aWorkerSecurityInfo)
|
||||
const ChannelInfo& aWorkerChannelInfo)
|
||||
: mChannel(aChannel)
|
||||
, mInternalResponse(aInternalResponse)
|
||||
, mWorkerSecurityInfo(aWorkerSecurityInfo)
|
||||
, mWorkerChannelInfo(aWorkerChannelInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -114,19 +114,17 @@ public:
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
nsCOMPtr<nsISupports> infoObj;
|
||||
nsAutoCString securityInfo(mInternalResponse->GetSecurityInfo());
|
||||
if (securityInfo.IsEmpty()) {
|
||||
ChannelInfo channelInfo;
|
||||
if (mInternalResponse->GetChannelInfo().IsInitialized()) {
|
||||
channelInfo = mInternalResponse->GetChannelInfo();
|
||||
} else {
|
||||
// We are dealing with a synthesized response here, so fall back to the
|
||||
// security info for the worker script.
|
||||
securityInfo = mWorkerSecurityInfo;
|
||||
// channel info for the worker script.
|
||||
channelInfo = mWorkerChannelInfo;
|
||||
}
|
||||
nsresult rv = NS_DeserializeObject(securityInfo, getter_AddRefs(infoObj));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mChannel->SetSecurityInfo(infoObj);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
nsresult rv = mChannel->SetChannelInfo(&channelInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mChannel->SynthesizeStatus(mInternalResponse->GetStatus(), mInternalResponse->GetStatusText());
|
||||
|
@ -169,14 +167,14 @@ struct RespondWithClosure
|
|||
{
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel;
|
||||
nsRefPtr<InternalResponse> mInternalResponse;
|
||||
nsCString mWorkerSecurityInfo;
|
||||
ChannelInfo mWorkerChannelInfo;
|
||||
|
||||
RespondWithClosure(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||
InternalResponse* aInternalResponse,
|
||||
const nsCString& aWorkerSecurityInfo)
|
||||
const ChannelInfo& aWorkerChannelInfo)
|
||||
: mInterceptedChannel(aChannel)
|
||||
, mInternalResponse(aInternalResponse)
|
||||
, mWorkerSecurityInfo(aWorkerSecurityInfo)
|
||||
, mWorkerChannelInfo(aWorkerChannelInfo)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -188,7 +186,7 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
|
|||
if (NS_SUCCEEDED(aStatus)) {
|
||||
event = new FinishResponse(data->mInterceptedChannel,
|
||||
data->mInternalResponse,
|
||||
data->mWorkerSecurityInfo);
|
||||
data->mWorkerChannelInfo);
|
||||
} else {
|
||||
event = new CancelChannelRunnable(data->mInterceptedChannel);
|
||||
}
|
||||
|
@ -255,7 +253,7 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
|||
worker->AssertIsOnWorkerThread();
|
||||
|
||||
nsAutoPtr<RespondWithClosure> closure(
|
||||
new RespondWithClosure(mInterceptedChannel, ir, worker->GetSecurityInfo()));
|
||||
new RespondWithClosure(mInterceptedChannel, ir, worker->GetChannelInfo()));
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
response->GetBody(getter_AddRefs(body));
|
||||
// Errors and redirects may not have a body.
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "mozilla/dom/cache/CacheStorage.h"
|
||||
#include "mozilla/dom/cache/Cache.h"
|
||||
#include "nsIThreadRetargetableRequest.h"
|
||||
#include "nsSerializationHelper.h"
|
||||
|
||||
#include "nsIPrincipal.h"
|
||||
#include "Workers.h"
|
||||
|
@ -446,9 +445,9 @@ public:
|
|||
}
|
||||
|
||||
void
|
||||
SetSecurityInfo(nsISerializable* aSecurityInfo)
|
||||
InitChannelInfo(nsIChannel* aChannel)
|
||||
{
|
||||
NS_SerializeToString(aSecurityInfo, mSecurityInfo);
|
||||
mChannelInfo.InitFromChannel(aChannel);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -545,7 +544,7 @@ private:
|
|||
new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
|
||||
ir->SetBody(body);
|
||||
|
||||
ir->SetSecurityInfo(mSecurityInfo);
|
||||
ir->InitChannelInfo(mChannelInfo);
|
||||
|
||||
nsRefPtr<Response> response = new Response(aCache->GetGlobalObject(), ir);
|
||||
|
||||
|
@ -577,7 +576,7 @@ private:
|
|||
// Only used if the network script has changed and needs to be cached.
|
||||
nsString mNewCacheName;
|
||||
|
||||
nsCString mSecurityInfo;
|
||||
ChannelInfo mChannelInfo;
|
||||
|
||||
nsCString mMaxScope;
|
||||
|
||||
|
@ -606,16 +605,7 @@ CompareNetwork::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
|||
MOZ_ASSERT(channel == mChannel);
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsISupports> infoObj;
|
||||
mChannel->GetSecurityInfo(getter_AddRefs(infoObj));
|
||||
if (infoObj) {
|
||||
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(infoObj);
|
||||
if (serializable) {
|
||||
mManager->SetSecurityInfo(serializable);
|
||||
} else {
|
||||
NS_WARNING("A non-serializable object was obtained from nsIChannel::GetSecurityInfo()!");
|
||||
}
|
||||
}
|
||||
mManager->InitChannelInfo(mChannel);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "nsIXPConnect.h"
|
||||
#include "nsPerformance.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsSerializationHelper.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "jsfriendapi.h"
|
||||
|
@ -4075,17 +4074,6 @@ WorkerPrivateParent<Derived>::SetPrincipal(nsIPrincipal* aPrincipal,
|
|||
PrincipalToPrincipalInfo(aPrincipal, mLoadInfo.mPrincipalInfo)));
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::SetSecurityInfo(nsISerializable* aSerializable)
|
||||
{
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
AssertIsOnMainThread();
|
||||
nsAutoCString securityInfo;
|
||||
NS_SerializeToString(aSerializable, securityInfo);
|
||||
SetSecurityInfo(securityInfo);
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
JSContext*
|
||||
WorkerPrivateParent<Derived>::ParentJSContext() const
|
||||
|
|
|
@ -498,24 +498,34 @@ public:
|
|||
return mLoadInfo.mServiceWorkerCacheName;
|
||||
}
|
||||
|
||||
const nsCString&
|
||||
GetSecurityInfo() const
|
||||
const ChannelInfo&
|
||||
GetChannelInfo() const
|
||||
{
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
return mLoadInfo.mSecurityInfo;
|
||||
return mLoadInfo.mChannelInfo;
|
||||
}
|
||||
|
||||
void
|
||||
SetSecurityInfo(const nsCString& aSecurityInfo)
|
||||
SetChannelInfo(const ChannelInfo& aChannelInfo)
|
||||
{
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mLoadInfo.mSecurityInfo.IsEmpty());
|
||||
mLoadInfo.mSecurityInfo = aSecurityInfo;
|
||||
MOZ_ASSERT(!mLoadInfo.mChannelInfo.IsInitialized());
|
||||
MOZ_ASSERT(aChannelInfo.IsInitialized());
|
||||
mLoadInfo.mChannelInfo = aChannelInfo;
|
||||
}
|
||||
|
||||
void
|
||||
SetSecurityInfo(nsISerializable* aSerializable);
|
||||
InitChannelInfo(nsIChannel* aChannel)
|
||||
{
|
||||
mLoadInfo.mChannelInfo.InitFromChannel(aChannel);
|
||||
}
|
||||
|
||||
void
|
||||
InitChannelInfo(const ChannelInfo& aChannelInfo)
|
||||
{
|
||||
mLoadInfo.mChannelInfo = aChannelInfo;
|
||||
}
|
||||
|
||||
// This is used to handle importScripts(). When the worker is first loaded
|
||||
// and executed, it happens in a sync loop. At this point it sets
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "nsILoadContext.h"
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "mozilla/dom/ChannelInfo.h"
|
||||
|
||||
#define BEGIN_WORKERS_NAMESPACE \
|
||||
namespace mozilla { namespace dom { namespace workers {
|
||||
|
@ -244,7 +245,7 @@ struct WorkerLoadInfo
|
|||
|
||||
nsString mServiceWorkerCacheName;
|
||||
|
||||
nsCString mSecurityInfo;
|
||||
ChannelInfo mChannelInfo;
|
||||
|
||||
uint64_t mWindowID;
|
||||
uint64_t mServiceWorkerID;
|
||||
|
|
|
@ -111,6 +111,7 @@ public:
|
|||
bool mLastUploadLengthComputable;
|
||||
bool mSeenLoadStart;
|
||||
bool mSeenUploadLoadStart;
|
||||
bool mOpening;
|
||||
|
||||
// Only touched on the main thread.
|
||||
bool mUploadEventListenersAttached;
|
||||
|
@ -126,7 +127,7 @@ public:
|
|||
mOuterEventStreamId(0), mOuterChannelId(0), mLastLoaded(0), mLastTotal(0),
|
||||
mLastUploadLoaded(0), mLastUploadTotal(0), mIsSyncXHR(false),
|
||||
mLastLengthComputable(false), mLastUploadLengthComputable(false),
|
||||
mSeenLoadStart(false), mSeenUploadLoadStart(false),
|
||||
mSeenLoadStart(false), mSeenUploadLoadStart(false), mOpening(false),
|
||||
mUploadEventListenersAttached(false), mMainThreadSeenLoadStart(false),
|
||||
mInOpen(false), mArrayBufferResponseWasTransferred(false)
|
||||
{ }
|
||||
|
@ -138,7 +139,7 @@ public:
|
|||
Init();
|
||||
|
||||
void
|
||||
Teardown();
|
||||
Teardown(bool aSendUnpin);
|
||||
|
||||
bool
|
||||
AddRemoveEventListeners(bool aUpload, bool aAdd);
|
||||
|
@ -308,7 +309,9 @@ private:
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
mProxy->Teardown();
|
||||
// This means the XHR was GC'd, so we can't be pinned, and we don't need to
|
||||
// try to unpin.
|
||||
mProxy->Teardown(/* aSendUnpin */ false);
|
||||
mProxy = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
|
@ -568,7 +571,7 @@ private:
|
|||
virtual nsresult
|
||||
MainThreadRun() override
|
||||
{
|
||||
mProxy->Teardown();
|
||||
mProxy->Teardown(/* aSendUnpin */ true);
|
||||
MOZ_ASSERT(!mProxy->mSyncLoopTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -941,7 +944,7 @@ Proxy::Init()
|
|||
}
|
||||
|
||||
void
|
||||
Proxy::Teardown()
|
||||
Proxy::Teardown(bool aSendUnpin)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
|
@ -954,10 +957,12 @@ Proxy::Teardown()
|
|||
mXHR->Abort();
|
||||
|
||||
if (mOutstandingSendCount) {
|
||||
nsRefPtr<XHRUnpinRunnable> runnable =
|
||||
new XHRUnpinRunnable(mWorkerPrivate, mXMLHttpRequestPrivate);
|
||||
if (!runnable->Dispatch(nullptr)) {
|
||||
NS_RUNTIMEABORT("We're going to hang at shutdown anyways.");
|
||||
if (aSendUnpin) {
|
||||
nsRefPtr<XHRUnpinRunnable> runnable =
|
||||
new XHRUnpinRunnable(mWorkerPrivate, mXMLHttpRequestPrivate);
|
||||
if (!runnable->Dispatch(nullptr)) {
|
||||
NS_RUNTIMEABORT("We're going to hang at shutdown anyways.");
|
||||
}
|
||||
}
|
||||
|
||||
if (mSyncLoopTarget) {
|
||||
|
@ -1547,7 +1552,11 @@ SendRunnable::MainThreadRun()
|
|||
variant = wvariant;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mProxy->mWorkerPrivate);
|
||||
// Send() has been already called.
|
||||
if (mProxy->mWorkerPrivate) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mProxy->mWorkerPrivate = mWorkerPrivate;
|
||||
|
||||
MOZ_ASSERT(!mProxy->mSyncLoopTarget);
|
||||
|
@ -1842,6 +1851,12 @@ XMLHttpRequest::SendInternal(const nsAString& aStringBody,
|
|||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
// No send() calls when open is running.
|
||||
if (mProxy->mOpening) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasUploadListeners = mUpload ? mUpload->HasListeners() : false;
|
||||
|
||||
MaybePin(aRv);
|
||||
|
@ -1927,12 +1942,15 @@ XMLHttpRequest::Open(const nsACString& aMethod, const nsAString& aUrl,
|
|||
mBackgroundRequest, mWithCredentials,
|
||||
mTimeout);
|
||||
|
||||
mProxy->mOpening = true;
|
||||
if (!runnable->Dispatch(mWorkerPrivate->GetJSContext())) {
|
||||
ReleaseProxy();
|
||||
mProxy->mOpening = false;
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
mProxy->mOpening = false;
|
||||
mProxy->mIsSyncXHR = !aAsync;
|
||||
}
|
||||
|
||||
|
|
|
@ -427,12 +427,20 @@ nsTextEditRules::CollapseSelectionToTrailingBRIfNeeded(Selection* aSelection)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(mEditor);
|
||||
|
||||
// If there is no selection ranges, we should set to the end of the editor.
|
||||
// This is usually performed in nsTextEditRules::Init(), however, if the
|
||||
// editor is reframed, this may be called by AfterEdit().
|
||||
if (!aSelection->RangeCount()) {
|
||||
mEditor->EndOfDocument();
|
||||
}
|
||||
|
||||
// if we are at the end of the textarea, we need to set the
|
||||
// selection to stick to the mozBR at the end of the textarea.
|
||||
int32_t selOffset;
|
||||
nsCOMPtr<nsIDOMNode> selNode;
|
||||
nsresult res;
|
||||
NS_ENSURE_STATE(mEditor);
|
||||
res = mEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(selNode), &selOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
|
|
|
@ -275,16 +275,20 @@ class UnboundnessFixer
|
|||
public:
|
||||
UnboundnessFixer() : mLayerCg(nullptr) {}
|
||||
|
||||
CGContextRef Check(CGContextRef baseCg, CompositionOp blend, const Rect* maskBounds = nullptr)
|
||||
CGContextRef Check(DrawTargetCG* dt, CompositionOp blend, const Rect* maskBounds = nullptr)
|
||||
{
|
||||
MOZ_ASSERT(baseCg);
|
||||
MOZ_ASSERT(dt->mCg);
|
||||
if (!IsOperatorBoundByMask(blend)) {
|
||||
mClipBounds = CGContextGetClipBoundingBox(baseCg);
|
||||
// The clip bounding box will be in user space so we need to clear our transform first
|
||||
CGContextSetCTM(dt->mCg, dt->mOriginalTransform);
|
||||
mClipBounds = CGContextGetClipBoundingBox(dt->mCg);
|
||||
|
||||
// If we're entirely clipped out or if the drawing operation covers the entire clip then
|
||||
// we don't need to create a temporary surface.
|
||||
if (CGRectIsEmpty(mClipBounds) ||
|
||||
(maskBounds && maskBounds->Contains(CGRectToRect(mClipBounds)))) {
|
||||
return baseCg;
|
||||
CGContextConcatCTM(dt->mCg, GfxMatrixToCGAffineTransform(dt->mTransform));
|
||||
return dt->mCg;
|
||||
}
|
||||
|
||||
// TransparencyLayers aren't blended using the blend mode so
|
||||
|
@ -292,7 +296,7 @@ class UnboundnessFixer
|
|||
|
||||
//XXX: The size here is in default user space units, of the layer relative to the graphics context.
|
||||
// is the clip bounds still correct if, for example, we have a scale applied to the context?
|
||||
mLayer = CGLayerCreateWithContext(baseCg, mClipBounds.size, nullptr);
|
||||
mLayer = CGLayerCreateWithContext(dt->mCg, mClipBounds.size, nullptr);
|
||||
mLayerCg = CGLayerGetContext(mLayer);
|
||||
// CGContext's default to have the origin at the bottom left
|
||||
// so flip it to the top left and adjust for the origin
|
||||
|
@ -302,23 +306,27 @@ class UnboundnessFixer
|
|||
}
|
||||
CGContextTranslateCTM(mLayerCg, -mClipBounds.origin.x, mClipBounds.origin.y + mClipBounds.size.height);
|
||||
CGContextScaleCTM(mLayerCg, 1, -1);
|
||||
CGContextConcatCTM(mLayerCg, GfxMatrixToCGAffineTransform(dt->mTransform));
|
||||
|
||||
return mLayerCg;
|
||||
} else {
|
||||
return baseCg;
|
||||
return dt->mCg;
|
||||
}
|
||||
}
|
||||
|
||||
void Fix(CGContextRef baseCg)
|
||||
void Fix(DrawTargetCG *dt)
|
||||
{
|
||||
if (mLayerCg) {
|
||||
// we pushed a layer so draw it to baseCg
|
||||
MOZ_ASSERT(baseCg);
|
||||
CGContextTranslateCTM(baseCg, 0, mClipBounds.size.height);
|
||||
CGContextScaleCTM(baseCg, 1, -1);
|
||||
// we pushed a layer so draw it to dt->mCg
|
||||
MOZ_ASSERT(dt->mCg);
|
||||
CGContextTranslateCTM(dt->mCg, 0, mClipBounds.size.height);
|
||||
CGContextScaleCTM(dt->mCg, 1, -1);
|
||||
mClipBounds.origin.y *= -1;
|
||||
CGContextDrawLayerAtPoint(baseCg, mClipBounds.origin, mLayer);
|
||||
CGContextDrawLayerAtPoint(dt->mCg, mClipBounds.origin, mLayer);
|
||||
CGContextRelease(mLayerCg);
|
||||
|
||||
// Reset the transform
|
||||
CGContextConcatCTM(dt->mCg, GfxMatrixToCGAffineTransform(dt->mTransform));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -339,15 +347,13 @@ DrawTargetCG::DrawSurface(SourceSurface *aSurface,
|
|||
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp, &aDest);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp, &aDest);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
|
||||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(aSurfOptions.mFilter));
|
||||
|
||||
CGImageRef image = GetRetainedImageFromSourceSurface(aSurface);
|
||||
|
@ -381,7 +387,7 @@ DrawTargetCG::DrawSurface(SourceSurface *aSurface,
|
|||
CGImageRelease(image);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
@ -894,7 +900,7 @@ DrawTargetCG::MaskSurface(const Pattern &aSource,
|
|||
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
|
@ -902,7 +908,6 @@ DrawTargetCG::MaskSurface(const Pattern &aSource,
|
|||
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
|
||||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
CGImageRef image = GetRetainedImageFromSourceSurface(aMask);
|
||||
|
||||
// use a negative-y so that the mask image draws right ways up
|
||||
|
@ -924,12 +929,18 @@ DrawTargetCG::MaskSurface(const Pattern &aSource,
|
|||
|
||||
CGImageRelease(image);
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawTargetCG::SetTransform(const Matrix &aTransform)
|
||||
{
|
||||
mTransform = aTransform;
|
||||
CGContextSetCTM(mCg, mOriginalTransform);
|
||||
CGContextConcatCTM(mCg, GfxMatrixToCGAffineTransform(aTransform));
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetCG::FillRect(const Rect &aRect,
|
||||
|
@ -945,7 +956,7 @@ DrawTargetCG::FillRect(const Rect &aRect,
|
|||
CGContextSaveGState(mCg);
|
||||
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp, &aRect);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp, &aRect);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
|
@ -954,8 +965,6 @@ DrawTargetCG::FillRect(const Rect &aRect,
|
|||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
if (isGradient(aPattern)) {
|
||||
CGContextClipToRect(cg, RectToCGRect(aRect));
|
||||
CGRect clipBounds = CGContextGetClipBoundingBox(cg);
|
||||
|
@ -989,7 +998,7 @@ DrawTargetCG::FillRect(const Rect &aRect,
|
|||
CGContextFillRect(cg, RectToCGRect(aRect));
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
|
@ -1169,7 +1178,7 @@ DrawTargetCG::StrokeLine(const Point &aP1, const Point &aP2, const Pattern &aPat
|
|||
CGContextSaveGState(mCg);
|
||||
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1177,8 +1186,6 @@ DrawTargetCG::StrokeLine(const Point &aP1, const Point &aP2, const Pattern &aPat
|
|||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
CGContextBeginPath(cg);
|
||||
CGContextMoveToPoint(cg, p1.x, p1.y);
|
||||
CGContextAddLineToPoint(cg, p2.x, p2.y);
|
||||
|
@ -1196,7 +1203,7 @@ DrawTargetCG::StrokeLine(const Point &aP1, const Point &aP2, const Pattern &aPat
|
|||
CGContextStrokePath(cg);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
|
@ -1247,7 +1254,7 @@ DrawTargetCG::StrokeRect(const Rect &aRect,
|
|||
CGContextSaveGState(mCg);
|
||||
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1267,8 +1274,6 @@ DrawTargetCG::StrokeRect(const Rect &aRect,
|
|||
CGContextSetShouldAntialias(cg,
|
||||
aDrawOptions.mAntialiasMode != AntialiasMode::NONE && !pixelAlignedStroke);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
SetStrokeOptions(cg, aStrokeOptions);
|
||||
|
||||
if (isGradient(aPattern)) {
|
||||
|
@ -1296,7 +1301,7 @@ DrawTargetCG::StrokeRect(const Rect &aRect,
|
|||
CGContextStrokePath(cg);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
|
@ -1311,7 +1316,6 @@ DrawTargetCG::ClearRect(const Rect &aRect)
|
|||
MarkChanged();
|
||||
|
||||
CGContextSaveGState(mCg);
|
||||
CGContextConcatCTM(mCg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
CGContextClearRect(mCg, RectToCGRect(aRect));
|
||||
|
||||
|
@ -1334,7 +1338,7 @@ DrawTargetCG::Stroke(const Path *aPath, const Pattern &aPattern, const StrokeOpt
|
|||
CGContextSaveGState(mCg);
|
||||
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1343,8 +1347,6 @@ DrawTargetCG::Stroke(const Path *aPath, const Pattern &aPattern, const StrokeOpt
|
|||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
|
||||
CGContextBeginPath(cg);
|
||||
|
||||
|
@ -1367,7 +1369,7 @@ DrawTargetCG::Stroke(const Path *aPath, const Pattern &aPattern, const StrokeOpt
|
|||
CGContextStrokePath(cg);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
|
@ -1386,7 +1388,7 @@ DrawTargetCG::Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions
|
|||
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1394,8 +1396,6 @@ DrawTargetCG::Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions
|
|||
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
|
||||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
CGContextBeginPath(cg);
|
||||
// XXX: we could put fill mode into the path fill rule if we wanted
|
||||
const PathCG *cgPath = static_cast<const PathCG*>(aPath);
|
||||
|
@ -1429,7 +1429,7 @@ DrawTargetCG::Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions
|
|||
CGContextFillPath(cg);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
|
@ -1515,7 +1515,7 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa
|
|||
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1526,8 +1526,6 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa
|
|||
CGContextSetShouldSmoothFonts(cg, aDrawOptions.mAntialiasMode == AntialiasMode::SUBPIXEL);
|
||||
}
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
ScaledFontMac* macFont = static_cast<ScaledFontMac*>(aFont);
|
||||
|
||||
// This code can execute millions of times in short periods, so we want to
|
||||
|
@ -1597,7 +1595,7 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa
|
|||
}
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(cg);
|
||||
}
|
||||
|
||||
|
@ -1625,6 +1623,7 @@ DrawTargetCG::CopySurface(SourceSurface *aSurface,
|
|||
// XXX: it might be more efficient for us to do the copy directly if we have access to the bits
|
||||
|
||||
CGContextSaveGState(mCg);
|
||||
CGContextSetCTM(mCg, mOriginalTransform);
|
||||
|
||||
// CopySurface ignores the clip, so we need to use private API to temporarily reset it
|
||||
CGContextResetClip(mCg);
|
||||
|
@ -1664,6 +1663,7 @@ DrawTargetCG::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
|
|||
|
||||
IntSize size = aSurface->GetSize();
|
||||
CGContextSaveGState(mCg);
|
||||
CGContextSetCTM(mCg, mOriginalTransform);
|
||||
//XXX do we need to do the fixup here?
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aOperator));
|
||||
|
||||
|
@ -1682,7 +1682,6 @@ DrawTargetCG::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
|
|||
|
||||
CGImageRelease(image);
|
||||
CGContextRestoreGState(mCg);
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1774,6 +1773,7 @@ DrawTargetCG::Init(BackendType aType,
|
|||
// so flip it to the top left
|
||||
CGContextTranslateCTM(mCg, 0, mSize.height);
|
||||
CGContextScaleCTM(mCg, 1, -1);
|
||||
mOriginalTransform = CGContextGetCTM(mCg);
|
||||
// See Bug 722164 for performance details
|
||||
// Medium or higher quality lead to expensive interpolation
|
||||
// for canvas we want to use low quality interpolation
|
||||
|
@ -1879,6 +1879,7 @@ DrawTargetCG::Init(CGContextRef cgContext, const IntSize &aSize)
|
|||
//
|
||||
// CGContextTranslateCTM(mCg, 0, mSize.height);
|
||||
// CGContextScaleCTM(mCg, 1, -1);
|
||||
mOriginalTransform = CGContextGetCTM(mCg);
|
||||
|
||||
mFormat = SurfaceFormat::B8G8R8A8;
|
||||
if (GetContextType(mCg) == CG_CONTEXT_TYPE_BITMAP) {
|
||||
|
@ -1963,18 +1964,9 @@ DrawTargetCG::PushClipRect(const Rect &aRect)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
mSavedClipBounds.push_back(CGContextGetClipBoundingBox(mCg));
|
||||
#endif
|
||||
|
||||
CGContextSaveGState(mCg);
|
||||
|
||||
/* We go through a bit of trouble to temporarilly set the transform
|
||||
* while we add the path */
|
||||
CGAffineTransform previousTransform = CGContextGetCTM(mCg);
|
||||
CGContextConcatCTM(mCg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
CGContextClipToRect(mCg, RectToCGRect(aRect));
|
||||
CGContextSetCTM(mCg, previousTransform);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1985,10 +1977,6 @@ DrawTargetCG::PushClip(const Path *aPath)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
mSavedClipBounds.push_back(CGContextGetClipBoundingBox(mCg));
|
||||
#endif
|
||||
|
||||
CGContextSaveGState(mCg);
|
||||
|
||||
CGContextBeginPath(mCg);
|
||||
|
@ -2009,7 +1997,6 @@ DrawTargetCG::PushClip(const Path *aPath)
|
|||
* while we add the path. XXX: this could be improved if we keep
|
||||
* the CTM as resident state on the DrawTarget. */
|
||||
CGContextSaveGState(mCg);
|
||||
CGContextConcatCTM(mCg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
CGContextAddPath(mCg, cgPath->GetPath());
|
||||
CGContextRestoreGState(mCg);
|
||||
|
||||
|
@ -2023,13 +2010,6 @@ void
|
|||
DrawTargetCG::PopClip()
|
||||
{
|
||||
CGContextRestoreGState(mCg);
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!mSavedClipBounds.empty(), "Unbalanced PopClip");
|
||||
MOZ_ASSERT(CGRectEqualToRect(mSavedClipBounds.back(), CGContextGetClipBoundingBox(mCg)),
|
||||
"PopClip didn't restore original clip");
|
||||
mSavedClipBounds.pop_back();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2064,8 +2044,6 @@ BorrowedCGContext::BorrowCGContextFromDrawTarget(DrawTarget *aDT)
|
|||
// save the state to make it easier for callers to avoid mucking with things
|
||||
CGContextSaveGState(cg);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(cgDT->mTransform));
|
||||
|
||||
return cg;
|
||||
}
|
||||
return nullptr;
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace mozilla {
|
|||
namespace gfx {
|
||||
|
||||
static inline CGAffineTransform
|
||||
GfxMatrixToCGAffineTransform(Matrix m)
|
||||
GfxMatrixToCGAffineTransform(const Matrix &m)
|
||||
{
|
||||
CGAffineTransform t;
|
||||
t.a = m._11;
|
||||
|
@ -113,6 +113,7 @@ class DrawTargetCG : public DrawTarget
|
|||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCG, override)
|
||||
friend class BorrowedCGContext;
|
||||
friend class UnboundnessFixer;
|
||||
friend class SourceSurfaceCGBitmapContext;
|
||||
DrawTargetCG();
|
||||
virtual ~DrawTargetCG();
|
||||
|
@ -173,6 +174,7 @@ public:
|
|||
|
||||
virtual IntSize GetSize() override { return mSize; }
|
||||
|
||||
virtual void SetTransform(const Matrix &aTransform) override;
|
||||
|
||||
/* This is for creating good compatible surfaces */
|
||||
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
|
@ -196,6 +198,7 @@ private:
|
|||
IntSize mSize;
|
||||
CGColorSpaceRef mColorSpace;
|
||||
CGContextRef mCg;
|
||||
CGAffineTransform mOriginalTransform;
|
||||
|
||||
/**
|
||||
* The image buffer, if the buffer is owned by this class.
|
||||
|
@ -207,10 +210,6 @@ private:
|
|||
|
||||
RefPtr<SourceSurfaceCGContext> mSnapshot;
|
||||
bool mMayContainInvalidPremultipliedData;
|
||||
|
||||
#ifdef DEBUG
|
||||
std::vector<CGRect> mSavedClipBounds;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ static const char *sExtensionNames[] = {
|
|||
"GL_ARB_texture_non_power_of_two",
|
||||
"GL_ARB_texture_rectangle",
|
||||
"GL_ARB_texture_storage",
|
||||
"GL_ARB_texture_swizzle",
|
||||
"GL_ARB_transform_feedback2",
|
||||
"GL_ARB_uniform_buffer_object",
|
||||
"GL_ARB_vertex_array_object",
|
||||
|
|
|
@ -128,6 +128,7 @@ enum class GLFeature {
|
|||
texture_half_float_linear,
|
||||
texture_non_power_of_two,
|
||||
texture_storage,
|
||||
texture_swizzle,
|
||||
transform_feedback2,
|
||||
uniform_buffer_object,
|
||||
uniform_matrix_nonsquare,
|
||||
|
@ -389,6 +390,7 @@ public:
|
|||
ARB_texture_non_power_of_two,
|
||||
ARB_texture_rectangle,
|
||||
ARB_texture_storage,
|
||||
ARB_texture_swizzle,
|
||||
ARB_transform_feedback2,
|
||||
ARB_uniform_buffer_object,
|
||||
ARB_vertex_array_object,
|
||||
|
|
|
@ -603,6 +603,15 @@ static const FeatureInfo sFeatureInfoArr[] = {
|
|||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"texture_swizzle",
|
||||
GLVersion::GL3_3,
|
||||
GLESVersion::ES3,
|
||||
GLContext::ARB_texture_swizzle,
|
||||
{
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"transform_feedback2",
|
||||
GLVersion::GL4,
|
||||
|
|
|
@ -90,7 +90,9 @@ TextRenderer::RenderText(const string& aText, const IntPoint& aOrigin,
|
|||
}
|
||||
|
||||
DataSourceSurface::MappedSurface map;
|
||||
textSurf->Map(DataSourceSurface::MapType::READ_WRITE, &map);
|
||||
if (NS_WARN_IF(!textSurf->Map(DataSourceSurface::MapType::READ_WRITE, &map))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the surface to transparent white.
|
||||
memset(map.mData, uint8_t(sBackgroundOpacity * 255.0f),
|
||||
|
@ -151,7 +153,9 @@ TextRenderer::EnsureInitialized()
|
|||
return;
|
||||
}
|
||||
|
||||
mGlyphBitmaps->Map(DataSourceSurface::MapType::READ_WRITE, &mMap);
|
||||
if (NS_WARN_IF(!mGlyphBitmaps->Map(DataSourceSurface::MapType::READ_WRITE, &mMap))) {
|
||||
return;
|
||||
}
|
||||
|
||||
png_structp png_ptr = NULL;
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче