mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 20:17:37 +00:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
b0bf38ca22
@ -100,11 +100,11 @@ let AdbController = {
|
||||
return;
|
||||
}
|
||||
let storage = this.storages[storageIndex];
|
||||
DEBUG && debug("Checking availability of storage: '" + storage.storageName);
|
||||
DEBUG && debug("Checking availability of storage: '" + storage.storageName + "'");
|
||||
|
||||
let req = storage.available();
|
||||
req.onsuccess = function(e) {
|
||||
DEBUG && debug("Storage: '" + storage.storageName + "' is '" + e.target.result);
|
||||
DEBUG && debug("Storage: '" + storage.storageName + "' is '" + e.target.result + "'");
|
||||
if (e.target.result == 'shared') {
|
||||
// We've found a storage area that's being shared with the PC.
|
||||
// We can stop looking now.
|
||||
@ -216,6 +216,11 @@ let AdbController = {
|
||||
// Configure adb.
|
||||
let currentConfig = libcutils.property_get("persist.sys.usb.config");
|
||||
let configFuncs = currentConfig.split(",");
|
||||
if (currentConfig == "" || currentConfig == "none") {
|
||||
// We want to treat none like the empty string.
|
||||
// "".split(",") yields [""] and not []
|
||||
configFuncs = [];
|
||||
}
|
||||
let adbIndex = configFuncs.indexOf("adb");
|
||||
|
||||
if (enableAdb) {
|
||||
@ -230,6 +235,11 @@ let AdbController = {
|
||||
}
|
||||
}
|
||||
let newConfig = configFuncs.join(",");
|
||||
if (newConfig == "") {
|
||||
// Convert the empty string back into none, since that's what init.rc
|
||||
// needs.
|
||||
newConfig = "none";
|
||||
}
|
||||
if (newConfig != currentConfig) {
|
||||
DEBUG && debug("updateState: currentConfig = " + currentConfig);
|
||||
DEBUG && debug("updateState: newConfig = " + newConfig);
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<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="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
|
@ -19,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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<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="67f2907bc340bad250b4ea6ce2902b52896c9ef0"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<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="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<!-- 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"/>
|
||||
|
@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<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="67f2907bc340bad250b4ea6ce2902b52896c9ef0"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<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="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<!-- 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"/>
|
||||
|
@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "65b7d35ad078b90133481983950c64ad8fd27dd4",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
"revision": "a7c053f5e582c15255c49645b07a19d72e4e5cb2",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<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="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
|
||||
|
@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<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="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
|
@ -509,8 +509,8 @@ SocialShare = {
|
||||
iframe.setAttribute("disableglobalhistory", "true");
|
||||
iframe.setAttribute("flex", "1");
|
||||
panel.appendChild(iframe);
|
||||
iframe.addEventListener("DOMContentLoaded", function _firstload() {
|
||||
iframe.removeEventListener("DOMContentLoaded", _firstload, true);
|
||||
iframe.addEventListener("load", function _firstload() {
|
||||
iframe.removeEventListener("load", _firstload, true);
|
||||
iframe.messageManager.loadFrameScript("chrome://browser/content/content.js", true);
|
||||
}, true);
|
||||
this.populateProviderMenu();
|
||||
|
@ -94,6 +94,15 @@ this.BingTranslator.prototype = {
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets the expiration time of the current token, in order to
|
||||
* force the token manager to ask for a new token during the next request.
|
||||
*/
|
||||
_resetToken : function() {
|
||||
// Force the token manager to get update token
|
||||
BingTokenManager._currentExpiryTime = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Function called when a request sent to the server completed successfully.
|
||||
* This function handles calling the function to parse the result and the
|
||||
@ -115,17 +124,19 @@ this.BingTranslator.prototype = {
|
||||
/**
|
||||
* Function called when a request sent to the server has failed.
|
||||
* This function handles deciding if the error is transient or means the
|
||||
* service is unavailable (zero balance on the key) and calling the
|
||||
* function to resolve the promise returned by the public `translate()`
|
||||
* method when there's no pending request left.
|
||||
* service is unavailable (zero balance on the key or request credentials are
|
||||
* not in an active state) and calling the function to resolve the promise
|
||||
* returned by the public `translate()` method when there's no pending.
|
||||
* request left.
|
||||
*
|
||||
* @param aError [optional] The RESTRequest that failed.
|
||||
*/
|
||||
_chunkFailed: function(aError) {
|
||||
if (aError instanceof RESTRequest &&
|
||||
aError.response.status == 400) {
|
||||
[400, 401].indexOf(aError.response.status) != -1) {
|
||||
let body = aError.response.body;
|
||||
if (body.contains("TranslateApiException") && body.contains("balance"))
|
||||
if (body.contains("TranslateApiException") &&
|
||||
(body.contains("balance") || body.contains("active state")))
|
||||
this._serviceUnavailable = true;
|
||||
}
|
||||
|
||||
|
@ -128,6 +128,13 @@ function checkAuth(req) {
|
||||
let auth = req.getHeader("Authorization");
|
||||
if (!auth.startsWith("Bearer "))
|
||||
throw new HTTPError(401, "Invalid Authorization header content: '" + auth + "'");
|
||||
|
||||
// Rejecting inactive subscriptions.
|
||||
if (auth.contains("inactive")) {
|
||||
const INACTIVE_STATE_RESPONSE = "<html><body><h1>TranslateApiException</h1><p>Method: TranslateArray()</p><p>Message: The Azure Market Place Translator Subscription associated with the request credentials is not in an active state.</p><code></code><p>message id=5641.V2_Rest.TranslateArray.48CC6470</p></body></html>";
|
||||
throw new HTTPError(401, INACTIVE_STATE_RESPONSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function reallyHandleRequest(req, res) {
|
||||
@ -189,8 +196,17 @@ const methodHandlers = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Defines the tokens for certain client ids.
|
||||
const TOKEN_MAP = {
|
||||
'testInactive' : 'inactive',
|
||||
'testClient' : 'test'
|
||||
};
|
||||
let token = 'test'; // Default token.
|
||||
if((params.client_id in TOKEN_MAP)){
|
||||
token = TOKEN_MAP[params.client_id];
|
||||
}
|
||||
let content = JSON.stringify({
|
||||
access_token: "test",
|
||||
access_token: token,
|
||||
expires_in: 600
|
||||
});
|
||||
|
||||
|
@ -11,46 +11,111 @@ const kClientSecretPref = "browser.translation.bing.apiKeyOverride";
|
||||
|
||||
const {BingTranslator} = Cu.import("resource:///modules/translation/BingTranslator.jsm", {});
|
||||
const {TranslationDocument} = Cu.import("resource:///modules/translation/TranslationDocument.jsm", {});
|
||||
const {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
add_task(function* setup() {
|
||||
Services.prefs.setCharPref(kClientIdPref, "testClient");
|
||||
Services.prefs.setCharPref(kClientSecretPref, "testSecret");
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(kClientIdPref);
|
||||
Services.prefs.clearUserPref(kClientSecretPref);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks if the translation is happening.
|
||||
*/
|
||||
add_task(function* test_bing_translation() {
|
||||
|
||||
// Ensure the correct client id is used for authentication.
|
||||
Services.prefs.setCharPref(kClientIdPref, "testClient");
|
||||
|
||||
// Loading the fixture page.
|
||||
let url = constructFixtureURL("bug1022725-fr.html");
|
||||
let tab = yield promiseTestPageLoad(url);
|
||||
|
||||
// Translating the contents of the loaded tab.
|
||||
gBrowser.selectedTab = tab;
|
||||
let browser = tab.linkedBrowser;
|
||||
let client = new BingTranslator(
|
||||
new TranslationDocument(browser.contentDocument), "fr", "en");
|
||||
let result = yield client.translate();
|
||||
|
||||
// XXXmikedeboer; here you would continue the test/ content inspection.
|
||||
Assert.ok(result, "There should be a result.");
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
/**
|
||||
* Ensures that the BingTranslator handles out-of-valid-key response
|
||||
* correctly. Sometimes Bing Translate replies with
|
||||
* "request credentials is not in an active state" error. BingTranslator
|
||||
* should catch this error and classify it as Service Unavailable.
|
||||
*
|
||||
*/
|
||||
add_task(function* test_handling_out_of_valid_key_error() {
|
||||
|
||||
// Simulating request from inactive subscription.
|
||||
Services.prefs.setCharPref(kClientIdPref, "testInactive");
|
||||
|
||||
// Loading the fixture page.
|
||||
let url = constructFixtureURL("bug1022725-fr.html");
|
||||
let tab = yield promiseTestPageLoad(url);
|
||||
|
||||
// Translating the contents of the loaded tab.
|
||||
gBrowser.selectedTab = tab;
|
||||
let browser = tab.linkedBrowser;
|
||||
let client = new BingTranslator(
|
||||
new TranslationDocument(browser.contentDocument), "fr", "en");
|
||||
client._resetToken();
|
||||
try {
|
||||
yield client.translate();
|
||||
} catch (ex) {
|
||||
// It is alright that the translation fails.
|
||||
}
|
||||
client._resetToken();
|
||||
|
||||
// Checking if the client detected service and unavailable.
|
||||
Assert.ok(client._serviceUnavailable, "Service should be detected unavailable.");
|
||||
|
||||
// Cleaning up.
|
||||
Services.prefs.setCharPref(kClientIdPref, "testClient");
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
/**
|
||||
* A helper function for constructing a URL to a page stored in the
|
||||
* local fixture folder.
|
||||
*
|
||||
* @param filename Name of a fixture file.
|
||||
*/
|
||||
function constructFixtureURL(filename){
|
||||
// Deduce the Mochitest server address in use from a pref that was pre-processed.
|
||||
let server = Services.prefs.getCharPref("browser.translation.bing.authURL")
|
||||
.replace("http://", "");
|
||||
server = server.substr(0, server.indexOf("/"));
|
||||
let tab = gBrowser.addTab("http://" + server +
|
||||
"/browser/browser/components/translation/test/fixtures/bug1022725-fr.html");
|
||||
gBrowser.selectedTab = tab;
|
||||
let url = "http://" + server +
|
||||
"/browser/browser/components/translation/test/fixtures/" + filename;
|
||||
return url;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gBrowser.removeTab(tab);
|
||||
Services.prefs.clearUserPref(kClientIdPref);
|
||||
Services.prefs.clearUserPref(kClientSecretPref);
|
||||
});
|
||||
|
||||
let browser = tab.linkedBrowser;
|
||||
browser.addEventListener("load", function onload() {
|
||||
/**
|
||||
* A helper function to open a new tab and wait for its content to load.
|
||||
*
|
||||
* @param String url A URL to be loaded in the new tab.
|
||||
*/
|
||||
function promiseTestPageLoad(url) {
|
||||
let deferred = Promise.defer();
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
browser.addEventListener("load", function listener() {
|
||||
if (browser.currentURI.spec == "about:blank")
|
||||
return;
|
||||
|
||||
browser.removeEventListener("load", onload, true);
|
||||
let client = new BingTranslator(
|
||||
new TranslationDocument(browser.contentDocument), "fr", "en");
|
||||
|
||||
client.translate().then(
|
||||
result => {
|
||||
// XXXmikedeboer; here you would continue the test/ content inspection.
|
||||
ok(result, "There should be a result.");
|
||||
finish();
|
||||
},
|
||||
error => {
|
||||
ok(false, "Unexpected Client Error: " + error);
|
||||
finish();
|
||||
}
|
||||
);
|
||||
info("Page loaded: " + browser.currentURI.spec);
|
||||
browser.removeEventListener("load", listener, true);
|
||||
deferred.resolve(tab);
|
||||
}, true);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
--tab-selection-box-shadow: 0 2px 0 #d7f1ff inset,
|
||||
0 8px 3px -5px #2b82bf inset,
|
||||
0 -1px 0 rgba(0,0,0,.2) inset;
|
||||
--pinned-tab-glow: radial-gradient(22px at center calc(100% - 2px), rgba(76,158,217,0.9) 13%, rgba(0,0,0,0.4) 16%, transparent 70%);
|
||||
|
||||
/* Toolbar buttons */
|
||||
--toolbarbutton-hover-background: rgba(25,33, 38,.6) linear-gradient(rgba(25,33,38,.6), rgba(25,33,38,.6)) padding-box;
|
||||
@ -97,6 +98,8 @@
|
||||
--tab-selection-box-shadow: 0 2px 0 #d7f1ff inset,
|
||||
0 8px 3px -5px #319BDB inset,
|
||||
0 -1px 0 #2A7CB1 inset;
|
||||
--pinned-tab-glow: radial-gradient(22px at center calc(100% - 2px), rgba(76,158,217,0.9) 13%, transparent 16%);
|
||||
|
||||
|
||||
/* Toolbar buttons */
|
||||
--toolbarbutton-hover-background: #D7D7D8;
|
||||
@ -281,7 +284,7 @@ window:not([chromehidden~="toolbar"]) #urlbar-wrapper {
|
||||
|
||||
.tabbrowser-tab[pinned][titlechanged]:not([selected="true"]) > .tab-stack > .tab-content {
|
||||
/* The -2px in `calc` is the height of `tabToolbarNavbarOverlap` plus a 1px offset from the center */
|
||||
background-image: radial-gradient(22px at center calc(100% - 2px), rgba(76,158,217,0.9) 13%, rgba(0,0,0,0.4) 16%, rgba(29,79,115,0) 70%);
|
||||
background-image: var(--pinned-tab-glow);
|
||||
background-position: center;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ support-files =
|
||||
|
||||
[test_app_enabled.html]
|
||||
[test_app_update.html]
|
||||
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
|
||||
[test_bug_795164.html]
|
||||
[test_import_export.html]
|
||||
[test_install_multiple_apps_origin.html]
|
||||
@ -42,3 +43,4 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
|
||||
[test_theme_role.html]
|
||||
[test_web_app_install.html]
|
||||
[test_widget.html]
|
||||
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
|
||||
|
@ -531,6 +531,7 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||
mLastCommand = 0;
|
||||
mPutPacketReceivedLength = 0;
|
||||
mDsFile = nullptr;
|
||||
mDummyDsFile = nullptr;
|
||||
|
||||
// We can't reset mSuccessFlag here since this function may be called
|
||||
// before we send system message of transfer complete
|
||||
@ -557,6 +558,34 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::RecoverFileName()
|
||||
{
|
||||
// Remove the trailing ".part" file name from mDsFile by two steps
|
||||
// 1. mDsFile->SetPath() so that the notification sent to Gaia will carry
|
||||
// correct information of the file.
|
||||
// 2. mDsFile->mFile->RenameTo() so that the file name would actually be
|
||||
// changed in file system.
|
||||
if (mDsFile && mDsFile->mFile) {
|
||||
nsString path;
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
|
||||
mDsFile->SetPath(path);
|
||||
mDsFile->mFile->RenameTo(nullptr, mFileName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::DeleteDummyFile()
|
||||
{
|
||||
// Remove the empty temp file
|
||||
if (mDummyDsFile && mDummyDsFile->mFile) {
|
||||
mDummyDsFile->mFile->Remove(false);
|
||||
mDummyDsFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::DeleteReceivedFile()
|
||||
{
|
||||
@ -569,6 +598,8 @@ BluetoothOppManager::DeleteReceivedFile()
|
||||
mDsFile->mFile->Remove(false);
|
||||
mDsFile = nullptr;
|
||||
}
|
||||
|
||||
DeleteDummyFile();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -576,25 +607,39 @@ BluetoothOppManager::CreateFile()
|
||||
{
|
||||
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
|
||||
|
||||
// Create one dummy file to be a placeholder for the target file name, and
|
||||
// create another file with a meaningless file extension to write the received
|
||||
// data. By doing this, we can prevent applications from parsing incomplete
|
||||
// data in the middle of the receiving process.
|
||||
nsString path;
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
|
||||
mDsFile = DeviceStorageFile::CreateUnique(
|
||||
path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
// Use an empty dummy file object to occupy the file name, so that after the
|
||||
// whole file has been received successfully by using mDsFile, we could just
|
||||
// remove mDummyDsFile and rename mDsFile to the file name of mDummyDsFile.
|
||||
mDummyDsFile =
|
||||
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
NS_ENSURE_TRUE(mDummyDsFile, false);
|
||||
|
||||
// The function CreateUnique() may create a file with a different file
|
||||
// name from the original mFileName. Therefore we have to retrieve
|
||||
// the file name again.
|
||||
mDummyDsFile->mFile->GetLeafName(mFileName);
|
||||
|
||||
BT_LOGR("mFileName: %s", NS_ConvertUTF16toUTF8(mFileName).get());
|
||||
|
||||
// Prepare the entire file path for the .part file
|
||||
path.Truncate();
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
path.AppendLiteral(".part");
|
||||
|
||||
mDsFile =
|
||||
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
NS_ENSURE_TRUE(mDsFile, false);
|
||||
|
||||
nsCOMPtr<nsIFile> f;
|
||||
mDsFile->mFile->Clone(getter_AddRefs(f));
|
||||
|
||||
/*
|
||||
* The function CreateUnique() may create a file with a different file
|
||||
* name from the original mFileName. Therefore we have to retrieve
|
||||
* the file name again.
|
||||
*/
|
||||
f->GetLeafName(mFileName);
|
||||
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mDsFile->mFile);
|
||||
NS_ENSURE_TRUE(mOutputStream, false);
|
||||
|
||||
return true;
|
||||
@ -911,6 +956,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
|
||||
// Success to receive a file and notify completion
|
||||
if (mPutFinalFlag) {
|
||||
mSuccessFlag = true;
|
||||
|
||||
DeleteDummyFile();
|
||||
RecoverFileName();
|
||||
|
||||
FileTransferComplete();
|
||||
NotifyAboutFileChange();
|
||||
}
|
||||
|
@ -85,6 +85,8 @@ private:
|
||||
void ReceivingFileConfirmation();
|
||||
bool CreateFile();
|
||||
bool WriteToFile(const uint8_t* aData, int aDataLength);
|
||||
void RecoverFileName();
|
||||
void DeleteDummyFile();
|
||||
void DeleteReceivedFile();
|
||||
void ReplyToConnect();
|
||||
void ReplyToDisconnectOrAbort();
|
||||
@ -209,6 +211,7 @@ private:
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
nsCOMPtr<nsIVolumeMountLock> mMountLock;
|
||||
nsRefPtr<DeviceStorageFile> mDsFile;
|
||||
nsRefPtr<DeviceStorageFile> mDummyDsFile;
|
||||
|
||||
// If a connection has been established, mSocket will be the socket
|
||||
// communicating with the remote socket. We maintain the invariant that if
|
||||
|
@ -553,6 +553,7 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||
mLastCommand = 0;
|
||||
mPutPacketReceivedLength = 0;
|
||||
mDsFile = nullptr;
|
||||
mDummyDsFile = nullptr;
|
||||
|
||||
// We can't reset mSuccessFlag here since this function may be called
|
||||
// before we send system message of transfer complete
|
||||
@ -579,6 +580,34 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::RecoverFileName()
|
||||
{
|
||||
// Remove the trailing ".part" file name from mDsFile by two steps
|
||||
// 1. mDsFile->SetPath() so that the notification sent to Gaia will carry
|
||||
// correct information of the file.
|
||||
// 2. mDsFile->mFile->RenameTo() so that the file name would actually be
|
||||
// changed in file system.
|
||||
if (mDsFile && mDsFile->mFile) {
|
||||
nsString path;
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
|
||||
mDsFile->SetPath(path);
|
||||
mDsFile->mFile->RenameTo(nullptr, mFileName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::DeleteDummyFile()
|
||||
{
|
||||
// Remove the empty temp file
|
||||
if (mDummyDsFile && mDummyDsFile->mFile) {
|
||||
mDummyDsFile->mFile->Remove(false);
|
||||
mDummyDsFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::DeleteReceivedFile()
|
||||
{
|
||||
@ -591,6 +620,8 @@ BluetoothOppManager::DeleteReceivedFile()
|
||||
mDsFile->mFile->Remove(false);
|
||||
mDsFile = nullptr;
|
||||
}
|
||||
|
||||
DeleteDummyFile();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -598,25 +629,39 @@ BluetoothOppManager::CreateFile()
|
||||
{
|
||||
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
|
||||
|
||||
// Create one dummy file to be a placeholder for the target file name, and
|
||||
// create another file with a meaningless file extension to write the received
|
||||
// data. By doing this, we can prevent applications from parsing incomplete
|
||||
// data in the middle of the receiving process.
|
||||
nsString path;
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
|
||||
mDsFile = DeviceStorageFile::CreateUnique(
|
||||
path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
// Use an empty dummy file object to occupy the file name, so that after the
|
||||
// whole file has been received successfully by using mDsFile, we could just
|
||||
// remove mDummyDsFile and rename mDsFile to the file name of mDummyDsFile.
|
||||
mDummyDsFile =
|
||||
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
NS_ENSURE_TRUE(mDummyDsFile, false);
|
||||
|
||||
// The function CreateUnique() may create a file with a different file
|
||||
// name from the original mFileName. Therefore we have to retrieve
|
||||
// the file name again.
|
||||
mDummyDsFile->mFile->GetLeafName(mFileName);
|
||||
|
||||
BT_LOGR("mFileName: %s", NS_ConvertUTF16toUTF8(mFileName).get());
|
||||
|
||||
// Prepare the entire file path for the .part file
|
||||
path.Truncate();
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
path.AppendLiteral(".part");
|
||||
|
||||
mDsFile =
|
||||
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
NS_ENSURE_TRUE(mDsFile, false);
|
||||
|
||||
nsCOMPtr<nsIFile> f;
|
||||
mDsFile->mFile->Clone(getter_AddRefs(f));
|
||||
|
||||
/*
|
||||
* The function CreateUnique() may create a file with a different file
|
||||
* name from the original mFileName. Therefore we have to retrieve
|
||||
* the file name again.
|
||||
*/
|
||||
f->GetLeafName(mFileName);
|
||||
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mDsFile->mFile);
|
||||
NS_ENSURE_TRUE(mOutputStream, false);
|
||||
|
||||
return true;
|
||||
@ -932,6 +977,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
|
||||
// Success to receive a file and notify completion
|
||||
if (mPutFinalFlag) {
|
||||
mSuccessFlag = true;
|
||||
|
||||
DeleteDummyFile();
|
||||
RecoverFileName();
|
||||
|
||||
FileTransferComplete();
|
||||
NotifyAboutFileChange();
|
||||
}
|
||||
|
@ -85,6 +85,8 @@ private:
|
||||
void ReceivingFileConfirmation();
|
||||
bool CreateFile();
|
||||
bool WriteToFile(const uint8_t* aData, int aDataLength);
|
||||
void RecoverFileName();
|
||||
void DeleteDummyFile();
|
||||
void DeleteReceivedFile();
|
||||
void ReplyToConnect();
|
||||
void ReplyToDisconnectOrAbort();
|
||||
@ -209,6 +211,7 @@ private:
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
nsCOMPtr<nsIVolumeMountLock> mMountLock;
|
||||
nsRefPtr<DeviceStorageFile> mDsFile;
|
||||
nsRefPtr<DeviceStorageFile> mDummyDsFile;
|
||||
|
||||
// If a connection has been established, mSocket will be the socket
|
||||
// communicating with the remote socket. We maintain the invariant that if
|
||||
|
@ -531,6 +531,7 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||
mLastCommand = 0;
|
||||
mPutPacketReceivedLength = 0;
|
||||
mDsFile = nullptr;
|
||||
mDummyDsFile = nullptr;
|
||||
|
||||
// We can't reset mSuccessFlag here since this function may be called
|
||||
// before we send system message of transfer complete
|
||||
@ -557,6 +558,34 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::RecoverFileName()
|
||||
{
|
||||
// Remove the trailing ".part" file name from mDsFile by two steps
|
||||
// 1. mDsFile->SetPath() so that the notification sent to Gaia will carry
|
||||
// correct information of the file.
|
||||
// 2. mDsFile->mFile->RenameTo() so that the file name would actually be
|
||||
// changed in file system.
|
||||
if (mDsFile && mDsFile->mFile) {
|
||||
nsString path;
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
|
||||
mDsFile->SetPath(path);
|
||||
mDsFile->mFile->RenameTo(nullptr, mFileName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::DeleteDummyFile()
|
||||
{
|
||||
// Remove the empty temp file
|
||||
if (mDummyDsFile && mDummyDsFile->mFile) {
|
||||
mDummyDsFile->mFile->Remove(false);
|
||||
mDummyDsFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::DeleteReceivedFile()
|
||||
{
|
||||
@ -569,6 +598,8 @@ BluetoothOppManager::DeleteReceivedFile()
|
||||
mDsFile->mFile->Remove(false);
|
||||
mDsFile = nullptr;
|
||||
}
|
||||
|
||||
DeleteDummyFile();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -576,25 +607,39 @@ BluetoothOppManager::CreateFile()
|
||||
{
|
||||
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
|
||||
|
||||
// Create one dummy file to be a placeholder for the target file name, and
|
||||
// create another file with a meaningless file extension to write the received
|
||||
// data. By doing this, we can prevent applications from parsing incomplete
|
||||
// data in the middle of the receiving process.
|
||||
nsString path;
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
|
||||
mDsFile = DeviceStorageFile::CreateUnique(
|
||||
path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
// Use an empty dummy file object to occupy the file name, so that after the
|
||||
// whole file has been received successfully by using mDsFile, we could just
|
||||
// remove mDummyDsFile and rename mDsFile to the file name of mDummyDsFile.
|
||||
mDummyDsFile =
|
||||
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
NS_ENSURE_TRUE(mDummyDsFile, false);
|
||||
|
||||
// The function CreateUnique() may create a file with a different file
|
||||
// name from the original mFileName. Therefore we have to retrieve
|
||||
// the file name again.
|
||||
mDummyDsFile->mFile->GetLeafName(mFileName);
|
||||
|
||||
BT_LOGR("mFileName: %s", NS_ConvertUTF16toUTF8(mFileName).get());
|
||||
|
||||
// Prepare the entire file path for the .part file
|
||||
path.Truncate();
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
path.AppendLiteral(".part");
|
||||
|
||||
mDsFile =
|
||||
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
NS_ENSURE_TRUE(mDsFile, false);
|
||||
|
||||
nsCOMPtr<nsIFile> f;
|
||||
mDsFile->mFile->Clone(getter_AddRefs(f));
|
||||
|
||||
/*
|
||||
* The function CreateUnique() may create a file with a different file
|
||||
* name from the original mFileName. Therefore we have to retrieve
|
||||
* the file name again.
|
||||
*/
|
||||
f->GetLeafName(mFileName);
|
||||
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mDsFile->mFile);
|
||||
NS_ENSURE_TRUE(mOutputStream, false);
|
||||
|
||||
return true;
|
||||
@ -911,6 +956,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
|
||||
// Success to receive a file and notify completion
|
||||
if (mPutFinalFlag) {
|
||||
mSuccessFlag = true;
|
||||
|
||||
DeleteDummyFile();
|
||||
RecoverFileName();
|
||||
|
||||
FileTransferComplete();
|
||||
NotifyAboutFileChange();
|
||||
}
|
||||
|
@ -85,6 +85,8 @@ private:
|
||||
void ReceivingFileConfirmation();
|
||||
bool CreateFile();
|
||||
bool WriteToFile(const uint8_t* aData, int aDataLength);
|
||||
void RecoverFileName();
|
||||
void DeleteDummyFile();
|
||||
void DeleteReceivedFile();
|
||||
void ReplyToConnect();
|
||||
void ReplyToDisconnectOrAbort();
|
||||
@ -209,6 +211,7 @@ private:
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
nsCOMPtr<nsIVolumeMountLock> mMountLock;
|
||||
nsRefPtr<DeviceStorageFile> mDsFile;
|
||||
nsRefPtr<DeviceStorageFile> mDummyDsFile;
|
||||
|
||||
// If a connection has been established, mSocket will be the socket
|
||||
// communicating with the remote socket. We maintain the invariant that if
|
||||
|
@ -553,6 +553,7 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||
mLastCommand = 0;
|
||||
mPutPacketReceivedLength = 0;
|
||||
mDsFile = nullptr;
|
||||
mDummyDsFile = nullptr;
|
||||
|
||||
// We can't reset mSuccessFlag here since this function may be called
|
||||
// before we send system message of transfer complete
|
||||
@ -579,6 +580,34 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::RecoverFileName()
|
||||
{
|
||||
// Remove the trailing ".part" file name from mDsFile by two steps
|
||||
// 1. mDsFile->SetPath() so that the notification sent to Gaia will carry
|
||||
// correct information of the file.
|
||||
// 2. mDsFile->mFile->RenameTo() so that the file name would actually be
|
||||
// changed in file system.
|
||||
if (mDsFile && mDsFile->mFile) {
|
||||
nsString path;
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
|
||||
mDsFile->SetPath(path);
|
||||
mDsFile->mFile->RenameTo(nullptr, mFileName);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::DeleteDummyFile()
|
||||
{
|
||||
// Remove the empty temp file
|
||||
if (mDummyDsFile && mDummyDsFile->mFile) {
|
||||
mDummyDsFile->mFile->Remove(false);
|
||||
mDummyDsFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothOppManager::DeleteReceivedFile()
|
||||
{
|
||||
@ -591,6 +620,8 @@ BluetoothOppManager::DeleteReceivedFile()
|
||||
mDsFile->mFile->Remove(false);
|
||||
mDsFile = nullptr;
|
||||
}
|
||||
|
||||
DeleteDummyFile();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -598,25 +629,39 @@ BluetoothOppManager::CreateFile()
|
||||
{
|
||||
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
|
||||
|
||||
// Create one dummy file to be a placeholder for the target file name, and
|
||||
// create another file with a meaningless file extension to write the received
|
||||
// data. By doing this, we can prevent applications from parsing incomplete
|
||||
// data in the middle of the receiving process.
|
||||
nsString path;
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
|
||||
mDsFile = DeviceStorageFile::CreateUnique(
|
||||
path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
// Use an empty dummy file object to occupy the file name, so that after the
|
||||
// whole file has been received successfully by using mDsFile, we could just
|
||||
// remove mDummyDsFile and rename mDsFile to the file name of mDummyDsFile.
|
||||
mDummyDsFile =
|
||||
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
NS_ENSURE_TRUE(mDummyDsFile, false);
|
||||
|
||||
// The function CreateUnique() may create a file with a different file
|
||||
// name from the original mFileName. Therefore we have to retrieve
|
||||
// the file name again.
|
||||
mDummyDsFile->mFile->GetLeafName(mFileName);
|
||||
|
||||
BT_LOGR("mFileName: %s", NS_ConvertUTF16toUTF8(mFileName).get());
|
||||
|
||||
// Prepare the entire file path for the .part file
|
||||
path.Truncate();
|
||||
path.AssignLiteral(TARGET_SUBDIR);
|
||||
path.Append(mFileName);
|
||||
path.AppendLiteral(".part");
|
||||
|
||||
mDsFile =
|
||||
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||
NS_ENSURE_TRUE(mDsFile, false);
|
||||
|
||||
nsCOMPtr<nsIFile> f;
|
||||
mDsFile->mFile->Clone(getter_AddRefs(f));
|
||||
|
||||
/*
|
||||
* The function CreateUnique() may create a file with a different file
|
||||
* name from the original mFileName. Therefore we have to retrieve
|
||||
* the file name again.
|
||||
*/
|
||||
f->GetLeafName(mFileName);
|
||||
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mDsFile->mFile);
|
||||
NS_ENSURE_TRUE(mOutputStream, false);
|
||||
|
||||
return true;
|
||||
@ -932,6 +977,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
|
||||
// Success to receive a file and notify completion
|
||||
if (mPutFinalFlag) {
|
||||
mSuccessFlag = true;
|
||||
|
||||
DeleteDummyFile();
|
||||
RecoverFileName();
|
||||
|
||||
FileTransferComplete();
|
||||
NotifyAboutFileChange();
|
||||
}
|
||||
|
@ -85,6 +85,8 @@ private:
|
||||
void ReceivingFileConfirmation();
|
||||
bool CreateFile();
|
||||
bool WriteToFile(const uint8_t* aData, int aDataLength);
|
||||
void RecoverFileName();
|
||||
void DeleteDummyFile();
|
||||
void DeleteReceivedFile();
|
||||
void ReplyToConnect();
|
||||
void ReplyToDisconnectOrAbort();
|
||||
@ -209,6 +211,7 @@ private:
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
nsCOMPtr<nsIVolumeMountLock> mMountLock;
|
||||
nsRefPtr<DeviceStorageFile> mDsFile;
|
||||
nsRefPtr<DeviceStorageFile> mDummyDsFile;
|
||||
|
||||
// If a connection has been established, mSocket will be the socket
|
||||
// communicating with the remote socket. We maintain the invariant that if
|
||||
|
@ -0,0 +1,42 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 1059662 - Only allow a app to embed others apps when it runs
|
||||
// in-process.
|
||||
//
|
||||
// The "inproc" version of this test should successfully embed the
|
||||
// app, and the "oop" version of this test should fail to embed the
|
||||
// app.
|
||||
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
browserElementTestHelpers.setEnabledPref(true);
|
||||
browserElementTestHelpers.addPermission();
|
||||
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
|
||||
function runTest() {
|
||||
var canEmbedApp = !browserElementTestHelpers.getOOPByDefaultPref();
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('mozbrowser', 'true');
|
||||
|
||||
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
|
||||
is(e.detail.message == 'app', canEmbedApp, e.detail.message);
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
var context = { 'url': 'http://example.org',
|
||||
'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
|
||||
'isInBrowserElement': true };
|
||||
SpecialPowers.pushPermissions([
|
||||
{'type': 'browser', 'allow': 1, 'context': context},
|
||||
{'type': 'embed-apps', 'allow': 1, 'context': context}
|
||||
], function() {
|
||||
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_DisallowEmbedAppsInOOP.html';
|
||||
});
|
||||
}
|
||||
|
||||
addEventListener('testready', runTest);
|
@ -0,0 +1,19 @@
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
addEventListener('load', function(e) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('mozbrowser', 'true');
|
||||
iframe.setAttribute('remote', 'false');
|
||||
iframe.setAttribute('mozapp', 'http://example.org/manifest.webapp');
|
||||
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
|
||||
alert(e.detail.message);
|
||||
});
|
||||
document.body.appendChild(iframe);
|
||||
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AppFramePermission.html';
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -31,6 +31,7 @@ skip-if = (toolkit == 'gonk' && !debug)
|
||||
[test_browserElement_oop_CopyPaste.html]
|
||||
[test_browserElement_oop_DOMRequestError.html]
|
||||
[test_browserElement_oop_DataURI.html]
|
||||
[test_browserElement_oop_DisallowEmbedAppsInOOP.html]
|
||||
[test_browserElement_oop_DocumentFirstPaint.html]
|
||||
[test_browserElement_oop_Download.html]
|
||||
disabled = bug 1022281
|
||||
|
@ -22,6 +22,7 @@ support-files =
|
||||
browserElement_CopyPaste.js
|
||||
browserElement_DOMRequestError.js
|
||||
browserElement_DataURI.js
|
||||
browserElement_DisallowEmbedAppsInOOP.js
|
||||
browserElement_DocumentFirstPaint.js
|
||||
browserElement_Download.js
|
||||
browserElement_ErrorSecurity.js
|
||||
@ -77,6 +78,7 @@ support-files =
|
||||
file_browserElement_CloseApp.html
|
||||
file_browserElement_CloseFromOpener.html
|
||||
file_browserElement_CookiesNotThirdParty.html
|
||||
file_browserElement_DisallowEmbedAppsInOOP.html
|
||||
file_browserElement_ForwardName.html
|
||||
file_browserElement_FrameWrongURI.html
|
||||
file_browserElement_LoadEvents.html
|
||||
@ -143,6 +145,8 @@ skip-if = buildapp == 'b2g'
|
||||
[test_browserElement_inproc_CopyPaste.html]
|
||||
[test_browserElement_inproc_DOMRequestError.html]
|
||||
[test_browserElement_inproc_DataURI.html]
|
||||
[test_browserElement_inproc_DisallowEmbedAppsInOOP.html]
|
||||
skip-if = os == "android" || toolkit == 'gonk' # embed-apps doesn't work in the mochitest app
|
||||
[test_browserElement_inproc_DocumentFirstPaint.html]
|
||||
[test_browserElement_inproc_Download.html]
|
||||
disabled = bug 1022281
|
||||
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 1059662</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_DisallowEmbedAppsInOOP.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 1059662</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7" src="browserElement_DisallowEmbedAppsInOOP.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -34,6 +34,7 @@ support-files =
|
||||
file_notify_system_message.html
|
||||
|
||||
[test_app_install.html]
|
||||
skip-if = toolkit == 'gonk' # embed-apps doesn't work in the mochitest app
|
||||
[test_readonly.html]
|
||||
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
|
||||
[test_basic.html]
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "nsGenericHTMLFrameElement.h"
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "GeckoProfiler.h"
|
||||
@ -437,6 +438,11 @@ nsGenericHTMLFrameElement::GetAppManifestURL(nsAString& aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
NS_WARNING("Can't embed-apps. Embed-apps is restricted to in-proc apps, see bug 1059662");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString appManifestURL;
|
||||
nsAutoString widgetManifestURL;
|
||||
|
||||
|
@ -469,9 +469,7 @@ child:
|
||||
RealKeyEvent(WidgetKeyboardEvent event, MaybeNativeKeyBinding keyBinding);
|
||||
MouseWheelEvent(WidgetWheelEvent event);
|
||||
RealTouchEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
|
||||
// We use a separate message for touchmove events only to apply
|
||||
// compression to them.
|
||||
RealTouchMoveEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid, uint64_t aInputBlockId) compress;
|
||||
RealTouchMoveEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
|
||||
|
||||
/**
|
||||
* @see nsIDOMWindowUtils sendKeyEvent.
|
||||
|
@ -123,9 +123,6 @@ this.SystemMessagePermissionsTable = {
|
||||
"nfc-manager-send-file": {
|
||||
"nfc-manager": []
|
||||
},
|
||||
"nfc-powerlevel-change": {
|
||||
"settings": ["read", "write"]
|
||||
},
|
||||
"wifip2p-pairing-request": { },
|
||||
"first-run-with-sim": {
|
||||
"settings": ["read", "write"]
|
||||
|
@ -102,6 +102,7 @@ namespace system {
|
||||
|
||||
#define USB_FUNC_ADB "adb"
|
||||
#define USB_FUNC_MTP "mtp"
|
||||
#define USB_FUNC_NONE "none"
|
||||
#define USB_FUNC_RNDIS "rndis"
|
||||
#define USB_FUNC_UMS "mass_storage"
|
||||
|
||||
@ -528,6 +529,13 @@ SetUsbFunction(const char* aUsbFunc)
|
||||
char oldSysUsbConfig[PROPERTY_VALUE_MAX];
|
||||
property_get(SYS_USB_CONFIG, oldSysUsbConfig, "");
|
||||
|
||||
if (strcmp(oldSysUsbConfig, USB_FUNC_NONE) == 0) {
|
||||
// It's quite possible that sys.usb.config may have the value "none". We
|
||||
// convert that to an empty string here, and at the end we convert the
|
||||
// empty string back to "none".
|
||||
oldSysUsbConfig[0] = '\0';
|
||||
}
|
||||
|
||||
if (IsUsbFunctionEnabled(oldSysUsbConfig, aUsbFunc)) {
|
||||
// The function is already configured. Nothing else to do.
|
||||
DBG("SetUsbFunction('%s') - already set - nothing to do", aUsbFunc);
|
||||
@ -583,6 +591,10 @@ SetUsbFunction(const char* aUsbFunc)
|
||||
return;
|
||||
}
|
||||
|
||||
if (newSysUsbConfig[0] == '\0') {
|
||||
// Convert the empty string back to the string "none"
|
||||
strlcpy(newSysUsbConfig, USB_FUNC_NONE, sizeof(newSysUsbConfig));
|
||||
}
|
||||
LOG("SetUsbFunction(%s) %s from '%s' to '%s'", aUsbFunc, SYS_USB_CONFIG,
|
||||
oldSysUsbConfig, newSysUsbConfig);
|
||||
property_set(SYS_USB_CONFIG, newSysUsbConfig);
|
||||
|
@ -17,7 +17,7 @@ support-files =
|
||||
localStorageCommon.js
|
||||
|
||||
[test_appIsolation.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 793211 # b2g(needs https to work) b2g-debug(needs https to work) b2g-desktop(needs https to work)
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #bug 793211 # b2g(needs https to work) b2g-debug(needs https to work) b2g-desktop(needs https to work)
|
||||
[test_brokenUTF-16.html]
|
||||
[test_bug600307-DBOps.html]
|
||||
[test_bug746272-1.html]
|
||||
|
@ -1,5 +1,6 @@
|
||||
[DEFAULT]
|
||||
skip-if = os == "linux" && e10s && debug # bug 1091322 - wallpaper over an e10s crash
|
||||
skip-if = os == "android" || toolkit == "gonk" || e10s
|
||||
support-files =
|
||||
file_app.sjs
|
||||
file_app.template.webapp
|
||||
|
@ -583,6 +583,19 @@ MessageChannel::ShouldDeferMessage(const Message& aMsg)
|
||||
return mSide == ParentSide && aMsg.transaction_id() != mCurrentTransaction;
|
||||
}
|
||||
|
||||
// Predicate that is true for messages that should be consolidated if 'compress' is set.
|
||||
class MatchingKinds {
|
||||
typedef IPC::Message Message;
|
||||
Message::msgid_t mType;
|
||||
int32_t mRoutingId;
|
||||
public:
|
||||
MatchingKinds(Message::msgid_t aType, int32_t aRoutingId) :
|
||||
mType(aType), mRoutingId(aRoutingId) {}
|
||||
bool operator()(const Message &msg) {
|
||||
return msg.type() == mType && msg.routing_id() == mRoutingId;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
|
||||
{
|
||||
@ -604,15 +617,22 @@ MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
|
||||
// Prioritized messages cannot be compressed.
|
||||
MOZ_ASSERT(!aMsg.compress() || aMsg.priority() == IPC::Message::PRIORITY_NORMAL);
|
||||
|
||||
bool compress = (aMsg.compress() && !mPending.empty() &&
|
||||
mPending.back().type() == aMsg.type() &&
|
||||
mPending.back().routing_id() == aMsg.routing_id());
|
||||
bool compress = (aMsg.compress() && !mPending.empty());
|
||||
if (compress) {
|
||||
// This message type has compression enabled, and the back of the
|
||||
// queue was the same message type and routed to the same destination.
|
||||
// Replace it with the newer message.
|
||||
MOZ_ASSERT(mPending.back().compress());
|
||||
mPending.pop_back();
|
||||
// Check the message queue for another message with this type/destination.
|
||||
auto it = std::find_if(mPending.rbegin(), mPending.rend(),
|
||||
MatchingKinds(aMsg.type(), aMsg.routing_id()));
|
||||
if (it != mPending.rend()) {
|
||||
// This message type has compression enabled, and the queue holds
|
||||
// a message with the same message type and routed to the same destination.
|
||||
// Erase it. Note that, since we always compress these redundancies, There Can
|
||||
// Be Only One.
|
||||
MOZ_ASSERT((*it).compress());
|
||||
mPending.erase((++it).base());
|
||||
} else {
|
||||
// No other messages with the same type/destination exist.
|
||||
compress = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldWakeUp = AwaitingInterruptReply() ||
|
||||
|
61
mobile/android/app/build.gradle
Normal file
61
mobile/android/app/build.gradle
Normal file
@ -0,0 +1,61 @@
|
||||
project.buildDir = "${topobjdir}/mobile/android/gradle/app/build"
|
||||
|
||||
apply plugin: 'android'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
runProguard false
|
||||
proguardFile getDefaultProguardFile('proguard-android.txt')
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
android {
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest {
|
||||
srcFile "${topobjdir}/mobile/android/base/AndroidManifest.xml"
|
||||
}
|
||||
|
||||
assets {
|
||||
srcDir "${topobjdir}/dist/fennec/assets"
|
||||
}
|
||||
|
||||
jniLibs {
|
||||
srcDir "${topobjdir}/dist/fennec/lib"
|
||||
}
|
||||
}
|
||||
|
||||
androidTest {
|
||||
java {
|
||||
srcDir "${topobjdir}/mobile/android/gradle/app/src/androidTest/robocop_harness/java"
|
||||
srcDir "${topobjdir}/mobile/android/gradle/app/src/androidTest/robocop/java"
|
||||
srcDir "${topobjdir}/mobile/android/gradle/app/src/androidTest/background/java"
|
||||
srcDir "${topobjdir}/mobile/android/gradle/app/src/androidTest/browser/java"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':base')
|
||||
androidTestCompile fileTree(dir: "../../../build/mobile/robocop", include: ['*.jar'])
|
||||
}
|
@ -9,6 +9,7 @@ import org.mozilla.gecko.util.GeckoRequest;
|
||||
import org.mozilla.gecko.util.NativeJSObject;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
@ -21,15 +22,17 @@ import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.CheckedTextView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnClickListener, GeckoEventListener {
|
||||
private static final String LOGTAG = "FindInPageBar";
|
||||
private static final String LOGTAG = "GeckoFindInPageBar";
|
||||
private static final String REQUEST_ID = "FindInPageBar";
|
||||
|
||||
private final Context mContext;
|
||||
private CustomEditText mFindText;
|
||||
private CheckedTextView mMatchCase;
|
||||
private TextView mStatusText;
|
||||
private boolean mInflated;
|
||||
|
||||
@ -64,6 +67,9 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||
}
|
||||
});
|
||||
|
||||
mMatchCase = (CheckedTextView) content.findViewById(R.id.find_matchcase);
|
||||
mMatchCase.setOnClickListener(this);
|
||||
|
||||
mStatusText = (TextView) content.findViewById(R.id.find_status);
|
||||
|
||||
mInflated = true;
|
||||
@ -123,6 +129,16 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||
public void onClick(View v) {
|
||||
final int viewId = v.getId();
|
||||
|
||||
if (viewId == R.id.find_matchcase) {
|
||||
// Toggle matchcase state (color).
|
||||
mMatchCase.toggle();
|
||||
|
||||
// Repeat the find after a matchcase change.
|
||||
sendRequestToFinderHelper("FindInPage:Find", mFindText.getText().toString());
|
||||
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (viewId == R.id.find_prev) {
|
||||
sendRequestToFinderHelper("FindInPage:Prev", mFindText.getText().toString());
|
||||
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
||||
@ -184,7 +200,16 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||
* Request find operation, and update matchCount results (current count and total).
|
||||
*/
|
||||
private void sendRequestToFinderHelper(final String request, final String searchString) {
|
||||
GeckoAppShell.sendRequestToGecko(new GeckoRequest(request, searchString) {
|
||||
final JSONObject json = new JSONObject();
|
||||
try {
|
||||
json.put("searchString", searchString);
|
||||
json.put("matchCase", mMatchCase.isChecked());
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "JSON error - Error creating JSONObject", e);
|
||||
return;
|
||||
}
|
||||
|
||||
GeckoAppShell.sendRequestToGecko(new GeckoRequest(request, json) {
|
||||
@Override
|
||||
public void onResponse(NativeJSObject nativeJSObject) {
|
||||
final int total = nativeJSObject.optInt("total", 0);
|
||||
|
@ -397,10 +397,10 @@ fennec_ids.txt: generated/org/mozilla/gecko/R.java fennec-ids-generator.py
|
||||
# Override the Java settings with some specific android settings
|
||||
include $(topsrcdir)/config/android-common.mk
|
||||
|
||||
# This target is only used by the Eclipse integration. It rebuilds
|
||||
# resources that end up in omni.ja, does most of the packaging step,
|
||||
# and then updates omni.ja in place. If you're not using Eclipse, you
|
||||
# should be using |mach build mobile/android && mach package|.
|
||||
# This target is only used by IDE integrations. It rebuilds resources
|
||||
# that end up in omni.ja, does most of the packaging step, and then
|
||||
# updates omni.ja in place. If you're not using an IDE, you should be
|
||||
# using |mach build mobile/android && mach package|.
|
||||
$(abspath $(DIST)/fennec/$(OMNIJAR_NAME)): FORCE
|
||||
$(REPORT_BUILD)
|
||||
$(MAKE) -C ../locales
|
||||
@ -413,6 +413,12 @@ $(abspath $(DIST)/fennec/$(OMNIJAR_NAME)): FORCE
|
||||
rsync --update $(DIST)/fennec/$(notdir $(OMNIJAR_NAME)) $@
|
||||
$(RM) $(DIST)/fennec/$(notdir $(OMNIJAR_NAME))
|
||||
|
||||
# Targets built very early during a Gradle build.
|
||||
gradle-targets: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME))
|
||||
gradle-targets: .aapt.deps
|
||||
|
||||
.PHONY: gradle-targets
|
||||
|
||||
libs:: geckoview_resources.zip classes.dex jni-stubs.inc GeneratedJNIWrappers.cpp fennec_ids.txt
|
||||
$(INSTALL) geckoview_resources.zip $(FINAL_TARGET)
|
||||
$(INSTALL) classes.dex $(FINAL_TARGET)
|
||||
|
98
mobile/android/base/build.gradle
Normal file
98
mobile/android/base/build.gradle
Normal file
@ -0,0 +1,98 @@
|
||||
project.buildDir = "${topobjdir}/mobile/android/gradle/base/build"
|
||||
|
||||
apply plugin: 'android-library'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'org.mozilla.gecko'
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
runProguard false
|
||||
proguardFile getDefaultProguardFile('proguard-android.txt')
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
android {
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest {
|
||||
srcFile 'gradle_AndroidManifest.xml'
|
||||
}
|
||||
|
||||
java {
|
||||
// The main sources are symlinked in here.
|
||||
srcDir "${topobjdir}/mobile/android/gradle/base/src/main/java"
|
||||
exclude '**/tests/**'
|
||||
exclude '**/resources/**'
|
||||
if (!MOZ_CRASHREPORTER) {
|
||||
exclude '**/CrashReporter.java'
|
||||
}
|
||||
srcDir "../search/java"
|
||||
srcDir "../stumbler/java"
|
||||
srcDir "${topobjdir}/mobile/android/base/generated"
|
||||
exclude '**/R.java'
|
||||
exclude '**/Manifest.java'
|
||||
}
|
||||
|
||||
res {
|
||||
srcDir "newtablet/res"
|
||||
srcDir "../branding/unofficial/res"
|
||||
srcDir "${topobjdir}/mobile/android/base/res"
|
||||
// The main resources are symlinked in here.
|
||||
srcDir "${topobjdir}/mobile/android/gradle/base/src/main/res"
|
||||
if (MOZ_CRASHREPORTER) {
|
||||
srcDir "crashreporter/res"
|
||||
}
|
||||
}
|
||||
|
||||
resources {
|
||||
srcDir '../locales'
|
||||
srcDir '../chrome'
|
||||
srcDir '../components'
|
||||
srcDir '../modules'
|
||||
srcDir '../app'
|
||||
srcDir '../themes/core'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile project(':thirdparty')
|
||||
compile 'com.android.support:support-v4:19.1.+'
|
||||
compile 'com.android.support:appcompat-v7:19.1.+'
|
||||
compile 'com.android.support:mediarouter-v7:19.1.+'
|
||||
compile 'com.google.android.gms:play-services:5.+'
|
||||
}
|
||||
|
||||
task prepareObjDir(type:Exec) {
|
||||
workingDir "${topobjdir}"
|
||||
|
||||
commandLine "${topsrcdir}/mach"
|
||||
args 'build'
|
||||
args '-C'
|
||||
args 'mobile/android/base'
|
||||
args 'gradle-targets'
|
||||
}
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
variant.checkManifest.dependsOn prepareObjDir
|
||||
}
|
98
mobile/android/base/docs/gradle.rst
Normal file
98
mobile/android/base/docs/gradle.rst
Normal file
@ -0,0 +1,98 @@
|
||||
.. -*- Mode: rst; fill-column: 80; -*-
|
||||
|
||||
======================
|
||||
Building with Gradle
|
||||
======================
|
||||
|
||||
Instructions
|
||||
============
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
./mach build && ./mach package
|
||||
cd $OBJDIR/mobile/android
|
||||
./gradlew build
|
||||
|
||||
The debug APK will be at
|
||||
``$OBJDIR/mobile/android/gradle/app/build/outputs/apk/app-debug.apk``.
|
||||
|
||||
The ``$OBJDIR/mobile/android/gradle`` directory can be imported into IntelliJ as
|
||||
follows:
|
||||
|
||||
- File > Import Project
|
||||
- [select ``$OBJDIR/mobile/android/gradle``]
|
||||
- Import project from external model > Gradle
|
||||
- [select Use default Gradle wrapper]
|
||||
|
||||
When prompted, do not add any files to git. You may need to re-open the
|
||||
project, or restart IntelliJ, to pick up a compiler language-level change.
|
||||
|
||||
Technical overview
|
||||
==================
|
||||
|
||||
Caveats
|
||||
-------
|
||||
|
||||
* The Gradle build will "succeed" but crash on start up if the object directory
|
||||
has not been properly packaged.
|
||||
* Changes to preprocessed source code and resources (namely, ``strings.xml.in``
|
||||
and the accompanying DTD files) may not be recognized.
|
||||
* There's minimal support for editing JavaScript.
|
||||
* There's no support for editing C/C++.
|
||||
|
||||
How the Gradle project is laid out
|
||||
----------------------------------
|
||||
|
||||
To the greatest extent possible, the Gradle configuration lives in the source
|
||||
directory. The only Gradle configuration that lives in the object directory is
|
||||
installed when building the ``mobile/android/gradle`` directory.
|
||||
|
||||
At the time of writing, their are three sub-modules: *app*, *base*, and *thirdparty*.
|
||||
|
||||
*app* is the Fennec wrapper; it generates the **org.mozilla.fennec.R** resource
|
||||
package. *base* is the Gecko code; it generates the **org.mozilla.gecko.R**
|
||||
resource package. Together, *app* and *base* address the "two package
|
||||
namespaces" that has plagued Fennec from day one.
|
||||
|
||||
Due to limitations in the Android Gradle plugin, all test code is shoved into
|
||||
the *app* module. (The issue is that, at the time of writing, there is no
|
||||
support for test-only APKs.) For no particular reason, the compiled C/C++
|
||||
libraries are included in the *app* module; they could be included in the *base*
|
||||
module. I expect *base* to rebuilt slightly more frequently than *app*, so I'm
|
||||
hoping this choice will allow for faster incremental builds.
|
||||
|
||||
*thirdparty* is the external code we use in Fennec; it's built as an Android
|
||||
library but uses no resources. It's separate simply to allow the build system
|
||||
to cache the compiled and pre-dexed artifacts, hopefully allowing for faster
|
||||
incremental builds.
|
||||
|
||||
Recursive make backend details
|
||||
------------------------------
|
||||
|
||||
The ``mobile/android/gradle`` directory writes the following into
|
||||
``$OBJDIR/mobile/android/gradle``:
|
||||
|
||||
1) the Gradle wrapper;
|
||||
2) ``gradle.properties``;
|
||||
3) symlinks to certain source and resource directories.
|
||||
|
||||
The Gradle wrapper is written to make it easy to build with Gradle from the
|
||||
object directory. The wrapper is `intended to be checked into version
|
||||
control`_.
|
||||
|
||||
``gradle.properties`` is the single source of per-object directory Gradle
|
||||
configuration, and provides the Gradle configuration access to
|
||||
configure/moz.build variables.
|
||||
|
||||
The symlinks are not necessary for the Gradle build itself, but they prevent
|
||||
nested directory errors and incorrect Java package scoping when the Gradle
|
||||
project is imported into IntelliJ. Because IntelliJ treats the Gradle project
|
||||
as authoritative, it's not sufficient to fix these manually in IntelliJ after
|
||||
the initial import -- IntelliJ reverts to the Gradle configuration after every
|
||||
build. Since there aren't many symlinks, I've done them in the Makefile rather
|
||||
than at a higher level of abstraction (like a moz.build definition, or a custom
|
||||
build backend). In future, I expect to be able to remove all such symlinks by
|
||||
making our in-tree directory structures agree with what Gradle and IntelliJ
|
||||
expect.
|
||||
|
||||
.. _intended to be checked into version control: http://www.gradle.org/docs/current/userguide/gradle_wrapper.html
|
@ -2,159 +2,9 @@
|
||||
Firefox for Android
|
||||
===================
|
||||
|
||||
UI Telemetry
|
||||
============
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Fennec records UI events using a telemetry framework called UITelemetry.
|
||||
|
||||
Some links:
|
||||
|
||||
- `Project page <https://wiki.mozilla.org/Mobile/Projects/Telemetry_probes_for_Fennec_UI_elements>`_
|
||||
- `Wiki page <https://wiki.mozilla.org/Mobile/Fennec/Android/UITelemetry>`_
|
||||
- `User research notes <https://wiki.mozilla.org/Mobile/User_Experience/Research>`_
|
||||
|
||||
Sessions
|
||||
========
|
||||
|
||||
**Sessions** are essentially scopes. They are meant to provide context to
|
||||
events; this allows events to be simpler and more reusable. Sessions are
|
||||
usually bound to some component of the UI, some user action with a duration, or
|
||||
some transient state.
|
||||
|
||||
For example, a session might be begun when a user begins interacting with a
|
||||
menu, and stopped when the interaction ends. Or a session might encapsulate
|
||||
period of no network connectivity, the first five seconds after the browser
|
||||
launched, the time spent with an active download, or a guest mode session.
|
||||
|
||||
Sessions implicitly record the duration of the interaction.
|
||||
|
||||
A simple use-case for sessions is the bookmarks panel in about:home. We start a
|
||||
session when the user swipes into the panel, and stop it when they swipe away.
|
||||
This bookmarks session does two things: firstly, it gives scope to any generic
|
||||
event that may occur within the panel (*e.g.*, loading a URL). Secondly, it
|
||||
allows us to figure out how much time users are spending in the bookmarks
|
||||
panel.
|
||||
|
||||
To start a session, call ``Telemetry.startUISession(String sessionName)``.
|
||||
|
||||
``sessionName``
|
||||
The name of the session. Session names should be brief, lowercase, and should describe which UI
|
||||
component the user is interacting with. In certain cases where the UI component is dynamic, they could include an ID, essential to identifying that component. An example of this is dynamic home panels: we use session names of the format ``homepanel:<panel_id>`` to identify home panel sessions.
|
||||
|
||||
To stop a session, call ``Telemetry.stopUISession(String sessionName, String reason)``.
|
||||
|
||||
``sessionName``
|
||||
The name of the open session
|
||||
|
||||
``reason`` (Optional)
|
||||
A descriptive cause for ending the session. It should be brief, lowercase, and generic so it can be reused in different places. Examples reasons are:
|
||||
|
||||
``switched``
|
||||
The user transitioned to a UI element of equal level.
|
||||
|
||||
``exit``
|
||||
The user left for an entirely different element.
|
||||
|
||||
Events
|
||||
======
|
||||
|
||||
Events capture key occurrences. They should be brief and simple, and should not contain sensitive or excess information. Context for events should come from the session (scope). An event can be created with four fields (via ``Telemetry.sendUIEvent``): ``action``, ``method``, ``extras``, and ``timestamp``.
|
||||
|
||||
``action``
|
||||
The name of the event. Should be brief and lowercase. If needed, you can make use of namespacing with a '``.``' separator. Example event names: ``panel.switch``, ``panel.enable``, ``panel.disable``, ``panel.install``.
|
||||
|
||||
``method`` (Optional)
|
||||
Used for user actions that can be performed in many ways. This field specifies the method by which the action was performed. For example, users can add an item to their reading list either by long-tapping the reader icon in the address bar, or from within reader mode. We would use the same event name for both user actions but specify two methods: ``addressbar`` and ``readermode``.
|
||||
|
||||
``extras`` (Optional)
|
||||
For extra information that may be useful in understanding the event. Make an effort to keep this brief.
|
||||
|
||||
``timestamp`` (Optional)
|
||||
The time at which the event occurred. If not specified, this field defaults to the current value of the realtime clock.
|
||||
|
||||
Versioning
|
||||
========
|
||||
|
||||
As a we improve on our Telemetry methods, it is foreseeable that our probes will change over time. Different versions of a probe could carry different data or have different interpretations on the server-side. To make it easier for the server to handle these changes, you should add version numbers to your event and session names. An example of a versioned session is ``homepanel.1``; this is version 1 of the ``homepanel`` session. This approach should also be applied to event names, an example being: ``panel.enable.1`` and ``panel.enable.2``.
|
||||
|
||||
|
||||
Clock
|
||||
=====
|
||||
|
||||
Times are relative to either elapsed realtime (an arbitrary monotonically increasing clock that continues to tick when the device is asleep), or elapsed uptime (which doesn't tick when the device is in deep sleep). We default to elapsed realtime.
|
||||
|
||||
See the documentation in `the source <http://mxr.mozilla.org/mozilla-central/source/mobile/android/base/Telemetry.java>`_ for more details.
|
||||
|
||||
Dictionary
|
||||
==========
|
||||
|
||||
Events
|
||||
------
|
||||
``action.1``
|
||||
Generic action, usually for tracking menu and toolbar actions.
|
||||
|
||||
``cancel.1``
|
||||
Cancel a state, action, etc.
|
||||
|
||||
``cast.1``
|
||||
Start casting a video.
|
||||
|
||||
``edit.1``
|
||||
Sent when the user edits a top site.
|
||||
|
||||
``launch.1``
|
||||
Launching (opening) an external application.
|
||||
Note: Only used in JavaScript for now.
|
||||
|
||||
``loadurl.1``
|
||||
Loading a URL.
|
||||
|
||||
``locale.browser.reset.1``
|
||||
When the user chooses "System default" in the browser locale picker.
|
||||
|
||||
``locale.browser.selected.1``
|
||||
When the user chooses a locale in the browser locale picker. The selected
|
||||
locale is provided as the extra.
|
||||
|
||||
``locale.browser.unselected.1``
|
||||
When the user chose a different locale in the browser locale picker, this
|
||||
event is fired with the previous locale as the extra. If the previous locale
|
||||
could not be determined, "unknown" is provided.
|
||||
|
||||
``setdefault.1``
|
||||
Set default home panel.
|
||||
|
||||
``pin.1``, ``unpin.1``
|
||||
Sent when the user pinned or unpinned a top site.
|
||||
|
||||
``policynotification.success.1:true``
|
||||
Sent when a user has accepted the data notification policy. Can be ``false``
|
||||
instead of ``true`` if an error occurs.
|
||||
|
||||
``sanitize.1``
|
||||
Sent when the user chooses to clear private data.
|
||||
|
||||
``save.1`` ``unsave.1``
|
||||
Saving or unsaving a resource (reader, bookmark, etc.) for viewing later.
|
||||
Note: Only used in JavaScript for now.
|
||||
|
||||
``search.1``
|
||||
Sent when the user performs a search. Currently used in the search activity.
|
||||
|
||||
``share.1``
|
||||
Sharing content.
|
||||
|
||||
Methods
|
||||
-------
|
||||
``banner``
|
||||
Action triggered from a banner (such as HomeBanner).
|
||||
Note: Only used in JavaScript for now.
|
||||
|
||||
``content``
|
||||
Action triggered from a content page.
|
||||
|
||||
Sessions
|
||||
--------
|
||||
``searchactivity.1``
|
||||
Started when the user launches the search activity (onStart) and stopped
|
||||
when they leave the search activity.
|
||||
localeswitching
|
||||
uitelemetry
|
||||
gradle
|
||||
|
@ -1,6 +1,8 @@
|
||||
==================================
|
||||
Runtime locale switching in Fennec
|
||||
==================================
|
||||
.. -*- Mode: rst; fill-column: 80; -*-
|
||||
|
||||
====================================
|
||||
Runtime locale switching in Fennec
|
||||
====================================
|
||||
|
||||
`Bug 917480 <https://bugzilla.mozilla.org/show_bug.cgi?id=917480>`_ built on `Bug 936756 <https://bugzilla.mozilla.org/show_bug.cgi?id=936756>`_ to allow users to switch between supported locales at runtime, within Fennec, without altering the system locale.
|
||||
|
||||
|
159
mobile/android/base/docs/uitelemetry.rst
Normal file
159
mobile/android/base/docs/uitelemetry.rst
Normal file
@ -0,0 +1,159 @@
|
||||
.. -*- Mode: rst; fill-column: 80; -*-
|
||||
|
||||
==============
|
||||
UI Telemetry
|
||||
==============
|
||||
|
||||
Fennec records UI events using a telemetry framework called UITelemetry.
|
||||
|
||||
Some links:
|
||||
|
||||
- `Project page <https://wiki.mozilla.org/Mobile/Projects/Telemetry_probes_for_Fennec_UI_elements>`_
|
||||
- `Wiki page <https://wiki.mozilla.org/Mobile/Fennec/Android/UITelemetry>`_
|
||||
- `User research notes <https://wiki.mozilla.org/Mobile/User_Experience/Research>`_
|
||||
|
||||
Sessions
|
||||
========
|
||||
|
||||
**Sessions** are essentially scopes. They are meant to provide context to
|
||||
events; this allows events to be simpler and more reusable. Sessions are
|
||||
usually bound to some component of the UI, some user action with a duration, or
|
||||
some transient state.
|
||||
|
||||
For example, a session might be begun when a user begins interacting with a
|
||||
menu, and stopped when the interaction ends. Or a session might encapsulate
|
||||
period of no network connectivity, the first five seconds after the browser
|
||||
launched, the time spent with an active download, or a guest mode session.
|
||||
|
||||
Sessions implicitly record the duration of the interaction.
|
||||
|
||||
A simple use-case for sessions is the bookmarks panel in about:home. We start a
|
||||
session when the user swipes into the panel, and stop it when they swipe away.
|
||||
This bookmarks session does two things: firstly, it gives scope to any generic
|
||||
event that may occur within the panel (*e.g.*, loading a URL). Secondly, it
|
||||
allows us to figure out how much time users are spending in the bookmarks
|
||||
panel.
|
||||
|
||||
To start a session, call ``Telemetry.startUISession(String sessionName)``.
|
||||
|
||||
``sessionName``
|
||||
The name of the session. Session names should be brief, lowercase, and should describe which UI
|
||||
component the user is interacting with. In certain cases where the UI component is dynamic, they could include an ID, essential to identifying that component. An example of this is dynamic home panels: we use session names of the format ``homepanel:<panel_id>`` to identify home panel sessions.
|
||||
|
||||
To stop a session, call ``Telemetry.stopUISession(String sessionName, String reason)``.
|
||||
|
||||
``sessionName``
|
||||
The name of the open session
|
||||
|
||||
``reason`` (Optional)
|
||||
A descriptive cause for ending the session. It should be brief, lowercase, and generic so it can be reused in different places. Examples reasons are:
|
||||
|
||||
``switched``
|
||||
The user transitioned to a UI element of equal level.
|
||||
|
||||
``exit``
|
||||
The user left for an entirely different element.
|
||||
|
||||
Events
|
||||
======
|
||||
|
||||
Events capture key occurrences. They should be brief and simple, and should not contain sensitive or excess information. Context for events should come from the session (scope). An event can be created with four fields (via ``Telemetry.sendUIEvent``): ``action``, ``method``, ``extras``, and ``timestamp``.
|
||||
|
||||
``action``
|
||||
The name of the event. Should be brief and lowercase. If needed, you can make use of namespacing with a '``.``' separator. Example event names: ``panel.switch``, ``panel.enable``, ``panel.disable``, ``panel.install``.
|
||||
|
||||
``method`` (Optional)
|
||||
Used for user actions that can be performed in many ways. This field specifies the method by which the action was performed. For example, users can add an item to their reading list either by long-tapping the reader icon in the address bar, or from within reader mode. We would use the same event name for both user actions but specify two methods: ``addressbar`` and ``readermode``.
|
||||
|
||||
``extras`` (Optional)
|
||||
For extra information that may be useful in understanding the event. Make an effort to keep this brief.
|
||||
|
||||
``timestamp`` (Optional)
|
||||
The time at which the event occurred. If not specified, this field defaults to the current value of the realtime clock.
|
||||
|
||||
Versioning
|
||||
========
|
||||
|
||||
As a we improve on our Telemetry methods, it is foreseeable that our probes will change over time. Different versions of a probe could carry different data or have different interpretations on the server-side. To make it easier for the server to handle these changes, you should add version numbers to your event and session names. An example of a versioned session is ``homepanel.1``; this is version 1 of the ``homepanel`` session. This approach should also be applied to event names, an example being: ``panel.enable.1`` and ``panel.enable.2``.
|
||||
|
||||
|
||||
Clock
|
||||
=====
|
||||
|
||||
Times are relative to either elapsed realtime (an arbitrary monotonically increasing clock that continues to tick when the device is asleep), or elapsed uptime (which doesn't tick when the device is in deep sleep). We default to elapsed realtime.
|
||||
|
||||
See the documentation in `the source <http://mxr.mozilla.org/mozilla-central/source/mobile/android/base/Telemetry.java>`_ for more details.
|
||||
|
||||
Dictionary
|
||||
==========
|
||||
|
||||
Events
|
||||
------
|
||||
``action.1``
|
||||
Generic action, usually for tracking menu and toolbar actions.
|
||||
|
||||
``cancel.1``
|
||||
Cancel a state, action, etc.
|
||||
|
||||
``cast.1``
|
||||
Start casting a video.
|
||||
|
||||
``edit.1``
|
||||
Sent when the user edits a top site.
|
||||
|
||||
``launch.1``
|
||||
Launching (opening) an external application.
|
||||
Note: Only used in JavaScript for now.
|
||||
|
||||
``loadurl.1``
|
||||
Loading a URL.
|
||||
|
||||
``locale.browser.reset.1``
|
||||
When the user chooses "System default" in the browser locale picker.
|
||||
|
||||
``locale.browser.selected.1``
|
||||
When the user chooses a locale in the browser locale picker. The selected
|
||||
locale is provided as the extra.
|
||||
|
||||
``locale.browser.unselected.1``
|
||||
When the user chose a different locale in the browser locale picker, this
|
||||
event is fired with the previous locale as the extra. If the previous locale
|
||||
could not be determined, "unknown" is provided.
|
||||
|
||||
``setdefault.1``
|
||||
Set default home panel.
|
||||
|
||||
``pin.1``, ``unpin.1``
|
||||
Sent when the user pinned or unpinned a top site.
|
||||
|
||||
``policynotification.success.1:true``
|
||||
Sent when a user has accepted the data notification policy. Can be ``false``
|
||||
instead of ``true`` if an error occurs.
|
||||
|
||||
``sanitize.1``
|
||||
Sent when the user chooses to clear private data.
|
||||
|
||||
``save.1`` ``unsave.1``
|
||||
Saving or unsaving a resource (reader, bookmark, etc.) for viewing later.
|
||||
Note: Only used in JavaScript for now.
|
||||
|
||||
``search.1``
|
||||
Sent when the user performs a search. Currently used in the search activity.
|
||||
|
||||
``share.1``
|
||||
Sharing content.
|
||||
|
||||
Methods
|
||||
-------
|
||||
``banner``
|
||||
Action triggered from a banner (such as HomeBanner).
|
||||
Note: Only used in JavaScript for now.
|
||||
|
||||
``content``
|
||||
Action triggered from a content page.
|
||||
|
||||
Sessions
|
||||
--------
|
||||
``searchactivity.1``
|
||||
Started when the user launches the search activity (onStart) and stopped
|
||||
when they leave the search activity.
|
4
mobile/android/base/gradle_AndroidManifest.xml
Normal file
4
mobile/android/base/gradle_AndroidManifest.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mozilla.gecko">
|
||||
|
||||
</manifest>
|
@ -557,3 +557,8 @@ just addresses the organization to follow, e.g. "This site is run by " -->
|
||||
"Last synced" is one of the user's other Sync clients, typically Firefox on
|
||||
their desktop or laptop.-->
|
||||
<!ENTITY remote_tabs_last_synced "Last synced: &formatS;">
|
||||
|
||||
<!-- Find-In-Page strings -->
|
||||
<!-- LOCALIZATION NOTE (find_matchcase): This is meant to appear as an icon that changes color
|
||||
if match-case is activated. i.e. No more than two letters, one uppercase, one lowercase. -->
|
||||
<!ENTITY find_matchcase "Aa">
|
||||
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_checked="true"
|
||||
android:color="@color/find_matchcase_on"/>
|
||||
|
||||
<item android:state_checked="false"
|
||||
android:color="@color/find_matchcase_off"/>
|
||||
|
||||
</selector>
|
@ -28,6 +28,15 @@
|
||||
android:textColor="@color/find_status_default"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/find_matchcase"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/find_in_page_matchcase_margin_right"
|
||||
android:checked="false"
|
||||
android:text="@string/find_matchcase"
|
||||
android:textColor="@drawable/find_matchcase_selector"/>
|
||||
|
||||
<ImageButton android:id="@+id/find_prev"
|
||||
style="@style/FindBar.ImageButton"
|
||||
android:contentDescription="@string/find_prev"
|
||||
|
@ -152,6 +152,8 @@
|
||||
|
||||
<!-- Colour used for Find-In-Page dialog -->
|
||||
<color name="find_status_default">#AFB1B3</color>
|
||||
<color name="find_matchcase_on">#AFB1B3</color>
|
||||
<color name="find_matchcase_off">#D02626</color>
|
||||
|
||||
<!-- Canvas delegate paint color -->
|
||||
<color name="canvas_delegate_paint">#FFFF0000</color>
|
||||
|
@ -183,7 +183,8 @@
|
||||
<dimen name="find_in_page_text_margin_right">12dip</dimen>
|
||||
<dimen name="find_in_page_text_padding_left">10dip</dimen>
|
||||
<dimen name="find_in_page_text_padding_right">10dip</dimen>
|
||||
<dimen name="find_in_page_status_margin_right">5dip</dimen>
|
||||
<dimen name="find_in_page_status_margin_right">15dip</dimen>
|
||||
<dimen name="find_in_page_matchcase_margin_right">10dip</dimen>
|
||||
<dimen name="find_in_page_control_margin_top">2dip</dimen>
|
||||
|
||||
</resources>
|
||||
|
@ -33,18 +33,18 @@ var FindHelper = {
|
||||
|
||||
_findOpened: function() {
|
||||
Messaging.addListener((data) => {
|
||||
this.doFind(data);
|
||||
return this._getMatchesCountResult(data);
|
||||
this.doFind(data.searchString, data.matchCase);
|
||||
return this._getMatchesCountResult(data.searchString);
|
||||
}, "FindInPage:Find");
|
||||
|
||||
Messaging.addListener((data) => {
|
||||
this.findAgain(data, false);
|
||||
return this._getMatchesCountResult(data);
|
||||
this.findAgain(data.searchString, false, data.matchCase);
|
||||
return this._getMatchesCountResult(data.searchString);
|
||||
}, "FindInPage:Next");
|
||||
|
||||
Messaging.addListener((data) => {
|
||||
this.findAgain(data, true);
|
||||
return this._getMatchesCountResult(data);
|
||||
this.findAgain(data.searchString, true, data.matchCase);
|
||||
return this._getMatchesCountResult(data.searchString);
|
||||
}, "FindInPage:Prev");
|
||||
},
|
||||
|
||||
@ -99,22 +99,24 @@ var FindHelper = {
|
||||
this._matchesCountResult = result;
|
||||
},
|
||||
|
||||
doFind: function(aSearchString) {
|
||||
doFind: function(searchString, matchCase) {
|
||||
if (!this._finder) {
|
||||
this._init();
|
||||
}
|
||||
|
||||
this._finder.fastFind(aSearchString, false);
|
||||
this._finder.caseSensitive = matchCase;
|
||||
this._finder.fastFind(searchString, false);
|
||||
},
|
||||
|
||||
findAgain: function(aString, aFindBackwards) {
|
||||
findAgain: function(searchString, findBackwards, matchCase) {
|
||||
// This can happen if the user taps next/previous after re-opening the search bar
|
||||
if (!this._finder) {
|
||||
this.doFind(aString);
|
||||
this.doFind(searchString, matchCase);
|
||||
return;
|
||||
}
|
||||
|
||||
this._finder.findAgain(aFindBackwards, false, false);
|
||||
this._finder.caseSensitive = matchCase;
|
||||
this._finder.findAgain(findBackwards, false, false);
|
||||
},
|
||||
|
||||
onFindResult: function(aData) {
|
||||
|
57
mobile/android/gradle/Makefile.in
Normal file
57
mobile/android/gradle/Makefile.in
Normal file
@ -0,0 +1,57 @@
|
||||
# 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/.
|
||||
|
||||
gradle := \
|
||||
gradle.properties.in \
|
||||
$(NULL)
|
||||
|
||||
gradle_PATH := $(CURDIR)
|
||||
gradle_FLAGS += -Dtopsrcdir=$(abspath $(topsrcdir))
|
||||
gradle_FLAGS += -Dtopobjdir=$(abspath $(DEPTH))
|
||||
gradle_KEEP_PATH := 1
|
||||
PP_TARGETS += gradle
|
||||
|
||||
wrapper_FILES := \
|
||||
build.gradle \
|
||||
settings.gradle \
|
||||
gradle/wrapper/gradle-wrapper.jar \
|
||||
gradle/wrapper/gradle-wrapper.properties \
|
||||
gradlew \
|
||||
$(NULL)
|
||||
|
||||
wrapper_DEST := $(CURDIR)
|
||||
wrapper_KEEP_PATH := 1
|
||||
INSTALL_TARGETS += wrapper
|
||||
|
||||
base/src/main/java/org/mozilla/gecko:
|
||||
$(NSINSTALL) -D ${@D}
|
||||
ln -s $(topsrcdir)/mobile/android/base $@
|
||||
libs:: base/src/main/java/org/mozilla/gecko
|
||||
|
||||
base/src/main/res:
|
||||
$(NSINSTALL) -D ${@D}
|
||||
ln -s $(topsrcdir)/mobile/android/base/resources $@
|
||||
libs:: base/src/main/res
|
||||
|
||||
app/src/androidTest/robocop_harness/java/org/mozilla/gecko:
|
||||
$(NSINSTALL) -D ${@D}
|
||||
ln -s $(topsrcdir)/build/mobile/robocop $@
|
||||
libs:: app/src/androidTest/robocop_harness/java/org/mozilla/gecko
|
||||
|
||||
app/src/androidTest/robocop/java/org/mozilla/gecko/tests:
|
||||
$(NSINSTALL) -D ${@D}
|
||||
ln -s $(topsrcdir)/mobile/android/base/tests $@
|
||||
libs:: app/src/androidTest/robocop/java/org/mozilla/gecko/tests
|
||||
|
||||
app/src/androidTest/browser/java/org/mozilla/gecko:
|
||||
$(NSINSTALL) -D ${@D}
|
||||
ln -s $(topsrcdir)/mobile/android/tests/browser/junit3/src $@
|
||||
libs:: app/src/androidTest/browser/java/org/mozilla/gecko
|
||||
|
||||
app/src/androidTest/background/java/org/mozilla/gecko/background:
|
||||
$(NSINSTALL) -D ${@D}
|
||||
ln -s $(topsrcdir)/mobile/android/tests/background/junit3/src $@
|
||||
libs:: app/src/androidTest/background/java/org/mozilla/gecko/background
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
23
mobile/android/gradle/build.gradle
Normal file
23
mobile/android/gradle/build.gradle
Normal file
@ -0,0 +1,23 @@
|
||||
buildDir = "${topobjdir}/mobile/android/gradle/build"
|
||||
|
||||
ext {
|
||||
compileSdkVersion = "${compileSdkVersion}"
|
||||
buildToolsVersion = "${buildToolsVersion}"
|
||||
|
||||
targetSdkVersion = "${targetSdkVersion}"
|
||||
minSdkVersion = "${minSdkVersion}"
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:0.12.2'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
15
mobile/android/gradle/gradle.properties.in
Normal file
15
mobile/android/gradle/gradle.properties.in
Normal file
@ -0,0 +1,15 @@
|
||||
#filter substitution
|
||||
topsrcdir=@topsrcdir@
|
||||
topobjdir=@topobjdir@
|
||||
compileSdkVersion=android-@ANDROID_TARGET_SDK@
|
||||
buildToolsVersion=20.0.0
|
||||
targetSdkVersion=@ANDROID_TARGET_SDK@
|
||||
minSdkVersion=@MOZ_ANDROID_MIN_SDK_VERSION@
|
||||
#ifdef MOZ_ANDROID_MAX_SDK_VERSION
|
||||
maxSdkVersion=@MOZ_ANDROID_MAX_SDK_VERSION@
|
||||
#endif
|
||||
#if MOZ_CRASHREPORTER
|
||||
MOZ_CRASHREPORTER=true
|
||||
#else
|
||||
MOZ_CRASHREPORTER=false
|
||||
#endif
|
BIN
mobile/android/gradle/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
mobile/android/gradle/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
mobile/android/gradle/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
mobile/android/gradle/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
#Wed Apr 10 15:27:10 PDT 2013
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
|
164
mobile/android/gradle/gradlew
vendored
Executable file
164
mobile/android/gradle/gradlew
vendored
Executable file
@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
5
mobile/android/gradle/moz.build
Normal file
5
mobile/android/gradle/moz.build
Normal file
@ -0,0 +1,5 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
8
mobile/android/gradle/settings.gradle
Normal file
8
mobile/android/gradle/settings.gradle
Normal file
@ -0,0 +1,8 @@
|
||||
include ':app'
|
||||
project(':app').projectDir = new File("${topsrcdir}/mobile/android/app")
|
||||
|
||||
include ':base'
|
||||
project(':base').projectDir = new File("${topsrcdir}/mobile/android/base")
|
||||
|
||||
include ':thirdparty'
|
||||
project(':thirdparty').projectDir = new File("${topsrcdir}/mobile/android/thirdparty")
|
@ -24,6 +24,7 @@ DIRS += [
|
||||
'fonts',
|
||||
'geckoview_library',
|
||||
'extensions',
|
||||
'gradle',
|
||||
]
|
||||
|
||||
if not CONFIG['LIBXUL_SDK']:
|
||||
|
@ -216,3 +216,6 @@
|
||||
<string name="fxaccount_remove_account_dialog_message">&fxaccount_remove_account_dialog_message;</string>
|
||||
<string name="fxaccount_remove_account_toast">&fxaccount_remove_account_toast;</string>
|
||||
<string name="fxaccount_remove_account_menu_item">&fxaccount_remove_account_menu_item;</string>
|
||||
|
||||
<!-- Find-In-Page strings -->
|
||||
<string name="find_matchcase">&find_matchcase;</string>
|
||||
|
49
mobile/android/thirdparty/build.gradle
vendored
Normal file
49
mobile/android/thirdparty/build.gradle
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
project.buildDir = "${topobjdir}/mobile/android/gradle/thirdparty/build"
|
||||
|
||||
apply plugin: 'android-library'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'org.mozilla.gecko.thirdparty'
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
runProguard false
|
||||
proguardFile getDefaultProguardFile('proguard-android.txt')
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
android {
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest {
|
||||
srcFile 'gradle_AndroidManifest.xml'
|
||||
}
|
||||
|
||||
java {
|
||||
srcDir "."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:support-v4:19.1.+'
|
||||
}
|
4
mobile/android/thirdparty/gradle_AndroidManifest.xml
vendored
Normal file
4
mobile/android/thirdparty/gradle_AndroidManifest.xml
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mozilla.gecko.thirdparty">
|
||||
|
||||
</manifest>
|
Loading…
Reference in New Issue
Block a user