зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound, a=merge
This commit is contained in:
Коммит
ac1c135457
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
|
||||
<!-- 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"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
|
||||
<!-- 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,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
|
||||
<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="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
|
||||
<!-- 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"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
|
||||
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
|
||||
<!-- 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"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "b290c77ccb7ab0af599b3d8287b71b9970d8dcb0",
|
||||
"git_revision": "5a7f87b1505ba89b586372cbbbe9507d1016c40c",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "87d96f3c66f704247d1996570748de07ca1aff07",
|
||||
"revision": "85b4fb5a2fd0040b3726a4f1e4218f2dbfd4edce",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
|
||||
<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="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<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="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
|
||||
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
|
||||
|
|
|
@ -154,20 +154,20 @@ const gXPInstallObserver = {
|
|||
host = (install.sourceURI instanceof Ci.nsIStandardURL) &&
|
||||
install.sourceURI.host;
|
||||
|
||||
let error = (host || install.error == 0) ? "addonError" : "addonLocalError";
|
||||
if (install.error != 0)
|
||||
let error = (host || install.error == 0) ? "addonInstallError" : "addonLocalInstallError";
|
||||
let args;
|
||||
if (install.error < 0) {
|
||||
error += install.error;
|
||||
else if (install.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
|
||||
args = [brandShortName, install.name];
|
||||
} else if (install.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
|
||||
error += "Blocklisted";
|
||||
else
|
||||
args = [install.name];
|
||||
} else {
|
||||
error += "Incompatible";
|
||||
args = [brandShortName, Services.appinfo.version, install.name];
|
||||
}
|
||||
|
||||
messageString = gNavigatorBundle.getString(error);
|
||||
messageString = messageString.replace("#1", install.name);
|
||||
if (host)
|
||||
messageString = messageString.replace("#2", host);
|
||||
messageString = messageString.replace("#3", brandShortName);
|
||||
messageString = messageString.replace("#4", Services.appinfo.version);
|
||||
messageString = gNavigatorBundle.getFormattedString(error, args);
|
||||
|
||||
PopupNotifications.show(browser, notificationID, messageString, anchorID,
|
||||
action, null, options);
|
||||
|
|
|
@ -483,38 +483,32 @@ var PlacesCommandHook = {
|
|||
* the address of the link target
|
||||
* @param aTitle
|
||||
* The link text
|
||||
* @param [optional] aDescription
|
||||
* The linked page description, if available
|
||||
*/
|
||||
bookmarkLink: Task.async(function* (aParentId, aURL, aTitle) {
|
||||
let node = null;
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
node = yield PlacesUIUtils.fetchNodeLike({ url: aURL });
|
||||
}
|
||||
else {
|
||||
let linkURI = makeURI(aURL);
|
||||
let itemId = PlacesUtils.getMostRecentBookmarkForURI(linkURI);
|
||||
if (itemId != -1) {
|
||||
node = { itemId, uri: aURL };
|
||||
PlacesUIUtils.completeNodeLikeObjectForItemId(node);
|
||||
}
|
||||
}
|
||||
|
||||
bookmarkLink: Task.async(function* (aParentId, aURL, aTitle, aDescription="") {
|
||||
let node = yield PlacesUIUtils.fetchNodeLike({ url: aURL });
|
||||
if (node) {
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "edit"
|
||||
, type: "bookmark"
|
||||
, node
|
||||
}, window);
|
||||
}
|
||||
else {
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "bookmark"
|
||||
, uri: linkURI
|
||||
, title: aTitle
|
||||
, hiddenRows: [ "description"
|
||||
, "location"
|
||||
, "loadInSidebar"
|
||||
, "keyword" ]
|
||||
}, window);
|
||||
}, window.top);
|
||||
return;
|
||||
}
|
||||
|
||||
let ip = new InsertionPoint(aParentId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
Components.interfaces.nsITreeView.DROP_ON);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "bookmark"
|
||||
, uri: makeURI(aURL)
|
||||
, title: aTitle
|
||||
, description: aDescription
|
||||
, defaultInsertionPoint: ip
|
||||
, hiddenRows: [ "description"
|
||||
, "location"
|
||||
, "loadInSidebar"
|
||||
, "keyword" ]
|
||||
}, window.top);
|
||||
}),
|
||||
|
||||
/**
|
||||
|
@ -586,7 +580,9 @@ var PlacesCommandHook = {
|
|||
else
|
||||
description = PlacesUIUtils.getDescriptionFromDocument(doc);
|
||||
|
||||
var toolbarIP = new InsertionPoint(PlacesUtils.toolbarFolderId, -1);
|
||||
var toolbarIP = new InsertionPoint(PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
Components.interfaces.nsITreeView.DROP_ON);
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "livemark"
|
||||
, feedURI: feedURI
|
||||
|
@ -1001,7 +997,7 @@ var PlacesMenuDNDHandler = {
|
|||
onDragOver: function PMDH_onDragOver(event) {
|
||||
let ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
Ci.nsITreeView.DROP_ON);
|
||||
Components.interfaces.nsITreeView.DROP_ON);
|
||||
if (ip && PlacesControllerDragHelper.canDrop(ip, event.dataTransfer))
|
||||
event.preventDefault();
|
||||
|
||||
|
@ -1017,7 +1013,7 @@ var PlacesMenuDNDHandler = {
|
|||
// Put the item at the end of bookmark menu.
|
||||
let ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
Ci.nsITreeView.DROP_ON);
|
||||
Components.interfaces.nsITreeView.DROP_ON);
|
||||
PlacesControllerDragHelper.onDrop(ip, event.dataTransfer);
|
||||
PlacesControllerDragHelper.currentDropTarget = null;
|
||||
event.stopPropagation();
|
||||
|
|
|
@ -4558,7 +4558,7 @@ var TabsProgressListener = {
|
|||
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
|
||||
// Reader mode actually cares about these:
|
||||
let mm = gBrowser.selectedBrowser.messageManager;
|
||||
mm.sendAsyncMessage("Reader:PushState");
|
||||
mm.sendAsyncMessage("Reader:PushState", {isArticle: gBrowser.selectedBrowser.isArticle});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1630,30 +1630,17 @@ nsContextMenu.prototype = {
|
|||
let onMessage = (message) => {
|
||||
mm.removeMessageListener("ContextMenu:BookmarkFrame:Result", onMessage);
|
||||
|
||||
let itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
|
||||
if (itemId == -1) {
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "add"
|
||||
, type: "bookmark"
|
||||
, uri: uri
|
||||
, title: message.data.title
|
||||
, description: message.data.description
|
||||
, hiddenRows: [ "description"
|
||||
, "location"
|
||||
, "loadInSidebar"
|
||||
, "keyword" ]
|
||||
}, window.top);
|
||||
}
|
||||
else {
|
||||
PlacesUIUtils.showBookmarkDialog({ action: "edit"
|
||||
, type: "bookmark"
|
||||
, itemId: itemId
|
||||
}, window.top);
|
||||
}
|
||||
window.top.PlacesCommandHook.bookmarkLink(PlacesUtils.bookmarksMenuFolderId,
|
||||
uri.spec,
|
||||
message.data.title,
|
||||
message.data.description)
|
||||
.catch(Components.utils.reportError);
|
||||
};
|
||||
mm.addMessageListener("ContextMenu:BookmarkFrame:Result", onMessage);
|
||||
|
||||
mm.sendAsyncMessage("ContextMenu:BookmarkFrame", null, { target: this.target });
|
||||
},
|
||||
|
||||
markLink: function CM_markLink(origin) {
|
||||
// send link to social, if it is the page url linkURI will be null
|
||||
SocialMarks.markLink(origin, this.linkURI ? this.linkURI.spec : null, this.target);
|
||||
|
|
|
@ -308,7 +308,7 @@ let AboutReaderListener = {
|
|||
break;
|
||||
|
||||
case "Reader:PushState":
|
||||
this.updateReaderButton();
|
||||
this.updateReaderButton(!!(message.data && message.data.isArticle));
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
@ -353,7 +353,7 @@ let AboutReaderListener = {
|
|||
|
||||
}
|
||||
},
|
||||
updateReaderButton: function() {
|
||||
updateReaderButton: function(forceNonArticle) {
|
||||
if (!ReaderMode.isEnabledForParseOnLoad || this.isAboutReader ||
|
||||
!(content.document instanceof content.HTMLDocument) ||
|
||||
content.document.mozSyntheticDocument) {
|
||||
|
@ -363,6 +363,8 @@ let AboutReaderListener = {
|
|||
// |false| all the time.
|
||||
if (ReaderMode.isProbablyReaderable(content.document)) {
|
||||
sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: true });
|
||||
} else if (forceNonArticle) {
|
||||
sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: false });
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -302,8 +302,7 @@ function test_failed_download() {
|
|||
wait_for_notification("addon-install-failed", function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.getAttribute("label"),
|
||||
"The add-on could not be downloaded because of a connection failure " +
|
||||
"on example.com.",
|
||||
"The add-on could not be downloaded because of a connection failure.",
|
||||
"Should have seen the right message");
|
||||
|
||||
Services.perms.remove("example.com", "install");
|
||||
|
@ -329,7 +328,7 @@ function test_corrupt_file() {
|
|||
wait_for_notification("addon-install-failed", function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.getAttribute("label"),
|
||||
"The add-on downloaded from example.com could not be installed " +
|
||||
"The add-on downloaded from this site could not be installed " +
|
||||
"because it appears to be corrupt.",
|
||||
"Should have seen the right message");
|
||||
|
||||
|
@ -663,7 +662,7 @@ function test_wronghost() {
|
|||
wait_for_notification("addon-install-failed", function(aPanel) {
|
||||
let notification = aPanel.childNodes[0];
|
||||
is(notification.getAttribute("label"),
|
||||
"The add-on downloaded from example.com could not be installed " +
|
||||
"The add-on downloaded from this site could not be installed " +
|
||||
"because it appears to be corrupt.",
|
||||
"Should have seen the right message");
|
||||
|
||||
|
|
|
@ -103,6 +103,10 @@
|
|||
observes="bookmarkThisPageBroadcaster"
|
||||
command="Browser:AddBookmarkAs"
|
||||
onclick="PanelUI.hide();"/>
|
||||
<toolbarseparator id="panelMenu_pocketSeparator"/>
|
||||
<toolbarbutton id="panelMenu_pocket" label="&pocketMenuitem.label;"
|
||||
class="subviewbutton cui-withicon"
|
||||
oncommand="openUILink(Pocket.listURL, event);"/>
|
||||
<toolbarseparator/>
|
||||
<toolbarbutton id="panelMenu_viewBookmarksSidebar"
|
||||
label="&viewBookmarksSidebar2.label;"
|
||||
|
@ -137,10 +141,6 @@
|
|||
<observes element="readingListSidebar" attribute="checked"/>
|
||||
<observes element="readingListSidebar" attribute="hidden"/>
|
||||
</toolbarbutton>
|
||||
<toolbarseparator id="panelMenu_pocketSeparator"/>
|
||||
<toolbarbutton id="panelMenu_pocket" label="&pocketMenuitem.label;"
|
||||
class="subviewbutton cui-withicon"
|
||||
oncommand="openUILink(Pocket.listURL, event);"/>
|
||||
<toolbarseparator class="small-separator"/>
|
||||
<toolbaritem id="panelMenu_bookmarksMenu"
|
||||
orient="vertical"
|
||||
|
|
|
@ -8,6 +8,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/Timer.jsm");
|
||||
|
||||
const {MozLoopService, LOOP_SESSION_TYPE} = Cu.import("resource:///modules/loop/MozLoopService.jsm", {});
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
|
@ -28,6 +29,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "loopUtils",
|
|||
"resource:///modules/loop/utils.js", "utils");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "loopCrypto",
|
||||
"resource:///modules/loop/crypto.js", "LoopCrypto");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ObjectUtils",
|
||||
"resource://gre/modules/ObjectUtils.jsm");
|
||||
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["LoopRooms", "roomsPushNotification"];
|
||||
|
@ -35,6 +38,13 @@ this.EXPORTED_SYMBOLS = ["LoopRooms", "roomsPushNotification"];
|
|||
// The maximum number of clients that we support currently.
|
||||
const CLIENT_MAX_SIZE = 2;
|
||||
|
||||
// Wait at least 5 seconds before doing opportunistic encryption.
|
||||
const MIN_TIME_BEFORE_ENCRYPTION = 5 * 1000;
|
||||
// Wait at maximum of 30 minutes before doing opportunistic encryption.
|
||||
const MAX_TIME_BEFORE_ENCRYPTION = 30 * 60 * 1000;
|
||||
// Wait time between individual re-encryption cycles (1 second).
|
||||
const TIME_BETWEEN_ENCRYPTIONS = 1000;
|
||||
|
||||
const roomsPushNotification = function(version, channelID) {
|
||||
return LoopRoomsInternal.onNotification(version, channelID);
|
||||
};
|
||||
|
@ -117,6 +127,23 @@ const checkForParticipantsUpdate = function(room, updatedRoom) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* These are wrappers which can be overriden by tests to allow us to manually
|
||||
* handle the timeouts.
|
||||
*/
|
||||
let timerHandlers = {
|
||||
/**
|
||||
* Wrapper for setTimeout.
|
||||
*
|
||||
* @param {Function} callback The callback function.
|
||||
* @param {Number} delay The delay in milliseconds.
|
||||
* @return {Number} The timer identifier.
|
||||
*/
|
||||
startTimer(callback, delay) {
|
||||
return setTimeout(callback, delay);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The Rooms class.
|
||||
*
|
||||
|
@ -137,6 +164,19 @@ let LoopRoomsInternal = {
|
|||
return gRoomsCache;
|
||||
},
|
||||
|
||||
/**
|
||||
* @var {Object} encryptionQueue This stores the list of rooms awaiting
|
||||
* encryption and associated timers.
|
||||
*/
|
||||
encryptionQueue: {
|
||||
queue: [],
|
||||
timer: null,
|
||||
reset: function() {
|
||||
this.queue = [];
|
||||
this.timer = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @var {String} sessionType The type of user session. May be 'FXA' or 'GUEST'.
|
||||
*/
|
||||
|
@ -160,6 +200,64 @@ let LoopRoomsInternal = {
|
|||
return count;
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes the encryption queue. Takes the next item off the queue,
|
||||
* restarts the timer if necessary.
|
||||
*
|
||||
* Although this is only called from a timer callback, it is an async function
|
||||
* so that tests can call it and be deterministic.
|
||||
*/
|
||||
processEncryptionQueue: Task.async(function* () {
|
||||
let roomToken = this.encryptionQueue.queue.shift();
|
||||
|
||||
// Performed in sync fashion so that we don't queue a timer until it has
|
||||
// completed, and to make it easier to run tests.
|
||||
let roomData = this.rooms.get(roomToken);
|
||||
|
||||
if (roomData) {
|
||||
try {
|
||||
// Passing the empty object for roomData is enough for the room to be
|
||||
// re-encrypted.
|
||||
yield LoopRooms.promise("update", roomToken, {});
|
||||
} catch (error) {
|
||||
MozLoopService.log.error("Upgrade encryption of room failed", error);
|
||||
// No need to remove the room from the list as that's done in the shift above.
|
||||
}
|
||||
}
|
||||
|
||||
if (this.encryptionQueue.queue.length) {
|
||||
this.encryptionQueue.timer =
|
||||
timerHandlers.startTimer(this.processEncryptionQueue.bind(this), TIME_BETWEEN_ENCRYPTIONS);
|
||||
} else {
|
||||
this.encryptionQueue.timer = null;
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Queues a room for encryption sometime in the future. This is done so as
|
||||
* not to overload the server or the browser when we initially request the
|
||||
* list of rooms.
|
||||
*
|
||||
* @param {String} roomToken The token for the room that needs encrypting.
|
||||
*/
|
||||
queueForEncryption: function(roomToken) {
|
||||
if (!this.encryptionQueue.queue.includes(roomToken)) {
|
||||
this.encryptionQueue.queue.push(roomToken);
|
||||
}
|
||||
|
||||
// Set up encryption to happen at a random time later. There's a minimum
|
||||
// wait time - we don't need to do this straight away, so no need if the user
|
||||
// is starting up. We then add a random factor on top of that. This is to
|
||||
// try and avoid any potential with a set of clients being restarted at the
|
||||
// same time and flooding the server.
|
||||
if (!this.encryptionQueue.timer) {
|
||||
let waitTime = (MAX_TIME_BEFORE_ENCRYPTION - MIN_TIME_BEFORE_ENCRYPTION) *
|
||||
Math.random() + MIN_TIME_BEFORE_ENCRYPTION;
|
||||
this.encryptionQueue.timer =
|
||||
timerHandlers.startTimer(this.processEncryptionQueue.bind(this), waitTime);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets or creates a room key for a room.
|
||||
*
|
||||
|
@ -214,24 +312,12 @@ let LoopRoomsInternal = {
|
|||
* any decrypted data.
|
||||
* - all: The roomData with both encrypted and decrypted
|
||||
* information.
|
||||
* If rejected, encryption has failed. This could be due to
|
||||
* missing keys for FxA, which this process can't manage. It
|
||||
* is generally expected the panel will prompt the user for
|
||||
* re-auth if the FxA keys are missing.
|
||||
*/
|
||||
promiseEncryptRoomData: Task.async(function* (roomData) {
|
||||
// XXX We should only return unencrypted data whilst we're still working
|
||||
// on context. Once bug 1115340 is fixed, this function should no longer be
|
||||
// here.
|
||||
function getUnencryptedData() {
|
||||
var serverRoomData = extend({}, roomData);
|
||||
delete serverRoomData.decryptedContext;
|
||||
|
||||
// We can only save roomName as non-encypted data for now.
|
||||
serverRoomData.roomName = roomData.decryptedContext.roomName;
|
||||
|
||||
return {
|
||||
all: roomData,
|
||||
encrypted: serverRoomData
|
||||
};
|
||||
}
|
||||
|
||||
var newRoomData = extend({}, roomData);
|
||||
|
||||
if (!newRoomData.context) {
|
||||
|
@ -241,17 +327,7 @@ let LoopRoomsInternal = {
|
|||
// First get the room key.
|
||||
let key = yield this.promiseGetOrCreateRoomKey(newRoomData);
|
||||
|
||||
try {
|
||||
newRoomData.context.wrappedKey = yield this.promiseEncryptedRoomKey(key);
|
||||
}
|
||||
catch (ex) {
|
||||
// XXX Bug 1153788 should remove this, then we can remove the whole
|
||||
// try/catch.
|
||||
if (ex.message == "FxA re-register not implemented") {
|
||||
return getUnencryptedData();
|
||||
}
|
||||
return Promise.reject(ex);
|
||||
}
|
||||
newRoomData.context.wrappedKey = yield this.promiseEncryptedRoomKey(key);
|
||||
|
||||
// Now encrypt the actual data.
|
||||
newRoomData.context.value = yield loopCrypto.encryptBytes(key,
|
||||
|
@ -312,7 +388,9 @@ let LoopRoomsInternal = {
|
|||
if (fallback) {
|
||||
// Fallback decryption succeeded, so we need to re-encrypt the room key and
|
||||
// save the data back again.
|
||||
// XXX Bug 1152764 will implement this or make it a separate bug.
|
||||
MozLoopService.log.debug("Fell back to saved key, queuing for encryption",
|
||||
roomData.roomToken);
|
||||
this.queueForEncryption(roomData.roomToken);
|
||||
} else if (!savedRoomKey || key != savedRoomKey) {
|
||||
// Decryption succeeded, but we don't have the right key saved.
|
||||
try {
|
||||
|
@ -363,17 +441,23 @@ let LoopRoomsInternal = {
|
|||
// We don't do anything with roomUrl here as it doesn't need a key
|
||||
// string adding at this stage.
|
||||
|
||||
// No encrypted data, use the old roomName field.
|
||||
// XXX Bug 1152764 will add functions for automatically encrypting the room
|
||||
// name.
|
||||
// No encrypted data yet, use the old roomName field.
|
||||
room.decryptedContext = {
|
||||
roomName: room.roomName
|
||||
};
|
||||
delete room.roomName;
|
||||
|
||||
// This room doesn't have context, so we'll save it for a later encryption
|
||||
// cycle.
|
||||
this.queueForEncryption(room.roomToken);
|
||||
|
||||
this.saveAndNotifyUpdate(room, isUpdate);
|
||||
} else {
|
||||
// XXX Don't decrypt if same?
|
||||
// We could potentially optimise this later by not decrypting if the
|
||||
// encrypted context hasn't already changed. However perf doesn't seem
|
||||
// to be too bigger an issue at the moment, so we just decrypt for now.
|
||||
// If we do change this, then we need to make sure we get the new room
|
||||
// data setup properly, as happens at the end of promiseDecryptRoomData.
|
||||
try {
|
||||
let roomData = yield this.promiseDecryptRoomData(room);
|
||||
|
||||
|
@ -725,13 +809,16 @@ let LoopRoomsInternal = {
|
|||
update: function(roomToken, roomData, callback) {
|
||||
let room = this.rooms.get(roomToken);
|
||||
let url = "/rooms/" + encodeURIComponent(roomToken);
|
||||
|
||||
if (!room.decryptedContext) {
|
||||
room.decryptedContext = {
|
||||
roomName: roomData.roomName || room.roomName
|
||||
};
|
||||
} else {
|
||||
room.decryptedContext.roomName = roomData.roomName || room.roomName;
|
||||
// room.roomName is the final fallback as this is pre-encryption support.
|
||||
// Bug 1166283 is tracking the removal of the fallback.
|
||||
room.decryptedContext.roomName = roomData.roomName ||
|
||||
room.decryptedContext.roomName ||
|
||||
room.roomName;
|
||||
}
|
||||
if (roomData.urls && roomData.urls.length) {
|
||||
// For now we only support adding one URL to the room context.
|
||||
|
@ -746,17 +833,9 @@ let LoopRoomsInternal = {
|
|||
context: encrypted.context
|
||||
};
|
||||
|
||||
// If we're not encrypting currently, then only send the roomName.
|
||||
// XXX This should go away once bug 1153788 is fixed.
|
||||
if (!sendData.context) {
|
||||
sendData = {
|
||||
roomName: room.decryptedContext.roomName
|
||||
};
|
||||
} else {
|
||||
// This might be an upgrade to encrypted rename, so store the key
|
||||
// just in case.
|
||||
yield this.roomsCache.setKey(this.sessionType, all.roomToken, all.roomKey);
|
||||
}
|
||||
// This might be an upgrade to encrypted rename, so store the key
|
||||
// just in case.
|
||||
yield this.roomsCache.setKey(this.sessionType, all.roomToken, all.roomKey);
|
||||
|
||||
let response = yield MozLoopService.hawkRequest(this.sessionType,
|
||||
url, "PATCH", sendData);
|
||||
|
|
|
@ -1349,9 +1349,10 @@ this.MozLoopService = {
|
|||
return;
|
||||
}
|
||||
|
||||
// XXX If we don't have a key for FxA yet, then simply reject for now.
|
||||
// We'll create some sign-in/sign-out UX in bug 1153788.
|
||||
reject(new Error("FxA re-register not implemented"));
|
||||
// This should generally never happen, but its not really possible
|
||||
// for us to force reauth from here in a sensible way for the user.
|
||||
// So we'll just have to flag it the best we can.
|
||||
reject(new Error("No FxA key available"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ Cu.import("resource:///modules/loop/LoopCalls.jsm");
|
|||
Cu.import("resource:///modules/loop/LoopRooms.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
const { MozLoopServiceInternal } = Cu.import("resource:///modules/loop/MozLoopService.jsm", {});
|
||||
const { LoopRoomsInternal } = Cu.import("resource:///modules/loop/LoopRooms.jsm", {});
|
||||
const { LoopRoomsInternal, timerHandlers } = Cu.import("resource:///modules/loop/LoopRooms.jsm", {});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "MozLoopPushHandler",
|
||||
"resource:///modules/loop/MozLoopPushHandler.jsm");
|
||||
|
|
|
@ -9,16 +9,18 @@ Cu.import("resource:///modules/loop/LoopRooms.jsm");
|
|||
Cu.import("resource:///modules/Chat.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
timerHandlers.startTimer = callback => callback();
|
||||
|
||||
let openChatOrig = Chat.open;
|
||||
|
||||
const kGuestKey = "uGIs-kGbYt1hBBwjyW7MLQ";
|
||||
const kKey = "uGIs-kGbYt1hBBwjyW7MLQ";
|
||||
|
||||
// Rooms details as responded by the server.
|
||||
const kRoomsResponses = new Map([
|
||||
["_nxD4V4FflQ", {
|
||||
roomToken: "_nxD4V4FflQ",
|
||||
// Encrypted with roomKey "FliIGLUolW-xkKZVWstqKw".
|
||||
// roomKey is wrapped with kGuestKey.
|
||||
// roomKey is wrapped with kKey.
|
||||
context: {
|
||||
wrappedKey: "F3V27oPB+FgjFbVPML2PupONYqoIZ53XRU4BqG46Lr3eyIGumgCEqgjSe/MXAXiQ//8=",
|
||||
value: "df7B4SNxhOI44eJjQavCevADyCCxz6/DEZbkOkRUMVUxzS42FbzN6C2PqmCKDYUGyCJTwJ0jln8TLw==",
|
||||
|
@ -304,12 +306,7 @@ add_task(function* setup_server() {
|
|||
room.deleted = kRoomUpdates[qs.version].deleted;
|
||||
res.write(JSON.stringify([room]));
|
||||
} else {
|
||||
// XXX Only return last 2 elements until FxA keys are implemented.
|
||||
if (MozLoopServiceInternal.fxAOAuthTokenData) {
|
||||
res.write(JSON.stringify([...kRoomsResponses.values()].slice(1, 3)));
|
||||
} else {
|
||||
res.write(JSON.stringify([...kRoomsResponses.values()]));
|
||||
}
|
||||
res.write(JSON.stringify([...kRoomsResponses.values()]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,8 +428,7 @@ add_task(function* test_openRoom() {
|
|||
|
||||
// Test if the rooms cache is refreshed after FxA signin or signout.
|
||||
add_task(function* test_refresh() {
|
||||
// XXX Temporarily whilst FxA encryption isn't handled (bug 1153788).
|
||||
Array.prototype.push.apply(gExpectedAdds, [...kExpectedRooms.values()].slice(1, 3));
|
||||
gExpectedAdds.push(...kExpectedRooms.values());
|
||||
gExpectedRefresh = true;
|
||||
|
||||
// Make the switch.
|
||||
|
@ -441,6 +437,7 @@ add_task(function* test_refresh() {
|
|||
email: "fake@invalid.com",
|
||||
uid: "fake"
|
||||
};
|
||||
Services.prefs.setCharPref("loop.key.fxa", kKey);
|
||||
|
||||
yield waitForCondition(() => !gExpectedRefresh);
|
||||
yield waitForCondition(() => gExpectedAdds.length === 0);
|
||||
|
@ -639,7 +636,7 @@ add_task(function* () {
|
|||
function run_test() {
|
||||
setupFakeLoopServer();
|
||||
|
||||
Services.prefs.setCharPref("loop.key", kGuestKey);
|
||||
Services.prefs.setCharPref("loop.key", kKey);
|
||||
|
||||
LoopRooms.on("add", onRoomAdded);
|
||||
LoopRooms.on("update", onRoomUpdated);
|
||||
|
@ -652,6 +649,7 @@ function run_test() {
|
|||
// Revert original Chat.open implementation
|
||||
Chat.open = openChatOrig;
|
||||
Services.prefs.clearUserPref("loop.key");
|
||||
Services.prefs.clearUserPref("loop.key.fxa");
|
||||
|
||||
MozLoopServiceInternal.fxAOAuthTokenData = null;
|
||||
MozLoopServiceInternal.fxAOAuthProfile = null;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
timerHandlers.startTimer = callback => callback();
|
||||
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
const { LOOP_ROOMS_CACHE_FILENAME } = Cu.import("resource:///modules/loop/LoopRoomsCache.jsm", {});
|
||||
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
|
||||
const loopCrypto = Cu.import("resource:///modules/loop/crypto.js", {}).LoopCrypto;
|
||||
const { LOOP_ROOMS_CACHE_FILENAME } = Cu.import("resource:///modules/loop/LoopRoomsCache.jsm", {});
|
||||
|
||||
let gTimerArgs = [];
|
||||
|
||||
timerHandlers.startTimer = function(callback, delay) {
|
||||
gTimerArgs.push({callback, delay});
|
||||
return gTimerArgs.length;
|
||||
};
|
||||
|
||||
let gRoomPatches = [];
|
||||
|
||||
const kContextEnabledPref = "loop.contextInConverations.enabled";
|
||||
|
||||
const kFxAKey = "uGIs-kGbYt1hBBwjyW7MLQ";
|
||||
|
||||
// Rooms details as responded by the server.
|
||||
const kRoomsResponses = new Map([
|
||||
["_nxD4V4FflQ", {
|
||||
roomToken: "_nxD4V4FflQ",
|
||||
roomName: "First Room Name",
|
||||
roomUrl: "http://localhost:3000/rooms/_nxD4V4FflQ"
|
||||
}],
|
||||
["QzBbvGmIZWU", {
|
||||
roomToken: "QzBbvGmIZWU",
|
||||
roomName: "Loopy Discussion",
|
||||
roomUrl: "http://localhost:3000/rooms/QzBbvGmIZWU"
|
||||
}]
|
||||
]);
|
||||
|
||||
// This is a cut-down version of the one in test_looprooms.js.
|
||||
add_task(function* setup_server() {
|
||||
loopServer.registerPathHandler("/registration", (req, res) => {
|
||||
res.setStatusLine(null, 200, "OK");
|
||||
res.processAsync();
|
||||
res.finish();
|
||||
});
|
||||
|
||||
loopServer.registerPathHandler("/rooms", (req, res) => {
|
||||
res.setStatusLine(null, 200, "OK");
|
||||
|
||||
res.write(JSON.stringify([...kRoomsResponses.values()]));
|
||||
|
||||
res.processAsync();
|
||||
res.finish();
|
||||
});
|
||||
|
||||
function returnRoomDetails(res, roomName) {
|
||||
roomDetail.roomName = roomName;
|
||||
res.setStatusLine(null, 200, "OK");
|
||||
res.write(JSON.stringify(roomDetail));
|
||||
res.processAsync();
|
||||
res.finish();
|
||||
}
|
||||
|
||||
function getJSONData(body) {
|
||||
return JSON.parse(CommonUtils.readBytesFromInputStream(body));
|
||||
}
|
||||
|
||||
// Add a request handler for each room in the list.
|
||||
[...kRoomsResponses.values()].forEach(function(room) {
|
||||
loopServer.registerPathHandler("/rooms/" + encodeURIComponent(room.roomToken), (req, res) => {
|
||||
let roomDetail = extend({}, room);
|
||||
if (req.method == "PATCH") {
|
||||
let data = getJSONData(req.bodyInputStream);
|
||||
Assert.ok("context" in data, "should have encrypted context");
|
||||
gRoomPatches.push(data);
|
||||
delete roomDetail.roomName;
|
||||
roomDetail.context = data.context;
|
||||
res.setStatusLine(null, 200, "OK");
|
||||
res.write(JSON.stringify(roomDetail));
|
||||
res.processAsync();
|
||||
res.finish();
|
||||
} else {
|
||||
res.setStatusLine(null, 200, "OK");
|
||||
res.write(JSON.stringify(room));
|
||||
res.processAsync();
|
||||
res.finish();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
mockPushHandler.registrationPushURL = kEndPointUrl;
|
||||
|
||||
yield MozLoopService.promiseRegisteredWithServers();
|
||||
});
|
||||
|
||||
// Test if getting rooms saves unknown keys correctly.
|
||||
add_task(function* test_get_rooms_upgrades_to_encryption() {
|
||||
let rooms = yield LoopRooms.promise("getAll");
|
||||
|
||||
// Check that we've saved the encryption keys correctly.
|
||||
Assert.equal(LoopRoomsInternal.encryptionQueue.queue.length, 2, "Should have two rooms queued");
|
||||
Assert.equal(gTimerArgs.length, 1, "Should have started a timer");
|
||||
|
||||
// Now pretend the timer has fired.
|
||||
yield gTimerArgs[0].callback();
|
||||
|
||||
Assert.equal(gRoomPatches.length, 1, "Should have patched one room");
|
||||
Assert.equal(gTimerArgs.length, 2, "Should have started a second timer");
|
||||
|
||||
yield gTimerArgs[1].callback();
|
||||
|
||||
Assert.equal(gRoomPatches.length, 2, "Should have patches a second room");
|
||||
Assert.equal(gTimerArgs.length, 2, "Should not have queued another timer");
|
||||
|
||||
// Now check that we've got the right data stored in the rooms.
|
||||
rooms = yield LoopRooms.promise("getAll");
|
||||
|
||||
Assert.equal(rooms.length, 2, "Should have two rooms");
|
||||
|
||||
// We have to decrypt the info, no other way.
|
||||
for (let room of rooms) {
|
||||
let roomData = yield loopCrypto.decryptBytes(room.roomKey, room.context.value);
|
||||
|
||||
Assert.deepEqual(JSON.parse(roomData),
|
||||
{ roomName: kRoomsResponses.get(room.roomToken).roomName },
|
||||
"Should have encrypted the data correctly");
|
||||
}
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
setupFakeLoopServer();
|
||||
|
||||
Services.prefs.setCharPref("loop.key.fxa", kFxAKey);
|
||||
Services.prefs.setBoolPref(kContextEnabledPref, true);
|
||||
|
||||
// Pretend we're signed into FxA.
|
||||
MozLoopServiceInternal.fxAOAuthTokenData = { token_type: "bearer" };
|
||||
MozLoopServiceInternal.fxAOAuthProfile = { email: "fake@invalid.com" };
|
||||
|
||||
do_register_cleanup(function () {
|
||||
Services.prefs.clearUserPref(kContextEnabledPref);
|
||||
Services.prefs.clearUserPref("loop.key.fxa");
|
||||
|
||||
MozLoopServiceInternal.fxAOAuthTokenData = null;
|
||||
MozLoopServiceInternal.fxAOAuthProfile = null;
|
||||
});
|
||||
|
||||
run_next_test();
|
||||
}
|
|
@ -57,7 +57,7 @@ add_task(function* test_fxaGetKey() {
|
|||
|
||||
// Currently unimplemented, add a test when we implement the code.
|
||||
yield Assert.rejects(MozLoopService.promiseProfileEncryptionKey(),
|
||||
/not implemented/, "should reject as unimplemented");
|
||||
/No FxA key available/, "should reject as not available");
|
||||
});
|
||||
|
||||
add_task(function test_hasEncryptionKey() {
|
||||
|
|
|
@ -9,6 +9,7 @@ skip-if = toolkit == 'gonk'
|
|||
[test_looprooms.js]
|
||||
[test_looprooms_encryption_in_fxa.js]
|
||||
[test_looprooms_first_notification.js]
|
||||
[test_looprooms_upgrade_to_encryption.js]
|
||||
[test_loopservice_directcall.js]
|
||||
[test_loopservice_dnd.js]
|
||||
[test_loopservice_encryptionkey.js]
|
||||
|
|
|
@ -235,14 +235,10 @@ var BookmarkPropertiesPanel = {
|
|||
else { // edit
|
||||
this._node = dialogInfo.node;
|
||||
this._title = this._node.title;
|
||||
switch (dialogInfo.type) {
|
||||
case "bookmark":
|
||||
this._itemType = BOOKMARK_ITEM;
|
||||
break;
|
||||
case "folder":
|
||||
this._itemType = BOOKMARK_FOLDER;
|
||||
break;
|
||||
}
|
||||
if (PlacesUtils.nodeIsFolder(this._node))
|
||||
this._itemType = BOOKMARK_FOLDER;
|
||||
else if (PlacesUtils.nodeIsURI(this._node))
|
||||
this._itemType = BOOKMARK_ITEM;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
accesskey="&sizeProportional.accesskey;"
|
||||
control="sizeVar"/>
|
||||
</hbox>
|
||||
<menulist id="sizeVar">
|
||||
<menulist id="sizeVar" delayprefsave="true">
|
||||
<menupopup>
|
||||
<menuitem value="9" label="9"/>
|
||||
<menuitem value="10" label="10"/>
|
||||
|
@ -141,7 +141,7 @@
|
|||
<hbox align="center" pack="end">
|
||||
<label accesskey="&serif.accesskey;" control="serif">&serif.label;</label>
|
||||
</hbox>
|
||||
<menulist id="serif" flex="1" style="width: 0px;"
|
||||
<menulist id="serif" flex="1" style="width: 0px;" delayprefsave="true"
|
||||
onsyncfrompreference="return gFontsDialog.readFontSelection(document.getElementById('serif'));"/>
|
||||
<spacer/>
|
||||
</row>
|
||||
|
@ -149,7 +149,7 @@
|
|||
<hbox align="center" pack="end">
|
||||
<label accesskey="&sans-serif.accesskey;" control="sans-serif">&sans-serif.label;</label>
|
||||
</hbox>
|
||||
<menulist id="sans-serif" flex="1" style="width: 0px;"
|
||||
<menulist id="sans-serif" flex="1" style="width: 0px;" delayprefsave="true"
|
||||
onsyncfrompreference="return gFontsDialog.readFontSelection(document.getElementById('sans-serif'));"/>
|
||||
<spacer/>
|
||||
</row>
|
||||
|
@ -157,14 +157,14 @@
|
|||
<hbox align="center" pack="end">
|
||||
<label accesskey="&monospace.accesskey;" control="monospace">&monospace.label;</label>
|
||||
</hbox>
|
||||
<menulist id="monospace" flex="1" style="width: 0px;" crop="right"
|
||||
<menulist id="monospace" flex="1" style="width: 0px;" crop="right" delayprefsave="true"
|
||||
onsyncfrompreference="return gFontsDialog.readFontSelection(document.getElementById('monospace'));"/>
|
||||
<hbox align="center" pack="end">
|
||||
<label value="&size.label;"
|
||||
accesskey="&sizeMonospace.accesskey;"
|
||||
control="sizeMono"/>
|
||||
</hbox>
|
||||
<menulist id="sizeMono">
|
||||
<menulist id="sizeMono" delayprefsave="true">
|
||||
<menupopup>
|
||||
<menuitem value="9" label="9"/>
|
||||
<menuitem value="10" label="10"/>
|
||||
|
|
|
@ -97,9 +97,9 @@
|
|||
<row id="fontRow">
|
||||
<hbox align="center">
|
||||
<label control="defaultFont" accesskey="&defaultFont.accesskey;">&defaultFont.label;</label>
|
||||
<menulist id="defaultFont" />
|
||||
<menulist id="defaultFont" delayprefsave="true"/>
|
||||
<label id="defaultFontSizeLabel" control="defaultFontSize" accesskey="&defaultSize.accesskey;">&defaultSize.label;</label>
|
||||
<menulist id="defaultFontSize">
|
||||
<menulist id="defaultFontSize" delayprefsave="true">
|
||||
<menupopup>
|
||||
<menuitem value="9" label="9"/>
|
||||
<menuitem value="10" label="10"/>
|
||||
|
|
|
@ -80,6 +80,7 @@ skip-if = !e10s || !crashreporter
|
|||
[browser_form_restore_events.js]
|
||||
[browser_formdata.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_formdata_cc.js]
|
||||
[browser_formdata_format.js]
|
||||
[browser_formdata_xpath.js]
|
||||
[browser_frametree.js]
|
||||
|
|
|
@ -181,76 +181,6 @@ add_task(function test_design_mode() {
|
|||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
/**
|
||||
* This test ensures that credit card numbers in form data will not be
|
||||
* collected, while numbers that don't look like credit card numbers will
|
||||
* still be collected.
|
||||
*/
|
||||
add_task(function test_ccNumbers() {
|
||||
const validCCNumbers = [
|
||||
// 15 digits
|
||||
"930771457288760", "474915027480942",
|
||||
"924894781317325", "714816113937185",
|
||||
"790466087343106", "474320195408363",
|
||||
"219211148122351", "633038472250799",
|
||||
"354236732906484", "095347810189325",
|
||||
// 16 digits
|
||||
"3091269135815020", "5471839082338112",
|
||||
"0580828863575793", "5015290610002932",
|
||||
"9465714503078607", "4302068493801686",
|
||||
"2721398408985465", "6160334316984331",
|
||||
"8643619970075142", "0218246069710785"
|
||||
];
|
||||
|
||||
const invalidCCNumbers = [
|
||||
// 15 digits
|
||||
"526931005800649", "724952425140686",
|
||||
"379761391174135", "030551436468583",
|
||||
"947377014076746", "254848023655752",
|
||||
"226871580283345", "708025346034339",
|
||||
"917585839076788", "918632588027666",
|
||||
// 16 digits
|
||||
"9946177098017064", "4081194386488872",
|
||||
"3095975979578034", "3662215692222536",
|
||||
"6723210018630429", "4411962856225025",
|
||||
"8276996369036686", "4449796938248871",
|
||||
"3350852696538147", "5011802870046957"
|
||||
];
|
||||
|
||||
const URL = "http://mochi.test:8888/browser/browser/components/" +
|
||||
"sessionstore/test/browser_formdata_sample.html";
|
||||
|
||||
// Creates a tab, loads a page with a form field, sets the value of the
|
||||
// field, and then removes the tab to trigger data collection.
|
||||
function* createAndRemoveTab(formValue) {
|
||||
// Create a new tab.
|
||||
let tab = gBrowser.addTab(URL);
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// Set form value.
|
||||
yield setInputValue(browser, {id: "txt", value: formValue});
|
||||
|
||||
// Remove the tab.
|
||||
yield promiseRemoveTab(tab);
|
||||
}
|
||||
|
||||
// Test that valid CC numbers are not collected.
|
||||
for (let number of validCCNumbers) {
|
||||
yield createAndRemoveTab(number);
|
||||
let [{state}] = JSON.parse(ss.getClosedTabData(window));
|
||||
ok(!("formdata" in state), "valid CC numbers are not collected");
|
||||
}
|
||||
|
||||
// Test that non-CC numbers are still collected.
|
||||
for (let number of invalidCCNumbers) {
|
||||
yield createAndRemoveTab(number);
|
||||
let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
|
||||
is(formdata.id.txt, number,
|
||||
"numbers that are not valid CC numbers are still collected");
|
||||
}
|
||||
});
|
||||
|
||||
function getInputValue(browser, id) {
|
||||
return sendMessage(browser, "ss-test:getInputValue", {id: id});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
"use strict";
|
||||
|
||||
const URL = "http://mochi.test:8888/browser/browser/components/" +
|
||||
"sessionstore/test/browser_formdata_sample.html";
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
/**
|
||||
* This test ensures that credit card numbers in form data will not be
|
||||
* collected, while numbers that don't look like credit card numbers will
|
||||
* still be collected.
|
||||
*/
|
||||
add_task(function* () {
|
||||
const validCCNumbers = [
|
||||
// 15 digits
|
||||
"930771457288760", "474915027480942",
|
||||
"924894781317325", "714816113937185",
|
||||
"790466087343106", "474320195408363",
|
||||
"219211148122351", "633038472250799",
|
||||
"354236732906484", "095347810189325",
|
||||
// 16 digits
|
||||
"3091269135815020", "5471839082338112",
|
||||
"0580828863575793", "5015290610002932",
|
||||
"9465714503078607", "4302068493801686",
|
||||
"2721398408985465", "6160334316984331",
|
||||
"8643619970075142", "0218246069710785"
|
||||
];
|
||||
|
||||
const invalidCCNumbers = [
|
||||
// 15 digits
|
||||
"526931005800649", "724952425140686",
|
||||
"379761391174135", "030551436468583",
|
||||
"947377014076746", "254848023655752",
|
||||
"226871580283345", "708025346034339",
|
||||
"917585839076788", "918632588027666",
|
||||
// 16 digits
|
||||
"9946177098017064", "4081194386488872",
|
||||
"3095975979578034", "3662215692222536",
|
||||
"6723210018630429", "4411962856225025",
|
||||
"8276996369036686", "4449796938248871",
|
||||
"3350852696538147", "5011802870046957"
|
||||
];
|
||||
|
||||
// Creates a tab, loads a page with a form field, sets the value of the
|
||||
// field, and then removes the tab to trigger data collection.
|
||||
function* createAndRemoveTab(formValue) {
|
||||
// Create a new tab.
|
||||
let tab = gBrowser.addTab(URL);
|
||||
let browser = tab.linkedBrowser;
|
||||
yield promiseBrowserLoaded(browser);
|
||||
|
||||
// Set form value.
|
||||
yield setInputValue(browser, formValue);
|
||||
|
||||
// Remove the tab.
|
||||
yield promiseRemoveTab(tab);
|
||||
}
|
||||
|
||||
// Test that valid CC numbers are not collected.
|
||||
for (let number of validCCNumbers) {
|
||||
yield createAndRemoveTab(number);
|
||||
let [{state}] = JSON.parse(ss.getClosedTabData(window));
|
||||
ok(!("formdata" in state), "valid CC numbers are not collected");
|
||||
}
|
||||
|
||||
// Test that non-CC numbers are still collected.
|
||||
for (let number of invalidCCNumbers) {
|
||||
yield createAndRemoveTab(number);
|
||||
let [{state: {formdata}}] = JSON.parse(ss.getClosedTabData(window));
|
||||
is(formdata.id.txt, number,
|
||||
"numbers that are not valid CC numbers are still collected");
|
||||
}
|
||||
});
|
||||
|
||||
function setInputValue(browser, formValue) {
|
||||
return ContentTask.spawn(browser, formValue, function* (formValue) {
|
||||
content.document.getElementById("txt").setUserInput(formValue);
|
||||
});
|
||||
}
|
|
@ -108,9 +108,7 @@ function test() {
|
|||
function addAndCheckCustomExpression(aTotal, aIndex, aString, noBlur) {
|
||||
addAndCheckExpressions(aTotal, aIndex, "", true);
|
||||
|
||||
for (let i = 0; i < aString.length; i++) {
|
||||
EventUtils.sendChar(aString[i], gDebugger);
|
||||
}
|
||||
EventUtils.sendString(aString, gDebugger);
|
||||
|
||||
gEditor.focus();
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ support-files =
|
|||
[browser_graphs-07a.js]
|
||||
[browser_graphs-07b.js]
|
||||
[browser_graphs-07c.js]
|
||||
[browser_graphs-07d.js]
|
||||
[browser_graphs-08.js]
|
||||
[browser_graphs-09a.js]
|
||||
[browser_graphs-09b.js]
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that selections are drawn onto the canvas.
|
||||
|
||||
const TEST_DATA = [{ delta: 112, value: 48 }, { delta: 213, value: 59 }, { delta: 313, value: 60 }, { delta: 413, value: 59 }, { delta: 530, value: 59 }, { delta: 646, value: 58 }, { delta: 747, value: 60 }, { delta: 863, value: 48 }, { delta: 980, value: 37 }, { delta: 1097, value: 30 }, { delta: 1213, value: 29 }, { delta: 1330, value: 23 }, { delta: 1430, value: 10 }, { delta: 1534, value: 17 }, { delta: 1645, value: 20 }, { delta: 1746, value: 22 }, { delta: 1846, value: 39 }, { delta: 1963, value: 26 }, { delta: 2080, value: 27 }, { delta: 2197, value: 35 }, { delta: 2312, value: 47 }, { delta: 2412, value: 53 }, { delta: 2514, value: 60 }, { delta: 2630, value: 37 }, { delta: 2730, value: 36 }, { delta: 2830, value: 37 }, { delta: 2946, value: 36 }, { delta: 3046, value: 40 }, { delta: 3163, value: 47 }, { delta: 3280, value: 41 }, { delta: 3380, value: 35 }, { delta: 3480, value: 27 }, { delta: 3580, value: 39 }, { delta: 3680, value: 42 }, { delta: 3780, value: 49 }, { delta: 3880, value: 55 }, { delta: 3980, value: 60 }, { delta: 4080, value: 60 }, { delta: 4180, value: 60 }];
|
||||
const TEST_REGIONS = [{ start: 320, end: 460 }, { start: 780, end: 860 }];
|
||||
let {LineGraphWidget} = Cu.import("resource:///modules/devtools/Graphs.jsm", {});
|
||||
let {Promise} = devtools.require("resource://gre/modules/Promise.jsm");
|
||||
|
||||
add_task(function*() {
|
||||
yield promiseTab("about:blank");
|
||||
yield performTest();
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
function* performTest() {
|
||||
let [host, win, doc] = yield createHost();
|
||||
let graph = new LineGraphWidget(doc.body, "fps");
|
||||
yield graph.once("ready");
|
||||
|
||||
testGraph(graph);
|
||||
|
||||
yield graph.destroy();
|
||||
host.destroy();
|
||||
}
|
||||
|
||||
function testGraph(graph) {
|
||||
graph.setData(TEST_DATA);
|
||||
graph.setRegions(TEST_REGIONS);
|
||||
|
||||
// Measure the color of the first pixel before any selection is made.
|
||||
graph._onAnimationFrame();
|
||||
let pixelNoSelection = graph._ctx.getImageData(1, 1, 1, 1).data;
|
||||
|
||||
graph.setSelection({ start: 0, end: 10 });
|
||||
graph._onAnimationFrame();
|
||||
let pixelNormalSelection = graph._ctx.getImageData(1, 1, 1, 1).data;
|
||||
|
||||
Assert.notDeepEqual(pixelNormalSelection, pixelNoSelection,
|
||||
"The first pixel is part of the drawn selection.");
|
||||
|
||||
graph.setSelection({ start: graph.width + 100, end: -100 });
|
||||
graph._onAnimationFrame();
|
||||
let pixelFullSelection = graph._ctx.getImageData(1, 1, 1, 1).data;
|
||||
|
||||
Assert.deepEqual(pixelFullSelection, pixelNormalSelection,
|
||||
"The first pixel is still part of the drawn selection.");
|
||||
}
|
|
@ -82,9 +82,7 @@ function testAdvanceCharCommit(doc) {
|
|||
advanceChars: ":",
|
||||
start: function(editor) {
|
||||
let input = editor.input;
|
||||
for each (let ch in "Test:") {
|
||||
EventUtils.sendChar(ch);
|
||||
}
|
||||
EventUtils.sendString("Test:");
|
||||
},
|
||||
done: onDone("Test", true, def)
|
||||
}, doc);
|
||||
|
|
|
@ -826,7 +826,9 @@ AbstractCanvasGraph.prototype = {
|
|||
stripesColor: this.selectionStripesColor
|
||||
});
|
||||
ctx.fillStyle = pattern;
|
||||
ctx.fillRect(start, 0, end - start, this._height);
|
||||
let rectStart = Math.min(this._width, Math.max(0, start));
|
||||
let rectEnd = Math.min(this._width, Math.max(0, end));
|
||||
ctx.fillRect(rectStart, 0, rectEnd - rectStart, this._height);
|
||||
|
||||
// Draw left boundary.
|
||||
|
||||
|
|
|
@ -2108,8 +2108,10 @@ CssRuleView.prototype = {
|
|||
// Get the actual property value displayed in the rule view
|
||||
let propertyValue = textProp.editor.valueSpan.textContent.toLowerCase();
|
||||
let propertyName = textProp.name.toLowerCase();
|
||||
let styleSheetSource = textProp.rule.title.toLowerCase();
|
||||
|
||||
let editor = textProp.editor;
|
||||
let source = editor.ruleEditor.source;
|
||||
|
||||
let isPropertyHighlighted = this._highlightMatches(editor.container, {
|
||||
searchName: name,
|
||||
|
@ -2137,7 +2139,14 @@ CssRuleView.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
if (isPropertyHighlighted || isComputedHighlighted) {
|
||||
// Highlight search matches in the stylesheet source
|
||||
let isStyleSheetHighlighted = styleSheetSource.includes(aValue);
|
||||
if (isStyleSheetHighlighted) {
|
||||
source.classList.add("ruleview-highlight");
|
||||
}
|
||||
|
||||
if (isPropertyHighlighted || isComputedHighlighted ||
|
||||
isStyleSheetHighlighted) {
|
||||
isHighlighted = true;
|
||||
}
|
||||
|
||||
|
@ -2262,11 +2271,11 @@ RuleEditor.prototype = {
|
|||
this.element.style.position = "relative";
|
||||
|
||||
// Add the source link.
|
||||
let source = createChild(this.element, "div", {
|
||||
this.source = createChild(this.element, "div", {
|
||||
class: "ruleview-rule-source theme-link"
|
||||
});
|
||||
source.addEventListener("click", function() {
|
||||
if (source.hasAttribute("unselectable")) {
|
||||
this.source.addEventListener("click", function() {
|
||||
if (this.source.hasAttribute("unselectable")) {
|
||||
return;
|
||||
}
|
||||
let rule = this.rule.domRule;
|
||||
|
@ -2275,7 +2284,7 @@ RuleEditor.prototype = {
|
|||
let sourceLabel = this.doc.createElementNS(XUL_NS, "label");
|
||||
sourceLabel.setAttribute("crop", "center");
|
||||
sourceLabel.classList.add("source-link-label");
|
||||
source.appendChild(sourceLabel);
|
||||
this.source.appendChild(sourceLabel);
|
||||
|
||||
this.updateSourceLink();
|
||||
|
||||
|
|
|
@ -133,6 +133,8 @@ skip-if = e10s # Bug 1090340
|
|||
[browser_ruleview_search-filter_09.js]
|
||||
[browser_ruleview_search-filter_10.js]
|
||||
[browser_ruleview_search-filter_11.js]
|
||||
[browser_ruleview_search-filter_12.js]
|
||||
[browser_ruleview_search-filter_13.js]
|
||||
[browser_ruleview_search-filter_clear.js]
|
||||
[browser_ruleview_search-filter_context-menu.js]
|
||||
[browser_ruleview_search-filter_escape-keypress.js]
|
||||
|
|
|
@ -49,9 +49,8 @@ function* testCancelNewOnEscape(inspector, ruleView) {
|
|||
let editor = yield focusEditableField(elementRuleEditor.closeBrace);
|
||||
|
||||
is(inplaceEditor(elementRuleEditor.newPropSpan), editor, "Next focused editor should be the new property editor.");
|
||||
for (let ch of "background") {
|
||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
||||
}
|
||||
|
||||
EventUtils.sendString("background", ruleView.doc.defaultView)
|
||||
|
||||
let onBlur = once(editor.input, "blur");
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
|
|
|
@ -64,9 +64,7 @@ function* runTestData(view, {value, commitKey, modifiers, expected}) {
|
|||
is(inplaceEditor(propEditor.valueSpan), editor, "Focused editor should be the value span.");
|
||||
|
||||
info("Entering test data " + value);
|
||||
for (let ch of value) {
|
||||
EventUtils.sendChar(ch, view.doc.defaultView);
|
||||
}
|
||||
EventUtils.sendString(value, view.doc.defaultView);
|
||||
|
||||
info("Waiting for focus on the field");
|
||||
let onBlur = once(editor.input, "blur");
|
||||
|
|
|
@ -60,9 +60,7 @@ function* testEditProperty(ruleEditor, name, value, isValid) {
|
|||
info("Entering a new property name, including : to commit and focus the value");
|
||||
let onValueFocus = once(ruleEditor.element, "focus", true);
|
||||
let onModifications = ruleEditor.rule._applyingModifications;
|
||||
for (let ch of name + ":") {
|
||||
EventUtils.sendChar(ch, doc.defaultView);
|
||||
}
|
||||
EventUtils.sendString(name + ":", doc.defaultView);
|
||||
yield onValueFocus;
|
||||
yield onModifications;
|
||||
|
||||
|
@ -74,9 +72,7 @@ function* testEditProperty(ruleEditor, name, value, isValid) {
|
|||
info("Entering a new value, including ; to commit and blur the value");
|
||||
let onBlur = once(input, "blur");
|
||||
onModifications = ruleEditor.rule._applyingModifications;
|
||||
for (let ch of value + ";") {
|
||||
EventUtils.sendChar(ch, doc.defaultView);
|
||||
}
|
||||
EventUtils.sendString(value + ";", doc.defaultView);
|
||||
yield onBlur;
|
||||
yield onModifications;
|
||||
|
||||
|
|
|
@ -46,9 +46,7 @@ function* testEditProperty(inspector, ruleView) {
|
|||
|
||||
info("Entering property name \"border-color\" followed by a colon to focus the value");
|
||||
let onFocus = once(idRuleEditor.element, "focus", true);
|
||||
for (let ch of "border-color:") {
|
||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
||||
}
|
||||
EventUtils.sendString("border-color:", ruleView.doc.defaultView);
|
||||
yield onFocus;
|
||||
yield idRuleEditor.rule._applyingModifications;
|
||||
|
||||
|
@ -60,6 +58,7 @@ function* testEditProperty(inspector, ruleView) {
|
|||
|
||||
info("Entering a value following by a semi-colon to commit it");
|
||||
let onBlur = once(editor.input, "blur");
|
||||
// Use sendChar() to pass each character as a string so that we can test propEditor.warning.hidden after each character.
|
||||
for (let ch of "red;") {
|
||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
||||
is(propEditor.warning.hidden, true,
|
||||
|
@ -77,9 +76,7 @@ function* testEditProperty(inspector, ruleView) {
|
|||
|
||||
info("Entering property name \"color\" followed by a colon to focus the value");
|
||||
onFocus = once(idRuleEditor.element, "focus", true);
|
||||
for (let ch of "color:") {
|
||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
||||
}
|
||||
EventUtils.sendString("color:", ruleView.doc.defaultView);
|
||||
yield onFocus;
|
||||
|
||||
info("Verifying that the focused field is the valueSpan");
|
||||
|
@ -87,9 +84,7 @@ function* testEditProperty(inspector, ruleView) {
|
|||
|
||||
info("Entering a value following by a semi-colon to commit it");
|
||||
onBlur = once(editor.input, "blur");
|
||||
for (let ch of "red;") {
|
||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
||||
}
|
||||
EventUtils.sendString("red;", ruleView.doc.defaultView);
|
||||
yield onBlur;
|
||||
yield idRuleEditor.rule._applyingModifications;
|
||||
|
||||
|
|
|
@ -47,9 +47,7 @@ function* testLivePreviewData(data, ruleView, selector) {
|
|||
is(inplaceEditor(propEditor.valueSpan), editor, "The focused editor is the value");
|
||||
|
||||
info("Enter a value in the editor")
|
||||
for (let ch of data.value) {
|
||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
||||
}
|
||||
EventUtils.sendString(data.value, ruleView.doc.defaultView);
|
||||
if (data.escape) {
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
} else {
|
||||
|
|
|
@ -31,9 +31,7 @@ function* testCreateNewMultiUnfinished(inspector, ruleEditor, view) {
|
|||
is(ruleEditor.rule.textProps.length, 4, "Should have created new text properties.");
|
||||
is(ruleEditor.propertyList.children.length, 4, "Should have created property editors.");
|
||||
|
||||
for (let ch of "red") {
|
||||
EventUtils.sendChar(ch, view.doc.defaultView);
|
||||
}
|
||||
EventUtils.sendString("red", view.doc.defaultView);
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
||||
|
||||
is(ruleEditor.rule.textProps.length, 4, "Should have the same number of text properties.");
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests that the rule view search filter works properly for stylesheet source.
|
||||
|
||||
const SEARCH = "doc_urls_clickable.css";
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_urls_clickable.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
yield selectNode(".relative1", inspector);
|
||||
yield testAddTextInFilter(inspector, view);
|
||||
});
|
||||
|
||||
function* testAddTextInFilter(inspector, ruleView) {
|
||||
info("Setting filter text to \"" + SEARCH + "\"");
|
||||
|
||||
let win = ruleView.doc.defaultView;
|
||||
let searchField = ruleView.searchField;
|
||||
let onRuleViewFiltered = inspector.once("ruleview-filtered");
|
||||
|
||||
searchField.focus();
|
||||
synthesizeKeys(SEARCH, win);
|
||||
yield onRuleViewFiltered;
|
||||
|
||||
info("Check that the correct rules are visible");
|
||||
is(ruleView.element.children.length, 2, "Should have 2 rules.");
|
||||
is(getRuleViewRuleEditor(ruleView, 0).rule.selectorText, "element",
|
||||
"First rule is inline element.");
|
||||
|
||||
let rule = getRuleViewRuleEditor(ruleView, 1).rule;
|
||||
let source = rule.textProps[0].editor.ruleEditor.source;
|
||||
|
||||
is(rule.selectorText, ".relative1", "Second rule is .relative1.");
|
||||
ok(source.classList.contains("ruleview-highlight"),
|
||||
"stylesheet source is correctly highlighted.");
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests that the rule view search filter does not highlight the source with
|
||||
// input that could be parsed as a property line.
|
||||
|
||||
const SEARCH = "doc_urls_clickable.css: url";
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_urls_clickable.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
yield selectNode(".relative1", inspector);
|
||||
yield testAddTextInFilter(inspector, view);
|
||||
});
|
||||
|
||||
function* testAddTextInFilter(inspector, ruleView) {
|
||||
info("Setting filter text to \"" + SEARCH + "\"");
|
||||
|
||||
let win = ruleView.doc.defaultView;
|
||||
let searchField = ruleView.searchField;
|
||||
let onRuleViewFiltered = inspector.once("ruleview-filtered");
|
||||
|
||||
searchField.focus();
|
||||
synthesizeKeys(SEARCH, win);
|
||||
yield onRuleViewFiltered;
|
||||
|
||||
info("Check that the correct rules are visible");
|
||||
is(ruleView.element.children.length, 1, "Should have 1 rules.");
|
||||
is(getRuleViewRuleEditor(ruleView, 0).rule.selectorText, "element",
|
||||
"First rule is inline element.");
|
||||
}
|
|
@ -58,10 +58,7 @@ function* testManualEdit(inspector, view) {
|
|||
info("Typing new value");
|
||||
let input = editor.input;
|
||||
let onBlur = once(input, "blur");
|
||||
for (let ch of newColor + ";"){
|
||||
EventUtils.sendChar(ch, view.doc.defaultView);
|
||||
}
|
||||
|
||||
EventUtils.sendString(newColor + ";", view.doc.defaultView);
|
||||
yield onBlur;
|
||||
yield wait(1);
|
||||
|
||||
|
|
|
@ -129,12 +129,14 @@ function doOK() {
|
|||
|
||||
// Create subfolder with fs-friendly name of project
|
||||
let subfolder = projectName.replace(/[\\/:*?"<>|]/g, '').toLowerCase();
|
||||
let win = Services.wm.getMostRecentWindow("devtools:webide");
|
||||
folder.append(subfolder);
|
||||
|
||||
try {
|
||||
folder.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
win.UI.reportError("error_folderCreationFailed");
|
||||
window.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,24 +77,25 @@ addonsInstalledNeedsRestart=#1 will be installed after you restart #3.;#2 add-on
|
|||
addonInstallRestartButton=Restart Now
|
||||
addonInstallRestartButton.accesskey=R
|
||||
|
||||
# LOCALIZATION NOTE (addonError-1, addonError-2, addonError-3, addonError-4, addonError-5):
|
||||
# #1 is the add-on name, #2 is the host name, #3 is the application name
|
||||
# #4 is the application version
|
||||
addonError-1=The add-on could not be downloaded because of a connection failure on #2.
|
||||
addonError-2=The add-on from #2 could not be installed because it does not match the add-on #3 expected.
|
||||
addonError-3=The add-on downloaded from #2 could not be installed because it appears to be corrupt.
|
||||
addonError-4=#1 could not be installed because #3 cannot modify the needed file.
|
||||
addonError-5=#3 has prevented this site from installing an unverified add-on.
|
||||
# LOCALIZATION NOTE (addonInstallError-1, addonInstallError-2, addonInstallError-3, addonInstallError-4, addonInstallError-5, addonLocalInstallError-1, addonLocalInstallError-2, addonLocalInstallError-3, addonLocalInstallError-4, addonLocalInstallError-5):
|
||||
# %1$S is the application name, %2$S is the add-on name
|
||||
addonInstallError-1=The add-on could not be downloaded because of a connection failure.
|
||||
addonInstallError-2=The add-on could not be installed because it does not match the add-on %1$S expected.
|
||||
addonInstallError-3=The add-on downloaded from this site could not be installed because it appears to be corrupt.
|
||||
addonInstallError-4=%2$S could not be installed because %1$S cannot modify the needed file.
|
||||
addonInstallError-5=%1$S has prevented this site from installing an unverified add-on.
|
||||
addonLocalInstallError-1=This add-on could not be installed because of a filesystem error.
|
||||
addonLocalInstallError-2=This add-on could not be installed because it does not match the add-on %1$S expected.
|
||||
addonLocalInstallError-3=This add-on could not be installed because it appears to be corrupt.
|
||||
addonLocalInstallError-4=%2$S could not be installed because %1$S cannot modify the needed file.
|
||||
addonLocalInstallError-5=This add-on could not be installed because it has not been verified.
|
||||
|
||||
# LOCALIZATION NOTE (addonLocalError-1, addonLocalError-2, addonLocalError-3, addonLocalError-4, addonLocalError-5, addonErrorIncompatible, addonErrorBlocklisted):
|
||||
# #1 is the add-on name, #3 is the application name, #4 is the application version
|
||||
addonLocalError-1=This add-on could not be installed because of a filesystem error.
|
||||
addonLocalError-2=This add-on could not be installed because it does not match the add-on #3 expected.
|
||||
addonLocalError-3=This add-on could not be installed because it appears to be corrupt.
|
||||
addonLocalError-4=#1 could not be installed because #3 cannot modify the needed file.
|
||||
addonLocalError-5=This add-on could not be installed because it has not been verified.
|
||||
addonErrorIncompatible=#1 could not be installed because it is not compatible with #3 #4.
|
||||
addonErrorBlocklisted=#1 could not be installed because it has a high risk of causing stability or security problems.
|
||||
# LOCALIZATION NOTE (addonInstallErrorIncompatible):
|
||||
# %1$S is the application name, %2$S is the application version, %3$S is the add-on name
|
||||
addonInstallErrorIncompatible=%3$S could not be installed because it is not compatible with %1$S %2$S.
|
||||
|
||||
# LOCALIZATION NOTE (addonInstallErrorBlocklisted): %S is add-on name
|
||||
addonInstallErrorBlocklisted=%S could not be installed because it has a high risk of causing stability or security problems.
|
||||
|
||||
unsignedAddonsDisabled.message=One or more installed add-ons cannot be verified and have been disabled.
|
||||
unsignedAddonsDisabled.learnMore.label=Learn More
|
||||
|
|
|
@ -46,6 +46,7 @@ error_cantConnectToApp=Can't connect to app: %1$S
|
|||
error_cantFetchAddonsJSON=Can't fetch the add-on list: %S
|
||||
|
||||
error_appProjectsLoadFailed=Unable to load project list. This can occur if you've used this profile with a newer version of Firefox.
|
||||
error_folderCreationFailed=Unable to create project folder in the selected directory.
|
||||
|
||||
addons_stable=stable
|
||||
addons_unstable=unstable
|
||||
|
|
|
@ -16,15 +16,15 @@
|
|||
}
|
||||
|
||||
.ruleview-rule-source {
|
||||
-moz-padding-start: 5px;
|
||||
text-align: end;
|
||||
float: right;
|
||||
-moz-user-select: none;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.ruleview-rule-source,
|
||||
.ruleview-rule-source > label {
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ruleview-rule-source[unselectable],
|
||||
|
@ -268,4 +268,4 @@
|
|||
#ruleview-add-rule-button::before {
|
||||
background-image: url("chrome://browser/skin/devtools/add.svg");
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -880,13 +880,22 @@
|
|||
|
||||
.line-graph-widget-gutter {
|
||||
position: absolute;
|
||||
background: rgba(255,255,255,0.75);
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-right: 1px solid rgba(255,255,255,0.25);
|
||||
pointer-events: none;
|
||||
-moz-border-end: 1px solid;
|
||||
}
|
||||
|
||||
.theme-light .line-graph-widget-gutter {
|
||||
background: rgba(255,255,255,0.75);
|
||||
-moz-border-end-color: rgba(255,255,255,0.25);
|
||||
}
|
||||
|
||||
.theme-dark .line-graph-widget-gutter {
|
||||
background: rgba(0,0,0,0.5);
|
||||
-moz-border-end-color: rgba(0,0,0,0.25);
|
||||
}
|
||||
|
||||
.line-graph-widget-gutter-line {
|
||||
|
@ -909,7 +918,6 @@
|
|||
|
||||
.line-graph-widget-tooltip {
|
||||
position: absolute;
|
||||
background: rgba(255,255,255,0.9);
|
||||
border-radius: 2px;
|
||||
line-height: 15px;
|
||||
-moz-padding-start: 6px;
|
||||
|
@ -920,6 +928,14 @@
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
.theme-light .line-graph-widget-tooltip {
|
||||
background: rgba(255,255,255,0.75);
|
||||
}
|
||||
|
||||
.theme-dark .line-graph-widget-tooltip {
|
||||
background: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.line-graph-widget-tooltip[with-arrows=true]::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
|
@ -929,15 +945,31 @@
|
|||
}
|
||||
|
||||
.line-graph-widget-tooltip[arrow=start][with-arrows=true]::before {
|
||||
-moz-border-end: 3px solid rgba(255,255,255,0.75);
|
||||
-moz-border-end: 3px solid;
|
||||
left: -3px;
|
||||
}
|
||||
|
||||
.line-graph-widget-tooltip[arrow=end][with-arrows=true]::before {
|
||||
-moz-border-start: 3px solid rgba(255,255,255,0.75);
|
||||
-moz-border-start: 3px solid;
|
||||
right: -3px;
|
||||
}
|
||||
|
||||
.theme-light .line-graph-widget-tooltip[arrow=start][with-arrows=true]::before {
|
||||
-moz-border-end-color: rgba(255,255,255,0.75);
|
||||
}
|
||||
|
||||
.theme-dark .line-graph-widget-tooltip[arrow=start][with-arrows=true]::before {
|
||||
-moz-border-end-color: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.theme-light .line-graph-widget-tooltip[arrow=end][with-arrows=true]::before {
|
||||
-moz-border-start-color: rgba(255,255,255,0.75);
|
||||
}
|
||||
|
||||
.theme-dark .line-graph-widget-tooltip[arrow=end][with-arrows=true]::before {
|
||||
-moz-border-start-color: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.line-graph-widget-tooltip[type=maximum] {
|
||||
left: 14px;
|
||||
}
|
||||
|
@ -951,7 +983,7 @@
|
|||
}
|
||||
|
||||
.line-graph-widget-tooltip > [text=info] {
|
||||
color: #18191a;
|
||||
color: var(--theme-content-color1);
|
||||
}
|
||||
|
||||
.line-graph-widget-tooltip > [text=value] {
|
||||
|
@ -960,27 +992,35 @@
|
|||
|
||||
.line-graph-widget-tooltip > [text=metric] {
|
||||
-moz-margin-start: 1px;
|
||||
color: #667380;
|
||||
color: var(--theme-content-color3);
|
||||
}
|
||||
|
||||
.line-graph-widget-tooltip > [text=value],
|
||||
.line-graph-widget-tooltip > [text=metric] {
|
||||
text-shadow: 1px 0px rgba(255,255,255,0.6),
|
||||
-1px 0px rgba(255,255,255,0.6),
|
||||
0px -1px rgba(255,255,255,0.6),
|
||||
0px 1px rgba(255,255,255,0.6);
|
||||
.theme-light .line-graph-widget-tooltip > [text=value],
|
||||
.theme-light .line-graph-widget-tooltip > [text=metric] {
|
||||
text-shadow: 1px 0px rgba(255,255,255,0.5),
|
||||
-1px 0px rgba(255,255,255,0.5),
|
||||
0px -1px rgba(255,255,255,0.5),
|
||||
0px 1px rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
.theme-dark .line-graph-widget-tooltip > [text=value],
|
||||
.theme-dark .line-graph-widget-tooltip > [text=metric] {
|
||||
text-shadow: 1px 0px rgba(0,0,0,0.5),
|
||||
-1px 0px rgba(0,0,0,0.5),
|
||||
0px -1px rgba(0,0,0,0.5),
|
||||
0px 1px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.line-graph-widget-tooltip[type=maximum] > [text=value] {
|
||||
color: #2cbb0f;
|
||||
color: var(--theme-highlight-green);
|
||||
}
|
||||
|
||||
.line-graph-widget-tooltip[type=minimum] > [text=value] {
|
||||
color: #ed2655;
|
||||
color: var(--theme-highlight-red);
|
||||
}
|
||||
|
||||
.line-graph-widget-tooltip[type=average] > [text=value] {
|
||||
color: #d97e00;
|
||||
color: var(--theme-highlight-orange);
|
||||
}
|
||||
|
||||
/* Bar graph widget */
|
||||
|
|
|
@ -68,10 +68,18 @@ Activity::Initialize(nsPIDOMWindow* aWindow,
|
|||
mProxy = do_CreateInstance("@mozilla.org/dom/activities/proxy;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We're about the pass the dictionary to a JS-implemented component, so
|
||||
// rehydrate it in a system scode so that security wrappers don't get in the
|
||||
// way. See bug 1161748 comment 16.
|
||||
bool ok;
|
||||
JS::Rooted<JS::Value> optionsValue(aCx);
|
||||
if (!ToJSValue(aCx, aOptions, &optionsValue)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
{
|
||||
JSAutoCompartment ac(aCx, xpc::PrivilegedJunkScope());
|
||||
ok = ToJSValue(aCx, aOptions, &optionsValue);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
}
|
||||
ok = JS_WrapValue(aCx, &optionsValue);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
||||
|
||||
mProxy->StartActivity(static_cast<nsIDOMDOMRequest*>(this), optionsValue, aWindow);
|
||||
return NS_OK;
|
||||
|
|
|
@ -203,16 +203,23 @@ TelephonyListener::HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend)
|
|||
uint32_t callIndex;
|
||||
uint16_t callState;
|
||||
nsAutoString number;
|
||||
nsAutoString disconnectedReason;
|
||||
bool isOutgoing;
|
||||
bool isConference;
|
||||
|
||||
aInfo->GetCallIndex(&callIndex);
|
||||
aInfo->GetCallState(&callState);
|
||||
aInfo->GetNumber(number);
|
||||
aInfo->GetDisconnectedReason(disconnectedReason);
|
||||
aInfo->GetIsOutgoing(&isOutgoing);
|
||||
aInfo->GetIsConference(&isConference);
|
||||
|
||||
hfp->HandleCallStateChanged(callIndex, callState, EmptyString(), number,
|
||||
// The disconnectedReason of a disconnected call must be nonempty no matter
|
||||
// the call is disconnected for a normal reason or an error.
|
||||
MOZ_ASSERT((callState != nsITelephonyService::CALL_STATE_DISCONNECTED ||
|
||||
!disconnectedReason.IsEmpty()),
|
||||
"disconnectedReason of an disconnected call must be nonempty.");
|
||||
hfp->HandleCallStateChanged(callIndex, callState, disconnectedReason, number,
|
||||
isOutgoing, isConference, aSend);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -233,30 +240,6 @@ TelephonyListener::EnumerateCallState(nsITelephonyCallInfo* aInfo)
|
|||
return HandleCallInfo(aInfo, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyListener::NotifyError(uint32_t aServiceId,
|
||||
int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
|
||||
NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
|
||||
|
||||
if (aCallIndex > 0) {
|
||||
// In order to not miss any related call state transition.
|
||||
// It's possible that 3G network signal lost for unknown reason.
|
||||
// If a call is released abnormally, NotifyError() will be called,
|
||||
// instead of CallStateChanged(). We need to reset the call array state
|
||||
// via setting CALL_STATE_DISCONNECTED
|
||||
hfp->HandleCallStateChanged(aCallIndex,
|
||||
nsITelephonyService::CALL_STATE_DISCONNECTED,
|
||||
aError, EmptyString(), false, false, true);
|
||||
BT_WARNING("Reset the call state due to call transition ends abnormally");
|
||||
}
|
||||
|
||||
BT_WARNING(NS_ConvertUTF16toUTF8(aError).get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState)
|
||||
{
|
||||
|
|
|
@ -194,21 +194,64 @@ let SNEP = (function() {
|
|||
function toggleNFC(enabled) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let promise;
|
||||
if (enabled) {
|
||||
promise = nfc.startPoll();
|
||||
} else {
|
||||
promise = nfc.powerOff();
|
||||
}
|
||||
// In bug 1109592, nfcd will only run when nfc is enabled.
|
||||
// The way we activate/deactivate nfcd is by using set property "ctl.start" & "ctl.stop".
|
||||
// In emulator it seems sometimes enable/disable NFC too quick will cause nfcd won't starat,
|
||||
// So here we use a simple workaround to delay enable or disable for 100ms, bug 1164786 is
|
||||
// created to track this issue.
|
||||
setTimeout(function() {
|
||||
let promise;
|
||||
if (enabled) {
|
||||
promise = nfc.startPoll();
|
||||
} else {
|
||||
promise = nfc.powerOff();
|
||||
}
|
||||
|
||||
promise.then(() => {
|
||||
promise.then(() => {
|
||||
deferred.resolve();
|
||||
}).catch(() => {
|
||||
ok(false, 'operation failed, error ' + req.error.name);
|
||||
deferred.reject();
|
||||
finish();
|
||||
});
|
||||
}, 100);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function activateAndwaitForTechDiscovered(re) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
sysMsgHelper.waitForTechDiscovered(function() {
|
||||
deferred.resolve();
|
||||
}).catch(() => {
|
||||
ok(false, 'operation failed, error ' + req.error.name);
|
||||
deferred.reject();
|
||||
finish();
|
||||
});
|
||||
|
||||
NCI.activateRE(re);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function deactivateAndWaitForTechLost() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
sysMsgHelper.waitForTechLost(function() {
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
NCI.deactivate();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function deactivateAndWaitForPeerLost() {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
nfc.onpeerlost = function() {
|
||||
deferred.resolve();
|
||||
};
|
||||
|
||||
NCI.deactivate();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* globals log, is, ok, runTests, toggleNFC, runNextTest,
|
||||
SpecialPowers, nfc */
|
||||
|
||||
const MARIONETTE_TIMEOUT = 30000;
|
||||
const MARIONETTE_TIMEOUT = 60000;
|
||||
const MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
const MANIFEST_URL = 'app://system.gaiamobile.org/manifest.webapp';
|
||||
|
@ -18,7 +18,7 @@ const FAKE_MANIFEST_URL = 'app://fake.gaiamobile.org/manifest.webapp';
|
|||
*/
|
||||
function testNoTargetNoSessionToken() {
|
||||
log('testNoTargetNoSessionToken');
|
||||
fireCheckP2PReg(MANIFEST_URL)
|
||||
nfc.checkP2PRegistration(MANIFEST_URL)
|
||||
.then((result) => {
|
||||
is(result, false, 'No target, no sesionToken, result should be false');
|
||||
runNextTest();
|
||||
|
@ -33,7 +33,7 @@ function testNoTargetNoSessionToken() {
|
|||
function testWithTargetNoSessionToken() {
|
||||
log('testWithTargetNoSessionToken');
|
||||
registerOnpeerready()
|
||||
.then(() => fireCheckP2PReg(MANIFEST_URL))
|
||||
.then(() => nfc.checkP2PRegistration(MANIFEST_URL))
|
||||
.then((result) => {
|
||||
is(result, false,
|
||||
'session token is available and it shouldnt be');
|
||||
|
@ -50,13 +50,13 @@ function testWithTargetNoSessionToken() {
|
|||
function testWithSessionTokenWithTarget() {
|
||||
log('testWithSessionTokenWithTarget');
|
||||
toggleNFC(true)
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerOnpeerready)
|
||||
.then(() => fireCheckP2PReg(MANIFEST_URL))
|
||||
.then(() => nfc.checkP2PRegistration(MANIFEST_URL))
|
||||
.then((result) => {
|
||||
is(result, true, 'should be true, onpeerready reg, sessionToken set');
|
||||
nfc.onpeerready = null;
|
||||
return toggleNFC(false);
|
||||
return deactivateAndWaitForTechLost().then(() => toggleNFC(false));
|
||||
})
|
||||
.then(runNextTest)
|
||||
.catch(handleRejectedPromiseWithNfcOn);
|
||||
|
@ -69,12 +69,12 @@ function testWithSessionTokenWithTarget() {
|
|||
function testWithSessionTokenNoTarget() {
|
||||
log('testWithSessionTokenNoTarget');
|
||||
toggleNFC(true)
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(() => fireCheckP2PReg(MANIFEST_URL))
|
||||
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
|
||||
.then(() => nfc.checkP2PRegistration(MANIFEST_URL))
|
||||
.then((result) => {
|
||||
is(result, false,
|
||||
'session token avilable but onpeerready not registered');
|
||||
return toggleNFC(false);
|
||||
return deactivateAndWaitForTechLost().then(() => toggleNFC(false));
|
||||
})
|
||||
.then(runNextTest)
|
||||
.catch(handleRejectedPromiseWithNfcOn);
|
||||
|
@ -87,13 +87,13 @@ function testWithSessionTokenNoTarget() {
|
|||
function testWithSessionTokenWrongTarget() {
|
||||
log('testWithSessionTokenWrongTarget');
|
||||
toggleNFC(true)
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerOnpeerready)
|
||||
.then(() => fireCheckP2PReg(FAKE_MANIFEST_URL))
|
||||
.then(() => nfc.checkP2PRegistration(FAKE_MANIFEST_URL))
|
||||
.then((result) => {
|
||||
is(result, false, 'should be false, fake manifest, sessionToken set');
|
||||
nfc.onpeerready = null;
|
||||
return toggleNFC(false);
|
||||
return deactivateAndWaitForTechLost().then(() => toggleNFC(false));
|
||||
})
|
||||
.then(runNextTest)
|
||||
.catch(handleRejectedPromiseWithNfcOn);
|
||||
|
@ -108,21 +108,6 @@ function registerOnpeerready() {
|
|||
return d.promise;
|
||||
}
|
||||
|
||||
function fireCheckP2PReg(manifestUrl) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let promise = nfc.checkP2PRegistration(manifestUrl);
|
||||
promise.then(() => {
|
||||
ok(true, 'checkP2PRegistration allways results in success');
|
||||
deferred.resolve(request.result);
|
||||
}).catch(() => {
|
||||
ok(false, 'see NfcContentHelper.handleCheckP2PRegistrationResponse');
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function handleRejectedPromise() {
|
||||
ok(false, 'Promise rejected. This should not happen');
|
||||
nfc.onpeerready = null;
|
||||
|
|
|
@ -25,8 +25,9 @@ let nfcPeers = [];
|
|||
function testNfcNotEnabledError() {
|
||||
log('testNfcNotEnabledError');
|
||||
toggleNFC(true)
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerAndFireOnpeerready)
|
||||
.then(() => deactivateAndWaitForPeerLost())
|
||||
.then(() => toggleNFC(false))
|
||||
.then(() => sendNDEFExpectError(nfcPeers[0]))
|
||||
.then(endTest)
|
||||
|
@ -43,13 +44,14 @@ function testNfcNotEnabledError() {
|
|||
function testNfcBadSessionIdError() {
|
||||
log('testNfcBadSessionIdError');
|
||||
toggleNFC(true)
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerAndFireOnpeerready)
|
||||
.then(() => NCI.deactivate())
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerAndFireOnpeerready)
|
||||
// we have 2 peers in nfcPeers array, peer0 has old/invalid session token
|
||||
.then(() => sendNDEFExpectError(nfcPeers[0]))
|
||||
.then(() => deactivateAndWaitForPeerLost())
|
||||
.then(() => toggleNFC(false))
|
||||
.then(endTest)
|
||||
.catch(handleRejectedPromise);
|
||||
|
@ -65,7 +67,7 @@ function testNoErrorInTechMsg() {
|
|||
|
||||
let techDiscoveredHandler = function(msg) {
|
||||
ok('Message handler for nfc-manager-tech-discovered');
|
||||
is(msg.type, 'techDiscovered');
|
||||
ok(msg.peer, 'check for correct tech type');
|
||||
is(msg.errorMsg, undefined, 'Should not get error msg in tech discovered');
|
||||
|
||||
setAndFireTechLostHandler()
|
||||
|
@ -108,13 +110,13 @@ function registerAndFireOnpeerready() {
|
|||
function sendNDEFExpectError(peer) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
try {
|
||||
peer.sendNDEF(NDEF_MESSAGE);
|
||||
peer.sendNDEF(NDEF_MESSAGE)
|
||||
.then(() => {
|
||||
deferred.reject();
|
||||
} catch (e) {
|
||||
}).catch((e) => {
|
||||
ok(true, 'this should happen ' + e);
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
@ -124,7 +126,6 @@ function setAndFireTechLostHandler() {
|
|||
|
||||
let techLostHandler = function(msg) {
|
||||
ok('Message handler for nfc-manager-tech-lost');
|
||||
is(msg.type, 'techLost');
|
||||
is(msg.errorMsg, undefined, 'Should not get error msg in tech lost');
|
||||
|
||||
deferred.resolve();
|
||||
|
@ -139,7 +140,8 @@ function setAndFireTechLostHandler() {
|
|||
|
||||
let tests = [
|
||||
testNfcNotEnabledError,
|
||||
testNfcBadSessionIdError,
|
||||
// This testcase is temporarily removed due to Bug 1055959, will reopen when it is fixed
|
||||
// testNfcBadSessionIdError
|
||||
testNoErrorInTechMsg
|
||||
];
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 30000;
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
function handleTechnologyDiscoveredRE0(msg) {
|
||||
log('Received \'nfc-manager-tech-discovered\'');
|
||||
is(msg.type, 'techDiscovered', 'check for correct message type');
|
||||
is(msg.isP2P, 'P2P', 'check for correct tech type');
|
||||
toggleNFC(false).then(runNextTest);
|
||||
ok(msg.peer, 'check for correct tech type');
|
||||
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
|
||||
}
|
||||
|
||||
function testActivateRE0() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 30000;
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
let tnf = NDEF.TNF_WELL_KNOWN;
|
||||
|
@ -18,13 +18,12 @@ function handleSnep(msg) {
|
|||
type: NfcUtils.fromUTF8(type),
|
||||
payload: NfcUtils.fromUTF8(payload)})];
|
||||
NDEF.compare(ndef, msg.records);
|
||||
toggleNFC(false).then(runNextTest);
|
||||
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
|
||||
}
|
||||
|
||||
function handleTechnologyDiscoveredRE0(msg) {
|
||||
log("Received 'nfc-manager-tech-discovered'");
|
||||
is(msg.type, "techDiscovered", "check for correct message type");
|
||||
is(msg.isP2P, "P2P", "check for correct tech type");
|
||||
ok(msg.peer, "check for correct tech type");
|
||||
|
||||
sysMsgHelper.waitForTechDiscovered(handleSnep);
|
||||
SNEP.put(SNEP.SAP_NDEF, SNEP.SAP_NDEF, 0, tnf, btoa(type), btoa(id), btoa(payload));
|
||||
|
|
|
@ -6,15 +6,14 @@ MARIONETTE_HEAD_JS = 'head.js';
|
|||
|
||||
function handleTechnologyLost(msg) {
|
||||
log('Received \'nfc-manager-tech-lost\'');
|
||||
is(msg.type, 'techLost', 'check for correct message type');
|
||||
ok(true);
|
||||
|
||||
toggleNFC(false).then(runNextTest)
|
||||
}
|
||||
|
||||
function handleTechnologyDiscoveredRE0(msg) {
|
||||
log('Received \'nfc-manager-tech-discovered\'');
|
||||
is(msg.type, 'techDiscovered', 'check for correct message type');
|
||||
is(msg.isP2P, 'P2P', 'check for correct tech type');
|
||||
ok(msg.peer, 'check for correct tech type');
|
||||
|
||||
NCI.deactivate();
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@ function peerLostCb(evt) {
|
|||
|
||||
function handleTechnologyDiscoveredRE0(msg) {
|
||||
log("Received \'nfc-manager-tech-discovered\'");
|
||||
is(msg.type, "techDiscovered", "check for correct message type");
|
||||
is(msg.isP2P, "P2P", "check for correct tech type");
|
||||
ok(msg.peer, "check for correct tech type");
|
||||
|
||||
nfc.onpeerready = peerReadyCb;
|
||||
nfc.onpeerlost = peerLostCb;
|
||||
|
@ -39,19 +38,13 @@ function handleTechnologyDiscoveredRE0(msg) {
|
|||
|
||||
function handleTechnologyDiscoveredRE0ForP2PRegFailure(msg) {
|
||||
log("Received \'nfc-manager-tech-discovered\'");
|
||||
is(msg.type, "techDiscovered", "check for correct message type");
|
||||
is(msg.isP2P, "P2P", "check for correct tech type");
|
||||
ok(msg.peer, "check for correct tech type");
|
||||
|
||||
nfc.onpeerready = peerReadyCb;
|
||||
|
||||
let promise = nfc.checkP2PRegistration(INCORRECT_MANIFEST_URL);
|
||||
promise.then(evt => {
|
||||
is(request.result, false, "check for P2P registration result");
|
||||
|
||||
nfc.onpeerready = null;
|
||||
NCI.deactivate().then(() => toggleNFC(false)).then(runNextTest);
|
||||
}).catch(() => {
|
||||
ok(false, "checkP2PRegistration failed.");
|
||||
nfc.checkP2PRegistration(INCORRECT_MANIFEST_URL)
|
||||
.then((result) => {
|
||||
is(result, false, "check for P2P registration result");
|
||||
|
||||
nfc.onpeerready = null;
|
||||
NCI.deactivate().then(() => toggleNFC(false)).then(runNextTest);
|
||||
|
@ -150,19 +143,19 @@ function testPeerShouldThrow() {
|
|||
|
||||
nfc.onpeerlost = function () {
|
||||
log("testPeerShouldThrow peerlost");
|
||||
try {
|
||||
peer.sendNDEF(ndef);
|
||||
peer.sendNDEF(ndef)
|
||||
.then(() => {
|
||||
ok(false, "sendNDEF should throw error");
|
||||
} catch (e) {
|
||||
}).catch((e) => {
|
||||
ok(true, "Exception expected " + e);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
peer.sendFile(new Blob());
|
||||
peer.sendFile(new Blob())
|
||||
.then(() => {
|
||||
ok(false, "sendfile should throw error");
|
||||
} catch (e) {
|
||||
}).catch((e) => {
|
||||
ok(true, "Exception expected" + e);
|
||||
}
|
||||
});
|
||||
|
||||
nfc.onpeerready = null;
|
||||
nfc.onpeerlost = null;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 30000;
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = "head.js";
|
||||
|
||||
let MANIFEST_URL = "app://system.gaiamobile.org/manifest.webapp";
|
||||
|
@ -23,16 +23,14 @@ function testSendFile() {
|
|||
};
|
||||
|
||||
sysMsgHelper.waitForTechDiscovered(function(msg) {
|
||||
let request = nfc.checkP2PRegistration(MANIFEST_URL);
|
||||
request.onsuccess = function(evt) {
|
||||
is(request.result, true, "check for P2P registration result");
|
||||
nfc.notifyUserAcceptedP2P(MANIFEST_URL);
|
||||
}
|
||||
|
||||
request.onerror = function() {
|
||||
ok(false, "checkP2PRegistration failed.");
|
||||
toggleNFC(false).then(runNextTest);
|
||||
}
|
||||
nfc.checkP2PRegistration(MANIFEST_URL).then(result => {
|
||||
if (result) {
|
||||
nfc.notifyUserAcceptedP2P(MANIFEST_URL);
|
||||
} else {
|
||||
ok(false, "checkP2PRegistration failed.");
|
||||
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
toggleNFC(true).then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
|
||||
|
@ -43,6 +41,5 @@ let tests = [
|
|||
];
|
||||
|
||||
SpecialPowers.pushPermissions(
|
||||
[{"type": "nfc", "allow": true,
|
||||
"read": true, 'write': true, context: document},
|
||||
[{"type": "nfc-share", "allow": true, context: document},
|
||||
{"type": "nfc-manager", 'allow': true, context: document}], runTests);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 30000;
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = "head.js";
|
||||
|
||||
let url = "https://www.example.com";
|
||||
|
@ -21,18 +21,17 @@ function sendNDEF(peer) {
|
|||
emulator.run(cmd, function(result) {
|
||||
is(result.pop(), "OK", "check SNEP PUT result");
|
||||
NDEF.compare(ndef, NDEF.parseString(result.pop()));
|
||||
toggleNFC(false).then(runNextTest);
|
||||
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
|
||||
});
|
||||
}).catch(() => {
|
||||
ok(false, "Failed to send NDEF message, error \'" + this.error + "\'");
|
||||
toggleNFC(false).then(runNextTest);
|
||||
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
|
||||
});
|
||||
}
|
||||
|
||||
function handleTechnologyDiscoveredRE0(msg) {
|
||||
log("Received \'nfc-manager-tech-discovered\' " + JSON.stringify(msg));
|
||||
is(msg.type, "techDiscovered", "check for correct message type");
|
||||
is(msg.isP2P, "check for \'P2P\' in tech list");
|
||||
ok(msg.peer, "techDiscovered", "check for correct message type");
|
||||
sendNDEF(msg.peer);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 30000;
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = "head.js";
|
||||
|
||||
let url = "http://www.mozilla.org";
|
||||
|
@ -16,16 +16,16 @@ function testUrlTagDiscover(re) {
|
|||
|
||||
sysMsgHelper.waitForTechDiscovered(function(msg) {
|
||||
log("Received \'nfc-manager-tech-ndiscovered\'");
|
||||
is(msg.type, "techDiscovered", "check for correct message type");
|
||||
ok(msg.peer === undefined, "peer object should be undefined");
|
||||
|
||||
let records = Cu.waiveXrays(msg.records);
|
||||
let records = msg.records;
|
||||
ok(records.length > 0);
|
||||
|
||||
is(tnf, records[0].tnf, "check for TNF field in NDEF");
|
||||
is(type, NfcUtils.toUTF8(records[0].type), "check for type field in NDEF");
|
||||
is(payload, NfcUtils.toUTF8(records[0].payload), "check for payload field in NDEF");
|
||||
is(type, NfcUtils.toUTF8(Cu.waiveXrays(records[0].type)), "check for type field in NDEF");
|
||||
is(payload, NfcUtils.toUTF8(Cu.waiveXrays(records[0].payload)), "check for payload field in NDEF");
|
||||
|
||||
toggleNFC(false).then(runNextTest);
|
||||
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
|
||||
});
|
||||
|
||||
toggleNFC(true)
|
||||
|
@ -38,12 +38,12 @@ function testEmptyTagDiscover(re) {
|
|||
|
||||
sysMsgHelper.waitForTechDiscovered(function(msg) {
|
||||
log("Received \'nfc-manager-tech-ndiscovered\'");
|
||||
is(msg.type, "techDiscovered", "check for correct message type");
|
||||
ok(msg.peer === undefined, "peer object should be undefined");
|
||||
|
||||
let records = msg.records;
|
||||
ok(records == null);
|
||||
|
||||
toggleNFC(false).then(runNextTest);
|
||||
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
|
||||
});
|
||||
|
||||
toggleNFC(true)
|
||||
|
|
|
@ -12,10 +12,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=678695
|
|||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=678695">Mozilla Bug 678695</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
SpecialPowers.addPermission("settings-api-read", true, document);
|
||||
SpecialPowers.addPermission("settings-api-write", true, document);
|
||||
SpecialPowers.addPermission("settings-read", true, document);
|
||||
SpecialPowers.addPermission("settings-write", true, document);
|
||||
|
||||
/** Test for Bug 678695 **/
|
||||
|
||||
|
|
|
@ -649,6 +649,17 @@ NetworkService.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
stopDhcp: function(interfaceName, callback) {
|
||||
let params = {
|
||||
cmd: "stopDhcp",
|
||||
ifname: interfaceName
|
||||
};
|
||||
|
||||
this.controlMessage(params, function(result) {
|
||||
callback.nativeCommandResult(!result.error);
|
||||
});
|
||||
},
|
||||
|
||||
enableInterface: function(interfaceName, callback) {
|
||||
let params = {
|
||||
cmd: "enableInterface",
|
||||
|
|
|
@ -1615,6 +1615,7 @@ void NetworkUtils::ExecuteCommand(NetworkParams aOptions)
|
|||
BUILD_ENTRY(updateUpStream),
|
||||
BUILD_ENTRY(configureInterface),
|
||||
BUILD_ENTRY(dhcpRequest),
|
||||
BUILD_ENTRY(stopDhcp),
|
||||
BUILD_ENTRY(enableInterface),
|
||||
BUILD_ENTRY(disableInterface),
|
||||
BUILD_ENTRY(resetConnections),
|
||||
|
@ -1833,6 +1834,11 @@ CommandResult NetworkUtils::configureInterface(NetworkParams& aOptions)
|
|||
);
|
||||
}
|
||||
|
||||
CommandResult NetworkUtils::stopDhcp(NetworkParams& aOptions)
|
||||
{
|
||||
return mNetUtils->do_dhcp_stop(GET_CHAR(mIfname));
|
||||
}
|
||||
|
||||
CommandResult NetworkUtils::dhcpRequest(NetworkParams& aOptions) {
|
||||
mozilla::dom::NetworkResultOptions result;
|
||||
|
||||
|
|
|
@ -287,6 +287,7 @@ private:
|
|||
*/
|
||||
CommandResult configureInterface(NetworkParams& aOptions);
|
||||
CommandResult dhcpRequest(NetworkParams& aOptions);
|
||||
CommandResult stopDhcp(NetworkParams& aOptions);
|
||||
CommandResult enableInterface(NetworkParams& aOptions);
|
||||
CommandResult disableInterface(NetworkParams& aOptions);
|
||||
CommandResult resetConnections(NetworkParams& aOptions);
|
||||
|
|
|
@ -159,7 +159,7 @@ interface nsIDhcpRequestCallback : nsISupports
|
|||
/**
|
||||
* Provide network services.
|
||||
*/
|
||||
[scriptable, uuid(8216224c-a4e0-43fa-9662-3f2446b500c6)]
|
||||
[scriptable, uuid(214c0810-fd41-11e4-b939-0800200c9a66)]
|
||||
interface nsINetworkService : nsISupports
|
||||
{
|
||||
const long MODIFY_ROUTE_ADD = 0;
|
||||
|
@ -417,6 +417,18 @@ interface nsINetworkService : nsISupports
|
|||
void dhcpRequest(in DOMString interfaceName,
|
||||
in nsIDhcpRequestCallback callback);
|
||||
|
||||
/**
|
||||
* Stop Dhcp daemon.
|
||||
*
|
||||
* @param ifname
|
||||
* Target interface.
|
||||
*
|
||||
* @param callback
|
||||
* Callback to notify the result of stopping dhcp request.
|
||||
*/
|
||||
void stopDhcp(in DOMString ifname,
|
||||
in nsINativeCommandCallback callback);
|
||||
|
||||
/**
|
||||
* Enable a network interface.
|
||||
*
|
||||
|
|
|
@ -375,10 +375,14 @@ Telephony::HandleCallInfo(nsITelephonyCallInfo* aInfo)
|
|||
nsRefPtr<TelephonyCallId> id = call->Id();
|
||||
id->UpdateNumber(number);
|
||||
|
||||
nsAutoString disconnectedReason;
|
||||
aInfo->GetDisconnectedReason(disconnectedReason);
|
||||
|
||||
// State changed.
|
||||
if (call->CallState() != callState) {
|
||||
if (callState == nsITelephonyService::CALL_STATE_DISCONNECTED) {
|
||||
call->ChangeStateInternal(callState, true);
|
||||
call->UpdateDisconnectedReason(disconnectedReason);
|
||||
call->ChangeState(nsITelephonyService::CALL_STATE_DISCONNECTED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -687,26 +691,6 @@ Telephony::SupplementaryServiceNotification(uint32_t aServiceId,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Telephony::NotifyError(uint32_t aServiceId,
|
||||
int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
nsRefPtr<TelephonyCall> callToNotify =
|
||||
GetCallFromEverywhere(aServiceId, aCallIndex);
|
||||
if (!callToNotify) {
|
||||
NS_ERROR("Don't call me with a bad call index!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Set the call state to 'disconnected' and remove it from the calls list.
|
||||
callToNotify->UpdateDisconnectedReason(aError);
|
||||
callToNotify->NotifyError(aError);
|
||||
callToNotify->ChangeState(nsITelephonyService::CALL_STATE_DISCONNECTED);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Telephony::NotifyCdmaCallWaiting(uint32_t aServiceId, const nsAString& aNumber,
|
||||
uint16_t aNumberPresentation,
|
||||
|
|
|
@ -119,7 +119,6 @@ TelephonyCall::ChangeStateInternal(uint16_t aCallState, bool aFireEvents)
|
|||
} else {
|
||||
mTelephony->RemoveCall(this);
|
||||
}
|
||||
UpdateDisconnectedReason(NS_LITERAL_STRING("NormalCallClearingError"));
|
||||
} else if (!mLive) {
|
||||
mLive = true;
|
||||
if (mGroup) {
|
||||
|
@ -196,16 +195,23 @@ TelephonyCall::NotifyError(const nsAString& aError)
|
|||
void
|
||||
TelephonyCall::UpdateDisconnectedReason(const nsAString& aDisconnectedReason)
|
||||
{
|
||||
NS_ASSERTION(Substring(aDisconnectedReason, aDisconnectedReason.Length() - 5).EqualsLiteral("Error"),
|
||||
NS_ASSERTION(Substring(aDisconnectedReason,
|
||||
aDisconnectedReason.Length() - 5).EqualsLiteral("Error"),
|
||||
"Disconnected reason should end with 'Error'");
|
||||
|
||||
if (mDisconnectedReason.IsNull()) {
|
||||
// There is no 'Error' suffix in the corresponding enum. We should skip
|
||||
// that part for comparison.
|
||||
CONVERT_STRING_TO_NULLABLE_ENUM(
|
||||
Substring(aDisconnectedReason, 0, aDisconnectedReason.Length() - 5),
|
||||
TelephonyCallDisconnectedReason,
|
||||
mDisconnectedReason);
|
||||
if (!mDisconnectedReason.IsNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// There is no 'Error' suffix in the corresponding enum. We should skip
|
||||
// that part for comparison.
|
||||
CONVERT_STRING_TO_NULLABLE_ENUM(
|
||||
Substring(aDisconnectedReason, 0, aDisconnectedReason.Length() - 5),
|
||||
TelephonyCallDisconnectedReason,
|
||||
mDisconnectedReason);
|
||||
|
||||
if (!aDisconnectedReason.EqualsLiteral("NormalCallClearingError")) {
|
||||
NotifyError(aDisconnectedReason);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,13 @@ NS_IMPL_ISUPPORTS(TelephonyCallInfo, nsITelephonyCallInfo)
|
|||
TelephonyCallInfo::TelephonyCallInfo(uint32_t aClientId,
|
||||
uint32_t aCallIndex,
|
||||
uint16_t aCallState,
|
||||
const nsAString& aDisconnectedReason,
|
||||
|
||||
const nsAString& aNumber,
|
||||
uint16_t aNumberPresentation,
|
||||
const nsAString& aName,
|
||||
uint16_t aNamePresentation,
|
||||
|
||||
bool aIsOutgoing,
|
||||
bool aIsEmergency,
|
||||
bool aIsConference,
|
||||
|
@ -27,10 +30,13 @@ TelephonyCallInfo::TelephonyCallInfo(uint32_t aClientId,
|
|||
: mClientId(aClientId),
|
||||
mCallIndex(aCallIndex),
|
||||
mCallState(aCallState),
|
||||
mDisconnectedReason(aDisconnectedReason),
|
||||
|
||||
mNumber(aNumber),
|
||||
mNumberPresentation(aNumberPresentation),
|
||||
mName(aName),
|
||||
mNamePresentation(aNamePresentation),
|
||||
|
||||
mIsOutgoing(aIsOutgoing),
|
||||
mIsEmergency(aIsEmergency),
|
||||
mIsConference(aIsConference),
|
||||
|
@ -60,6 +66,13 @@ TelephonyCallInfo::GetCallState(uint16_t* aCallState)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyCallInfo::GetDisconnectedReason(nsAString& aDisconnectedReason)
|
||||
{
|
||||
aDisconnectedReason = mDisconnectedReason;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyCallInfo::GetNumber(nsAString& aNumber)
|
||||
{
|
||||
|
|
|
@ -21,12 +21,21 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITELEPHONYCALLINFO
|
||||
|
||||
TelephonyCallInfo(uint32_t aClientId, uint32_t aCallIndex,
|
||||
uint16_t aCallState, const nsAString& aNumber,
|
||||
uint16_t aNumberPresentation, const nsAString& aName,
|
||||
uint16_t aNamePresentation, bool aIsOutgoing,
|
||||
bool aIsEmergency, bool aIsConference,
|
||||
bool aIsSwitchable, bool aIsMergeable);
|
||||
TelephonyCallInfo(uint32_t aClientId,
|
||||
uint32_t aCallIndex,
|
||||
uint16_t aCallState,
|
||||
const nsAString& aDisconnectedReason,
|
||||
|
||||
const nsAString& aNumber,
|
||||
uint16_t aNumberPresentation,
|
||||
const nsAString& aName,
|
||||
uint16_t aNamePresentation,
|
||||
|
||||
bool aIsOutgoing,
|
||||
bool aIsEmergency,
|
||||
bool aIsConference,
|
||||
bool aIsSwitchable,
|
||||
bool aIsMergeable);
|
||||
|
||||
private:
|
||||
// Don't try to use the default constructor.
|
||||
|
@ -37,10 +46,13 @@ private:
|
|||
uint32_t mClientId;
|
||||
uint32_t mCallIndex;
|
||||
uint16_t mCallState;
|
||||
nsString mDisconnectedReason;
|
||||
|
||||
nsString mNumber;
|
||||
uint16_t mNumberPresentation;
|
||||
nsString mName;
|
||||
uint16_t mNamePresentation;
|
||||
|
||||
bool mIsOutgoing;
|
||||
bool mIsEmergency;
|
||||
bool mIsConference;
|
||||
|
|
|
@ -124,10 +124,13 @@ function TelephonyCallInfo(aCall) {
|
|||
this.clientId = aCall.clientId;
|
||||
this.callIndex = aCall.callIndex;
|
||||
this.callState = aCall.state;
|
||||
this.disconnectedReason = aCall.disconnectedReason || "";
|
||||
|
||||
this.number = aCall.number;
|
||||
this.numberPresentation = aCall.numberPresentation;
|
||||
this.name = aCall.name;
|
||||
this.namePresentation = aCall.namePresentation;
|
||||
|
||||
this.isOutgoing = aCall.isOutgoing;
|
||||
this.isEmergency = aCall.isEmergency;
|
||||
this.isConference = aCall.isConference;
|
||||
|
@ -148,10 +151,13 @@ TelephonyCallInfo.prototype = {
|
|||
clientId: 0,
|
||||
callIndex: 0,
|
||||
callState: nsITelephonyService.CALL_STATE_UNKNOWN,
|
||||
disconnectedReason: "",
|
||||
|
||||
number: "",
|
||||
numberPresentation: nsITelephonyService.CALL_PRESENTATION_ALLOWED,
|
||||
name: "",
|
||||
namePresentation: nsITelephonyService.CALL_PRESENTATION_ALLOWED,
|
||||
|
||||
isOutgoing: true,
|
||||
isEmergency: false,
|
||||
isConference: false,
|
||||
|
@ -1438,10 +1444,6 @@ TelephonyService.prototype = {
|
|||
* calls being disconnected as well.
|
||||
*
|
||||
* @return Array a list of calls we need to fire callStateChange
|
||||
*
|
||||
* TODO: The list currently doesn't contain calls that we fire notifyError
|
||||
* for them. However, after Bug 1147736, notifyError is replaced by
|
||||
* callStateChanged and those calls should be included in the list.
|
||||
*/
|
||||
_disconnectCalls: function(aClientId, aCalls,
|
||||
aFailCause = RIL.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING) {
|
||||
|
@ -1465,7 +1467,7 @@ TelephonyService.prototype = {
|
|||
|
||||
disconnectedCalls.forEach(call => {
|
||||
call.state = nsITelephonyService.CALL_STATE_DISCONNECTED;
|
||||
call.failCause = aFailCause;
|
||||
call.disconnectedReason = aFailCause;
|
||||
|
||||
if (call.parentId) {
|
||||
let parentCall = this._currentCalls[aClientId][call.parentId];
|
||||
|
@ -1474,13 +1476,7 @@ TelephonyService.prototype = {
|
|||
|
||||
this._notifyCallEnded(call);
|
||||
|
||||
if (call.hangUpLocal || !call.failCause ||
|
||||
call.failCause === RIL.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING) {
|
||||
callsForStateChanged.push(call);
|
||||
} else {
|
||||
this._notifyAllListeners("notifyError",
|
||||
[aClientId, call.callIndex, call.failCause]);
|
||||
}
|
||||
callsForStateChanged.push(call);
|
||||
|
||||
delete this._currentCalls[aClientId][call.callIndex];
|
||||
});
|
||||
|
|
|
@ -125,8 +125,6 @@ sync protocol PTelephony {
|
|||
manages PTelephonyRequest;
|
||||
|
||||
child:
|
||||
NotifyCallError(uint32_t aClientId, int32_t aCallIndex, nsString aError);
|
||||
|
||||
NotifyCallStateChanged(nsTelephonyCallInfo[] aAllInfo);
|
||||
|
||||
NotifyCdmaCallWaiting(uint32_t aClientId, IPCCdmaWaitingCallData aData);
|
||||
|
|
|
@ -47,17 +47,6 @@ TelephonyChild::DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyChild::RecvNotifyCallError(const uint32_t& aClientId,
|
||||
const int32_t& aCallIndex,
|
||||
const nsString& aError)
|
||||
{
|
||||
MOZ_ASSERT(mService);
|
||||
|
||||
mService->NotifyError(aClientId, aCallIndex, aError);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyChild::RecvNotifyCallStateChanged(nsTArray<nsITelephonyCallInfo*>&& aAllInfo)
|
||||
{
|
||||
|
|
|
@ -34,10 +34,6 @@ protected:
|
|||
virtual bool
|
||||
DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor) override;
|
||||
|
||||
virtual bool
|
||||
RecvNotifyCallError(const uint32_t& aClientId, const int32_t& aCallIndex,
|
||||
const nsString& aError) override;
|
||||
|
||||
virtual bool
|
||||
RecvNotifyCallStateChanged(nsTArray<nsITelephonyCallInfo*>&& aAllInfo) override;
|
||||
|
||||
|
|
|
@ -37,10 +37,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
|||
uint32_t clientId;
|
||||
uint32_t callIndex;
|
||||
uint16_t callState;
|
||||
nsString disconnectedReason;
|
||||
|
||||
nsString number;
|
||||
uint16_t numberPresentation;
|
||||
nsString name;
|
||||
uint16_t namePresentation;
|
||||
|
||||
bool isOutgoing;
|
||||
bool isEmergency;
|
||||
bool isConference;
|
||||
|
@ -50,10 +53,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
|||
aParam->GetClientId(&clientId);
|
||||
aParam->GetCallIndex(&callIndex);
|
||||
aParam->GetCallState(&callState);
|
||||
aParam->GetDisconnectedReason(disconnectedReason);
|
||||
|
||||
aParam->GetNumber(number);
|
||||
aParam->GetNumberPresentation(&numberPresentation);
|
||||
aParam->GetName(name);
|
||||
aParam->GetNamePresentation(&namePresentation);
|
||||
|
||||
aParam->GetIsOutgoing(&isOutgoing);
|
||||
aParam->GetIsEmergency(&isEmergency);
|
||||
aParam->GetIsConference(&isConference);
|
||||
|
@ -63,10 +69,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
|||
WriteParam(aMsg, clientId);
|
||||
WriteParam(aMsg, callIndex);
|
||||
WriteParam(aMsg, callState);
|
||||
WriteParam(aMsg, disconnectedReason);
|
||||
|
||||
WriteParam(aMsg, number);
|
||||
WriteParam(aMsg, numberPresentation);
|
||||
WriteParam(aMsg, name);
|
||||
WriteParam(aMsg, namePresentation);
|
||||
|
||||
WriteParam(aMsg, isOutgoing);
|
||||
WriteParam(aMsg, isEmergency);
|
||||
WriteParam(aMsg, isConference);
|
||||
|
@ -90,10 +99,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
|||
uint32_t clientId;
|
||||
uint32_t callIndex;
|
||||
uint16_t callState;
|
||||
nsString disconnectedReason;
|
||||
|
||||
nsString number;
|
||||
uint16_t numberPresentation;
|
||||
nsString name;
|
||||
uint16_t namePresentation;
|
||||
|
||||
bool isOutgoing;
|
||||
bool isEmergency;
|
||||
bool isConference;
|
||||
|
@ -104,10 +116,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
|||
if (!(ReadParam(aMsg, aIter, &clientId) &&
|
||||
ReadParam(aMsg, aIter, &callIndex) &&
|
||||
ReadParam(aMsg, aIter, &callState) &&
|
||||
ReadParam(aMsg, aIter, &disconnectedReason) &&
|
||||
|
||||
ReadParam(aMsg, aIter, &number) &&
|
||||
ReadParam(aMsg, aIter, &numberPresentation) &&
|
||||
ReadParam(aMsg, aIter, &name) &&
|
||||
ReadParam(aMsg, aIter, &namePresentation) &&
|
||||
|
||||
ReadParam(aMsg, aIter, &isOutgoing) &&
|
||||
ReadParam(aMsg, aIter, &isEmergency) &&
|
||||
ReadParam(aMsg, aIter, &isConference) &&
|
||||
|
@ -117,10 +132,21 @@ struct ParamTraits<nsITelephonyCallInfo*>
|
|||
}
|
||||
|
||||
nsCOMPtr<nsITelephonyCallInfo> info =
|
||||
new TelephonyCallInfo(clientId, callIndex, callState, number,
|
||||
numberPresentation, name, namePresentation,
|
||||
isOutgoing, isEmergency, isConference,
|
||||
isSwitchable, isMergeable);
|
||||
new TelephonyCallInfo(clientId,
|
||||
callIndex,
|
||||
callState,
|
||||
disconnectedReason,
|
||||
|
||||
number,
|
||||
numberPresentation,
|
||||
name,
|
||||
namePresentation,
|
||||
|
||||
isOutgoing,
|
||||
isEmergency,
|
||||
isConference,
|
||||
isSwitchable,
|
||||
isMergeable);
|
||||
|
||||
info.forget(aResult);
|
||||
|
||||
|
|
|
@ -421,16 +421,6 @@ TelephonyIPCService::NotifyConferenceError(const nsAString& aName,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::NotifyError(uint32_t aClientId, int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
for (uint32_t i = 0; i < mListeners.Length(); i++) {
|
||||
mListeners[i]->NotifyError(aClientId, aCallIndex, aError);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyIPCService::SupplementaryServiceNotification(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
|
|
|
@ -331,17 +331,6 @@ TelephonyParent::NotifyConferenceError(const nsAString& aName,
|
|||
: NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyParent::NotifyError(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
|
||||
|
||||
return SendNotifyCallError(aClientId, aCallIndex, nsString(aError))
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyParent::SupplementaryServiceNotification(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
|
@ -431,14 +420,6 @@ TelephonyRequestParent::NotifyConferenceError(const nsAString& aName,
|
|||
MOZ_CRASH("Not a TelephonyParent!");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyRequestParent::NotifyError(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
MOZ_CRASH("Not a TelephonyParent!");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyRequestParent::SupplementaryServiceNotification(uint32_t aClientId,
|
||||
int32_t aCallIndex,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(3ea2d155-8ea2-42be-85d7-bd8ede8afc40)]
|
||||
[scriptable, uuid(e5e1be26-a3d4-49b3-8d9f-c1df5192b364)]
|
||||
interface nsITelephonyCallInfo : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -22,6 +22,14 @@ interface nsITelephonyCallInfo : nsISupports
|
|||
*/
|
||||
readonly attribute unsigned short callState;
|
||||
|
||||
/**
|
||||
* The disconnectedReason of a call is defualt to an empty string when the
|
||||
* call is "not disconnected", but once the call becomes "disconnected" the
|
||||
* disconnectedReason should be a non-empty string no matter the call is
|
||||
* disconnected for a noraml reason or an error.
|
||||
*/
|
||||
readonly attribute DOMString disconnectedReason;
|
||||
|
||||
/**
|
||||
* Number of the other party.
|
||||
*/
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
interface nsIMobileCallForwardingOptions;
|
||||
interface nsITelephonyCallInfo;
|
||||
|
||||
[scriptable, uuid(37fb45bb-ae10-4cfd-b24e-d656a9787a0a)]
|
||||
[scriptable, uuid(80faf34e-286b-4487-bd55-135bd92668b9)]
|
||||
interface nsITelephonyListener : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -54,20 +54,6 @@ interface nsITelephonyListener : nsISupports
|
|||
in long callIndex,
|
||||
in unsigned short notification);
|
||||
|
||||
/**
|
||||
* Called when RIL error occurs.
|
||||
*
|
||||
* @param clientId
|
||||
Indicate the RIL client, 0 ~ (number of client - 1).
|
||||
* @param callIndex
|
||||
* Call identifier assigned by the RIL. -1 if no connection
|
||||
* @param error
|
||||
* Error from RIL.
|
||||
*/
|
||||
void notifyError(in unsigned long clientId,
|
||||
in long callIndex,
|
||||
in AString error);
|
||||
|
||||
/**
|
||||
* Called when a waiting call comes in CDMA networks.
|
||||
*
|
||||
|
|
|
@ -791,7 +791,12 @@ pref("media.useAudioChannelService", false);
|
|||
pref("gfx.canvas.azure.backends", "skia");
|
||||
pref("gfx.canvas.azure.accelerated", true);
|
||||
|
||||
pref("general.useragent.override.youtube.com", "Android; Tablet;#Android; Mobile;");
|
||||
// See ua-update.json.in for the packaged UA override list
|
||||
// See Bug 1163759 before setting this to true
|
||||
pref("general.useragent.updates.enabled", false);
|
||||
pref("general.useragent.updates.url", "https://dynamicua.cdn.mozilla.net/0/%APP_ID%");
|
||||
pref("general.useragent.updates.interval", 604800); // 1 week
|
||||
pref("general.useragent.updates.retry", 86400); // 1 day
|
||||
|
||||
// When true, phone number linkification is enabled.
|
||||
pref("browser.ui.linkify.phone", false);
|
||||
|
|
|
@ -17,3 +17,6 @@ JS_PREFERENCE_FILES += [
|
|||
'mobile.js',
|
||||
]
|
||||
|
||||
DIST_FILES += [
|
||||
'ua-update.json.in',
|
||||
]
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#filter slashslash
|
||||
// Everything after the first // on a line will be removed by the preproccesor.
|
||||
// Send these sites a custom user-agent. Bugs should be included with an entry.
|
||||
{
|
||||
// bug 788422, youtube.com
|
||||
"youtube.com": "Android; Tablet;#Android; Mobile;"
|
||||
}
|
|
@ -254,8 +254,7 @@
|
|||
<!-- The main reason for the Tab Queue build flag is to not mess with the VIEW intent filter
|
||||
before the rest of the plumbing is in place -->
|
||||
|
||||
<service android:name="org.mozilla.gecko.tabqueue.TabQueueService"
|
||||
android:taskAffinity="@ANDROID_PACKAGE_NAME@.TABQUEUE" />
|
||||
<service android:name="org.mozilla.gecko.tabqueue.TabQueueService" />
|
||||
|
||||
<activity android:name="org.mozilla.gecko.tabqueue.TabQueuePrompt"
|
||||
android:launchMode="singleTop"
|
||||
|
@ -265,6 +264,7 @@
|
|||
android:label="@MOZ_APP_DISPLAYNAME@"
|
||||
android:launchMode="singleTask"
|
||||
android:excludeFromRecents="true"
|
||||
android:taskAffinity="@ANDROID_PACKAGE_NAME@.TABQUEUE"
|
||||
android:theme="@style/TabQueueActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
|
|
@ -11,7 +11,6 @@ import org.mozilla.gecko.GeckoSharedPrefs;
|
|||
import org.mozilla.gecko.Locales;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
import org.mozilla.gecko.sync.setup.activities.WebURLFinder;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
@ -33,17 +32,24 @@ public class TabQueueDispatcher extends Locales.LocaleAwareActivity {
|
|||
|
||||
GeckoAppShell.ensureCrashHandling();
|
||||
|
||||
ContextUtils.SafeIntent intent = new ContextUtils.SafeIntent(getIntent());
|
||||
// The EXCLUDE_FROM_RECENTS flag is sticky
|
||||
// (see http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.0_r1/com/android/server/am/ActivityRecord.java/#468)
|
||||
// So let's remove this whilst keeping all other flags the same, otherwise BrowserApp will vanish from Recents!
|
||||
Intent intent = getIntent();
|
||||
int flags = intent.getFlags() & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
|
||||
intent.setFlags(flags);
|
||||
|
||||
ContextUtils.SafeIntent safeIntent = new ContextUtils.SafeIntent(intent);
|
||||
|
||||
// For the moment lets exit early and start fennec as normal if we're not in nightly with
|
||||
// the tab queue build flag.
|
||||
if (!AppConstants.MOZ_ANDROID_TAB_QUEUE || !AppConstants.NIGHTLY_BUILD) {
|
||||
loadNormally(intent.getUnsafe());
|
||||
loadNormally(safeIntent.getUnsafe());
|
||||
return;
|
||||
}
|
||||
|
||||
// The URL is usually hiding somewhere in the extra text. Extract it.
|
||||
final String dataString = intent.getDataString();
|
||||
final String dataString = safeIntent.getDataString();
|
||||
if (TextUtils.isEmpty(dataString)) {
|
||||
abortDueToNoURL(dataString);
|
||||
return;
|
||||
|
@ -52,9 +58,9 @@ public class TabQueueDispatcher extends Locales.LocaleAwareActivity {
|
|||
boolean shouldShowOpenInBackgroundToast = GeckoSharedPrefs.forApp(this).getBoolean(GeckoPreferences.PREFS_TAB_QUEUE, false);
|
||||
|
||||
if (shouldShowOpenInBackgroundToast) {
|
||||
showToast(intent.getUnsafe());
|
||||
showToast(safeIntent.getUnsafe());
|
||||
} else {
|
||||
loadNormally(intent.getUnsafe());
|
||||
loadNormally(safeIntent.getUnsafe());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -512,6 +512,7 @@
|
|||
@BINPATH@/@PREF_DIR@/mobile.js
|
||||
@BINPATH@/@PREF_DIR@/mobile-branding.js
|
||||
@BINPATH@/@PREF_DIR@/channel-prefs.js
|
||||
@BINPATH@/ua-update.json
|
||||
@BINPATH@/greprefs.js
|
||||
@BINPATH@/defaults/autoconfig/prefcalls.js
|
||||
@BINPATH@/defaults/profile/prefs.js
|
||||
|
|
|
@ -123,6 +123,11 @@ abstract class UITest extends BaseRobocopTest
|
|||
return mActions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringHelper getStringHelper() {
|
||||
return mStringHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dumpLog(final String logtag, final String message) {
|
||||
mAsserter.dumpLog(logtag + ": " + message);
|
||||
|
|
|
@ -32,6 +32,7 @@ public interface UITestContext {
|
|||
public Driver getDriver();
|
||||
public Actions getActions();
|
||||
public Instrumentation getInstrumentation();
|
||||
public StringHelper getStringHelper();
|
||||
|
||||
public void dumpLog(final String logtag, final String message);
|
||||
public void dumpLog(final String logtag, final String message, final Throwable t);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package org.mozilla.gecko.tests.components;
|
||||
|
||||
import org.mozilla.gecko.Actions;
|
||||
import org.mozilla.gecko.tests.StringHelper;
|
||||
import org.mozilla.gecko.tests.UITestContext;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -23,11 +24,13 @@ public abstract class BaseComponent {
|
|||
protected final Activity mActivity;
|
||||
protected final Solo mSolo;
|
||||
protected final Actions mActions;
|
||||
protected final StringHelper mStringHelper;
|
||||
|
||||
public BaseComponent(final UITestContext testContext) {
|
||||
mTestContext = testContext;
|
||||
mActivity = mTestContext.getActivity();
|
||||
mSolo = mTestContext.getSolo();
|
||||
mActions = mTestContext.getActions();
|
||||
mStringHelper = mTestContext.getStringHelper();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,8 +56,8 @@ public class ToolbarComponent extends BaseComponent {
|
|||
final String expected;
|
||||
final String absoluteURL = NavigationHelper.adjustUrl(url);
|
||||
|
||||
if (StringHelper.get().ABOUT_HOME_URL.equals(absoluteURL)) {
|
||||
expected = StringHelper.get().ABOUT_HOME_TITLE;
|
||||
if (mStringHelper.ABOUT_HOME_URL.equals(absoluteURL)) {
|
||||
expected = mStringHelper.ABOUT_HOME_TITLE;
|
||||
} else if (absoluteURL.startsWith(URL_HTTP_PREFIX)) {
|
||||
expected = absoluteURL.substring(URL_HTTP_PREFIX.length());
|
||||
} else {
|
||||
|
@ -134,7 +134,7 @@ public class ToolbarComponent extends BaseComponent {
|
|||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View view = pageActionLayout.getChildAt(i);
|
||||
if (StringHelper.get().CONTENT_DESCRIPTION_READER_MODE_BUTTON.equals(view.getContentDescription())) {
|
||||
if (mStringHelper.CONTENT_DESCRIPTION_READER_MODE_BUTTON.equals(view.getContentDescription())) {
|
||||
return (ImageButton) view;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ public final class WaitHelper {
|
|||
* the invocation of storeState to the invocation of hasStateChanged. A boolean will be
|
||||
* returned from hasStateChanged, indicating this change of status.
|
||||
*/
|
||||
private static interface ChangeVerifier {
|
||||
private interface ChangeVerifier {
|
||||
public String getLogTag();
|
||||
|
||||
/**
|
||||
|
|
|
@ -194,9 +194,9 @@ this.Async = {
|
|||
|
||||
querySpinningly: function querySpinningly(query, names) {
|
||||
// 'Synchronously' asyncExecute, fetching all results by name.
|
||||
let storageCallback = {names: names,
|
||||
syncCb: Async.makeSyncCallback()};
|
||||
storageCallback.__proto__ = Async._storageCallbackPrototype;
|
||||
let storageCallback = Object.create(Async._storageCallbackPrototype);
|
||||
storageCallback.names = names;
|
||||
storageCallback.syncCb = Async.makeSyncCallback();
|
||||
query.executeAsync(storageCallback);
|
||||
return Async.waitForSyncCallback(storageCallback.syncCb);
|
||||
},
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
FROM quay.io/mozilla/builder:0.5.4
|
||||
FROM quay.io/mozilla/builder:0.5.5
|
||||
MAINTAINER Wander Lairson Costa <wcosta@mozilla.com>
|
||||
|
||||
ENV SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE /home/worker/socorro.token
|
||||
|
||||
# Add utilities and configuration
|
||||
ADD bin /home/worker/bin
|
||||
ADD config /home/worker/.aws/config
|
||||
ADD socorro.token /home/worker/socorro.token
|
||||
|
||||
RUN yum install -y bc lzop
|
||||
RUN pip install awscli
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.13
|
||||
0.0.14
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/bash -e
|
||||
|
||||
while getopts "t:i:k:" arg; do
|
||||
while getopts "t:i:k:s:" arg; do
|
||||
case $arg in
|
||||
t)
|
||||
TAG=$OPTARG
|
||||
|
@ -11,6 +11,9 @@ while getopts "t:i:k:" arg; do
|
|||
k)
|
||||
SECRET_KEY=$OPTARG
|
||||
;;
|
||||
s)
|
||||
SOCORRO_TOKEN=$OPTARG
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
@ -19,12 +22,16 @@ pushd $(dirname $0)
|
|||
test $TAG
|
||||
test $KEY_ID
|
||||
test $SECRET_KEY
|
||||
test $SOCORRO_TOKEN
|
||||
|
||||
(echo '[default]'
|
||||
echo "aws_access_key_id = $KEY_ID"
|
||||
echo "aws_secret_access_key = $SECRET_KEY") > config
|
||||
|
||||
echo $SOCORRO_TOKEN > socorro.token
|
||||
|
||||
docker build -t $TAG .
|
||||
rm -f config
|
||||
rm -f socorro.token
|
||||
|
||||
popd
|
||||
|
|
|
@ -386,3 +386,76 @@ class Graph(object):
|
|||
graph.pop('metadata', None)
|
||||
|
||||
print(json.dumps(graph, indent=4))
|
||||
|
||||
@CommandProvider
|
||||
class CIBuild(object):
|
||||
@Command('taskcluster-build', category='ci',
|
||||
description="Create taskcluster try server build task")
|
||||
@CommandArgument('--base-repository',
|
||||
help='URL for "base" repository to clone')
|
||||
@CommandArgument('--head-repository',
|
||||
required=True,
|
||||
help='URL for "head" repository to fetch revision from')
|
||||
@CommandArgument('--head-ref',
|
||||
help='Reference (this is same as rev usually for hg)')
|
||||
@CommandArgument('--head-rev',
|
||||
required=True,
|
||||
help='Commit revision to use')
|
||||
@CommandArgument('--mozharness-repository',
|
||||
help='URL for custom mozharness repo')
|
||||
@CommandArgument('--mozharness-rev',
|
||||
help='Commit revision to use from mozharness repository')
|
||||
@CommandArgument('--owner',
|
||||
default='foobar@mozilla.com',
|
||||
help='email address of who owns this graph')
|
||||
@CommandArgument('build_task',
|
||||
help='path to build task definition')
|
||||
def create_ci_build(self, **params):
|
||||
templates = Templates(ROOT)
|
||||
# TODO handle git repos
|
||||
head_repository = params['head_repository']
|
||||
if not head_repository:
|
||||
head_repository = get_hg_url()
|
||||
|
||||
head_rev = params['head_rev']
|
||||
if not head_rev:
|
||||
head_rev = get_latest_hg_revision(head_repository)
|
||||
|
||||
head_ref = params['head_ref'] or head_rev
|
||||
|
||||
mozharness = load_mozharness_info()
|
||||
|
||||
mozharness_repo = params['mozharness_repository']
|
||||
if mozharness_repo is None:
|
||||
mozharness_repo = mozharness['repo']
|
||||
|
||||
mozharness_rev = params['mozharness_rev']
|
||||
if mozharness_rev is None:
|
||||
mozharness_rev = mozharness['revision']
|
||||
|
||||
build_parameters = dict(gaia_info().items() + {
|
||||
'docker_image': docker_image,
|
||||
'owner': params['owner'],
|
||||
'from_now': json_time_from_now,
|
||||
'now': current_json_time(),
|
||||
'base_repository': params['base_repository'] or head_repository,
|
||||
'head_repository': head_repository,
|
||||
'head_rev': head_rev,
|
||||
'head_ref': head_ref,
|
||||
'mozharness_repository': mozharness_repo,
|
||||
'mozharness_ref': mozharness_rev,
|
||||
'mozharness_rev': mozharness_rev
|
||||
}.items())
|
||||
|
||||
try:
|
||||
build_task = templates.load(params['build_task'], build_parameters)
|
||||
except IOError:
|
||||
sys.stderr.write(
|
||||
"Could not load build task file. Ensure path is a relative " \
|
||||
"path from testing/taskcluster"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
taskcluster_graph.build_task.validate(build_task)
|
||||
|
||||
print(json.dumps(build_task['task'], indent=4))
|
||||
|
|
|
@ -50,7 +50,7 @@ mkdir -p $HOME/artifacts-public
|
|||
|
||||
mv $WORKSPACE/B2G/upload-public/$mar_file $HOME/artifacts-public/
|
||||
mv $WORKSPACE/B2G/upload/sources.xml $HOME/artifacts/sources.xml
|
||||
#mv $WORKSPACE/B2G/upload/b2g-*.crashreporter-symbols.zip $HOME/artifacts/b2g-crashreporter-symbols.zip
|
||||
mv $WORKSPACE/B2G/upload/b2g-*.crashreporter-symbols.zip $HOME/artifacts/b2g-crashreporter-symbols.zip
|
||||
mv $WORKSPACE/B2G/upload/b2g-*.android-arm.tar.gz $HOME/artifacts/b2g-android-arm.tar.gz
|
||||
mv $WORKSPACE/B2G/upload/${TARGET}.zip $HOME/artifacts/${TARGET}.zip
|
||||
mv $WORKSPACE/B2G/upload/gaia.zip $HOME/artifacts/gaia.zip
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче