--- a/b2g/components/LogShake.jsm
+++ b/b2g/components/LogShake.jsm
@@ -123,17 +123,20 @@ var LogShake = {
"/proc/cmdline": LogParser.prettyPrintArray,
"/proc/kmsg": LogParser.prettyPrintArray,
"/proc/last_kmsg": LogParser.prettyPrintArray,
"/proc/meminfo": LogParser.prettyPrintArray,
"/proc/uptime": LogParser.prettyPrintArray,
"/proc/version": LogParser.prettyPrintArray,
"/proc/vmallocinfo": LogParser.prettyPrintArray,
"/proc/vmstat": LogParser.prettyPrintArray,
- "/system/b2g/application.ini": LogParser.prettyPrintArray
+ "/system/b2g/application.ini": LogParser.prettyPrintArray,
+ "/cache/recovery/last_install": LogParser.prettyPrintArray,
+ "/cache/recovery/last_kmsg": LogParser.prettyPrintArray,
+ "/cache/recovery/last_log": LogParser.prettyPrintArray
},
/**
* Start existing, observing motion events if the screen is turned on.
*/
init: function() {
// TODO: no way of querying screen state from power manager
// this.handleScreenChangeEvent({ detail: {
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,20 +10,20 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,20 +10,20 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,18 +14,18 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
<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="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="065f6361461030d32c6dc08d716b013bfadab1d9"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,18 +12,18 @@
<!--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="660169a3d7e034a892359e39135e8c2785a6ad6f">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,19 +10,19 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,19 +10,19 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,18 +14,18 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
<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="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="065f6361461030d32c6dc08d716b013bfadab1d9"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,20 +10,20 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
{
"git": {
- "git_revision": "4973f57cd8f9a62a95f783a24eac32da2bde99fc",
+ "git_revision": "e698df503ff700eb5782e3d50c6eb753567d3451",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
- "revision": "c728de03bc96ef160fd5a662b3efcd5cf2c2b844",
+ "revision": "bd073200a776c714b8160a38c77f980b19fd97c2",
"repo_path": "integration/gaia-central"
}
--- a/b2g/config/nexus-4-kk/sources.xml
+++ b/b2g/config/nexus-4-kk/sources.xml
@@ -10,20 +10,20 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -13,18 +13,18 @@
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,20 +10,20 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="4973f57cd8f9a62a95f783a24eac32da2bde99fc"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e698df503ff700eb5782e3d50c6eb753567d3451"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
- <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7e0fe55ac52323eace5a6119ab2b911fc4f64495"/>
+ <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
<project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
--- a/b2g/simulator/build_xpi.py
+++ b/b2g/simulator/build_xpi.py
@@ -5,17 +5,16 @@
# Generate xpi for the simulator addon by:
# - building a special gaia profile for it, as we need:
# * more languages, and,
# * less apps
# than b2g desktop's one
# - retrieve usefull app version metadata from the build system
# - finally, use addon sdk's cfx tool to build the addon xpi
# that ships:
-# * a small firefox addon registering to the app manager
# * b2g desktop runtime
# * gaia profile
import sys, os, re, subprocess
from mozbuild.preprocessor import Preprocessor
from mozbuild.base import MozbuildObject
from mozbuild.util import ensureParentDir
from mozpack.mozjar import JarWriter
@@ -121,29 +120,20 @@ def main(platform):
# Preprocess some files...
manifest = os.path.join(build.topobjdir, "b2g", "simulator", "install.rdf")
preprocess_file(os.path.join(srcdir, "install.rdf.in"),
manifest,
version,
app_buildid,
update_url)
- options_file = os.path.join(build.topobjdir, "b2g", "simulator", "options.xul")
- preprocess_file(os.path.join(srcdir, "options.xul.in"),
- options_file,
- version,
- app_buildid,
- update_url)
-
with JarWriter(xpi_path, optimize=False) as zip:
# Ship addon files into the .xpi
- add_dir_to_zip(zip, os.path.join(srcdir, "lib"), "lib")
add_file_to_zip(zip, manifest, "install.rdf")
add_file_to_zip(zip, os.path.join(srcdir, "bootstrap.js"), "bootstrap.js")
- add_file_to_zip(zip, options_file, "options.xul")
add_file_to_zip(zip, os.path.join(srcdir, "icon.png"), "icon.png")
add_file_to_zip(zip, os.path.join(srcdir, "icon64.png"), "icon64.png")
# Ship b2g-desktop, but prevent its gaia profile to be shipped in the xpi
add_dir_to_zip(zip, os.path.join(distdir, "b2g"), "b2g",
("gaia", "B2G.app/Contents/MacOS/gaia",
"B2G.app/Contents/Resources/gaia"))
# Then ship our own gaia profile
deleted file mode 100644
--- a/b2g/simulator/lib/main.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* 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/.
- */
-
-const { Cc, Ci, Cu } = require("chrome");
-
-const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
-const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
-const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
-const { Simulator } = Cu.import("resource://gre/modules/devtools/shared/apps/Simulator.jsm");
-const { SimulatorProcess } = require("./simulator-process");
-const Runtime = require("sdk/system/runtime");
-const URL = require("sdk/url");
-
-const ROOT_URI = require("addon").uri;
-const PROFILE_URL = ROOT_URI + "profile/";
-const BIN_URL = ROOT_URI + "b2g/";
-
-var process;
-
-function launch(options) {
- // Close already opened simulation.
- if (process) {
- return close().then(launch.bind(null, options));
- }
-
- // Compute B2G runtime path.
- let path;
- try {
- let pref = "extensions." + require("addon").id + ".customRuntime";
- path = Services.prefs.getComplexValue(pref, Ci.nsIFile);
- } catch(e) {}
-
- if (!path) {
- let executables = {
- WINNT: "b2g-bin.exe",
- Darwin: "B2G.app/Contents/MacOS/b2g-bin",
- Linux: "b2g-bin",
- };
- path = URL.toFilename(BIN_URL);
- path += Runtime.OS == "WINNT" ? "\\" : "/";
- path += executables[Runtime.OS];
- }
- options.runtimePath = path;
- console.log("simulator path:", options.runtimePath);
-
- // Compute Gaia profile path.
- if (!options.profilePath) {
- let gaiaProfile;
- try {
- let pref = "extensions." + require("addon").id + ".gaiaProfile";
- gaiaProfile = Services.prefs.getComplexValue(pref, Ci.nsIFile).path;
- } catch(e) {}
-
- options.profilePath = gaiaProfile || URL.toFilename(PROFILE_URL);
- }
-
- process = new SimulatorProcess(options);
- process.run();
-
- return promise.resolve();
-}
-
-function close() {
- if (!process) {
- return promise.resolve();
- }
- let p = process;
- process = null;
- return p.kill();
-}
-
-var name;
-
-AddonManager.getAddonByID(require("addon").id, function (addon) {
- name = addon.name.replace(" Simulator", "");
-
- Simulator.register(name, {
- // We keep the deprecated `appinfo` object so that recent simulator addons
- // remain forward-compatible with older Firefox.
- appinfo: { label: name },
- launch: launch,
- close: close
- });
-});
-
-exports.shutdown = function () {
- Simulator.unregister(name);
- close();
-}
-
deleted file mode 100644
--- a/b2g/simulator/lib/simulator-process.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/* 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/.
- */
-
-'use strict';
-
-const { Cc, Ci, Cu, ChromeWorker } = require("chrome");
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-const Environment = require("sdk/system/environment").env;
-const Runtime = require("sdk/system/runtime");
-const Subprocess = require("sdk/system/child_process/subprocess");
-const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
-const { EventEmitter } = Cu.import("resource://gre/modules/devtools/shared/event-emitter.js", {});
-
-
-// Log subprocess error and debug messages to the console. This logs messages
-// for all consumers of the API. We trim the messages because they sometimes
-// have trailing newlines. And note that registerLogHandler actually registers
-// an error handler, despite its name.
-Subprocess.registerLogHandler(
- s => console.error("subprocess: " + s.trim())
-);
-Subprocess.registerDebugHandler(
- s => console.debug("subprocess: " + s.trim())
-);
-
-function SimulatorProcess(options) {
- this.options = options;
-
- EventEmitter.decorate(this);
- this.on("stdout", (e, data) => { console.log(data.trim()) });
- this.on("stderr", (e, data) => { console.error(data.trim()) });
-}
-
-SimulatorProcess.prototype = {
-
- // check if b2g is running
- get isRunning() {
- return !!this.process;
- },
-
- /**
- * Start the process and connect the debugger client.
- */
- run: function() {
- // kill before start if already running
- if (this.process != null) {
- this.process
- .kill()
- .then(this.run.bind(this));
- return;
- }
-
- // resolve b2g binaries path (raise exception if not found)
- let b2gExecutable = this.b2gExecutable;
-
- this.once("stdout", function () {
- if (Runtime.OS == "Darwin") {
- console.debug("WORKAROUND run osascript to show b2g-desktop window"+
- " on Runtime.OS=='Darwin'");
- // Escape double quotes and escape characters for use in AppleScript.
- let path = b2gExecutable.path
- .replace(/\\/g, "\\\\").replace(/\"/g, '\\"');
-
- Subprocess.call({
- command: "/usr/bin/osascript",
- arguments: ["-e", 'tell application "' + path + '" to activate'],
- });
- }
- });
-
- let environment;
- if (Runtime.OS == "Linux") {
- environment = ["TMPDIR=" + Services.dirsvc.get("TmpD", Ci.nsIFile).path];
- if ("DISPLAY" in Environment) {
- environment.push("DISPLAY=" + Environment.DISPLAY);
- }
- }
-
- // spawn a b2g instance
- this.process = Subprocess.call({
- command: b2gExecutable,
- arguments: this.b2gArguments,
- environment: environment,
-
- // emit stdout event
- stdout: data => {
- this.emit("stdout", data);
- },
-
- // emit stderr event
- stderr: data => {
- this.emit("stderr", data);
- },
-
- // on b2g instance exit, reset tracked process, remote debugger port and
- // shuttingDown flag, then finally emit an exit event
- done: (function(result) {
- console.log("B2G terminated with " + result.exitCode);
- this.process = null;
- this.emit("exit", result.exitCode);
- }).bind(this)
- });
- },
-
- // request a b2g instance kill
- kill: function() {
- let deferred = promise.defer();
- if (this.process) {
- this.once("exit", (e, exitCode) => {
- this.shuttingDown = false;
- deferred.resolve(exitCode);
- });
- if (!this.shuttingDown) {
- this.shuttingDown = true;
- this.emit("kill", null);
- this.process.kill();
- }
- return deferred.promise;
- } else {
- return promise.resolve(undefined);
- }
- },
-
- // compute current b2g file handle
- get b2gExecutable() {
- if (this._executable) {
- return this._executable;
- }
-
- let executable = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- executable.initWithPath(this.options.runtimePath);
-
- if (!executable.exists()) {
- // B2G binaries not found
- throw Error("b2g-desktop Executable not found.");
- }
-
- this._executable = executable;
-
- return executable;
- },
-
- // compute b2g CLI arguments
- get b2gArguments() {
- let args = [];
-
- let profile = this.options.profilePath;
- args.push("-profile", profile);
- console.log("profile", profile);
-
- // NOTE: push dbgport option on the b2g-desktop commandline
- args.push("-start-debugger-server", "" + this.options.port);
-
- // Ignore eventual zombie instances of b2g that are left over
- args.push("-no-remote");
-
- return args;
- },
-};
-
-exports.SimulatorProcess = SimulatorProcess;
deleted file mode 100644
--- a/b2g/simulator/options.xul.in
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" ?>
-<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <setting pref="extensions.@ADDON_ID@.gaiaProfile" type="directory" title="Select a custom Gaia profile directory"/>
- <setting pref="extensions.@ADDON_ID@.customRuntime" type="file" title="Select a custom runtime executable"/>
-</vbox>
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -914,46 +914,46 @@ notification[value="loop-sharing-notific
display: none;
}
/* Social */
/* Note the chatbox 'width' values are duplicated in socialchat.xml */
chatbox {
-moz-binding: url("chrome://browser/content/socialchat.xml#chatbox");
transition: height 150ms ease-out, width 150ms ease-out;
- height: 285px;
- width: 260px; /* CHAT_WIDTH_OPEN in socialchat.xml */
+ height: 290px;
+ width: 300px; /* CHAT_WIDTH_OPEN in socialchat.xml */
}
chatbox[customSize] {
- width: 300px; /* CHAT_WIDTH_OPEN_ALT in socialchat.xml */
+ width: 350px; /* CHAT_WIDTH_OPEN_ALT in socialchat.xml */
}
#chat-window[customSize] {
- min-width: 300px;
+ min-width: 350px;
}
chatbox[customSize="loopChatEnabled"] {
/* 325px as defined per UX */
height: 325px;
}
#chat-window[customSize="loopChatEnabled"] {
/* 325px + 30px top bar height. */
min-height: calc(325px + 30px);
}
chatbox[customSize="loopChatMessageAppended"] {
- /* 445px as defined per UX */
- height: 445px;
+ /* 400px as defined per UX */
+ height: 400px;
}
#chat-window[customSize="loopChatMessageAppended"] {
/* 445px + 30px top bar height. */
- min-height: calc(445px + 30px);
+ min-height: calc(400px + 30px);
}
chatbox[minimized="true"] {
width: 160px;
height: 20px; /* CHAT_WIDTH_MINIMIZED in socialchat.xml */
}
chatbar {
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -1,15 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
-var Cu = Components.utils;
-Cu.import("resource://gre/modules/LoadContextInfo.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/LoadContextInfo.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
//******** define a js object to implement nsITreeView
function pageInfoTreeView(treeid, copycol)
{
// copycol is the index number for the column that we want to add to
// the copy-n-paste buffer when the user hits accel-c
this.treeid = treeid;
this.copycol = copycol;
--- a/browser/base/content/socialchat.xml
+++ b/browser/base/content/socialchat.xml
@@ -468,18 +468,18 @@
]]></body>
</method>
<method name="getTotalChildWidth">
<parameter name="aChatbox"/>
<body><![CDATA[
// These are from the CSS for the chatbox and must be kept in sync.
// We can't use calcTotalWidthOf due to the transitions...
- const CHAT_WIDTH_OPEN = 260;
- const CHAT_WIDTH_OPEN_ALT = 300;
+ const CHAT_WIDTH_OPEN = 300;
+ const CHAT_WIDTH_OPEN_ALT = 350;
const CHAT_WIDTH_MINIMIZED = 160;
let openWidth = aChatbox.hasAttribute("customSize") ?
CHAT_WIDTH_OPEN_ALT : CHAT_WIDTH_OPEN;
return aChatbox.minimized ? CHAT_WIDTH_MINIMIZED : openWidth;
]]></body>
</method>
--- a/browser/components/loop/content/css/panel.css
+++ b/browser/components/loop/content/css/panel.css
@@ -71,174 +71,32 @@ body {
.sign-in-request-button {
font-size: 1rem;
margin: 1rem;
width: 80%;
padding: .5rem 1rem;
border-radius: 3px;
}
-/* Tabs and tab selection buttons */
-
-.tab-view-container {
- width: 100%;
- background-image: url("../shared/img/beta-ribbon.svg#beta-ribbon");
- background-color: #fbfbfb;
- background-size: 36px 36px;
- background-repeat: no-repeat;
- flex: 1;
- display: flex;
- flex-flow: column nowrap;
- overflow: hidden;
-}
-
-.tab-view {
- position: relative;
- width: 100%;
- height: 4rem;
- line-height: 3.7rem;
- color: #4A4A4A;
- list-style: none;
- border-bottom: 2px solid #ccc;
-}
-
-.tab-view > li {
- display: inline-block;
- text-align: center;
- padding: 0;
- cursor: pointer;
-}
-
-.tab-view > .slide-bar {
- position: absolute;
- bottom: -2px;
- left: 0;
- height: .2em;
- width: 50%;
- background: #00A9DC;
- border: none;
- transition: margin .3s ease-in-out;
-}
-
-.tab-view li:nth-child(1).selected ~ .slide-bar {
- margin-left: 0;
-}
-
-.tab-view li:nth-child(2).selected ~ .slide-bar {
- margin-left: 50%;
-}
-
-html[dir="rtl"] .tab-view li:nth-child(1).selected ~ .slide-bar {
- margin-left: 50%;
-}
-
-html[dir="rtl"] .tab-view li:nth-child(2).selected ~ .slide-bar {
- margin-left: 0;
-}
-
-.tab-view > li > div {
- font-size: 1.2rem;
- pointer-events: none;
- display: inline;
-}
-
-.tab-view > li:before {
- content: "";
- pointer-events: none;
- display: inline-block;
- -moz-margin-end: .5rem;
- vertical-align: middle;
- height: 1.4rem;
- width: 1.4rem;
- transition-property: background-image;
-}
-
-.tab-view > li.selected {
- transition-delay: .3s;
-}
-
-.tab-view > li[data-tab-name="rooms"]:before {
- background-image: url("../shared/img/icons-14x14.svg#hello");
-}
-
-.tab-view > li[data-tab-name="rooms"]:hover:before {
- background-image: url("../shared/img/icons-14x14.svg#hello-hover");
-}
-
-.tab-view > li[data-tab-name="rooms"].selected:before {
- background-image: url("../shared/img/icons-14x14.svg#hello-active");
-}
-
-.tab-view > li[data-tab-name="contacts"]:before {
- background-image: url("../shared/img/icons-14x14.svg#contacts");
-}
-
-.tab-view > li[data-tab-name="contacts"]:hover:before {
- background-image: url("../shared/img/icons-14x14.svg#contacts-hover");
-}
-
-.tab-view > li[data-tab-name="contacts"].selected:before {
- background-image: url("../shared/img/icons-14x14.svg#contacts-active");
-}
-
-/* Styling for one tab */
-.tab-view li:first-child:nth-last-child(2) {
- width: 100%;
-}
-
-.tab-view li:first-child:nth-last-child(2) > span {
- display: none;
-}
-
-.tab-view li:first-child:nth-last-child(2) > span {
- display: none;
-}
-
-.tab-view li:first-child:nth-last-child(2):before {
- background-image: url("../shared/img/icons-14x14.svg#hello-hover");
-}
-
-.tab-view li:first-child:nth-last-child(2) ~ li {
- /* hide the tab-slider when there is only one tab shown */
- display: none;
-}
-
-.tab-view li:first-child:nth-last-child(3),
-.tab-view li:first-child:nth-last-child(3) ~ li {
- width: 50%;
-}
-
-.tab {
- display: none;
- flex: 1;
- overflow: auto;
-}
-
-.tab.selected {
- display: flex;
- flex-flow: column nowrap;
-}
-
/* Content area and input fields */
.content-area {
padding: .5rem 1rem;
}
.content-area header {
font-weight: 700;
}
/* Need to remove when these rules when the Beta tag is removed */
#share-link-header {
-moz-padding-start: 20px;
}
-.fte-get-started-container + .generate-url > #share-link-header,
-.tab-view + .tab .content-area > .generate-url > #share-link-header {
+.fte-get-started-container + .generate-url > #share-link-header {
/* The header shouldn't be indented if the tabs are present. */
-moz-padding-start: 0;
}
.content-area label {
display: block;
width: 100%;
margin-top: 10px;
@@ -326,16 +184,17 @@ html[dir="rtl"] .tab-view li:nth-child(2
}
/* Rooms */
.rooms {
flex: 1;
display: flex;
flex-flow: column nowrap;
+ width: 100%;
}
.rooms > h1 {
font-weight: bold;
color: #666;
padding: .5rem 0;
height: 3rem;
line-height: 3rem;
@@ -409,16 +268,17 @@ html[dir="rtl"] .tab-view li:nth-child(2
/* xxx not sure why flex needs the 3 value setting
but setting flex to just 1, the whole tab including the new room is scrollable.
seems to not like the 0% of the default setting - may be FF bug */
flex: 1 1 0;
overflow-y: auto;
overflow-x: hidden;
display: flex;
flex-flow: column nowrap;
+ width: 100%;
}
.room-list-empty {
border-bottom-width: 0;
flex: 1;
/* the child no-conversations-message is vertical aligned inside this container
see: http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/
stops blurring from decimal pixels being rendered - pixel rounding */
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -5,119 +5,18 @@
var loop = loop || {};
loop.panel = (function(_, mozL10n) {
"use strict";
var sharedViews = loop.shared.views;
var sharedModels = loop.shared.models;
var sharedMixins = loop.shared.mixins;
var sharedActions = loop.shared.actions;
- var sharedUtils = loop.shared.utils;
var Button = sharedViews.Button;
- var ButtonGroup = sharedViews.ButtonGroup;
var Checkbox = sharedViews.Checkbox;
- var ContactsControllerView = loop.contacts.ContactsControllerView;
-
- var TabView = React.createClass({displayName: "TabView",
- propTypes: {
- buttonsHidden: React.PropTypes.array,
- children: React.PropTypes.arrayOf(React.PropTypes.element),
- mozLoop: React.PropTypes.object,
- // The selectedTab prop is used by the UI showcase.
- selectedTab: React.PropTypes.string
- },
-
- getDefaultProps: function() {
- return {
- buttonsHidden: []
- };
- },
-
- shouldComponentUpdate: function(nextProps, nextState) {
- var tabChange = this.state.selectedTab !== nextState.selectedTab;
- if (tabChange) {
- this.props.mozLoop.notifyUITour("Loop:PanelTabChanged", nextState.selectedTab);
- }
-
- if (!tabChange && nextProps.buttonsHidden) {
- if (nextProps.buttonsHidden.length !== this.props.buttonsHidden.length) {
- tabChange = true;
- } else {
- for (var i = 0, l = nextProps.buttonsHidden.length; i < l && !tabChange; ++i) {
- if (this.props.buttonsHidden.indexOf(nextProps.buttonsHidden[i]) === -1) {
- tabChange = true;
- }
- }
- }
- }
- return tabChange;
- },
-
- getInitialState: function() {
- // XXX Work around props.selectedTab being undefined initially.
- // When we don't need to rely on the pref, this can move back to
- // getDefaultProps (bug 1100258).
- return {
- selectedTab: this.props.selectedTab || "rooms"
- };
- },
-
- handleSelectTab: function(event) {
- var tabName = event.target.dataset.tabName;
- this.setState({selectedTab: tabName});
- },
-
- render: function() {
- var cx = React.addons.classSet;
- var tabButtons = [];
- var tabs = [];
- React.Children.forEach(this.props.children, function(tab, i) {
- // Filter out null tabs (eg. rooms when the feature is disabled)
- if (!tab) {
- return;
- }
- var tabName = tab.props.name;
- if (this.props.buttonsHidden.indexOf(tabName) > -1) {
- return;
- }
- var isSelected = (this.state.selectedTab === tabName);
- if (!tab.props.hidden) {
- var label = mozL10n.get(tabName + "_tab_button");
- tabButtons.push(
- React.createElement("li", {className: cx({selected: isSelected}),
- "data-tab-name": tabName,
- key: i,
- onClick: this.handleSelectTab},
- React.createElement("div", null, label)
- )
- );
- }
- tabs.push(
- React.createElement("div", {className: cx({tab: true, selected: isSelected}), key: i},
- tab.props.children
- )
- );
- }, this);
- return (
- React.createElement("div", {className: "tab-view-container"},
- React.createElement("ul", {className: "tab-view"},
- tabButtons,
- React.createElement("li", {className: "slide-bar"})
- ),
- tabs
- )
- );
- }
- });
-
- var Tab = React.createClass({displayName: "Tab",
- render: function() {
- return null;
- }
- });
/**
* Availability drop down menu subview.
*/
var AvailabilityDropdown = React.createClass({displayName: "AvailabilityDropdown",
mixins: [sharedMixins.DropdownMenuMixin()],
getInitialState: function() {
@@ -764,19 +663,17 @@ loop.panel = (function(_, mozL10n) {
* Room list.
*/
var RoomList = React.createClass({displayName: "RoomList",
mixins: [Backbone.Events, sharedMixins.WindowCloseMixin],
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
mozLoop: React.PropTypes.object.isRequired,
- store: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
- // Used for room creation, associated with room owner.
- userProfile: userProfileValidator
+ store: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
},
getInitialState: function() {
return this.props.store.getStoreState();
},
componentDidMount: function() {
this.listenTo(this.props.store, "change", this._onStoreStateChanged);
@@ -799,21 +696,16 @@ loop.panel = (function(_, mozL10n) {
this.closeWindow();
}
},
_onStoreStateChanged: function() {
this.setState(this.props.store.getStoreState());
},
- _getUserDisplayName: function() {
- return this.props.userProfile && this.props.userProfile.email ||
- mozL10n.get("display_name_guest");
- },
-
/**
* Let the user know we're loading rooms
* @returns {Object} React render
*/
_renderLoadingRoomsView: function() {
return (
React.createElement("div", {className: "room-list"},
React.createElement("div", {className: "room-list-loading"},
@@ -842,18 +734,17 @@ loop.panel = (function(_, mozL10n) {
);
},
_renderNewRoomButton: function() {
return (
React.createElement(NewRoomView, {dispatcher: this.props.dispatcher,
mozLoop: this.props.mozLoop,
pendingOperation: this.state.pendingCreation ||
- this.state.pendingInitialRetrieval,
- userDisplayName: this._getUserDisplayName()})
+ this.state.pendingInitialRetrieval})
);
},
render: function() {
if (this.state.error) {
// XXX Better end user reporting of errors.
console.error("RoomList error", this.state.error);
}
@@ -888,18 +779,17 @@ loop.panel = (function(_, mozL10n) {
/**
* Used for creating a new room with or without context.
*/
var NewRoomView = React.createClass({displayName: "NewRoomView",
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
mozLoop: React.PropTypes.object.isRequired,
- pendingOperation: React.PropTypes.bool.isRequired,
- userDisplayName: React.PropTypes.string.isRequired
+ pendingOperation: React.PropTypes.bool.isRequired
},
mixins: [
sharedMixins.DocumentVisibilityMixin,
React.addons.PureRenderMixin
],
getInitialState: function() {
@@ -996,24 +886,20 @@ loop.panel = (function(_, mozL10n) {
});
/**
* Panel view.
*/
var PanelView = React.createClass({displayName: "PanelView",
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
- initialSelectedTabComponent: React.PropTypes.string,
mozLoop: React.PropTypes.object.isRequired,
notifications: React.PropTypes.object.isRequired,
roomStore:
- React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
- selectedTab: React.PropTypes.string,
- // Used only for unit tests.
- showTabButtons: React.PropTypes.bool
+ React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
},
getInitialState: function() {
return {
hasEncryptionKey: this.props.mozLoop.hasEncryptionKey,
userProfile: this.props.mozLoop.userProfile,
gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen")
};
@@ -1051,62 +937,39 @@ loop.panel = (function(_, mozL10n) {
_onStatusChanged: function() {
var profile = this.props.mozLoop.userProfile;
var currUid = this.state.userProfile ? this.state.userProfile.uid : null;
var newUid = profile ? profile.uid : null;
if (currUid === newUid) {
// Update the state of hasEncryptionKey as this might have changed now.
this.setState({hasEncryptionKey: this.props.mozLoop.hasEncryptionKey});
} else {
- // On profile change (login, logout), switch back to the default tab.
- this.selectTab("rooms");
this.setState({userProfile: profile});
}
this.updateServiceErrors();
},
_gettingStartedSeen: function() {
this.setState({
gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen")
});
},
- _UIActionHandler: function(e) {
- switch (e.detail.action) {
- case "selectTab":
- this.selectTab(e.detail.tab);
- break;
- default:
- console.error("Invalid action", e.detail.action);
- break;
- }
- },
-
- selectTab: function(name) {
- // The tab view might not be created yet (e.g. getting started or fxa
- // re-sign in.
- if (this.refs.tabView) {
- this.refs.tabView.setState({ selectedTab: name });
- }
- },
-
componentWillMount: function() {
this.updateServiceErrors();
},
componentDidMount: function() {
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
- window.addEventListener("UIAction", this._UIActionHandler);
},
componentWillUnmount: function() {
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
- window.removeEventListener("UIAction", this._UIActionHandler);
},
render: function() {
var NotificationListView = sharedViews.NotificationListView;
if (!this.state.gettingStartedSeen) {
return (
React.createElement("div", {className: "fte-get-started-container"},
@@ -1118,45 +981,24 @@ loop.panel = (function(_, mozL10n) {
)
);
}
if (!this.state.hasEncryptionKey) {
return React.createElement(SignInRequestView, {mozLoop: this.props.mozLoop});
}
- // Determine which buttons to NOT show.
- var hideButtons = [];
- if (!this.state.userProfile && !this.props.showTabButtons) {
- hideButtons.push("contacts");
- }
-
return (
React.createElement("div", {className: "panel-content"},
React.createElement(NotificationListView, {
clearOnDocumentHidden: true,
notifications: this.props.notifications}),
- React.createElement(TabView, {
- buttonsHidden: hideButtons,
- mozLoop: this.props.mozLoop,
- ref: "tabView",
- selectedTab: this.props.selectedTab},
- React.createElement(Tab, {name: "rooms"},
- React.createElement(RoomList, {dispatcher: this.props.dispatcher,
- mozLoop: this.props.mozLoop,
- store: this.props.roomStore,
- userProfile: this.state.userProfile})
- ),
- React.createElement(Tab, {name: "contacts"},
- React.createElement(ContactsControllerView, {initialSelectedTabComponent: this.props.initialSelectedTabComponent,
- mozLoop: this.props.mozLoop,
- notifications: this.props.notifications,
- ref: "contactControllerView"})
- )
- ),
+ React.createElement(RoomList, {dispatcher: this.props.dispatcher,
+ mozLoop: this.props.mozLoop,
+ store: this.props.roomStore}),
React.createElement("div", {className: "footer"},
React.createElement("div", {className: "user-details"},
React.createElement(AvailabilityDropdown, null)
),
React.createElement("div", {className: "signin-details"},
React.createElement(AccountLink, {fxAEnabled: this.props.mozLoop.fxAEnabled,
userProfile: this.state.userProfile}),
React.createElement(SettingsDropdown, {mozLoop: this.props.mozLoop})
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -5,119 +5,18 @@
var loop = loop || {};
loop.panel = (function(_, mozL10n) {
"use strict";
var sharedViews = loop.shared.views;
var sharedModels = loop.shared.models;
var sharedMixins = loop.shared.mixins;
var sharedActions = loop.shared.actions;
- var sharedUtils = loop.shared.utils;
var Button = sharedViews.Button;
- var ButtonGroup = sharedViews.ButtonGroup;
var Checkbox = sharedViews.Checkbox;
- var ContactsControllerView = loop.contacts.ContactsControllerView;
-
- var TabView = React.createClass({
- propTypes: {
- buttonsHidden: React.PropTypes.array,
- children: React.PropTypes.arrayOf(React.PropTypes.element),
- mozLoop: React.PropTypes.object,
- // The selectedTab prop is used by the UI showcase.
- selectedTab: React.PropTypes.string
- },
-
- getDefaultProps: function() {
- return {
- buttonsHidden: []
- };
- },
-
- shouldComponentUpdate: function(nextProps, nextState) {
- var tabChange = this.state.selectedTab !== nextState.selectedTab;
- if (tabChange) {
- this.props.mozLoop.notifyUITour("Loop:PanelTabChanged", nextState.selectedTab);
- }
-
- if (!tabChange && nextProps.buttonsHidden) {
- if (nextProps.buttonsHidden.length !== this.props.buttonsHidden.length) {
- tabChange = true;
- } else {
- for (var i = 0, l = nextProps.buttonsHidden.length; i < l && !tabChange; ++i) {
- if (this.props.buttonsHidden.indexOf(nextProps.buttonsHidden[i]) === -1) {
- tabChange = true;
- }
- }
- }
- }
- return tabChange;
- },
-
- getInitialState: function() {
- // XXX Work around props.selectedTab being undefined initially.
- // When we don't need to rely on the pref, this can move back to
- // getDefaultProps (bug 1100258).
- return {
- selectedTab: this.props.selectedTab || "rooms"
- };
- },
-
- handleSelectTab: function(event) {
- var tabName = event.target.dataset.tabName;
- this.setState({selectedTab: tabName});
- },
-
- render: function() {
- var cx = React.addons.classSet;
- var tabButtons = [];
- var tabs = [];
- React.Children.forEach(this.props.children, function(tab, i) {
- // Filter out null tabs (eg. rooms when the feature is disabled)
- if (!tab) {
- return;
- }
- var tabName = tab.props.name;
- if (this.props.buttonsHidden.indexOf(tabName) > -1) {
- return;
- }
- var isSelected = (this.state.selectedTab === tabName);
- if (!tab.props.hidden) {
- var label = mozL10n.get(tabName + "_tab_button");
- tabButtons.push(
- <li className={cx({selected: isSelected})}
- data-tab-name={tabName}
- key={i}
- onClick={this.handleSelectTab}>
- <div>{label}</div>
- </li>
- );
- }
- tabs.push(
- <div className={cx({tab: true, selected: isSelected})} key={i}>
- {tab.props.children}
- </div>
- );
- }, this);
- return (
- <div className="tab-view-container">
- <ul className="tab-view">
- {tabButtons}
- <li className="slide-bar" />
- </ul>
- {tabs}
- </div>
- );
- }
- });
-
- var Tab = React.createClass({
- render: function() {
- return null;
- }
- });
/**
* Availability drop down menu subview.
*/
var AvailabilityDropdown = React.createClass({
mixins: [sharedMixins.DropdownMenuMixin()],
getInitialState: function() {
@@ -764,19 +663,17 @@ loop.panel = (function(_, mozL10n) {
* Room list.
*/
var RoomList = React.createClass({
mixins: [Backbone.Events, sharedMixins.WindowCloseMixin],
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
mozLoop: React.PropTypes.object.isRequired,
- store: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
- // Used for room creation, associated with room owner.
- userProfile: userProfileValidator
+ store: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
},
getInitialState: function() {
return this.props.store.getStoreState();
},
componentDidMount: function() {
this.listenTo(this.props.store, "change", this._onStoreStateChanged);
@@ -799,21 +696,16 @@ loop.panel = (function(_, mozL10n) {
this.closeWindow();
}
},
_onStoreStateChanged: function() {
this.setState(this.props.store.getStoreState());
},
- _getUserDisplayName: function() {
- return this.props.userProfile && this.props.userProfile.email ||
- mozL10n.get("display_name_guest");
- },
-
/**
* Let the user know we're loading rooms
* @returns {Object} React render
*/
_renderLoadingRoomsView: function() {
return (
<div className="room-list">
<div className="room-list-loading">
@@ -842,18 +734,17 @@ loop.panel = (function(_, mozL10n) {
);
},
_renderNewRoomButton: function() {
return (
<NewRoomView dispatcher={this.props.dispatcher}
mozLoop={this.props.mozLoop}
pendingOperation={this.state.pendingCreation ||
- this.state.pendingInitialRetrieval}
- userDisplayName={this._getUserDisplayName()} />
+ this.state.pendingInitialRetrieval} />
);
},
render: function() {
if (this.state.error) {
// XXX Better end user reporting of errors.
console.error("RoomList error", this.state.error);
}
@@ -888,18 +779,17 @@ loop.panel = (function(_, mozL10n) {
/**
* Used for creating a new room with or without context.
*/
var NewRoomView = React.createClass({
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
mozLoop: React.PropTypes.object.isRequired,
- pendingOperation: React.PropTypes.bool.isRequired,
- userDisplayName: React.PropTypes.string.isRequired
+ pendingOperation: React.PropTypes.bool.isRequired
},
mixins: [
sharedMixins.DocumentVisibilityMixin,
React.addons.PureRenderMixin
],
getInitialState: function() {
@@ -996,24 +886,20 @@ loop.panel = (function(_, mozL10n) {
});
/**
* Panel view.
*/
var PanelView = React.createClass({
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
- initialSelectedTabComponent: React.PropTypes.string,
mozLoop: React.PropTypes.object.isRequired,
notifications: React.PropTypes.object.isRequired,
roomStore:
- React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
- selectedTab: React.PropTypes.string,
- // Used only for unit tests.
- showTabButtons: React.PropTypes.bool
+ React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
},
getInitialState: function() {
return {
hasEncryptionKey: this.props.mozLoop.hasEncryptionKey,
userProfile: this.props.mozLoop.userProfile,
gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen")
};
@@ -1051,62 +937,39 @@ loop.panel = (function(_, mozL10n) {
_onStatusChanged: function() {
var profile = this.props.mozLoop.userProfile;
var currUid = this.state.userProfile ? this.state.userProfile.uid : null;
var newUid = profile ? profile.uid : null;
if (currUid === newUid) {
// Update the state of hasEncryptionKey as this might have changed now.
this.setState({hasEncryptionKey: this.props.mozLoop.hasEncryptionKey});
} else {
- // On profile change (login, logout), switch back to the default tab.
- this.selectTab("rooms");
this.setState({userProfile: profile});
}
this.updateServiceErrors();
},
_gettingStartedSeen: function() {
this.setState({
gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen")
});
},
- _UIActionHandler: function(e) {
- switch (e.detail.action) {
- case "selectTab":
- this.selectTab(e.detail.tab);
- break;
- default:
- console.error("Invalid action", e.detail.action);
- break;
- }
- },
-
- selectTab: function(name) {
- // The tab view might not be created yet (e.g. getting started or fxa
- // re-sign in.
- if (this.refs.tabView) {
- this.refs.tabView.setState({ selectedTab: name });
- }
- },
-
componentWillMount: function() {
this.updateServiceErrors();
},
componentDidMount: function() {
window.addEventListener("LoopStatusChanged", this._onStatusChanged);
window.addEventListener("GettingStartedSeen", this._gettingStartedSeen);
- window.addEventListener("UIAction", this._UIActionHandler);
},
componentWillUnmount: function() {
window.removeEventListener("LoopStatusChanged", this._onStatusChanged);
window.removeEventListener("GettingStartedSeen", this._gettingStartedSeen);
- window.removeEventListener("UIAction", this._UIActionHandler);
},
render: function() {
var NotificationListView = sharedViews.NotificationListView;
if (!this.state.gettingStartedSeen) {
return (
<div className="fte-get-started-container">
@@ -1118,45 +981,24 @@ loop.panel = (function(_, mozL10n) {
</div>
);
}
if (!this.state.hasEncryptionKey) {
return <SignInRequestView mozLoop={this.props.mozLoop} />;
}
- // Determine which buttons to NOT show.
- var hideButtons = [];
- if (!this.state.userProfile && !this.props.showTabButtons) {
- hideButtons.push("contacts");
- }
-
return (
<div className="panel-content">
<NotificationListView
clearOnDocumentHidden={true}
notifications={this.props.notifications} />
- <TabView
- buttonsHidden={hideButtons}
- mozLoop={this.props.mozLoop}
- ref="tabView"
- selectedTab={this.props.selectedTab}>
- <Tab name="rooms">
- <RoomList dispatcher={this.props.dispatcher}
- mozLoop={this.props.mozLoop}
- store={this.props.roomStore}
- userProfile={this.state.userProfile} />
- </Tab>
- <Tab name="contacts">
- <ContactsControllerView initialSelectedTabComponent={this.props.initialSelectedTabComponent}
- mozLoop={this.props.mozLoop}
- notifications={this.props.notifications}
- ref="contactControllerView" />
- </Tab>
- </TabView>
+ <RoomList dispatcher={this.props.dispatcher}
+ mozLoop={this.props.mozLoop}
+ store={this.props.roomStore} />
<div className="footer">
<div className="user-details">
<AvailabilityDropdown />
</div>
<div className="signin-details">
<AccountLink fxAEnabled={this.props.mozLoop.fxAEnabled}
userProfile={this.state.userProfile}/>
<SettingsDropdown mozLoop={this.props.mozLoop}/>
--- a/browser/components/loop/content/shared/css/conversation.css
+++ b/browser/components/loop/content/shared/css/conversation.css
@@ -1107,17 +1107,17 @@ body[platform="win"] .share-service-drop
}
.media-wrapper.receiving-screen-share > .text-chat-view {
order: 4;
}
}
/* e.g. very narrow widths similar to conversation window */
-@media screen and (max-width:300px) {
+@media screen and (max-width:350px) {
.media-layout > .media-wrapper {
flex-flow: column nowrap;
}
.media-wrapper > .focus-stream > .local ~ .conversation-toolbar {
max-width: calc(75% - 22px);
}
@@ -1434,17 +1434,17 @@ html[dir="rtl"] .text-chat-entry.receive
width: 100%;
}
.standalone .room-conversation .video_wrapper.remote_wrapper.not-joined {
width: 100%;
}
}
/* e.g. very narrow widths similar to conversation window */
-@media screen and (max-width:300px) {
+@media screen and (max-width:350px) {
.text-chat-view {
display: flex;
flex-flow: column nowrap;
/* 120px max-height of .text-chat-entries plus 40px of .text-chat-box */
max-height: 160px;
/* 60px min-height of .text-chat-entries plus 40px of .text-chat-box */
min-height: 100px;
height: auto;
--- a/browser/components/loop/test/desktop-local/panel_test.js
+++ b/browser/components/loop/test/desktop-local/panel_test.js
@@ -205,79 +205,16 @@ describe("loop.panel", function() {
React.createElement(loop.panel.SettingsDropdown, {
mozLoop: fakeMozLoop
}));
expect(view.getDOMNode().querySelectorAll(".icon-account"))
.to.have.length.of(0);
});
- describe("TabView", function() {
- var view, callTab, roomsTab, contactsTab;
-
- beforeEach(function() {
- navigator.mozLoop.getLoopPref = function(pref) {
- if (pref === "gettingStarted.seen") {
- return true;
- }
- };
-
- view = createTestPanelView();
-
- [roomsTab, contactsTab] =
- TestUtils.scryRenderedDOMComponentsWithClass(view, "tab");
- });
-
- it("should select contacts tab when clicking tab button", function() {
- TestUtils.Simulate.click(
- view.getDOMNode().querySelector("li[data-tab-name=\"contacts\"]"));
-
- expect(contactsTab.getDOMNode().classList.contains("selected"))
- .to.be.true;
- });
-
- it("should select rooms tab when clicking tab button", function() {
- TestUtils.Simulate.click(
- view.getDOMNode().querySelector("li[data-tab-name=\"rooms\"]"));
-
- expect(roomsTab.getDOMNode().classList.contains("selected"))
- .to.be.true;
- });
- });
-
- describe("Contacts", function() {
- var view, roomsTab, contactsTab;
-
- beforeEach(function() {
- view = TestUtils.renderIntoDocument(
- React.createElement(loop.panel.PanelView, {
- dispatcher: dispatcher,
- initialSelectedTabComponent: "contactList",
- mozLoop: navigator.mozLoop,
- notifications: notifications,
- roomStore: roomStore,
- selectedTab: "contacts",
- showTabButtons: true
- }));
-
- [roomsTab, contactsTab] =
- TestUtils.scryRenderedDOMComponentsWithClass(view, "tab");
- });
-
- it("should expect Contacts tab to be selected when Contacts List displayed", function() {
- expect(contactsTab.getDOMNode().classList.contains("selected"))
- .to.be.true;
- });
-
- it("should expect Rooms tab to be not selected when Contacts List displayed", function() {
- expect(roomsTab.getDOMNode().classList.contains("selected"))
- .to.be.false;
- });
- });
-
describe("AccountLink", function() {
beforeEach(function() {
navigator.mozLoop.calls = { clearCallInProgress: function() {} };
});
afterEach(function() {
delete navigator.mozLoop.logInToFxA;
delete navigator.mozLoop.calls;
--- a/browser/components/loop/test/mochitest/browser_toolbarbutton.js
+++ b/browser/components/loop/test/mochitest/browser_toolbarbutton.js
@@ -27,55 +27,23 @@ registerCleanupFunction(function*() {
MozLoopServiceInternal.fxAOAuthProfile = null;
yield MozLoopServiceInternal.clearError("testing");
Services.prefs.clearUserPref("loop.gettingStarted.seen");
});
add_task(function* test_LoopUI_getters() {
Assert.ok(LoopUI.panel, "LoopUI panel element should be set");
Assert.strictEqual(LoopUI.browser, null, "Browser element should not be there yet");
- Assert.strictEqual(LoopUI.selectedTab, null, "No tab should be selected yet");
// Load and show the Loop panel for the very first time this session.
yield loadLoopPanel();
Assert.ok(LoopUI.browser, "Browser element should be there");
- Assert.strictEqual(LoopUI.selectedTab, "rooms", "Initially the rooms tab should be selected");
- let panelTabs = LoopUI.browser.contentDocument.querySelectorAll(".tab-view > li:not(.slide-bar)");
- Assert.strictEqual(panelTabs.length, 1, "Only one tab, 'rooms', should be visible");
// Hide the panel.
yield LoopUI.togglePanel();
- Assert.strictEqual(LoopUI.selectedTab, "rooms", "Rooms tab should still be selected");
-
- // Make sure the contacts tab shows up by simulating a login.
- MozLoopServiceInternal.fxAOAuthTokenData = fxASampleToken;
- MozLoopServiceInternal.fxAOAuthProfile = fxASampleProfile;
- yield MozLoopServiceInternal.notifyStatusChanged("login");
-
- yield LoopUI.togglePanel();
- Assert.strictEqual(LoopUI.selectedTab, "rooms", "Rooms tab should still be selected");
- panelTabs = LoopUI.browser.contentDocument.querySelectorAll(".tab-view > li:not(.slide-bar)");
- Assert.strictEqual(panelTabs.length, 2, "Two tabs should be visible");
- yield LoopUI.togglePanel();
-
- // Programmatically select the contacts tab.
- yield LoopUI.togglePanel(null, "contacts");
- Assert.strictEqual(LoopUI.selectedTab, "contacts", "Contacts tab should be selected now");
-
- // Switch back to the rooms tab.
- yield LoopUI.openCallPanel(null, "rooms");
- Assert.strictEqual(LoopUI.selectedTab, "rooms", "Rooms tab should be selected now");
-
- // Hide the panel.
- yield LoopUI.togglePanel();
-
- // Logout to prevent interfering with the tests after this one.
- MozLoopServiceInternal.fxAOAuthTokenData =
- MozLoopServiceInternal.fxAOAuthProfile = null;
- yield MozLoopServiceInternal.notifyStatusChanged();
});
add_task(function* test_doNotDisturb() {
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "", "Check button is in default state");
yield MozLoopService.doNotDisturb = true;
Assert.strictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "disabled", "Check button is in disabled state");
yield MozLoopService.doNotDisturb = false;
Assert.notStrictEqual(LoopUI.toolbarButton.node.getAttribute("state"), "disabled", "Check button is not in disabled state");
--- a/browser/components/loop/ui/ui-showcase.js
+++ b/browser/components/loop/ui/ui-showcase.js
@@ -761,103 +761,97 @@
height: 410,
summary: "First time experience view",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: firstTimeUseMozLoop,
notifications: notifications,
- roomStore: roomStore,
- selectedTab: "rooms"})
+ roomStore: roomStore})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Re-sign-in view",
width: 332},
React.createElement("div", {className: "panel"},
React.createElement(SignInRequestView, {mozLoop: mockMozLoopLoggedIn})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
- summary: "Room list tab",
+ summary: "Room list",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopLoggedIn,
notifications: notifications,
- roomStore: roomStore,
- selectedTab: "rooms"})
+ roomStore: roomStore})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
- summary: "Room list tab (No Context)",
+ summary: "Room list (No Context)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopLoggedInNoContext,
notifications: notifications,
- roomStore: roomStore,
- selectedTab: "rooms"})
+ roomStore: roomStore})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
- summary: "Room list tab (no rooms)",
+ summary: "Room list (no rooms)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopNoRooms,
notifications: notifications,
- roomStore: roomStoreNoRooms,
- selectedTab: "rooms"})
+ roomStore: roomStoreNoRooms})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
- summary: "Room list tab (no rooms and no context)",
+ summary: "Room list (no rooms and no context)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopNoRoomsNoContext,
notifications: notifications,
- roomStore: roomStoreNoRooms,
- selectedTab: "rooms"})
+ roomStore: roomStoreNoRooms})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
- summary: "Room list tab (loading view)",
+ summary: "Room list (loading view)",
width: 330},
React.createElement("div", {className: "panel"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopNoRoomsNoContext,
notifications: notifications,
- roomStore: roomStoreNoRoomsPending,
- selectedTab: "rooms"})
+ roomStore: roomStoreNoRoomsPending})
)
),
React.createElement(FramedExample, {cssClass: "fx-embedded-panel",
dashed: true,
height: 410,
summary: "Contact list tab",
width: 330},
@@ -1210,20 +1204,20 @@
mozLoop: navigator.mozLoop,
outgoing: true})
)
)
),
React.createElement(Section, {name: "OngoingConversationView"},
React.createElement(FramedExample, {dashed: true,
- height: 394,
+ height: 398,
onContentsRendered: conversationStores[0].forcedUpdate,
summary: "Desktop ongoing conversation window",
- width: 298},
+ width: 348},
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
audio: { enabled: true, visible: true},
chatWindowDetached: false,
conversationStore: conversationStores[0],
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mediaConnected: true,
@@ -1266,39 +1260,39 @@
mediaConnected: true,
remotePosterUrl: "sample-img/video-screen-remote.png",
remoteVideoEnabled: true,
video: { enabled: true, visible: true}})
)
),
React.createElement(FramedExample, {dashed: true,
- height: 394,
+ height: 398,
onContentsRendered: conversationStores[3].forcedUpdate,
summary: "Desktop ongoing conversation window - local face mute",
- width: 298},
+ width: 348},
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
audio: { enabled: true, visible: true},
chatWindowDetached: false,
conversationStore: conversationStores[3],
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mediaConnected: true,
remotePosterUrl: "sample-img/video-screen-remote.png",
remoteVideoEnabled: true,
video: { enabled: false, visible: true}})
)
),
React.createElement(FramedExample, {dashed: true,
- height: 394,
+ height: 398,
onContentsRendered: conversationStores[4].forcedUpdate,
summary: "Desktop ongoing conversation window - remote face mute",
- width: 298},
+ width: 348},
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
audio: { enabled: true, visible: true},
chatWindowDetached: false,
conversationStore: conversationStores[4],
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mediaConnected: true,
@@ -1309,31 +1303,31 @@
)
),
React.createElement(Section, {name: "FeedbackView"},
React.createElement("p", {className: "note"}
),
React.createElement(FramedExample, {dashed: true,
- height: 272,
+ height: 288,
summary: "Default (useable demo)",
- width: 300},
+ width: 348},
React.createElement("div", {className: "fx-embedded"},
React.createElement(FeedbackView, {mozLoop: {},
onAfterFeedbackReceived: function() {}})
)
)
),
React.createElement(Section, {name: "AlertMessages"},
React.createElement(FramedExample, {dashed: true,
- height: 272,
+ height: 288,
summary: "Various alerts",
- width: 300},
+ width: 348},
React.createElement("div", null,
React.createElement("div", {className: "alert alert-warning"},
React.createElement("button", {className: "close"}),
React.createElement("p", {className: "message"},
"The person you were calling has ended the conversation."
)
),
React.createElement("br", null),
@@ -1369,87 +1363,87 @@
React.createElement(UnsupportedDeviceView, {platform: "ios"})
)
)
),
React.createElement(Section, {name: "RoomFailureView"},
React.createElement(FramedExample, {
dashed: true,
- height: 254,
+ height: 288,
summary: "Desktop Room Failure View",
- width: 298},
+ width: 348},
React.createElement("div", {className: "fx-embedded"},
React.createElement(RoomFailureView, {
dispatcher: dispatcher,
failureReason: FAILURE_DETAILS.UNKNOWN,
mozLoop: navigator.mozLoop})
)
)
),
React.createElement(Section, {name: "DesktopRoomConversationView"},
React.createElement(FramedExample, {height: 398,
onContentsRendered: invitationRoomStore.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)",
- width: 298},
+ width: 348},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
onCallTerminated: function(){},
roomState: ROOM_STATES.INIT,
roomStore: invitationRoomStore})
)
),
- React.createElement(FramedExample, {height: 278.6,
+ React.createElement(FramedExample, {height: 288,
onContentsRendered: invitationRoomStore.activeRoomStore.forcedUpdate,
summary: "Desktop room Edit Context w/Error",
- width: 298},
+ width: 348},
React.createElement("div", {className: "fx-embedded room-invitation-overlay"},
React.createElement(DesktopRoomEditContextView, {
dispatcher: dispatcher,
error: {},
mozLoop: navigator.mozLoop,
onClose: function(){},
roomData: {},
savingContext: false,
show: true}
)
)
),
React.createElement(FramedExample, {dashed: true,
- height: 394,
+ height: 398,
onContentsRendered: desktopRoomStoreLoading.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation (loading)",
- width: 298},
+ width: 348},
/* Hide scrollbars here. Rotating loading div overflows and causes
scrollbars to appear */
React.createElement("div", {className: "fx-embedded overflow-hidden"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
onCallTerminated: function(){},
remotePosterUrl: "sample-img/video-screen-remote.png",
roomState: ROOM_STATES.HAS_PARTICIPANTS,
roomStore: desktopRoomStoreLoading})
)
),
React.createElement(FramedExample, {dashed: true,
- height: 394,
+ height: 398,
onContentsRendered: roomStore.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation",
- width: 298},
+ width: 348},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
onCallTerminated: function(){},
remotePosterUrl: "sample-img/video-screen-remote.png",
@@ -1490,36 +1484,36 @@
onCallTerminated: function(){},
remotePosterUrl: "sample-img/video-screen-remote.png",
roomState: ROOM_STATES.HAS_PARTICIPANTS,
roomStore: desktopRoomStoreLarge})
)
),
React.createElement(FramedExample, {dashed: true,
- height: 394,
+ height: 398,
onContentsRendered: desktopLocalFaceMuteRoomStore.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation local face-mute",
- width: 298},
+ width: 348},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
onCallTerminated: function(){},
remotePosterUrl: "sample-img/video-screen-remote.png",
roomStore: desktopLocalFaceMuteRoomStore})
)
),
React.createElement(FramedExample, {dashed: true,
- height: 394,
+ height: 398,
onContentsRendered: desktopRemoteFaceMuteRoomStore.activeRoomStore.forcedUpdate,
summary: "Desktop room conversation remote face-mute",
- width: 298},
+ width: 348},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
chatWindowDetached: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
onCallTerminated: function(){},
remotePosterUrl: "sample-img/video-screen-remote.png",
--- a/browser/components/loop/ui/ui-showcase.jsx
+++ b/browser/components/loop/ui/ui-showcase.jsx
@@ -761,103 +761,97 @@
height={410}
summary="First time experience view"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={firstTimeUseMozLoop}
notifications={notifications}
- roomStore={roomStore}
- selectedTab="rooms" />
+ roomStore={roomStore} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Re-sign-in view"
width={332}>
<div className="panel">
<SignInRequestView mozLoop={mockMozLoopLoggedIn} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
- summary="Room list tab"
+ summary="Room list"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopLoggedIn}
notifications={notifications}
- roomStore={roomStore}
- selectedTab="rooms" />
+ roomStore={roomStore} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
- summary="Room list tab (No Context)"
+ summary="Room list (No Context)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopLoggedInNoContext}
notifications={notifications}
- roomStore={roomStore}
- selectedTab="rooms" />
+ roomStore={roomStore} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
- summary="Room list tab (no rooms)"
+ summary="Room list (no rooms)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopNoRooms}
notifications={notifications}
- roomStore={roomStoreNoRooms}
- selectedTab="rooms" />
+ roomStore={roomStoreNoRooms} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
- summary="Room list tab (no rooms and no context)"
+ summary="Room list (no rooms and no context)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopNoRoomsNoContext}
notifications={notifications}
- roomStore={roomStoreNoRooms}
- selectedTab="rooms" />
+ roomStore={roomStoreNoRooms} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
- summary="Room list tab (loading view)"
+ summary="Room list (loading view)"
width={330}>
<div className="panel">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopNoRoomsNoContext}
notifications={notifications}
- roomStore={roomStoreNoRoomsPending}
- selectedTab="rooms" />
+ roomStore={roomStoreNoRoomsPending} />
</div>
</FramedExample>
<FramedExample cssClass="fx-embedded-panel"
dashed={true}
height={410}
summary="Contact list tab"
width={330}>
@@ -1210,20 +1204,20 @@
mozLoop={navigator.mozLoop}
outgoing={true} />
</div>
</FramedExample>
</Section>
<Section name="OngoingConversationView">
<FramedExample dashed={true}
- height={394}
+ height={398}
onContentsRendered={conversationStores[0].forcedUpdate}
summary="Desktop ongoing conversation window"
- width={298}>
+ width={348}>
<div className="fx-embedded">
<OngoingConversationView
audio={{ enabled: true, visible: true }}
chatWindowDetached={false}
conversationStore={conversationStores[0]}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mediaConnected={true}
@@ -1266,39 +1260,39 @@
mediaConnected={true}
remotePosterUrl="sample-img/video-screen-remote.png"
remoteVideoEnabled={true}
video={{ enabled: true, visible: true }} />
</div>
</FramedExample>
<FramedExample dashed={true}
- height={394}
+ height={398}
onContentsRendered={conversationStores[3].forcedUpdate}
summary="Desktop ongoing conversation window - local face mute"
- width={298}>
+ width={348}>
<div className="fx-embedded">
<OngoingConversationView
audio={{ enabled: true, visible: true }}
chatWindowDetached={false}
conversationStore={conversationStores[3]}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mediaConnected={true}
remotePosterUrl="sample-img/video-screen-remote.png"
remoteVideoEnabled={true}
video={{ enabled: false, visible: true }} />
</div>
</FramedExample>
<FramedExample dashed={true}
- height={394}
+ height={398}
onContentsRendered={conversationStores[4].forcedUpdate}
summary="Desktop ongoing conversation window - remote face mute"
- width={298} >
+ width={348} >
<div className="fx-embedded">
<OngoingConversationView
audio={{ enabled: true, visible: true }}
chatWindowDetached={false}
conversationStore={conversationStores[4]}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mediaConnected={true}
@@ -1309,31 +1303,31 @@
</FramedExample>
</Section>
<Section name="FeedbackView">
<p className="note">
</p>
<FramedExample dashed={true}
- height={272}
+ height={288}
summary="Default (useable demo)"
- width={300}>
+ width={348}>
<div className="fx-embedded">
<FeedbackView mozLoop={{}}
onAfterFeedbackReceived={function() {}} />
</div>
</FramedExample>
</Section>
<Section name="AlertMessages">
<FramedExample dashed={true}
- height={272}
+ height={288}
summary="Various alerts"
- width={300}>
+ width={348}>
<div>
<div className="alert alert-warning">
<button className="close"></button>
<p className="message">
The person you were calling has ended the conversation.
</p>
</div>
<br />
@@ -1369,87 +1363,87 @@
<UnsupportedDeviceView platform="ios"/>
</div>
</FramedExample>
</Section>
<Section name="RoomFailureView">
<FramedExample
dashed={true}
- height={254}
+ height={288}
summary="Desktop Room Failure View"
- width={298}>
+ width={348}>
<div className="fx-embedded">
<RoomFailureView
dispatcher={dispatcher}
failureReason={FAILURE_DETAILS.UNKNOWN}
mozLoop={navigator.mozLoop} />
</div>
</FramedExample>
</Section>
<Section name="DesktopRoomConversationView">
<FramedExample height={398}
onContentsRendered={invitationRoomStore.activeRoomStore.forcedUpdate}
summary="Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)"
- width={298}>
+ width={348}>
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
onCallTerminated={function(){}}
roomState={ROOM_STATES.INIT}
roomStore={invitationRoomStore} />
</div>
</FramedExample>
- <FramedExample height={278.6}
+ <FramedExample height={288}
onContentsRendered={invitationRoomStore.activeRoomStore.forcedUpdate}
summary="Desktop room Edit Context w/Error"
- width={298}>
+ width={348}>
<div className="fx-embedded room-invitation-overlay">
<DesktopRoomEditContextView
dispatcher={dispatcher}
error={{}}
mozLoop={navigator.mozLoop}
onClose={function(){}}
roomData={{}}
savingContext={false}
show={true}
/>
</div>
</FramedExample>
<FramedExample dashed={true}
- height={394}
+ height={398}
onContentsRendered={desktopRoomStoreLoading.activeRoomStore.forcedUpdate}
summary="Desktop room conversation (loading)"
- width={298}>
+ width={348}>
{/* Hide scrollbars here. Rotating loading div overflows and causes
scrollbars to appear */}
<div className="fx-embedded overflow-hidden">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
onCallTerminated={function(){}}
remotePosterUrl="sample-img/video-screen-remote.png"
roomState={ROOM_STATES.HAS_PARTICIPANTS}
roomStore={desktopRoomStoreLoading} />
</div>
</FramedExample>
<FramedExample dashed={true}
- height={394}
+ height={398}
onContentsRendered={roomStore.activeRoomStore.forcedUpdate}
summary="Desktop room conversation"
- width={298}>
+ width={348}>
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
onCallTerminated={function(){}}
remotePosterUrl="sample-img/video-screen-remote.png"
@@ -1490,36 +1484,36 @@
onCallTerminated={function(){}}
remotePosterUrl="sample-img/video-screen-remote.png"
roomState={ROOM_STATES.HAS_PARTICIPANTS}
roomStore={desktopRoomStoreLarge} />
</div>
</FramedExample>
<FramedExample dashed={true}
- height={394}
+ height={398}
onContentsRendered={desktopLocalFaceMuteRoomStore.activeRoomStore.forcedUpdate}
summary="Desktop room conversation local face-mute"
- width={298}>
+ width={348}>
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
onCallTerminated={function(){}}
remotePosterUrl="sample-img/video-screen-remote.png"
roomStore={desktopLocalFaceMuteRoomStore} />
</div>
</FramedExample>
<FramedExample dashed={true}
- height={394}
+ height={398}
onContentsRendered={desktopRemoteFaceMuteRoomStore.activeRoomStore.forcedUpdate}
summary="Desktop room conversation remote face-mute"
- width={298} >
+ width={348} >
<div className="fx-embedded">
<DesktopRoomConversationView
chatWindowDetached={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
onCallTerminated={function(){}}
remotePosterUrl="sample-img/video-screen-remote.png"
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -156,31 +156,25 @@ this.UITour = {
allowAdd: true,
query: "#loop-button",
widgetName: "loop-button",
}],
["loop-newRoom", {
infoPanelPosition: "leftcenter topright",
query: (aDocument) => {
let loopUI = aDocument.defaultView.LoopUI;
- if (loopUI.selectedTab != "rooms") {
- return null;
- }
// Use the parentElement full-width container of the button so our arrow
// doesn't overlap the panel contents much.
return loopUI.browser.contentDocument.querySelector(".new-room-button").parentElement;
},
}],
["loop-roomList", {
infoPanelPosition: "leftcenter topright",
query: (aDocument) => {
let loopUI = aDocument.defaultView.LoopUI;
- if (loopUI.selectedTab != "rooms") {
- return null;
- }
return loopUI.browser.contentDocument.querySelector(".room-list");
},
}],
["loop-selectedRoomButtons", {
infoPanelOffsetY: -20,
infoPanelPosition: "start_after",
query: (aDocument) => {
let chatbox = aDocument.querySelector("chatbox[src^='about\:loopconversation'][selected]");
--- a/browser/components/uitour/test/browser_UITour_loop.js
+++ b/browser/components/uitour/test/browser_UITour_loop.js
@@ -179,65 +179,16 @@ var tests = [
yield Promise.all(hiddenPromises);
isnot(infoPanel.state, "open", "Info panel should have automatically hid");
isnot(highlightPanel.state, "open", "Highlight panel should have automatically hid");
done();
}), "Info panel should be anchored to the new room button");
});
});
},
- taskify(function* test_panelTabChangeNotifications() {
- // First make sure the Loop panel looks like we're logged in to have more than
- // just one tab to switch to.
- const fxASampleToken = {
- token_type: "bearer",
- access_token: "1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1752",
- scope: "profile"
- };
- const fxASampleProfile = {
- email: "test@example.com",
- uid: "abcd1234"
- };
- MozLoopServiceInternal.fxAOAuthTokenData = fxASampleToken;
- MozLoopServiceInternal.fxAOAuthProfile = fxASampleProfile;
- Services.prefs.setCharPref("loop.key.fxa", "fake");
- yield MozLoopServiceInternal.notifyStatusChanged("login");
-
- // Show the Loop menu.
- yield showMenuPromise("loop");
-
- // Listen for and test the notifications that will arrive from now on.
- let tabChangePromise = new Promise(resolve => {
- gContentAPI.observe((event, params) => {
- is(event, "Loop:PanelTabChanged", "Check Loop:PanelTabChanged notification");
- is(params, "contacts", "Check the tab name param");
-
- gContentAPI.observe((event, params) => {
- is(event, "Loop:PanelTabChanged", "Check Loop:PanelTabChanged notification");
- is(params, "rooms", "Check the tab name param");
-
- gContentAPI.observe((event, params) => {
- ok(false, "No more notifications should have arrived");
- });
- resolve();
- });
- });
- });
-
- // Switch to the contacts tab.
- yield window.LoopUI.openCallPanel(null, "contacts");
-
- // Logout. The panel tab will switch back to 'rooms'.
- MozLoopServiceInternal.fxAOAuthTokenData =
- MozLoopServiceInternal.fxAOAuthProfile = null;
- Services.prefs.clearUserPref("loop.key.fxa");
- yield MozLoopServiceInternal.notifyStatusChanged();
-
- yield tabChangePromise;
- }),
runOffline(function test_notifyLoopChatWindowOpenedClosed(done) {
gContentAPI.observe((event, params) => {
is(event, "Loop:ChatWindowOpened", "Check Loop:ChatWindowOpened notification");
gContentAPI.observe((event, params) => {
is(event, "Loop:ChatWindowShown", "Check Loop:ChatWindowShown notification");
gContentAPI.observe((event, params) => {
is(event, "Loop:ChatWindowClosed", "Check Loop:ChatWindowClosed notification");
gContentAPI.observe((event, params) => {
--- a/browser/locales/en-US/chrome/browser/loop/loop.properties
+++ b/browser/locales/en-US/chrome/browser/loop/loop.properties
@@ -4,19 +4,16 @@
# Panel Strings
## LOCALIZATION NOTE(clientShortname2): This should not be localized and
## should remain "Firefox Hello" for all locales.
clientShortname2=Firefox Hello
clientSuperShortname=Hello
-rooms_tab_button=Conversations
-contacts_tab_button=Contacts
-
## LOCALIZATION_NOTE(sign_in_again_title_line_one, sign_in_again_title_line_two2):
## These are displayed together at the top of the panel when a user is needed to
## sign-in again. The emphesis is on the first line to get the user to sign-in again,
## and this is displayed in slightly larger font. Please arrange as necessary for
## your locale.
## {{clientShortname2}} will be replaced by the brand name for either string.
sign_in_again_title_line_one=Please sign in again
sign_in_again_title_line_two2=to continue using {{clientShortname2}}
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -888,17 +888,17 @@ toolbarbutton[constrain-size="true"][cui
-moz-margin-start: 0;
}
.urlbar-history-dropmarker {
-moz-appearance: toolbarbutton-dropdown;
transition: opacity 0.15s ease;
}
-#urlbar:not(:hover) > .urlbar-textbox-container > .urlbar-history-dropmarker {
+#navigator-toolbox:not(:hover) .urlbar-history-dropmarker {
opacity: 0;
}
#urlbar-container {
-moz-box-align: center;
}
@conditionalForwardWithUrlbar@ > #urlbar {
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -1691,17 +1691,17 @@ toolbarbutton[constrain-size="true"][cui
.urlbar-history-dropmarker {
padding: 0 3px;
list-style-image: var(--urlbar-dropmarker-url);
-moz-image-region: var(--urlbar-dropmarker-region);
transition: opacity 0.15s ease;
}
-#urlbar:not(:hover) > .urlbar-textbox-container > .urlbar-history-dropmarker {
+#navigator-toolbox:not(:hover) .urlbar-history-dropmarker {
opacity: 0;
}
.urlbar-history-dropmarker[open="true"],
.urlbar-history-dropmarker:hover:active {
-moz-image-region: var(--urlbar-dropmarker-active-region);
}
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -44,16 +44,28 @@
--urlbar-dropmarker-hover-2x-region: rect(0, 44px, 28px, 22px);
--urlbar-dropmarker-active-2x-region: rect(0, 66px, 28px, 44px);
--panel-separator-color: ThreeDLightShadow;
--urlbar-separator-color: hsla(0,0%,16%,.2);
}
+#nav-bar[brighttext] {
+ --toolbarbutton-hover-background: rgba(255,255,255,.25);
+ --toolbarbutton-hover-bordercolor: rgba(255,255,255,.5);
+ --toolbarbutton-hover-boxshadow: none;
+
+ --toolbarbutton-active-background: rgba(255,255,255,.4);
+ --toolbarbutton-active-bordercolor: rgba(255,255,255,.7);
+ --toolbarbutton-active-boxshadow: 0 0 0 1px rgba(255,255,255,.4) inset;
+
+ --toolbarbutton-checkedhover-backgroundcolor: rgba(255,255,255,.3);
+}
+
#menubar-items {
-moz-box-orient: vertical; /* for flex hack */
}
#main-menubar {
-moz-box-flex: 1; /* make menu items expand to fill toolbar height */
}
@@ -1113,16 +1125,20 @@ toolbarbutton[constrain-size="true"][cui
--urlbar-border-color: ThreeDShadow;
--urlbar-border-color-hover: var(--urlbar-border-color);
}
#nav-bar:-moz-lwtheme {
--urlbar-border-color: rgba(0,0,0,.32);
}
+#nav-bar:-moz-lwtheme-brighttext {
+ --urlbar-border-color: var(--toolbarbutton-hover-bordercolor);
+}
+
@media (-moz-windows-default-theme) {
@media (-moz-os-version: windows-vista),
(-moz-os-version: windows-win7),
(-moz-os-version: windows-win8) {
#nav-bar:not(:-moz-lwtheme) {
--urlbar-border-color: hsla(210,54%,20%,.25) hsla(210,54%,20%,.27) hsla(210,54%,20%,.3);
--urlbar-border-color-hover: hsla(210,54%,20%,.35) hsla(210,54%,20%,.37) hsla(210,54%,20%,.4);
}
@@ -1141,16 +1157,21 @@ toolbarbutton[constrain-size="true"][cui
-moz-appearance: none;
margin: 0 3px;
padding: 0;
background-clip: padding-box;
border: 1px solid;
border-color: var(--urlbar-border-color);
}
+#urlbar:-moz-lwtheme-brighttext,
+.searchbar-textbox:-moz-lwtheme-brighttext {
+ background-clip: border-box;
+}
+
#urlbar:hover,
.searchbar-textbox:hover {
border-color: var(--urlbar-border-color-hover);
}
/* overlap the urlbar's border */
#PopupAutoCompleteRichResult {
margin-top: -1px;
@@ -1371,17 +1392,17 @@ html|*.urlbar-input:-moz-lwtheme::-moz-p
background-color: transparent;
border: none;
width: auto;
list-style-image: var(--urlbar-dropmarker-url);
-moz-image-region: var(--urlbar-dropmarker-region);
transition: opacity 0.15s ease;
}
-#urlbar:not(:hover) > .urlbar-textbox-container > .urlbar-history-dropmarker {
+#navigator-toolbox:not(:hover) .urlbar-history-dropmarker {
opacity: 0;
}
.urlbar-history-dropmarker:hover {
-moz-image-region: var(--urlbar-dropmarker-hover-region);
}
.urlbar-history-dropmarker:hover:active,
--- a/devtools/client/debugger/debugger-controller.js
+++ b/devtools/client/debugger/debugger-controller.js
@@ -37,16 +37,17 @@ const EVENTS = {
FETCHED_VARIABLES: "Debugger:FetchedVariables",
FETCHED_PROPERTIES: "Debugger:FetchedProperties",
FETCHED_BUBBLE_PROPERTIES: "Debugger:FetchedBubbleProperties",
FETCHED_WATCH_EXPRESSIONS: "Debugger:FetchedWatchExpressions",
// When a breakpoint has been added or removed on the debugger server.
BREAKPOINT_ADDED: "Debugger:BreakpointAdded",
BREAKPOINT_REMOVED: "Debugger:BreakpointRemoved",
+ BREAKPOINT_CLICKED: "Debugger:BreakpointClicked",
// When a breakpoint has been shown or hidden in the source editor
// or the pane.
BREAKPOINT_SHOWN_IN_EDITOR: "Debugger:BreakpointShownInEditor",
BREAKPOINT_SHOWN_IN_PANE: "Debugger:BreakpointShownInPane",
BREAKPOINT_HIDDEN_IN_EDITOR: "Debugger:BreakpointHiddenInEditor",
BREAKPOINT_HIDDEN_IN_PANE: "Debugger:BreakpointHiddenInPane",
--- a/devtools/client/debugger/test/mochitest/browser_dbg_conditional-breakpoints-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_conditional-breakpoints-02.js
@@ -190,13 +190,15 @@ function test() {
"The editor caret position is not properly set.");
}
function setCaretPosition(aLine) {
gEditor.setCursor({ line: aLine - 1, ch: 0 });
}
function clickOnBreakpoint(aIndex) {
+ let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_CLICKED);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
gDebugger);
+ return finished;
}
}
--- a/devtools/client/debugger/test/mochitest/browser_dbg_server-conditional-bp-02.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_server-conditional-bp-02.js
@@ -179,13 +179,15 @@ function test() {
"The editor caret position is not properly set.");
}
function setCaretPosition(aLine) {
gEditor.setCursor({ line: aLine - 1, ch: 0 });
}
function clickOnBreakpoint(aIndex) {
+ let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_CLICKED);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
gDebugger);
+ return finished;
}
}
--- a/devtools/client/debugger/views/sources-view.js
+++ b/devtools/client/debugger/views/sources-view.js
@@ -461,19 +461,19 @@ SourcesView.prototype = Heritage.extend(
// Update the editor location if necessary.
if (!aOptions.noEditorUpdate) {
this.DebuggerView.setEditorLocation(aLocation.actor, aLocation.line, { noDebug: true });
}
// If the breakpoint requires a new conditional expression, display
// the panel to input the corresponding expression.
if (aOptions.openPopup) {
- this._openConditionalPopup();
+ return this._openConditionalPopup();
} else {
- this._hideConditionalPopup();
+ return this._hideConditionalPopup();
}
},
/**
* Highlight the breakpoint on the current currently focused line/column
* if it exists.
*/
highlightBreakpointAtCursor: function() {
@@ -712,23 +712,23 @@ SourcesView.prototype = Heritage.extend(
*/
_openConditionalPopup: function() {
let breakpointItem = this._selectedBreakpointItem;
let attachment = breakpointItem.attachment;
// Check if this is an enabled conditional breakpoint, and if so,
// retrieve the current conditional epression.
let breakpointPromise = this.Breakpoints._getAdded(attachment);
if (breakpointPromise) {
- breakpointPromise.then(aBreakpointClient => {
+ return breakpointPromise.then(aBreakpointClient => {
let isConditionalBreakpoint = aBreakpointClient.hasCondition();
let condition = aBreakpointClient.getCondition();
- doOpen.call(this, isConditionalBreakpoint ? condition : "")
+ return doOpen.call(this, isConditionalBreakpoint ? condition : "")
});
} else {
- doOpen.call(this, "")
+ return doOpen.call(this, "")
}
function doOpen(aConditionalExpression) {
// Update the conditional expression textbox. If no expression was
// previously set, revert to using an empty string by default.
this._cbTextbox.value = aConditionalExpression;
// Show the conditional expression panel. The popup arrow should be pointing
@@ -1035,28 +1035,34 @@ SourcesView.prototype = Heritage.extend(
* The click listener for a breakpoint container.
*/
_onBreakpointClick: function(e) {
let sourceItem = this.getItemForElement(e.target);
let breakpointItem = this.getItemForElement.call(sourceItem, e.target);
let attachment = breakpointItem.attachment;
// Check if this is an enabled conditional breakpoint.
- let breakpointPromise = this.Breakpoints._getAdded(attachment);
- if (breakpointPromise) {
- breakpointPromise.then(aBreakpointClient => {
- doHighlight.call(this, aBreakpointClient.hasCondition());
+ let promise = this.Breakpoints._getAdded(attachment);
+ if (promise) {
+ promise = promise.then(aBreakpointClient => {
+ return doHighlight.call(this, aBreakpointClient.hasCondition());
});
} else {
- doHighlight.call(this, false);
+ promise = Promise.resolve().then(() => {
+ return doHighlight.call(this, false)
+ });
}
+ promise.then(() => {
+ window.emit(EVENTS.BREAKPOINT_CLICKED);
+ });
+
function doHighlight(aConditionalBreakpointFlag) {
// Highlight the breakpoint in this pane and in the editor.
- this.highlightBreakpoint(attachment, {
+ return this.highlightBreakpoint(attachment, {
// Don't show the conditional expression popup if this is not a
// conditional breakpoint, or the right mouse button was pressed (to
// avoid clashing the popup with the context menu).
openPopup: aConditionalBreakpointFlag && e.button == 0
});
}
},
--- a/devtools/client/framework/gDevTools.jsm
+++ b/devtools/client/framework/gDevTools.jsm
@@ -546,24 +546,16 @@ var gDevToolsBrowser = {
// If a toolbox exists, using toggle from the Main window :
// - should close a docked toolbox
// - should focus a windowed toolbox
let isDocked = toolbox && toolbox.hostType != Toolbox.HostType.WINDOW;
isDocked ? toolbox.destroy() : gDevTools.showToolbox(target);
},
- toggleBrowserToolboxCommand: function(gBrowser) {
- let target = TargetFactory.forWindow(gBrowser.ownerDocument.defaultView);
- let toolbox = gDevTools.getToolbox(target);
-
- toolbox ? toolbox.destroy()
- : gDevTools.showToolbox(target, "inspector", Toolbox.HostType.WINDOW);
- },
-
/**
* This function ensures the right commands are enabled in a window,
* depending on their relevant prefs. It gets run when a window is registered,
* or when any of the devtools prefs change.
*/
updateCommandAvailability: function(win) {
let doc = win.document;
--- a/devtools/client/framework/target.js
+++ b/devtools/client/framework/target.js
@@ -1,37 +1,38 @@
/* 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/. */
"use strict";
-const {Cc, Ci, Cu} = require("chrome");
+const { Ci, Cu } = require("chrome");
const promise = require("promise");
const EventEmitter = require("devtools/shared/event-emitter");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
-loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/main", true);
+loader.lazyRequireGetter(this, "DebuggerClient",
+ "devtools/shared/client/main", true);
const targets = new WeakMap();
const promiseTargets = new WeakMap();
/**
* Functions for creating Targets
*/
exports.TargetFactory = {
/**
* Construct a Target
* @param {XULTab} tab
* The tab to use in creating a new target.
*
* @return A target object
*/
- forTab: function TF_forTab(tab) {
+ forTab: function(tab) {
let target = targets.get(tab);
if (target == null) {
target = new TabTarget(tab);
targets.set(tab, target);
}
return target;
},
@@ -43,129 +44,76 @@ exports.TargetFactory = {
* form: the remote protocol form of a tab,
* client: a DebuggerClient instance
* (caller owns this and is responsible for closing),
* chrome: true if the remote target is the whole process
* }
*
* @return A promise of a target object
*/
- forRemoteTab: function TF_forRemoteTab(options) {
+ forRemoteTab: function(options) {
let targetPromise = promiseTargets.get(options);
if (targetPromise == null) {
let target = new TabTarget(options);
targetPromise = target.makeRemote().then(() => target);
promiseTargets.set(options, targetPromise);
}
return targetPromise;
},
- forWorker: function TF_forWorker(workerClient) {
+ forWorker: function(workerClient) {
let target = targets.get(workerClient);
if (target == null) {
target = new WorkerTarget(workerClient);
targets.set(workerClient, target);
}
return target;
},
/**
* Creating a target for a tab that is being closed is a problem because it
* allows a leak as a result of coming after the close event which normally
* clears things up. This function allows us to ask if there is a known
* target for a tab without creating a target
* @return true/false
*/
- isKnownTab: function TF_isKnownTab(tab) {
+ isKnownTab: function(tab) {
return targets.has(tab);
},
-
- /**
- * Construct a Target
- * @param {nsIDOMWindow} window
- * The chromeWindow to use in creating a new target
- * @return A target object
- */
- forWindow: function TF_forWindow(window) {
- let target = targets.get(window);
- if (target == null) {
- target = new WindowTarget(window);
- targets.set(window, target);
- }
- return target;
- },
-
- /**
- * Get all of the targets known to the local browser instance
- * @return An array of target objects
- */
- allTargets: function TF_allTargets() {
- let windows = [];
- let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Ci.nsIWindowMediator);
- let en = wm.getXULWindowEnumerator(null);
- while (en.hasMoreElements()) {
- windows.push(en.getNext());
- }
-
- return windows.map(function(window) {
- return TargetFactory.forWindow(window);
- });
- },
};
/**
- * The 'version' property allows the developer tools equivalent of browser
- * detection. Browser detection is evil, however while we don't know what we
- * will need to detect in the future, it is an easy way to postpone work.
- * We should be looking to use the support features added in bug 1069673
- * in place of version where possible.
- */
-function getVersion() {
- // FIXME: return something better
- return 20;
-}
-
-/**
* A Target represents something that we can debug. Targets are generally
* read-only. Any changes that you wish to make to a target should be done via
* a Tool that attaches to the target. i.e. a Target is just a pointer saying
* "the thing to debug is over there".
*
* Providing a generalized abstraction of a web-page or web-browser (available
* either locally or remotely) is beyond the scope of this class (and maybe
* also beyond the scope of this universe) However Target does attempt to
* abstract some common events and read-only properties common to many Tools.
*
* Supported read-only properties:
* - name, isRemote, url
*
* Target extends EventEmitter and provides support for the following events:
* - close: The target window has been closed. All tools attached to this
- * target should close. This event is not currently cancelable.
+ * target should close. This event is not currently cancelable.
* - navigate: The target window has navigated to a different URL
*
* Optional events:
* - will-navigate: The target window will navigate to a different URL
- * - hidden: The target is not visible anymore (for TargetTab, another tab is selected)
+ * - hidden: The target is not visible anymore (for TargetTab, another tab is
+ * selected)
* - visible: The target is visible (for TargetTab, tab is selected)
*
* Comparing Targets: 2 instances of a Target object can point at the same
* thing, so t1 !== t2 and t1 != t2 even when they represent the same object.
* To compare to targets use 't1.equals(t2)'.
*/
-function Target() {
- throw new Error("Use TargetFactory.newXXX or Target.getXXX to create a Target in place of 'new Target()'");
-}
-
-Object.defineProperty(Target.prototype, "version", {
- get: getVersion,
- enumerable: true
-});
-
/**
* A TabTarget represents a page living in a browser tab. Generally these will
* be web pages served over http(s), but they don't have to be.
*/
function TabTarget(tab) {
EventEmitter.decorate(this);
this.destroy = this.destroy.bind(this);
@@ -178,32 +126,36 @@ function TabTarget(tab) {
if (tab && !["client", "form", "chrome"].every(tab.hasOwnProperty, tab)) {
this._tab = tab;
this._setupListeners();
} else {
this._form = tab.form;
this._client = tab.client;
this._chrome = tab.chrome;
}
- // Default isTabActor to true if not explicitely specified
- this._isTabActor = typeof(tab.isTabActor) == "boolean" ? tab.isTabActor : true;
+ // Default isTabActor to true if not explicitly specified
+ if (typeof tab.isTabActor == "boolean") {
+ this._isTabActor = tab.isTabActor;
+ } else {
+ this._isTabActor = true;
+ }
}
TabTarget.prototype = {
_webProgressListener: null,
/**
- * Returns a promise for the protocol description from the root actor.
- * Used internally with `target.actorHasMethod`. Takes advantage of
- * caching if definition was fetched previously with the corresponding
- * actor information. Actors are lazily loaded, so not only must the tool using
- * a specific actor be in use, the actors are only registered after invoking
- * a method (for performance reasons, added in bug 988237), so to use these actor
- * detection methods, one must already be communicating with a specific actor of
- * that type.
+ * Returns a promise for the protocol description from the root actor. Used
+ * internally with `target.actorHasMethod`. Takes advantage of caching if
+ * definition was fetched previously with the corresponding actor information.
+ * Actors are lazily loaded, so not only must the tool using a specific actor
+ * be in use, the actors are only registered after invoking a method (for
+ * performance reasons, added in bug 988237), so to use these actor detection
+ * methods, one must already be communicating with a specific actor of that
+ * type.
*
* Must be a remote target.
*
* @return {Promise}
* {
* "category": "actor",
* "typeName": "longstractor",
* "methods": [{
@@ -223,24 +175,26 @@ TabTarget.prototype = {
* "substring": {
* "_retval": "primitive"
* }
* }
* }],
* "events": {}
* }
*/
- getActorDescription: function (actorName) {
+ getActorDescription: function(actorName) {
if (!this.client) {
- throw new Error("TabTarget#getActorDescription() can only be called on remote tabs.");
+ throw new Error("TabTarget#getActorDescription() can only be called on " +
+ "remote tabs.");
}
let deferred = promise.defer();
- if (this._protocolDescription && this._protocolDescription.types[actorName]) {
+ if (this._protocolDescription &&
+ this._protocolDescription.types[actorName]) {
deferred.resolve(this._protocolDescription.types[actorName]);
} else {
this.client.mainRoot.protocolDescription(description => {
this._protocolDescription = description;
deferred.resolve(description.types[actorName]);
});
}
@@ -249,19 +203,20 @@ TabTarget.prototype = {
/**
* Returns a boolean indicating whether or not the specific actor
* type exists. Must be a remote target.
*
* @param {String} actorName
* @return {Boolean}
*/
- hasActor: function (actorName) {
+ hasActor: function(actorName) {
if (!this.client) {
- throw new Error("TabTarget#hasActor() can only be called on remote tabs.");
+ throw new Error("TabTarget#hasActor() can only be called on remote " +
+ "tabs.");
}
if (this.form) {
return !!this.form[actorName + "Actor"];
}
return false;
},
/**
@@ -270,50 +225,50 @@ TabTarget.prototype = {
* the restrictions in the `getActorDescription` comments),
* so this is for use inside of tool. Returns a promise that
* resolves to a boolean. Must be a remote target.
*
* @param {String} actorName
* @param {String} methodName
* @return {Promise}
*/
- actorHasMethod: function (actorName, methodName) {
+ actorHasMethod: function(actorName, methodName) {
if (!this.client) {
- throw new Error("TabTarget#actorHasMethod() can only be called on remote tabs.");
+ throw new Error("TabTarget#actorHasMethod() can only be called on " +
+ "remote tabs.");
}
return this.getActorDescription(actorName).then(desc => {
if (desc && desc.methods) {
return !!desc.methods.find(method => method.name === methodName);
}
return false;
});
},
/**
* Returns a trait from the root actor.
*
* @param {String} traitName
* @return {Mixed}
*/
- getTrait: function (traitName) {
+ getTrait: function(traitName) {
if (!this.client) {
- throw new Error("TabTarget#getTrait() can only be called on remote tabs.");
+ throw new Error("TabTarget#getTrait() can only be called on remote " +
+ "tabs.");
}
- // If the targeted actor exposes traits and has a defined value for this traits,
- // override the root actor traits
+ // If the targeted actor exposes traits and has a defined value for this
+ // traits, override the root actor traits
if (this.form.traits && traitName in this.form.traits) {
return this.form.traits[traitName];
}
return this.client.traits[traitName];
},
- get version() { return getVersion(); },
-
get tab() {
return this._tab;
},
get form() {
return this._form;
},
@@ -321,17 +276,17 @@ TabTarget.prototype = {
// is cached.
get root() {
if (!this._root) {
this._root = this._getRoot();
}
return this._root;
},
- _getRoot: function () {
+ _getRoot: function() {
return new Promise((resolve, reject) => {
this.client.listTabs(response => {
if (response.error) {
reject(new Error(response.error + ": " + response.message));
return;
}
resolve(response);
@@ -359,35 +314,35 @@ TabTarget.prototype = {
},
get window() {
// XXX - this is a footgun for e10s - there .contentWindow will be null,
// and even though .contentWindowAsCPOW *might* work, it will not work
// in all contexts. Consumers of .window need to be refactored to not
// rely on this.
if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
- Cu.reportError("The .window getter on devtools' |target| object isn't e10s friendly!\n"
- + Error().stack);
+ Cu.reportError("The .window getter on devtools' |target| object isn't " +
+ "e10s friendly!\n" + Error().stack);
}
// Be extra careful here, since this may be called by HS_getHudByWindow
// during shutdown.
if (this._tab && this._tab.linkedBrowser) {
return this._tab.linkedBrowser.contentWindow;
}
return null;
},
get name() {
if (this._tab && this._tab.linkedBrowser.contentDocument) {
- return this._tab.linkedBrowser.contentDocument.title
- } else if (this.isAddon) {
+ return this._tab.linkedBrowser.contentDocument.title;
+ }
+ if (this.isAddon) {
return this._form.name;
- } else {
- return this._form.title;
}
+ return this._form.title;
},
get url() {
return this._tab ? this._tab.linkedBrowser.currentURI.spec :
this._form.url;
},
get isRemote() {
@@ -411,17 +366,17 @@ TabTarget.prototype = {
return !!this._isThreadPaused;
},
/**
* Adds remote protocol capabilities to the target, so that it can be used
* for tools that support the Remote Debugging Protocol even for local
* connections.
*/
- makeRemote: function TabTarget_makeRemote() {
+ makeRemote: function() {
if (this._remote) {
return this._remote.promise;
}
this._remote = promise.defer();
if (this.isLocalTab) {
// Since a remote protocol connection will be made, let's start the
@@ -434,89 +389,90 @@ TabTarget.prototype = {
this._client = new DebuggerClient(DebuggerServer.connectPipe());
// A local TabTarget will never perform chrome debugging.
this._chrome = false;
}
this._setupRemoteListeners();
let attachTab = () => {
- this._client.attachTab(this._form.actor, (aResponse, aTabClient) => {
- if (!aTabClient) {
+ this._client.attachTab(this._form.actor, (response, tabClient) => {
+ if (!tabClient) {
this._remote.reject("Unable to attach to the tab");
return;
}
- this.activeTab = aTabClient;
- this.threadActor = aResponse.threadActor;
+ this.activeTab = tabClient;
+ this.threadActor = response.threadActor;
attachConsole();
});
};
+ let onConsoleAttached = (response, consoleClient) => {
+ if (!consoleClient) {
+ this._remote.reject("Unable to attach to the console");
+ return;
+ }
+ this.activeConsole = consoleClient;
+ this._remote.resolve(null);
+ };
+
let attachConsole = () => {
this._client.attachConsole(this._form.consoleActor,
[ "NetworkActivity" ],
- (aResponse, aWebConsoleClient) => {
- if (!aWebConsoleClient) {
- this._remote.reject("Unable to attach to the console");
- return;
- }
- this.activeConsole = aWebConsoleClient;
- this._remote.resolve(null);
- });
+ onConsoleAttached);
};
if (this.isLocalTab) {
- this._client.connect((aType, aTraits) => {
- this._client.getTab({ tab: this.tab })
- .then(aResponse => {
- this._form = aResponse.tab;
+ this._client.connect(() => {
+ this._client.getTab({ tab: this.tab }).then(response => {
+ this._form = response.tab;
attachTab();
});
});
} else if (this.isTabActor) {
// In the remote debugging case, the protocol connection will have been
// already initialized in the connection screen code.
attachTab();
} else {
- // AddonActor and chrome debugging on RootActor doesn't inherits from TabActor and
- // doesn't need to be attached.
+ // AddonActor and chrome debugging on RootActor doesn't inherits from
+ // TabActor and doesn't need to be attached.
attachConsole();
}
return this._remote.promise;
},
/**
* Listen to the different events.
*/
- _setupListeners: function TabTarget__setupListeners() {
+ _setupListeners: function() {
this._webProgressListener = new TabWebProgressListener(this);
this.tab.linkedBrowser.addProgressListener(this._webProgressListener);
this.tab.addEventListener("TabClose", this);
this.tab.parentNode.addEventListener("TabSelect", this);
this.tab.ownerDocument.defaultView.addEventListener("unload", this);
},
/**
* Teardown event listeners.
*/
- _teardownListeners: function TabTarget__teardownListeners() {
+ _teardownListeners: function() {
if (this._webProgressListener) {
this._webProgressListener.destroy();
}
this._tab.ownerDocument.defaultView.removeEventListener("unload", this);
this._tab.removeEventListener("TabClose", this);
this._tab.parentNode.removeEventListener("TabSelect", this);
},
/**
* Setup listeners for remote debugging, updating existing ones as necessary.
*/
- _setupRemoteListeners: function TabTarget__setupRemoteListeners() {
+ _setupRemoteListeners: function() {
this.client.addListener("closed", this.destroy);
this._onTabDetached = (aType, aPacket) => {
// We have to filter message to ensure that this detach is for this tab
if (aPacket.from == this._form.actor) {
this.destroy();
}
};
@@ -546,27 +502,27 @@ TabTarget.prototype = {
this.emit("frame-update", aPacket);
};
this.client.addListener("frameUpdate", this._onFrameUpdate);
},
/**
* Teardown listeners for remote debugging.
*/
- _teardownRemoteListeners: function TabTarget__teardownRemoteListeners() {
+ _teardownRemoteListeners: function() {
this.client.removeListener("closed", this.destroy);
this.client.removeListener("tabNavigated", this._onTabNavigated);
this.client.removeListener("tabDetached", this._onTabDetached);
this.client.removeListener("frameUpdate", this._onFrameUpdate);
},
/**
* Handle tabs events.
*/
- handleEvent: function (event) {
+ handleEvent: function(event) {
switch (event.type) {
case "TabClose":
case "unload":
this.destroy();
break;
case "TabSelect":
if (this.tab.selected) {
this.emit("visible", event);
@@ -645,52 +601,53 @@ TabTarget.prototype = {
}
return this._destroyer.promise;
},
/**
* Clean up references to what this target points to.
*/
- _cleanup: function TabTarget__cleanup() {
+ _cleanup: function() {
if (this._tab) {
targets.delete(this._tab);
} else {
promiseTargets.delete(this._form);
}
this.activeTab = null;
this.activeConsole = null;
this._client = null;
this._tab = null;
this._form = null;
this._remote = null;
},
toString: function() {
- return 'TabTarget:' + (this._tab ? this._tab : (this._form && this._form.actor));
+ let id = this._tab ? this._tab : (this._form && this._form.actor);
+ return `TabTarget:${id}`;
},
};
-
/**
* WebProgressListener for TabTarget.
*
* @param object aTarget
* The TabTarget instance to work with.
*/
function TabWebProgressListener(aTarget) {
this.target = aTarget;
}
TabWebProgressListener.prototype = {
target: null,
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
+ Ci.nsISupportsWeakReference]),
- onStateChange: function TWPL_onStateChange(progress, request, flag, status) {
+ onStateChange: function(progress, request, flag) {
let isStart = flag & Ci.nsIWebProgressListener.STATE_START;
let isDocument = flag & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
let isNetwork = flag & Ci.nsIWebProgressListener.STATE_IS_NETWORK;
let isRequest = flag & Ci.nsIWebProgressListener.STATE_IS_REQUEST;
// Skip non-interesting states.
if (!isStart || !isDocument || !isRequest || !isNetwork) {
return;
@@ -707,129 +664,48 @@ TabWebProgressListener.prototype = {
}
}
},
onProgressChange: function() {},
onSecurityChange: function() {},
onStatusChange: function() {},
- onLocationChange: function TWPL_onLocationChange(webProgress, request, URI, flags) {
+ onLocationChange: function(webProgress, request, URI, flags) {
if (this.target &&
!(flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT)) {
let window = webProgress.DOMWindow;
// Emit the event if the target is not remoted or store the payload for
// later emission otherwise.
if (this.target._client) {
this.target._navWindow = window;
} else {
this.target.emit("navigate", window);
}
}
},
/**
* Destroy the progress listener instance.
*/
- destroy: function TWPL_destroy() {
+ destroy: function() {
if (this.target.tab) {
try {
this.target.tab.linkedBrowser.removeProgressListener(this);
} catch (ex) {
// This can throw when a tab crashes in e10s.
}
}
this.target._webProgressListener = null;
this.target._navRequest = null;
this.target._navWindow = null;
this.target = null;
}
};
-
-/**
- * A WindowTarget represents a page living in a xul window or panel. Generally
- * these will have a chrome: URL
- */
-function WindowTarget(window) {
- EventEmitter.decorate(this);
- this._window = window;
- this._setupListeners();
-}
-
-WindowTarget.prototype = {
- get version() { return getVersion(); },
-
- get window() {
- return this._window;
- },
-
- get name() {
- return this._window.document.title;
- },
-
- get url() {
- return this._window.document.location.href;
- },
-
- get isRemote() {
- return false;
- },
-
- get isLocalTab() {
- return false;
- },
-
- get isThreadPaused() {
- return !!this._isThreadPaused;
- },
-
- /**
- * Listen to the different events.
- */
- _setupListeners: function() {
- this._handleThreadState = this._handleThreadState.bind(this);
- this.on("thread-paused", this._handleThreadState);
- this.on("thread-resumed", this._handleThreadState);
- },
-
- _handleThreadState: function(event) {
- switch (event) {
- case "thread-resumed":
- this._isThreadPaused = false;
- break;
- case "thread-paused":
- this._isThreadPaused = true;
- break;
- }
- },
-
- /**
- * Target is not alive anymore.
- */
- destroy: function() {
- if (!this._destroyed) {
- this._destroyed = true;
-
- this.off("thread-paused", this._handleThreadState);
- this.off("thread-resumed", this._handleThreadState);
- this.emit("close");
-
- targets.delete(this._window);
- this._window = null;
- }
-
- return promise.resolve(null);
- },
-
- toString: function() {
- return 'WindowTarget:' + this.window;
- },
-};
-
function WorkerTarget(workerClient) {
EventEmitter.decorate(this);
this._workerClient = workerClient;
}
/**
* A WorkerTarget represents a worker. Unlike TabTarget, which can represent
* either a local or remote tab, WorkerTarget always represents a remote worker.
@@ -872,20 +748,20 @@ WorkerTarget.prototype = {
get activeTab() {
return this._workerClient;
},
get client() {
return this._workerClient.client;
},
- destroy: function () {},
+ destroy: function() {},
- hasActor: function (name) {
+ hasActor: function() {
return false;
},
- getTrait: function (name) {
+ getTrait: function() {
return undefined;
},
- makeRemote: function () {}
+ makeRemote: function() {}
};
--- a/devtools/shared/gcli/commands/screenshot.js
+++ b/devtools/shared/gcli/commands/screenshot.js
@@ -62,21 +62,21 @@ const standardParams = {
{
name: "delay",
type: { name: "number", min: 0 },
defaultValue: 0,
description: l10n.lookup("screenshotDelayDesc"),
manual: l10n.lookup("screenshotDelayManual")
},
{
- name: "dpi",
+ name: "dpr",
type: { name: "number", min: 0, allowFloat: true },
defaultValue: 0,
- description: l10n.lookup("screenshotDPIDesc"),
- manual: l10n.lookup("screenshotDPIManual")
+ description: l10n.lookup("screenshotDPRDesc"),
+ manual: l10n.lookup("screenshotDPRManual")
},
{
name: "fullpage",
type: "boolean",
description: l10n.lookup("screenshotFullPageDesc"),
manual: l10n.lookup("screenshotFullPageManual")
},
{
@@ -288,17 +288,17 @@ function createScreenshotData(document,
const scrollbarHeight = {};
const scrollbarWidth = {};
winUtils.getScrollbarSize(false, scrollbarWidth, scrollbarHeight);
width -= scrollbarWidth.value;
height -= scrollbarHeight.value;
const canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
const ctx = canvas.getContext("2d");
- const ratio = args.dpi ? args.dpi : window.devicePixelRatio;
+ const ratio = args.dpr ? args.dpr : window.devicePixelRatio;
canvas.width = width * ratio;
canvas.height = height * ratio;
ctx.scale(ratio, ratio);
ctx.drawWindow(window, left, top, width, height, "#fff");
const data = canvas.toDataURL("image/png", "");
// See comment above on bug 961832
if (args.fullpage) {
--- a/dom/media/omx/MediaOmxReader.cpp
+++ b/dom/media/omx/MediaOmxReader.cpp
@@ -384,19 +384,18 @@ bool MediaOmxReader::DecodeVideoFrame(bo
// and we will preserve the ratio of the crop rectangle as it
// was reported relative to the picture size reported by the container.
picture.x = (mPicture.x * frame.Y.mWidth) / mInitialFrame.width;
picture.y = (mPicture.y * frame.Y.mHeight) / mInitialFrame.height;
picture.width = (frame.Y.mWidth * mPicture.width) / mInitialFrame.width;
picture.height = (frame.Y.mHeight * mPicture.height) / mInitialFrame.height;
}
- MOZ_ASSERT(mStreamSource);
// This is the approximate byte position in the stream.
- int64_t pos = mStreamSource->Tell();
+ int64_t pos = mStreamSource ? mStreamSource->Tell() : 0;
nsRefPtr<VideoData> v;
if (!frame.mGraphicBuffer) {
VideoData::YCbCrBuffer b;
b.mPlanes[0].mData = static_cast<uint8_t *>(frame.Y.mData);
b.mPlanes[0].mStride = frame.Y.mStride;
b.mPlanes[0].mHeight = frame.Y.mHeight;
@@ -487,19 +486,18 @@ void MediaOmxReader::NotifyDataArrivedIn
}
}
bool MediaOmxReader::DecodeAudioData()
{
MOZ_ASSERT(OnTaskQueue());
EnsureActive();
- MOZ_ASSERT(mStreamSource);
// This is the approximate byte position in the stream.
- int64_t pos = mStreamSource->Tell();
+ int64_t pos = mStreamSource ? mStreamSource->Tell() : 0;
// Read next frame
MPAPI::AudioFrame source;
if (!mOmxDecoder->ReadAudio(&source, mAudioSeekTimeUs)) {
return false;
}
mAudioSeekTimeUs = -1;
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.h
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.h
@@ -84,17 +84,17 @@ protected:
static void TrimLessFitCandidates(CapabilitySet& set);
static void LogConstraints(const dom::MediaTrackConstraintSet& aConstraints,
bool aAdvanced);
static void LogCapability(const char* aHeader,
const webrtc::CaptureCapability &aCapability,
uint32_t aDistance);
virtual size_t NumCapabilities();
virtual void GetCapability(size_t aIndex, webrtc::CaptureCapability& aOut);
- bool ChooseCapability(const dom::MediaTrackConstraints &aConstraints,
+ virtual bool ChooseCapability(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId);
void SetName(nsString aName);
void SetUUID(const char* aUUID);
const nsCString& GetUUID(); // protected access
// Engine variables.
@@ -113,17 +113,17 @@ static void LogCapability(const char* aH
// end of data protected by mMonitor
bool mInitDone;
bool mHasDirectListeners;
int mCaptureIndex;
TrackID mTrackID;
- webrtc::CaptureCapability mCapability; // Doesn't work on OS X.
+ webrtc::CaptureCapability mCapability;
nsTArray<webrtc::CaptureCapability> mHardcodedCapabilities; // For OSX & B2G
private:
nsString mDeviceName;
nsCString mUniqueId;
nsString mFacingMode;
};
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -382,16 +382,41 @@ MediaEngineRemoteVideoSource::NumCapabil
c.maxFPS = 0;
mHardcodedCapabilities.AppendElement(c);
break;
}
return mHardcodedCapabilities.Length();
}
+bool
+MediaEngineRemoteVideoSource::ChooseCapability(const MediaTrackConstraints &aConstraints,
+ const MediaEnginePrefs &aPrefs,
+ const nsString& aDeviceId)
+{
+
+ switch(mMediaSource) {
+ case dom::MediaSourceEnum::Screen:
+ case dom::MediaSourceEnum::Window:
+ case dom::MediaSourceEnum::Application: {
+ FlattenedConstraints c(aConstraints);
+ mCapability.width = c.mWidth.Clamp(c.mWidth.mIdeal.WasPassed() ?
+ c.mWidth.mIdeal.Value() : aPrefs.mWidth);
+ mCapability.height = c.mHeight.Clamp(c.mHeight.mIdeal.WasPassed() ?
+ c.mHeight.mIdeal.Value() : aPrefs.mHeight);
+ mCapability.maxFPS = c.mFrameRate.Clamp(c.mFrameRate.mIdeal.WasPassed() ?
+ c.mFrameRate.mIdeal.Value() : aPrefs.mFPS);
+ return true;
+ }
+ default:
+ return MediaEngineCameraVideoSource::ChooseCapability(aConstraints, aPrefs, aDeviceId);
+ }
+
+}
+
void
MediaEngineRemoteVideoSource::GetCapability(size_t aIndex,
webrtc::CaptureCapability& aOut)
{
if (!mHardcodedCapabilities.IsEmpty()) {
MediaEngineCameraVideoSource::GetCapability(aIndex, aOut);
}
mozilla::camera::GetCaptureCapability(mCapEngine,
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.h
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.h
@@ -77,16 +77,20 @@ public:
virtual void NotifyPull(MediaStreamGraph* aGraph,
SourceMediaStream* aSource,
TrackID aId,
StreamTime aDesiredTime) override;
virtual const dom::MediaSourceEnum GetMediaSource() override {
return mMediaSource;
}
+ bool ChooseCapability(const dom::MediaTrackConstraints &aConstraints,
+ const MediaEnginePrefs &aPrefs,
+ const nsString& aDeviceId) override;
+
void Refresh(int aIndex);
virtual void Shutdown() override;
protected:
~MediaEngineRemoteVideoSource() { Shutdown(); }
private:
--- a/mobile/android/base/GeckoEvent.java
+++ b/mobile/android/base/GeckoEvent.java
@@ -765,16 +765,26 @@ public class GeckoEvent {
public static GeckoEvent createTelemetryHistogramAddEvent(String histogram,
int value) {
GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_HISTOGRAM_ADD);
event.mCharacters = histogram;
event.mCount = value;
return event;
}
+ public static GeckoEvent createTelemetryKeyedHistogramAddEvent(String histogram,
+ String key,
+ int value) {
+ GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_HISTOGRAM_ADD);
+ event.mCharacters = histogram;
+ event.mCharactersExtra = key;
+ event.mCount = value;
+ return event;
+ }
+
public static GeckoEvent createTelemetryUISessionStartEvent(String session, long timestamp) {
GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.TELEMETRY_UI_SESSION_START);
event.mCharacters = session;
event.mTime = timestamp;
return event;
}
public static GeckoEvent createTelemetryUISessionStopEvent(String session, String reason, long timestamp) {
--- a/mobile/android/base/Telemetry.java
+++ b/mobile/android/base/Telemetry.java
@@ -38,16 +38,22 @@ public class Telemetry {
// Define new histograms in:
// toolkit/components/telemetry/Histograms.json
public static void addToHistogram(String name, int value) {
GeckoEvent event = GeckoEvent.createTelemetryHistogramAddEvent(name, value);
GeckoAppShell.sendEventToGecko(event);
}
+ public static void addToKeyedHistogram(String histogram, String keyName, int value) {
+ GeckoEvent event = GeckoEvent.createTelemetryKeyedHistogramAddEvent(histogram,
+ keyName, value);
+ GeckoAppShell.sendEventToGecko(event);
+ }
+
public abstract static class Timer {
private final long mStartTime;
private final String mName;
private volatile boolean mHasFinished;
private volatile long mElapsed = -1;
protected abstract long now();
--- a/mobile/android/base/fxa/activities/FxAccountStatusActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountStatusActivity.java
@@ -171,21 +171,16 @@ public class FxAccountStatusActivity ext
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == android.R.id.home) {
finish();
return true;
}
- if (itemId == R.id.remove_account) {
- maybeDeleteAndroidAccount(this, FirefoxAccounts.getFirefoxAccount(this), null);
- return true;
- }
-
if (itemId == R.id.enable_debug_mode) {
FxAccountUtils.LOG_PERSONAL_INFORMATION = !FxAccountUtils.LOG_PERSONAL_INFORMATION;
Toast.makeText(this, (FxAccountUtils.LOG_PERSONAL_INFORMATION ? "Enabled" : "Disabled") +
" Firefox Account personal information!", Toast.LENGTH_LONG).show();
item.setChecked(!item.isChecked());
// Display or hide debug options.
statusFragment.hardRefresh();
return true;
--- a/mobile/android/base/fxa/activities/FxAccountStatusFragment.java
+++ b/mobile/android/base/fxa/activities/FxAccountStatusFragment.java
@@ -93,16 +93,17 @@ public class FxAccountStatusFragment
// configured to use a custom Sync server. In debug mode, this is set.
private static boolean ALWAYS_SHOW_SYNC_SERVER = false;
protected PreferenceCategory accountCategory;
protected Preference profilePreference;
protected Preference emailPreference;
protected Preference manageAccountPreference;
protected Preference authServerPreference;
+ protected Preference removeAccountPreference;
protected Preference needsPasswordPreference;
protected Preference needsUpgradePreference;
protected Preference needsVerificationPreference;
protected Preference needsMasterSyncAutomaticallyEnabledPreference;
protected Preference needsFinishMigratingPreference;
protected PreferenceCategory syncCategory;
@@ -172,16 +173,17 @@ public class FxAccountStatusFragment
} else {
accountCategory.removePreference(profilePreference);
}
manageAccountPreference = ensureFindPreference("manage_account");
if (AppConstants.MOZ_ANDROID_NATIVE_ACCOUNT_UI) {
accountCategory.removePreference(manageAccountPreference);
}
authServerPreference = ensureFindPreference("auth_server");
+ removeAccountPreference = ensureFindPreference("remove_account");
needsPasswordPreference = ensureFindPreference("needs_credentials");
needsUpgradePreference = ensureFindPreference("needs_upgrade");
needsVerificationPreference = ensureFindPreference("needs_verification");
needsMasterSyncAutomaticallyEnabledPreference = ensureFindPreference("needs_master_sync_automatically_enabled");
needsFinishMigratingPreference = ensureFindPreference("needs_finish_migrating");
syncCategory = (PreferenceCategory) ensureFindPreference("sync_category");
@@ -200,16 +202,17 @@ public class FxAccountStatusFragment
}
if (AppConstants.MOZ_ANDROID_FIREFOX_ACCOUNT_PROFILES) {
profilePreference.setOnPreferenceClickListener(this);
} else {
emailPreference.setOnPreferenceClickListener(this);
}
manageAccountPreference.setOnPreferenceClickListener(this);
+ removeAccountPreference.setOnPreferenceClickListener(this);
needsPasswordPreference.setOnPreferenceClickListener(this);
needsVerificationPreference.setOnPreferenceClickListener(this);
needsFinishMigratingPreference.setOnPreferenceClickListener(this);
bookmarksPreference.setOnPreferenceClickListener(this);
historyPreference.setOnPreferenceClickListener(this);
tabsPreference.setOnPreferenceClickListener(this);
@@ -250,16 +253,21 @@ public class FxAccountStatusFragment
}
if (preference == manageAccountPreference) {
// There's no native equivalent, so no need to re-direct through an Intent filter.
ActivityUtils.openURLInFennec(getActivity().getApplicationContext(), "about:accounts?action=manage");
return true;
}
+ if (preference == removeAccountPreference) {
+ FxAccountStatusActivity.maybeDeleteAndroidAccount(getActivity(), fxAccount.getAndroidAccount(), null);
+ return true;
+ }
+
if (preference == needsPasswordPreference) {
final Intent intent = new Intent(FxAccountConstants.ACTION_FXA_UPDATE_CREDENTIALS);
intent.putExtra(FxAccountWebFlowActivity.EXTRA_ENDPOINT, FxAccountConstants.ENDPOINT_PREFERENCES);
final Bundle extras = getExtrasForAccount();
if (extras != null) {
intent.putExtras(extras);
}
// Per http://stackoverflow.com/a/8992365, this triggers a known bug with
--- a/mobile/android/base/locales/en-US/sync_strings.dtd
+++ b/mobile/android/base/locales/en-US/sync_strings.dtd
@@ -218,24 +218,24 @@
<!ENTITY fxaccount_status_legal 'Legal' >
<!-- Localization note: when tapped, the following two strings link to
external web pages. Compare fxaccount_policy_{linktos,linkprivacy}:
these strings are separated to accommodate languages that decline
the two uses differently. -->
<!ENTITY fxaccount_status_linktos 'Terms of Service'>
<!ENTITY fxaccount_status_linkprivacy 'Privacy Notice'>
<!ENTITY fxaccount_status_more 'More&ellipsis;'>
+<!ENTITY fxaccount_remove_account 'Disconnect ...'>
<!ENTITY fxaccount_remove_account_dialog_title 'Remove Firefox Account?'>
<!ENTITY fxaccount_remove_account_dialog_message '&brandShortName; will stop syncing with your account, but won’t delete any of your browsing data on this device.'>
<!-- Localization note: format string below will be replaced
with the Firefox Account's email address. -->
<!ENTITY fxaccount_remove_account_toast 'Firefox Account &formatS; removed.'>
-<!ENTITY fxaccount_remove_account_menu_item 'Remove Account'>
<!ENTITY fxaccount_enable_debug_mode 'Enable Debug Mode'>
<!-- Localization note: this is the name shown by the Android system
itself for a Firefox Account. Don't localize this. -->
<!ENTITY fxaccount_account_type_label 'Firefox'>
<!-- Localization note: these are shown by the Android system itself,
when the user navigates to the Android > Accounts > {Firefox
--- a/mobile/android/base/resources/menu/fxaccount_status_menu.xml
+++ b/mobile/android/base/resources/menu/fxaccount_status_menu.xml
@@ -1,11 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
- android:id="@+id/remove_account"
- android:title="@string/fxaccount_remove_account_menu_item" />
- <item
android:id="@+id/enable_debug_mode"
android:checkable="true"
android:checked="false"
android:title="@string/fxaccount_enable_debug_mode" />
</menu>
--- a/mobile/android/base/resources/xml/fxaccount_status_prefscreen.xml
+++ b/mobile/android/base/resources/xml/fxaccount_status_prefscreen.xml
@@ -97,17 +97,21 @@
android:persistent="false"
android:title="@string/fxaccount_status_device_name" />
<Preference
android:editable="false"
android:key="sync_server"
android:persistent="false"
android:title="@string/fxaccount_status_sync_server" />
-
+ <Preference
+ android:editable="false"
+ android:key="remove_account"
+ android:persistent="false"
+ android:title="@string/fxaccount_remove_account" />
<Preference
android:editable="false"
android:key="more"
android:persistent="false"
android:title="@string/fxaccount_status_more" />
</PreferenceCategory>
<PreferenceCategory
--- a/mobile/android/services/strings.xml.in
+++ b/mobile/android/services/strings.xml.in
@@ -206,16 +206,17 @@
<string name="fxaccount_status_history">&fxaccount_status_history;</string>
<string name="fxaccount_status_passwords">&fxaccount_status_passwords2;</string>
<string name="fxaccount_status_tabs">&fxaccount_status_tabs;</string>
<string name="fxaccount_status_reading_list">&reading_list_title;</string>
<string name="fxaccount_status_legal">&fxaccount_status_legal;</string>
<string name="fxaccount_status_linktos">&fxaccount_status_linktos;</string>
<string name="fxaccount_status_linkprivacy">&fxaccount_status_linkprivacy;</string>
<string name="fxaccount_status_more">&fxaccount_status_more;</string>
+<string name="fxaccount_remove_account">&fxaccount_remove_account;</string>
<string name="fxaccount_label">&fxaccount_account_type_label;</string>
<string name="fxaccount_options_title">&fxaccount_options_title;</string>
<string name="fxaccount_options_configure_title">&fxaccount_options_configure_title;</string>
<string name="fxaccount_remote_error_UPGRADE_REQUIRED">&fxaccount_remote_error_UPGRADE_REQUIRED;</string>
<string name="fxaccount_remote_error_ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS">&fxaccount_remote_error_ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS_2;</string>
@@ -230,15 +231,14 @@
<string name="fxaccount_sync_sign_in_error_notification_title">&fxaccount_sync_sign_in_error_notification_title2;</string>
<string name="fxaccount_sync_sign_in_error_notification_text">&fxaccount_sync_sign_in_error_notification_text2;</string>
<!-- Remove Account -->
<string name="fxaccount_remove_account_dialog_title">&fxaccount_remove_account_dialog_title;</string>
<string name="fxaccount_remove_account_dialog_message">&fxaccount_remove_account_dialog_message;</string>
<string name="fxaccount_remove_account_toast">&fxaccount_remove_account_toast;</string>
-<string name="fxaccount_remove_account_menu_item">&fxaccount_remove_account_menu_item;</string>
<string name="fxaccount_sync_finish_migrating_notification_title">&fxaccount_sync_finish_migrating_notification_title;</string>
<string name="fxaccount_sync_finish_migrating_notification_text">&fxaccount_sync_finish_migrating_notification_text;</string>
<!-- Log Personal information -->
<string name="fxaccount_enable_debug_mode">&fxaccount_enable_debug_mode;</string>
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -3265,16 +3265,21 @@ pref("ui.osk.enabled", true);
// Only show the on-screen keyboard if there are no physical keyboards attached
// to the device.
pref("ui.osk.detect_physical_keyboard", true);
// Path to TabTip.exe on local machine. Cached for performance reasons.
pref("ui.osk.on_screen_keyboard_path", "");
// Only show the on-screen keyboard when Windows is in Tablet mode. Setting
// this pref to false will allow the OSK to show in regular non-tablet mode.
pref("ui.osk.require_tablet_mode", true);
+// This pref stores the "reason" that the on-screen keyboard was either
+// shown or not shown when focus is moved to an editable text field. It is
+// used to help debug why the keyboard is either not appearing when expected
+// or appearing when it is not expected.
+pref("ui.osk.debug.keyboardDisplayReason", "");
# XP_WIN
#endif
#ifdef XP_MACOSX
// Mac specific preference defaults
pref("browser.drag_out_of_frame_style", 1);
pref("ui.key.saveLink.shift", false); // true = shift, false = meta
--- a/testing/taskcluster/tasks/branches/base_job_flags.yml
+++ b/testing/taskcluster/tasks/branches/base_job_flags.yml
@@ -11,17 +11,16 @@ flags:
- emulator-kk
- emulator-x86-kk
- emulator-l
- linux32_gecko # b2g desktop linux 32 bit
- linux64_gecko # b2g desktop linux 64 bit
- linux64-mulet # Firefox desktop - b2g gecko linux 64 bit
- macosx64_gecko # b2g desktop osx 64 bit
- win32_gecko # b2g desktop win 32 bit
- - flame-kk-ota
- flame-kk # b2g flame kitkat
- flame-kk-eng # b2g flame eng build
- flame-kk-spark-eng
- nexus-4
- nexus-4-eng
- nexus-4-kk
- nexus-4-kk-eng
- nexus-5l
--- a/testing/taskcluster/tasks/branches/mozilla-central/job_flags.yml
+++ b/testing/taskcluster/tasks/branches/mozilla-central/job_flags.yml
@@ -26,22 +26,8 @@ builds:
aries-ota:
platforms:
- b2g
types:
opt:
task: tasks/builds/b2g_aries_spark_ota_opt.yml
debug:
task: tasks/builds/b2g_aries_spark_ota_debug.yml
- flame-kk-ota:
- platforms:
- - b2g
- types:
- opt:
- task: tasks/builds/b2g_flame_kk_ota_opt.yml
- debug:
- task: tasks/builds/b2g_flame_kk_ota_debug.yml
-
-post-build:
- simulator:
- allowed_build_tasks:
- - tasks/builds/mulet_linux.yml
- task: tasks/post-builds/mulet_simulator.yml
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -3720,16 +3720,29 @@ Accumulate(const char* name, uint32_t sa
Histogram *h;
rv = GetHistogramByEnumId(id, &h);
if (NS_SUCCEEDED(rv)) {
HistogramAdd(*h, sample, gHistograms[id].dataset);
}
}
void
+Accumulate(const char *name, const nsCString& key, uint32_t sample)
+{
+ if (!TelemetryImpl::CanRecordBase()) {
+ return;
+ }
+ ID id;
+ nsresult rv = TelemetryImpl::GetHistogramEnumId(name, &id);
+ if (NS_SUCCEEDED(rv)) {
+ Accumulate(id, key, sample);
+ }
+}
+
+void
AccumulateTimeDelta(ID aHistogram, TimeStamp start, TimeStamp end)
{
Accumulate(aHistogram,
static_cast<uint32_t>((end - start).ToMilliseconds()));
}
bool
CanRecordBase()
--- a/toolkit/components/telemetry/Telemetry.h
+++ b/toolkit/components/telemetry/Telemetry.h
@@ -58,16 +58,28 @@ void Accumulate(ID id, const nsCString&
* certainly be using the by-enum-id version instead of this one.
*
* @param name - histogram name
* @param sample - value to record
*/
void Accumulate(const char* name, uint32_t sample);
/**
+ * Adds a sample to a histogram defined in TelemetryHistograms.h.
+ * This function is here to support telemetry measurements from Java,
+ * where we have only names and not numeric IDs. You should almost
+ * certainly be using the by-enum-id version instead of this one.
+ *
+ * @param name - histogram name
+ * @param key - the string key
+ * @param sample - sample - (optional) value to record, defaults to 1.
+ */
+void Accumulate(const char *name, const nsCString& key, uint32_t sample = 1);
+
+/**
* Adds time delta in milliseconds to a histogram defined in TelemetryHistograms.h
*
* @param id - histogram id
* @param start - start time
* @param end - end time
*/
void AccumulateTimeDelta(ID id, TimeStamp start, TimeStamp end = TimeStamp::Now());
--- a/toolkit/content/aboutwebrtc/aboutWebrtc.js
+++ b/toolkit/content/aboutwebrtc/aboutWebrtc.js
@@ -519,20 +519,19 @@ RTPStats.prototype = {
statsString = label + statsString;
}
let line = document.createElement("p");
line.textContent = statsString;
return line;
},
- renderTransportStats: function(stats, type) {
- let label = this.labelize(type);
+ renderTransportStats: function(stats, typeLabel) {
let time = new Date(stats.timestamp).toTimeString();
- let statsString = `${label}: ${time} ${stats.type} SSRC: ${stats.ssrc}`;
+ let statsString = `${typeLabel}: ${time} ${stats.type} SSRC: ${stats.ssrc}`;
if (stats.packetsReceived) {
statsString += ` ${getString("received_label")}: ${stats.packetsReceived} ${getString("packets")}`;
if (stats.bytesReceived) {
statsString += ` (${(stats.bytesReceived / 1024).toFixed(2)} Kb)`;
}
@@ -560,28 +559,24 @@ RTPStats.prototype = {
heading.textContent = stats.id;
div.appendChild(heading);
if (stats.MozAvSyncDelay || stats.mozJitterBufferDelay) {
div.appendChild(this.renderAvStats(stats));
}
div.appendChild(this.renderCoderStats(stats));
- div.appendChild(this.renderTransportStats(stats, getString("local")));
+ div.appendChild(this.renderTransportStats(stats, getString("typeLocal")));
if (stats.remoteId && stats.remoteRtpStats) {
- div.appendChild(this.renderTransportStats(stats.remoteRtpStats, getString("remote")));
+ div.appendChild(this.renderTransportStats(stats.remoteRtpStats, getString("typeRemote")));
}
return div;
},
-
- labelize: function(label) {
- return `${label.charAt(0).toUpperCase()}${label.slice(1)}`;
- }
};
function ICEStats(report) {
this._report = report;
}
ICEStats.prototype = {
render: function() {
--- a/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties
+++ b/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties
@@ -71,21 +71,21 @@ av_sync_label = A/V sync
# This is used as a data label.
jitter_buffer_delay_label = Jitter-buffer delay
# LOCALIZATION NOTE (avg_bitrate_label, avg_framerate_label): "Avg." is an abbreviation
# for Average. These are used as data labels.
avg_bitrate_label = Avg. bitrate
avg_framerate_label = Avg. framerate
-# LOCALIZATION NOTE (local, remote): These adjectives are used to label a
+# LOCALIZATION NOTE (typeLocal, typeRemote): These adjectives are used to label a
# line of statistics collected for a peer connection. The data represents
# either the local or remote end of the connection.
-local = local
-remote = remote
+typeLocal = Local
+typeRemote = Remote
# LOCALIZATION NOTE (nominated): This adjective is used to label a table column.
# Cells in this column contain the localized javascript string representation of "true"
# or are left blank.
nominated = Nominated
# LOCALIZATION NOTE (selected): This adjective is used to label a table column.
# Cells in this column contain the localized javascript string representation of "true"
--- a/toolkit/locales/en-US/chrome/global/devtools/gclicommands.properties
+++ b/toolkit/locales/en-US/chrome/global/devtools/gclicommands.properties
@@ -91,25 +91,25 @@ screenshotAdvancedOptions=Advanced Optio
# a dialog when the user is using this command.
screenshotDelayDesc=Delay (seconds)
# LOCALIZATION NOTE (screenshotDelayManual) A fuller description of the
# 'delay' parameter to the 'screenshot' command, displayed when the user
# asks for help on what it does.
screenshotDelayManual=The time to wait (in seconds) before the screenshot is taken
-# LOCALIZATION NOTE (screenshotDPIDesc) A very short string to describe
-# the 'dpi' parameter to the 'screenshot' command, which is displayed in
+# LOCALIZATION NOTE (screenshotDPRDesc) A very short string to describe
+# the 'dpr' parameter to the 'screenshot' command, which is displayed in
# a dialog when the user is using this command.
-screenshotDPIDesc=Dots per inch
+screenshotDPRDesc=Device pixel ratio
-# LOCALIZATION NOTE (screenshotDPIManual) A fuller description of the
-# 'dpi' parameter to the 'screenshot' command, displayed when the user
+# LOCALIZATION NOTE (screenshotDPRManual) A fuller description of the
+# 'dpr' parameter to the 'screenshot' command, displayed when the user
# asks for help on what it does.
-screenshotDPIManual=The number of dots per inch in the screenshot
+screenshotDPRManual=The device pixel ratio to use when taking the screenshot
# LOCALIZATION NOTE (screenshotFullscreenDesc) A very short string to describe
# the 'fullscreen' parameter to the 'screenshot' command, which is displayed in
# a dialog when the user is using this command.
screenshotFullPageDesc=Entire webpage? (true/false)
# LOCALIZATION NOTE (screenshotFullscreenManual) A fuller description of the
# 'fullscreen' parameter to the 'screenshot' command, displayed when the user
--- a/toolkit/modules/Troubleshoot.jsm
+++ b/toolkit/modules/Troubleshoot.jsm
@@ -84,16 +84,20 @@ const PREFS_WHITELIST = [
"plugins.",
"print.",
"privacy.",
"security.",
"social.enabled",
"storage.vacuum.last.",
"svg.",
"toolkit.startup.recent_crashes",
+ "ui.osk.enabled",
+ "ui.osk.detect_physical_keyboard",
+ "ui.osk.require_tablet_mode",
+ "ui.osk.debug.keyboardDisplayReason",
"webgl.",
];
// The blacklist, unlike the whitelist, is a list of regular expressions.
const PREFS_BLACKLIST = [
/^network[.]proxy[.]/,
/[.]print_to_filename$/,
/^print[.]macosx[.]pagesetup/,
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -548,16 +548,17 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jo
case NETWORK_LINK_CHANGE: {
ReadCharactersField(jenv);
break;
}
case TELEMETRY_HISTOGRAM_ADD: {
ReadCharactersField(jenv);
+ ReadCharactersExtraField(jenv);
mCount = jenv->GetIntField(jobj, jCountField);
break;
}
case TELEMETRY_UI_SESSION_START: {
ReadCharactersField(jenv);
mTime = jenv->GetLongField(jobj, jTimeField);
break;
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -727,18 +727,25 @@ nsAppShell::LegacyGeckoEvent::Run()
os->NotifyObservers(nullptr,
NS_NETWORK_LINK_TOPIC,
nsString(curEvent->Characters()).get());
}
break;
}
case AndroidGeckoEvent::TELEMETRY_HISTOGRAM_ADD:
- Telemetry::Accumulate(NS_ConvertUTF16toUTF8(curEvent->Characters()).get(),
- curEvent->Count());
+ // If the extras field is not empty then this is a keyed histogram.
+ if (!curEvent->CharactersExtra().IsVoid()) {
+ Telemetry::Accumulate(NS_ConvertUTF16toUTF8(curEvent->Characters()).get(),
+ NS_ConvertUTF16toUTF8(curEvent->CharactersExtra()),
+ curEvent->Count());
+ } else {
+ Telemetry::Accumulate(NS_ConvertUTF16toUTF8(curEvent->Characters()).get(),
+ curEvent->Count());
+ }
break;
case AndroidGeckoEvent::GAMEPAD_ADDREMOVE: {
#ifdef MOZ_GAMEPAD
if (curEvent->Action() == AndroidGeckoEvent::ACTION_GAMEPAD_ADDED) {
int svc_id = dom::GamepadFunctions::AddGamepad("android",
dom::GamepadMappingType::Standard,
dom::kStandardGamepadButtons,
--- a/widget/windows/WinIMEHandler.cpp
+++ b/widget/windows/WinIMEHandler.cpp
@@ -24,16 +24,17 @@
#include "powrprof.h"
#include "setupapi.h"
#include "cfgmgr32.h"
const char* kOskPathPrefName = "ui.osk.on_screen_keyboard_path";
const char* kOskEnabled = "ui.osk.enabled";
const char* kOskDetectPhysicalKeyboard = "ui.osk.detect_physical_keyboard";
const char* kOskRequireTabletMode = "ui.osk.require_tablet_mode";
+const char* kOskDebugReason = "ui.osk.debug.keyboardDisplayReason";
namespace mozilla {
namespace widget {
/******************************************************************************
* IMEHandler
******************************************************************************/
@@ -542,17 +543,17 @@ IMEHandler::MaybeShowOnScreenKeyboard()
// run on Windows 8 and higher (adjusting the IsWin10OrLater
// guard above and within MaybeDismissOnScreenKeyboard).
if (!IsInTabletMode() &&
Preferences::GetBool(kOskRequireTabletMode, true) &&
!AutoInvokeOnScreenKeyboardInDesktopMode()) {
return;
}
- IMEHandler::ShowOnScreenKeyboard();
+ IMEHandler::ShowOnScreenKeyboard();
}
// static
void
IMEHandler::MaybeDismissOnScreenKeyboard()
{
if (sPluginHasFocus ||
!IsWin10OrLater() ||
@@ -585,32 +586,36 @@ IMEHandler::WStringStartsWithCaseInsensi
// are attached to the machine.
// Based on IsKeyboardPresentOnSlate() in Chromium's base/win/win_util.cc.
// static
bool
IMEHandler::IsKeyboardPresentOnSlate()
{
// This function is only supported for Windows 8 and up.
if (!IsWin8OrLater()) {
+ Preferences::SetString(kOskDebugReason, L"IKPOS: Requires Win8+.");
return true;
}
if (!Preferences::GetBool(kOskDetectPhysicalKeyboard, true)) {
- // Detection for physical keyboard has been disabled for testing.
+ Preferences::SetString(kOskDebugReason, L"IKPOS: Detection disabled.");
return false;
}
// This function should be only invoked for machines with touch screens.
if ((::GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH)
!= NID_INTEGRATED_TOUCH) {
+ Preferences::SetString(kOskDebugReason,
+ L"IKPOS: Touch screen not found.");
return true;
}
// If the device is docked, the user is treating the device as a PC.
if (::GetSystemMetrics(SM_SYSTEMDOCKED) != 0) {
+ Preferences::SetString(kOskDebugReason, L"IKPOS: System docked.");
return true;
}
// To determine whether a keyboard is present on the device, we do the
// following:-
// 1. Check whether the device supports auto rotation. If it does then
// it possibly supports flipping from laptop to slate mode. If it
// does not support auto rotation, then we assume it is a desktop
@@ -627,50 +632,61 @@ IMEHandler::IsKeyboardPresentOnSlate()
typedef BOOL (WINAPI* GetAutoRotationState)(PAR_STATE state);
GetAutoRotationState get_rotation_state =
reinterpret_cast<GetAutoRotationState>(::GetProcAddress(
::GetModuleHandleW(L"user32.dll"), "GetAutoRotationState"));
if (get_rotation_state) {
AR_STATE auto_rotation_state = AR_ENABLED;
get_rotation_state(&auto_rotation_state);
- if ((auto_rotation_state & AR_NOSENSOR) ||
- (auto_rotation_state & AR_NOT_SUPPORTED)) {
- // If there is no auto rotation sensor or rotation is not supported in
- // the current configuration, then we can assume that this is a desktop
- // or a traditional laptop.
+ // If there is no auto rotation sensor or rotation is not supported in
+ // the current configuration, then we can assume that this is a desktop
+ // or a traditional laptop.
+ if (auto_rotation_state & AR_NOSENSOR) {
+ Preferences::SetString(kOskDebugReason,
+ L"IKPOS: Rotation sensor not found.");
+ return true;
+ } else if (auto_rotation_state & AR_NOT_SUPPORTED) {
+ Preferences::SetString(kOskDebugReason,
+ L"IKPOS: Auto-rotation not supported.");
return true;
}
}
// Check if the device is being used as a laptop or a tablet. This can be
// checked by first checking the role of the device and then the
// corresponding system metric (SM_CONVERTIBLESLATEMODE). If it is being
// used as a tablet then we want the OSK to show up.
typedef POWER_PLATFORM_ROLE (WINAPI* PowerDeterminePlatformRole)();
PowerDeterminePlatformRole power_determine_platform_role =
reinterpret_cast<PowerDeterminePlatformRole>(::GetProcAddress(
::LoadLibraryW(L"PowrProf.dll"), "PowerDeterminePlatformRole"));
if (power_determine_platform_role) {
POWER_PLATFORM_ROLE role = power_determine_platform_role();
if (((role == PlatformRoleMobile) || (role == PlatformRoleSlate)) &&
(::GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0)) {
+ if (role == PlatformRoleMobile) {
+ Preferences::SetString(kOskDebugReason, L"IKPOS: PlatformRoleMobile.");
+ } else if (role == PlatformRoleSlate) {
+ Preferences::SetString(kOskDebugReason, L"IKPOS: PlatformRoleSlate.");
+ }
return false;
}
}
const GUID KEYBOARD_CLASS_GUID =
{ 0x4D36E96B, 0xE325, 0x11CE,
{ 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } };
// Query for all the keyboard devices.
HDEVINFO device_info =
::SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, nullptr,
nullptr, DIGCF_PRESENT);
if (device_info == INVALID_HANDLE_VALUE) {
+ Preferences::SetString(kOskDebugReason, L"IKPOS: No keyboard info.");
return false;
}
// Enumerate all keyboards and look for ACPI\PNP and HID\VID devices. If
// the count is more than 1 we assume that a keyboard is present. This is
// under the assumption that there will always be one keyboard device.
for (DWORD i = 0;; ++i) {
SP_DEVINFO_DATA device_info_data = { 0 };
@@ -691,63 +707,85 @@ IMEHandler::IsKeyboardPresentOnSlate()
if (IMEHandler::WStringStartsWithCaseInsensitive(device_id,
L"ACPI") ||
IMEHandler::WStringStartsWithCaseInsensitive(device_id,
L"HID\\VID")) {
// The heuristic we are using is to check the count of keyboards and
// return true if the API's report one or more keyboards. Please note
// that this will break for non keyboard devices which expose a
// keyboard PDO.
+ Preferences::SetString(kOskDebugReason,
+ L"IKPOS: Keyboard presence confirmed.");
return true;
}
}
}
+ Preferences::SetString(kOskDebugReason,
+ L"IKPOS: Lack of keyboard confirmed.");
return false;
}
// static
bool
IMEHandler::IsInTabletMode()
{
nsCOMPtr<nsIWindowsUIUtils>
uiUtils(do_GetService("@mozilla.org/windows-ui-utils;1"));
if (NS_WARN_IF(!uiUtils)) {
+ Preferences::SetString(kOskDebugReason,
+ L"IITM: nsIWindowsUIUtils not available.");
return false;
}
bool isInTabletMode = false;
uiUtils->GetInTabletMode(&isInTabletMode);
+ if (isInTabletMode) {
+ Preferences::SetString(kOskDebugReason, L"IITM: GetInTabletMode=true.");
+ } else {
+ Preferences::SetString(kOskDebugReason, L"IITM: GetInTabletMode=false.");
+ }
return isInTabletMode;
}
// static
bool
IMEHandler::AutoInvokeOnScreenKeyboardInDesktopMode()
{
nsresult rv;
nsCOMPtr<nsIWindowsRegKey> regKey
(do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv));
if (NS_WARN_IF(NS_FAILED(rv))) {
+ Preferences::SetString(kOskDebugReason, L"AIOSKIDM: "
+ L"nsIWindowsRegKey not available");
return false;
}
rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
NS_LITERAL_STRING("SOFTWARE\\Microsoft\\TabletTip\\1.7"),
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
if (NS_FAILED(rv)) {
+ Preferences::SetString(kOskDebugReason,
+ L"AIOSKIDM: failed opening regkey.");
return false;
}
// EnableDesktopModeAutoInvoke is an opt-in option from the Windows
// Settings to "Automatically show the touch keyboard in windowed apps
// when there's no keyboard attached to your device." If the user has
// opted-in to this behavior, the tablet-mode requirement is skipped.
uint32_t value;
rv = regKey->ReadIntValue(NS_LITERAL_STRING("EnableDesktopModeAutoInvoke"),
&value);
if (NS_FAILED(rv)) {
+ Preferences::SetString(kOskDebugReason,
+ L"AIOSKIDM: failed reading value of regkey.");
return false;
}
+ if (!!value) {
+ Preferences::SetString(kOskDebugReason, L"AIOSKIDM: regkey value=true.");
+ } else {
+ Preferences::SetString(kOskDebugReason, L"AIOSKIDM: regkey value=false.");
+ }
return !!value;
}
// Based on DisplayVirtualKeyboard() in Chromium's base/win/win_util.cc.
// static
void
IMEHandler::ShowOnScreenKeyboard()
{