Merge b2g-inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-09-05 12:04:44 -04:00
commit d132cca22b
57 changed files with 1442 additions and 803 deletions

View File

@ -1003,8 +1003,8 @@ pref("dom.wakelock.enabled", true);
// Enable touch caret by default
pref("touchcaret.enabled", true);
// Disable selection caret by default
pref("selectioncaret.enabled", false);
// Enable selection caret by default
pref("selectioncaret.enabled", true);
// Enable sync and mozId with Firefox Accounts.
pref("services.sync.fxaccounts.enabled", true);

View File

@ -283,15 +283,17 @@ int main(int argc, _CONST char* argv[])
*/
_argv = new char *[argc + 1];
for (int i = 0; i < argc; i++) {
_argv[i] = strdup(argv[i]);
size_t len = strlen(argv[i]) + 1;
_argv[i] = new char[len];
MOZ_ASSERT(_argv[i] != nullptr);
memcpy(_argv[i], argv[i], len);
}
_argv[argc] = nullptr;
result = do_main(argc, _argv);
for (int i = 0; i < argc; i++) {
free(_argv[i]);
delete[] _argv[i];
}
delete[] _argv;
}

View File

@ -110,10 +110,10 @@ let SystemAppProxy = {
if (content) {
content.removeEventListener.apply(content, arguments);
} else {
let idx = this._pendingListeners.indexOf(listener);
if (idx != -1) {
this._pendingListeners.splice(idx, 1);
}
this._pendingListeners = this._pendingListeners.filter(
args => {
return args[0] != name || args[1] != listener;
});
}
},

View File

@ -94,7 +94,7 @@ let steps = [
// Ensure that listener being registered before the system app is ready
// are correctly removed from the pending list
function removedListener() {
assert(false, "Listener isn't correctly removed from the pending list");
assert.ok(false, "Listener isn't correctly removed from the pending list");
}
SystemAppProxy.addEventListener("mozChromeEvent", removedListener);
SystemAppProxy.removeEventListener("mozChromeEvent", removedListener);

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
@ -127,7 +127,7 @@
<!-- Stock Android things -->
<project name="platform/external/icu4c" path="external/icu4c" revision="2bb01561780583cc37bc667f0ea79f48a122d8a2"/>
<!-- dolphin specific things -->
<project name="device/sprd" path="device/sprd" revision="3ba0b8b4e3f55d68f84603218e522d054a723532"/>
<project name="device/sprd" path="device/sprd" revision="ebb1ce6af72efe15c6919e2ceb9ee805ce2e5960"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="4e58336019b5cbcfd134caf55b142236cf986618"/>
<project name="platform/frameworks/av" path="frameworks/av" revision="facca8d3e35431b66f85a4eb42bc6c5b24bd04da"/>
<project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
@ -130,6 +130,7 @@
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="197cd9492b9fadaa915c5daf36ff557f8f4a8d1c"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="libnfcemu" path="platform/external/libnfcemu" remote="b2g" revision="682e556367e0049bb3ae127cec6e6c459abca1b0"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="57b16fcb790bdf0b53b3c6435a37ccc8ca90ed36"/>
<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"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
@ -132,7 +132,7 @@
<!-- Flame specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
<project name="device/qcom/common" path="device/qcom/common" revision="da9043131590b23754c6411e8704c1dc425b0ead"/>
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="84136f83161a8445afb3e16076913a309087874a"/>
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="540314ae9c56394c6b1f17a267db9f25c5acb9d6"/>
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="893238eb1215f8fd4f3747169170cc5e1cc33969"/>
<project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="9e62af4da848d56841bdde326f9bba26c743c33a"/>
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="082a1f98422e6a6b56f61218d6fcf465e85d4c58"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
@ -122,7 +122,7 @@
<!-- Flame specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="e8a318f7690092e639ba88891606f4183e846d3f"/>
<project name="device/qcom/common" path="device/qcom/common" revision="878804e0becfe5635bb8ccbf2671333d546c6fb6"/>
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="f686fa63e8766a4799cffab0b072c7b80194c4fc"/>
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="55ba09d8edffe7daffd954986b913319fd97890f"/>
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="ebb14165369f5edc3f335d5bde6eef8439073589"/>
<project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="9eb619d2efdf4bd121587d8296f5c10481f750b8"/>
<project name="platform_bootable_recovery" path="bootable/recovery" remote="b2g" revision="e81502511cda303c803e63f049574634bc96f9f2"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "c24176cfc9d128e5673782e05532f09ff94d09c5",
"revision": "4a65d170154483d723a976506190db72ca5d6e6d",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5765c62163bcb7fde5ebfd211881117de31a7c46"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0de5fcdc11a15abdf8d64f28bed2abb30041ea4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7af569a39a6a7d01a58093a01b16644c2c0f5657"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2d42429985b77df4bb001dbdd2802518aa86b713"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>

View File

@ -35,6 +35,7 @@
#include "nsIObjectFrame.h"
#include "nsBindingManager.h"
#include "nsStyleCoord.h"
#include "SelectionCarets.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/dom/Element.h"
@ -1545,6 +1546,11 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
return true;
}
nsRefPtr<SelectionCarets> selectionCarets = presShell->GetSelectionCarets();
if (selectionCarets) {
selectionCarets->SetVisibility(false);
}
bool clearFirstBlurEvent = false;
if (!mFirstBlurEvent) {
mFirstBlurEvent = content;

View File

@ -319,10 +319,13 @@ DroidSocketImpl::OnSocketCanReceiveWithoutBlocking(int aFd)
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(!mShuttingDownOnIOThread);
nsresult rv = ReceiveData(aFd, this);
if (NS_FAILED(rv)) {
ssize_t res = ReceiveData(aFd, this);
if (res < 0) {
/* I/O error */
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
return;
} else if (!res) {
/* EOF or peer shutdown */
RemoveWatchers(READ_WATCHER);
}
}

View File

@ -394,6 +394,19 @@ enum BluetoothObjectType {
TYPE_INVALID
};
enum BluetoothA2dpAudioState {
A2DP_AUDIO_STATE_REMOTE_SUSPEND,
A2DP_AUDIO_STATE_STOPPED,
A2DP_AUDIO_STATE_STARTED,
};
enum BluetoothA2dpConnectionState {
A2DP_CONNECTION_STATE_DISCONNECTED,
A2DP_CONNECTION_STATE_CONNECTING,
A2DP_CONNECTION_STATE_CONNECTED,
A2DP_CONNECTION_STATE_DISCONNECTING
};
enum ControlPlayStatus {
PLAYSTATUS_STOPPED = 0x00,
PLAYSTATUS_PLAYING = 0x01,
@ -404,6 +417,16 @@ enum ControlPlayStatus {
PLAYSTATUS_ERROR = 0xFF,
};
enum BluetoothAvrcpMediaAttribute {
AVRCP_MEDIA_ATTRIBUTE_TITLE,
AVRCP_MEDIA_ATTRIBUTE_ARTIST,
AVRCP_MEDIA_ATTRIBUTE_ALBUM,
AVRCP_MEDIA_ATTRIBUTE_TRACK_NUM,
AVRCP_MEDIA_ATTRIBUTE_NUM_TRACKS,
AVRCP_MEDIA_ATTRIBUTE_GENRE,
AVRCP_MEDIA_ATTRIBUTE_PLAYING_TIME
};
enum BluetoothAvrcpPlayerAttribute {
AVRCP_PLAYER_ATTRIBUTE_EQUALIZER,
AVRCP_PLAYER_ATTRIBUTE_REPEAT,
@ -433,6 +456,13 @@ enum BluetoothAvrcpNotification {
AVRCP_NTF_CHANGED
};
enum BluetoothAvrcpRemoteFeature {
AVRCP_REMOTE_FEATURE_NONE,
AVRCP_REMOTE_FEATURE_METADATA,
AVRCP_REMOTE_FEATURE_ABSOLUTE_VOLUME,
AVRCP_REMOTE_FEATURE_BROWSE
};
struct BluetoothAvrcpElementAttribute {
uint32_t mId;
nsString mValue;
@ -447,6 +477,12 @@ struct BluetoothAvrcpNotificationParam {
uint8_t mValues[256];
};
struct BluetoothAvrcpPlayerSettings {
uint8_t mNumAttr;
uint8_t mIds[256];
uint8_t mValues[256];
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_bluetoothcommon_h__

View File

@ -8,7 +8,6 @@
#include "BluetoothA2dpManager.h"
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
#include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h"
@ -37,173 +36,42 @@ namespace {
#endif
} // anonymous namespace
class SinkPropertyChangedHandler : public nsRunnable
{
public:
SinkPropertyChangedHandler(const BluetoothSignal& aSignal)
: mSignal(aSignal)
{
}
NS_IMETHOD
Run()
{
MOZ_ASSERT(NS_IsMainThread());
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
NS_ENSURE_TRUE(a2dp, NS_ERROR_FAILURE);
a2dp->HandleSinkPropertyChanged(mSignal);
return NS_OK;
}
private:
BluetoothSignal mSignal;
};
class RequestPlayStatusTask : public nsRunnable
{
public:
RequestPlayStatusTask()
{
MOZ_ASSERT(!NS_IsMainThread());
}
nsresult Run()
{
MOZ_ASSERT(NS_IsMainThread());
BluetoothSignal signal(NS_LITERAL_STRING(REQUEST_MEDIA_PLAYSTATUS_ID),
NS_LITERAL_STRING(KEY_ADAPTER),
InfallibleTArray<BluetoothNamedValue>());
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
bs->DistributeSignal(signal);
return NS_OK;
}
};
#if ANDROID_VERSION > 17
class UpdateRegisterNotificationTask : public nsRunnable
{
public:
UpdateRegisterNotificationTask(BluetoothAvrcpEvent aEvent, uint32_t aParam)
: mEvent(aEvent)
, mParam(aParam)
{
MOZ_ASSERT(!NS_IsMainThread());
}
nsresult Run()
{
MOZ_ASSERT(NS_IsMainThread());
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
NS_ENSURE_TRUE(a2dp, NS_OK);
a2dp->UpdateRegisterNotification(mEvent, mParam);
return NS_OK;
}
private:
BluetoothAvrcpEvent mEvent;
uint32_t mParam;
};
/*
* This function maps attribute id and returns corresponding values
* Attribute id refers to btrc_media_attr_t in bt_rc.h
*/
static void
ConvertAttributeString(int aAttrId, nsAString& aAttrStr)
ConvertAttributeString(BluetoothAvrcpMediaAttribute aAttrId,
nsAString& aAttrStr)
{
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
NS_ENSURE_TRUE_VOID(a2dp);
switch (aAttrId) {
case BTRC_MEDIA_ATTR_TITLE:
case AVRCP_MEDIA_ATTRIBUTE_TITLE:
a2dp->GetTitle(aAttrStr);
break;
case BTRC_MEDIA_ATTR_ARTIST:
case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
a2dp->GetArtist(aAttrStr);
break;
case BTRC_MEDIA_ATTR_ALBUM:
case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
a2dp->GetAlbum(aAttrStr);
break;
case BTRC_MEDIA_ATTR_TRACK_NUM:
case AVRCP_MEDIA_ATTRIBUTE_TRACK_NUM:
aAttrStr.AppendInt(a2dp->GetMediaNumber());
break;
case BTRC_MEDIA_ATTR_NUM_TRACKS:
case AVRCP_MEDIA_ATTRIBUTE_NUM_TRACKS:
aAttrStr.AppendInt(a2dp->GetTotalMediaNumber());
break;
case BTRC_MEDIA_ATTR_GENRE:
case AVRCP_MEDIA_ATTRIBUTE_GENRE:
// TODO: we currently don't support genre from music player
aAttrStr.Truncate();
break;
case BTRC_MEDIA_ATTR_PLAYING_TIME:
case AVRCP_MEDIA_ATTRIBUTE_PLAYING_TIME:
aAttrStr.AppendInt(a2dp->GetDuration());
break;
}
}
class UpdateElementAttrsTask : public nsRunnable
{
public:
UpdateElementAttrsTask(uint8_t aNumAttr, const btrc_media_attr_t* aPlayerAttrs)
: mNumAttr(aNumAttr)
{
MOZ_ASSERT(!NS_IsMainThread());
mAttrs = new BluetoothAvrcpElementAttribute[mNumAttr];
for (uint8_t i = 0; i < mNumAttr; ++i) {
mAttrs[i].mId = aPlayerAttrs[i];
}
}
nsresult Run()
{
MOZ_ASSERT(NS_IsMainThread());
for (uint8_t i = 0; i < mNumAttr; ++i) {
ConvertAttributeString(mAttrs[i].mId, mAttrs[i].mValue);
}
NS_ENSURE_TRUE(sBtAvrcpInterface, NS_OK);
sBtAvrcpInterface->GetElementAttrRsp(mNumAttr, mAttrs, nullptr);
return NS_OK;
}
private:
uint8_t mNumAttr;
nsAutoArrayPtr<BluetoothAvrcpElementAttribute> mAttrs;
};
class UpdatePassthroughCmdTask : public nsRunnable
{
public:
UpdatePassthroughCmdTask(const nsAString& aName)
: mName(aName)
{
MOZ_ASSERT(!NS_IsMainThread());
}
nsresult Run()
{
MOZ_ASSERT(NS_IsMainThread());
NS_NAMED_LITERAL_STRING(type, "media-button");
BroadcastSystemMessage(type, BluetoothValue(mName));
return NS_OK;
}
private:
nsString mName;
};
#endif
NS_IMETHODIMP
BluetoothA2dpManager::Observe(nsISupports* aSubject,
const char* aTopic,
@ -233,288 +101,27 @@ BluetoothA2dpManager::Reset()
}
static void
AvStatusToSinkString(btav_connection_state_t aStatus, nsAString& aState)
AvStatusToSinkString(BluetoothA2dpConnectionState aState, nsAString& aString)
{
nsAutoString state;
if (aStatus == BTAV_CONNECTION_STATE_DISCONNECTED) {
aState = NS_LITERAL_STRING("disconnected");
} else if (aStatus == BTAV_CONNECTION_STATE_CONNECTING) {
aState = NS_LITERAL_STRING("connecting");
} else if (aStatus == BTAV_CONNECTION_STATE_CONNECTED) {
aState = NS_LITERAL_STRING("connected");
} else if (aStatus == BTAV_CONNECTION_STATE_DISCONNECTING) {
aState = NS_LITERAL_STRING("disconnecting");
} else {
BT_WARNING("Unknown sink state");
}
}
static void
A2dpConnectionStateCallback(btav_connection_state_t aState,
bt_bdaddr_t* aBdAddress)
{
MOZ_ASSERT(!NS_IsMainThread());
nsString remoteDeviceBdAddress;
BdAddressTypeToString(aBdAddress, remoteDeviceBdAddress);
nsString a2dpState;
AvStatusToSinkString(aState, a2dpState);
InfallibleTArray<BluetoothNamedValue> props;
BT_APPEND_NAMED_VALUE(props, "State", a2dpState);
BluetoothSignal signal(NS_LITERAL_STRING("AudioSink"),
remoteDeviceBdAddress, props);
NS_DispatchToMainThread(new SinkPropertyChangedHandler(signal));
}
static void
A2dpAudioStateCallback(btav_audio_state_t aState,
bt_bdaddr_t* aBdAddress)
{
MOZ_ASSERT(!NS_IsMainThread());
nsString remoteDeviceBdAddress;
BdAddressTypeToString(aBdAddress, remoteDeviceBdAddress);
nsString a2dpState;
if (aState == BTAV_AUDIO_STATE_STARTED) {
a2dpState = NS_LITERAL_STRING("playing");
} else if (aState == BTAV_AUDIO_STATE_STOPPED) {
// for avdtp state stop stream
a2dpState = NS_LITERAL_STRING("connected");
} else if (aState == BTAV_AUDIO_STATE_REMOTE_SUSPEND) {
// for avdtp state suspend stream from remote side
a2dpState = NS_LITERAL_STRING("connected");
}
InfallibleTArray<BluetoothNamedValue> props;
BT_APPEND_NAMED_VALUE(props, "State", a2dpState);
BluetoothSignal signal(NS_LITERAL_STRING("AudioSink"),
remoteDeviceBdAddress, props);
NS_DispatchToMainThread(new SinkPropertyChangedHandler(signal));
}
#if ANDROID_VERSION > 17
/*
* Avrcp 1.3 callbacks
*/
/*
* This function is to request Gaia player application to update
* current play status.
* Callback for play status request
*/
static void
AvrcpGetPlayStatusCallback()
{
MOZ_ASSERT(!NS_IsMainThread());
NS_DispatchToMainThread(new RequestPlayStatusTask());
}
/*
* This function is trying to get element attributes, which request from CT
* Unlike BlueZ only calls UpdateMetaData, bluedroid does not cache meta data
* information, but instead uses callback AvrcpGetElementAttrCallback and
* call get_element_attr_rsp() to reply request.
*
* Callback to fetch the get element attributes of the current song
* aNumAttr: It represents the number of attributes requested in aPlayerAttrs
* aPlayerAttrs: It represents Attribute Ids
*/
static void
AvrcpGetElementAttrCallback(uint8_t aNumAttr, btrc_media_attr_t* aPlayerAttrs)
{
MOZ_ASSERT(!NS_IsMainThread());
NS_DispatchToMainThread(new UpdateElementAttrsTask(aNumAttr, aPlayerAttrs));
}
/*
* Callback for register notification (Play state change/track change/...)
* To reply RegisterNotification INTERIM response
* See AVRCP 1.3 Spec 25.2
* aParam: It only valids if event_id is BTRC_EVT_PLAY_POS_CHANGED,
* which is playback interval time
*/
static void
AvrcpRegisterNotificationCallback(btrc_event_id_t aEventId, uint32_t aParam)
{
BluetoothAvrcpEvent event;
MOZ_ASSERT(!NS_IsMainThread());
switch (aEventId) {
case BTRC_EVT_PLAY_STATUS_CHANGED:
event = AVRCP_EVENT_PLAY_STATUS_CHANGED;
case BTRC_EVT_TRACK_CHANGE:
event = AVRCP_EVENT_TRACK_CHANGE;
case BTRC_EVT_TRACK_REACHED_END:
event = AVRCP_EVENT_TRACK_REACHED_END;
case BTRC_EVT_TRACK_REACHED_START:
event = AVRCP_EVENT_TRACK_REACHED_START;
case BTRC_EVT_PLAY_POS_CHANGED:
event = AVRCP_EVENT_PLAY_POS_CHANGED;
case BTRC_EVT_APP_SETTINGS_CHANGED:
event = AVRCP_EVENT_APP_SETTINGS_CHANGED;
switch (aState) {
case A2DP_CONNECTION_STATE_DISCONNECTED:
aString.AssignLiteral("disconnected");
break;
case A2DP_CONNECTION_STATE_CONNECTING:
aString.AssignLiteral("connecting");
break;
case A2DP_CONNECTION_STATE_CONNECTED:
aString.AssignLiteral("connected");
break;
case A2DP_CONNECTION_STATE_DISCONNECTING:
aString.AssignLiteral("disconnecting");
break;
default:
BT_LOGR("Unknown event 0x%x", aEventId);
BT_WARNING("Unknown sink state %d", static_cast<int>(aState));
return;
}
NS_DispatchToMainThread(new UpdateRegisterNotificationTask(event, aParam));
}
/*
* Player application settings is optional for Avrcp 1.3
* B2G 1.3 currently does not support Player application setting
* related functions. Support Player Setting in the future version
*/
static void
AvrcpListPlayerAppAttributeCallback()
{
MOZ_ASSERT(!NS_IsMainThread());
// TODO: Support avrcp application setting related functions
}
static void
AvrcpListPlayerAppValuesCallback(btrc_player_attr_t aAttrId)
{
MOZ_ASSERT(!NS_IsMainThread());
// TODO: Support avrcp application setting related functions
}
static void
AvrcpGetPlayerAppValueCallback(uint8_t aNumAttr,
btrc_player_attr_t* aPlayerAttrs)
{
MOZ_ASSERT(!NS_IsMainThread());
// TODO: Support avrcp application setting related functions
}
static void
AvrcpGetPlayerAppAttrsTextCallback(uint8_t aNumAttr,
btrc_player_attr_t* PlayerAttrs)
{
MOZ_ASSERT(!NS_IsMainThread());
// TODO: Support avrcp application setting related functions
}
static void
AvrcpGetPlayerAppValuesTextCallback(uint8_t aAttrId, uint8_t aNumVal,
uint8_t* PlayerVals)
{
MOZ_ASSERT(!NS_IsMainThread());
// TODO: Support avrcp application setting related functions
}
static void
AvrcpSetPlayerAppValueCallback(btrc_player_settings_t* aPlayerVals)
{
MOZ_ASSERT(!NS_IsMainThread());
// TODO: Support avrcp application setting related functions
}
#endif
#if ANDROID_VERSION > 18
/*
* This callback function is to get CT features from Feature Bit Mask.
* If Advanced Control Player bit is set, CT supports
* volume sync (absolute volume feature). If Browsing bit is set, Avrcp 1.4
* Browse feature will be supported
*/
static void
AvrcpRemoteFeaturesCallback(bt_bdaddr_t* aBdAddress,
btrc_remote_features_t aFeatures)
{
// TODO: Support avrcp 1.4 absolute volume/browse
}
/*
* This callback function is to get notification that volume changed on the
* remote car kit (if it supports Avrcp 1.4), not notification from phone.
*/
static void
AvrcpRemoteVolumeChangedCallback(uint8_t aVolume, uint8_t aCType)
{
// TODO: Support avrcp 1.4 absolute volume/browse
}
/*
* This callback function is to handle passthrough commands.
*/
static void
AvrcpPassThroughCallback(int aId, int aKeyState)
{
// Fast-forward and rewind key events won't be generated from bluedroid
// stack after ANDROID_VERSION > 18, but via passthrough callback.
nsAutoString name;
NS_ENSURE_TRUE_VOID(aKeyState == AVRC_KEY_PRESS_STATE ||
aKeyState == AVRC_KEY_RELEASE_STATE);
switch (aId) {
case AVRC_ID_FAST_FOR:
if (aKeyState == AVRC_KEY_PRESS_STATE) {
name.AssignLiteral("media-fast-forward-button-press");
} else {
name.AssignLiteral("media-fast-forward-button-release");
}
break;
case AVRC_ID_REWIND:
if (aKeyState == AVRC_KEY_PRESS_STATE) {
name.AssignLiteral("media-rewind-button-press");
} else {
name.AssignLiteral("media-rewind-button-release");
}
break;
default:
BT_WARNING("Unable to handle the unknown PassThrough command %d", aId);
break;
}
if (!name.IsEmpty()) {
NS_DispatchToMainThread(new UpdatePassthroughCmdTask(name));
}
}
#endif
static btav_callbacks_t sBtA2dpCallbacks = {
sizeof(sBtA2dpCallbacks),
A2dpConnectionStateCallback,
A2dpAudioStateCallback
};
#if ANDROID_VERSION > 17
static btrc_callbacks_t sBtAvrcpCallbacks = {
sizeof(sBtAvrcpCallbacks),
#if ANDROID_VERSION > 18
AvrcpRemoteFeaturesCallback,
#endif
AvrcpGetPlayStatusCallback,
AvrcpListPlayerAppAttributeCallback,
AvrcpListPlayerAppValuesCallback,
AvrcpGetPlayerAppValueCallback,
AvrcpGetPlayerAppAttrsTextCallback,
AvrcpGetPlayerAppValuesTextCallback,
AvrcpSetPlayerAppValueCallback,
AvrcpGetElementAttrCallback,
AvrcpRegisterNotificationCallback,
#if ANDROID_VERSION > 18
AvrcpRemoteVolumeChangedCallback,
AvrcpPassThroughCallback
#endif
};
#endif
#if ANDROID_VERSION > 17
class InitAvrcpResultHandler MOZ_FINAL : public BluetoothAvrcpResultHandler
{
@ -580,8 +187,8 @@ public:
return;
}
sBtAvrcpInterface->Init(&sBtAvrcpCallbacks,
new InitAvrcpResultHandler(mRes));
BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get();
sBtAvrcpInterface->Init(a2dpManager, new InitAvrcpResultHandler(mRes));
#else
/* ...or signal success otherwise. */
if (mRes) {
@ -622,7 +229,8 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
return;
}
sBtA2dpInterface->Init(&sBtA2dpCallbacks, new InitA2dpResultHandler(aRes));
BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get();
sBtA2dpInterface->Init(a2dpManager, new InitA2dpResultHandler(aRes));
}
BluetoothA2dpManager::~BluetoothA2dpManager()
@ -1327,5 +935,230 @@ BluetoothA2dpManager::GetArtist(nsAString& aArtist)
aArtist.Assign(mArtist);
}
/*
* A2DP Notifications
*/
void
BluetoothA2dpManager::ConnectionStateNotification(BluetoothA2dpConnectionState aState,
const nsAString& aBdAddr)
{
MOZ_ASSERT(NS_IsMainThread());
nsString a2dpState;
AvStatusToSinkString(aState, a2dpState);
InfallibleTArray<BluetoothNamedValue> props;
BT_APPEND_NAMED_VALUE(props, "State", a2dpState);
HandleSinkPropertyChanged(BluetoothSignal(NS_LITERAL_STRING("AudioSink"),
nsString(aBdAddr), props));
}
void
BluetoothA2dpManager::AudioStateNotification(BluetoothA2dpAudioState aState,
const nsAString& aBdAddr)
{
MOZ_ASSERT(NS_IsMainThread());
nsString a2dpState;
if (aState == A2DP_AUDIO_STATE_STARTED) {
a2dpState = NS_LITERAL_STRING("playing");
} else if (aState == A2DP_AUDIO_STATE_STOPPED) {
// for avdtp state stop stream
a2dpState = NS_LITERAL_STRING("connected");
} else if (aState == A2DP_AUDIO_STATE_REMOTE_SUSPEND) {
// for avdtp state suspend stream from remote side
a2dpState = NS_LITERAL_STRING("connected");
}
InfallibleTArray<BluetoothNamedValue> props;
BT_APPEND_NAMED_VALUE(props, "State", a2dpState);
HandleSinkPropertyChanged(BluetoothSignal(NS_LITERAL_STRING("AudioSink"),
nsString(aBdAddr), props));
}
/*
* AVRCP Notifications
*/
void
BluetoothA2dpManager::GetPlayStatusNotification()
{
MOZ_ASSERT(NS_IsMainThread());
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
return;
}
bs->DistributeSignal(
BluetoothSignal(NS_LITERAL_STRING(REQUEST_MEDIA_PLAYSTATUS_ID),
NS_LITERAL_STRING(KEY_ADAPTER),
InfallibleTArray<BluetoothNamedValue>()));
}
/* Player application settings is optional for AVRCP 1.3. B2G
* currently does not support player-application-setting related
* functionality.
*/
void
BluetoothA2dpManager::ListPlayerAppAttrNotification()
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::ListPlayerAppValuesNotification(
BluetoothAvrcpPlayerAttribute aAttrId)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::GetPlayerAppValueNotification(
uint8_t aNumAttrs, const BluetoothAvrcpPlayerAttribute* aAttrs)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::GetPlayerAppAttrsTextNotification(
uint8_t aNumAttrs, const BluetoothAvrcpPlayerAttribute* aAttrs)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::GetPlayerAppValuesTextNotification(
uint8_t aAttrId, uint8_t aNumVals, const uint8_t* aValues)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
void
BluetoothA2dpManager::SetPlayerAppValueNotification(
const BluetoothAvrcpPlayerSettings& aSettings)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP application-setting-related functions
}
/* This method returns element attributes, which are requested from
* CT. Unlike BlueZ it calls only UpdateMetaData. Bluedroid does not cache
* meta-data information, but instead uses |GetElementAttrNotifications|
* and |GetElementAttrRsp| request them.
*/
void
BluetoothA2dpManager::GetElementAttrNotification(
uint8_t aNumAttrs, const BluetoothAvrcpMediaAttribute* aAttrs)
{
MOZ_ASSERT(NS_IsMainThread());
nsAutoArrayPtr<BluetoothAvrcpElementAttribute> attrs(
new BluetoothAvrcpElementAttribute[aNumAttrs]);
for (uint8_t i = 0; i < aNumAttrs; ++i) {
attrs[i].mId = aAttrs[i];
ConvertAttributeString(
static_cast<BluetoothAvrcpMediaAttribute>(attrs[i].mId),
attrs[i].mValue);
}
#if ANDROID_VERSION >= 18
MOZ_ASSERT(sBtAvrcpInterface);
sBtAvrcpInterface->GetElementAttrRsp(aNumAttrs, attrs, nullptr);
#endif // ANDROID_VERSION >= 18
}
void
BluetoothA2dpManager::RegisterNotificationNotification(
BluetoothAvrcpEvent aEvent, uint32_t aParam)
{
MOZ_ASSERT(NS_IsMainThread());
BluetoothA2dpManager* a2dp = BluetoothA2dpManager::Get();
if (!a2dp) {
return;
}
#if ANDROID_VERSION >= 18
a2dp->UpdateRegisterNotification(aEvent, aParam);
#endif // ANDROID_VERSION >= 18
}
/* This method is used to get CT features from the Feature Bit Mask. If
* Advanced Control Player bit is set, the CT supports volume sync (absolute
* volume feature). If Browsing bit is set, AVRCP 1.4 Browse feature will be
* supported.
*/
void
BluetoothA2dpManager::RemoteFeatureNotification(
const nsAString& aBdAddr, unsigned long aFeatures)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP 1.4 absolute volume/browse
}
/* This method is used to get notifications about volume changes on the
* remote car kit (if it supports AVRCP 1.4), not notification from phone.
*/
void
BluetoothA2dpManager::VolumeChangeNotification(uint8_t aVolume,
uint8_t aCType)
{
MOZ_ASSERT(NS_IsMainThread());
// TODO: Support AVRCP 1.4 absolute volume/browse
}
void
BluetoothA2dpManager::PassthroughCmdNotification(int aId, int aKeyState)
{
MOZ_ASSERT(NS_IsMainThread());
// Fast-forward and rewind key events won't be generated from bluedroid
// stack after ANDROID_VERSION > 18, but via passthrough callback.
nsAutoString name;
NS_ENSURE_TRUE_VOID(aKeyState == AVRC_KEY_PRESS_STATE ||
aKeyState == AVRC_KEY_RELEASE_STATE);
switch (aId) {
case AVRC_ID_FAST_FOR:
if (aKeyState == AVRC_KEY_PRESS_STATE) {
name.AssignLiteral("media-fast-forward-button-press");
} else {
name.AssignLiteral("media-fast-forward-button-release");
}
break;
case AVRC_ID_REWIND:
if (aKeyState == AVRC_KEY_PRESS_STATE) {
name.AssignLiteral("media-rewind-button-press");
} else {
name.AssignLiteral("media-rewind-button-release");
}
break;
default:
BT_WARNING("Unable to handle the unknown PassThrough command %d", aId);
return;
}
NS_NAMED_LITERAL_STRING(type, "media-button");
BroadcastSystemMessage(type, BluetoothValue(name));
}
NS_IMPL_ISUPPORTS(BluetoothA2dpManager, nsIObserver)

View File

@ -8,11 +8,14 @@
#define mozilla_dom_bluetooth_bluetootha2dpmanager_h__
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
#include "BluetoothProfileController.h"
#include "BluetoothProfileManagerBase.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothA2dpManager : public BluetoothProfileManagerBase
, public BluetoothA2dpNotificationHandler
, public BluetoothAvrcpNotificationHandler
{
public:
BT_DECL_PROFILE_MGR_BASE
@ -63,7 +66,6 @@ public:
void GetArtist(nsAString& aArtist);
private:
class SinkPropertyChangedHandler;
BluetoothA2dpManager();
void ResetA2dp();
void ResetAvrcp();
@ -71,6 +73,46 @@ private:
void HandleShutdown();
void NotifyConnectionStatusChanged();
void ConnectionStateNotification(BluetoothA2dpConnectionState aState,
const nsAString& aBdAddr) MOZ_OVERRIDE;
void AudioStateNotification(BluetoothA2dpAudioState aState,
const nsAString& aBdAddr) MOZ_OVERRIDE;
void GetPlayStatusNotification() MOZ_OVERRIDE;
void ListPlayerAppAttrNotification() MOZ_OVERRIDE;
void ListPlayerAppValuesNotification(
BluetoothAvrcpPlayerAttribute aAttrId) MOZ_OVERRIDE;
void GetPlayerAppValueNotification(
uint8_t aNumAttrs,
const BluetoothAvrcpPlayerAttribute* aAttrs) MOZ_OVERRIDE;
void GetPlayerAppAttrsTextNotification(
uint8_t aNumAttrs,
const BluetoothAvrcpPlayerAttribute* aAttrs) MOZ_OVERRIDE;
void GetPlayerAppValuesTextNotification(
uint8_t aAttrId, uint8_t aNumVals, const uint8_t* aValues) MOZ_OVERRIDE;
void SetPlayerAppValueNotification(
const BluetoothAvrcpPlayerSettings& aSettings) MOZ_OVERRIDE;
void GetElementAttrNotification(
uint8_t aNumAttrs,
const BluetoothAvrcpMediaAttribute* aAttrs) MOZ_OVERRIDE;
void RegisterNotificationNotification(
BluetoothAvrcpEvent aEvent, uint32_t aParam) MOZ_OVERRIDE;
void RemoteFeatureNotification(
const nsAString& aBdAddr, unsigned long aFeatures) MOZ_OVERRIDE;
void VolumeChangeNotification(uint8_t aVolume, uint8_t aCType) MOZ_OVERRIDE;
void PassthroughCmdNotification(int aId, int aKeyState) MOZ_OVERRIDE;
nsString mDeviceAddress;
nsRefPtr<BluetoothProfileController> mController;

View File

@ -438,16 +438,6 @@ Convert(bt_device_type_t aIn, BluetoothDeviceType& aOut)
return NS_OK;
}
static nsresult
Convert(const bt_remote_version_t& aIn, BluetoothRemoteInfo& aOut)
{
aOut.mVerMajor = aIn.version;
aOut.mVerMinor = aIn.sub_ver;
aOut.mManufacturer = aIn.manufacturer;
return NS_OK;
}
static nsresult
Convert(const bt_service_record_t& aIn, BluetoothServiceRecord& aOut)
{
@ -715,7 +705,52 @@ Convert(bthf_volume_type_t aIn, BluetoothHandsfreeVolumeType& aOut)
return NS_OK;
}
static nsresult
Convert(btav_connection_state_t aIn, BluetoothA2dpConnectionState& aOut)
{
static const BluetoothA2dpConnectionState sConnectionState[] = {
CONVERT(BTAV_CONNECTION_STATE_DISCONNECTED,
A2DP_CONNECTION_STATE_DISCONNECTED),
CONVERT(BTAV_CONNECTION_STATE_CONNECTING,
A2DP_CONNECTION_STATE_CONNECTING),
CONVERT(BTAV_CONNECTION_STATE_CONNECTED,
A2DP_CONNECTION_STATE_CONNECTED),
CONVERT(BTAV_CONNECTION_STATE_DISCONNECTING,
A2DP_CONNECTION_STATE_DISCONNECTING),
};
if (aIn >= MOZ_ARRAY_LENGTH(sConnectionState)) {
return NS_ERROR_ILLEGAL_VALUE;
}
aOut = sConnectionState[aIn];
return NS_OK;
}
static nsresult
Convert(btav_audio_state_t aIn, BluetoothA2dpAudioState& aOut)
{
static const BluetoothA2dpAudioState sAudioState[] = {
CONVERT(BTAV_AUDIO_STATE_REMOTE_SUSPEND, A2DP_AUDIO_STATE_REMOTE_SUSPEND),
CONVERT(BTAV_AUDIO_STATE_STOPPED, A2DP_AUDIO_STATE_STOPPED),
CONVERT(BTAV_AUDIO_STATE_STARTED, A2DP_AUDIO_STATE_STARTED),
};
if (aIn >= MOZ_ARRAY_LENGTH(sAudioState)) {
return NS_ERROR_ILLEGAL_VALUE;
}
aOut = sAudioState[aIn];
return NS_OK;
}
#if ANDROID_VERSION >= 18
static nsresult
Convert(const bt_remote_version_t& aIn, BluetoothRemoteInfo& aOut)
{
aOut.mVerMajor = aIn.version;
aOut.mVerMinor = aIn.sub_ver;
aOut.mManufacturer = aIn.manufacturer;
return NS_OK;
}
static nsresult
Convert(ControlPlayStatus aIn, btrc_play_status_t& aOut)
{
@ -749,6 +784,23 @@ Convert(enum BluetoothAvrcpPlayerAttribute aIn, btrc_player_attr_t& aOut)
return NS_OK;
}
static nsresult
Convert(btrc_player_attr_t aIn, enum BluetoothAvrcpPlayerAttribute& aOut)
{
static const BluetoothAvrcpPlayerAttribute sPlayerAttr[] = {
CONVERT(0, static_cast<BluetoothAvrcpPlayerAttribute>(0)), // invalid, [0] required by gcc
CONVERT(BTRC_PLAYER_ATTR_EQUALIZER, AVRCP_PLAYER_ATTRIBUTE_EQUALIZER),
CONVERT(BTRC_PLAYER_ATTR_REPEAT, AVRCP_PLAYER_ATTRIBUTE_REPEAT),
CONVERT(BTRC_PLAYER_ATTR_SHUFFLE, AVRCP_PLAYER_ATTRIBUTE_SHUFFLE),
CONVERT(BTRC_PLAYER_ATTR_SCAN, AVRCP_PLAYER_ATTRIBUTE_SCAN)
};
if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sPlayerAttr)) {
return NS_ERROR_ILLEGAL_VALUE;
}
aOut = sPlayerAttr[aIn];
return NS_OK;
}
static nsresult
Convert(enum BluetoothAvrcpStatus aIn, btrc_status_t& aOut)
{
@ -784,6 +836,47 @@ Convert(enum BluetoothAvrcpEvent aIn, btrc_event_id_t& aOut)
return NS_OK;
}
static nsresult
Convert(btrc_event_id_t aIn, enum BluetoothAvrcpEvent& aOut)
{
static const BluetoothAvrcpEvent sEventId[] = {
CONVERT(0, static_cast<BluetoothAvrcpEvent>(0)), // invalid, [0] required by gcc
CONVERT(BTRC_EVT_PLAY_STATUS_CHANGED, AVRCP_EVENT_PLAY_STATUS_CHANGED),
CONVERT(BTRC_EVT_TRACK_CHANGE, AVRCP_EVENT_TRACK_CHANGE),
CONVERT(BTRC_EVT_TRACK_REACHED_END, AVRCP_EVENT_TRACK_REACHED_END),
CONVERT(BTRC_EVT_TRACK_REACHED_START, AVRCP_EVENT_TRACK_REACHED_START),
CONVERT(BTRC_EVT_PLAY_POS_CHANGED, AVRCP_EVENT_PLAY_POS_CHANGED),
CONVERT(6, static_cast<BluetoothAvrcpEvent>(0)), // invalid, [6] required by gcc
CONVERT(7, static_cast<BluetoothAvrcpEvent>(0)), // invalid, [7] required by gcc
CONVERT(BTRC_EVT_APP_SETTINGS_CHANGED, AVRCP_EVENT_APP_SETTINGS_CHANGED)
};
if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sEventId)) {
return NS_ERROR_ILLEGAL_VALUE;
}
aOut = sEventId[aIn];
return NS_OK;
}
static nsresult
Convert(btrc_media_attr_t aIn, enum BluetoothAvrcpMediaAttribute& aOut)
{
static const BluetoothAvrcpMediaAttribute sEventId[] = {
CONVERT(0, static_cast<BluetoothAvrcpMediaAttribute>(0)), // invalid, [0] required by gcc
CONVERT(BTRC_MEDIA_ATTR_TITLE, AVRCP_MEDIA_ATTRIBUTE_TITLE),
CONVERT(BTRC_MEDIA_ATTR_ARTIST, AVRCP_MEDIA_ATTRIBUTE_ARTIST),
CONVERT(BTRC_MEDIA_ATTR_ALBUM, AVRCP_MEDIA_ATTRIBUTE_ALBUM),
CONVERT(BTRC_MEDIA_ATTR_TRACK_NUM, AVRCP_MEDIA_ATTRIBUTE_TRACK_NUM),
CONVERT(BTRC_MEDIA_ATTR_NUM_TRACKS, AVRCP_MEDIA_ATTRIBUTE_NUM_TRACKS),
CONVERT(BTRC_MEDIA_ATTR_GENRE, AVRCP_MEDIA_ATTRIBUTE_GENRE),
CONVERT(BTRC_MEDIA_ATTR_PLAYING_TIME, AVRCP_MEDIA_ATTRIBUTE_PLAYING_TIME)
};
if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sEventId)) {
return NS_ERROR_ILLEGAL_VALUE;
}
aOut = sEventId[aIn];
return NS_OK;
}
static nsresult
Convert(enum BluetoothAvrcpNotification aIn, btrc_notification_type_t& aOut)
{
@ -811,7 +904,28 @@ Convert(const BluetoothAvrcpElementAttribute& aIn, btrc_element_attr_val_t& aOut
return NS_OK;
}
#endif
static nsresult
Convert(const btrc_player_settings_t& aIn, BluetoothAvrcpPlayerSettings& aOut)
{
aOut.mNumAttr = aIn.num_attr;
memcpy(aOut.mIds, aIn.attr_ids, aIn.num_attr);
memcpy(aOut.mValues, aIn.attr_values, aIn.num_attr);
return NS_OK;
}
#endif // ANDROID_VERSION >= 18
#if ANDROID_VERSION >= 19
static nsresult
Convert(btrc_remote_features_t aIn, unsigned long& aOut)
{
/* The input type's name is misleading. The converted value is
* actually a bitmask.
*/
aOut = static_cast<unsigned long>(aIn);
return NS_OK;
}
#endif // ANDROID_VERSION >= 19
/* |ConvertArray| is a helper for converting arrays. Pass an
* instance of this structure as the first argument to |Convert|
@ -2714,6 +2828,69 @@ DispatchBluetoothA2dpResult(
return rv;
}
// Notification handling
//
BluetoothA2dpNotificationHandler::~BluetoothA2dpNotificationHandler()
{ }
static BluetoothA2dpNotificationHandler* sA2dpNotificationHandler;
struct BluetoothA2dpCallback
{
class A2dpNotificationHandlerWrapper
{
public:
typedef BluetoothA2dpNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sA2dpNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationRunnable2<A2dpNotificationHandlerWrapper,
void,
BluetoothA2dpConnectionState,
nsString,
BluetoothA2dpConnectionState,
const nsAString&>
ConnectionStateNotification;
typedef BluetoothNotificationRunnable2<A2dpNotificationHandlerWrapper,
void,
BluetoothA2dpAudioState,
nsString,
BluetoothA2dpAudioState,
const nsAString&>
AudioStateNotification;
// Bluedroid A2DP callbacks
static void
ConnectionState(btav_connection_state_t aState, bt_bdaddr_t* aBdAddr)
{
ConnectionStateNotification::Dispatch(
&BluetoothA2dpNotificationHandler::ConnectionStateNotification,
aState, aBdAddr);
}
static void
AudioState(btav_audio_state_t aState, bt_bdaddr_t* aBdAddr)
{
AudioStateNotification::Dispatch(
&BluetoothA2dpNotificationHandler::AudioStateNotification,
aState, aBdAddr);
}
};
// Interface
//
BluetoothA2dpInterface::BluetoothA2dpInterface(
const btav_interface_t* aInterface)
: mInterface(aInterface)
@ -2725,10 +2902,19 @@ BluetoothA2dpInterface::~BluetoothA2dpInterface()
{ }
void
BluetoothA2dpInterface::Init(btav_callbacks_t* aCallbacks,
BluetoothA2dpResultHandler* aRes)
BluetoothA2dpInterface::Init(
BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes)
{
bt_status_t status = mInterface->init(aCallbacks);
static btav_callbacks_t sCallbacks = {
sizeof(sCallbacks),
BluetoothA2dpCallback::ConnectionState,
BluetoothA2dpCallback::AudioState
};
sA2dpNotificationHandler = aNotificationHandler;
bt_status_t status = mInterface->init(&sCallbacks);
if (aRes) {
DispatchBluetoothA2dpResult(aRes, &BluetoothA2dpResultHandler::Init,
@ -2832,6 +3018,199 @@ DispatchBluetoothAvrcpResult(
}
return rv;
}
#endif
// Notification handling
//
BluetoothAvrcpNotificationHandler::~BluetoothAvrcpNotificationHandler()
{ }
#if ANDROID_VERSION >= 18
static BluetoothAvrcpNotificationHandler* sAvrcpNotificationHandler;
struct BluetoothAvrcpCallback
{
class AvrcpNotificationHandlerWrapper
{
public:
typedef BluetoothAvrcpNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sAvrcpNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationRunnable0<AvrcpNotificationHandlerWrapper,
void>
GetPlayStatusNotification;
typedef BluetoothNotificationRunnable0<AvrcpNotificationHandlerWrapper,
void>
ListPlayerAppAttrNotification;
typedef BluetoothNotificationRunnable1<AvrcpNotificationHandlerWrapper,
void,
BluetoothAvrcpPlayerAttribute>
ListPlayerAppValuesNotification;
typedef BluetoothNotificationRunnable2<AvrcpNotificationHandlerWrapper, void,
uint8_t, nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
uint8_t, const BluetoothAvrcpPlayerAttribute*>
GetPlayerAppValueNotification;
typedef BluetoothNotificationRunnable2<AvrcpNotificationHandlerWrapper, void,
uint8_t, nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
uint8_t, const BluetoothAvrcpPlayerAttribute*>
GetPlayerAppAttrsTextNotification;
typedef BluetoothNotificationRunnable3<AvrcpNotificationHandlerWrapper,
void,
uint8_t, uint8_t,
nsAutoArrayPtr<uint8_t>,
uint8_t, uint8_t, const uint8_t*>
GetPlayerAppValuesTextNotification;
typedef BluetoothNotificationRunnable1<AvrcpNotificationHandlerWrapper,
void,
BluetoothAvrcpPlayerSettings,
const BluetoothAvrcpPlayerSettings&>
SetPlayerAppValueNotification;
typedef BluetoothNotificationRunnable2<AvrcpNotificationHandlerWrapper, void,
uint8_t, nsAutoArrayPtr<BluetoothAvrcpMediaAttribute>,
uint8_t, const BluetoothAvrcpMediaAttribute*>
GetElementAttrNotification;
typedef BluetoothNotificationRunnable2<AvrcpNotificationHandlerWrapper,
void,
BluetoothAvrcpEvent, uint32_t>
RegisterNotificationNotification;
#if ANDROID_VERSION >= 19
typedef BluetoothNotificationRunnable2<AvrcpNotificationHandlerWrapper,
void,
nsString, unsigned long,
const nsAString&>
RemoteFeatureNotification;
typedef BluetoothNotificationRunnable2<AvrcpNotificationHandlerWrapper,
void,
uint8_t, uint8_t>
VolumeChangeNotification;
typedef BluetoothNotificationRunnable2<AvrcpNotificationHandlerWrapper,
void,
int, int>
PassthroughCmdNotification;
#endif // ANDROID_VERSION >= 19
// Bluedroid AVRCP callbacks
static void
GetPlayStatus()
{
GetPlayStatusNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayStatusNotification);
}
static void
ListPlayerAppAttr()
{
ListPlayerAppAttrNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::ListPlayerAppAttrNotification);
}
static void
ListPlayerAppValues(btrc_player_attr_t aAttrId)
{
ListPlayerAppValuesNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::ListPlayerAppValuesNotification,
aAttrId);
}
static void
GetPlayerAppValue(uint8_t aNumAttrs, btrc_player_attr_t* aAttrs)
{
GetPlayerAppValueNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayerAppValueNotification,
aNumAttrs, ConvertArray<btrc_player_attr_t>(aAttrs, aNumAttrs));
}
static void
GetPlayerAppAttrsText(uint8_t aNumAttrs, btrc_player_attr_t* aAttrs)
{
GetPlayerAppAttrsTextNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayerAppAttrsTextNotification,
aNumAttrs, ConvertArray<btrc_player_attr_t>(aAttrs, aNumAttrs));
}
static void
GetPlayerAppValuesText(uint8_t aAttrId, uint8_t aNumVals, uint8_t* aVals)
{
GetPlayerAppValuesTextNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayerAppValuesTextNotification,
aAttrId, aNumVals, ConvertArray<uint8_t>(aVals, aNumVals));
}
static void
SetPlayerAppValue(btrc_player_settings_t* aVals)
{
SetPlayerAppValueNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::SetPlayerAppValueNotification,
*aVals);
}
static void
GetElementAttr(uint8_t aNumAttrs, btrc_media_attr_t* aAttrs)
{
GetElementAttrNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetElementAttrNotification,
aNumAttrs, ConvertArray<btrc_media_attr_t>(aAttrs, aNumAttrs));
}
static void
RegisterNotification(btrc_event_id_t aEvent, uint32_t aParam)
{
RegisterNotificationNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::RegisterNotificationNotification,
aEvent, aParam);
}
#if ANDROID_VERSION >= 19
static void
RemoteFeature(bt_bdaddr_t* aBdAddr, btrc_remote_features_t aFeatures)
{
RemoteFeatureNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::RemoteFeatureNotification,
aBdAddr, aFeatures);
}
static void
VolumeChange(uint8_t aVolume, uint8_t aCType)
{
VolumeChangeNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::VolumeChangeNotification,
aVolume, aCType);
}
static void
PassthroughCmd(int aId, int aKeyState)
{
PassthroughCmdNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::PassthroughCmdNotification,
aId, aKeyState);
}
#endif // ANDROID_VERSION >= 19
};
// Interface
//
BluetoothAvrcpInterface::BluetoothAvrcpInterface(
const btrc_interface_t* aInterface)
@ -2844,10 +3223,34 @@ BluetoothAvrcpInterface::~BluetoothAvrcpInterface()
{ }
void
BluetoothAvrcpInterface::Init(btrc_callbacks_t* aCallbacks,
BluetoothAvrcpResultHandler* aRes)
BluetoothAvrcpInterface::Init(
BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status = mInterface->init(aCallbacks);
static btrc_callbacks_t sCallbacks = {
sizeof(sCallbacks),
#if ANDROID_VERSION >= 19
BluetoothAvrcpCallback::RemoteFeature,
#endif
BluetoothAvrcpCallback::GetPlayStatus,
BluetoothAvrcpCallback::ListPlayerAppAttr,
BluetoothAvrcpCallback::ListPlayerAppValues,
BluetoothAvrcpCallback::GetPlayerAppValue,
BluetoothAvrcpCallback::GetPlayerAppAttrsText,
BluetoothAvrcpCallback::GetPlayerAppValuesText,
BluetoothAvrcpCallback::SetPlayerAppValue,
BluetoothAvrcpCallback::GetElementAttr,
BluetoothAvrcpCallback::RegisterNotification
#if ANDROID_VERSION >= 19
,
BluetoothAvrcpCallback::VolumeChange,
BluetoothAvrcpCallback::PassthroughCmd
#endif
};
sAvrcpNotificationHandler = aNotificationHandler;
bt_status_t status = mInterface->init(&sCallbacks);
if (aRes) {
DispatchBluetoothAvrcpResult(aRes, &BluetoothAvrcpResultHandler::Init,

View File

@ -265,6 +265,26 @@ private:
// Bluetooth Advanced Audio Interface
//
class BluetoothA2dpNotificationHandler
{
public:
virtual ~BluetoothA2dpNotificationHandler();
virtual void
ConnectionStateNotification(BluetoothA2dpConnectionState aState,
const nsAString& aBdAddr)
{ }
virtual void
AudioStateNotification(BluetoothA2dpAudioState aState,
const nsAString& aBdAddr)
{ }
protected:
BluetoothA2dpNotificationHandler()
{ }
};
class BluetoothA2dpResultHandler
{
public:
@ -288,7 +308,7 @@ class BluetoothA2dpInterface
public:
friend class BluetoothInterface;
void Init(btav_callbacks_t *aCallbacks,
void Init(BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes);
void Cleanup(BluetoothA2dpResultHandler* aRes);
@ -309,6 +329,69 @@ private:
// Bluetooth AVRCP Interface
//
class BluetoothAvrcpNotificationHandler
{
public:
virtual ~BluetoothAvrcpNotificationHandler();
virtual void
GetPlayStatusNotification()
{ }
virtual void
ListPlayerAppAttrNotification()
{ }
virtual void
ListPlayerAppValuesNotification(BluetoothAvrcpPlayerAttribute aAttrId)
{ }
virtual void
GetPlayerAppValueNotification(uint8_t aNumAttrs,
const BluetoothAvrcpPlayerAttribute* aAttrs)
{ }
virtual void
GetPlayerAppAttrsTextNotification(uint8_t aNumAttrs,
const BluetoothAvrcpPlayerAttribute* aAttrs)
{ }
virtual void
GetPlayerAppValuesTextNotification(uint8_t aAttrId, uint8_t aNumVals,
const uint8_t* aValues)
{ }
virtual void
SetPlayerAppValueNotification(const BluetoothAvrcpPlayerSettings& aSettings)
{ }
virtual void
GetElementAttrNotification(uint8_t aNumAttrs,
const BluetoothAvrcpMediaAttribute* aAttrs)
{ }
virtual void
RegisterNotificationNotification(BluetoothAvrcpEvent aEvent,
uint32_t aParam)
{ }
virtual void
RemoteFeatureNotification(const nsAString& aBdAddr, unsigned long aFeatures)
{ }
virtual void
VolumeChangeNotification(uint8_t aVolume, uint8_t aCType)
{ }
virtual void
PassthroughCmdNotification(int aId, int aKeyState)
{ }
protected:
BluetoothAvrcpNotificationHandler()
{ }
};
class BluetoothAvrcpResultHandler
{
public:
@ -348,7 +431,7 @@ class BluetoothAvrcpInterface
public:
friend class BluetoothInterface;
void Init(btrc_callbacks_t* aCallbacks,
void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes);
void Cleanup(BluetoothAvrcpResultHandler* aRes);

View File

@ -319,10 +319,13 @@ DroidSocketImpl::OnSocketCanReceiveWithoutBlocking(int aFd)
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(!mShuttingDownOnIOThread);
nsresult rv = ReceiveData(aFd, this);
if (NS_FAILED(rv)) {
ssize_t res = ReceiveData(aFd, this);
if (res < 0) {
/* I/O error */
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
return;
} else if (!res) {
/* EOF or peer shutdown */
RemoveWatchers(READ_WATCHER);
}
}

View File

@ -23,19 +23,6 @@
BEGIN_BLUETOOTH_NAMESPACE
void
BdAddressTypeToString(bt_bdaddr_t* aBdAddressType, nsAString& aRetBdAddress)
{
uint8_t* addr = aBdAddressType->address;
char bdstr[18];
sprintf(bdstr, "%02x:%02x:%02x:%02x:%02x:%02x",
(int)addr[0],(int)addr[1],(int)addr[2],
(int)addr[3],(int)addr[4],(int)addr[5]);
aRetBdAddress = NS_ConvertUTF8toUTF16(bdstr);
}
void
UuidToString(const BluetoothUuid& aUuid, nsAString& aString)
{

View File

@ -7,8 +7,6 @@
#ifndef mozilla_dom_bluetooth_bluetoothutils_h__
#define mozilla_dom_bluetooth_bluetoothutils_h__
#include <hardware/bluetooth.h>
#include "BluetoothCommon.h"
#include "js/TypeDecls.h"
@ -18,14 +16,6 @@ class BluetoothNamedValue;
class BluetoothValue;
class BluetoothReplyRunnable;
void
StringToBdAddressType(const nsAString& aBdAddress,
bt_bdaddr_t *aRetBdAddressType);
void
BdAddressTypeToString(bt_bdaddr_t* aBdAddressType,
nsAString& aRetBdAddress);
void
UuidToString(const BluetoothUuid& aUuid, nsAString& aString);

View File

@ -51,7 +51,7 @@ let tests = [
expect: {name: "send_dtmf_cmd_3_without_alpha_identifier",
commandQualifier: 0x00,
iconSelfExplanatory: true,
icons: [colorIcon]}},
icons: [colorTransparencyIcon]}},
{command: "d01c810301140082028183850953656e642044544d46ac02c1f29e020101",
func: testSendDTMF,
expect: {name: "send_dtmf_cmd_4_with_alpha_identifier",
@ -64,7 +64,7 @@ let tests = [
expect: {name: "send_dtmf_cmd_4_without_alpha_identifier",
commandQualifier: 0x00,
iconSelfExplanatory: false,
icons: [colorIcon]}},
icons: [colorTransparencyIcon]}},
{command: "d028810301140082028183851980041704140420041004120421042204120423041904220415ac02c1f2",
func: testSendDTMF,
expect: {name: "send_dtmf_cmd_5_with_alpha_identifier",

View File

@ -109,7 +109,7 @@ let tests = [
address: "+012340123456,1,2",
iconSelfExplanatory: false,
icons: [colorIcon]}},
{command: "d04c81030110008202818385165365742075702063616c6c2049636f6e20332e342e318609911032042143651c2c9e02000185165365742075702063616c6c2049636f6e20332e342e329e020005",
{command: "d04c81030110008202818385165365742075702063616c6c2049636f6e20332e342e318609911032042143651c2c9e02000185165365742075702063616c6c2049636f6e20332e342e329e020001",
func: testSetupCall,
expect: {name: "setup_call_cmd_13",
commandQualifier: 0x00,
@ -117,7 +117,7 @@ let tests = [
callMessage: "Set up call Icon 3.4.2",
address: "+012340123456,1,2",
iconSelfExplanatory: true,
icons: [colorTransparencyIcon]}},
icons: [basicIcon]}},
{command: "d038810301100082028183850e434f4e4649524d4154494f4e20318609911032042143651c2c850643414c4c2031d004000e00b4d004000600b4",
func: testSetupCall,
expect: {name: "setup_call_cmd_14",

View File

@ -49,7 +49,7 @@ let tests = [
commandQualifier: 0x00,
text: "Idle text",
iconSelfExplanatory: false,
icons: [colorIcon]}},
icons: [colorTransparencyIcon]}},
{command: "d0198103012800820281828d0a0449646c6520746578749e020007",
func: testSetupIdleModeText,
expect: {name: "setup_idle_mode_text_cmd_6",

View File

@ -81,7 +81,9 @@ for (var i = 0; i < testRanges.length; i++) {
}
}
generate_tests(testCollapse, tests);
setup(function () {
generate_tests(testCollapse, tests);
}, { timeout_multiplier: 2 });
testDiv.style.display = "none";
</script>

View File

@ -18,6 +18,10 @@ XPCOMUtils.defineLazyServiceGetter(Services, "fm",
"@mozilla.org/focus-manager;1",
"nsIFocusManager");
XPCOMUtils.defineLazyServiceGetter(Services, "threadManager",
"@mozilla.org/thread-manager;1",
"nsIThreadManager");
XPCOMUtils.defineLazyGetter(this, "domWindowUtils", function () {
return content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
@ -250,9 +254,6 @@ let FormAssistant = {
this._observer.disconnect();
this._observer = null;
}
if (!element) {
this.focusedElement.blur();
}
if (this._selectionPrivate) {
this._selectionPrivate.removeSelectionListener(this);
this._selectionPrivate = null;
@ -298,8 +299,9 @@ let FormAssistant = {
});
});
if (del && element === self.focusedElement) {
// item was deleted, fake a blur so all state gets set correctly
self.handleEvent({ target: element, type: "blur" });
self.hideKeyboard();
self.selectionStart = -1;
self.selectionEnd = -1;
}
});
@ -378,8 +380,13 @@ let FormAssistant = {
break;
}
// fall through
case "blur":
case "submit":
if (this.focusedElement) {
this.focusedElement.blur();
}
break;
case "blur":
if (this.focusedElement) {
this.hideKeyboard();
this.selectionStart = -1;
@ -434,6 +441,13 @@ let FormAssistant = {
}
},
waitForNextTick: function(callback) {
var tm = Services.threadManager;
tm.mainThread.dispatch({
run: callback,
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
},
receiveMessage: function fa_receiveMessage(msg) {
let target = this.focusedElement;
let json = msg.json;
@ -536,7 +550,10 @@ let FormAssistant = {
break;
case "Forms:Select:Blur": {
this.setFocusedElement(null);
if (this.focusedElement) {
this.focusedElement.blur();
}
break;
}
@ -649,15 +666,35 @@ let FormAssistant = {
this.setFocusedElement(target);
let kbOpened = this.sendKeyboardState(target);
if (this.isTextInputElement(target))
this.isKeyboardOpened = kbOpened;
let count = this._focusCounter;
this.waitForNextTick(function fa_showKeyboardSync() {
if (count !== this._focusCounter) {
return;
}
let kbOpened = this.sendKeyboardState(target);
if (this.isTextInputElement(target))
this.isKeyboardOpened = kbOpened;
}.bind(this));
},
hideKeyboard: function fa_hideKeyboard() {
sendAsyncMessage("Forms:Input", { "type": "blur" });
this.isKeyboardOpened = false;
this.setFocusedElement(null);
let count = this._focusCounter;
// Wait for the next tick before unset the focused element and etc.
// If the user move from one input from another,
// the remote process should get one Forms:Input message instead of two.
this.waitForNextTick(function fa_hideKeyboardSync() {
if (count !== this._focusCounter ||
!this.isKeyboardOpened) {
return;
}
this.isKeyboardOpened = false;
sendAsyncMessage("Forms:Input", { "type": "blur" });
}.bind(this));
},
isFocusableElement: function fa_isFocusableElement(element) {
@ -738,7 +775,7 @@ let FormAssistant = {
// one to [0,0] and one to actual value. Both are sent in same tick.
// Prevent firing two events in that scenario, always only use the last 1.
//
// It is also a workaround for Bug 1053048, which prevents
// It is also a workaround for Bug 1053048, which prevents
// getSelectionInfo() accessing selectionStart or selectionEnd in the
// callback function of nsISelectionListener::NotifySelectionChanged().
if (this._selectionTimeout) {

View File

@ -19,3 +19,4 @@ support-files =
[test_bug1043828.html]
[test_delete_focused_element.html]
[test_sendkey_cancel.html]
[test_two_inputs.html]

View File

@ -29,12 +29,17 @@ function appFrameScript() {
content.document.body.appendChild(textarea);
textarea.onfocus = function() {
textarea.parentNode.removeChild(textarea);
sendAsyncMessage('test:InputMethod:finished', {});
content.setTimeout(function() {
textarea.parentNode.removeChild(textarea);
sendAsyncMessage('test:InputMethod:finished', {});
}, 10);
};
content.setTimeout(function() {
textarea.focus();
content.setTimeout(function() {
textarea.focus();
}, 10);
input.parentNode.removeChild(input);
}, 0);
}

View File

@ -0,0 +1,151 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1057898
-->
<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=1057898">Mozilla Bug 1057898</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 input1 = content.document.body.firstElementChild;
let input2 = content.document.body.children[1];
let i = 1;
input1.focus();
addMessageListener('test:next', function() {
i++;
switch (i) {
case 2:
input2.focus();
break;
case 3:
input2.blur();
input2.focus();
break;
case 4:
input2.blur();
break;
case 5:
input2.focus();
input2.blur();
input1.focus();
break;
case 6:
input1.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><input value="First"><input value="Second"></body></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>

View File

@ -174,6 +174,21 @@ MobileConnectionProvider.prototype = {
_getSupportedNetworkTypes: function() {
let key = "ro.moz.ril." + this._clientId + ".network_types";
let supportedNetworkTypes = libcutils.property_get(key, "").split(",");
// If mozRIL system property is not available, fallback to AOSP system
// property for support network types.
if (supportedNetworkTypes.length === 1 && supportedNetworkTypes[0] === "") {
key = "ro.telephony.default_network";
let indexString = libcutils.property_get(key, "");
let index = parseInt(indexString, 10);
if (DEBUG) this._debug("Fallback to " + key + ": " + index)
let networkTypes = RIL.RIL_PREFERRED_NETWORK_TYPE_TO_GECKO[index];
supportedNetworkTypes = networkTypes ?
networkTypes.replace("-auto", "", "g").split("/") :
RIL.GECKO_SUPPORTED_NETWORK_TYPES_DEFAULT.split(",");
}
for (let type of supportedNetworkTypes) {
// If the value in system property is not valid, use the default one which
// is defined in ril_consts.js.
@ -1304,7 +1319,7 @@ MobileConnectionGonkService.prototype = {
notifyUssdReceived: function(aClientId, aMessage, aSessionEnded) {
if (DEBUG) {
debug("notifyUssdReceived for " + aClientId + ": " +
JSON.stringify(ussd));
aMessage + " (sessionEnded : " + aSessionEnded + ")");
}
let provider = this._providers[aClientId];

View File

@ -67,10 +67,7 @@ MozNDEFRecord::DropData()
/* static */
already_AddRefed<MozNDEFRecord>
MozNDEFRecord::Constructor(const GlobalObject& aGlobal,
uint8_t aTnf,
const Optional<Uint8Array>& aType,
const Optional<Uint8Array>& aId,
const Optional<Uint8Array>& aPayload,
const MozNDEFRecordOptions& aOptions,
ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aGlobal.GetAsSupports());
@ -80,8 +77,7 @@ MozNDEFRecord::Constructor(const GlobalObject& aGlobal,
}
nsRefPtr<MozNDEFRecord> ndefrecord = new MozNDEFRecord(aGlobal.Context(),
win, aTnf, aType, aId,
aPayload);
win, aOptions);
if (!ndefrecord) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
@ -90,27 +86,28 @@ MozNDEFRecord::Constructor(const GlobalObject& aGlobal,
}
MozNDEFRecord::MozNDEFRecord(JSContext* aCx, nsPIDOMWindow* aWindow,
uint8_t aTnf,
const Optional<Uint8Array>& aType,
const Optional<Uint8Array>& aId,
const Optional<Uint8Array>& aPayload)
: mTnf(aTnf)
const MozNDEFRecordOptions& aOptions)
{
mWindow = aWindow; // For GetParentObject()
if (aType.WasPassed()) {
aType.Value().ComputeLengthAndData();
mType = Uint8Array::Create(aCx, this, aType.Value().Length(), aType.Value().Data());
mTnf = aOptions.mTnf;
if (aOptions.mType.WasPassed()) {
const Uint8Array& type = aOptions.mType.Value();
type.ComputeLengthAndData();
mType = Uint8Array::Create(aCx, this, type.Length(), type.Data());
}
if (aId.WasPassed()) {
aId.Value().ComputeLengthAndData();
mId = Uint8Array::Create(aCx, this, aId.Value().Length(), aId.Value().Data());
if (aOptions.mId.WasPassed()) {
const Uint8Array& id = aOptions.mId.Value();
id.ComputeLengthAndData();
mId = Uint8Array::Create(aCx, this, id.Length(), id.Data());
}
if (aPayload.WasPassed()) {
aPayload.Value().ComputeLengthAndData();
mPayload = Uint8Array::Create(aCx, this, aPayload.Value().Length(), aPayload.Value().Data());
if (aOptions.mPayload.WasPassed()) {
const Uint8Array& payload = aOptions.mPayload.Value();
payload.ComputeLengthAndData();
mPayload = Uint8Array::Create(aCx, this, payload.Length(), payload.Data());
}
SetIsDOMBinding();

View File

@ -25,6 +25,8 @@ struct JSContext;
namespace mozilla {
namespace dom {
class MozNDEFRecordOptions;
class MozNDEFRecord MOZ_FINAL : public nsISupports,
public nsWrapperCache
{
@ -34,10 +36,8 @@ public:
public:
MozNDEFRecord(JSContext* aCx, nsPIDOMWindow* aWindow, uint8_t aTnf,
const Optional<Uint8Array>& aType,
const Optional<Uint8Array>& aId,
const Optional<Uint8Array>& aPlayload);
MozNDEFRecord(JSContext* aCx, nsPIDOMWindow* aWindow,
const MozNDEFRecordOptions& aOptions);
~MozNDEFRecord();
@ -49,10 +49,9 @@ public:
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
static already_AddRefed<MozNDEFRecord>
Constructor(const GlobalObject& aGlobal, uint8_t aTnf,
const Optional<Uint8Array>& aType,
const Optional<Uint8Array>& aId,
const Optional<Uint8Array>& aPayload, ErrorResult& aRv);
Constructor(const GlobalObject& aGlobal,
const MozNDEFRecordOptions& aOptions,
ErrorResult& aRv);
uint8_t Tnf() const
{

View File

@ -104,9 +104,9 @@ NfcContentHelper.prototype = {
let record = records[i];
encodedRecords.push({
tnf: record.tnf,
type: record.type,
id: record.id,
payload: record.payload,
type: record.type || undefined,
id: record.id || undefined,
payload: record.payload || undefined,
});
}
return encodedRecords;
@ -365,13 +365,11 @@ NfcContentHelper.prototype = {
fireRequestSuccess: function fireRequestSuccess(requestId, result) {
let request = this.takeRequest(requestId);
if (!request) {
debug("not firing success for id: " + requestId +
", result: " + JSON.stringify(result));
debug("not firing success for id: " + requestId);
return;
}
debug("fire request success, id: " + requestId +
", result: " + JSON.stringify(result));
debug("fire request success, id: " + requestId);
Services.DOMRequest.fireSuccess(request, result);
},
@ -389,7 +387,7 @@ NfcContentHelper.prototype = {
},
receiveMessage: function receiveMessage(message) {
debug("Message received: " + JSON.stringify(message));
DEBUG && debug("Message received: " + JSON.stringify(message));
let result = message.json;
switch (message.name) {
@ -445,10 +443,10 @@ NfcContentHelper.prototype = {
let records = result.records;
for (let i = 0; i < records.length; i++) {
let record = records[i];
ndefMsg.push(new requester.MozNDEFRecord(record.tnf,
record.type,
record.id,
record.payload));
ndefMsg.push(new requester.MozNDEFRecord({tnf: record.tnf,
type: record.type,
id: record.id,
payload: record.payload}));
}
this.fireRequestSuccess(requestId, ndefMsg);
},

View File

@ -232,7 +232,8 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
*/
receiveMessage: function receiveMessage(message) {
debug("Received '" + JSON.stringify(message) + "' message from content process");
DEBUG && debug("Received message from content process: " + JSON.stringify(message));
if (message.name == "child-process-shutdown") {
this.removePeerTarget(message.target);
this.nfc.removeTarget(message.target);
@ -398,7 +399,7 @@ Nfc.prototype = {
*/
onEvent: function onEvent(event) {
let message = Cu.cloneInto(event, this);
debug("Received message from NFC Service: " + JSON.stringify(message));
DEBUG && debug("Received message from NFC Service: " + JSON.stringify(message));
// mapping error code to error message
if (message.status !== undefined && message.status !== NFC.NFC_SUCCESS) {

View File

@ -40,28 +40,28 @@ struct CommandOptions
return;
}
mozilla::dom::Sequence<mozilla::dom::NDEFRecord> const & currentValue = aOther.mRecords.InternalValue();
mozilla::dom::Sequence<mozilla::dom::MozNDEFRecordOptions> const & currentValue = aOther.mRecords.InternalValue();
int count = currentValue.Length();
for (uint32_t i = 0; i < count; i++) {
for (int32_t i = 0; i < count; i++) {
NDEFRecordStruct record;
record.mTnf = currentValue[i].mTnf.Value();
record.mTnf = currentValue[i].mTnf;
if (currentValue[i].mType.WasPassed()) {
currentValue[i].mType.Value().ComputeLengthAndData();
record.mType.AppendElements(currentValue[i].mType.Value().Data(),
currentValue[i].mType.Value().Length());
const dom::Uint8Array& type = currentValue[i].mType.Value();
type.ComputeLengthAndData();
record.mType.AppendElements(type.Data(), type.Length());
}
if (currentValue[i].mId.WasPassed()) {
currentValue[i].mId.Value().ComputeLengthAndData();
record.mId.AppendElements(currentValue[i].mId.Value().Data(),
currentValue[i].mId.Value().Length());
const dom::Uint8Array& id = currentValue[i].mId.Value();
id.ComputeLengthAndData();
record.mId.AppendElements(id.Data(), id.Length());
}
if (currentValue[i].mPayload.WasPassed()) {
currentValue[i].mPayload.Value().ComputeLengthAndData();
record.mPayload.AppendElements(currentValue[i].mPayload.Value().Data(),
currentValue[i].mPayload.Value().Length());
const dom::Uint8Array& payload = currentValue[i].mPayload.Value();
payload.ComputeLengthAndData();
record.mPayload.AppendElements(payload.Data(), payload.Length());
}
mRecords.AppendElement(record);

View File

@ -130,10 +130,9 @@ public:
for (int i = 0; i < length; i++) {
NDEFRecordStruct& recordStruct = mEvent.mRecords[i];
NDEFRecord& record = *event.mRecords.Value().AppendElement();
MozNDEFRecordOptions& record = *event.mRecords.Value().AppendElement();
record.mTnf.Construct();
record.mTnf.Value() = recordStruct.mTnf;
record.mTnf = recordStruct.mTnf;
if (recordStruct.mType.Length() > 0) {
record.mType.Construct();

View File

@ -287,11 +287,10 @@ const NDEF = {
}
// and build NDEF array
let ndef = arr.map(function(value) {
let type = new Uint8Array(NfcUtils.fromUTF8(this.atob(value.type)));
let id = new Uint8Array(NfcUtils.fromUTF8(this.atob(value.id)));
let payload =
new Uint8Array(NfcUtils.fromUTF8(this.atob(value.payload)));
return new MozNDEFRecord(value.tnf, type, id, payload);
let type = NfcUtils.fromUTF8(this.atob(value.type));
let id = NfcUtils.fromUTF8(this.atob(value.id));
let payload = NfcUtils.fromUTF8(this.atob(value.payload));
return new MozNDEFRecord({tnf: value.tnf, type: type, id: id, payload: payload});
}, window);
return ndef;
}

View File

@ -7,19 +7,11 @@ MARIONETTE_HEAD_JS = 'head.js';
function testConstructNDEF() {
try {
// omit type, id and payload.
let r = new MozNDEFRecord(0x0);
is(r.type, null, "r.type should be null")
is(r.id, null, "r.id should be null")
is(r.payload, null, "r.payload should be null")
// omit id and payload.
r = new MozNDEFRecord(0x0, new Uint8Array());
is(r.id, null, "r.id should be null")
is(r.payload, null, "r.payload should be null")
// omit payload.
r = new MozNDEFRecord(0x0, new Uint8Array(), new Uint8Array());
is(r.payload, null, "r.payload should be null")
let r = new MozNDEFRecord();
is(r.tnf, 0, "r.tnf should be 0");
is(r.type, null, "r.type should be null");
is(r.id, null, "r.id should be null");
is(r.payload, null, "r.payload should be null");
ok(true);
} catch (e) {

View File

@ -10,10 +10,9 @@ const MARIONETTE_TIMEOUT = 60000;
const MARIONETTE_HEAD_JS = 'head.js';
const MANIFEST_URL = 'app://system.gaiamobile.org/manifest.webapp';
const NDEF_MESSAGE = [new MozNDEFRecord(0x01,
new Uint8Array(0x84),
new Uint8Array(0),
new Uint8Array(0x20))];
const NDEF_MESSAGE = [new MozNDEFRecord({tnf: 0x01,
type: new Uint8Array(0x84),
payload: new Uint8Array(0x20)})];
let nfcPeers = [];

View File

@ -15,10 +15,9 @@ function handleSnep(msg) {
ok(msg.records != null, "msg.records should have values");
isnot(msg.techList.indexOf("NDEF"), -1, "check for correct tech type");
// validate received NDEF message against reference
let ndef = [new MozNDEFRecord(tnf,
new Uint8Array(NfcUtils.fromUTF8(type)),
new Uint8Array(NfcUtils.fromUTF8(id)),
new Uint8Array(NfcUtils.fromUTF8(payload)))];
let ndef = [new MozNDEFRecord({tnf: tnf,
type: NfcUtils.fromUTF8(type),
payload: NfcUtils.fromUTF8(payload)})];
NDEF.compare(ndef, msg.records);
toggleNFC(false).then(runNextTest);
}

View File

@ -144,9 +144,8 @@ function testPeerShouldThrow() {
let peer;
let tnf = NDEF.TNF_WELL_KNOWN;
let type = new Uint8Array(NfcUtils.fromUTF8("U"));
let id = new Uint8Array(NfcUtils.fromUTF8(""));
let payload = new Uint8Array(NfcUtils.fromUTF8("http://www.hi.com"));
let ndef = [new MozNDEFRecord(tnf, type, id, payload)];
let ndef = [new MozNDEFRecord({tnf: tnf, type: type, payload: payload})];
nfc.onpeerready = function (evt) {
log("testPeerShouldThrow peerready");

View File

@ -9,9 +9,8 @@ let url = "https://www.example.com";
function sendNDEF(techType, sessionToken) {
let tnf = NDEF.TNF_WELL_KNOWN;
let type = new Uint8Array(NfcUtils.fromUTF8("U"));
let id = new Uint8Array(NfcUtils.fromUTF8(""));
let payload = new Uint8Array(NfcUtils.fromUTF8(url));
let ndef = [new MozNDEFRecord(tnf, type, id, payload)];
let ndef = [new MozNDEFRecord({tnf: tnf, type: type, payload: payload})];
let peer = window.navigator.mozNfc.getNFCPeer(sessionToken);
let req = peer.sendNDEF(ndef);

View File

@ -13605,10 +13605,12 @@ SimRecordHelperObject.prototype = {
let numInstances = GsmPDUHelper.readHexOctet();
// Correct data length should be 9n+1 or 9n+2. See TS 31.102, sub-clause
// 4.6.1.1.
if (octetLen != (9 * numInstances + 1) ||
octetLen != (9 * numInstances + 2)) {
// Data length is defined as 9n+1 or 9n+2. See TS 31.102, sub-clause
// 4.6.1.1. However, it's likely to have padding appended so we have a
// rather loose check.
if (octetLen < (9 * numInstances + 1)) {
Buf.seekIncoming((octetLen - 1) * Buf.PDU_HEX_OCTET_SIZE);
Buf.readStringDelimiter(strLen);
if (onerror) {
onerror();
}
@ -13629,6 +13631,7 @@ SimRecordHelperObject.prototype = {
GsmPDUHelper.readHexOctet()
};
}
Buf.seekIncoming((octetLen - 9 * numInstances - 1) * Buf.PDU_HEX_OCTET_SIZE);
Buf.readStringDelimiter(strLen);
let instances = [];
@ -13688,6 +13691,8 @@ SimRecordHelperObject.prototype = {
if (octetLen < offset + dataLen) {
// Data length is not enough. See TS 31.102, clause 4.6.1.1, the
// paragraph "Bytes 8 and 9: Length of Image Instance Data."
Buf.seekIncoming(octetLen * Buf.PDU_HEX_OCTET_SIZE);
Buf.readStringDelimiter(strLen);
if (onerror) {
onerror();
}

View File

@ -627,6 +627,19 @@ add_test(function test_reading_img_basic() {
height: 0x05,
codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
body: [0x11, 0x33, 0x55, 0xfe]}]},
{img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06,
/* Padding */
0xff, 0xff],
iidf: [
[/* Header */
0x05, 0x05,
/* Image body */
0x11, 0x33, 0x55, 0xfe]],
expected: [
{width: 0x05,
height: 0x05,
codingScheme: ICC_IMG_CODING_SCHEME_BASIC,
body: [0x11, 0x33, 0x55, 0xfe]}]},
{img: [0x02, 0x10, 0x01, 0x11, 0x4f, 0x04, 0x00, 0x05, 0x00, 0x04, 0x10,
0x01, 0x11, 0x4f, 0x05, 0x00, 0x05, 0x00, 0x04],
iidf: [
@ -770,57 +783,66 @@ add_test(function test_reading_img_length_error() {
let buf = context.Buf;
let io = context.ICCIOHelper;
// Offset is 0x0004.
let img_test = [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x04, 0x00, 0x06];
let iidf_test = [0xff, 0xff, 0xff, // Offset length not enough.
0x05, 0x05, 0x11, 0x22, 0x33, 0xfe];
let test_data = [
{/* Offset length not enough, should be 4. */
img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x04, 0x00, 0x06],
iidf: [0xff, 0xff, 0xff, // Offset.
0x05, 0x05, 0x11, 0x22, 0x33, 0xfe]},
{/* iidf data length not enough, should be 6. */
img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06],
iidf: [0x05, 0x05, 0x11, 0x22, 0x33]}];
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
// Write data size
buf.writeInt32(img_test.length * 2);
function do_test(img, iidf) {
io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
// Write data size
buf.writeInt32(img.length * 2);
// Write data
for (let i = 0; i < img_test.length; i++) {
helper.writeHexOctet(img_test[i]);
}
// Write data
for (let i = 0; i < img.length; i++) {
helper.writeHexOctet(img[i]);
}
// Write string delimiter
buf.writeStringDelimiter(img_test.length * 2);
// Write string delimiter
buf.writeStringDelimiter(img.length * 2);
if (options.callback) {
options.callback(options);
}
};
if (options.callback) {
options.callback(options);
}
};
io.loadTransparentEF = function fakeLoadTransparentEF(options) {
// Write data size
buf.writeInt32(iidf_test.length * 2);
io.loadTransparentEF = function fakeLoadTransparentEF(options) {
// Write data size
buf.writeInt32(iidf.length * 2);
// Write data
for (let i = 0; i < iidf_test.length; i++) {
helper.writeHexOctet(iidf_test[i]);
}
// Write data
for (let i = 0; i < iidf.length; i++) {
helper.writeHexOctet(iidf[i]);
}
// Write string delimiter
buf.writeStringDelimiter(iidf_test.length * 2);
// Write string delimiter
buf.writeStringDelimiter(iidf.length * 2);
if (options.callback) {
options.callback(options);
}
};
if (options.callback) {
options.callback(options);
}
};
let onsuccess = function() {
do_print("onsuccess shouldn't be called.");
do_check_true(false);
};
let onsuccess = function() {
do_print("onsuccess shouldn't be called.");
do_check_true(false);
};
let onerror = function() {
do_print("onerror called as expected.");
do_check_true(true);
};
let onerror = function() {
do_print("onerror called as expected.");
do_check_true(true);
};
record.readIMG(0, onsuccess, onerror);
record.readIMG(0, onsuccess, onerror);
}
for (let i = 0; i < test_data.length; i++) {
do_test(test_data[i].img, test_data[i].iidf);
}
run_next_test();
});
@ -902,8 +924,7 @@ add_test(function test_reading_img_wrong_record_length() {
let io = context.ICCIOHelper;
let test_data = [
[0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06,
0xff, 0xff],
[0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00],
[0x02, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06]];
function do_test(img) {

View File

@ -5,7 +5,7 @@
/* Copyright © 2013 Deutsche Telekom, Inc. */
[Constructor(octet tnf, optional Uint8Array type, optional Uint8Array id, optional Uint8Array payload)]
[Constructor(optional MozNDEFRecordOptions options)]
interface MozNDEFRecord
{
/**
@ -41,3 +41,10 @@ interface MozNDEFRecord
[Constant]
readonly attribute Uint8Array? payload;
};
dictionary MozNDEFRecordOptions {
octet tnf = 0; // default to tnf_empty.
Uint8Array type;
Uint8Array id;
Uint8Array payload;
};

View File

@ -2,14 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
dictionary NDEFRecord
{
byte tnf;
Uint8Array type;
Uint8Array id;
Uint8Array payload;
};
dictionary NfcCommandOptions
{
DOMString type = "";
@ -21,7 +13,7 @@ dictionary NfcCommandOptions
long techType;
sequence<NDEFRecord> records;
sequence<MozNDEFRecordOptions> records;
};
dictionary NfcEventOptions
@ -36,7 +28,7 @@ dictionary NfcEventOptions
long minorVersion;
sequence<NFCTechType> techList;
sequence<NDEFRecord> records;
sequence<MozNDEFRecordOptions> records;
boolean isReadOnly;
boolean canBeMadeReadOnly;

View File

@ -100,13 +100,13 @@ needs-focus == spellcheck-superscript-1.html spellcheck-superscript-1-ref.html
skip-if(B2G) fails-if(Android) needs-focus != spellcheck-superscript-2.html spellcheck-superscript-2-ref.html # bug 783658
needs-focus == 824080-1.html 824080-1-ref.html
needs-focus == 824080-2.html 824080-2-ref.html
needs-focus == 824080-3.html 824080-3-ref.html
needs-focus test-pref(selectioncaret.enabled,false) == 824080-3.html 824080-3-ref.html
needs-focus != 824080-2.html 824080-3.html
needs-focus == 824080-4.html 824080-4-ref.html
needs-focus == 824080-5.html 824080-5-ref.html
needs-focus test-pref(selectioncaret.enabled,false) == 824080-5.html 824080-5-ref.html
needs-focus != 824080-4.html 824080-5.html
needs-focus == 824080-6.html 824080-6-ref.html
needs-focus == 824080-7.html 824080-7-ref.html
needs-focus pref(selectioncaret.enabled,false) == 824080-7.html 824080-7-ref.html
needs-focus != 824080-6.html 824080-7.html
# Bug 674927: copy spellcheck-textarea tests to contenteditable
== spellcheck-contenteditable-attr.html spellcheck-contenteditable-nofocus-ref.html

View File

@ -311,7 +311,7 @@ private:
//
/* |SocketIOBase| is a base class for Socket I/O classes that
* perform operations on the I/O thread. It provides methds
* perform operations on the I/O thread. It provides methods
* for the most common read and write scenarios.
*/
class SocketIOBase
@ -323,46 +323,42 @@ public:
bool HasPendingData() const;
template <typename T>
nsresult ReceiveData(int aFd, T* aIO)
ssize_t ReceiveData(int aFd, T* aIO)
{
MOZ_ASSERT(aFd >= 0);
MOZ_ASSERT(aIO);
do {
nsAutoPtr<UnixSocketRawData> incoming(
new UnixSocketRawData(mMaxReadSize));
nsAutoPtr<UnixSocketRawData> incoming(
new UnixSocketRawData(mMaxReadSize));
ssize_t res =
TEMP_FAILURE_RETRY(read(aFd, incoming->mData, incoming->mSize));
ssize_t res =
TEMP_FAILURE_RETRY(read(aFd, incoming->mData, incoming->mSize));
if (res < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
return NS_OK; /* no more data available */
}
/* an error occored */
nsRefPtr<nsRunnable> r = new SocketIORequestClosingRunnable<T>(aIO);
NS_DispatchToMainThread(r);
return NS_ERROR_FAILURE;
} else if (!res) {
/* EOF or peer shut down sending */
nsRefPtr<nsRunnable> r = new SocketIORequestClosingRunnable<T>(aIO);
NS_DispatchToMainThread(r);
return NS_OK;
}
if (res < 0) {
/* an I/O error occured */
nsRefPtr<nsRunnable> r = new SocketIORequestClosingRunnable<T>(aIO);
NS_DispatchToMainThread(r);
return -1;
} else if (!res) {
/* EOF or peer shut down sending */
nsRefPtr<nsRunnable> r = new SocketIORequestClosingRunnable<T>(aIO);
NS_DispatchToMainThread(r);
return 0;
}
incoming->mSize = res;
#ifdef MOZ_TASK_TRACER
// Make unix socket creation events to be the source events of TaskTracer,
// and originate the rest correlation tasks from here.
AutoSourceEvent taskTracerEvent(SourceEventType::UNIXSOCKET);
// Make unix socket creation events to be the source events of TaskTracer,
// and originate the rest correlation tasks from here.
AutoSourceEvent taskTracerEvent(SourceEventType::UNIXSOCKET);
#endif
incoming->mSize = res;
nsRefPtr<nsRunnable> r =
new SocketIOReceiveRunnable<T>(aIO, incoming.forget());
NS_DispatchToMainThread(r);
} while (true);
nsRefPtr<nsRunnable> r =
new SocketIOReceiveRunnable<T>(aIO, incoming.forget());
NS_DispatchToMainThread(r);
return NS_OK;
return res;
}
template <typename T>

View File

@ -389,10 +389,13 @@ UnixSocketConsumerIO::OnSocketCanReceiveWithoutBlocking()
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984
nsresult rv = ReceiveData(GetFd(), this);
if (NS_FAILED(rv)) {
ssize_t res = ReceiveData(GetFd(), this);
if (res < 0) {
/* I/O error */
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
return;
} else if (!res) {
/* EOF or peer shutdown */
RemoveWatchers(READ_WATCHER);
}
}

View File

@ -0,0 +1,101 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=558663
-->
<head>
<title>Test for Bug 558663</title>
</head>
<body>
<p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=558663">Mozilla Bug 558663</a></p>
<!-- 20x20 of red -->
<iframe id="iframe" src="data:text/html,<img id='image' border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC'>"></iframe>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 558663 **/
var ok = parent.ok;
var SimpleTest = parent.SimpleTest;
var compareSnapshots = parent.compareSnapshots;
var snapshotWindow = parent.snapshotWindow;
var synthesizeMouse = parent.synthesizeMouse;
window.addEventListener("load", runTest, false);
function checkSnapshots(s1, s2, shouldBeEqual, testName) {
var res = compareSnapshots(s1, s2, shouldBeEqual);
if (res[0]) {
ok(true, testName + " snapshots compare correctly");
} else {
ok(false, testName + " snapshots compare incorrectly. snapshot 1: " +
res[1] + " snapshot 2: " + res[2]);
}
}
function runTest() {
document.getElementById("iframe").contentWindow.document.designMode = "on";
// The editor requires the event loop to spin after you turn on design mode
// before it takes effect.
setTimeout(continueTest, 100);
}
function continueTest() {
var win = document.getElementById("iframe").contentWindow;
var doc = win.document;
var image = doc.getElementById("image");
// We want to test that clicking on the image and then clicking on one of the
// draggers doesn't make the draggers disappear.
// clean snapshot
var before = snapshotWindow(win);
// click to get the draggers
synthesizeMouse(image, 1, 1, {type: "mousedown"}, win);
synthesizeMouse(image, 1, 1, {type: "mouseup"}, win);
// mouse over a dragger will change its color, so move the mouse away
synthesizeMouse(doc.documentElement, 50, 50, {type: "mousemove"}, win);
// snapshot with hopefully draggers
var middle = snapshotWindow(win);
// clicking on the top left dragger shouldn't change anything
synthesizeMouse(image, 1, 1, {type: "mousedown"}, win);
synthesizeMouse(image, 1, 1, {type: "mouseup"}, win);
// mouse over a dragger will change its color, so move the mouse away
synthesizeMouse(doc.documentElement, 50, 50, {type: "mousemove"}, win);
// snapshot with hopefully draggers again
var middle2 = snapshotWindow(win);
// click outside the image (but inside the document) to unselect it
synthesizeMouse(doc.documentElement, 50, 50, {type: "mousedown"}, win);
synthesizeMouse(doc.documentElement, 50, 50, {type: "mouseup"}, win);
// and then click outside the document so we don't draw a caret
synthesizeMouse(document.documentElement, 1, 1, {type: "mousedown"}, window);
synthesizeMouse(document.documentElement, 1, 1, {type: "mouseup"}, window);
// hopefully clean snapshot
var end = snapshotWindow(win);
// before == end && middle == middle2 && before/end != middle/middle2
checkSnapshots(before, end, true, "before and after should be the same")
checkSnapshots(middle, middle2, true, "middle two should be the same");
checkSnapshots(before, middle, false, "before and middle should not be the same");
checkSnapshots(before, middle2, false, "before and middle2 should not be the same");
checkSnapshots(middle, end, false, "middle and end should not be the same");
checkSnapshots(middle2, end, false, "middle2 and end should not be the same");
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

View File

@ -30,6 +30,7 @@ support-files =
bug467672-4-ref.html
bug467672-5.html
bug467672-5-ref.html
bug558663.html
bug570378-arabic-1.html
bug570378-arabic-1-ref.html
bug570378-arabic-2.html

View File

@ -1,101 +1,33 @@
<!DOCTYPE HTML>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=558663
-->
<head>
<title>Test for Bug 558663</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=558663">Mozilla Bug 514127</a></p>
<!-- 20x20 of red -->
<iframe id="iframe" src="data:text/html,<img id='image' border='0' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC'>"></iframe>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 558663 **/
SimpleTest.waitForExplicitFinish();
window.addEventListener("load", runTest, false);
function checkSnapshots(s1, s2, shouldBeEqual, testName) {
var res = compareSnapshots(s1, s2, shouldBeEqual);
if (res[0]) {
ok(true, testName + " snapshots compare correctly");
} else {
ok(false, testName + " snapshots compare incorrectly. snapshot 1: " +
res[1] + " snapshot 2: " + res[2]);
}
}
function runTest() {
document.getElementById("iframe").contentWindow.document.designMode = "on";
// The editor requires the event loop to spin after you turn on design mode
// before it takes effect.
setTimeout(continueTest, 100);
}
function continueTest() {
var win = document.getElementById("iframe").contentWindow;
var doc = win.document;
var image = doc.getElementById("image");
// We want to test that clicking on the image and then clicking on one of the
// draggers doesn't make the draggers disappear.
// clean snapshot
var before = snapshotWindow(win);
// click to get the draggers
synthesizeMouse(image, 1, 1, {type: "mousedown"}, win);
synthesizeMouse(image, 1, 1, {type: "mouseup"}, win);
// mouse over a dragger will change its color, so move the mouse away
synthesizeMouse(doc.documentElement, 50, 50, {type: "mousemove"}, win);
// snapshot with hopefully draggers
var middle = snapshotWindow(win);
// clicking on the top left dragger shouldn't change anything
synthesizeMouse(image, 1, 1, {type: "mousedown"}, win);
synthesizeMouse(image, 1, 1, {type: "mouseup"}, win);
// mouse over a dragger will change its color, so move the mouse away
synthesizeMouse(doc.documentElement, 50, 50, {type: "mousemove"}, win);
// snapshot with hopefully draggers again
var middle2 = snapshotWindow(win);
// click outside the image (but inside the document) to unselect it
synthesizeMouse(doc.documentElement, 50, 50, {type: "mousedown"}, win);
synthesizeMouse(doc.documentElement, 50, 50, {type: "mouseup"}, win);
// and then click outside the document so we don't draw a caret
synthesizeMouse(document.documentElement, 1, 1, {type: "mousedown"}, window);
synthesizeMouse(document.documentElement, 1, 1, {type: "mouseup"}, window);
// hopefully clean snapshot
var end = snapshotWindow(win);
// before == end && middle == middle2 && before/end != middle/middle2
checkSnapshots(before, end, true, "before and after should be the same")
checkSnapshots(middle, middle2, true, "middle two should be the same");
checkSnapshots(before, middle, false, "before and middle should not be the same");
checkSnapshots(before, middle2, false, "before and middle2 should not be the same");
checkSnapshots(middle, end, false, "middle and end should not be the same");
checkSnapshots(middle2, end, false, "middle2 and end should not be the same");
SimpleTest.finish();
}
</script>
</pre>
</body>
<head>
<title>Bug 558663 test</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
iframe {
width: 600px;
height: 400px;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
<script>
SimpleTest.waitForExplicitFinish();
// Selection caret's pref is checked only when PresShell is initialized. To turn
// off the pref, we test bug 558663 in an iframe.
SpecialPowers.pushPrefEnv({"set": [['selectioncaret.enabled', false]]}, function() {
var iframe = document.createElement("iframe");
iframe.src = "bug558663.html";
document.getElementById('container').appendChild(iframe);
});
</script>
</html>