merge b2g-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-12-17 12:57:09 +01:00
commit 70b3e47b2d
38 changed files with 763 additions and 97 deletions

View File

@ -1037,6 +1037,9 @@ pref("browser.autofocus", false);
// Enable wakelock
pref("dom.wakelock.enabled", true);
// Enable webapps add-ons
pref("dom.apps.customization.enabled", true);
// Enable touch caret by default
pref("touchcaret.enabled", true);

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<!-- 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"/>

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<!-- 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"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "99bea97a4bd9d6af1d7462e1abe15c8aaf4d7981",
"revision": "8175c3383310bf79cbfd01d36273620dede2a111",
"repo_path": "integration/gaia-central"
}

View File

@ -17,11 +17,11 @@
<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="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>

View File

@ -15,6 +15,11 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
try {
if (Services.prefs.getBoolPref("dom.apps.customization.enabled")) {
Cu.import("resource://gre/modules/UserCustomizations.jsm");
}
} catch(e) {}
const APPS_SERVICE_CID = Components.ID("{05072afa-92fe-45bf-ae22-39b69c117058}");

View File

@ -479,9 +479,12 @@ this.AppsUtils = {
return true;
},
allowUnsignedAddons: false, // for testing purposes.
/**
* Checks if the app role is allowed.
* Checks if the app role is allowed:
* Only certified apps can be themes.
* Only privileged or certified apps can be addons.
* @param aRole : the role assigned to this app.
* @param aStatus : the APP_STATUS_* for this app.
*/
@ -489,6 +492,12 @@ this.AppsUtils = {
if (aRole == "theme" && aStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
return false;
}
if (!this.allowUnsignedAddons &&
(aRole == "addon" &&
aStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED &&
aStatus !== Ci.nsIPrincipal.APP_STATUS_PRIVILEGED)) {
return false;
}
return true;
},
@ -718,6 +727,11 @@ this.AppsUtils = {
// Convert the binary hash data to a hex string.
return [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
},
// Returns the hash for a JS object.
computeObjectHash: function(aObject) {
return this.computeHash(JSON.stringify(aObject));
}
}

View File

@ -0,0 +1,368 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
this.EXPORTED_SYMBOLS = ["UserCustomizations"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1",
"nsIMessageBroadcaster");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
XPCOMUtils.defineLazyServiceGetter(this, "console",
"@mozilla.org/consoleservice;1",
"nsIConsoleService");
/**
* Customization scripts and CSS stylesheets can be specified in an
* application manifest with the following syntax:
* "customizations": [
* {
* "filter": "http://youtube.com",
* "css": ["file1.css", "file2.css"],
* "scripts": ["script1.js", "script2.js"]
* }
* ]
*/
let debug = Services.prefs.getBoolPref("dom.mozApps.debug")
? (aMsg) => {
dump("-*-*- UserCustomizations (" +
(UserCustomizations._inParent ? "parent" : "child") +
"): " + aMsg + "\n");
}
: (aMsg) => {};
function log(aStr) {
console.logStringMessage(aStr);
}
this.UserCustomizations = {
_items: [],
_loaded : {}, // Keep track per manifestURL of css and scripts loaded.
_windows: null, // Set of currently opened windows.
_enabled: false,
_addItem: function(aItem) {
debug("_addItem: " + uneval(aItem));
this._items.push(aItem);
if (this._inParent) {
ppmm.broadcastAsyncMessage("UserCustomizations:Add", [aItem]);
}
},
_removeItem: function(aHash) {
debug("_removeItem: " + aHash);
let index = -1;
this._items.forEach((script, pos) => {
if (script.hash == aHash ) {
index = pos;
}
});
if (index != -1) {
this._items.splice(index, 1);
}
if (this._inParent) {
ppmm.broadcastAsyncMessage("UserCustomizations:Remove", aHash);
}
},
register: function(aManifest, aApp) {
debug("Starting customization registration for " + aApp.manifestURL);
if (!this._enabled || !aApp.enabled || aApp.role != "addon") {
debug("Rejecting registration (global enabled=" + this._enabled +
") (app role=" + aApp.role +
", enabled=" + aApp.enabled + ")");
debug(uneval(aApp));
return;
}
let customizations = aManifest.customizations;
if (customizations === undefined || !Array.isArray(customizations)) {
return;
}
let base = Services.io.newURI(aApp.origin, null, null);
customizations.forEach(item => {
// The filter property is mandatory.
if (!item.filter || (typeof item.filter !== "string")) {
log("Mandatory filter property not found in this customization item: " +
uneval(item) + " in " + aApp.manifestURL);
return;
}
// Create a new object with resolved urls and a hash that we reuse to
// remove items.
let custom = {
filter: item.filter,
status: aApp.appStatus,
manifestURL: aApp.manifestURL,
css: [],
scripts: []
};
custom.hash = AppsUtils.computeObjectHash(item);
if (item.css && Array.isArray(item.css)) {
item.css.forEach((css) => {
custom.css.push(base.resolve(css));
});
}
if (item.scripts && Array.isArray(item.scripts)) {
item.scripts.forEach((script) => {
custom.scripts.push(base.resolve(script));
});
}
this._addItem(custom);
});
this._updateAllWindows();
},
_updateAllWindows: function() {
debug("UpdateWindows");
if (this._inParent) {
ppmm.broadcastAsyncMessage("UserCustomizations:UpdateWindows", {});
}
// Inject in all currently opened windows.
this._windows.forEach(this._injectInWindow.bind(this));
},
unregister: function(aManifest, aApp) {
if (!this._enabled) {
return;
}
debug("Starting customization unregistration for " + aApp.manifestURL);
let customizations = aManifest.customizations;
if (customizations === undefined || !Array.isArray(customizations)) {
return;
}
customizations.forEach(item => {
this._removeItem(AppsUtils.computeObjectHash(item));
});
this._unloadForManifestURL(aApp.manifestURL);
},
_unloadForManifestURL: function(aManifestURL) {
debug("_unloadForManifestURL " + aManifestURL);
if (this._inParent) {
ppmm.broadcastAsyncMessage("UserCustomizations:Unload", aManifestURL);
}
if (!this._loaded[aManifestURL]) {
return;
}
if (this._loaded[aManifestURL].scripts &&
this._loaded[aManifestURL].scripts.length > 0) {
// We can't rollback script changes, so don't even try to unload in this
// situation.
return;
}
this._loaded[aManifestURL].css.forEach(aItem => {
try {
debug("unloading " + aItem.uri.spec);
let utils = aItem.window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
utils.removeSheet(aItem.uri, Ci.nsIDOMWindowUtils.AUTHOR_SHEET);
} catch(e) {
log("Error unloading stylesheet " + aItem.uri.spec + " : " + e);
}
});
this._loaded[aManifestURL] = null;
},
_injectItem: function(aWindow, aItem, aInjected) {
debug("Injecting item " + uneval(aItem) + " in " + aWindow.location.href);
let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let manifestURL = aItem.manifestURL;
// Load the stylesheets only in this window.
aItem.css.forEach(aCss => {
if (aInjected.indexOf(aCss) !== -1) {
debug("Skipping duplicated css: " + aCss);
return;
}
let uri = Services.io.newURI(aCss, null, null);
try {
utils.loadSheet(uri, Ci.nsIDOMWindowUtils.AUTHOR_SHEET);
if (!this._loaded[manifestURL]) {
this._loaded[manifestURL] = { css: [], scripts: [] };
}
this._loaded[manifestURL].css.push({ window: aWindow, uri: uri });
aInjected.push(aCss);
} catch(e) {
log("Error loading stylesheet " + aCss + " : " + e);
}
});
let sandbox;
if (aItem.scripts.length > 0) {
sandbox = Cu.Sandbox([aWindow],
{ wantComponents: false,
sandboxPrototype: aWindow });
}
// Load the scripts using a sandbox.
aItem.scripts.forEach(aScript => {
debug("Sandboxing " + aScript);
if (aInjected.indexOf(aScript) !== -1) {
debug("Skipping duplicated script: " + aScript);
return;
}
try {
Services.scriptloader.loadSubScript(aScript, sandbox, "UTF-8");
if (!this._loaded[manifestURL]) {
this._loaded[manifestURL] = { css: [], scripts: [] };
}
this._loaded[manifestURL].scripts.push({ sandbox: sandbox, uri: aScript });
aInjected.push(aScript);
} catch(e) {
log("Error sandboxing " + aScript + " : " + e);
}
});
// Makes sure we get rid of the sandbox.
if (sandbox) {
aWindow.addEventListener("unload", () => {
Cu.nukeSandbox(sandbox);
sandbox = null;
});
}
},
_injectInWindow: function(aWindow) {
debug("_injectInWindow");
if (!aWindow || !aWindow.document) {
return;
}
let principal = aWindow.document.nodePrincipal;
debug("principal status: " + principal.appStatus);
let href = aWindow.location.href;
// The list of resources loaded in this window, used to filter out
// duplicates.
let injected = [];
this._items.forEach((aItem) => {
// We only allow customizations to apply to apps with an equal or lower
// privilege level.
if (principal.appStatus > aItem.status) {
return;
}
let regexp = new RegExp(aItem.filter, "g");
if (regexp.test(href)) {
this._injectItem(aWindow, aItem, injected);
debug("Currently injected: " + injected.toString());
}
});
},
observe: function(aSubject, aTopic, aData) {
if (aTopic === "content-document-global-created") {
let window = aSubject.QueryInterface(Ci.nsIDOMWindow);
let href = window.location.href;
if (!href || href == "about:blank") {
return;
}
let id = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.currentInnerWindowID;
this._windows.set(id, window);
debug("document created: " + href);
this._injectInWindow(window);
} else if (aTopic === "inner-window-destroyed") {
let winId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
this._windows.delete(winId);
}
},
init: function() {
this._enabled = false;
try {
this._enabled = Services.prefs.getBoolPref("dom.apps.customization.enabled");
} catch(e) {}
if (!this._enabled) {
return;
}
this._windows = new Map(); // Can't be a WeakMap because we need to enumerate.
this._inParent = Cc["@mozilla.org/xre/runtime;1"]
.getService(Ci.nsIXULRuntime)
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
debug("init");
Services.obs.addObserver(this, "content-document-global-created",
/* ownsWeak */ false);
Services.obs.addObserver(this, "inner-window-destroyed",
/* ownsWeak */ false);
if (this._inParent) {
ppmm.addMessageListener("UserCustomizations:List", this);
} else {
cpmm.addMessageListener("UserCustomizations:Add", this);
cpmm.addMessageListener("UserCustomizations:Remove", this);
cpmm.addMessageListener("UserCustomizations:Unload", this);
cpmm.addMessageListener("UserCustomizations:UpdateWindows", this);
cpmm.sendAsyncMessage("UserCustomizations:List", {});
}
},
receiveMessage: function(aMessage) {
let name = aMessage.name;
let data = aMessage.data;
switch(name) {
case "UserCustomizations:List":
aMessage.target.sendAsyncMessage("UserCustomizations:Add", this._items);
break;
case "UserCustomizations:Add":
data.forEach(this._addItem, this);
break;
case "UserCustomizations:Remove":
this._removeItem(data);
break;
case "UserCustomizations:Unload":
this._unloadForManifestURL(data);
break;
case "UserCustomizations:UpdateWindows":
this._updateAllWindows();
break;
}
}
}
UserCustomizations.init();

View File

@ -43,6 +43,23 @@ Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyGetter(this, "UserCustomizations", function() {
let enabled = false;
try {
enabled = Services.prefs.getBoolPref("dom.apps.customization.enabled");
} catch(e) {}
if (enabled) {
return Cu.import("resource://gre/modules/UserCustomizations.jsm", {})
.UserCustomizations;
} else {
return {
register: function() {},
unregister: function() {}
};
}
});
XPCOMUtils.defineLazyModuleGetter(this, "TrustedRootCertificate",
"resource://gre/modules/StoreTrustAnchor.jsm");
@ -406,6 +423,7 @@ this.DOMApplicationRegistry = {
app.redirects = this.sanitizeRedirects(aResult.redirects);
}
app.kind = this.appKind(app, aResult.manifest);
UserCustomizations.register(aResult.manifest, app);
});
// Nothing else to do but notifying we're ready.
@ -1097,6 +1115,7 @@ this.DOMApplicationRegistry = {
this._registerSystemMessages(manifest, app);
this._registerInterAppConnections(manifest, app);
appsToRegister.push({ manifest: manifest, app: app });
UserCustomizations.register(manifest, app);
});
this._safeToClone.resolve();
this._registerActivitiesForApps(appsToRegister, aRunUpdate);
@ -1991,7 +2010,8 @@ this.DOMApplicationRegistry = {
// Updates the redirect mapping, activities and system message handlers.
// aOldManifest can be null if we don't have any handler to unregister.
updateAppHandlers: function(aOldManifest, aNewManifest, aApp) {
debug("updateAppHandlers: old=" + aOldManifest + " new=" + aNewManifest);
debug("updateAppHandlers: old=" + uneval(aOldManifest) +
" new=" + uneval(aNewManifest));
this.notifyAppsRegistryStart();
if (aApp.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
aApp.redirects = this.sanitizeRedirects(aNewManifest.redirects);
@ -2001,6 +2021,8 @@ this.DOMApplicationRegistry = {
new ManifestHelper(aNewManifest, aApp.origin, aApp.manifestURL);
this._saveWidgetsFullPath(manifest, aApp);
aApp.role = manifest.role ? manifest.role : "";
if (supportSystemMessages()) {
if (aOldManifest) {
this._unregisterActivities(aOldManifest, aApp);
@ -2012,6 +2034,12 @@ this.DOMApplicationRegistry = {
// Nothing else to do but notifying we're ready.
this.notifyAppsRegistryReady();
}
// Update user customizations.
if (aOldManifest) {
UserCustomizations.unregister(aOldManifest, aApp);
}
UserCustomizations.register(aNewManifest, aApp);
},
checkForUpdate: function(aData, aMm) {
@ -4019,6 +4047,7 @@ this.DOMApplicationRegistry = {
if (supportSystemMessages()) {
this._unregisterActivities(aApp.manifest, aApp);
}
UserCustomizations.unregister(aApp.manifest, aApp);
let dir = this._getAppDir(id);
try {
@ -4388,6 +4417,12 @@ this.DOMApplicationRegistry = {
});
this.broadcastMessage("Webapps:SetEnabled:Return", app);
});
// Update customization.
this.getManifestFor(app.manifestURL).then((aManifest) => {
app.enabled ? UserCustomizations.register(aManifest, app)
: UserCustomizations.unregister(aManifest, app);
});
},
getManifestFor: function(aManifestURL) {

View File

@ -38,6 +38,7 @@ EXTRA_JS_MODULES += [
'PermissionsInstaller.jsm',
'PermissionsTable.jsm',
'StoreTrustAnchor.jsm',
'UserCustomizations.jsm',
]
EXTRA_PP_JS_MODULES += [

Binary file not shown.

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<title>This page will be modified by the add-on</title>
<script>
function sendAlertsForNode(node) {
alert(node.textContent);
var color = window.getComputedStyle(node).getPropertyValue("color");
alert(color);
}
function run() {
sendAlertsForNode(document.getElementById("header"));
sendAlertsForNode(document.getElementById("header2"));
}
</script>
</head>
<body onload="run()">
<h1 id="header">Lorem ipsum</h1>
<h2 id="header2">Uncustomized content</h2>
</body>
</html>

View File

@ -0,0 +1,12 @@
{
"name": "Addon app",
"description": "Let me inject script and css!",
"customizations" : [
{
"filter": "http://mochi.test:8888/tests/dom/apps/tests/addons",
"css": ["style.css", "style2.css", "invalid.css", "style.css"],
"scripts": ["script.js", "script2.js", "invalid.js", "script.js"]
}
],
"role": "addon"
}

View File

@ -0,0 +1,4 @@
document.addEventListener("DOMContentLoaded", function() {
var head = document.getElementById("header");
head.innerHTML = "Hello World!";
}, false);

View File

@ -0,0 +1,3 @@
#header {
color: red;
}

View File

@ -0,0 +1,5 @@
{
"name": "Addon app",
"description": "Let me inject script and css!",
"package_path" : "application.zip"
}

View File

@ -0,0 +1 @@
Content-Type: application/manifest+json

View File

@ -1,6 +1,10 @@
[DEFAULT]
skip-if = e10s
support-files =
addons/application.zip
addons/update.webapp
addons/update.webapp^headers^
addons/index.html
chromeAddCert.js
file_app.sjs
file_app.template.html
@ -25,6 +29,8 @@ support-files =
marketplace/*
pkg_install_iframe.html
[test_app_addons.html]
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
[test_app_enabled.html]
[test_app_update.html]
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app

View File

@ -0,0 +1,186 @@
<!DOCTYPE HTML><!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1042881
-->
<html>
<head>
<meta charset="utf-8">
<title>Test for Bug 923897 - Test apps as addons</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="application/javascript;version=1.7">
/**
* Test for Bug 923897
* This file covers testing addons.
*
* The setup is as follows:
* - app is installed and offers both script and css to inject in
* http://mochi.test:8888/tests/dom/apps/tests/addons/index.html
*/
SimpleTest.waitForExplicitFinish();
let appManifestURL = "http://mochi.test:8888/tests/dom/apps/tests/addons/update.webapp";
let gGenerator = runTest();
function go() {
gGenerator.next();
}
function continueTest() {
try {
gGenerator.next();
} catch (e if e instanceof StopIteration) {
SimpleTest.finish();
}
}
function mozAppsError() {
ok(false, "mozApps error: " + this.error.name);
SimpleTest.finish();
}
// Triggers one navigation test to the given page.
// Waits for alert() messages before tearing down the iframe.
function openPage(pageURL, messages) {
info("Navigating to " + pageURL);
let ifr = document.createElement("iframe");
let listener = function(event) {
let message = messages.shift();
is(event.detail.message, message, "Checking alert message for " + pageURL);
if (messages.length == 0) {
ifr.removeEventListener("mozbrowsershowmodalprompt", listener);
ifr.parentNode.removeChild(ifr);
continueTest();
}
}
ifr.addEventListener("mozbrowsershowmodalprompt", listener, false);
// Open an the app url in an iframe.
ifr.setAttribute("mozbrowser", "true");
ifr.setAttribute("src", pageURL);
document.getElementById("container").appendChild(ifr);
}
let apps = [];
function installApp(manifestURL) {
info("About to install app at " + manifestURL);
let req = navigator.mozApps.installPackage(manifestURL);
req.onsuccess = function() {
apps.push(req.result);
is(req.result.manifestURL, manifestURL, "app installed");
if (req.result.installState == "installed") {
is(req.result.installState, "installed", "app downloaded");
continueTest();
} else {
req.result.ondownloadapplied = function() {
is(req.result.installState, "installed", "app downloaded");
continueTest();
}
}
}
req.onerror = mozAppsError;
}
function runTest() {
// Set up.
SpecialPowers.setAllAppsLaunchable(true);
SpecialPowers.allowUnsignedAddons();
SpecialPowers.pushPrefEnv({'set': [
["dom.mozBrowserFramesEnabled", true],
["dom.apps.customization.enabled", true],
]},continueTest);
yield undefined;
SpecialPowers.pushPermissions(
[{ "type": "webapps-manage", "allow": 1, "context": document },
{ "type": "browser", "allow": 1, "context": document } ],
continueTest);
yield undefined;
SpecialPowers.autoConfirmAppInstall(continueTest);
yield undefined;
SpecialPowers.autoConfirmAppUninstall(continueTest);
yield undefined;
// Opens the iframe to the test page, initial state.
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
["Lorem ipsum", "rgb(0, 0, 0)",
"Uncustomized content", "rgb(0, 0, 0)"]);
yield undefined;
// Install addon app.
installApp(appManifestURL);
yield undefined;
// Opens the iframe to the test page, customized.
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
["Hello World!", "rgb(255, 0, 0)",
"Customized content", "rgb(0, 0, 255)"]);
yield undefined;
// Disable the app.
navigator.mozApps.mgmt.onenabledstatechange = function(event) {
ok(true, "onenabledstatechange received");
is(event.application.enabled, false, "Application is disabled");
is(apps[0].enabled, false, "Application is disabled");
continueTest();
}
navigator.mozApps.mgmt.setEnabled(apps[0], false);
yield undefined;
// Opens the iframe to the test page, back to initial state.
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
["Lorem ipsum", "rgb(0, 0, 0)",
"Uncustomized content", "rgb(0, 0, 0)"]);
yield undefined;
// Re-enable the app.
navigator.mozApps.mgmt.onenabledstatechange = function(event) {
ok(true, "onenabledstatechange received");
is(event.application.enabled, true, "Application is enabled");
is(apps[0].enabled, true, "Application is enabled");
continueTest();
}
navigator.mozApps.mgmt.setEnabled(apps[0], true);
yield undefined;
// Opens the iframe to the test page, customized.
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
["Hello World!", "rgb(255, 0, 0)",
"Customized content", "rgb(0, 0, 255)"]);
yield undefined;
// Clean up after ourselves by uninstalling apps.
while (apps.length) {
let app = apps.pop();
req = navigator.mozApps.mgmt.uninstall(app);
req.onsuccess = continueTest;
req.onerror = mozAppsError;
yield undefined;
}
// Opens the iframe to the test page, back to initial state.
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
["Lorem ipsum", "rgb(0, 0, 0)",
"Uncustomized content", "rgb(0, 0, 0)"]);
yield undefined;
}
</script>
</head>
<body onload="go()">
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
<div id="container"></div>
</body>
</html>

View File

@ -27,6 +27,11 @@ const BrowserElementIsPreloaded = true;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/SettingsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
try {
if (Services.prefs.getBoolPref("dom.apps.customization.enabled")) {
Cu.import("resource://gre/modules/UserCustomizations.jsm");
}
} catch(e) {}
Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci["nsIAppShellService"]);
Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci["nsIWindowMediator"]);

View File

@ -494,19 +494,13 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
_getNumCards: function() {
let numCards = 0;
for (let i = 0, N = _ril.numRadioInterfaces; i < N; ++i) {
if (this._isCardPresentAtClient(i)) {
if (_ril.getRadioInterface(i).isCardPresent()) {
numCards++;
}
}
return numCards;
},
_isCardPresentAtClient: function(clientId) {
let cardState = _ril.getRadioInterface(clientId).rilContext.cardState;
return cardState !== Ci.nsIIccProvider.CARD_STATE_UNDETECTED &&
cardState !== Ci.nsIIccProvider.CARD_STATE_UNKNOWN;
},
_isRadioAbleToEnableAtClient: function(clientId, numCards) {
if (!RILQUIRKS_RADIO_OFF_WO_CARD) {
return true;
@ -516,7 +510,7 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
// 1. a SIM card is presented or
// 2. it is the default clientId and there is no any SIM card at any client.
if (this._isCardPresentAtClient(clientId)) {
if (_ril.getRadioInterface(clientId).isCardPresent()) {
return true;
}
@ -1511,12 +1505,15 @@ RadioInterfaceLayer.prototype = {
},
getClientIdForEmergencyCall: function() {
// Select the client with sim card first.
for (let cid = 0; cid < this.numRadioInterfaces; ++cid) {
if (gRadioEnabledController._isRadioAbleToEnableAtClient(cid)) {
if (this.getRadioInterface(cid).isCardPresent()) {
return cid;
}
}
return -1;
// Use the defualt client if no card presents.
return HW_DEFAULT_CLIENT_ID;
},
setMicrophoneMuted: function(muted) {
@ -1824,6 +1821,12 @@ RadioInterface.prototype = {
return false;
},
isCardPresent: function() {
let cardState = this.rilContext.cardState;
return cardState !== Ci.nsIIccProvider.CARD_STATE_UNDETECTED &&
cardState !== Ci.nsIIccProvider.CARD_STATE_UNKNOWN;
},
/**
* Process a message from the content process.
*/

View File

@ -62,27 +62,17 @@ public:
}
};
class Telephony::EnumerationAck : public nsRunnable
{
nsRefPtr<Telephony> mTelephony;
public:
explicit EnumerationAck(Telephony* aTelephony)
: mTelephony(aTelephony)
{
MOZ_ASSERT(mTelephony);
}
NS_IMETHOD Run()
{
mTelephony->NotifyEvent(NS_LITERAL_STRING("ready"));
return NS_OK;
}
};
Telephony::Telephony(nsPIDOMWindow* aOwner)
: DOMEventTargetHelper(aOwner), mEnumerated(false)
: DOMEventTargetHelper(aOwner)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aOwner);
MOZ_ASSERT(global);
ErrorResult rv;
nsRefPtr<Promise> promise = Promise::Create(global, rv);
MOZ_ASSERT(!rv.Failed());
mReadyPromise = promise;
}
Telephony::~Telephony()
@ -327,6 +317,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Telephony,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCalls)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallsList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGroup)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReadyPromise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Telephony,
@ -335,6 +326,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Telephony,
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCalls)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallsList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGroup)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mReadyPromise)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Telephony)
@ -462,14 +454,16 @@ Telephony::ConferenceGroup() const
return group.forget();
}
// EventTarget
void
Telephony::EventListenerAdded(nsIAtom* aType)
already_AddRefed<Promise>
Telephony::GetReady(ErrorResult& aRv) const
{
if (aType == nsGkAtoms::onready) {
EnqueueEnumerationAck();
if (!mReadyPromise) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<Promise> promise = mReadyPromise;
return promise.forget();
}
// nsITelephonyListener
@ -548,8 +542,6 @@ Telephony::ConferenceCallStateChanged(uint16_t aCallState)
NS_IMETHODIMP
Telephony::EnumerateCallStateComplete()
{
MOZ_ASSERT(!mEnumerated);
// Set conference state.
if (mGroup->CallsArray().Length() >= 2) {
const nsTArray<nsRefPtr<TelephonyCall> > &calls = mGroup->CallsArray();
@ -565,10 +557,8 @@ Telephony::EnumerateCallStateComplete()
mGroup->ChangeState(callState);
}
mEnumerated = true;
if (NS_FAILED(NotifyEvent(NS_LITERAL_STRING("ready")))) {
NS_WARNING("Failed to notify ready!");
if (mReadyPromise) {
mReadyPromise->MaybeResolve(JS::UndefinedHandleValue);
}
if (NS_FAILED(mService->RegisterListener(mListener))) {
@ -693,19 +683,6 @@ Telephony::DispatchCallEvent(const nsAString& aType,
return DispatchTrustedEvent(event);
}
void
Telephony::EnqueueEnumerationAck()
{
if (!mEnumerated) {
return;
}
nsCOMPtr<nsIRunnable> task = new EnumerationAck(this);
if (NS_FAILED(NS_DispatchToCurrentThread(task))) {
NS_WARNING("Failed to dispatch to current thread!");
}
}
already_AddRefed<nsITelephonyService>
NS_CreateTelephonyService()
{

View File

@ -40,9 +40,7 @@ class Telephony MOZ_FINAL : public DOMEventTargetHelper,
* also bug 775997 comment #51.
*/
class Listener;
class EnumerationAck;
friend class EnumerationAck;
friend class telephony::TelephonyDialCallback;
nsCOMPtr<nsITelephonyService> mService;
@ -53,7 +51,7 @@ class Telephony MOZ_FINAL : public DOMEventTargetHelper,
nsRefPtr<TelephonyCallGroup> mGroup;
bool mEnumerated;
nsRefPtr<Promise> mReadyPromise;
public:
NS_DECL_ISUPPORTS_INHERITED
@ -109,7 +107,9 @@ public:
already_AddRefed<TelephonyCallGroup>
ConferenceGroup() const;
IMPL_EVENT_HANDLER(ready)
already_AddRefed<Promise>
GetReady(ErrorResult& aRv) const;
IMPL_EVENT_HANDLER(incoming)
IMPL_EVENT_HANDLER(callschanged)
IMPL_EVENT_HANDLER(remoteheld)
@ -146,8 +146,6 @@ public:
return mCalls;
}
virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
private:
explicit Telephony(nsPIDOMWindow* aOwner);
~Telephony();
@ -198,9 +196,6 @@ private:
nsresult
DispatchCallEvent(const nsAString& aType, TelephonyCall* aCall);
void
EnqueueEnumerationAck();
already_AddRefed<TelephonyCall>
GetCall(uint32_t aServiceId, uint32_t aCallIndex);

View File

@ -13,10 +13,10 @@ function cleanUp() {
let telephony = window.navigator.mozTelephony;
ok(telephony);
telephony.onready = function() {
log("Receive 'ready' event");
telephony.ready.then(function() {
log("Telephony got ready");
// Test registering 'ready' event in another window.
// Test telephony.ready in another window.
let iframe = document.createElement("iframe");
iframe.addEventListener("load", function load() {
iframe.removeEventListener("load", load);
@ -24,12 +24,12 @@ telephony.onready = function() {
let iframeTelephony = iframe.contentWindow.navigator.mozTelephony;
ok(iframeTelephony);
iframeTelephony.onready = function() {
log("Receive 'ready' event in iframe");
iframeTelephony.ready.then(function() {
log("Telephony in iframe got ready");
cleanUp();
};
});
});
document.body.appendChild(iframe);
};
});

View File

@ -46,8 +46,9 @@ interface Telephony : EventTarget {
readonly attribute CallsList calls;
readonly attribute TelephonyCallGroup conferenceGroup;
// The 'ready' event will be fired when the telephony object is ready.
attribute EventHandler onready;
// Async notification that object initialization is done.
[Throws]
readonly attribute Promise<void> ready;
attribute EventHandler onincoming;
attribute EventHandler oncallschanged;

View File

@ -27,7 +27,11 @@
#include <sys/syscall.h>
#include <sys/resource.h>
#include <time.h>
#if ANDROID_VERSION >= 21
#include <limits.h>
#else
#include <asm/page.h>
#endif
#include "mozilla/DebugOnly.h"

View File

@ -346,7 +346,7 @@ mozJSSubScriptLoader::DoLoadSubScriptWithOptions(const nsAString &url,
return ReportError(cx, LOAD_ERROR_NOSCHEME, uri);
}
if (!scheme.EqualsLiteral("chrome")) {
if (!scheme.EqualsLiteral("chrome") && !scheme.EqualsLiteral("app")) {
// This might be a URI to a local file, though!
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(uri);
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(innerURI);

View File

@ -251,6 +251,8 @@ user_pref("browser.aboutHomeSnippets.updateUrl", "nonexistent://test");
// Enable debug logging in the mozApps implementation.
user_pref("dom.mozApps.debug", true);
// Enable apps customizations
user_pref("dom.apps.customization.enabled", true);
// Don't fetch or send directory tiles data from real servers
user_pref("browser.newtabpage.directory.source", 'data:application/json,{"testing":1}');

View File

@ -353,6 +353,13 @@ SpecialPowersObserverAPI.prototype = {
let val = Webapps.DOMApplicationRegistry.allAppsLaunchable;
Webapps.DOMApplicationRegistry.allAppsLaunchable = aMessage.json.launchable;
return val;
case "allow-unsigned-addons":
{
let utils = {};
Components.utils.import("resource://gre/modules/AppsUtils.jsm", utils);
utils.AppsUtils.allowUnsignedAddons = true;
return;
}
default:
throw new SpecialPowersException("Invalid operation for SPWebAppsService");
}

View File

@ -1099,6 +1099,13 @@ SpecialPowersAPI.prototype = {
});
},
// Allow tests to install addons without signing the package, for convenience.
allowUnsignedAddons: function() {
this._sendSyncMessage("SPWebAppService", {
op: "allow-unsigned-addons"
});
},
// Restore the launchable property to its default value.
flushAllAppsLaunchable: function() {
this._sendSyncMessage("SPWebAppService", {