зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound. a=merge
This commit is contained in:
Коммит
e8471bb514
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
|
||||||
|
@ -131,10 +131,10 @@
|
||||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="197cd9492b9fadaa915c5daf36ff557f8f4a8d1c"/>
|
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="197cd9492b9fadaa915c5daf36ff557f8f4a8d1c"/>
|
||||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
||||||
<project name="libnfcemu" path="external/libnfcemu" remote="b2g" revision="125ccf9bd5986c7728ea44508b3e1d1185ac028b"/>
|
<project name="libnfcemu" path="external/libnfcemu" remote="b2g" revision="125ccf9bd5986c7728ea44508b3e1d1185ac028b"/>
|
||||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="d259117b4976decbe2f76eeed85218bf0109190f"/>
|
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c5f8d282efe4a4e8b1e31a37300944e338e60e4f"/>
|
||||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9f28c4faea3b2f01db227b2467b08aeba96d9bec"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9f28c4faea3b2f01db227b2467b08aeba96d9bec"/>
|
||||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d872fc1462d367eb67833de6942c297d6c4dc874"/>
|
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="a28a47cf4de9cc676e8a14d58826f7927d77f5d5"/>
|
||||||
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
|
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
|
||||||
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
|
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
<project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
|
<project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
|
||||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
|
<project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
|
||||||
<project name="platform/system/core" path="system/core" revision="350eac5403124dacb2a5fd9e28ac290a59fc3b8e"/>
|
<project name="platform/system/core" path="system/core" revision="350eac5403124dacb2a5fd9e28ac290a59fc3b8e"/>
|
||||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d872fc1462d367eb67833de6942c297d6c4dc874"/>
|
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="a28a47cf4de9cc676e8a14d58826f7927d77f5d5"/>
|
||||||
<project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
|
<project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
|
||||||
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/>
|
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/>
|
||||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="7704e16da545f4207812e593743d6743e1afb9c5"/>
|
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="7704e16da545f4207812e593743d6743e1afb9c5"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
|
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
|
||||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
|
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
|
||||||
<project name="platform/system/core" path="system/core" revision="adc485d8755af6a61641d197de7cfef667722580"/>
|
<project name="platform/system/core" path="system/core" revision="adc485d8755af6a61641d197de7cfef667722580"/>
|
||||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d872fc1462d367eb67833de6942c297d6c4dc874"/>
|
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="a28a47cf4de9cc676e8a14d58826f7927d77f5d5"/>
|
||||||
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
|
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
|
||||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
|
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
|
||||||
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>
|
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
"remote": "",
|
"remote": "",
|
||||||
"branch": ""
|
"branch": ""
|
||||||
},
|
},
|
||||||
"revision": "ce8e42aa3688f56113d68bc82409a7fea055547b",
|
"revision": "2bf3274b9e149c6a0ffc13be4c7d3a2f7236e311",
|
||||||
"repo_path": "/integration/gaia-central"
|
"repo_path": "/integration/gaia-central"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
|
||||||
|
@ -129,7 +129,7 @@
|
||||||
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
|
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
|
||||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
|
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
|
||||||
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
|
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
|
||||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d872fc1462d367eb67833de6942c297d6c4dc874"/>
|
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="a28a47cf4de9cc676e8a14d58826f7927d77f5d5"/>
|
||||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
||||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||||
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
|
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3ec94f448bb5c1c9c264896685c6ef77ab718c87"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="82174cee5ede9f23aedad8a39f8b8cdc1ae710c4"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="73d68c9c91bc568ce7c888ac057b3f44bd1b2e79"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
|
|
@ -2576,8 +2576,8 @@ let BrowserOnClick = {
|
||||||
TabCrashReporter.submitCrashReport(browser);
|
TabCrashReporter.submitCrashReport(browser);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
let tab = gBrowser.getTabForBrowser(browser);
|
||||||
TabCrashReporter.reloadCrashedTab(browser);
|
SessionStore.reviveCrashedTab(tab);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ const WINDOW_HIDEABLE_FEATURES = [
|
||||||
"menubar", "toolbar", "locationbar", "personalbar", "statusbar", "scrollbars"
|
"menubar", "toolbar", "locationbar", "personalbar", "statusbar", "scrollbars"
|
||||||
];
|
];
|
||||||
|
|
||||||
const MESSAGES = [
|
// Messages that will be received via the Frame Message Manager.
|
||||||
|
const FMM_MESSAGES = [
|
||||||
// The content script gives us a reference to an object that performs
|
// The content script gives us a reference to an object that performs
|
||||||
// synchronous collection of session data.
|
// synchronous collection of session data.
|
||||||
"SessionStore:setupSyncHandler",
|
"SessionStore:setupSyncHandler",
|
||||||
|
@ -73,6 +74,16 @@ const MESSAGES = [
|
||||||
"SessionStore:reloadPendingTab",
|
"SessionStore:reloadPendingTab",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Messages that will be received via the Parent Process Message Manager.
|
||||||
|
const PPMM_MESSAGES = [
|
||||||
|
// A tab is being revived from the crashed state. The sender of this
|
||||||
|
// message should actually be running in the parent process, since this
|
||||||
|
// will be the crashed tab interface. We use the Child and Parent Process
|
||||||
|
// Message Managers because the message is sent during framescript unload
|
||||||
|
// when the Frame Message Manager is not available.
|
||||||
|
"SessionStore:RemoteTabRevived",
|
||||||
|
];
|
||||||
|
|
||||||
// These are tab events that we listen to.
|
// These are tab events that we listen to.
|
||||||
const TAB_EVENTS = [
|
const TAB_EVENTS = [
|
||||||
"TabOpen", "TabClose", "TabSelect", "TabShow", "TabHide", "TabPinned",
|
"TabOpen", "TabClose", "TabSelect", "TabShow", "TabHide", "TabPinned",
|
||||||
|
@ -97,7 +108,9 @@ XPCOMUtils.defineLazyServiceGetter(this, "gScreenManager",
|
||||||
"@mozilla.org/gfx/screenmanager;1", "nsIScreenManager");
|
"@mozilla.org/gfx/screenmanager;1", "nsIScreenManager");
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
|
XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
|
||||||
"@mozilla.org/base/telemetry;1", "nsITelemetry");
|
"@mozilla.org/base/telemetry;1", "nsITelemetry");
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||||
|
"@mozilla.org/parentprocessmessagemanager;1",
|
||||||
|
"nsIMessageListenerManager");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "console",
|
XPCOMUtils.defineLazyModuleGetter(this, "console",
|
||||||
"resource://gre/modules/devtools/Console.jsm");
|
"resource://gre/modules/devtools/Console.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
||||||
|
@ -263,6 +276,10 @@ this.SessionStore = {
|
||||||
return SessionStoreInternal.getCurrentState(aUpdateAll);
|
return SessionStoreInternal.getCurrentState(aUpdateAll);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
reviveCrashedTab(aTab) {
|
||||||
|
return SessionStoreInternal.reviveCrashedTab(aTab);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backstage pass to implementation details, used for testing purpose.
|
* Backstage pass to implementation details, used for testing purpose.
|
||||||
* Controlled by preference "browser.sessionstore.testmode".
|
* Controlled by preference "browser.sessionstore.testmode".
|
||||||
|
@ -297,6 +314,11 @@ let SessionStoreInternal = {
|
||||||
// For each <browser> element being restored, records the current epoch.
|
// For each <browser> element being restored, records the current epoch.
|
||||||
_browserEpochs: new WeakMap(),
|
_browserEpochs: new WeakMap(),
|
||||||
|
|
||||||
|
// Any browsers that fires the oop-browser-crashed event gets stored in
|
||||||
|
// here - that way we know which browsers to ignore messages from (until
|
||||||
|
// they get restored).
|
||||||
|
_crashedBrowsers: new WeakSet(),
|
||||||
|
|
||||||
// whether a setBrowserState call is in progress
|
// whether a setBrowserState call is in progress
|
||||||
_browserSetState: false,
|
_browserSetState: false,
|
||||||
|
|
||||||
|
@ -383,6 +405,8 @@ let SessionStoreInternal = {
|
||||||
Services.obs.addObserver(this, aTopic, true);
|
Services.obs.addObserver(this, aTopic, true);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
PPMM_MESSAGES.forEach(msg => ppmm.addMessageListener(msg, this));
|
||||||
|
|
||||||
this._initPrefs();
|
this._initPrefs();
|
||||||
this._initialized = true;
|
this._initialized = true;
|
||||||
},
|
},
|
||||||
|
@ -509,6 +533,8 @@ let SessionStoreInternal = {
|
||||||
|
|
||||||
// Make sure to cancel pending saves.
|
// Make sure to cancel pending saves.
|
||||||
SessionSaver.cancel();
|
SessionSaver.cancel();
|
||||||
|
|
||||||
|
PPMM_MESSAGES.forEach(msg => ppmm.removeMessageListener(msg, this));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -551,9 +577,18 @@ let SessionStoreInternal = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method handles incoming messages sent by the session store content
|
* This method handles incoming messages sent by the session store content
|
||||||
* script and thus enables communication with OOP tabs.
|
* script via the Frame Message Manager or Parent Process Message Manager,
|
||||||
|
* and thus enables communication with OOP tabs.
|
||||||
*/
|
*/
|
||||||
receiveMessage: function ssi_receiveMessage(aMessage) {
|
receiveMessage(aMessage) {
|
||||||
|
// We'll deal with any Parent Process Message Manager messages first...
|
||||||
|
if (aMessage.name == "SessionStore:RemoteTabRevived") {
|
||||||
|
this._crashedBrowsers.delete(aMessage.objects.browser.permanentKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got here, that means we're dealing with a frame message
|
||||||
|
// manager message, so the target will be a <xul:browser>.
|
||||||
var browser = aMessage.target;
|
var browser = aMessage.target;
|
||||||
var win = browser.ownerDocument.defaultView;
|
var win = browser.ownerDocument.defaultView;
|
||||||
let tab = this._getTabForBrowser(browser);
|
let tab = this._getTabForBrowser(browser);
|
||||||
|
@ -567,6 +602,11 @@ let SessionStoreInternal = {
|
||||||
TabState.setSyncHandler(browser, aMessage.objects.handler);
|
TabState.setSyncHandler(browser, aMessage.objects.handler);
|
||||||
break;
|
break;
|
||||||
case "SessionStore:update":
|
case "SessionStore:update":
|
||||||
|
if (this._crashedBrowsers.has(browser.permanentKey)) {
|
||||||
|
// Ignore messages from <browser> elements that have crashed
|
||||||
|
// and not yet been revived.
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.recordTelemetry(aMessage.data.telemetry);
|
this.recordTelemetry(aMessage.data.telemetry);
|
||||||
TabState.update(browser, aMessage.data);
|
TabState.update(browser, aMessage.data);
|
||||||
this.saveStateDelayed(win);
|
this.saveStateDelayed(win);
|
||||||
|
@ -651,7 +691,7 @@ let SessionStoreInternal = {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
debug("received unknown message '" + aMessage.name + "'");
|
debug(`received unknown message '${aMessage.name}'`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -675,7 +715,6 @@ let SessionStoreInternal = {
|
||||||
*/
|
*/
|
||||||
handleEvent: function ssi_handleEvent(aEvent) {
|
handleEvent: function ssi_handleEvent(aEvent) {
|
||||||
var win = aEvent.currentTarget.ownerDocument.defaultView;
|
var win = aEvent.currentTarget.ownerDocument.defaultView;
|
||||||
let browser;
|
|
||||||
switch (aEvent.type) {
|
switch (aEvent.type) {
|
||||||
case "TabOpen":
|
case "TabOpen":
|
||||||
this.onTabAdd(win, aEvent.originalTarget);
|
this.onTabAdd(win, aEvent.originalTarget);
|
||||||
|
@ -700,6 +739,9 @@ let SessionStoreInternal = {
|
||||||
case "SwapDocShells":
|
case "SwapDocShells":
|
||||||
this.saveStateDelayed(win);
|
this.saveStateDelayed(win);
|
||||||
break;
|
break;
|
||||||
|
case "oop-browser-crashed":
|
||||||
|
this._crashedBrowsers.add(aEvent.originalTarget.permanentKey);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
this._clearRestoringWindows();
|
this._clearRestoringWindows();
|
||||||
},
|
},
|
||||||
|
@ -738,7 +780,7 @@ let SessionStoreInternal = {
|
||||||
aWindow.__SSi = this._generateWindowID();
|
aWindow.__SSi = this._generateWindowID();
|
||||||
|
|
||||||
let mm = aWindow.getGroupMessageManager("browsers");
|
let mm = aWindow.getGroupMessageManager("browsers");
|
||||||
MESSAGES.forEach(msg => mm.addMessageListener(msg, this));
|
FMM_MESSAGES.forEach(msg => mm.addMessageListener(msg, this));
|
||||||
|
|
||||||
// Load the frame script after registering listeners.
|
// Load the frame script after registering listeners.
|
||||||
mm.loadFrameScript("chrome://browser/content/content-sessionStore.js", true);
|
mm.loadFrameScript("chrome://browser/content/content-sessionStore.js", true);
|
||||||
|
@ -1067,7 +1109,7 @@ let SessionStoreInternal = {
|
||||||
DyingWindowCache.set(aWindow, winData);
|
DyingWindowCache.set(aWindow, winData);
|
||||||
|
|
||||||
let mm = aWindow.getGroupMessageManager("browsers");
|
let mm = aWindow.getGroupMessageManager("browsers");
|
||||||
MESSAGES.forEach(msg => mm.removeMessageListener(msg, this));
|
FMM_MESSAGES.forEach(msg => mm.removeMessageListener(msg, this));
|
||||||
|
|
||||||
delete aWindow.__SSi;
|
delete aWindow.__SSi;
|
||||||
},
|
},
|
||||||
|
@ -1260,6 +1302,7 @@ let SessionStoreInternal = {
|
||||||
onTabAdd: function ssi_onTabAdd(aWindow, aTab, aNoNotification) {
|
onTabAdd: function ssi_onTabAdd(aWindow, aTab, aNoNotification) {
|
||||||
let browser = aTab.linkedBrowser;
|
let browser = aTab.linkedBrowser;
|
||||||
browser.addEventListener("SwapDocShells", this);
|
browser.addEventListener("SwapDocShells", this);
|
||||||
|
browser.addEventListener("oop-browser-crashed", this);
|
||||||
if (!aNoNotification) {
|
if (!aNoNotification) {
|
||||||
this.saveStateDelayed(aWindow);
|
this.saveStateDelayed(aWindow);
|
||||||
}
|
}
|
||||||
|
@ -1278,6 +1321,7 @@ let SessionStoreInternal = {
|
||||||
let browser = aTab.linkedBrowser;
|
let browser = aTab.linkedBrowser;
|
||||||
delete browser.__SS_data;
|
delete browser.__SS_data;
|
||||||
browser.removeEventListener("SwapDocShells", this);
|
browser.removeEventListener("SwapDocShells", this);
|
||||||
|
browser.removeEventListener("oop-browser-crashed", this);
|
||||||
|
|
||||||
// If this tab was in the middle of restoring or still needs to be restored,
|
// If this tab was in the middle of restoring or still needs to be restored,
|
||||||
// we need to reset that state. If the tab was restoring, we will attempt to
|
// we need to reset that state. If the tab was restoring, we will attempt to
|
||||||
|
@ -1908,6 +1952,35 @@ let SessionStoreInternal = {
|
||||||
LastSession.clear();
|
LastSession.clear();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revive a crashed tab and restore its state from before it crashed.
|
||||||
|
*
|
||||||
|
* @param aTab
|
||||||
|
* A <xul:tab> linked to a crashed browser. This is a no-op if the
|
||||||
|
* browser hasn't actually crashed, or is not associated with a tab.
|
||||||
|
* This function will also throw if the browser happens to be remote.
|
||||||
|
*/
|
||||||
|
reviveCrashedTab(aTab) {
|
||||||
|
if (!aTab) {
|
||||||
|
throw new Error("SessionStore.reviveCrashedTab expected a tab, but got null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
let browser = aTab.linkedBrowser;
|
||||||
|
if (!this._crashedBrowsers.has(browser.permanentKey)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check - the browser to be revived should not be remote
|
||||||
|
// at this point.
|
||||||
|
if (browser.isRemoteBrowser) {
|
||||||
|
throw new Error("SessionStore.reviveCrashedTab: " +
|
||||||
|
"Somehow a crashed browser is still remote.")
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = TabState.collect(aTab);
|
||||||
|
this.restoreTab(aTab, data);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See if aWindow is usable for use when restoring a previous session via
|
* See if aWindow is usable for use when restoring a previous session via
|
||||||
* restoreLastSession. If usable, prepare it for use.
|
* restoreLastSession. If usable, prepare it for use.
|
||||||
|
|
|
@ -29,6 +29,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "SessionHistory",
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
|
XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
|
||||||
"resource:///modules/sessionstore/SessionStorage.jsm");
|
"resource:///modules/sessionstore/SessionStorage.jsm");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||||
|
"@mozilla.org/childprocessmessagemanager;1",
|
||||||
|
"nsISyncMessageSender");
|
||||||
|
|
||||||
Cu.import("resource:///modules/sessionstore/FrameTree.jsm", this);
|
Cu.import("resource:///modules/sessionstore/FrameTree.jsm", this);
|
||||||
let gFrameTree = new FrameTree(this);
|
let gFrameTree = new FrameTree(this);
|
||||||
|
|
||||||
|
@ -711,7 +715,42 @@ ScrollPositionListener.init();
|
||||||
DocShellCapabilitiesListener.init();
|
DocShellCapabilitiesListener.init();
|
||||||
PrivacyListener.init();
|
PrivacyListener.init();
|
||||||
|
|
||||||
|
function handleRevivedTab() {
|
||||||
|
if (!content) {
|
||||||
|
removeEventListener("pagehide", handleRevivedTab);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content.document.documentURI.startsWith("about:tabcrashed")) {
|
||||||
|
if (Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT) {
|
||||||
|
// Sanity check - we'd better be loading this in a non-remote browser.
|
||||||
|
throw new Error("We seem to be navigating away from about:tabcrashed in " +
|
||||||
|
"a non-remote browser. This should really never happen.");
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEventListener("pagehide", handleRevivedTab);
|
||||||
|
|
||||||
|
// We can't send a message using the frame message manager because by
|
||||||
|
// the time we reach the unload event handler, it's "too late", and messages
|
||||||
|
// won't be sent or received. The child-process message manager works though,
|
||||||
|
// despite the fact that we're really running in the parent process.
|
||||||
|
let browser = docShell.chromeEventHandler;
|
||||||
|
cpmm.sendSyncMessage("SessionStore:RemoteTabRevived", null, {browser: browser});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're browsing from the tab crashed UI to a blacklisted URI that keeps
|
||||||
|
// this browser non-remote, we'll handle that in a pagehide event.
|
||||||
|
addEventListener("pagehide", handleRevivedTab);
|
||||||
|
|
||||||
addEventListener("unload", () => {
|
addEventListener("unload", () => {
|
||||||
|
// If we're browsing from the tab crashed UI to a URI that causes the tab
|
||||||
|
// to go remote again, we catch this in the unload event handler, because
|
||||||
|
// swapping out the non-remote browser for a remote one in
|
||||||
|
// tabbrowser.xml's updateBrowserRemoteness doesn't cause the pagehide
|
||||||
|
// event to be fired.
|
||||||
|
handleRevivedTab();
|
||||||
|
|
||||||
// Remove all registered nsIObservers.
|
// Remove all registered nsIObservers.
|
||||||
PageStyleListener.uninit();
|
PageStyleListener.uninit();
|
||||||
SessionStorageListener.uninit();
|
SessionStorageListener.uninit();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
skip-if = e10s # Most of these tests fail due to Bug ?????? - SessionStore is disabled in e10s
|
|
||||||
support-files =
|
support-files =
|
||||||
dummy_page.html
|
dummy_page.html
|
||||||
head.js
|
head.js
|
||||||
|
@ -23,6 +22,7 @@ skip-if = buildapp == 'mulet'
|
||||||
[browser_tabview_bug587990.js]
|
[browser_tabview_bug587990.js]
|
||||||
[browser_tabview_bug588265.js]
|
[browser_tabview_bug588265.js]
|
||||||
[browser_tabview_bug589324.js]
|
[browser_tabview_bug589324.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug590606.js]
|
[browser_tabview_bug590606.js]
|
||||||
[browser_tabview_bug591706.js]
|
[browser_tabview_bug591706.js]
|
||||||
[browser_tabview_bug593283.js]
|
[browser_tabview_bug593283.js]
|
||||||
|
@ -36,6 +36,7 @@ skip-if = buildapp == 'mulet'
|
||||||
[browser_tabview_bug595930.js]
|
[browser_tabview_bug595930.js]
|
||||||
[browser_tabview_bug595943.js]
|
[browser_tabview_bug595943.js]
|
||||||
[browser_tabview_bug595965.js]
|
[browser_tabview_bug595965.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug596781.js]
|
[browser_tabview_bug596781.js]
|
||||||
[browser_tabview_bug597360.js]
|
[browser_tabview_bug597360.js]
|
||||||
[browser_tabview_bug597399.js]
|
[browser_tabview_bug597399.js]
|
||||||
|
@ -48,6 +49,7 @@ skip-if = true # Bug 711907
|
||||||
skip-if = os == 'linux' || e10s # Disabled on Linux: Bug 939620, much fail, so amaze; Disabled for e10s: Bug ??????
|
skip-if = os == 'linux' || e10s # Disabled on Linux: Bug 939620, much fail, so amaze; Disabled for e10s: Bug ??????
|
||||||
[browser_tabview_bug600645.js]
|
[browser_tabview_bug600645.js]
|
||||||
[browser_tabview_bug600812.js]
|
[browser_tabview_bug600812.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug602432.js]
|
[browser_tabview_bug602432.js]
|
||||||
skip-if = true # Bug 704417
|
skip-if = true # Bug 704417
|
||||||
[browser_tabview_bug604098.js]
|
[browser_tabview_bug604098.js]
|
||||||
|
@ -56,6 +58,7 @@ skip-if = true # Bug 704417
|
||||||
[browser_tabview_bug607108.js]
|
[browser_tabview_bug607108.js]
|
||||||
skip-if = os == 'linux' # Bug 947521
|
skip-if = os == 'linux' # Bug 947521
|
||||||
[browser_tabview_bug608037.js]
|
[browser_tabview_bug608037.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug608153.js]
|
[browser_tabview_bug608153.js]
|
||||||
[browser_tabview_bug608158.js]
|
[browser_tabview_bug608158.js]
|
||||||
[browser_tabview_bug608184.js]
|
[browser_tabview_bug608184.js]
|
||||||
|
@ -67,6 +70,7 @@ skip-if = true # Bug 736036
|
||||||
[browser_tabview_bug613541.js]
|
[browser_tabview_bug613541.js]
|
||||||
skip-if = os == "win" # Bug 951477
|
skip-if = os == "win" # Bug 951477
|
||||||
[browser_tabview_bug616729.js]
|
[browser_tabview_bug616729.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug616967.js]
|
[browser_tabview_bug616967.js]
|
||||||
[browser_tabview_bug618816.js]
|
[browser_tabview_bug618816.js]
|
||||||
[browser_tabview_bug618828.js]
|
[browser_tabview_bug618828.js]
|
||||||
|
@ -74,12 +78,14 @@ skip-if = buildapp == 'mulet'
|
||||||
[browser_tabview_bug619937.js]
|
[browser_tabview_bug619937.js]
|
||||||
[browser_tabview_bug622835.js]
|
[browser_tabview_bug622835.js]
|
||||||
[browser_tabview_bug623768.js]
|
[browser_tabview_bug623768.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug624265_perwindowpb.js]
|
[browser_tabview_bug624265_perwindowpb.js]
|
||||||
skip-if = true # Bug 921984, hopefully fixed by bug 930202
|
skip-if = true # Bug 921984, hopefully fixed by bug 930202
|
||||||
[browser_tabview_bug624692.js]
|
[browser_tabview_bug624692.js]
|
||||||
[browser_tabview_bug624727_perwindowpb.js]
|
[browser_tabview_bug624727_perwindowpb.js]
|
||||||
skip-if = buildapp == 'mulet'
|
skip-if = buildapp == 'mulet'
|
||||||
[browser_tabview_bug624847.js]
|
[browser_tabview_bug624847.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug624931.js]
|
[browser_tabview_bug624931.js]
|
||||||
[browser_tabview_bug624953.js]
|
[browser_tabview_bug624953.js]
|
||||||
[browser_tabview_bug625195.js]
|
[browser_tabview_bug625195.js]
|
||||||
|
@ -87,7 +93,9 @@ skip-if = buildapp == 'mulet'
|
||||||
[browser_tabview_bug625424.js]
|
[browser_tabview_bug625424.js]
|
||||||
[browser_tabview_bug625955.js]
|
[browser_tabview_bug625955.js]
|
||||||
[browser_tabview_bug626368.js]
|
[browser_tabview_bug626368.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug626455.js]
|
[browser_tabview_bug626455.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug626525.js]
|
[browser_tabview_bug626525.js]
|
||||||
[browser_tabview_bug626791.js]
|
[browser_tabview_bug626791.js]
|
||||||
skip-if = buildapp == 'mulet'
|
skip-if = buildapp == 'mulet'
|
||||||
|
@ -133,6 +141,7 @@ skip-if = true # Bug 754222
|
||||||
[browser_tabview_bug656778.js]
|
[browser_tabview_bug656778.js]
|
||||||
skip-if = os == "mac" # Bug 946918
|
skip-if = os == "mac" # Bug 946918
|
||||||
[browser_tabview_bug656913.js]
|
[browser_tabview_bug656913.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_bug659594.js]
|
[browser_tabview_bug659594.js]
|
||||||
skip-if = os == "mac" || e10s # mac: Bug 939617; e10s - Bug ?????? - "leaked until shutdown [nsGlobalWindow #82 about:blank]"
|
skip-if = os == "mac" || e10s # mac: Bug 939617; e10s - Bug ?????? - "leaked until shutdown [nsGlobalWindow #82 about:blank]"
|
||||||
[browser_tabview_bug662266.js]
|
[browser_tabview_bug662266.js]
|
||||||
|
@ -173,6 +182,7 @@ skip-if = buildapp == 'mulet'
|
||||||
skip-if = os == "mac" || os == "win" # Bug 945687
|
skip-if = os == "mac" || os == "win" # Bug 945687
|
||||||
[browser_tabview_launch.js]
|
[browser_tabview_launch.js]
|
||||||
[browser_tabview_multiwindow_search.js]
|
[browser_tabview_multiwindow_search.js]
|
||||||
|
skip-if = e10s # Bug 1086190
|
||||||
[browser_tabview_pending_tabs.js]
|
[browser_tabview_pending_tabs.js]
|
||||||
[browser_tabview_privatebrowsing_perwindowpb.js]
|
[browser_tabview_privatebrowsing_perwindowpb.js]
|
||||||
skip-if = os == 'linux' || e10s # linux: Bug 944300; e10s: bug ?????? - "leaked until shutdown [nsGlobalWindow #82 about:blank]"
|
skip-if = os == 'linux' || e10s # linux: Bug 944300; e10s: bug ?????? - "leaked until shutdown [nsGlobalWindow #82 about:blank]"
|
||||||
|
|
|
@ -63,9 +63,8 @@ function endGame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function newWindowWithTabView(callback, completeCallback) {
|
function newWindowWithTabView(callback, completeCallback) {
|
||||||
let charsetArg = "charset=" + window.content.document.characterSet;
|
|
||||||
let win = window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no,height=800,width=800",
|
let win = window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no,height=800,width=800",
|
||||||
"about:blank", charsetArg, null, null, true);
|
"about:blank", null, null, null, true);
|
||||||
let onLoad = function() {
|
let onLoad = function() {
|
||||||
win.removeEventListener("load", onLoad, false);
|
win.removeEventListener("load", onLoad, false);
|
||||||
let onShown = function() {
|
let onShown = function() {
|
||||||
|
|
|
@ -9,10 +9,9 @@ function animateZoom() prefsBranch.getBoolPref("animate_zoom");
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
waitForExplicitFinish();
|
waitForExplicitFinish();
|
||||||
|
|
||||||
let charsetArg = "charset=" + window.content.document.characterSet;
|
|
||||||
let win = window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no",
|
let win = window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no",
|
||||||
"about:blank", charsetArg, null, null, true);
|
"about:blank", null, null, null, true);
|
||||||
|
|
||||||
registerCleanupFunction(function() {
|
registerCleanupFunction(function() {
|
||||||
prefsBranch.setBoolPref("animate_zoom", true);
|
prefsBranch.setBoolPref("animate_zoom", true);
|
||||||
|
|
|
@ -103,7 +103,7 @@ loop-call-button3.label = Hello
|
||||||
loop-call-button3.tooltiptext = Start a conversation
|
loop-call-button3.tooltiptext = Start a conversation
|
||||||
|
|
||||||
social-share-button.label = Share This Page
|
social-share-button.label = Share This Page
|
||||||
social-share-button.tooltiptext = Share This Page
|
social-share-button.tooltiptext = Share this page
|
||||||
|
|
||||||
panic-button.label = Forget
|
panic-button.label = Forget
|
||||||
panic-button.tooltiptext = Forget about some browsing history
|
panic-button.tooltiptext = Forget about some browsing history
|
||||||
|
|
|
@ -87,18 +87,6 @@ this.TabCrashReporter = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
reloadCrashedTab: function (browser) {
|
|
||||||
if (browser.isRemoteBrowser)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let doc = browser.contentDocument;
|
|
||||||
if (!doc.documentURI.startsWith("about:tabcrashed"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
let url = browser.currentURI.spec;
|
|
||||||
browser.loadURIWithFlags(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
|
|
||||||
},
|
|
||||||
|
|
||||||
onAboutTabCrashedLoad: function (aBrowser) {
|
onAboutTabCrashedLoad: function (aBrowser) {
|
||||||
if (!this.childMap)
|
if (!this.childMap)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1937,6 +1937,10 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
|
||||||
background-clip: padding-box;
|
background-clip: padding-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#urlbar[readonly] {
|
||||||
|
background-color: -moz-field;
|
||||||
|
}
|
||||||
|
|
||||||
@media (-moz-mac-lion-theme) {
|
@media (-moz-mac-lion-theme) {
|
||||||
#urlbar,
|
#urlbar,
|
||||||
.searchbar-textbox {
|
.searchbar-textbox {
|
||||||
|
|
|
@ -1536,7 +1536,6 @@ if test "$GNU_CXX"; then
|
||||||
# -Wreturn-type - catches missing returns, zero false positives
|
# -Wreturn-type - catches missing returns, zero false positives
|
||||||
# -Wsequence-point - catches undefined order behavior like `a = a++`
|
# -Wsequence-point - catches undefined order behavior like `a = a++`
|
||||||
# -Wsign-compare - catches comparison of signed and unsigned types
|
# -Wsign-compare - catches comparison of signed and unsigned types
|
||||||
# -Wswitch - catches switches without all enum cases or default case
|
|
||||||
# -Wtrigraphs - catches unlikely use of trigraphs
|
# -Wtrigraphs - catches unlikely use of trigraphs
|
||||||
# -Wtype-limits - catches overflow bugs, few false positives
|
# -Wtype-limits - catches overflow bugs, few false positives
|
||||||
# -Wunused-label - catches unused goto labels
|
# -Wunused-label - catches unused goto labels
|
||||||
|
@ -1555,7 +1554,6 @@ if test "$GNU_CXX"; then
|
||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=pointer-arith"
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=pointer-arith"
|
||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
|
||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=sequence-point"
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=sequence-point"
|
||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=switch"
|
|
||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
|
||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
|
||||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
|
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
|
||||||
|
|
|
@ -143,6 +143,11 @@ public:
|
||||||
return mConsumer.get();
|
return mConsumer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SocketBase* GetSocketBase()
|
||||||
|
{
|
||||||
|
return GetConsumer();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
|
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
|
||||||
* directly from main thread. All non-main-thread accesses should happen with
|
* directly from main thread. All non-main-thread accesses should happen with
|
||||||
|
@ -661,7 +666,8 @@ BluetoothSocket::SendSocketData(UnixSocketRawData* aData)
|
||||||
MOZ_ASSERT(!mImpl->IsShutdownOnMainThread());
|
MOZ_ASSERT(!mImpl->IsShutdownOnMainThread());
|
||||||
|
|
||||||
XRE_GetIOMessageLoop()->PostTask(
|
XRE_GetIOMessageLoop()->PostTask(
|
||||||
FROM_HERE, new SocketIOSendTask<DroidSocketImpl>(mImpl, aData));
|
FROM_HERE,
|
||||||
|
new SocketIOSendTask<DroidSocketImpl, UnixSocketRawData>(mImpl, aData));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,11 @@ public:
|
||||||
return mConsumer.get();
|
return mConsumer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SocketBase* GetSocketBase()
|
||||||
|
{
|
||||||
|
return GetConsumer();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
|
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
|
||||||
* directly from main thread. All non-main-thread accesses should happen with
|
* directly from main thread. All non-main-thread accesses should happen with
|
||||||
|
@ -661,7 +666,7 @@ BluetoothSocket::SendSocketData(UnixSocketRawData* aData)
|
||||||
MOZ_ASSERT(!mImpl->IsShutdownOnMainThread());
|
MOZ_ASSERT(!mImpl->IsShutdownOnMainThread());
|
||||||
|
|
||||||
XRE_GetIOMessageLoop()->PostTask(
|
XRE_GetIOMessageLoop()->PostTask(
|
||||||
FROM_HERE, new SocketIOSendTask<DroidSocketImpl>(mImpl, aData));
|
FROM_HERE, new SocketIOSendTask<DroidSocketImpl, UnixSocketRawData>(mImpl, aData));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,7 +216,7 @@ let FormAssistant = {
|
||||||
'range'
|
'range'
|
||||||
]),
|
]),
|
||||||
|
|
||||||
isKeyboardOpened: false,
|
isHandlingFocus: false,
|
||||||
selectionStart: -1,
|
selectionStart: -1,
|
||||||
selectionEnd: -1,
|
selectionEnd: -1,
|
||||||
textBeforeCursor: "",
|
textBeforeCursor: "",
|
||||||
|
@ -304,7 +304,7 @@ let FormAssistant = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (del && element === self.focusedElement) {
|
if (del && element === self.focusedElement) {
|
||||||
self.hideKeyboard();
|
self.unhandleFocus();
|
||||||
self.selectionStart = -1;
|
self.selectionStart = -1;
|
||||||
self.selectionEnd = -1;
|
self.selectionEnd = -1;
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ let FormAssistant = {
|
||||||
if (this._editing) {
|
if (this._editing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.sendKeyboardState(this.focusedElement);
|
this.sendInputState(this.focusedElement);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleEvent: function fa_handleEvent(evt) {
|
handleEvent: function fa_handleEvent(evt) {
|
||||||
|
@ -379,13 +379,13 @@ let FormAssistant = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isContentEditable(target)) {
|
if (isContentEditable(target)) {
|
||||||
this.showKeyboard(this.getTopLevelEditable(target));
|
this.handleFocus(this.getTopLevelEditable(target));
|
||||||
this.updateSelection();
|
this.updateSelection();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isFocusableElement(target)) {
|
if (this.isFocusableElement(target)) {
|
||||||
this.showKeyboard(target);
|
this.handleFocus(target);
|
||||||
this.updateSelection();
|
this.updateSelection();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -406,14 +406,14 @@ let FormAssistant = {
|
||||||
|
|
||||||
case "blur":
|
case "blur":
|
||||||
if (this.focusedElement) {
|
if (this.focusedElement) {
|
||||||
this.hideKeyboard();
|
this.unhandleFocus();
|
||||||
this.selectionStart = -1;
|
this.selectionStart = -1;
|
||||||
this.selectionEnd = -1;
|
this.selectionEnd = -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "resize":
|
case "resize":
|
||||||
if (!this.isKeyboardOpened)
|
if (!this.isHandlingFocus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.scrollIntoViewTimeout) {
|
if (this.scrollIntoViewTimeout) {
|
||||||
|
@ -672,7 +672,7 @@ let FormAssistant = {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
showKeyboard: function fa_showKeyboard(target) {
|
handleFocus: function fa_handleFocus(target) {
|
||||||
if (this.focusedElement === target)
|
if (this.focusedElement === target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -682,18 +682,17 @@ let FormAssistant = {
|
||||||
this.setFocusedElement(target);
|
this.setFocusedElement(target);
|
||||||
|
|
||||||
let count = this._focusCounter;
|
let count = this._focusCounter;
|
||||||
this.waitForNextTick(function fa_showKeyboardSync() {
|
this.waitForNextTick(function fa_handleFocusSync() {
|
||||||
if (count !== this._focusCounter) {
|
if (count !== this._focusCounter) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let kbOpened = this.sendKeyboardState(target);
|
let isHandlingFocus = this.sendInputState(target);
|
||||||
if (this.isTextInputElement(target))
|
this.isHandlingFocus = isHandlingFocus;
|
||||||
this.isKeyboardOpened = kbOpened;
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
hideKeyboard: function fa_hideKeyboard() {
|
unhandleFocus: function fa_unhandleFocus() {
|
||||||
this.setFocusedElement(null);
|
this.setFocusedElement(null);
|
||||||
|
|
||||||
let count = this._focusCounter;
|
let count = this._focusCounter;
|
||||||
|
@ -701,13 +700,13 @@ let FormAssistant = {
|
||||||
// Wait for the next tick before unset the focused element and etc.
|
// Wait for the next tick before unset the focused element and etc.
|
||||||
// If the user move from one input from another,
|
// If the user move from one input from another,
|
||||||
// the remote process should get one Forms:Input message instead of two.
|
// the remote process should get one Forms:Input message instead of two.
|
||||||
this.waitForNextTick(function fa_hideKeyboardSync() {
|
this.waitForNextTick(function fa_unhandleFocusSync() {
|
||||||
if (count !== this._focusCounter ||
|
if (count !== this._focusCounter ||
|
||||||
!this.isKeyboardOpened) {
|
!this.isHandlingFocus) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isKeyboardOpened = false;
|
this.isHandlingFocus = false;
|
||||||
sendAsyncMessage("Forms:Input", { "type": "blur" });
|
sendAsyncMessage("Forms:Input", { "type": "blur" });
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
@ -725,12 +724,6 @@ let FormAssistant = {
|
||||||
!this.ignoredInputTypes.has(element.type));
|
!this.ignoredInputTypes.has(element.type));
|
||||||
},
|
},
|
||||||
|
|
||||||
isTextInputElement: function fa_isTextInputElement(element) {
|
|
||||||
return element instanceof HTMLInputElement ||
|
|
||||||
element instanceof HTMLTextAreaElement ||
|
|
||||||
isContentEditable(element);
|
|
||||||
},
|
|
||||||
|
|
||||||
getTopLevelEditable: function fa_getTopLevelEditable(element) {
|
getTopLevelEditable: function fa_getTopLevelEditable(element) {
|
||||||
function retrieveTopLevelEditable(element) {
|
function retrieveTopLevelEditable(element) {
|
||||||
while (element && !isContentEditable(element))
|
while (element && !isContentEditable(element))
|
||||||
|
@ -742,7 +735,7 @@ let FormAssistant = {
|
||||||
return retrieveTopLevelEditable(element) || element;
|
return retrieveTopLevelEditable(element) || element;
|
||||||
},
|
},
|
||||||
|
|
||||||
sendKeyboardState: function(element) {
|
sendInputState: function(element) {
|
||||||
// FIXME/bug 729623: work around apparent bug in the IME manager
|
// FIXME/bug 729623: work around apparent bug in the IME manager
|
||||||
// in gecko.
|
// in gecko.
|
||||||
let readonly = element.getAttribute("readonly");
|
let readonly = element.getAttribute("readonly");
|
||||||
|
|
|
@ -24,3 +24,4 @@ support-files =
|
||||||
[test_delete_focused_element.html]
|
[test_delete_focused_element.html]
|
||||||
[test_sendkey_cancel.html]
|
[test_sendkey_cancel.html]
|
||||||
[test_two_inputs.html]
|
[test_two_inputs.html]
|
||||||
|
[test_two_selects.html]
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=1079728
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Test switching between two inputs</title>
|
||||||
|
<script type="application/javascript;version=1.7" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript;version=1.7" src="inputmethod_common.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1079728">Mozilla Bug 1079728</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<pre id="test">
|
||||||
|
<script class="testbody" type="application/javascript;version=1.7">
|
||||||
|
|
||||||
|
inputmethod_setup(function() {
|
||||||
|
runTest();
|
||||||
|
});
|
||||||
|
|
||||||
|
let appFrameScript = function appFrameScript() {
|
||||||
|
let select1 = content.document.body.firstElementChild;
|
||||||
|
let select2 = content.document.body.children[1];
|
||||||
|
|
||||||
|
let i = 1;
|
||||||
|
|
||||||
|
select1.focus();
|
||||||
|
|
||||||
|
addMessageListener('test:next', function() {
|
||||||
|
i++;
|
||||||
|
switch (i) {
|
||||||
|
case 2:
|
||||||
|
select2.focus();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
select2.blur();
|
||||||
|
select2.focus();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
select2.blur();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
select2.focus();
|
||||||
|
select2.blur();
|
||||||
|
|
||||||
|
select1.focus();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
select1.blur();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
let im = navigator.mozInputMethod;
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
im.oninputcontextchange = function(evt) {
|
||||||
|
var inputcontext = navigator.mozInputMethod.inputcontext;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
switch (i) {
|
||||||
|
// focus on the first input receives the first input context.
|
||||||
|
case 1:
|
||||||
|
ok(!!inputcontext, 'Receving the first input context');
|
||||||
|
is(inputcontext.textAfterCursor, 'First');
|
||||||
|
|
||||||
|
mm.sendAsyncMessage('test:next');
|
||||||
|
break;
|
||||||
|
|
||||||
|
// focus on the second input (implicitly blur the first input)
|
||||||
|
// results the second input context.
|
||||||
|
case 2:
|
||||||
|
ok(!!inputcontext, 'Receving the second input context');
|
||||||
|
is(inputcontext.textAfterCursor, 'Second');
|
||||||
|
|
||||||
|
|
||||||
|
mm.sendAsyncMessage('test:next');
|
||||||
|
break;
|
||||||
|
|
||||||
|
// blur and re-focus on the second input results updated
|
||||||
|
// input context for the second input.
|
||||||
|
case 3:
|
||||||
|
ok(!!inputcontext, 'Receving the second input context');
|
||||||
|
is(inputcontext.textAfterCursor, 'Second');
|
||||||
|
|
||||||
|
mm.sendAsyncMessage('test:next');
|
||||||
|
break;
|
||||||
|
|
||||||
|
// blur on the second input results null input context
|
||||||
|
case 4:
|
||||||
|
is(inputcontext, null, 'Receving null inputcontext');
|
||||||
|
|
||||||
|
mm.sendAsyncMessage('test:next');
|
||||||
|
break;
|
||||||
|
|
||||||
|
// focus and blur on the second input sends no message;
|
||||||
|
// focus on the first input receives the first input context.
|
||||||
|
case 5:
|
||||||
|
ok(!!inputcontext, 'Receving the first input context');
|
||||||
|
is(inputcontext.textAfterCursor, 'First');
|
||||||
|
|
||||||
|
mm.sendAsyncMessage('test:next');
|
||||||
|
break;
|
||||||
|
|
||||||
|
// blur on the first input results null input context
|
||||||
|
case 6:
|
||||||
|
is(inputcontext, null, 'Receving null inputcontext');
|
||||||
|
|
||||||
|
inputmethod_cleanup();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ok(false, 'Receving extra inputcontextchange calls');
|
||||||
|
inputmethod_cleanup();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set current page as an input method.
|
||||||
|
SpecialPowers.wrap(im).setActive(true);
|
||||||
|
|
||||||
|
let iframe = document.createElement('iframe');
|
||||||
|
iframe.src = 'data:text/html,<html><body><select><option>First</option></select><select><option>Second</option></select></html>';
|
||||||
|
iframe.setAttribute('mozbrowser', true);
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
|
||||||
|
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
|
||||||
|
|
||||||
|
iframe.addEventListener('mozbrowserloadend', function() {
|
||||||
|
mm.loadFrameScript('data:,(' + encodeURIComponent(appFrameScript.toString()) + ')();', false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
#define NFCD_MAJOR_VERSION 1
|
#define NFCD_MAJOR_VERSION 1
|
||||||
#define NFCD_MINOR_VERSION 12
|
#define NFCD_MINOR_VERSION 13
|
||||||
|
|
||||||
enum NfcRequest {
|
enum NfcRequest {
|
||||||
ConfigReq = 0,
|
ConfigReq = 0,
|
||||||
|
|
|
@ -25,36 +25,24 @@ this.DEBUG_NFC = false || DEBUG_ALL;
|
||||||
// nfcd error codes
|
// nfcd error codes
|
||||||
this.NFC_SUCCESS = 0;
|
this.NFC_SUCCESS = 0;
|
||||||
this.NFC_ERROR_IO = -1;
|
this.NFC_ERROR_IO = -1;
|
||||||
this.NFC_ERROR_CANCELLED = -2;
|
this.NFC_ERROR_TIMEOUT = -2;
|
||||||
this.NFC_ERROR_TIMEOUT = -3;
|
this.NFC_ERROR_BUSY = -3;
|
||||||
this.NFC_ERROR_BUSY = -4;
|
this.NFC_ERROR_CONNECT = -4;
|
||||||
this.NFC_ERROR_CONNECT = -5;
|
this.NFC_ERROR_DISCONNECT = -5;
|
||||||
this.NFC_ERROR_DISCONNECT = -6;
|
this.NFC_ERROR_READ = -6;
|
||||||
this.NFC_ERROR_READ = -7;
|
this.NFC_ERROR_WRITE = -7;
|
||||||
this.NFC_ERROR_WRITE = -8;
|
this.NFC_ERROR_INVALID_PARAM = -8;
|
||||||
this.NFC_ERROR_INVALID_PARAM = -9;
|
this.NFC_ERROR_INSUFFICIENT_RESOURCES = -9;
|
||||||
this.NFC_ERROR_INSUFFICIENT_RESOURCES = -10;
|
this.NFC_ERROR_SOCKET_CREATION = -10;
|
||||||
this.NFC_ERROR_SOCKET_CREATION = -11;
|
this.NFC_ERROR_FAIL_ENABLE_DISCOVERY = -11;
|
||||||
this.NFC_ERROR_SOCKET_NOT_CONNECTED = -12;
|
this.NFC_ERROR_FAIL_DISABLE_DISCOVERY = -12;
|
||||||
this.NFC_ERROR_BUFFER_TOO_SMALL = -13;
|
this.NFC_ERROR_NOT_INITIALIZED = -13;
|
||||||
this.NFC_ERROR_SAP_USED = -14;
|
this.NFC_ERROR_INITIALIZE_FAIL = -14;
|
||||||
this.NFC_ERROR_SERVICE_NAME_USED = -15;
|
this.NFC_ERROR_DEINITIALIZE_FAIL = -15;
|
||||||
this.NFC_ERROR_SOCKET_OPTIONS = -16;
|
this.NFC_ERROR_NOT_SUPPORTED = -16;
|
||||||
this.NFC_ERROR_FAIL_ENABLE_DISCOVERY = -17;
|
this.NFC_ERROR_BAD_SESSION_ID = -17,
|
||||||
this.NFC_ERROR_FAIL_DISABLE_DISCOVERY = -18;
|
this.NFC_ERROR_FAIL_ENABLE_LOW_POWER_MODE = -18;
|
||||||
this.NFC_ERROR_NOT_INITIALIZED = -19;
|
this.NFC_ERROR_FAIL_DISABLE_LOW_POWER_MODE = -19;
|
||||||
this.NFC_ERROR_INITIALIZE_FAIL = -20;
|
|
||||||
this.NFC_ERROR_DEINITIALIZE_FAIL = -21;
|
|
||||||
this.NFC_ERROR_SE_CONNECTED = -22;
|
|
||||||
this.NFC_ERROR_NO_SE_CONNECTED = -23;
|
|
||||||
this.NFC_ERROR_NOT_SUPPORTED = -24;
|
|
||||||
this.NFC_ERROR_BAD_SESSION_ID = -25;
|
|
||||||
this.NFC_ERROR_LOST_TECH = -26;
|
|
||||||
this.NFC_ERROR_BAD_TECH_TYPE = -27;
|
|
||||||
this.NFC_ERROR_SELECT_SE_FAIL = -28;
|
|
||||||
this.NFC_ERROR_DESELECT_SE_FAIL = -29;
|
|
||||||
this.NFC_ERROR_FAIL_ENABLE_LOW_POWER_MODE = -30;
|
|
||||||
this.NFC_ERROR_FAIL_DISABLE_LOW_POWER_MODE = -31;
|
|
||||||
|
|
||||||
// Gecko specific error codes
|
// Gecko specific error codes
|
||||||
this.NFC_GECKO_ERROR_GENERIC_FAILURE = 1;
|
this.NFC_GECKO_ERROR_GENERIC_FAILURE = 1;
|
||||||
|
@ -64,7 +52,6 @@ this.NFC_GECKO_ERROR_SEND_FILE_FAILED = 4;
|
||||||
|
|
||||||
this.NFC_ERROR_MSG = {};
|
this.NFC_ERROR_MSG = {};
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_IO] = "NfcIoError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_IO] = "NfcIoError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_CANCELLED] = "NfcCancelledError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_TIMEOUT] = "NfcTimeoutError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_TIMEOUT] = "NfcTimeoutError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_BUSY] = "NfcBusyError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_BUSY] = "NfcBusyError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_CONNECT] = "NfcConnectError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_CONNECT] = "NfcConnectError";
|
||||||
|
@ -74,24 +61,13 @@ this.NFC_ERROR_MSG[this.NFC_ERROR_WRITE] = "NfcWriteError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_INVALID_PARAM] = "NfcInvalidParamError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_INVALID_PARAM] = "NfcInvalidParamError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_INSUFFICIENT_RESOURCES] = "NfcInsufficentResourcesError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_INSUFFICIENT_RESOURCES] = "NfcInsufficentResourcesError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_SOCKET_CREATION] = "NfcSocketCreationError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_SOCKET_CREATION] = "NfcSocketCreationError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_SOCKET_NOT_CONNECTED] = "NfcSocketNotConntectedError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_BUFFER_TOO_SMALL] = "NfcBufferTooSmallError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_SAP_USED] = "NfcSapUsedError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_SERVICE_NAME_USED] = "NfcServiceNameUsedError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_SOCKET_OPTIONS] = "NfcSocketOptionsError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_FAIL_ENABLE_DISCOVERY] = "NfcFailEnableDiscoveryError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_FAIL_ENABLE_DISCOVERY] = "NfcFailEnableDiscoveryError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_FAIL_DISABLE_DISCOVERY] = "NfcFailDisableDiscoveryError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_FAIL_DISABLE_DISCOVERY] = "NfcFailDisableDiscoveryError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_NOT_INITIALIZED] = "NfcNotInitializedError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_NOT_INITIALIZED] = "NfcNotInitializedError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_INITIALIZE_FAIL] = "NfcInitializeFailError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_INITIALIZE_FAIL] = "NfcInitializeFailError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_DEINITIALIZE_FAIL] = "NfcDeinitializeFailError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_DEINITIALIZE_FAIL] = "NfcDeinitializeFailError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_SE_CONNECTED] = "NfcSeConnectedError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_NO_SE_CONNECTED] = "NfcNoSeConnectedError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_NOT_SUPPORTED] = "NfcNotSupportedError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_NOT_SUPPORTED] = "NfcNotSupportedError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_BAD_SESSION_ID] = "NfcBadSessionIdError";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_BAD_SESSION_ID] = "NfcBadSessionIdError";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_LOST_TECH] = "NfcLostTechError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_BAD_TECH_TYPE] = "NfcBadTechTypeError";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_SELECT_SE_FAIL] = "SelectSecureElementFailed";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_DESELECT_SE_FAIL] = "DeselectSecureElementFailed";
|
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_FAIL_ENABLE_LOW_POWER_MODE] = "EnableLowPowerModeFail";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_FAIL_ENABLE_LOW_POWER_MODE] = "EnableLowPowerModeFail";
|
||||||
this.NFC_ERROR_MSG[this.NFC_ERROR_FAIL_DISABLE_LOW_POWER_MODE] = "DisableLowPowerModeFail";
|
this.NFC_ERROR_MSG[this.NFC_ERROR_FAIL_DISABLE_LOW_POWER_MODE] = "DisableLowPowerModeFail";
|
||||||
this.NFC_ERROR_MSG[this.NFC_GECKO_ERROR_GENERIC_FAILURE] = "NfcGenericFailureError";
|
this.NFC_ERROR_MSG[this.NFC_GECKO_ERROR_GENERIC_FAILURE] = "NfcGenericFailureError";
|
||||||
|
|
|
@ -704,7 +704,9 @@ let SettingsRequestManager = {
|
||||||
removeObserver: function(aMsgMgr) {
|
removeObserver: function(aMsgMgr) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
let principal = this.mmPrincipals.get(aMsgMgr);
|
let principal = this.mmPrincipals.get(aMsgMgr);
|
||||||
debug("Remove observer for " + principal.origin);
|
if (principal) {
|
||||||
|
debug("Remove observer for " + principal.origin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let index = this.children.indexOf(aMsgMgr);
|
let index = this.children.indexOf(aMsgMgr);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
|
@ -745,26 +747,31 @@ let SettingsRequestManager = {
|
||||||
|
|
||||||
removeMessageManager: function(aMsgMgr, aPrincipal) {
|
removeMessageManager: function(aMsgMgr, aPrincipal) {
|
||||||
if (DEBUG) debug("Removing message manager");
|
if (DEBUG) debug("Removing message manager");
|
||||||
|
let msgMgrPrincipal = this.mmPrincipals.get(aMsgMgr);
|
||||||
this.removeObserver(aMsgMgr);
|
this.removeObserver(aMsgMgr);
|
||||||
let closedLockIDs = [];
|
|
||||||
let lockIDs = Object.keys(this.lockInfo);
|
let lockIDs = Object.keys(this.lockInfo);
|
||||||
for (let i in lockIDs) {
|
for (let i in lockIDs) {
|
||||||
let lock = this.lockInfo[lockIDs[i]];
|
let lockId = lockIDs[i];
|
||||||
if (lock._mm == aMsgMgr) {
|
let lock = this.lockInfo[lockId];
|
||||||
|
if (lock._mm === aMsgMgr && msgMgrPrincipal === aPrincipal) {
|
||||||
let is_finalizing = false;
|
let is_finalizing = false;
|
||||||
for (let task_index in lock.tasks) {
|
let task_index;
|
||||||
if (lock.tasks[task_index].operation === "finalize") {
|
// Go in reverse order because finalize should be the last one
|
||||||
|
for (task_index = lock.tasks.length; task_index >= 0; task_index--) {
|
||||||
|
if (lock.tasks[task_index]
|
||||||
|
&& lock.tasks[task_index].operation === "finalize") {
|
||||||
is_finalizing = true;
|
is_finalizing = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!is_finalizing) {
|
if (!is_finalizing) {
|
||||||
this.queueTask("finalize", {lockID: lockIDs[i]}, aPrincipal).then(
|
this.queueTask("finalize", {lockID: lockId}, aPrincipal).then(
|
||||||
function() {
|
function() {
|
||||||
if (DEBUG) debug("Lock " + lockIDs[i] + " with dead message manager finalized");
|
if (DEBUG) debug("Lock " + lockId + " with dead message manager finalized");
|
||||||
},
|
},
|
||||||
function(error) {
|
function(error) {
|
||||||
if (DEBUG) debug("Lock " + lockIDs[i] + " with dead message manager NOT FINALIZED due to error: " + error);
|
if (DEBUG) debug("Lock " + lockId + " with dead message manager NOT FINALIZED due to error: " + error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,3 +23,5 @@ EXTRA_JS_MODULES += [
|
||||||
]
|
]
|
||||||
|
|
||||||
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
|
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
|
||||||
|
|
||||||
|
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const Cu = Components.utils;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||||
|
"@mozilla.org/childprocessmessagemanager;1",
|
||||||
|
"nsIMessageSender");
|
||||||
|
|
||||||
|
let principal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||||
|
let lockID = "{435d2192-4f21-48d4-90b7-285f147a56be}";
|
||||||
|
|
||||||
|
// Helper to start the Settings Request Manager
|
||||||
|
function startSettingsRequestManager() {
|
||||||
|
Cu.import("resource://gre/modules/SettingsRequestManager.jsm");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to add a listener, send message and treat the reply
|
||||||
|
function addAndSend(msg, reply, callback, payload, runNext = true) {
|
||||||
|
let handler = {
|
||||||
|
receiveMessage: function(message) {
|
||||||
|
if (message.name === reply) {
|
||||||
|
cpmm.removeMessageListener(reply, handler);
|
||||||
|
callback(message);
|
||||||
|
if (runNext) {
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cpmm.addMessageListener(reply, handler);
|
||||||
|
cpmm.sendAsyncMessage(msg, payload, undefined, principal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to trigger a Settings:Run message to make the queue progress
|
||||||
|
function send_settingsRun() {
|
||||||
|
let msg = {lockID: lockID, isServiceLock: true};
|
||||||
|
cpmm.sendAsyncMessage("Settings:Run", msg, undefined, principal);
|
||||||
|
}
|
||||||
|
|
||||||
|
function kill_child() {
|
||||||
|
let msg = {lockID: lockID, isServiceLock: true};
|
||||||
|
cpmm.sendAsyncMessage("child-process-shutdown", msg, undefined, principal);
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
do_get_profile();
|
||||||
|
startSettingsRequestManager();
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
add_test(function test_createLock() {
|
||||||
|
let msg = {lockID: lockID, isServiceLock: true};
|
||||||
|
cpmm.sendAsyncMessage("Settings:CreateLock", msg, undefined, principal);
|
||||||
|
cpmm.sendAsyncMessage(
|
||||||
|
"Settings:RegisterForMessages", undefined, undefined, principal);
|
||||||
|
ok(true);
|
||||||
|
run_next_test();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_get_empty() {
|
||||||
|
let requestID = 10;
|
||||||
|
let msgReply = "Settings:Get:OK";
|
||||||
|
let msgHandler = function(message) {
|
||||||
|
equal(requestID, message.data.requestID);
|
||||||
|
equal(lockID, message.data.lockID);
|
||||||
|
ok(Object.keys(message.data.settings).length >= 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
addAndSend("Settings:Get", msgReply, msgHandler, {
|
||||||
|
requestID: requestID,
|
||||||
|
lockID: lockID,
|
||||||
|
name: "language.current"
|
||||||
|
});
|
||||||
|
|
||||||
|
send_settingsRun();
|
||||||
|
});
|
||||||
|
|
||||||
|
add_test(function test_set_get_nonempty() {
|
||||||
|
let settings = { "language.current": "fr-FR:XPC" };
|
||||||
|
let requestIDSet = 20;
|
||||||
|
let msgReplySet = "Settings:Set:OK";
|
||||||
|
let msgHandlerSet = function(message) {
|
||||||
|
equal(requestIDSet, message.data.requestID);
|
||||||
|
equal(lockID, message.data.lockID);
|
||||||
|
};
|
||||||
|
|
||||||
|
addAndSend("Settings:Set", msgReplySet, msgHandlerSet, {
|
||||||
|
requestID: requestIDSet,
|
||||||
|
lockID: lockID,
|
||||||
|
settings: settings
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
let requestIDGet = 25;
|
||||||
|
let msgReplyGet = "Settings:Get:OK";
|
||||||
|
let msgHandlerGet = function(message) {
|
||||||
|
equal(requestIDGet, message.data.requestID);
|
||||||
|
equal(lockID, message.data.lockID);
|
||||||
|
for(let p in settings) {
|
||||||
|
equal(settings[p], message.data.settings[p]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addAndSend("Settings:Get", msgReplyGet, msgHandlerGet, {
|
||||||
|
requestID: requestIDGet,
|
||||||
|
lockID: lockID,
|
||||||
|
name: Object.keys(settings)[0]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set and Get have been push into the queue, let's run
|
||||||
|
send_settingsRun();
|
||||||
|
});
|
||||||
|
|
||||||
|
// This test exposes bug 1076597 behavior
|
||||||
|
add_test(function test_wait_for_finalize() {
|
||||||
|
let settings = { "language.current": "en-US:XPC" };
|
||||||
|
let requestIDSet = 30;
|
||||||
|
let msgReplySet = "Settings:Set:OK";
|
||||||
|
let msgHandlerSet = function(message) {
|
||||||
|
equal(requestIDSet, message.data.requestID);
|
||||||
|
equal(lockID, message.data.lockID);
|
||||||
|
};
|
||||||
|
|
||||||
|
addAndSend("Settings:Set", msgReplySet, msgHandlerSet, {
|
||||||
|
requestID: requestIDSet,
|
||||||
|
lockID: lockID,
|
||||||
|
settings: settings
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
let requestIDGet = 35;
|
||||||
|
let msgReplyGet = "Settings:Get:OK";
|
||||||
|
let msgHandlerGet = function(message) {
|
||||||
|
equal(requestIDGet, message.data.requestID);
|
||||||
|
equal(lockID, message.data.lockID);
|
||||||
|
for(let p in settings) {
|
||||||
|
equal(settings[p], message.data.settings[p]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addAndSend("Settings:Get", msgReplyGet, msgHandlerGet, {
|
||||||
|
requestID: requestIDGet,
|
||||||
|
lockID: lockID,
|
||||||
|
name: Object.keys(settings)[0]
|
||||||
|
});
|
||||||
|
|
||||||
|
// We simulate a child death, which will force previous requests to be set
|
||||||
|
// into finalize state
|
||||||
|
kill_child();
|
||||||
|
|
||||||
|
// Then when we issue Settings:Run, those finalized should be triggered
|
||||||
|
send_settingsRun();
|
||||||
|
});
|
|
@ -0,0 +1,6 @@
|
||||||
|
[DEFAULT]
|
||||||
|
head =
|
||||||
|
tail =
|
||||||
|
|
||||||
|
[test_settingsrequestmanager_messages.js]
|
||||||
|
skip-if = ((buildapp != 'b2g') || ((toolkit == 'gonk') && debug)) # bug 1080377: for some reason, this is not working on emulator-b2g debug build
|
|
@ -348,7 +348,7 @@ function RilObject(aContext) {
|
||||||
|
|
||||||
this.telephonyRequestQueue = new TelephonyRequestQueue(this);
|
this.telephonyRequestQueue = new TelephonyRequestQueue(this);
|
||||||
this.currentCalls = {};
|
this.currentCalls = {};
|
||||||
this.currentConference = {state: null, participants: {}};
|
this.currentConferenceState = CALL_STATE_UNKNOWN;
|
||||||
this.currentDataCalls = {};
|
this.currentDataCalls = {};
|
||||||
this._pendingSentSmsMap = {};
|
this._pendingSentSmsMap = {};
|
||||||
this.pendingNetworkType = {};
|
this.pendingNetworkType = {};
|
||||||
|
@ -375,9 +375,9 @@ RilObject.prototype = {
|
||||||
currentCalls: null,
|
currentCalls: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Existing conference call and its participants.
|
* Call state of current conference group.
|
||||||
*/
|
*/
|
||||||
currentConference: null,
|
currentConferenceState: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Existing data calls.
|
* Existing data calls.
|
||||||
|
@ -1919,24 +1919,11 @@ RilObject.prototype = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Flag indicating whether user has requested making a conference call.
|
|
||||||
_hasConferenceRequest: false,
|
|
||||||
|
|
||||||
conferenceCall: function(options) {
|
conferenceCall: function(options) {
|
||||||
if (this._isCdma) {
|
if (this._isCdma) {
|
||||||
options.featureStr = "";
|
options.featureStr = "";
|
||||||
this.sendCdmaFlashCommand(options);
|
this.sendCdmaFlashCommand(options);
|
||||||
} else {
|
} else {
|
||||||
// Only accept one conference request at a time..
|
|
||||||
if (this._hasConferenceRequest) {
|
|
||||||
options.success = false;
|
|
||||||
options.errorName = "addError";
|
|
||||||
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
|
|
||||||
this.sendChromeMessage(options);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._hasConferenceRequest = true;
|
|
||||||
this.telephonyRequestQueue.push(REQUEST_CONFERENCE,
|
this.telephonyRequestQueue.push(REQUEST_CONFERENCE,
|
||||||
this.sendRilRequestConference, options);
|
this.sendRilRequestConference, options);
|
||||||
}
|
}
|
||||||
|
@ -3833,171 +3820,184 @@ RilObject.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helpers for processing call state and handle the active call.
|
* Classify new calls into three groups: (removed, remained, added).
|
||||||
*/
|
*/
|
||||||
_processCalls: function(newCalls) {
|
_classifyCalls: function(newCalls) {
|
||||||
let conferenceChanged = false;
|
newCalls = newCalls || {};
|
||||||
let clearConferenceRequest = false;
|
|
||||||
|
let removedCalls = [];
|
||||||
|
let remainedCalls = [];
|
||||||
|
let addedCalls = [];
|
||||||
|
|
||||||
// Go through the calls we currently have on file and see if any of them
|
|
||||||
// changed state. Remove them from the newCalls map as we deal with them
|
|
||||||
// so that only new calls remain in the map after we're done.
|
|
||||||
for each (let currentCall in this.currentCalls) {
|
for each (let currentCall in this.currentCalls) {
|
||||||
let newCall;
|
let newCall = newCalls[currentCall.callIndex];
|
||||||
if (newCalls) {
|
|
||||||
newCall = newCalls[currentCall.callIndex];
|
|
||||||
delete newCalls[currentCall.callIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call is no longer reported by the radio. Remove from our map and send
|
|
||||||
// disconnected state change.
|
|
||||||
if (!newCall) {
|
if (!newCall) {
|
||||||
if (this.currentConference.participants[currentCall.callIndex]) {
|
removedCalls.push(currentCall);
|
||||||
conferenceChanged = true;
|
|
||||||
}
|
|
||||||
this._removeVoiceCall(currentCall,
|
|
||||||
currentCall.hangUpLocal ?
|
|
||||||
GECKO_CALL_ERROR_NORMAL_CALL_CLEARING : null);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call is still valid.
|
|
||||||
if (newCall.state == currentCall.state &&
|
|
||||||
newCall.isMpty == currentCall.isMpty) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// State has changed.
|
|
||||||
if (newCall.state == CALL_STATE_INCOMING &&
|
|
||||||
currentCall.state == CALL_STATE_WAITING) {
|
|
||||||
// Update the call internally but we don't notify chrome since these two
|
|
||||||
// states are viewed as the same one there.
|
|
||||||
currentCall.state = newCall.state;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currentCall.started && newCall.state == CALL_STATE_ACTIVE) {
|
|
||||||
currentCall.started = new Date().getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentCall.isMpty == newCall.isMpty &&
|
|
||||||
newCall.state != currentCall.state) {
|
|
||||||
currentCall.state = newCall.state;
|
|
||||||
if (currentCall.isConference) {
|
|
||||||
conferenceChanged = true;
|
|
||||||
}
|
|
||||||
this._handleChangedCallState(currentCall);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// '.isMpty' becomes false when the conference call is put on hold.
|
|
||||||
// We need to introduce additional 'isConference' to correctly record the
|
|
||||||
// real conference status
|
|
||||||
|
|
||||||
// Update a possible conference participant when .isMpty changes.
|
|
||||||
if (!currentCall.isMpty && newCall.isMpty) {
|
|
||||||
if (this._hasConferenceRequest) {
|
|
||||||
conferenceChanged = true;
|
|
||||||
clearConferenceRequest = true;
|
|
||||||
currentCall.state = newCall.state;
|
|
||||||
currentCall.isMpty = newCall.isMpty;
|
|
||||||
currentCall.isConference = true;
|
|
||||||
this.currentConference.participants[currentCall.callIndex] = currentCall;
|
|
||||||
this._handleChangedCallState(currentCall);
|
|
||||||
} else if (currentCall.isConference) {
|
|
||||||
// The case happens when resuming a held conference call.
|
|
||||||
conferenceChanged = true;
|
|
||||||
currentCall.state = newCall.state;
|
|
||||||
currentCall.isMpty = newCall.isMpty;
|
|
||||||
this.currentConference.participants[currentCall.callIndex] = currentCall;
|
|
||||||
this._handleChangedCallState(currentCall);
|
|
||||||
} else {
|
|
||||||
// Weird. This sometimes happens when we switch two calls, but it is
|
|
||||||
// not a conference call.
|
|
||||||
currentCall.state = newCall.state;
|
|
||||||
this._handleChangedCallState(currentCall);
|
|
||||||
}
|
|
||||||
} else if (currentCall.isMpty && !newCall.isMpty) {
|
|
||||||
if (!this.currentConference.participants[newCall.callIndex]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// '.isMpty' of a conference participant is set to false by rild when
|
|
||||||
// the conference call is put on hold. We don't actually know if the call
|
|
||||||
// still attends the conference until updating all calls finishes. We
|
|
||||||
// cache it for further determination.
|
|
||||||
if (newCall.state != CALL_STATE_HOLDING) {
|
|
||||||
delete this.currentConference.participants[newCall.callIndex];
|
|
||||||
currentCall.state = newCall.state;
|
|
||||||
currentCall.isMpty = newCall.isMpty;
|
|
||||||
currentCall.isConference = false;
|
|
||||||
conferenceChanged = true;
|
|
||||||
this._handleChangedCallState(currentCall);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.currentConference.cache) {
|
|
||||||
this.currentConference.cache = {};
|
|
||||||
}
|
|
||||||
this.currentConference.cache[currentCall.callIndex] = newCall;
|
|
||||||
currentCall.state = newCall.state;
|
|
||||||
currentCall.isMpty = newCall.isMpty;
|
|
||||||
conferenceChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have a successful dialing request. Check whether we could find a new
|
|
||||||
// call for it.
|
|
||||||
if (this.pendingMO) {
|
|
||||||
let options = this.pendingMO.options;
|
|
||||||
this.pendingMO = null;
|
|
||||||
|
|
||||||
// Find the callIndex of the new outgoing call.
|
|
||||||
let callIndex = -1;
|
|
||||||
for (let i in newCalls) {
|
|
||||||
if (newCalls[i].state !== CALL_STATE_INCOMING) {
|
|
||||||
callIndex = newCalls[i].callIndex;
|
|
||||||
newCalls[i].isEmergency = options.isEmergency;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (callIndex === -1) {
|
|
||||||
// The call doesn't exist.
|
|
||||||
options.success = false;
|
|
||||||
options.errorMsg = GECKO_CALL_ERROR_UNSPECIFIED;
|
|
||||||
this.sendChromeMessage(options);
|
|
||||||
} else {
|
} else {
|
||||||
options.success = true;
|
remainedCalls.push(newCall);
|
||||||
options.callIndex = callIndex;
|
delete newCalls[currentCall.callIndex];
|
||||||
this.sendChromeMessage(options);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go through any remaining calls that are new to us.
|
// Go through any remaining calls that are new to us.
|
||||||
for each (let newCall in newCalls) {
|
for each (let newCall in newCalls) {
|
||||||
if (!newCall.isVoice) {
|
if (newCall.isVoice) {
|
||||||
|
addedCalls.push(newCall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [removedCalls, remainedCalls, addedCalls];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the calls in addedCalls and assign an appropriate one to pendingMO.
|
||||||
|
* Also update the |isEmergency| on that call.
|
||||||
|
*/
|
||||||
|
_assignPendingMO: function(addedCalls) {
|
||||||
|
let options = this.pendingMO.options;
|
||||||
|
this.pendingMO = null;
|
||||||
|
|
||||||
|
for (let call of addedCalls) {
|
||||||
|
if (call.state !== CALL_STATE_INCOMING) {
|
||||||
|
call.isEmergency = options.isEmergency;
|
||||||
|
options.success = true;
|
||||||
|
options.callIndex = call.callIndex;
|
||||||
|
this.sendChromeMessage(options);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The call doesn't exist.
|
||||||
|
options.success = false;
|
||||||
|
options.errorMsg = GECKO_CALL_ERROR_UNSPECIFIED;
|
||||||
|
this.sendChromeMessage(options);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the currentCalls and identify the conference group.
|
||||||
|
* Return the conference state and the group as a set.
|
||||||
|
*/
|
||||||
|
_detectConference: function() {
|
||||||
|
// There are some difficuties to identify the conference by |.isMpty| so we
|
||||||
|
// don't rely on this flag.
|
||||||
|
// - |.isMpty| becomes false when the conference call is put on hold.
|
||||||
|
// - |.isMpty| may remain true when other participants left the conference.
|
||||||
|
|
||||||
|
// All the calls in the conference should have the same state and it is
|
||||||
|
// either ACTIVE or HOLDING. That means, if we find a group of call with
|
||||||
|
// the same state and its size is larger than 2, it must be a conference.
|
||||||
|
let activeCalls = new Set();
|
||||||
|
let holdingCalls = new Set();
|
||||||
|
|
||||||
|
for each (let call in this.currentCalls) {
|
||||||
|
if (call.state === CALL_STATE_ACTIVE) {
|
||||||
|
activeCalls.add(call);
|
||||||
|
} else if (call.state === CALL_STATE_HOLDING) {
|
||||||
|
holdingCalls.add(call);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeCalls.size >= 2) {
|
||||||
|
return [CALL_STATE_ACTIVE, activeCalls];
|
||||||
|
} else if (holdingCalls.size >= 2) {
|
||||||
|
return [CALL_STATE_HOLDING, holdingCalls];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [CALL_STATE_UNKNOWN, new Set()];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helpers for processing call state changes.
|
||||||
|
*/
|
||||||
|
_processClassifiedCalls: function(removedCalls, remainedCalls, addedCalls,
|
||||||
|
failCause) {
|
||||||
|
// Handle removed calls.
|
||||||
|
for (let call of removedCalls) {
|
||||||
|
this._removeVoiceCall(call, call.hangUpLocal ?
|
||||||
|
GECKO_CALL_ERROR_NORMAL_CALL_CLEARING : failCause);
|
||||||
|
}
|
||||||
|
|
||||||
|
let changedCalls = new Set();
|
||||||
|
|
||||||
|
// Handle remained calls.
|
||||||
|
for (let newCall of remainedCalls) {
|
||||||
|
let oldCall = this.currentCalls[newCall.callIndex];
|
||||||
|
if (oldCall.state == newCall.state) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newCall.isMpty) {
|
if (oldCall.state == CALL_STATE_WAITING &&
|
||||||
conferenceChanged = true;
|
newCall.state == CALL_STATE_INCOMING) {
|
||||||
|
// Update the call internally but we don't notify chrome since these two
|
||||||
|
// states are viewed as the same one there.
|
||||||
|
oldCall.state = newCall.state;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._addNewVoiceCall(newCall);
|
if (!oldCall.started && newCall.state == CALL_STATE_ACTIVE) {
|
||||||
|
oldCall.started = new Date().getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
oldCall.state = newCall.state;
|
||||||
|
changedCalls.add(oldCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clearConferenceRequest) {
|
// Handle pendingMO.
|
||||||
this._hasConferenceRequest = false;
|
if (this.pendingMO) {
|
||||||
}
|
this._assignPendingMO(addedCalls);
|
||||||
if (conferenceChanged) {
|
|
||||||
this._ensureConference();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update audio state.
|
// Handle added calls.
|
||||||
let message = {rilMessageType: "audioStateChanged",
|
for (let call of addedCalls) {
|
||||||
state: this._detectAudioState()};
|
this._addVoiceCall(call);
|
||||||
this.sendChromeMessage(message);
|
changedCalls.add(call);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect conference and update isConference flag.
|
||||||
|
let [newConferenceState, conference] = this._detectConference();
|
||||||
|
for each (let call in this.currentCalls) {
|
||||||
|
let isConference = conference.has(call);
|
||||||
|
if (call.isConference != isConference) {
|
||||||
|
call.isConference = isConference;
|
||||||
|
changedCalls.add(call);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update audio state. We have to send the message before callstatechange
|
||||||
|
// to make sure that the audio state is ready first.
|
||||||
|
this.sendChromeMessage({
|
||||||
|
rilMessageType: "audioStateChanged",
|
||||||
|
state: this._detectAudioState()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Notify call state change.
|
||||||
|
for (let call of changedCalls) {
|
||||||
|
this._handleChangedCallState(call);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify conference state change.
|
||||||
|
if (this.currentConferenceState != newConferenceState) {
|
||||||
|
this.currentConferenceState = newConferenceState;
|
||||||
|
let message = {rilMessageType: "conferenceCallStateChanged",
|
||||||
|
state: newConferenceState};
|
||||||
|
this.sendChromeMessage(message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_processCalls: function(newCalls) {
|
||||||
|
let [removed, remained, added] = this._classifyCalls(newCalls);
|
||||||
|
|
||||||
|
// Let's get the failCause first if there are removed calls. Otherwise, we
|
||||||
|
// need to trigger another async request when removing call and it cause
|
||||||
|
// the order of callDisconnected and conferenceCallStateChanged
|
||||||
|
// unpredictable.
|
||||||
|
if (removed.length) {
|
||||||
|
this.getFailCauseCode((function(removed, remained, added, failCause) {
|
||||||
|
this._processClassifiedCalls(removed, remained, added, failCause);
|
||||||
|
}).bind(this, removed, remained, added));
|
||||||
|
} else {
|
||||||
|
this._processClassifiedCalls(removed, remained, added);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_detectAudioState: function() {
|
_detectAudioState: function() {
|
||||||
|
@ -4015,90 +4015,23 @@ RilObject.prototype = {
|
||||||
return AUDIO_STATE_IN_CALL;
|
return AUDIO_STATE_IN_CALL;
|
||||||
},
|
},
|
||||||
|
|
||||||
_addNewVoiceCall: function(newCall) {
|
_addVoiceCall: function(newCall) {
|
||||||
// Format international numbers appropriately.
|
// Format international numbers appropriately.
|
||||||
if (newCall.number && newCall.toa == TOA_INTERNATIONAL &&
|
if (newCall.number && newCall.toa == TOA_INTERNATIONAL &&
|
||||||
newCall.number[0] != "+") {
|
newCall.number[0] != "+") {
|
||||||
newCall.number = "+" + newCall.number;
|
newCall.number = "+" + newCall.number;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newCall.state == CALL_STATE_INCOMING) {
|
newCall.isOutgoing = !(newCall.state == CALL_STATE_INCOMING);
|
||||||
newCall.isOutgoing = false;
|
newCall.isConference = false;
|
||||||
} else if (newCall.state == CALL_STATE_DIALING) {
|
|
||||||
newCall.isOutgoing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set flag for conference.
|
|
||||||
newCall.isConference = newCall.isMpty ? true : false;
|
|
||||||
|
|
||||||
// Add to our map.
|
|
||||||
if (newCall.isMpty) {
|
|
||||||
this.currentConference.participants[newCall.callIndex] = newCall;
|
|
||||||
}
|
|
||||||
this._handleChangedCallState(newCall);
|
|
||||||
this.currentCalls[newCall.callIndex] = newCall;
|
this.currentCalls[newCall.callIndex] = newCall;
|
||||||
},
|
},
|
||||||
|
|
||||||
_removeVoiceCall: function(removedCall, failCause) {
|
_removeVoiceCall: function(call, failCause) {
|
||||||
if (this.currentConference.participants[removedCall.callIndex]) {
|
delete this.currentCalls[call.callIndex];
|
||||||
removedCall.isConference = false;
|
call.failCause = failCause;
|
||||||
delete this.currentConference.participants[removedCall.callIndex];
|
this._handleDisconnectedCall(call);
|
||||||
delete this.currentCalls[removedCall.callIndex];
|
|
||||||
// We don't query the fail cause here as it triggers another asynchrouns
|
|
||||||
// request that leads to a problem of updating all conferece participants
|
|
||||||
// in one task.
|
|
||||||
this._handleDisconnectedCall(removedCall);
|
|
||||||
} else {
|
|
||||||
delete this.currentCalls[removedCall.callIndex];
|
|
||||||
if (failCause) {
|
|
||||||
removedCall.failCause = failCause;
|
|
||||||
this._handleDisconnectedCall(removedCall);
|
|
||||||
} else {
|
|
||||||
this.getFailCauseCode((function(call, failCause) {
|
|
||||||
call.failCause = failCause;
|
|
||||||
this._handleDisconnectedCall(call);
|
|
||||||
}).bind(this, removedCall));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_ensureConference: function() {
|
|
||||||
let oldState = this.currentConference.state;
|
|
||||||
let remaining = Object.keys(this.currentConference.participants);
|
|
||||||
|
|
||||||
if (remaining.length == 1) {
|
|
||||||
// Remove that if only does one remain in a conference call.
|
|
||||||
let call = this.currentCalls[remaining[0]];
|
|
||||||
call.isConference = false;
|
|
||||||
this._handleChangedCallState(call);
|
|
||||||
delete this.currentConference.participants[call.callIndex];
|
|
||||||
} else if (remaining.length > 1) {
|
|
||||||
for each (let call in this.currentConference.cache) {
|
|
||||||
call.isConference = true;
|
|
||||||
this.currentConference.participants[call.callIndex] = call;
|
|
||||||
this.currentCalls[call.callIndex] = call;
|
|
||||||
this._handleChangedCallState(call);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete this.currentConference.cache;
|
|
||||||
|
|
||||||
// Update the conference call's state.
|
|
||||||
let state = CALL_STATE_UNKNOWN;
|
|
||||||
for each (let call in this.currentConference.participants) {
|
|
||||||
if (state != CALL_STATE_UNKNOWN && state != call.state) {
|
|
||||||
// Each participant should have the same state, otherwise something
|
|
||||||
// wrong happens.
|
|
||||||
state = CALL_STATE_UNKNOWN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
state = call.state;
|
|
||||||
}
|
|
||||||
if (oldState != state) {
|
|
||||||
this.currentConference.state = state;
|
|
||||||
let message = {rilMessageType: "conferenceCallStateChanged",
|
|
||||||
state: state};
|
|
||||||
this.sendChromeMessage(message);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleChangedCallState: function(changedCall) {
|
_handleChangedCallState: function(changedCall) {
|
||||||
|
@ -5528,7 +5461,6 @@ RilObject.prototype[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = function REQ
|
||||||
RilObject.prototype[REQUEST_CONFERENCE] = function REQUEST_CONFERENCE(length, options) {
|
RilObject.prototype[REQUEST_CONFERENCE] = function REQUEST_CONFERENCE(length, options) {
|
||||||
options.success = (options.rilRequestError === 0);
|
options.success = (options.rilRequestError === 0);
|
||||||
if (!options.success) {
|
if (!options.success) {
|
||||||
this._hasConferenceRequest = false;
|
|
||||||
options.errorName = "addError";
|
options.errorName = "addError";
|
||||||
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
||||||
this.sendChromeMessage(options);
|
this.sendChromeMessage(options);
|
||||||
|
|
|
@ -495,6 +495,11 @@ Telephony::CallStateChanged(uint32_t aServiceId, uint32_t aCallIndex,
|
||||||
modifiedCall->UpdateMergeable(aIsMergeable);
|
modifiedCall->UpdateMergeable(aIsMergeable);
|
||||||
|
|
||||||
if (modifiedCall->CallState() != aCallState) {
|
if (modifiedCall->CallState() != aCallState) {
|
||||||
|
if (aCallState == nsITelephonyService::CALL_STATE_DISCONNECTED) {
|
||||||
|
modifiedCall->ChangeStateInternal(aCallState, true);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// We don't fire the statechange event on a call in conference here.
|
// We don't fire the statechange event on a call in conference here.
|
||||||
// Instead, the event will be fired later in
|
// Instead, the event will be fired later in
|
||||||
// TelephonyCallGroup::ChangeState(). Thus the sequence of firing the
|
// TelephonyCallGroup::ChangeState(). Thus the sequence of firing the
|
||||||
|
|
|
@ -227,15 +227,26 @@ let emulator = (function() {
|
||||||
is(call.state, state, "call state");
|
is(call.state, state, "call state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenient helper to compare two call lists. Size should be the same and
|
||||||
|
* order is not important.
|
||||||
|
*/
|
||||||
|
function checkCalls(actualCalls, expectedCalls) {
|
||||||
|
if (actualCalls.length == expectedCalls.length) {
|
||||||
|
let expectedSet = new Set(expectedCalls);
|
||||||
|
for (let i = 0; i < actualCalls.length; ++i) {
|
||||||
|
ok(expectedSet.has(actualCalls[i]), "should contain the call");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenient helper to check mozTelephony.active and mozTelephony.calls.
|
* Convenient helper to check mozTelephony.active and mozTelephony.calls.
|
||||||
*/
|
*/
|
||||||
function checkTelephonyActiveAndCalls(active, calls) {
|
function checkTelephonyActiveAndCalls(active, calls) {
|
||||||
is(telephony.active, active, "telephony.active");
|
is(telephony.active, active, "telephony.active");
|
||||||
is(telephony.calls.length, calls.length, "telephony.calls");
|
is(telephony.calls.length, calls.length, "telephony.calls");
|
||||||
for (let i = 0; i < calls.length; ++i) {
|
checkCalls(telephony.calls, calls);
|
||||||
is(telephony.calls[i], calls[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,9 +256,7 @@ let emulator = (function() {
|
||||||
function checkConferenceStateAndCalls(state, calls) {
|
function checkConferenceStateAndCalls(state, calls) {
|
||||||
is(conference.state, state, "conference.state");
|
is(conference.state, state, "conference.state");
|
||||||
is(conference.calls.length, calls.length, "conference.calls");
|
is(conference.calls.length, calls.length, "conference.calls");
|
||||||
for (let i = 0; i < calls.length; i++) {
|
checkCalls(conference.calls, calls);
|
||||||
is(conference.calls[i], calls[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,10 +15,10 @@ namespace mozilla {
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
//
|
//
|
||||||
// UnixSocketRawData
|
// UnixSocketIOBuffer
|
||||||
//
|
//
|
||||||
|
|
||||||
UnixSocketRawData::UnixSocketRawData(const void* aData, size_t aSize)
|
UnixSocketIOBuffer::UnixSocketIOBuffer(const void* aData, size_t aSize)
|
||||||
: mSize(aSize)
|
: mSize(aSize)
|
||||||
, mOffset(0)
|
, mOffset(0)
|
||||||
, mAvailableSpace(aSize)
|
, mAvailableSpace(aSize)
|
||||||
|
@ -29,14 +29,90 @@ UnixSocketRawData::UnixSocketRawData(const void* aData, size_t aSize)
|
||||||
memcpy(mData, aData, mSize);
|
memcpy(mData, aData, mSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnixSocketRawData::UnixSocketRawData(size_t aSize)
|
UnixSocketIOBuffer::UnixSocketIOBuffer(size_t aAvailableSpace)
|
||||||
: mSize(0)
|
: mSize(0)
|
||||||
, mOffset(0)
|
, mOffset(0)
|
||||||
, mAvailableSpace(aSize)
|
, mAvailableSpace(aAvailableSpace)
|
||||||
{
|
{
|
||||||
mData = new uint8_t[mAvailableSpace];
|
mData = new uint8_t[mAvailableSpace];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnixSocketIOBuffer::~UnixSocketIOBuffer()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
const uint8_t*
|
||||||
|
UnixSocketIOBuffer::Consume(size_t aLen)
|
||||||
|
{
|
||||||
|
if (NS_WARN_IF(GetSize() < aLen)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
uint8_t* data = mData + mOffset;
|
||||||
|
mOffset += aLen;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
UnixSocketIOBuffer::Read(void* aValue, size_t aLen)
|
||||||
|
{
|
||||||
|
const uint8_t* data = Consume(aLen);
|
||||||
|
if (!data) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
memcpy(aValue, data, aLen);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
UnixSocketIOBuffer::Append(size_t aLen)
|
||||||
|
{
|
||||||
|
if (((mAvailableSpace - mSize) < aLen)) {
|
||||||
|
size_t availableSpace = mAvailableSpace + std::max(mAvailableSpace, aLen);
|
||||||
|
uint8_t* data = new uint8_t[availableSpace];
|
||||||
|
memcpy(data, mData, mSize);
|
||||||
|
mData = data;
|
||||||
|
mAvailableSpace = availableSpace;
|
||||||
|
}
|
||||||
|
uint8_t* data = mData + mSize;
|
||||||
|
mSize += aLen;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
UnixSocketIOBuffer::Write(const void* aValue, size_t aLen)
|
||||||
|
{
|
||||||
|
uint8_t* data = Append(aLen);
|
||||||
|
if (!data) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
memcpy(data, aValue, aLen);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UnixSocketIOBuffer::CleanupLeadingSpace()
|
||||||
|
{
|
||||||
|
if (GetLeadingSpace()) {
|
||||||
|
if (GetSize() <= GetLeadingSpace()) {
|
||||||
|
memcpy(mData, GetData(), GetSize());
|
||||||
|
} else {
|
||||||
|
memmove(mData, GetData(), GetSize());
|
||||||
|
}
|
||||||
|
mOffset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// UnixSocketRawData
|
||||||
|
//
|
||||||
|
|
||||||
|
UnixSocketRawData::UnixSocketRawData(const void* aData, size_t aSize)
|
||||||
|
: UnixSocketIOBuffer(aData, aSize)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
UnixSocketRawData::UnixSocketRawData(size_t aSize)
|
||||||
|
: UnixSocketIOBuffer(aSize)
|
||||||
|
{ }
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
UnixSocketRawData::Receive(int aFd)
|
UnixSocketRawData::Receive(int aFd)
|
||||||
{
|
{
|
||||||
|
@ -45,12 +121,7 @@ UnixSocketRawData::Receive(int aFd)
|
||||||
return -1; /* buffer is full */
|
return -1; /* buffer is full */
|
||||||
}
|
}
|
||||||
/* free up space at the end of data buffer */
|
/* free up space at the end of data buffer */
|
||||||
if (GetSize() <= GetLeadingSpace()) {
|
CleanupLeadingSpace();
|
||||||
memcpy(mData, GetData(), GetSize());
|
|
||||||
} else {
|
|
||||||
memmove(mData, GetData(), GetSize());
|
|
||||||
}
|
|
||||||
mOffset = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t res =
|
ssize_t res =
|
||||||
|
@ -64,7 +135,7 @@ UnixSocketRawData::Receive(int aFd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSize += res;
|
Append(res); /* mark read data as 'valid' */
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -94,16 +165,16 @@ UnixSocketRawData::Send(int aFd)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// SocketConsumerBase
|
// SocketBase
|
||||||
//
|
//
|
||||||
|
|
||||||
SocketConsumerBase::~SocketConsumerBase()
|
SocketBase::~SocketBase()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mConnectionStatus == SOCKET_DISCONNECTED);
|
MOZ_ASSERT(mConnectionStatus == SOCKET_DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketConnectionStatus
|
SocketConnectionStatus
|
||||||
SocketConsumerBase::GetConnectionStatus() const
|
SocketBase::GetConnectionStatus() const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
@ -111,7 +182,7 @@ SocketConsumerBase::GetConnectionStatus() const
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SocketConsumerBase::GetSuggestedConnectDelayMs() const
|
SocketBase::GetSuggestedConnectDelayMs() const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
@ -119,7 +190,7 @@ SocketConsumerBase::GetSuggestedConnectDelayMs() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SocketConsumerBase::NotifySuccess()
|
SocketBase::NotifySuccess()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
@ -129,7 +200,7 @@ SocketConsumerBase::NotifySuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SocketConsumerBase::NotifyError()
|
SocketBase::NotifyError()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
@ -140,7 +211,7 @@ SocketConsumerBase::NotifyError()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SocketConsumerBase::NotifyDisconnect()
|
SocketBase::NotifyDisconnect()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
@ -151,7 +222,7 @@ SocketConsumerBase::NotifyDisconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
SocketConsumerBase::CalculateConnectDelayMs() const
|
SocketBase::CalculateConnectDelayMs() const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
@ -170,19 +241,25 @@ SocketConsumerBase::CalculateConnectDelayMs() const
|
||||||
return connectDelayMs;
|
return connectDelayMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketConsumerBase::SocketConsumerBase()
|
SocketBase::SocketBase()
|
||||||
: mConnectionStatus(SOCKET_DISCONNECTED)
|
: mConnectionStatus(SOCKET_DISCONNECTED)
|
||||||
, mConnectTimestamp(0)
|
, mConnectTimestamp(0)
|
||||||
, mConnectDelayMs(0)
|
, mConnectDelayMs(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void
|
void
|
||||||
SocketConsumerBase::SetConnectionStatus(
|
SocketBase::SetConnectionStatus(SocketConnectionStatus aConnectionStatus)
|
||||||
SocketConnectionStatus aConnectionStatus)
|
|
||||||
{
|
{
|
||||||
mConnectionStatus = aConnectionStatus;
|
mConnectionStatus = aConnectionStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// SocketConsumerBase
|
||||||
|
//
|
||||||
|
|
||||||
|
SocketConsumerBase::~SocketConsumerBase()
|
||||||
|
{ }
|
||||||
|
|
||||||
//
|
//
|
||||||
// SocketIOBase
|
// SocketIOBase
|
||||||
//
|
//
|
||||||
|
|
|
@ -22,11 +22,153 @@ using namespace mozilla::tasktracer;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
|
//
|
||||||
|
// UnixSocketIOBuffer
|
||||||
|
//
|
||||||
|
|
||||||
|
class UnixSocketIOBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const uint8_t* GetData() const
|
||||||
|
{
|
||||||
|
return mData + mOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetSize() const
|
||||||
|
{
|
||||||
|
return mSize - mOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t* Consume(size_t aLen);
|
||||||
|
|
||||||
|
nsresult Read(void* aValue, size_t aLen);
|
||||||
|
|
||||||
|
nsresult Read(int8_t& aValue)
|
||||||
|
{
|
||||||
|
return Read(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Read(uint8_t& aValue)
|
||||||
|
{
|
||||||
|
return Read(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Read(int16_t& aValue)
|
||||||
|
{
|
||||||
|
return Read(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Read(uint16_t& aValue)
|
||||||
|
{
|
||||||
|
return Read(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Read(int32_t& aValue)
|
||||||
|
{
|
||||||
|
return Read(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Read(uint32_t& aValue)
|
||||||
|
{
|
||||||
|
return Read(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* Append(size_t aLen);
|
||||||
|
|
||||||
|
nsresult Write(const void* aValue, size_t aLen);
|
||||||
|
|
||||||
|
nsresult Write(int8_t aValue)
|
||||||
|
{
|
||||||
|
return Write(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Write(uint8_t aValue)
|
||||||
|
{
|
||||||
|
return Write(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Write(int16_t aValue)
|
||||||
|
{
|
||||||
|
return Write(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Write(uint16_t aValue)
|
||||||
|
{
|
||||||
|
return Write(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Write(int32_t aValue)
|
||||||
|
{
|
||||||
|
return Write(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult Write(uint32_t aValue)
|
||||||
|
{
|
||||||
|
return Write(&aValue, sizeof(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* This constructor copies aData of aSize bytes length into the
|
||||||
|
* new instance of |UnixSocketIOBuffer|.
|
||||||
|
*/
|
||||||
|
UnixSocketIOBuffer(const void* aData, size_t aSize);
|
||||||
|
|
||||||
|
/* This constructor reserves aAvailableSpace bytes of space.
|
||||||
|
*/
|
||||||
|
UnixSocketIOBuffer(size_t aAvailableSpace);
|
||||||
|
|
||||||
|
~UnixSocketIOBuffer();
|
||||||
|
|
||||||
|
size_t GetLeadingSpace() const
|
||||||
|
{
|
||||||
|
return mOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetTrailingSpace() const
|
||||||
|
{
|
||||||
|
return mAvailableSpace - mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetAvailableSpace() const
|
||||||
|
{
|
||||||
|
return mAvailableSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* GetTrailingBytes()
|
||||||
|
{
|
||||||
|
return mData + mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* GetData(size_t aOffset)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aOffset <= mSize);
|
||||||
|
|
||||||
|
return mData + aOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRange(size_t aOffset, size_t aSize)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT((aOffset + aSize) <= mAvailableSpace);
|
||||||
|
|
||||||
|
mOffset = aOffset;
|
||||||
|
mSize = mOffset + aSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanupLeadingSpace();
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t mSize;
|
||||||
|
size_t mOffset;
|
||||||
|
size_t mAvailableSpace;
|
||||||
|
nsAutoArrayPtr<uint8_t> mData;
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// UnixSocketRawData
|
// UnixSocketRawData
|
||||||
//
|
//
|
||||||
|
|
||||||
class UnixSocketRawData
|
class UnixSocketRawData MOZ_FINAL : public UnixSocketIOBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/* This constructor copies aData of aSize bytes length into the
|
/* This constructor copies aData of aSize bytes length into the
|
||||||
|
@ -51,51 +193,6 @@ public:
|
||||||
* is the number of bytes written, or a negative value on error.
|
* is the number of bytes written, or a negative value on error.
|
||||||
*/
|
*/
|
||||||
ssize_t Send(int aFd);
|
ssize_t Send(int aFd);
|
||||||
|
|
||||||
const uint8_t* GetData() const
|
|
||||||
{
|
|
||||||
return mData + mOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetSize() const
|
|
||||||
{
|
|
||||||
return mSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Consume(size_t aSize)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(aSize <= mSize);
|
|
||||||
|
|
||||||
mSize -= aSize;
|
|
||||||
mOffset += aSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
size_t GetLeadingSpace() const
|
|
||||||
{
|
|
||||||
return mOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetTrailingSpace() const
|
|
||||||
{
|
|
||||||
return mAvailableSpace - (mOffset + mSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetAvailableSpace() const
|
|
||||||
{
|
|
||||||
return mAvailableSpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* GetTrailingBytes()
|
|
||||||
{
|
|
||||||
return mData + mOffset + mSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t mSize;
|
|
||||||
size_t mOffset;
|
|
||||||
size_t mAvailableSpace;
|
|
||||||
nsAutoArrayPtr<uint8_t> mData;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SocketConnectionStatus {
|
enum SocketConnectionStatus {
|
||||||
|
@ -106,15 +203,15 @@ enum SocketConnectionStatus {
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// SocketConsumerBase
|
// SocketBase
|
||||||
//
|
//
|
||||||
|
|
||||||
class SocketConsumerBase
|
class SocketBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SocketConsumerBase)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SocketBase)
|
||||||
|
|
||||||
virtual ~SocketConsumerBase();
|
virtual ~SocketBase();
|
||||||
|
|
||||||
SocketConnectionStatus GetConnectionStatus() const;
|
SocketConnectionStatus GetConnectionStatus() const;
|
||||||
|
|
||||||
|
@ -126,24 +223,6 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void CloseSocket() = 0;
|
virtual void CloseSocket() = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to be called whenever data is received. This is only called on the
|
|
||||||
* main thread.
|
|
||||||
*
|
|
||||||
* @param aMessage Data received from the socket.
|
|
||||||
*/
|
|
||||||
virtual void ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queue data to be sent to the socket on the IO thread. Can only be called on
|
|
||||||
* originating thread.
|
|
||||||
*
|
|
||||||
* @param aMessage Data to be sent to socket
|
|
||||||
*
|
|
||||||
* @return true if data is queued, false otherwise (i.e. not connected)
|
|
||||||
*/
|
|
||||||
virtual bool SendSocketData(UnixSocketRawData* aMessage) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for socket connect/accept success. Called after connect/accept has
|
* Callback for socket connect/accept success. Called after connect/accept has
|
||||||
* finished. Will be run on main thread, before any reads take place.
|
* finished. Will be run on main thread, before any reads take place.
|
||||||
|
@ -176,7 +255,7 @@ public:
|
||||||
void NotifyDisconnect();
|
void NotifyDisconnect();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SocketConsumerBase();
|
SocketBase();
|
||||||
|
|
||||||
void SetConnectionStatus(SocketConnectionStatus aConnectionStatus);
|
void SetConnectionStatus(SocketConnectionStatus aConnectionStatus);
|
||||||
|
|
||||||
|
@ -188,6 +267,34 @@ private:
|
||||||
uint32_t mConnectDelayMs;
|
uint32_t mConnectDelayMs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// SocketConsumerBase
|
||||||
|
//
|
||||||
|
|
||||||
|
class SocketConsumerBase : public SocketBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~SocketConsumerBase();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to be called whenever data is received. This is only called on the
|
||||||
|
* main thread.
|
||||||
|
*
|
||||||
|
* @param aMessage Data received from the socket.
|
||||||
|
*/
|
||||||
|
virtual void ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue data to be sent to the socket on the IO thread. Can only be called on
|
||||||
|
* originating thread.
|
||||||
|
*
|
||||||
|
* @param aMessage Data to be sent to socket
|
||||||
|
*
|
||||||
|
* @return true if data is queued, false otherwise (i.e. not connected)
|
||||||
|
*/
|
||||||
|
virtual bool SendSocketData(UnixSocketRawData* aMessage) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Socket I/O runnables
|
// Socket I/O runnables
|
||||||
//
|
//
|
||||||
|
@ -249,15 +356,15 @@ public:
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketConsumerBase* consumer = io->GetConsumer();
|
SocketBase* base = io->GetSocketBase();
|
||||||
MOZ_ASSERT(consumer);
|
MOZ_ASSERT(base);
|
||||||
|
|
||||||
if (mEvent == CONNECT_SUCCESS) {
|
if (mEvent == CONNECT_SUCCESS) {
|
||||||
consumer->NotifySuccess();
|
base->NotifySuccess();
|
||||||
} else if (mEvent == CONNECT_ERROR) {
|
} else if (mEvent == CONNECT_ERROR) {
|
||||||
consumer->NotifyError();
|
base->NotifyError();
|
||||||
} else if (mEvent == DISCONNECT) {
|
} else if (mEvent == DISCONNECT) {
|
||||||
consumer->NotifyDisconnect();
|
base->NotifyDisconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -325,10 +432,10 @@ public:
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketConsumerBase* consumer = io->GetConsumer();
|
SocketBase* base = io->GetSocketBase();
|
||||||
MOZ_ASSERT(consumer);
|
MOZ_ASSERT(base);
|
||||||
|
|
||||||
consumer->CloseSocket();
|
base->CloseSocket();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -453,14 +560,14 @@ private:
|
||||||
/* |SocketIOTask| holds a reference to a Socket I/O object. It's
|
/* |SocketIOTask| holds a reference to a Socket I/O object. It's
|
||||||
* supposed to run on the I/O thread.
|
* supposed to run on the I/O thread.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template<typename Tio>
|
||||||
class SocketIOTask : public CancelableTask
|
class SocketIOTask : public CancelableTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~SocketIOTask()
|
virtual ~SocketIOTask()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
T* GetIO() const
|
Tio* GetIO() const
|
||||||
{
|
{
|
||||||
return mIO;
|
return mIO;
|
||||||
}
|
}
|
||||||
|
@ -476,25 +583,26 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SocketIOTask(T* aIO)
|
SocketIOTask(Tio* aIO)
|
||||||
: mIO(aIO)
|
: mIO(aIO)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mIO);
|
MOZ_ASSERT(mIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T* mIO;
|
Tio* mIO;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* |SocketIOSendTask| transfers an instance of |UnixSocketRawData| to
|
/* |SocketIOSendTask| transfers an instance of |Tdata|, such as
|
||||||
* the I/O thread and queues it up for sending the contained data.
|
* |UnixSocketRawData|, to the I/O thread and queues it up for
|
||||||
|
* sending the contained data.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template<typename Tio, typename Tdata>
|
||||||
class SocketIOSendTask MOZ_FINAL : public SocketIOTask<T>
|
class SocketIOSendTask MOZ_FINAL : public SocketIOTask<Tio>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SocketIOSendTask(T* aIO, UnixSocketRawData* aData)
|
SocketIOSendTask(Tio* aIO, Tdata* aData)
|
||||||
: SocketIOTask<T>(aIO)
|
: SocketIOTask<Tio>(aIO)
|
||||||
, mData(aData)
|
, mData(aData)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aData);
|
MOZ_ASSERT(aData);
|
||||||
|
@ -503,34 +611,34 @@ public:
|
||||||
void Run() MOZ_OVERRIDE
|
void Run() MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
MOZ_ASSERT(!SocketIOTask<T>::IsCanceled());
|
MOZ_ASSERT(!SocketIOTask<Tio>::IsCanceled());
|
||||||
|
|
||||||
T* io = SocketIOTask<T>::GetIO();
|
Tio* io = SocketIOTask<Tio>::GetIO();
|
||||||
MOZ_ASSERT(!io->IsShutdownOnIOThread());
|
MOZ_ASSERT(!io->IsShutdownOnIOThread());
|
||||||
|
|
||||||
io->Send(mData);
|
io->Send(mData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UnixSocketRawData* mData;
|
Tdata* mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* |SocketIOShutdownTask| signals shutdown to the Socket I/O object on
|
/* |SocketIOShutdownTask| signals shutdown to the Socket I/O object on
|
||||||
* the I/O thread and sends it to the main thread for destruction.
|
* the I/O thread and sends it to the main thread for destruction.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template<typename Tio>
|
||||||
class SocketIOShutdownTask MOZ_FINAL : public SocketIOTask<T>
|
class SocketIOShutdownTask MOZ_FINAL : public SocketIOTask<Tio>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SocketIOShutdownTask(T* aIO)
|
SocketIOShutdownTask(Tio* aIO)
|
||||||
: SocketIOTask<T>(aIO)
|
: SocketIOTask<Tio>(aIO)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void Run() MOZ_OVERRIDE
|
void Run() MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
T* io = SocketIOTask<T>::GetIO();
|
Tio* io = SocketIOTask<Tio>::GetIO();
|
||||||
|
|
||||||
// At this point, there should be no new events on the I/O thread
|
// At this point, there should be no new events on the I/O thread
|
||||||
// after this one with the possible exception of an accept task,
|
// after this one with the possible exception of an accept task,
|
||||||
|
@ -539,7 +647,7 @@ public:
|
||||||
// |io| safely knowing that it's not reference any longer.
|
// |io| safely knowing that it's not reference any longer.
|
||||||
io->ShutdownOnIOThread();
|
io->ShutdownOnIOThread();
|
||||||
|
|
||||||
nsRefPtr<nsRunnable> r = new SocketIODeleteInstanceRunnable<T>(io);
|
nsRefPtr<nsRunnable> r = new SocketIODeleteInstanceRunnable<Tio>(io);
|
||||||
nsresult rv = NS_DispatchToMainThread(r);
|
nsresult rv = NS_DispatchToMainThread(r);
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
NS_ENSURE_SUCCESS_VOID(rv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
|
|
||||||
void GetSocketAddr(nsAString& aAddrStr) const;
|
void GetSocketAddr(nsAString& aAddrStr) const;
|
||||||
SocketConsumerBase* GetConsumer();
|
SocketConsumerBase* GetConsumer();
|
||||||
|
SocketBase* GetSocketBase();
|
||||||
|
|
||||||
// Shutdown state
|
// Shutdown state
|
||||||
//
|
//
|
||||||
|
@ -157,6 +158,12 @@ UnixSocketConsumerIO::GetConsumer()
|
||||||
return mConsumer.get();
|
return mConsumer.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SocketBase*
|
||||||
|
UnixSocketConsumerIO::GetSocketBase()
|
||||||
|
{
|
||||||
|
return GetConsumer();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
UnixSocketConsumerIO::IsShutdownOnMainThread() const
|
UnixSocketConsumerIO::IsShutdownOnMainThread() const
|
||||||
{
|
{
|
||||||
|
@ -548,7 +555,8 @@ UnixSocketConsumer::SendSocketData(UnixSocketRawData* aData)
|
||||||
|
|
||||||
MOZ_ASSERT(!mIO->IsShutdownOnMainThread());
|
MOZ_ASSERT(!mIO->IsShutdownOnMainThread());
|
||||||
XRE_GetIOMessageLoop()->PostTask(
|
XRE_GetIOMessageLoop()->PostTask(
|
||||||
FROM_HERE, new SocketIOSendTask<UnixSocketConsumerIO>(mIO, aData));
|
FROM_HERE,
|
||||||
|
new SocketIOSendTask<UnixSocketConsumerIO, UnixSocketRawData>(mIO, aData));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ function init() {
|
||||||
|
|
||||||
// Fill "Last visited site" input with most recent history entry URL.
|
// Fill "Last visited site" input with most recent history entry URL.
|
||||||
Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
|
Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
|
||||||
|
aData = aData.substring(0, 200);
|
||||||
document.getElementById("last-url").value = aData;
|
document.getElementById("last-url").value = aData;
|
||||||
// Enable the parent div iff the URL is valid.
|
// Enable the parent div iff the URL is valid.
|
||||||
if (aData.length != 0) {
|
if (aData.length != 0) {
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
<h1 class="header">&sad.header;</h1>
|
<h1 class="header">&sad.header;</h1>
|
||||||
<form>
|
<form>
|
||||||
<div class="message">&sad.message;</div>
|
<div class="message">&sad.message;</div>
|
||||||
<textarea class="description" placeholder="&sad.placeholder;" rows="4" required="true"/>
|
<textarea class="description" placeholder="&sad.placeholder;" rows="4" required="true" maxlength="10000"/>
|
||||||
<div class="message" id="last-url-div">
|
<div class="message" id="last-url-div">
|
||||||
<span>&sad.lastSite2;</span>
|
<span>&sad.lastSite2;</span>
|
||||||
<input id="last-checkbox" type="checkbox" checked="checked"/>
|
<input id="last-checkbox" type="checkbox" checked="checked"/>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче