mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Merge m-c to inbound.
This commit is contained in:
commit
e2cbddca2e
@ -49,7 +49,7 @@ pref("network.protocol-handler.warn-external.vnd.youtube", false);
|
||||
// By default, all protocol handlers are exposed. This means that the browser
|
||||
// will response to openURL commands for all URL types. It will also try to open
|
||||
// link clicks inside the browser before failing over to the system handlers.
|
||||
pref("network.protocol-handler.expose.rtsp", false);
|
||||
pref("network.protocol-handler.expose.rtsp", true);
|
||||
|
||||
/* http prefs */
|
||||
pref("network.http.pipelining", true);
|
||||
|
@ -19,11 +19,11 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="52720b94a4f709d5f96c23b2d63c398e7002ecb9"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="0292e64ef8451df104dcf9ac3b2c6749b81684dd"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="85f9690323b235f4dcf2901ea2240d3c60fc22a0"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
|
||||
@ -128,7 +128,7 @@
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
|
||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="09485b73629856b21b2ed6073e327ab0e69a1189"/>
|
||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="8afce6d5d48b71b6e7cb917179fb6147fb747521"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9a00b3db898a83ef0766baa93e935e525572899e"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="72e3a520e3c700839f07ba0113fd527b923c3330"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="baaf899afb158b9530690002f3656e958e3eb047"/>
|
||||
|
@ -12,10 +12,10 @@
|
||||
<!--original fetch url was https://git.mozilla.org/releases-->
|
||||
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
|
||||
<!-- B2G specific things. -->
|
||||
<project name="platform_build" path="build" remote="b2g" revision="52c909ccead537f8f9dbf634f3e6639078a8b0bd">
|
||||
<project name="platform_build" path="build" remote="b2g" revision="65fba428f8d76336b33ddd9e15900357953600ba">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
@ -119,15 +119,15 @@
|
||||
<project name="platform/system/netd" path="system/netd" revision="36704b0da24debcab8090156568ac236315036bb"/>
|
||||
<project name="platform/system/security" path="system/security" revision="583374f69f531ba68fc3dcbff1f74893d2a96406"/>
|
||||
<project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
|
||||
<project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="ee814270f52127febfcf29bacf9f1b327d7c4c29"/>
|
||||
<project name="platform_system_core" path="system/core" remote="b2g" revision="9395eb5aa885cf6d305a202de6e9694a58a89717"/>
|
||||
<default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
|
||||
<!-- Emulator specific things -->
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
|
||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="a706bf388e30ec1f5273cf72cd0156e429f23fac"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="0909f27aaa6bf55314edddb48bb1cd6296a2d55c"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3ef6c54fd5bba6fbd4c11f3870ab3aa32693f0da"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="694cecf256122d0cb3b6a1a4efb4b5c7401db223"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="e5dba2723b3e417b107cf9546fb8e10b98e977ae"/>
|
||||
<project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="ee814270f52127febfcf29bacf9f1b327d7c4c29"/>
|
||||
<project name="platform_system_core" path="system/core" remote="b2g" revision="9395eb5aa885cf6d305a202de6e9694a58a89717"/>
|
||||
<project name="platform/development" path="development" revision="5968ff4e13e0d696ad8d972281fc27ae5a12829b"/>
|
||||
<project name="android-sdk" path="sdk" remote="b2g" revision="0951179277915335251c5e11d242e4e1a8c2236f"/>
|
||||
</manifest>
|
||||
|
@ -19,11 +19,11 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="55bcc2d7e44dc805c24b57d1e783fc26e8a2ee86"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="52720b94a4f709d5f96c23b2d63c398e7002ecb9"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="0292e64ef8451df104dcf9ac3b2c6749b81684dd"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="85f9690323b235f4dcf2901ea2240d3c60fc22a0"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -18,7 +18,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "3f54f719dc145f1544db67881a48819559ecb71b",
|
||||
"revision": "b209dbf62facaae103d9a577ef885d429a431d6c",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -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="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f0463704888881b8ed1619e8d4b0d851b0e0311b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0a4d2dea25a7162ee43db3a0db817798b70e7521"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
@ -663,13 +663,7 @@ pref("plugins.click_to_play", true);
|
||||
|
||||
pref("plugins.hideMissingPluginsNotification", false);
|
||||
|
||||
#ifdef RELEASE_BUILD
|
||||
// For now, plugins other than Java and Flash are enabled in beta/release
|
||||
// and click-to-activate in earlier channels.
|
||||
pref("plugin.default.state", 2);
|
||||
#else
|
||||
pref("plugin.default.state", 1);
|
||||
#endif
|
||||
|
||||
// Plugins bundled in XPIs are enabled by default.
|
||||
pref("plugin.defaultXpi.state", 2);
|
||||
@ -679,6 +673,124 @@ pref("plugin.defaultXpi.state", 2);
|
||||
pref("plugin.state.flash", 2);
|
||||
pref("plugin.state.java", 1);
|
||||
|
||||
// Whitelist Requests
|
||||
|
||||
// Unity player, bug 979849
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npunity3d", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.unity web player", 2);
|
||||
#endif
|
||||
|
||||
// Cisco Jabber SDK, bug 980133
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npciscowebcommunicator", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.ciscowebcommunicator", 2);
|
||||
#endif
|
||||
|
||||
// McAfee Security Scanner detection plugin, bug 980772
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npmcafeemss", 2);
|
||||
#endif
|
||||
|
||||
// Cisco VGConnect for directv.com, bug 981403
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npplayerplugin", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.playerplugin", 2);
|
||||
#endif
|
||||
|
||||
// Cisco Jabber Client, bug 981905
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npchip", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.cisco jabber guest plug-in", 2);
|
||||
#endif
|
||||
|
||||
// Estonian ID-card plugin, bug 982045
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npesteid-firefox-plugin", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.esteidfirefoxplugin", 2);
|
||||
#endif
|
||||
#ifdef UNIX_BUT_NOT_MAC
|
||||
pref("plugin.state.npesteid-firefox-plugin", 2);
|
||||
#endif
|
||||
|
||||
// coupons.com, bug 984441
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npmozcouponprinter", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.couponprinter-firefox_v", 2);
|
||||
#endif
|
||||
|
||||
// Nexus Personal BankID, bug 987056
|
||||
pref("plugin.state.npbispbrowser", 2);
|
||||
|
||||
// Gradecam, bug 988119
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npgcplugin", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.gcplugin", 2);
|
||||
#endif
|
||||
|
||||
// Smart Card Plugin, bug 988781
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npwebcard", 2);
|
||||
#endif
|
||||
|
||||
// Cisco WebEx, bug 989096
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npatgpc", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.webex", 2);
|
||||
#endif
|
||||
#ifdef UNIX_BUT_NOT_MAC
|
||||
pref("plugin.state.npatgpc", 2);
|
||||
#endif
|
||||
|
||||
// Skype, bug 990067
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npskypewebplugin", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.skypewebplugin", 2);
|
||||
#endif
|
||||
|
||||
// Facebook video calling, bug 990068
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npfacebookvideocalling", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.facebookvideocalling", 2);
|
||||
#endif
|
||||
|
||||
// MS Office Lync plugin, bug 990069
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npmeetingjoinpluginoc", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.lwaplugin", 2);
|
||||
#endif
|
||||
|
||||
// VidyoWeb, bug 990286
|
||||
#ifdef XP_WIN
|
||||
pref("plugin.state.npvidyoweb", 2);
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
pref("plugin.state.npvidyoweb", 2);
|
||||
pref("plugin.state.vidyoweb", 2);
|
||||
#endif
|
||||
|
||||
// display door hanger if flash not installed
|
||||
pref("plugins.notifyMissingFlash", true);
|
||||
|
||||
@ -1286,7 +1398,7 @@ pref("devtools.eyedropper.zoom", 6);
|
||||
// - keymap: which keymap to use (can be 'default', 'emacs' or 'vim')
|
||||
// - autoclosebrackets: whether to permit automatic bracket/quote closing.
|
||||
// - detectindentation: whether to detect the indentation from the file
|
||||
pref("devtools.editor.tabsize", 4);
|
||||
pref("devtools.editor.tabsize", 2);
|
||||
pref("devtools.editor.expandtab", true);
|
||||
pref("devtools.editor.keymap", "default");
|
||||
pref("devtools.editor.autoclosebrackets", true);
|
||||
|
@ -122,36 +122,25 @@ tabbrowser {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.tab-background,
|
||||
.tab-close-button,
|
||||
.tab-label {
|
||||
.tab-background {
|
||||
/* Explicitly set the visibility to override the value (collapsed)
|
||||
* we inherit from #TabsToolbar[collapsed] upon opening a browser window. */
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.tab-close-button[fadein],
|
||||
.tab-background[fadein] {
|
||||
/* This transition is only wanted for opening tabs. */
|
||||
transition: visibility 0ms 25ms;
|
||||
}
|
||||
|
||||
.tab-close-button:not([fadein]),
|
||||
.tab-background:not([fadein]) {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.tab-close-button[fadein],
|
||||
.tab-label[fadein] {
|
||||
/* This transition is only wanted for opening tabs. */
|
||||
transition: opacity 70ms 230ms,
|
||||
visibility 0ms 230ms;
|
||||
}
|
||||
|
||||
.tab-close-button:not([fadein]),
|
||||
.tab-label:not([fadein]) {
|
||||
visibility: collapse;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.tab-label:not([fadein]),
|
||||
.tab-throbber:not([fadein]),
|
||||
.tab-icon-image:not([fadein]) {
|
||||
display: none;
|
||||
|
@ -27,6 +27,6 @@ add_task(function() {
|
||||
is(newWinBookmarksToolbarPlaceholder.getAttribute("wrap"), "true",
|
||||
"Button in new window should have 'wrap' attribute");
|
||||
yield newWin.PanelUI.hide();
|
||||
newWin.close();
|
||||
yield promiseWindowClosed(newWin);
|
||||
CustomizableUI.reset();
|
||||
});
|
||||
|
@ -133,7 +133,6 @@ PlacesController.prototype = {
|
||||
case "cmd_paste":
|
||||
case "cmd_delete":
|
||||
case "placesCmd_delete":
|
||||
case "placesCmd_moveBookmarks":
|
||||
case "cmd_paste":
|
||||
case "placesCmd_paste":
|
||||
case "placesCmd_new:folder":
|
||||
|
@ -23,27 +23,38 @@ var gMoveBookmarksDialog = {
|
||||
},
|
||||
|
||||
onOK: function MBD_onOK(aEvent) {
|
||||
var selectedNode = this.foldersTree.selectedNode;
|
||||
NS_ASSERT(selectedNode,
|
||||
"selectedNode must be set in a single-selection tree with initial selection set");
|
||||
var selectedFolderID = PlacesUtils.getConcreteItemId(selectedNode);
|
||||
let selectedNode = this.foldersTree.selectedNode;
|
||||
let selectedFolderId = PlacesUtils.getConcreteItemId(selectedNode);
|
||||
|
||||
var transactions = [];
|
||||
for (var i=0; i < this._nodes.length; i++) {
|
||||
// Nothing to do if the node is already under the selected folder
|
||||
if (this._nodes[i].parent.itemId == selectedFolderID)
|
||||
continue;
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let transactions = [];
|
||||
for (var i=0; i < this._nodes.length; i++) {
|
||||
// Nothing to do if the node is already under the selected folder
|
||||
if (this._nodes[i].parent.itemId == selectedFolderId)
|
||||
continue;
|
||||
|
||||
let txn = new PlacesMoveItemTransaction(this._nodes[i].itemId,
|
||||
selectedFolderID,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
transactions.push(txn);
|
||||
let txn = new PlacesMoveItemTransaction(this._nodes[i].itemId,
|
||||
selectedFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
transactions.push(txn);
|
||||
}
|
||||
if (transactions.length != 0) {
|
||||
let txn = new PlacesAggregatedTransaction("Move Items", transactions);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (transactions.length != 0) {
|
||||
let txn = new PlacesAggregatedTransaction("Move Items", transactions);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
}
|
||||
PlacesTransactions.transact(function* () {
|
||||
let newParentGUID = yield PlacesUtils.promiseItemGUID(selectedFolderId);
|
||||
for (let node of this._nodes) {
|
||||
// Nothing to do if the node is already under the selected folder.
|
||||
if (node.parent.itemId == selectedFolderId)
|
||||
continue;
|
||||
yield PlacesTransactions.MoveItem({ GUID: node.bookmarkGuid
|
||||
, newParentGUID: newParentGUID });
|
||||
}
|
||||
}.bind(this)).then(null, Components.utils.reportError);
|
||||
},
|
||||
|
||||
newFolder: function MBD_newFolder() {
|
||||
|
@ -52,7 +52,7 @@ function test(){
|
||||
}
|
||||
|
||||
function testSourceIsUgly() {
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
"The source shouldn't be pretty printed yet.");
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ function testAutoPrettyPrintOff(){
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ function test(){
|
||||
}
|
||||
|
||||
function testSourceIsUgly() {
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
"The source shouldn't be pretty printed yet.");
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ function disableAutoPrettyPrint(){
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ function test() {
|
||||
}
|
||||
|
||||
function testSourceIsUgly() {
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
"The source shouldn't be pretty printed yet.");
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ function testProgressBarShown() {
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ function testSourceIsStillPretty() {
|
||||
|
||||
const { source } = gSources.selectedItem.attachment;
|
||||
gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
|
||||
ok(text.contains("\n "),
|
||||
ok(text.contains("\n "),
|
||||
"Subsequent calls to getText return the pretty printed source.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
@ -43,7 +43,7 @@ function selectContextMenuItem() {
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ function test() {
|
||||
}
|
||||
|
||||
function testSourceIsUgly() {
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
"The source shouldn't be pretty printed yet.");
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ function clickPrettyPrintButton() {
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ function test() {
|
||||
}
|
||||
|
||||
function testSourceIsUgly() {
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
ok(!gEditor.getText().contains("\n "),
|
||||
"The source shouldn't be pretty printed yet.");
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ function testProgressBarShown() {
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ function testSourceIsStillPretty() {
|
||||
|
||||
const { source } = gSources.selectedItem.attachment;
|
||||
gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
|
||||
ok(text.contains("\n "),
|
||||
ok(text.contains("\n "),
|
||||
"Subsequent calls to getText return the pretty printed source.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
@ -28,7 +28,6 @@ support-files =
|
||||
# [browser_inspector_bug_831693_searchbox_panel_navigation.js]
|
||||
# Disabled for too many intermittent failures (bug 851349)
|
||||
[browser_inspector_bug_840156_destroy_after_navigation.js]
|
||||
[browser_inspector_changes.js]
|
||||
[browser_inspector_cmd_inspect.js]
|
||||
[browser_inspector_dead_node_exception.js]
|
||||
[browser_inspector_destroyselection.js]
|
||||
|
@ -1,156 +0,0 @@
|
||||
/* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=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/. */
|
||||
let doc;
|
||||
let testDiv;
|
||||
|
||||
function test() {
|
||||
let inspector;
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = '<div id="testdiv">Test div!</div>';
|
||||
doc.title = "Inspector Change Test";
|
||||
openInspector(runInspectorTests);
|
||||
}
|
||||
|
||||
function getInspectorRuleProp(aName)
|
||||
{
|
||||
let ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview.view;
|
||||
let inlineStyles = ruleview._elementStyle.rules[0];
|
||||
|
||||
for (let key in inlineStyles.textProps) {
|
||||
let prop = inlineStyles.textProps[key];
|
||||
if (prop.name == aName) {
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function runInspectorTests(aInspector)
|
||||
{
|
||||
inspector = aInspector;
|
||||
|
||||
waitForView("computedview", () => {
|
||||
info("Computed View ready");
|
||||
inspector.sidebar.select("computedview");
|
||||
|
||||
testDiv = doc.getElementById("testdiv");
|
||||
|
||||
testDiv.style.fontSize = "10px";
|
||||
|
||||
// Start up the style inspector panel...
|
||||
inspector.once("computed-view-refreshed", () => {
|
||||
executeSoon(computedStylePanelTests);
|
||||
});
|
||||
inspector.selection.setNode(testDiv);
|
||||
});
|
||||
}
|
||||
|
||||
function computedStylePanelTests()
|
||||
{
|
||||
let computedview = inspector.sidebar.getWindowForTab("computedview").computedview;
|
||||
ok(computedview, "Style Panel has a cssHtmlTree");
|
||||
|
||||
let fontSize = getComputedPropertyValue("font-size");
|
||||
is(fontSize, "10px", "Style inspector should be showing the correct font size.");
|
||||
|
||||
testDiv.style.cssText = "font-size: 15px; color: red;";
|
||||
|
||||
// Wait until layout-change fires from mutation to skip earlier refresh event
|
||||
inspector.once("layout-change", () => {
|
||||
inspector.once("computed-view-refreshed", () => {
|
||||
executeSoon(computedStylePanelAfterChange);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function computedStylePanelAfterChange()
|
||||
{
|
||||
let fontSize = getComputedPropertyValue("font-size");
|
||||
is(fontSize, "15px", "Style inspector should be showing the new font size.");
|
||||
|
||||
let color = getComputedPropertyValue("color");
|
||||
is(color, "#F00", "Style inspector should be showing the new color.");
|
||||
|
||||
computedStylePanelNotActive();
|
||||
}
|
||||
|
||||
function computedStylePanelNotActive()
|
||||
{
|
||||
// Tests changes made while the style panel is not active.
|
||||
inspector.sidebar.select("ruleview");
|
||||
|
||||
testDiv.style.cssText = "font-size: 20px; color: blue; text-align: center";
|
||||
|
||||
inspector.once("computed-view-refreshed", () => {
|
||||
executeSoon(computedStylePanelAfterSwitch);
|
||||
});
|
||||
}
|
||||
|
||||
function computedStylePanelAfterSwitch()
|
||||
{
|
||||
let fontSize = getComputedPropertyValue("font-size");
|
||||
is(fontSize, "20px", "Style inspector should be showing the new font size.");
|
||||
|
||||
let color = getComputedPropertyValue("color");
|
||||
is(color, "#00F", "Style inspector should be showing the new color.");
|
||||
|
||||
let textAlign = getComputedPropertyValue("text-align");
|
||||
is(textAlign, "center", "Style inspector should be showing the new text align.");
|
||||
|
||||
rulePanelTests();
|
||||
}
|
||||
|
||||
function rulePanelTests()
|
||||
{
|
||||
inspector.sidebar.select("ruleview");
|
||||
let ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview;
|
||||
ok(ruleview, "Style Panel has a ruleview");
|
||||
|
||||
let propView = getInspectorRuleProp("text-align");
|
||||
is(propView.value, "center", "Style inspector should be showing the new text align.");
|
||||
|
||||
testDiv.style.cssText = "font-size: 3em; color: lightgoldenrodyellow; text-align: right; text-transform: uppercase";
|
||||
|
||||
inspector.once("rule-view-refreshed", () => {
|
||||
executeSoon(rulePanelAfterChange);
|
||||
});
|
||||
}
|
||||
|
||||
function rulePanelAfterChange()
|
||||
{
|
||||
let propView = getInspectorRuleProp("text-align");
|
||||
is(propView.value, "right", "Style inspector should be showing the new text align.");
|
||||
|
||||
let propView = getInspectorRuleProp("color");
|
||||
is(propView.value, "lightgoldenrodyellow", "Style inspector should be showing the new color.")
|
||||
|
||||
let propView = getInspectorRuleProp("font-size");
|
||||
is(propView.value, "3em", "Style inspector should be showing the new font size.");
|
||||
|
||||
let propView = getInspectorRuleProp("text-transform");
|
||||
is(propView.value, "uppercase", "Style inspector should be showing the new text transform.");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,browser_inspector_changes.js";
|
||||
}
|
@ -169,7 +169,25 @@ function onEditorKeypress({ ed, Editor }, event) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((event.ctrlKey || event.metaKey) && event.keyCode == event.DOM_VK_SPACE) {
|
||||
// When Ctrl/Cmd + Space is pressed, two simultaneous keypresses are emitted
|
||||
// first one for just the Ctrl/Cmd and second one for combo. The first one
|
||||
// leave the private.doNotAutocomplete as true, so we have to make it false
|
||||
private.doNotAutocomplete = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.ctrlKey || event.metaKey || event.altKey) {
|
||||
private.doNotAutocomplete = true;
|
||||
private.popup.hidePopup();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event.keyCode) {
|
||||
case event.DOM_VK_RETURN:
|
||||
private.doNotAutocomplete = true;
|
||||
break;
|
||||
|
||||
case event.DOM_VK_ESCAPE:
|
||||
if (private.popup.isOpen)
|
||||
event.preventDefault();
|
||||
|
@ -62,26 +62,26 @@ function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
setup((ed, win) => {
|
||||
is(ed.getOption("indentUnit"), 4,
|
||||
"4 spaces before code added");
|
||||
is(ed.getOption("indentUnit"), 2,
|
||||
"2 spaces before code added");
|
||||
is(ed.getOption("indentWithTabs"), false,
|
||||
"spaces is default");
|
||||
|
||||
ed.setText(TWO_SPACES_CODE);
|
||||
is(ed.getOption("indentUnit"), 2,
|
||||
"2 spaces detected in 2 space code");
|
||||
is(ed.getOption("indentWithTabs"), false,
|
||||
"spaces detected in 2 space code");
|
||||
|
||||
ed.setText(FOUR_SPACES_CODE);
|
||||
is(ed.getOption("indentUnit"), 4,
|
||||
"4 spaces detected in 4 space code");
|
||||
is(ed.getOption("indentWithTabs"), false,
|
||||
"spaces detected in 4 space code");
|
||||
|
||||
ed.setText(TWO_SPACES_CODE);
|
||||
is(ed.getOption("indentUnit"), 2,
|
||||
"2 spaces detected in 2 space code");
|
||||
is(ed.getOption("indentWithTabs"), false,
|
||||
"spaces detected in 2 space code");
|
||||
|
||||
ed.setText(TABS_CODE);
|
||||
is(ed.getOption("indentUnit"), 4,
|
||||
"4 space indentation unit");
|
||||
is(ed.getOption("indentUnit"), 2,
|
||||
"2 space indentation unit");
|
||||
is(ed.getOption("indentWithTabs"), true,
|
||||
"tabs detected in majority tabs code");
|
||||
|
||||
|
@ -31,6 +31,8 @@ support-files =
|
||||
[browser_computedview_media-queries.js]
|
||||
[browser_computedview_no-results-placeholder.js]
|
||||
[browser_computedview_original-source-link.js]
|
||||
[browser_computedview_refresh-on-style-change_01.js]
|
||||
[browser_computedview_refresh-on-style-change_02.js]
|
||||
[browser_computedview_search-filter.js]
|
||||
[browser_computedview_select-and-copy-styles.js]
|
||||
[browser_computedview_style-editor-link.js]
|
||||
@ -77,6 +79,7 @@ skip-if = os == "win" && debug # bug 963492
|
||||
[browser_ruleview_pseudo-element.js]
|
||||
[browser_ruleview_refresh-on-attribute-change_01.js]
|
||||
[browser_ruleview_refresh-on-attribute-change_02.js]
|
||||
[browser_ruleview_refresh-on-style-change.js]
|
||||
[browser_ruleview_select-and-copy-styles.js]
|
||||
[browser_ruleview_style-editor-link.js]
|
||||
[browser_ruleview_urls-clickable.js]
|
||||
|
@ -0,0 +1,35 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the computed view refreshes when the current node has its style
|
||||
// changed
|
||||
|
||||
const TESTCASE_URI = 'data:text/html;charset=utf-8,' +
|
||||
'<div id="testdiv" style="font-size:10px;">Test div!</div>';
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab(TESTCASE_URI);
|
||||
|
||||
info("Getting the test node");
|
||||
let div = getNode("#testdiv");
|
||||
|
||||
info("Opening the computed view and selecting the test node");
|
||||
let {toolbox, inspector, view} = yield openComputedView();
|
||||
yield selectNode(div, inspector);
|
||||
|
||||
let fontSize = getComputedViewPropertyValue(view, "font-size");
|
||||
is(fontSize, "10px", "The computed view shows the right font-size");
|
||||
|
||||
info("Changing the node's style and waiting for the update");
|
||||
let onUpdated = inspector.once("computed-view-refreshed");
|
||||
div.style.cssText = "font-size: 15px; color: red;";
|
||||
yield onUpdated;
|
||||
|
||||
fontSize = getComputedViewPropertyValue(view, "font-size");
|
||||
is(fontSize, "15px", "The computed view shows the updated font-size");
|
||||
let color = getComputedViewPropertyValue(view, "color");
|
||||
is(color, "#F00", "The computed view also shows the color now");
|
||||
});
|
@ -0,0 +1,40 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the computed view refreshes when the current node has its style
|
||||
// changed, even if the view is not the active one
|
||||
|
||||
const TESTCASE_URI = 'data:text/html;charset=utf-8,' +
|
||||
'<div id="testdiv" style="font-size:10px;">Test div!</div>';
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab(TESTCASE_URI);
|
||||
|
||||
info("Getting the test node");
|
||||
let div = getNode("#testdiv");
|
||||
|
||||
info("Opening the computed view and selecting the test node");
|
||||
let {toolbox, inspector, view} = yield openComputedView();
|
||||
yield selectNode(div, inspector);
|
||||
|
||||
let fontSize = getComputedViewPropertyValue(view, "font-size");
|
||||
is(fontSize, "10px", "The computed view shows the right font-size");
|
||||
|
||||
info("Now switching to the rule view");
|
||||
yield openRuleView();
|
||||
|
||||
info("Changing the node's style and waiting for the update");
|
||||
let onUpdated = inspector.once("computed-view-refreshed");
|
||||
div.style.cssText = "font-size: 20px; color: blue; text-align: center";
|
||||
yield onUpdated;
|
||||
|
||||
fontSize = getComputedViewPropertyValue(view, "font-size");
|
||||
is(fontSize, "20px", "The computed view shows the updated font-size");
|
||||
let color = getComputedViewPropertyValue(view, "color");
|
||||
is(color, "#00F", "The computed view also shows the color now");
|
||||
let textAlign = getComputedViewPropertyValue(view, "text-align");
|
||||
is(textAlign, "center", "The computed view also shows the text-align now");
|
||||
});
|
@ -0,0 +1,41 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the rule view refreshes when the current node has its style
|
||||
// changed
|
||||
|
||||
const TESTCASE_URI = 'data:text/html;charset=utf-8,' +
|
||||
'<div id="testdiv" style="font-size:10px;">Test div!</div>';
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
yield addTab(TESTCASE_URI);
|
||||
|
||||
Services.prefs.setCharPref("devtools.defaultColorUnit", "name");
|
||||
|
||||
info("Getting the test node");
|
||||
let div = getNode("#testdiv");
|
||||
|
||||
info("Opening the rule view and selecting the test node");
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
yield selectNode(div, inspector);
|
||||
|
||||
let fontSize = getRuleViewPropertyValue(view, "element", "font-size");
|
||||
is(fontSize, "10px", "The rule view shows the right font-size");
|
||||
|
||||
info("Changing the node's style and waiting for the update");
|
||||
let onUpdated = inspector.once("rule-view-refreshed");
|
||||
div.style.cssText = "font-size: 3em; color: lightgoldenrodyellow; text-align: right; text-transform: uppercase";
|
||||
yield onUpdated;
|
||||
|
||||
let textAlign = getRuleViewPropertyValue(view, "element", "text-align");
|
||||
is(textAlign, "right", "The rule view shows the new text align.");
|
||||
let color = getRuleViewPropertyValue(view, "element", "color");
|
||||
is(color, "lightgoldenrodyellow", "The rule view shows the new color.")
|
||||
let fontSize = getRuleViewPropertyValue(view, "element", "font-size");
|
||||
is(fontSize, "3em", "The rule view shows the new font size.");
|
||||
let textTransform = getRuleViewPropertyValue(view, "element", "text-transform");
|
||||
is(textTransform, "uppercase", "The rule view shows the new text transform.");
|
||||
});
|
@ -34,9 +34,14 @@ registerCleanupFunction(() => {
|
||||
}
|
||||
});
|
||||
|
||||
// Uncomment to log events
|
||||
// Services.prefs.setBoolPref("devtools.dump.emit", true);
|
||||
|
||||
// Clean-up all prefs that might have been changed during a test run
|
||||
// (safer here because if the test fails, then the pref is never reverted)
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.dump.emit");
|
||||
Services.prefs.clearUserPref("devtools.defaultColorUnit");
|
||||
});
|
||||
|
||||
/**
|
||||
@ -477,7 +482,7 @@ function hasSideBarTab(inspector, id) {
|
||||
function getRuleViewRule(view, selectorText) {
|
||||
let rule;
|
||||
for (let r of view.doc.querySelectorAll(".ruleview-rule")) {
|
||||
let selector = r.querySelector(".ruleview-selector-matched");
|
||||
let selector = r.querySelector(".ruleview-selector, .ruleview-selector-matched");
|
||||
if (selector && selector.textContent === selectorText) {
|
||||
rule = r;
|
||||
break;
|
||||
@ -515,6 +520,20 @@ function getRuleViewProperty(view, selectorText, propertyName) {
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value of the property corresponding to a given selector and name
|
||||
* in the rule-view
|
||||
* @param {CssRuleView} view The instance of the rule-view panel
|
||||
* @param {String} selectorText The selector in the rule-view to look for the
|
||||
* property in
|
||||
* @param {String} propertyName The name of the property
|
||||
* @return {String} The property value
|
||||
*/
|
||||
function getRuleViewPropertyValue(view, selectorText, propertyName) {
|
||||
return getRuleViewProperty(view, selectorText, propertyName)
|
||||
.valueSpan.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate a color change in a given color picker tooltip, and optionally wait
|
||||
* for a given element in the page to have its style changed as a result
|
||||
@ -655,6 +674,18 @@ function getComputedViewProperty(view, name) {
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value of the property corresponding to a given name in the
|
||||
* computed-view
|
||||
* @param {CssHtmlTree} view The instance of the computed view panel
|
||||
* @param {String} name The name of the property to retrieve
|
||||
* @return {String} The property value
|
||||
*/
|
||||
function getComputedViewPropertyValue(view, selectorText, propertyName) {
|
||||
return getComputedViewProperty(view, selectorText, propertyName)
|
||||
.valueSpan.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand a given property, given its index in the current property list of
|
||||
* the computed view
|
||||
|
@ -51,17 +51,20 @@
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
#nav-bar {
|
||||
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
|
||||
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
|
||||
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
|
||||
margin-top: -@tabToolbarNavbarOverlap@; /* Move up into the TabsToolbar */
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
/* Position the toolbar above the bottom of background tabs */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#nav-bar {
|
||||
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
|
||||
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
#nav-bar-overflow-button {
|
||||
-moz-image-region: rect(-5px, 12px, 11px, -4px);
|
||||
}
|
||||
|
@ -109,6 +109,13 @@ toolbarseparator {
|
||||
background: url(chrome://browser/skin/Toolbar-background-noise.png) hsl(0,0%,83%);
|
||||
}
|
||||
|
||||
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
|
||||
margin-top: -@tabToolbarNavbarOverlap@; /* Move up into the TabsToolbar */
|
||||
/* Position the toolbar above the bottom of background tabs */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#nav-bar {
|
||||
-moz-appearance: none;
|
||||
background: url(chrome://browser/skin/Toolbar-background-noise.png),
|
||||
@ -124,10 +131,6 @@ toolbarseparator {
|
||||
background-position: 0 1px, 0 0;
|
||||
|
||||
box-shadow: inset 0 1px 0 hsla(0,0%,100%,.4);
|
||||
margin-top: -@tabToolbarNavbarOverlap@;
|
||||
/* Position the toolbar above the bottom of background tabs */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
|
@ -99,6 +99,10 @@
|
||||
background-position: top 5px left 4px;
|
||||
}
|
||||
|
||||
.subviewbutton[checked="true"]:-moz-locale-dir(rtl) {
|
||||
background-position: top 5px right 4px;
|
||||
}
|
||||
|
||||
.subviewbutton:not(:-moz-any([image],[targetURI],.cui-withicon, .bookmark-item)) > .menu-iconic-left {
|
||||
display: none;
|
||||
}
|
||||
|
@ -1068,6 +1068,10 @@ toolbaritem[overflowedItem=true],
|
||||
background: url("chrome://global/skin/menu/shared-menu-check.png") center left 7px / 11px 11px no-repeat transparent;
|
||||
}
|
||||
|
||||
.subviewbutton[checked="true"]:-moz-locale-dir(rtl) {
|
||||
background-position: center right 7px;
|
||||
}
|
||||
|
||||
.subviewbutton > .menu-iconic-left {
|
||||
-moz-appearance: none;
|
||||
-moz-margin-end: 3px;
|
||||
|
@ -283,15 +283,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
#nav-bar {
|
||||
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
|
||||
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
|
||||
#TabsToolbar:not([collapsed="true"]) + #nav-bar {
|
||||
margin-top: -@tabToolbarNavbarOverlap@; /* Move up into the TabsToolbar */
|
||||
/* Position the toolbar above the bottom of background tabs */
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#nav-bar {
|
||||
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
|
||||
box-shadow: 0 1px 0 @toolbarHighlight@ inset;
|
||||
}
|
||||
|
||||
#personal-bookmarks {
|
||||
min-height: 24px;
|
||||
}
|
||||
|
@ -430,6 +430,11 @@ DecoderTraits::CanHandleMediaType(const char* aMIMEType,
|
||||
if (MediaDecoder::IsMediaPluginsEnabled() &&
|
||||
GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList))
|
||||
result = CANPLAY_MAYBE;
|
||||
#endif
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
if (IsRtspSupportedType(nsDependentCString(aMIMEType))) {
|
||||
result = CANPLAY_MAYBE;
|
||||
}
|
||||
#endif
|
||||
if (result == CANPLAY_NO || !aHaveRequestedCodecs || !codecList) {
|
||||
return result;
|
||||
@ -664,6 +669,9 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
|
||||
#endif
|
||||
#ifdef MOZ_APPLEMEDIA
|
||||
IsAppleMediaSupportedType(aType) ||
|
||||
#endif
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
IsRtspSupportedType(aType) ||
|
||||
#endif
|
||||
false;
|
||||
}
|
||||
|
@ -1552,6 +1552,11 @@ MediaCache::ReleaseStream(MediaCacheStream* aStream)
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
CACHE_LOG(PR_LOG_DEBUG, ("Stream %p closed", aStream));
|
||||
mStreams.RemoveElement(aStream);
|
||||
|
||||
// Update MediaCache again for |mStreams| is changed.
|
||||
// We need to re-run Update() to ensure streams reading from the same resource
|
||||
// as the removed stream get a chance to continue reading.
|
||||
gMediaCache->QueueUpdate();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,6 +15,10 @@
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIStreamingProtocolService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
#include "mozilla/net/RtspChannelChild.h"
|
||||
#endif
|
||||
using namespace mozilla::net;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* gRtspMediaResourceLog;
|
||||
@ -37,9 +41,9 @@ namespace mozilla {
|
||||
* Even though the ring buffer is divided into fixed size slots, it still can
|
||||
* store the data which size is larger than one slot size.
|
||||
* */
|
||||
#define BUFFER_SLOT_NUM 512
|
||||
#define BUFFER_SLOT_NUM 8192
|
||||
#define BUFFER_SLOT_DEFAULT_SIZE 256
|
||||
#define BUFFER_SLOT_MAX_SIZE 8192
|
||||
#define BUFFER_SLOT_MAX_SIZE 512
|
||||
#define BUFFER_SLOT_INVALID -1
|
||||
#define BUFFER_SLOT_EMPTY 0
|
||||
|
||||
@ -354,21 +358,21 @@ RtspMediaResource::RtspMediaResource(MediaDecoder* aDecoder,
|
||||
, mIsConnected(false)
|
||||
, mRealTime(false)
|
||||
{
|
||||
nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService =
|
||||
do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(mediaControllerService);
|
||||
if (mediaControllerService) {
|
||||
mediaControllerService->Create(mChannel,
|
||||
getter_AddRefs(mMediaStreamController));
|
||||
MOZ_ASSERT(mMediaStreamController);
|
||||
mListener = new Listener(this);
|
||||
mMediaStreamController->AsyncOpen(mListener);
|
||||
}
|
||||
#ifndef NECKO_PROTOCOL_rtsp
|
||||
MOZ_CRASH("Should not be called except for B2G platform");
|
||||
#else
|
||||
MOZ_ASSERT(aChannel);
|
||||
mMediaStreamController =
|
||||
static_cast<RtspChannelChild*>(aChannel)->GetController();
|
||||
MOZ_ASSERT(mMediaStreamController);
|
||||
mListener = new Listener(this);
|
||||
mMediaStreamController->AsyncOpen(mListener);
|
||||
#ifdef PR_LOGGING
|
||||
if (!gRtspMediaResourceLog) {
|
||||
gRtspMediaResourceLog = PR_NewLogModule("RtspMediaResource");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
RtspMediaResource::~RtspMediaResource()
|
||||
@ -634,6 +638,9 @@ RtspMediaResource::OnDisconnected(uint8_t aTrackIdx, nsresult aReason)
|
||||
void RtspMediaResource::Suspend(bool aCloseImmediately)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
|
||||
if (NS_WARN_IF(!mDecoder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
|
||||
NS_ENSURE_TRUE_VOID(owner);
|
||||
@ -647,6 +654,9 @@ void RtspMediaResource::Suspend(bool aCloseImmediately)
|
||||
void RtspMediaResource::Resume()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
|
||||
if (NS_WARN_IF(!mDecoder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
|
||||
NS_ENSURE_TRUE_VOID(owner);
|
||||
|
@ -175,6 +175,7 @@ LOCAL_INCLUDES += [
|
||||
'/content/base/src',
|
||||
'/layout/generic',
|
||||
'/layout/xul',
|
||||
'/netwerk/base/src',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_DIRECTSHOW']:
|
||||
|
@ -47,6 +47,10 @@ PRLogModuleInfo* gAudioOffloadPlayerLog;
|
||||
#define AUDIO_OFFLOAD_LOG(type, msg)
|
||||
#endif
|
||||
|
||||
// maximum time in paused state when offloading audio decompression.
|
||||
// When elapsed, the AudioSink is destroyed to allow the audio DSP to power down.
|
||||
static const uint64_t OFFLOAD_PAUSE_MAX_MSECS = 60000ll;
|
||||
|
||||
AudioOffloadPlayer::AudioOffloadPlayer(MediaOmxDecoder* aObserver) :
|
||||
mObserver(aObserver),
|
||||
mInputBuffer(nullptr),
|
||||
@ -78,9 +82,7 @@ AudioOffloadPlayer::AudioOffloadPlayer(MediaOmxDecoder* aObserver) :
|
||||
|
||||
AudioOffloadPlayer::~AudioOffloadPlayer()
|
||||
{
|
||||
if (mStarted) {
|
||||
Reset();
|
||||
}
|
||||
Reset();
|
||||
AudioSystem::releaseAudioSessionId(mSessionId);
|
||||
}
|
||||
|
||||
@ -109,12 +111,6 @@ status_t AudioOffloadPlayer::Start(bool aSourceAlreadyStarted)
|
||||
}
|
||||
}
|
||||
|
||||
MediaSource::ReadOptions options;
|
||||
if (mSeeking) {
|
||||
options.setSeekTo(mSeekTimeUs);
|
||||
mSeeking = false;
|
||||
}
|
||||
|
||||
sp<MetaData> format = mSource->getFormat();
|
||||
const char* mime;
|
||||
int avgBitRate = -1;
|
||||
@ -177,21 +173,24 @@ status_t AudioOffloadPlayer::Start(bool aSourceAlreadyStarted)
|
||||
return err;
|
||||
}
|
||||
|
||||
void AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
|
||||
status_t AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mPlayState = aState;
|
||||
|
||||
switch (mPlayState) {
|
||||
case MediaDecoder::PLAY_STATE_PLAYING:
|
||||
Play();
|
||||
case MediaDecoder::PLAY_STATE_PLAYING: {
|
||||
status_t err = Play();
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
StartTimeUpdate();
|
||||
break;
|
||||
} break;
|
||||
|
||||
case MediaDecoder::PLAY_STATE_SEEKING: {
|
||||
int64_t seekTimeUs
|
||||
= mObserver->GetSeekTime();
|
||||
SeekTo(seekTimeUs);
|
||||
SeekTo(seekTimeUs, true);
|
||||
mObserver->ResetSeekTime();
|
||||
} break;
|
||||
|
||||
@ -209,33 +208,70 @@ void AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void ResetCallback(nsITimer* aTimer, void* aClosure)
|
||||
{
|
||||
AudioOffloadPlayer* player = static_cast<AudioOffloadPlayer*>(aClosure);
|
||||
if (player) {
|
||||
player->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioOffloadPlayer::Pause(bool aPlayPendingSamples)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
CHECK(mStarted);
|
||||
CHECK(mAudioSink.get());
|
||||
|
||||
if (aPlayPendingSamples) {
|
||||
mAudioSink->Stop();
|
||||
} else {
|
||||
mAudioSink->Pause();
|
||||
if (mStarted) {
|
||||
CHECK(mAudioSink.get());
|
||||
if (aPlayPendingSamples) {
|
||||
mAudioSink->Stop();
|
||||
} else {
|
||||
mAudioSink->Pause();
|
||||
}
|
||||
mPlaying = false;
|
||||
}
|
||||
mPlaying = false;
|
||||
|
||||
if (mResetTimer) {
|
||||
return;
|
||||
}
|
||||
mResetTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mResetTimer->InitWithFuncCallback(ResetCallback,
|
||||
this,
|
||||
OFFLOAD_PAUSE_MAX_MSECS,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
status_t AudioOffloadPlayer::Play()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
CHECK(mStarted);
|
||||
CHECK(mAudioSink.get());
|
||||
|
||||
if (mResetTimer) {
|
||||
mResetTimer->Cancel();
|
||||
mResetTimer = nullptr;
|
||||
}
|
||||
|
||||
status_t err = OK;
|
||||
err = mAudioSink->Start();
|
||||
|
||||
if (err == OK) {
|
||||
mPlaying = true;
|
||||
if (!mStarted) {
|
||||
// Last pause timed out and offloaded audio sink was reset. Start it again
|
||||
err = Start(false);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
// Seek to last play position only when there was no seek during last pause
|
||||
if (!mSeeking) {
|
||||
SeekTo(mPositionTimeMediaUs);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mPlaying) {
|
||||
CHECK(mAudioSink.get());
|
||||
err = mAudioSink->Start();
|
||||
if (err == OK) {
|
||||
mPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
@ -243,7 +279,10 @@ status_t AudioOffloadPlayer::Play()
|
||||
|
||||
void AudioOffloadPlayer::Reset()
|
||||
{
|
||||
CHECK(mStarted);
|
||||
if (!mStarted) {
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK(mAudioSink.get());
|
||||
|
||||
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("reset: mPlaying=%d mReachedEOS=%d",
|
||||
@ -273,19 +312,18 @@ void AudioOffloadPlayer::Reset()
|
||||
mInputBuffer->release();
|
||||
mInputBuffer = nullptr;
|
||||
}
|
||||
mSource->stop();
|
||||
|
||||
IPCThreadState::self()->flushCommands();
|
||||
StopTimeUpdate();
|
||||
|
||||
mSeeking = false;
|
||||
mSeekTimeUs = 0;
|
||||
mReachedEOS = false;
|
||||
mStarted = false;
|
||||
mPlaying = false;
|
||||
mStartPosUs = 0;
|
||||
}
|
||||
|
||||
status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs)
|
||||
status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
CHECK(mAudioSink.get());
|
||||
@ -299,26 +337,33 @@ status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs)
|
||||
mPositionTimeMediaUs = -1;
|
||||
mSeekTimeUs = aTimeUs;
|
||||
mStartPosUs = aTimeUs;
|
||||
mDispatchSeekEvents = aDispatchSeekEvents;
|
||||
|
||||
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
|
||||
&MediaDecoder::SeekingStarted);
|
||||
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
|
||||
if (mDispatchSeekEvents) {
|
||||
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
|
||||
&MediaDecoder::SeekingStarted);
|
||||
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
if (mPlaying) {
|
||||
mAudioSink->Pause();
|
||||
}
|
||||
|
||||
mAudioSink->Flush();
|
||||
|
||||
if (mPlaying) {
|
||||
mAudioSink->Flush();
|
||||
mAudioSink->Start();
|
||||
|
||||
} else {
|
||||
mSeekDuringPause = true;
|
||||
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Fake seek complete during pause"));
|
||||
|
||||
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
|
||||
&MediaDecoder::SeekingStopped);
|
||||
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
|
||||
if (mStarted) {
|
||||
mAudioSink->Flush();
|
||||
}
|
||||
|
||||
if (mDispatchSeekEvents) {
|
||||
mDispatchSeekEvents = false;
|
||||
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Fake seek complete during pause"));
|
||||
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
|
||||
&MediaDecoder::SeekingStopped);
|
||||
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -339,6 +384,9 @@ int64_t AudioOffloadPlayer::GetMediaTimeUs()
|
||||
if (mSeeking) {
|
||||
return mSeekTimeUs;
|
||||
}
|
||||
if (!mStarted) {
|
||||
return mPositionTimeMediaUs;
|
||||
}
|
||||
|
||||
playPosition = GetOutputPlayPositionUs_l();
|
||||
if (!mReachedEOS) {
|
||||
@ -427,8 +475,6 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool postSeekComplete = false;
|
||||
|
||||
size_t sizeDone = 0;
|
||||
size_t sizeRemaining = aSize;
|
||||
while (sizeRemaining > 0) {
|
||||
@ -446,9 +492,7 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
|
||||
mInputBuffer->release();
|
||||
mInputBuffer = nullptr;
|
||||
}
|
||||
|
||||
mSeeking = false;
|
||||
postSeekComplete = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -491,31 +535,31 @@ size_t AudioOffloadPlayer::FillBuffer(void* aData, size_t aSize)
|
||||
kKeyTime, &mPositionTimeMediaUs));
|
||||
}
|
||||
|
||||
// need to adjust the mStartPosUs for offload decoding since parser
|
||||
// might not be able to get the exact seek time requested.
|
||||
if (refreshSeekTime) {
|
||||
if (postSeekComplete) {
|
||||
|
||||
if (!mSeekDuringPause) {
|
||||
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("FillBuffer posting SEEK_COMPLETE"));
|
||||
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
|
||||
&MediaDecoder::SeekingStopped);
|
||||
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
|
||||
} else {
|
||||
// Callback is already called for seek during pause. Just reset the
|
||||
// flag
|
||||
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Not posting seek complete as its"
|
||||
" already faked"));
|
||||
mSeekDuringPause = false;
|
||||
}
|
||||
if (mDispatchSeekEvents && !mSeekDuringPause) {
|
||||
mDispatchSeekEvents = false;
|
||||
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("FillBuffer posting SEEK_COMPLETE"));
|
||||
nsCOMPtr<nsIRunnable> nsEvent = NS_NewRunnableMethod(mObserver,
|
||||
&MediaDecoder::SeekingStopped);
|
||||
NS_DispatchToMainThread(nsEvent, NS_DISPATCH_NORMAL);
|
||||
|
||||
NotifyPositionChanged();
|
||||
postSeekComplete = false;
|
||||
} else if (mSeekDuringPause) {
|
||||
// Callback is already called for seek during pause. Just reset the
|
||||
// flag
|
||||
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Not posting seek complete as its"
|
||||
" already faked"));
|
||||
mSeekDuringPause = false;
|
||||
}
|
||||
|
||||
NotifyPositionChanged();
|
||||
|
||||
// need to adjust the mStartPosUs for offload decoding since parser
|
||||
// might not be able to get the exact seek time requested.
|
||||
mStartPosUs = mPositionTimeMediaUs;
|
||||
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Adjust seek time to: %.2f",
|
||||
mStartPosUs / 1E6));
|
||||
|
||||
// clear seek time with mLock locked and once we have valid
|
||||
// mPositionTimeMediaUs
|
||||
// before clearing mSeekTimeUs check if a new seek request has been
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
// To update progress bar when the element is visible
|
||||
void SetElementVisibility(bool aIsVisible);
|
||||
|
||||
void ChangeState(MediaDecoder::PlayState aState);
|
||||
status_t ChangeState(MediaDecoder::PlayState aState);
|
||||
|
||||
void SetVolume(double aVolume);
|
||||
|
||||
@ -97,6 +97,9 @@ public:
|
||||
|
||||
void TimeUpdate();
|
||||
|
||||
// Close the audio sink, stop time updates, frees the input buffers
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
// Set when audio source is started and audioSink is initialized
|
||||
// Used only in main thread
|
||||
@ -122,6 +125,12 @@ private:
|
||||
// mLock
|
||||
bool mSeekDuringPause;
|
||||
|
||||
// Seek can be triggered internally or by MediaDecoder. This bool is to
|
||||
// to track seek triggered by MediaDecoder so that we can send back
|
||||
// SeekingStarted and SeekingStopped events.
|
||||
// Used in main thread and offload callback thread, protected by Mutex mLock
|
||||
bool mDispatchSeekEvents;
|
||||
|
||||
// Set when the HTML Audio Element is visible to the user.
|
||||
// Used only in main thread
|
||||
bool mIsElementVisible;
|
||||
@ -164,7 +173,7 @@ private:
|
||||
android::sp<MediaSource> mSource;
|
||||
|
||||
// Audio sink wrapper to access offloaded audio tracks
|
||||
// Used in main thread and offload callback thread, access is protected by
|
||||
// Used in main thread and offload callback thread
|
||||
// Race conditions are protected in underlying Android::AudioTrack class
|
||||
android::sp<AudioSink> mAudioSink;
|
||||
|
||||
@ -175,10 +184,17 @@ private:
|
||||
MediaOmxDecoder* mObserver;
|
||||
|
||||
TimeStamp mLastFireUpdateTime;
|
||||
|
||||
// Timer to trigger position changed events
|
||||
nsCOMPtr<nsITimer> mTimeUpdateTimer;
|
||||
|
||||
// Timer to reset AudioSink when audio is paused for OFFLOAD_PAUSE_MAX_USECS.
|
||||
// It is triggered in Pause() and canceled when there is a Play() within
|
||||
// OFFLOAD_PAUSE_MAX_USECS. Used only from main thread so no lock is needed.
|
||||
nsCOMPtr<nsITimer> mResetTimer;
|
||||
|
||||
int64_t GetMediaTimeUs();
|
||||
|
||||
// Provide the playback position in microseconds from total number of
|
||||
// frames played by audio track
|
||||
int64_t GetOutputPlayPositionUs_l() const;
|
||||
@ -198,16 +214,14 @@ private:
|
||||
bool IsSeeking();
|
||||
|
||||
// Set mSeekTime to the given position and restart the sink. Actual seek
|
||||
// happens in FillBuffer(). To MediaDecoder, send SeekingStarted event always
|
||||
// and SeekingStopped event when the play state is paused.
|
||||
// happens in FillBuffer(). If aDispatchSeekEvents is true, send
|
||||
// SeekingStarted event always and SeekingStopped event when the play state is
|
||||
// paused to MediaDecoder.
|
||||
// When decoding and playing happens separately, if there is a seek during
|
||||
// pause, we can decode and keep data ready.
|
||||
// In case of offload player, no way to seek during pause. So just fake that
|
||||
// seek is done.
|
||||
status_t SeekTo(int64_t aTimeUs);
|
||||
|
||||
// Close the audio sink, stop time updates, frees the input buffers
|
||||
void Reset();
|
||||
status_t SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents = false);
|
||||
|
||||
// Start/Resume the audio sink so that callback will start being called to get
|
||||
// compressed data
|
||||
|
@ -49,7 +49,10 @@ public:
|
||||
return android::NO_INIT;
|
||||
}
|
||||
|
||||
virtual void ChangeState(MediaDecoder::PlayState aState) {}
|
||||
virtual status_t ChangeState(MediaDecoder::PlayState aState)
|
||||
{
|
||||
return android::NO_INIT;
|
||||
}
|
||||
|
||||
virtual void SetVolume(double aVolume) {}
|
||||
|
||||
|
@ -65,7 +65,6 @@ void MediaOmxDecoder::MetadataLoaded(int aChannels,
|
||||
MediaDecoder::MetadataLoaded(aChannels, aRate, aHasAudio, aHasVideo, aTags);
|
||||
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
|
||||
if (!mCanOffloadAudio || mFallbackToStateMachine || mOutputStreams.Length() ||
|
||||
mInitialPlaybackRate != 1.0) {
|
||||
DECODER_LOG(PR_LOG_DEBUG, ("In %s Offload Audio check failed",
|
||||
@ -95,7 +94,6 @@ void MediaOmxDecoder::PauseStateMachine()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
|
||||
|
||||
if (!mDecoderStateMachine) {
|
||||
return;
|
||||
}
|
||||
@ -106,7 +104,7 @@ void MediaOmxDecoder::PauseStateMachine()
|
||||
void MediaOmxDecoder::ResumeStateMachine()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
DECODER_LOG(PR_LOG_DEBUG, ("%s current time %f", __PRETTY_FUNCTION__,
|
||||
mCurrentTime));
|
||||
|
||||
@ -130,7 +128,6 @@ void MediaOmxDecoder::AudioOffloadTearDown()
|
||||
DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
|
||||
{
|
||||
// Audio offload player sent tear down event. Fallback to state machine
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
ResumeStateMachine();
|
||||
}
|
||||
}
|
||||
@ -143,7 +140,6 @@ void MediaOmxDecoder::AddOutputStream(ProcessedMediaStream* aStream,
|
||||
|
||||
if (mAudioOffloadPlayer) {
|
||||
// Offload player cannot handle MediaStream. Fallback
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
ResumeStateMachine();
|
||||
}
|
||||
|
||||
@ -158,7 +154,6 @@ void MediaOmxDecoder::SetPlaybackRate(double aPlaybackRate)
|
||||
if (mAudioOffloadPlayer &&
|
||||
((aPlaybackRate != 0.0) || (aPlaybackRate != 1.0))) {
|
||||
// Offload player cannot handle playback rate other than 1/0. Fallback
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
ResumeStateMachine();
|
||||
}
|
||||
|
||||
@ -168,21 +163,22 @@ void MediaOmxDecoder::SetPlaybackRate(double aPlaybackRate)
|
||||
void MediaOmxDecoder::ChangeState(PlayState aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Keep MediaDecoder state in sync with MediaElement irrespective of offload
|
||||
// playback so it will continue to work in normal mode when offloading fails
|
||||
// in between
|
||||
MediaDecoder::ChangeState(aState);
|
||||
|
||||
if (mAudioOffloadPlayer) {
|
||||
mAudioOffloadPlayer->ChangeState(aState);
|
||||
status_t err = mAudioOffloadPlayer->ChangeState(aState);
|
||||
if (err != OK) {
|
||||
ResumeStateMachine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MediaOmxDecoder::ApplyStateToStateMachine(PlayState aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// During offload playback, state machine should be in dormant state.
|
||||
// ApplyStateToStateMachine() can change state machine state to
|
||||
// something else or reset the seek time. So don't call this when audio is
|
||||
|
@ -538,8 +538,17 @@ nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
return presShell ? presShell->SetResolution(aXResolution, aYResolution)
|
||||
: NS_ERROR_FAILURE;
|
||||
if (!presShell) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
|
||||
if (sf) {
|
||||
sf->SetResolution(gfxSize(aXResolution, aYResolution));
|
||||
presShell->SetResolution(aXResolution, aYResolution);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -550,13 +559,21 @@ nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution)
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (!presShell) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (presShell) {
|
||||
nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
|
||||
if (sf) {
|
||||
const gfxSize& res = sf->GetResolution();
|
||||
*aXResolution = res.width;
|
||||
*aYResolution = res.height;
|
||||
} else {
|
||||
*aXResolution = presShell->GetXResolution();
|
||||
*aYResolution = presShell->GetYResolution();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -999,15 +999,6 @@ BluetoothHfpManager::SendResponse(bthf_at_response_t aResponseCode)
|
||||
void
|
||||
BluetoothHfpManager::UpdatePhoneCIND(uint32_t aCallIndex, bool aSend)
|
||||
{
|
||||
// Update callsetup state
|
||||
uint16_t callState = mCurrentCallArray[aCallIndex].mState;
|
||||
if (callState == nsITelephonyProvider::CALL_STATE_CONNECTED ||
|
||||
callState == nsITelephonyProvider::CALL_STATE_HELD) {
|
||||
mCallSetupState = nsITelephonyProvider::CALL_STATE_DISCONNECTED;
|
||||
} else {
|
||||
mCallSetupState = callState;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
|
||||
|
||||
int numActive = GetNumberOfCalls(nsITelephonyProvider::CALL_STATE_CONNECTED);
|
||||
@ -1016,8 +1007,8 @@ BluetoothHfpManager::UpdatePhoneCIND(uint32_t aCallIndex, bool aSend)
|
||||
nsAutoCString number = NS_ConvertUTF16toUTF8(mCurrentCallArray[aCallIndex].mNumber);
|
||||
bthf_call_addrtype_t type = mCurrentCallArray[aCallIndex].mType;
|
||||
|
||||
BT_LOGR("[%d] state %d => BTHF: active[%d] held[%d] state[%d]",
|
||||
aCallIndex, callState, numActive, numHeld, bthfCallState);
|
||||
BT_LOGR("[%d] state %d => BTHF: active[%d] held[%d] state[%d]", aCallIndex,
|
||||
mCurrentCallArray[aCallIndex].mState, numActive, numHeld, bthfCallState);
|
||||
|
||||
NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
|
||||
sBluetoothHfpInterface->phone_state_change(
|
||||
@ -1124,6 +1115,22 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
||||
mCurrentCallArray[aCallIndex].mType = BTHF_CALL_ADDRTYPE_INTERNATIONAL;
|
||||
}
|
||||
|
||||
bool isSetupCall = (aCallState == nsITelephonyProvider::CALL_STATE_INCOMING ||
|
||||
aCallState == nsITelephonyProvider::CALL_STATE_ALERTING ||
|
||||
aCallState == nsITelephonyProvider::CALL_STATE_DIALING);
|
||||
bool hasSetupCall = (FindFirstCall(nsITelephonyProvider::CALL_STATE_INCOMING) ||
|
||||
FindFirstCall(nsITelephonyProvider::CALL_STATE_ALERTING) ||
|
||||
FindFirstCall(nsITelephonyProvider::CALL_STATE_DIALING));
|
||||
|
||||
// Update callsetup state when
|
||||
// 1) this call is in call setup
|
||||
// 2) all calls in the call array including this call are not in call setup
|
||||
if (isSetupCall) {
|
||||
mCallSetupState = aCallState;
|
||||
} else if (!hasSetupCall) {
|
||||
mCallSetupState = nsITelephonyProvider::CALL_STATE_DISCONNECTED;
|
||||
}
|
||||
|
||||
UpdatePhoneCIND(aCallIndex, aSend);
|
||||
|
||||
switch (aCallState) {
|
||||
|
@ -1162,6 +1162,74 @@ AppendDeviceName(BluetoothSignal& aSignal)
|
||||
unused << handler.forget(); // picked up by callback handler
|
||||
}
|
||||
|
||||
class SetPairingConfirmationTask : public Task
|
||||
{
|
||||
public:
|
||||
SetPairingConfirmationTask(const nsAString& aDeviceAddress,
|
||||
bool aConfirm,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
: mDeviceAddress(aDeviceAddress)
|
||||
, mConfirm(aConfirm)
|
||||
, mRunnable(aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
|
||||
}
|
||||
|
||||
void Run() MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
|
||||
MOZ_ASSERT(sDBusConnection);
|
||||
|
||||
nsAutoString errorStr;
|
||||
BluetoothValue v = true;
|
||||
DBusMessage *msg;
|
||||
|
||||
if (!sPairingReqTable->Get(mDeviceAddress, &msg) && mRunnable) {
|
||||
BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
|
||||
errorStr.AssignLiteral("Couldn't get original request message.");
|
||||
DispatchBluetoothReply(mRunnable, v, errorStr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DBusMessage *reply;
|
||||
|
||||
if (mConfirm) {
|
||||
reply = dbus_message_new_method_return(msg);
|
||||
} else {
|
||||
reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected",
|
||||
"User rejected confirmation");
|
||||
}
|
||||
|
||||
if (!reply) {
|
||||
BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
|
||||
dbus_message_unref(msg);
|
||||
errorStr.AssignLiteral("Memory can't be allocated for the message.");
|
||||
if (mRunnable) {
|
||||
DispatchBluetoothReply(mRunnable, v, errorStr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool result = sDBusConnection->Send(reply);
|
||||
if (!result) {
|
||||
errorStr.AssignLiteral("Can't send message!");
|
||||
}
|
||||
|
||||
dbus_message_unref(msg);
|
||||
dbus_message_unref(reply);
|
||||
sPairingReqTable->Remove(mDeviceAddress);
|
||||
if (mRunnable) {
|
||||
DispatchBluetoothReply(mRunnable, v, errorStr);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nsString mDeviceAddress;
|
||||
bool mConfirm;
|
||||
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||
};
|
||||
|
||||
static DBusHandlerResult
|
||||
AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||
{
|
||||
@ -1331,7 +1399,25 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data)
|
||||
dbus_connection_send(conn, reply, nullptr);
|
||||
dbus_message_unref(reply);
|
||||
|
||||
// Do not send an notification to upper layer, too annoying.
|
||||
// Do not send a notification to upper layer, too annoying.
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
} else if (dbus_message_is_method_call(msg, DBUS_AGENT_IFACE, "RequestPairingConsent")) {
|
||||
// Directly SetPairingconfirmation for RequestPairingConsent here
|
||||
if (!dbus_message_get_args(msg, nullptr,
|
||||
DBUS_TYPE_OBJECT_PATH, &objectPath,
|
||||
DBUS_TYPE_INVALID)) {
|
||||
errorStr.AssignLiteral("Invalid arguments: RequestPairingConsent()");
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
nsString address = GetAddressFromObjectPath(NS_ConvertUTF8toUTF16(objectPath));
|
||||
sPairingReqTable->Put(address, msg);
|
||||
Task* task = new SetPairingConfirmationTask(address, true, nullptr);
|
||||
DispatchToDBusThread(task);
|
||||
// Increase dbus message reference counts, it will be decreased in
|
||||
// SetPairingConfirmationTask
|
||||
dbus_message_ref(msg);
|
||||
// Do not send a notification to upper layer
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
@ -3182,68 +3268,6 @@ BluetoothDBusService::SetPasskeyInternal(const nsAString& aDeviceAddress,
|
||||
return true;
|
||||
}
|
||||
|
||||
class SetPairingConfirmationTask : public Task
|
||||
{
|
||||
public:
|
||||
SetPairingConfirmationTask(const nsAString& aDeviceAddress,
|
||||
bool aConfirm,
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
: mDeviceAddress(aDeviceAddress)
|
||||
, mConfirm(aConfirm)
|
||||
, mRunnable(aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
|
||||
MOZ_ASSERT(mRunnable);
|
||||
}
|
||||
|
||||
void Run() MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
|
||||
MOZ_ASSERT(sDBusConnection);
|
||||
|
||||
nsAutoString errorStr;
|
||||
BluetoothValue v = true;
|
||||
DBusMessage *msg;
|
||||
if (!sPairingReqTable->Get(mDeviceAddress, &msg)) {
|
||||
BT_WARNING("%s: Couldn't get original request message.", __FUNCTION__);
|
||||
errorStr.AssignLiteral("Couldn't get original request message.");
|
||||
DispatchBluetoothReply(mRunnable, v, errorStr);
|
||||
return;
|
||||
}
|
||||
|
||||
DBusMessage *reply;
|
||||
|
||||
if (mConfirm) {
|
||||
reply = dbus_message_new_method_return(msg);
|
||||
} else {
|
||||
reply = dbus_message_new_error(msg, "org.bluez.Error.Rejected",
|
||||
"User rejected confirmation");
|
||||
}
|
||||
|
||||
if (!reply) {
|
||||
BT_WARNING("%s: Memory can't be allocated for the message.", __FUNCTION__);
|
||||
dbus_message_unref(msg);
|
||||
errorStr.AssignLiteral("Memory can't be allocated for the message.");
|
||||
DispatchBluetoothReply(mRunnable, v, errorStr);
|
||||
return;
|
||||
}
|
||||
|
||||
bool result = sDBusConnection->Send(reply);
|
||||
if (!result) {
|
||||
errorStr.AssignLiteral("Can't send message!");
|
||||
}
|
||||
dbus_message_unref(msg);
|
||||
dbus_message_unref(reply);
|
||||
|
||||
sPairingReqTable->Remove(mDeviceAddress);
|
||||
DispatchBluetoothReply(mRunnable, v, errorStr);
|
||||
}
|
||||
|
||||
private:
|
||||
nsString mDeviceAddress;
|
||||
bool mConfirm;
|
||||
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||
};
|
||||
|
||||
bool
|
||||
BluetoothDBusService::SetPairingConfirmationInternal(
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include <cutils/properties.h>
|
||||
#include <system/audio.h>
|
||||
|
||||
#define RES_720P (720 * 1280)
|
||||
namespace android {
|
||||
|
||||
GonkRecorder::GonkRecorder()
|
||||
@ -370,6 +371,11 @@ status_t GonkRecorder::setParamMaxFileSizeBytes(int64_t bytes) {
|
||||
RE_LOGW("Target file size (%lld bytes) is too small to be respected", bytes);
|
||||
}
|
||||
|
||||
if (bytes >= 0xffffffffLL) {
|
||||
RE_LOGW("Target file size (%lld bytes) too large to be respected, clipping to 4GB", bytes);
|
||||
bytes = 0xffffffffLL;
|
||||
}
|
||||
|
||||
mMaxFileSizeBytes = bytes;
|
||||
return OK;
|
||||
}
|
||||
@ -656,6 +662,13 @@ status_t GonkRecorder::setClientName(const String16& clientName) {
|
||||
}
|
||||
|
||||
status_t GonkRecorder::prepare() {
|
||||
if (mVideoSource != VIDEO_SOURCE_LIST_END && mVideoEncoder != VIDEO_ENCODER_LIST_END &&
|
||||
mVideoHeight && mVideoWidth && // Video recording
|
||||
(mVideoHeight * mVideoWidth >= RES_720P)) {
|
||||
// TODO: Above check needs to be updated when mMaxFileDurationUs is set from camera app
|
||||
RE_LOGV("Video is high resolution so setting 64-bit file offsets");
|
||||
setParam64BitFileOffset(true);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -30,14 +30,6 @@ using namespace mozilla::dom;
|
||||
using mozilla::ErrorResult;
|
||||
using mozilla::dom::telephony::kOutgoingPlaceholderCallIndex;
|
||||
|
||||
namespace {
|
||||
|
||||
typedef nsAutoTArray<Telephony*, 2> TelephonyList;
|
||||
|
||||
TelephonyList* gTelephonyList;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
class Telephony::Listener : public nsITelephonyListener
|
||||
{
|
||||
Telephony* mTelephony;
|
||||
@ -121,26 +113,11 @@ public:
|
||||
Telephony::Telephony(nsPIDOMWindow* aOwner)
|
||||
: DOMEventTargetHelper(aOwner), mActiveCall(nullptr), mEnumerated(false)
|
||||
{
|
||||
if (!gTelephonyList) {
|
||||
gTelephonyList = new TelephonyList();
|
||||
}
|
||||
|
||||
gTelephonyList->AppendElement(this);
|
||||
}
|
||||
|
||||
Telephony::~Telephony()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
NS_ASSERTION(gTelephonyList, "This should never be null!");
|
||||
NS_ASSERTION(gTelephonyList->Contains(this), "Should be in the list!");
|
||||
|
||||
if (gTelephonyList->Length() == 1) {
|
||||
delete gTelephonyList;
|
||||
gTelephonyList = nullptr;
|
||||
} else {
|
||||
gTelephonyList->RemoveElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -787,7 +787,8 @@ TelephonyProvider.prototype = {
|
||||
aCall.isSwitchable,
|
||||
aCall.isMergeable]);
|
||||
} else {
|
||||
this.notifyCallError(aClientId, aCall.callIndex, aCall.failCause);
|
||||
this._notifyAllListeners("notifyError",
|
||||
[aClientId, aCall.callIndex, aCall.failCause]);
|
||||
}
|
||||
delete this._currentCalls[aClientId][aCall.callIndex];
|
||||
|
||||
@ -796,13 +797,6 @@ TelephonyProvider.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle call error.
|
||||
*/
|
||||
notifyCallError: function(aClientId, aCallIndex, aErrorMsg) {
|
||||
this._notifyAllListeners("notifyError", [aClientId, aCallIndex, aErrorMsg]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle an incoming call.
|
||||
*
|
||||
|
@ -10,14 +10,11 @@
|
||||
"@mozilla.org/telephony/gonktelephonyprovider;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(5fdd720f-fbe8-46f5-b671-3bf3360013dd)]
|
||||
[scriptable, uuid(9d884482-90fc-4050-a4b1-1a370afe7a35)]
|
||||
interface nsIGonkTelephonyProvider : nsITelephonyProvider
|
||||
{
|
||||
void notifyCallDisconnected(in unsigned long clientId, in jsval call);
|
||||
|
||||
void notifyCallError(in unsigned long clientId, in long callIndex,
|
||||
in AString error);
|
||||
|
||||
void notifyCallRing();
|
||||
|
||||
void notifyCallStateChanged(in unsigned long clientId, in jsval call,
|
||||
|
@ -12,6 +12,7 @@
|
||||
#define nsPresState_h_
|
||||
|
||||
#include "nsPoint.h"
|
||||
#include "gfxPoint.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsPresState
|
||||
@ -20,6 +21,7 @@ public:
|
||||
nsPresState()
|
||||
: mContentData(nullptr)
|
||||
, mScrollState(0, 0)
|
||||
, mResolution(1.0, 1.0)
|
||||
, mDisabledSet(false)
|
||||
, mDisabled(false)
|
||||
{}
|
||||
@ -29,18 +31,28 @@ public:
|
||||
mScrollState = aState;
|
||||
}
|
||||
|
||||
nsPoint GetScrollState()
|
||||
nsPoint GetScrollState() const
|
||||
{
|
||||
return mScrollState;
|
||||
}
|
||||
|
||||
void SetResolution(const gfxSize& aSize)
|
||||
{
|
||||
mResolution = aSize;
|
||||
}
|
||||
|
||||
gfxSize GetResolution() const
|
||||
{
|
||||
return mResolution;
|
||||
}
|
||||
|
||||
void ClearNonScrollState()
|
||||
{
|
||||
mContentData = nullptr;
|
||||
mDisabledSet = false;
|
||||
}
|
||||
|
||||
bool GetDisabled()
|
||||
bool GetDisabled() const
|
||||
{
|
||||
return mDisabled;
|
||||
}
|
||||
@ -51,12 +63,12 @@ public:
|
||||
mDisabledSet = true;
|
||||
}
|
||||
|
||||
bool IsDisabledSet()
|
||||
bool IsDisabledSet() const
|
||||
{
|
||||
return mDisabledSet;
|
||||
}
|
||||
|
||||
nsISupports* GetStateProperty()
|
||||
nsISupports* GetStateProperty() const
|
||||
{
|
||||
return mContentData;
|
||||
}
|
||||
@ -70,6 +82,7 @@ public:
|
||||
protected:
|
||||
nsCOMPtr<nsISupports> mContentData;
|
||||
nsPoint mScrollState;
|
||||
gfxSize mResolution;
|
||||
bool mDisabledSet;
|
||||
bool mDisabled;
|
||||
};
|
||||
|
@ -1600,6 +1600,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
|
||||
, mScrollPosAtLastPaint(0, 0)
|
||||
, mRestorePos(-1, -1)
|
||||
, mLastPos(-1, -1)
|
||||
, mResolution(1.0, 1.0)
|
||||
, mScrollPosForLayerPixelAlignment(-1, -1)
|
||||
, mLastUpdateImagesPos(-1, -1)
|
||||
, mNeverHasVerticalScrollbar(false)
|
||||
@ -2786,6 +2787,18 @@ ScrollFrameHelper::GetScrollPositionClampingScrollPortSize() const
|
||||
return mScrollPort.Size();
|
||||
}
|
||||
|
||||
gfxSize
|
||||
ScrollFrameHelper::GetResolution() const
|
||||
{
|
||||
return mResolution;
|
||||
}
|
||||
|
||||
void
|
||||
ScrollFrameHelper::SetResolution(const gfxSize& aResolution)
|
||||
{
|
||||
mResolution = aResolution;
|
||||
}
|
||||
|
||||
static void
|
||||
AdjustForWholeDelta(int32_t aDelta, nscoord* aCoord)
|
||||
{
|
||||
@ -4486,7 +4499,7 @@ ScrollFrameHelper::GetCoordAttribute(nsIFrame* aBox, nsIAtom* aAtom,
|
||||
}
|
||||
|
||||
nsPresState*
|
||||
ScrollFrameHelper::SaveState()
|
||||
ScrollFrameHelper::SaveState() const
|
||||
{
|
||||
nsIScrollbarMediator* mediator = do_QueryFrame(GetScrolledFrame());
|
||||
if (mediator) {
|
||||
@ -4511,6 +4524,7 @@ ScrollFrameHelper::SaveState()
|
||||
pt = mRestorePos;
|
||||
}
|
||||
state->SetScrollState(pt);
|
||||
state->SetResolution(mResolution);
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -4520,6 +4534,11 @@ ScrollFrameHelper::RestoreState(nsPresState* aState)
|
||||
mRestorePos = aState->GetScrollState();
|
||||
mDidHistoryRestore = true;
|
||||
mLastPos = mScrolledFrame ? GetLogicalScrollPosition() : nsPoint(0,0);
|
||||
mResolution = aState->GetResolution();
|
||||
|
||||
if (mIsRoot) {
|
||||
mOuter->PresContext()->PresShell()->SetResolution(mResolution.width, mResolution.height);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -163,6 +163,9 @@ public:
|
||||
// Get the scroll range assuming the scrollport has size (aWidth, aHeight).
|
||||
nsRect GetScrollRange(nscoord aWidth, nscoord aHeight) const;
|
||||
nsSize GetScrollPositionClampingScrollPortSize() const;
|
||||
gfxSize GetResolution() const;
|
||||
void SetResolution(const gfxSize& aResolution);
|
||||
|
||||
protected:
|
||||
nsRect GetScrollRangeForClamping() const;
|
||||
|
||||
@ -207,7 +210,7 @@ public:
|
||||
nsSize GetLineScrollAmount() const;
|
||||
nsSize GetPageScrollAmount() const;
|
||||
|
||||
nsPresState* SaveState();
|
||||
nsPresState* SaveState() const;
|
||||
void RestoreState(nsPresState* aState);
|
||||
|
||||
nsIFrame* GetScrolledFrame() const { return mScrolledFrame; }
|
||||
@ -348,6 +351,9 @@ public:
|
||||
// other than trying to restore mRestorePos.
|
||||
nsPoint mLastPos;
|
||||
|
||||
// The current resolution derived from the zoom level and device pixel ratio.
|
||||
gfxSize mResolution;
|
||||
|
||||
nsExpirationState mActivityExpirationState;
|
||||
|
||||
nsCOMPtr<nsITimer> mScrollActivityTimer;
|
||||
@ -577,6 +583,12 @@ public:
|
||||
virtual nsSize GetScrollPositionClampingScrollPortSize() const MOZ_OVERRIDE {
|
||||
return mHelper.GetScrollPositionClampingScrollPortSize();
|
||||
}
|
||||
virtual gfxSize GetResolution() const MOZ_OVERRIDE {
|
||||
return mHelper.GetResolution();
|
||||
}
|
||||
virtual void SetResolution(const gfxSize& aResolution) MOZ_OVERRIDE {
|
||||
return mHelper.SetResolution(aResolution);
|
||||
}
|
||||
virtual nsSize GetLineScrollAmount() const MOZ_OVERRIDE {
|
||||
return mHelper.GetLineScrollAmount();
|
||||
}
|
||||
@ -887,6 +899,12 @@ public:
|
||||
virtual nsSize GetScrollPositionClampingScrollPortSize() const MOZ_OVERRIDE {
|
||||
return mHelper.GetScrollPositionClampingScrollPortSize();
|
||||
}
|
||||
virtual gfxSize GetResolution() const MOZ_OVERRIDE {
|
||||
return mHelper.GetResolution();
|
||||
}
|
||||
virtual void SetResolution(const gfxSize& aResolution) MOZ_OVERRIDE {
|
||||
return mHelper.SetResolution(aResolution);
|
||||
}
|
||||
virtual nsSize GetLineScrollAmount() const MOZ_OVERRIDE {
|
||||
return mHelper.GetLineScrollAmount();
|
||||
}
|
||||
|
@ -134,7 +134,14 @@ public:
|
||||
* position.
|
||||
*/
|
||||
virtual nsSize GetScrollPositionClampingScrollPortSize() const = 0;
|
||||
|
||||
/**
|
||||
* Get the element resolution.
|
||||
*/
|
||||
virtual gfxSize GetResolution() const = 0;
|
||||
/**
|
||||
* Set the element resolution.
|
||||
*/
|
||||
virtual void SetResolution(const gfxSize& aResolution) = 0;
|
||||
/**
|
||||
* Return how much we would try to scroll by in each direction if
|
||||
* asked to scroll by one "line" vertically and horizontally.
|
||||
|
@ -83,7 +83,7 @@ public class HomeProvider extends SQLiteBridgeContentProvider {
|
||||
private Cursor queryFakeItems(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||
JSONArray items = null;
|
||||
try {
|
||||
final String jsonString = RawResource.get(getContext(), R.raw.fake_home_items);
|
||||
final String jsonString = RawResource.getAsString(getContext(), R.raw.fake_home_items);
|
||||
items = new JSONArray(jsonString);
|
||||
} catch (IOException e) {
|
||||
Log.e(LOGTAG, "Error getting fake home items", e);
|
||||
|
@ -86,6 +86,13 @@ public class ToolbarComponent extends BaseComponent {
|
||||
return (ImageButton) getToolbarView().findViewById(R.id.forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the View for the edit cancel button in the browser toolbar.
|
||||
*/
|
||||
private ImageButton getEditCancelButton() {
|
||||
return (ImageButton) getToolbarView().findViewById(R.id.edit_cancel);
|
||||
}
|
||||
|
||||
private CharSequence getTitle() {
|
||||
return getTitleHelper(true);
|
||||
}
|
||||
@ -145,14 +152,19 @@ public class ToolbarComponent extends BaseComponent {
|
||||
public ToolbarComponent dismissEditingMode() {
|
||||
assertIsEditing();
|
||||
|
||||
if (getUrlEditText().isInputMethodTarget()) {
|
||||
// Drop the soft keyboard.
|
||||
// TODO: Solo.hideSoftKeyboard() does not clear focus, causing unexpected
|
||||
// behavior, but we may want to use it over goBack().
|
||||
mSolo.goBack();
|
||||
}
|
||||
// Cancel Button not implemeneted in tablet.
|
||||
if (DeviceHelper.isTablet()) {
|
||||
if (getUrlEditText().isInputMethodTarget()) {
|
||||
// Drop the soft keyboard.
|
||||
// TODO: Solo.hideSoftKeyboard() does not clear focus, causing unexpected
|
||||
// behavior, but we may want to use it over goBack().
|
||||
mSolo.goBack();
|
||||
}
|
||||
|
||||
mSolo.goBack();
|
||||
mSolo.goBack();
|
||||
} else {
|
||||
mSolo.clickOnView(getEditCancelButton());
|
||||
}
|
||||
|
||||
waitForNotEditing();
|
||||
|
||||
|
@ -12,8 +12,17 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* {@code RawResource} provides API to load raw resources in different
|
||||
* forms. For now, we only load them as strings. We're using raw resources
|
||||
* as localizable 'assets' as opposed to a string that can be directly
|
||||
* translatable e.g. JSON file vs string.
|
||||
*
|
||||
* This is just a utility class to avoid code duplication for the different
|
||||
* cases where need to read such assets.
|
||||
*/
|
||||
public final class RawResource {
|
||||
public static String get(Context context, int id) throws IOException {
|
||||
public static String getAsString(Context context, int id) throws IOException {
|
||||
InputStreamReader reader = null;
|
||||
|
||||
try {
|
||||
|
@ -2882,6 +2882,7 @@ function Tab(aURL, aParams) {
|
||||
this.lastTouchedAt = Date.now();
|
||||
this._zoom = 1.0;
|
||||
this._drawZoom = 1.0;
|
||||
this._restoreZoom = false;
|
||||
this._fixedMarginLeft = 0;
|
||||
this._fixedMarginTop = 0;
|
||||
this._fixedMarginRight = 0;
|
||||
@ -3486,6 +3487,7 @@ Tab.prototype = {
|
||||
|
||||
let win = this.browser.contentWindow;
|
||||
win.scrollTo(x, y);
|
||||
this.saveSessionZoom(aViewport.zoom);
|
||||
|
||||
this.userScrollPos.x = win.scrollX;
|
||||
this.userScrollPos.y = win.scrollY;
|
||||
@ -3535,12 +3537,13 @@ Tab.prototype = {
|
||||
getViewport: function() {
|
||||
let screenW = gScreenWidth - gViewportMargins.left - gViewportMargins.right;
|
||||
let screenH = gScreenHeight - gViewportMargins.top - gViewportMargins.bottom;
|
||||
let zoom = this.restoredSessionZoom() || this._zoom;
|
||||
|
||||
let viewport = {
|
||||
width: screenW,
|
||||
height: screenH,
|
||||
cssWidth: screenW / this._zoom,
|
||||
cssHeight: screenH / this._zoom,
|
||||
cssWidth: screenW / zoom,
|
||||
cssHeight: screenH / zoom,
|
||||
pageLeft: 0,
|
||||
pageTop: 0,
|
||||
pageRight: screenW,
|
||||
@ -3548,13 +3551,13 @@ Tab.prototype = {
|
||||
// We make up matching css page dimensions
|
||||
cssPageLeft: 0,
|
||||
cssPageTop: 0,
|
||||
cssPageRight: screenW / this._zoom,
|
||||
cssPageBottom: screenH / this._zoom,
|
||||
cssPageRight: screenW / zoom,
|
||||
cssPageBottom: screenH / zoom,
|
||||
fixedMarginLeft: this._fixedMarginLeft,
|
||||
fixedMarginTop: this._fixedMarginTop,
|
||||
fixedMarginRight: this._fixedMarginRight,
|
||||
fixedMarginBottom: this._fixedMarginBottom,
|
||||
zoom: this._zoom,
|
||||
zoom: zoom,
|
||||
};
|
||||
|
||||
// Set the viewport offset to current scroll offset
|
||||
@ -4186,6 +4189,9 @@ Tab.prototype = {
|
||||
tabID: this.id,
|
||||
};
|
||||
|
||||
// Restore zoom only when moving in session history, not for new page loads.
|
||||
this._restoreZoom = aMessage != "New";
|
||||
|
||||
if (aParams) {
|
||||
if ("url" in aParams)
|
||||
message.url = aParams.url;
|
||||
@ -4198,6 +4204,22 @@ Tab.prototype = {
|
||||
sendMessageToJava(message);
|
||||
},
|
||||
|
||||
saveSessionZoom: function(aZoom) {
|
||||
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
cwu.setResolution(aZoom / window.devicePixelRatio, aZoom / window.devicePixelRatio);
|
||||
},
|
||||
|
||||
restoredSessionZoom: function() {
|
||||
if (!this._restoreZoom) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
let res = {x: {}, y: {}};
|
||||
cwu.getResolution(res.x, res.y);
|
||||
return res.x.value * window.devicePixelRatio;
|
||||
},
|
||||
|
||||
OnHistoryNewEntry: function(aUri) {
|
||||
this._sendHistoryEvent("New", { url: aUri.spec });
|
||||
},
|
||||
@ -4322,8 +4344,11 @@ Tab.prototype = {
|
||||
// In all of these cases, we maintain how much actual content is visible
|
||||
// within the screen width. Note that "actual content" may be different
|
||||
// with respect to CSS pixels because of the CSS viewport size changing.
|
||||
let zoomScale = (screenW * oldBrowserWidth) / (aOldScreenWidth * viewportW);
|
||||
let zoom = (aInitialLoad && metadata.defaultZoom) ? metadata.defaultZoom : this.clampZoom(this._zoom * zoomScale);
|
||||
let zoom = this.restoredSessionZoom() || metadata.defaultZoom;
|
||||
if (!zoom || !aInitialLoad) {
|
||||
let zoomScale = (screenW * oldBrowserWidth) / (aOldScreenWidth * viewportW);
|
||||
zoom = this.clampZoom(this._zoom * zoomScale);
|
||||
}
|
||||
this.setResolution(zoom, false);
|
||||
this.setScrollClampingSize(zoom);
|
||||
|
||||
@ -4459,7 +4484,8 @@ Tab.prototype = {
|
||||
// and zoom when calculating the new ones, so we need to reset these
|
||||
// things here before calling updateMetadata.
|
||||
this.setBrowserSize(kDefaultCSSViewportWidth, kDefaultCSSViewportHeight);
|
||||
this.setResolution(gScreenWidth / this.browserWidth, false);
|
||||
let zoom = this.restoredSessionZoom() || gScreenWidth / this.browserWidth;
|
||||
this.setResolution(zoom, true);
|
||||
ViewportHandler.updateMetadata(this, true);
|
||||
|
||||
// Note that if we draw without a display-port, things can go wrong. By the
|
||||
|
@ -13,6 +13,7 @@ jar.sources += [
|
||||
'src/tests/BrowserTestCase.java',
|
||||
'src/tests/TestGeckoSharedPrefs.java',
|
||||
'src/tests/TestJarReader.java',
|
||||
'src/tests/TestRawResource.java',
|
||||
'src/tests/TestTopSitesCursorWrapper.java',
|
||||
]
|
||||
jar.generated_sources = [] # None yet -- try to keep it this way.
|
||||
|
@ -0,0 +1,67 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
package org.mozilla.gecko.browser.tests;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.test.mock.MockContext;
|
||||
import android.test.mock.MockResources;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.mozilla.gecko.util.RawResource;
|
||||
|
||||
/**
|
||||
* Tests whether RawResource.getAsString() produces the right String
|
||||
* result after reading the returned raw resource's InputStream.
|
||||
*/
|
||||
public class TestRawResource extends BrowserTestCase {
|
||||
private static final int RAW_RESOURCE_ID = 1;
|
||||
private static final String RAW_CONTENTS = "RAW";
|
||||
|
||||
private static class TestContext extends MockContext {
|
||||
private final Resources resources;
|
||||
|
||||
public TestContext() {
|
||||
resources = new TestResources();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources() {
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Browser instrumentation tests can't have access to test-only
|
||||
* resources (bug 994135) yet so we mock the access to resources
|
||||
* for now.
|
||||
*/
|
||||
private static class TestResources extends MockResources {
|
||||
@Override
|
||||
public InputStream openRawResource(int id) {
|
||||
if (id == RAW_RESOURCE_ID) {
|
||||
return new ByteArrayInputStream(RAW_CONTENTS.getBytes());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void testGet() {
|
||||
Context context = new TestContext();
|
||||
String result;
|
||||
|
||||
try {
|
||||
result = RawResource.getAsString(context, RAW_RESOURCE_ID);
|
||||
} catch (IOException e) {
|
||||
result = null;
|
||||
}
|
||||
|
||||
assertEquals(RAW_CONTENTS, result);
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
|
||||
include protocol PHttpChannel;
|
||||
include protocol PFTPChannel;
|
||||
include protocol PRtspChannel;
|
||||
include URIParams;
|
||||
include InputStreamParams;
|
||||
|
||||
@ -89,5 +90,15 @@ union ChannelDiverterArgs
|
||||
PFTPChannel;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RTSP IPDL structs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct RtspChannelConnectArgs
|
||||
{
|
||||
URIParams uri;
|
||||
uint32_t channelId;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "mozilla/dom/network/UDPSocketChild.h"
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
#include "mozilla/net/RtspControllerChild.h"
|
||||
#include "mozilla/net/RtspChannelChild.h"
|
||||
#endif
|
||||
#include "SerializedLoadContext.h"
|
||||
|
||||
@ -181,6 +182,23 @@ NeckoChild::DeallocPRtspControllerChild(PRtspControllerChild* child)
|
||||
return true;
|
||||
}
|
||||
|
||||
PRtspChannelChild*
|
||||
NeckoChild::AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
|
||||
{
|
||||
NS_NOTREACHED("AllocPRtspController should not be called");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoChild::DeallocPRtspChannelChild(PRtspChannelChild* child)
|
||||
{
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
RtspChannelChild* p = static_cast<RtspChannelChild*>(child);
|
||||
p->ReleaseIPDLReference();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
PTCPSocketChild*
|
||||
NeckoChild::AllocPTCPSocketChild()
|
||||
{
|
||||
|
@ -62,6 +62,10 @@ protected:
|
||||
virtual bool DeallocPRemoteOpenFileChild(PRemoteOpenFileChild*) MOZ_OVERRIDE;
|
||||
virtual PRtspControllerChild* AllocPRtspControllerChild() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRtspControllerChild(PRtspControllerChild*) MOZ_OVERRIDE;
|
||||
virtual PRtspChannelChild*
|
||||
AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
|
||||
MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRtspChannelChild(PRtspChannelChild*) MOZ_OVERRIDE;
|
||||
virtual PChannelDiverterChild*
|
||||
AllocPChannelDiverterChild(const ChannelDiverterArgs& channel) MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "mozilla/net/WebSocketChannelParent.h"
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
#include "mozilla/net/RtspControllerParent.h"
|
||||
#include "mozilla/net/RtspChannelParent.h"
|
||||
#endif
|
||||
#include "mozilla/net/DNSRequestParent.h"
|
||||
#include "mozilla/net/RemoteOpenFileParent.h"
|
||||
@ -336,6 +337,42 @@ NeckoParent::DeallocPRtspControllerParent(PRtspControllerParent* actor)
|
||||
return true;
|
||||
}
|
||||
|
||||
PRtspChannelParent*
|
||||
NeckoParent::AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
|
||||
{
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
nsCOMPtr<nsIURI> uri = DeserializeURI(aArgs.uri());
|
||||
RtspChannelParent *p = new RtspChannelParent(uri);
|
||||
p->AddRef();
|
||||
return p;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoParent::RecvPRtspChannelConstructor(
|
||||
PRtspChannelParent* aActor,
|
||||
const RtspChannelConnectArgs& aConnectArgs)
|
||||
{
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
RtspChannelParent* p = static_cast<RtspChannelParent*>(aActor);
|
||||
return p->Init(aConnectArgs);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoParent::DeallocPRtspChannelParent(PRtspChannelParent* actor)
|
||||
{
|
||||
#ifdef NECKO_PROTOCOL_rtsp
|
||||
RtspChannelParent* p = static_cast<RtspChannelParent*>(actor);
|
||||
p->Release();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
PTCPSocketParent*
|
||||
NeckoParent::AllocPTCPSocketParent()
|
||||
{
|
||||
|
@ -144,6 +144,15 @@ protected:
|
||||
virtual PRtspControllerParent* AllocPRtspControllerParent() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRtspControllerParent(PRtspControllerParent*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PRtspChannelParent*
|
||||
AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
|
||||
MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
RecvPRtspChannelConstructor(PRtspChannelParent* aActor,
|
||||
const RtspChannelConnectArgs& aArgs)
|
||||
MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRtspChannelParent(PRtspChannelParent*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PChannelDiverterParent*
|
||||
AllocPChannelDiverterParent(const ChannelDiverterArgs& channel) MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
|
@ -22,6 +22,7 @@ include protocol PBlob; //FIXME: bug #792908
|
||||
include protocol PFileDescriptorSet;
|
||||
|
||||
include protocol PRtspController;
|
||||
include protocol PRtspChannel;
|
||||
include URIParams;
|
||||
include InputStreamParams;
|
||||
include NeckoChannelParams;
|
||||
@ -47,6 +48,7 @@ sync protocol PNecko
|
||||
manages PDNSRequest;
|
||||
manages PRemoteOpenFile;
|
||||
manages PRtspController;
|
||||
manages PRtspChannel;
|
||||
manages PChannelDiverter;
|
||||
|
||||
parent:
|
||||
@ -71,6 +73,7 @@ parent:
|
||||
HTMLDNSPrefetch(nsString hostname, uint16_t flags);
|
||||
CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
|
||||
PRtspController();
|
||||
PRtspChannel(RtspChannelConnectArgs args);
|
||||
PChannelDiverter(ChannelDiverterArgs channel);
|
||||
|
||||
both:
|
||||
|
25
netwerk/ipc/PRtspChannel.ipdl
Normal file
25
netwerk/ipc/PRtspChannel.ipdl
Normal file
@ -0,0 +1,25 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
|
||||
|
||||
/* 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 protocol PNecko;
|
||||
include URIParams;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
async protocol PRtspChannel
|
||||
{
|
||||
manager PNecko;
|
||||
|
||||
parent:
|
||||
// Note: channels are opened during construction, so no open method here:
|
||||
// see PNecko.ipdl
|
||||
__delete__();
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
@ -34,6 +34,7 @@ IPDL_SOURCES = [
|
||||
'PChannelDiverter.ipdl',
|
||||
'PNecko.ipdl',
|
||||
'PRemoteOpenFile.ipdl',
|
||||
'PRtspChannel.ipdl',
|
||||
'PRtspController.ipdl',
|
||||
]
|
||||
|
||||
|
@ -5,42 +5,72 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RtspChannelChild.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsStandardURL.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(RtspChannelChild,
|
||||
nsBaseChannel,
|
||||
nsIChannel)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RtspChannelChild::nsIChannel
|
||||
// RtspChannelChild
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
|
||||
RtspChannelChild::RtspChannelChild(nsIURI *aUri)
|
||||
: mIPCOpen(false)
|
||||
, mCanceled(false)
|
||||
{
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
nsCOMPtr<nsIURI> uri = nsBaseChannel::URI();
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
nsAutoCString uriSpec;
|
||||
uri->GetSpec(uriSpec);
|
||||
|
||||
mListener = aListener;
|
||||
mListenerContext = aContext;
|
||||
|
||||
// Call OnStartRequest directly. mListener is expected to create/load an
|
||||
// RtspMediaResource which will create an RtspMediaController. This controller
|
||||
// manages the control and data streams to and from the network.
|
||||
mListener->OnStartRequest(this, aContext);
|
||||
return NS_OK;
|
||||
nsBaseChannel::SetURI(aUri);
|
||||
}
|
||||
|
||||
RtspChannelChild::~RtspChannelChild()
|
||||
{
|
||||
}
|
||||
|
||||
nsIStreamingProtocolController*
|
||||
RtspChannelChild::GetController()
|
||||
{
|
||||
return mMediaStreamController;
|
||||
}
|
||||
|
||||
void
|
||||
RtspChannelChild::ReleaseController()
|
||||
{
|
||||
if (mMediaStreamController) {
|
||||
mMediaStreamController = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// IPDL
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
RtspChannelChild::AddIPDLReference()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!mIPCOpen,
|
||||
"Attempt to retain more than one IPDL reference");
|
||||
mIPCOpen = true;
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void
|
||||
RtspChannelChild::ReleaseIPDLReference()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
|
||||
mIPCOpen = false;
|
||||
Release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(RtspChannelChild,
|
||||
nsBaseChannel,
|
||||
nsIChannel,
|
||||
nsIChildChannel)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::GetContentType(nsACString& aContentType)
|
||||
{
|
||||
@ -48,15 +78,194 @@ RtspChannelChild::GetContentType(nsACString& aContentType)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::Init(nsIURI* aUri)
|
||||
class CallListenerOnStartRequestEvent : public nsRunnable
|
||||
{
|
||||
MOZ_ASSERT(aUri);
|
||||
public:
|
||||
CallListenerOnStartRequestEvent(nsIStreamListener *aListener,
|
||||
nsIRequest *aRequest, nsISupports *aContext)
|
||||
: mListener(aListener)
|
||||
, mRequest(aRequest)
|
||||
, mContext(aContext)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aListener);
|
||||
}
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mListener->OnStartRequest(mRequest, mContext);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsRefPtr<nsIStreamListener> mListener;
|
||||
nsRefPtr<nsIRequest> mRequest;
|
||||
nsRefPtr<nsISupports> mContext;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
|
||||
{
|
||||
// Precondition checks.
|
||||
MOZ_ASSERT(aListener);
|
||||
nsCOMPtr<nsIURI> uri = nsBaseChannel::URI();
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// Create RtspController.
|
||||
nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService =
|
||||
do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID);
|
||||
MOZ_RELEASE_ASSERT(mediaControllerService,
|
||||
"Cannot proceed if media controller service is unavailable!");
|
||||
mediaControllerService->Create(this, getter_AddRefs(mMediaStreamController));
|
||||
MOZ_ASSERT(mMediaStreamController);
|
||||
|
||||
// Add ourselves to the load group.
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->AddRequest(this, nullptr);
|
||||
}
|
||||
|
||||
// Dispatch mListener's OnStartRequest directly. mListener is expected to
|
||||
// create an RtspMediaResource and use the RtspController we just created to
|
||||
// manage the control and data streams to and from the network.
|
||||
mListener = aListener;
|
||||
mListenerContext = aContext;
|
||||
NS_DispatchToMainThread(
|
||||
new CallListenerOnStartRequestEvent(mListener, this, mListenerContext));
|
||||
|
||||
nsBaseChannel::Init();
|
||||
nsBaseChannel::SetURI(aUri);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla::net
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
|
||||
nsresult aStatusCode)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIStreamListener
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIChannel::nsIRequest
|
||||
//-----------------------------------------------------------------------------
|
||||
class CallListenerOnStopRequestEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
CallListenerOnStopRequestEvent(nsIStreamListener *aListener,
|
||||
nsIRequest *aRequest,
|
||||
nsISupports *aContext, nsresult aStatus)
|
||||
: mListener(aListener)
|
||||
, mRequest(aRequest)
|
||||
, mContext(aContext)
|
||||
, mStatus(aStatus)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aListener);
|
||||
}
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mListener->OnStopRequest(mRequest, mContext, mStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsRefPtr<nsIStreamListener> mListener;
|
||||
nsRefPtr<nsIRequest> mRequest;
|
||||
nsRefPtr<nsISupports> mContext;
|
||||
nsresult mStatus;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::Cancel(nsresult status)
|
||||
{
|
||||
if (mCanceled) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mCanceled = true;
|
||||
// Stop RtspController.
|
||||
if (mMediaStreamController) {
|
||||
mMediaStreamController->Stop();
|
||||
}
|
||||
|
||||
// Call mListener's OnStopRequest to do clean up.
|
||||
NS_DispatchToMainThread(
|
||||
new CallListenerOnStopRequestEvent(mListener, this,
|
||||
mListenerContext, status));
|
||||
mListener = nullptr;
|
||||
mListenerContext = nullptr;
|
||||
|
||||
// Remove ourselves from the load group.
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->RemoveRequest(this, nullptr, status);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::Suspend()
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::Resume()
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIChildChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::ConnectParent(uint32_t id)
|
||||
{
|
||||
// Create RtspChannelParent for redirection.
|
||||
AddIPDLReference();
|
||||
RtspChannelConnectArgs connectArgs;
|
||||
SerializeURI(nsBaseChannel::URI(), connectArgs.uri());
|
||||
connectArgs.channelId() = id;
|
||||
if (!gNeckoChild->SendPRtspChannelConstructor(this, connectArgs)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelChild::CompleteRedirectSetup(nsIStreamListener *aListener,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
return AsyncOpen(aListener, aContext);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
@ -7,69 +7,82 @@
|
||||
#ifndef RtspChannelChild_h
|
||||
#define RtspChannelChild_h
|
||||
|
||||
#include "mozilla/net/PRtspChannelChild.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "nsBaseChannel.h"
|
||||
#include "nsIChildChannel.h"
|
||||
#include "nsIStreamingProtocolController.h"
|
||||
#include "nsIStreamingProtocolService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RtspChannelChild is a dummy channel used to aid MediaResource creation in
|
||||
// HTMLMediaElement. Actual network control and data flows are managed by an
|
||||
// RtspController object created and owned by RtspMediaResource.
|
||||
// Therefore, when RtspChannelChild::AsyncOpen is called, mListener->OnStartRequest
|
||||
// will be called immediately. It is expected that an RtspMediaResource object
|
||||
// will be created in that calling context or after; the RtspController object
|
||||
// will be created internally by RtspMediaResource."
|
||||
// HTMLMediaElement. Network control and data flows are managed by an
|
||||
// RtspController object, which is created by us and manipulated by
|
||||
// RtspMediaResource. This object is also responsible for inter-process
|
||||
// communication with the parent process.
|
||||
// When RtspChannelChild::AsyncOpen is called, it should create an
|
||||
// RtspController object, dispatch an OnStartRequest and immediately return.
|
||||
// We expect an RtspMediaResource object will be created in the calling context
|
||||
// and it will use the RtpController we create.
|
||||
|
||||
class RtspChannelChild : public nsBaseChannel
|
||||
class RtspChannelChild : public PRtspChannelChild
|
||||
, public nsBaseChannel
|
||||
, public nsIChildChannel
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICHILDCHANNEL
|
||||
|
||||
RtspChannelChild() { }
|
||||
RtspChannelChild(nsIURI *aUri);
|
||||
~RtspChannelChild();
|
||||
|
||||
~RtspChannelChild() { }
|
||||
|
||||
// Overrides nsBaseChannel::AsyncOpen and call listener's OnStartRequest immediately.
|
||||
NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
|
||||
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
|
||||
// Set Rtsp URL.
|
||||
NS_IMETHOD Init(nsIURI* uri);
|
||||
// Overrides nsBaseChannel::GetContentType, return streaming protocol type "RTSP".
|
||||
// nsBaseChannel::nsIChannel
|
||||
NS_IMETHOD GetContentType(nsACString & aContentType) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
|
||||
MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
NS_IMETHOD OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// nsIRequestObserver
|
||||
NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
|
||||
NS_IMETHOD OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
||||
MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsIStreamListener
|
||||
// nsBaseChannel::nsIStreamListener
|
||||
NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel::nsIChannel::nsIRequest
|
||||
NS_IMETHOD Cancel(nsresult status) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD Suspend() MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD Resume() MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel
|
||||
NS_IMETHOD OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// IPDL
|
||||
void AddIPDLReference();
|
||||
void ReleaseIPDLReference();
|
||||
|
||||
// RtspChannelChild
|
||||
nsIStreamingProtocolController* GetController();
|
||||
void ReleaseController();
|
||||
|
||||
private:
|
||||
bool mIPCOpen;
|
||||
bool mCanceled;
|
||||
nsCOMPtr<nsIStreamingProtocolController> mMediaStreamController;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mozilla::net
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // RtspChannelChild_h
|
||||
|
159
netwerk/protocol/rtsp/RtspChannelParent.cpp
Normal file
159
netwerk/protocol/rtsp/RtspChannelParent.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et 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 "RtspChannelParent.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RtspChannelParent
|
||||
//-----------------------------------------------------------------------------
|
||||
RtspChannelParent::RtspChannelParent(nsIURI *aUri)
|
||||
: mIPCClosed(false)
|
||||
{
|
||||
nsBaseChannel::SetURI(aUri);
|
||||
}
|
||||
|
||||
RtspChannelParent::~RtspChannelParent()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RtspChannelParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
mIPCClosed = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(RtspChannelParent,
|
||||
nsBaseChannel,
|
||||
nsIParentChannel)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RtspChannelParent methods
|
||||
//-----------------------------------------------------------------------------
|
||||
bool
|
||||
RtspChannelParent::Init(const RtspChannelConnectArgs& aArgs)
|
||||
{
|
||||
return ConnectChannel(aArgs.channelId());
|
||||
}
|
||||
|
||||
bool
|
||||
RtspChannelParent::ConnectChannel(const uint32_t& channelId)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::GetContentType(nsACString& aContentType)
|
||||
{
|
||||
aContentType.AssignLiteral("RTSP");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::OnStartRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::OnStopRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatusCode)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIStreamListener
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsIChannel::nsIRequeset
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::Cancel(nsresult status)
|
||||
{
|
||||
// FIXME: This method will be called by
|
||||
// nsXMLHttpRequest::CloseRequestWithError while closing the browser app.
|
||||
// However, the root cause is RtspChannelParent will be created by
|
||||
// nsXMLHttpRequest::Open when we navigate away from an RTSP web page.
|
||||
// We should find out why it happens and decide how to fix it.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::Suspend()
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::Resume()
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel)
|
||||
{
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIParentChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::SetParentListener(HttpChannelParentListener *aListener)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RtspChannelParent::Delete()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
84
netwerk/protocol/rtsp/RtspChannelParent.h
Normal file
84
netwerk/protocol/rtsp/RtspChannelParent.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et 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 RtspChannelParent_h
|
||||
#define RtspChannelParent_h
|
||||
|
||||
#include "mozilla/net/PRtspChannelParent.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "nsBaseChannel.h"
|
||||
#include "nsIParentChannel.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Note: RtspChannel doesn't transport streams as normal channel does.
|
||||
// (See RtspChannelChild.h for detail).
|
||||
// The reason for the existence of RtspChannelParent is to support HTTP->RTSP
|
||||
// redirection.
|
||||
// When redirection happens, two instances of RtspChannelParent will be created:
|
||||
// - One will be created when HTTP creates the new channel for redirects, and
|
||||
// will be registered as an nsIChannel.
|
||||
// - The other will be created via IPDL by RtspChannelChild, and will be
|
||||
// registered as an nsIParentChannel.
|
||||
class RtspChannelParent : public PRtspChannelParent
|
||||
, public nsBaseChannel
|
||||
, public nsIParentChannel
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPARENTCHANNEL
|
||||
|
||||
RtspChannelParent(nsIURI *aUri);
|
||||
~RtspChannelParent();
|
||||
|
||||
// nsBaseChannel::nsIChannel
|
||||
NS_IMETHOD GetContentType(nsACString & aContentType) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
|
||||
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel::nsIStreamListener::nsIRequestObserver
|
||||
NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatusCode) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel::nsIStreamListener
|
||||
NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel::nsIChannel::nsIRequest
|
||||
NS_IMETHOD Cancel(nsresult status) MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD Suspend() MOZ_OVERRIDE MOZ_FINAL;
|
||||
NS_IMETHOD Resume() MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// nsBaseChannel
|
||||
NS_IMETHOD OpenContentStream(bool aAsync,
|
||||
nsIInputStream **aStream,
|
||||
nsIChannel **aChannel) MOZ_OVERRIDE MOZ_FINAL;
|
||||
|
||||
// RtspChannelParent
|
||||
bool Init(const RtspChannelConnectArgs& aArgs);
|
||||
|
||||
protected:
|
||||
// Used to connect redirected-to channel in parent with just created
|
||||
// ChildChannel. Used during HTTP->RTSP redirection.
|
||||
bool ConnectChannel(const uint32_t& channelId);
|
||||
|
||||
private:
|
||||
bool mIPCClosed;
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // RtspChannelParent_h
|
@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RtspChannelChild.h"
|
||||
#include "RtspChannelParent.h"
|
||||
#include "RtspHandler.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
@ -68,15 +69,19 @@ NS_IMETHODIMP
|
||||
RtspHandler::NewChannel(nsIURI *aURI, nsIChannel **aResult)
|
||||
{
|
||||
bool isRtsp = false;
|
||||
nsRefPtr<RtspChannelChild> rtspChannel;
|
||||
nsRefPtr<nsBaseChannel> rtspChannel;
|
||||
|
||||
nsresult rv = aURI->SchemeIs("rtsp", &isRtsp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(isRtsp, NS_ERROR_UNEXPECTED);
|
||||
|
||||
rtspChannel = new RtspChannelChild();
|
||||
if (IsNeckoChild()) {
|
||||
rtspChannel = new RtspChannelChild(aURI);
|
||||
} else {
|
||||
rtspChannel = new RtspChannelParent(aURI);
|
||||
}
|
||||
|
||||
rv = rtspChannel->Init(aURI);
|
||||
rv = rtspChannel->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rtspChannel.forget(aResult);
|
||||
|
@ -78,6 +78,12 @@ RtspControllerChild::~RtspControllerChild()
|
||||
LOG(("RtspControllerChild::~RtspControllerChild()"));
|
||||
}
|
||||
|
||||
void
|
||||
RtspControllerChild::ReleaseChannel()
|
||||
{
|
||||
static_cast<RtspChannelChild*>(mChannel.get())->ReleaseController();
|
||||
}
|
||||
|
||||
bool
|
||||
RtspControllerChild::OKToSendIPC()
|
||||
{
|
||||
@ -174,6 +180,7 @@ RtspControllerChild::RecvOnDisconnected(
|
||||
if (mListener) {
|
||||
mListener->OnDisconnected(index, reason);
|
||||
}
|
||||
ReleaseChannel();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -185,6 +192,7 @@ RtspControllerChild::RecvAsyncOpenFailed(const nsresult& reason)
|
||||
if (mListener) {
|
||||
mListener->OnDisconnected(0, NS_ERROR_CONNECTION_REFUSED);
|
||||
}
|
||||
ReleaseChannel();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/net/RtspChannelChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
@ -70,6 +71,8 @@ class RtspControllerChild : public nsIStreamingProtocolController
|
||||
uint32_t mTotalTracks;
|
||||
// Current suspension depth for this channel object
|
||||
uint32_t mSuspendCount;
|
||||
// Detach channel-controller relationship.
|
||||
void ReleaseChannel();
|
||||
};
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
@ -10,6 +10,7 @@ EXPORTS.mozilla.net += [
|
||||
'controller/RtspMetaData.h',
|
||||
'rtsp/RTSPSource.h',
|
||||
'RtspChannelChild.h',
|
||||
'RtspChannelParent.h',
|
||||
'RtspHandler.h',
|
||||
]
|
||||
|
||||
@ -20,6 +21,7 @@ SOURCES += [
|
||||
'controller/RtspControllerParent.cpp',
|
||||
'controller/RtspMetaData.cpp',
|
||||
'RtspChannelChild.cpp',
|
||||
'RtspChannelParent.cpp',
|
||||
'RtspHandler.cpp',
|
||||
]
|
||||
|
||||
|
@ -351,16 +351,20 @@ let PlacesTransactions = {
|
||||
* are not protected from consumers who use the raw places APIs directly.
|
||||
*/
|
||||
transact: function (aToTransact) {
|
||||
let generatorMode = typeof(aToTransact) == "function";
|
||||
if (generatorMode) {
|
||||
if (!aToTransact.isGenerator())
|
||||
let isGeneratorObj =
|
||||
o => Object.prototype.toString.call(o) == "[object Generator]";
|
||||
|
||||
let generator = null;
|
||||
if (typeof(aToTransact) == "function") {
|
||||
generator = aToTransact();
|
||||
if (!isGeneratorObj(generator))
|
||||
throw new Error("aToTransact is not a generator function");
|
||||
}
|
||||
else {
|
||||
if (!TransactionsHistory.isProxifiedTransactionObject(aToTransact))
|
||||
throw new Error("aToTransact is not a valid transaction object");
|
||||
if (executedTransactions.has(aToTransact))
|
||||
throw new Error("Transactions objects may not be recycled.");
|
||||
else if (!TransactionsHistory.isProxifiedTransactionObject(aToTransact)) {
|
||||
throw new Error("aToTransact is not a valid transaction object");
|
||||
}
|
||||
else if (executedTransactions.has(aToTransact)) {
|
||||
throw new Error("Transactions objects may not be recycled.");
|
||||
}
|
||||
|
||||
return Serialize(function* () {
|
||||
@ -387,7 +391,7 @@ let PlacesTransactions = {
|
||||
let next = error ?
|
||||
aGenerator.throw(sendValue) : aGenerator.next(sendValue);
|
||||
sendValue = next.value;
|
||||
if (Object.prototype.toString.call(sendValue) == "[object Generator]") {
|
||||
if (isGeneratorObj(sendValue)) {
|
||||
sendValue = yield transactBatch(sendValue);
|
||||
}
|
||||
else if (typeof(sendValue) == "object" && sendValue) {
|
||||
@ -410,8 +414,8 @@ let PlacesTransactions = {
|
||||
return sendValue;
|
||||
}
|
||||
|
||||
if (generatorMode)
|
||||
return yield transactBatch(aToTransact());
|
||||
if (generator)
|
||||
return yield transactBatch(generator);
|
||||
else
|
||||
return yield transactOneTransaction(aToTransact);
|
||||
}.bind(this));
|
||||
@ -887,9 +891,10 @@ PT.NewLivemark.prototype = Object.seal({
|
||||
/**
|
||||
* Transaction for moving an item.
|
||||
*
|
||||
* Required Input Properties: GUID, newParentGUID, newIndex.
|
||||
* Required Input Properties: GUID, newParentGUID.
|
||||
* Optional Input Properties newIndex.
|
||||
*/
|
||||
PT.MoveItem = DefineTransaction(["GUID", "newParentGUID", "newIndex"]);
|
||||
PT.MoveItem = DefineTransaction(["GUID", "newParentGUID"], ["newIndex"]);
|
||||
PT.MoveItem.prototype = Object.seal({
|
||||
execute: function* (aGUID, aNewParentGUID, aNewIndex) {
|
||||
let itemId = yield PlacesUtils.promiseItemId(aGUID),
|
||||
|
@ -454,8 +454,7 @@ add_task(function* test_move_items_to_folder() {
|
||||
ensureUndoState([[bkm_b_txn, bkm_a_txn, folder_a_txn]], 0);
|
||||
|
||||
let moveTxn = PT.MoveItem({ GUID: bkm_a_info.GUID
|
||||
, newParentGUID: folder_a_info.GUID
|
||||
, newIndex: bmsvc.DEFAULT_INDEX });
|
||||
, newParentGUID: folder_a_info.GUID });
|
||||
yield PT.transact(moveTxn);
|
||||
|
||||
let ensureDo = () => {
|
||||
|
@ -13,7 +13,7 @@ toolkit.jar:
|
||||
skin/classic/mozapps/downloads/unknownContentType.css (downloads/unknownContentType.css)
|
||||
skin/classic/mozapps/extensions/about.css (extensions/about.css)
|
||||
skin/classic/mozapps/extensions/blocklist.css (extensions/blocklist.css)
|
||||
skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
|
||||
* skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
|
||||
* skin/classic/mozapps/extensions/selectAddons.css (extensions/selectAddons.css)
|
||||
skin/classic/mozapps/extensions/update.css (extensions/update.css)
|
||||
skin/classic/mozapps/extensions/extensions.svg (extensions/extensions.svg)
|
||||
|
Loading…
Reference in New Issue
Block a user