mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
e7fb1af512
@ -155,9 +155,10 @@ let AdbController = {
|
||||
// If USB Mass Storage, USB tethering, or a debug session is active,
|
||||
// then we don't want to disable adb in an automatic fashion (i.e.
|
||||
// when the screen locks or due to timeout).
|
||||
let sysUsbConfig = libcutils.property_get("sys.usb.config");
|
||||
let rndisActive = (sysUsbConfig.split(",").indexOf("rndis") >= 0);
|
||||
let usbFuncActive = rndisActive || this.umsActive || isDebugging;
|
||||
let sysUsbConfig = libcutils.property_get("sys.usb.config").split(",");
|
||||
let usbFuncActive = this.umsActive || isDebugging;
|
||||
usbFuncActive |= (sysUsbConfig.indexOf("rndis") >= 0);
|
||||
usbFuncActive |= (sysUsbConfig.indexOf("mtp") >= 0);
|
||||
|
||||
let enableAdb = this.remoteDebuggerEnabled &&
|
||||
(!(this.lockEnabled && this.locked) || usbFuncActive);
|
||||
@ -216,7 +217,6 @@ let AdbController = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
SettingsListener.observe("lockscreen.locked", false,
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -133,7 +133,7 @@
|
||||
<project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>
|
||||
<project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/>
|
||||
<project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/>
|
||||
<project name="kernel/common" path="kernel" revision="310657b79caae2c89e6375a4185fe35fde089c39"/>
|
||||
<project name="kernel/common" path="kernel" revision="291a7d55be6b0117786bf4d25366186c301185c2"/>
|
||||
<project name="platform/system/core" path="system/core" revision="53d584d4a4b4316e4de9ee5f210d662f89b44e7e"/>
|
||||
<project name="u-boot" path="u-boot" revision="982c1fd67b89d5573317c1796cf5b0143de44e8a"/>
|
||||
<project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="6974f8e771d4d8e910357a6739ab124768891e8f"/>
|
||||
|
@ -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="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</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="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -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="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -132,7 +132,7 @@
|
||||
<!-- Flame specific things -->
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
|
||||
<project name="device/qcom/common" path="device/qcom/common" revision="54c32c2ddef066fbdf611d29e4b7c47e0363599e"/>
|
||||
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="05aa7b98d3f891b334031dc710d48d0d6b82ec1d"/>
|
||||
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="dbd93c93782c9aa2306b909acdfb6ded15d49022"/>
|
||||
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="3c4f041e3e3dc676f2111caf20a186ec0467dbdb"/>
|
||||
<project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="fda40423ffa573dc6cafd3780515010cb2a086be"/>
|
||||
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="30b96dfca99cb384bf520a16b81f3aba56f09907"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</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="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "e7679f24177bc939b159dd075085352229a4b709",
|
||||
"revision": "b508914e27b34f26949fddbe8963fde897ae2268",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,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="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -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="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</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="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
|
||||
|
@ -17,7 +17,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="d893a9b971a0f3ee48e5a57dca516837d92cf52b"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -1761,3 +1761,6 @@ pref("experiments.supported", true);
|
||||
pref("media.gmp-gmpopenh264.provider.enabled", true);
|
||||
|
||||
pref("browser.apps.URL", "https://marketplace.firefox.com/discovery/");
|
||||
|
||||
pref("browser.polaris.enabled", false);
|
||||
pref("privacy.trackingprotection.ui.enabled", false);
|
||||
|
@ -74,3 +74,13 @@ tabpanels {
|
||||
browser[pending] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
browser[pendingpaint] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
tabbrowser[pendingpaint] {
|
||||
background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
|
@ -136,6 +136,10 @@
|
||||
""
|
||||
</field>
|
||||
|
||||
<field name="_contentWaitingCount">
|
||||
0
|
||||
</field>
|
||||
|
||||
<property name="_numPinnedTabs" readonly="true">
|
||||
<getter><![CDATA[
|
||||
for (var i = 0; i < this.tabs.length; i++) {
|
||||
@ -3238,6 +3242,31 @@
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_showBusySpinnerRemoteBrowser">
|
||||
<parameter name="aBrowser"/>
|
||||
<body><![CDATA[
|
||||
aBrowser.setAttribute("pendingpaint", "true");
|
||||
if (this._contentWaitingCount <= 0) {
|
||||
// We are not currently spinning
|
||||
this.setAttribute("pendingpaint", "true");
|
||||
this._contentWaitingCount = 1;
|
||||
} else {
|
||||
this._contentWaitingCount++;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_hideBusySpinnerRemoteBrowser">
|
||||
<parameter name="aBrowser"/>
|
||||
<body><![CDATA[
|
||||
aBrowser.removeAttribute("pendingpaint");
|
||||
this._contentWaitingCount--;
|
||||
if (this._contentWaitingCount <= 0) {
|
||||
this.removeAttribute("pendingpaint");
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_prepareForTabSwitch">
|
||||
<parameter name="toTab"/>
|
||||
<parameter name="fromTab"/>
|
||||
@ -3276,16 +3305,19 @@
|
||||
|
||||
let timeoutPromise = new Promise((aResolve, aReject) => {
|
||||
timeoutId = setTimeout(() => {
|
||||
this._showBusySpinnerRemoteBrowser(toBrowser);
|
||||
attemptTabSwitch(aResolve, aReject);
|
||||
}, kTabSwitchTimeout);
|
||||
});
|
||||
|
||||
let paintPromise = new Promise((aResolve, aReject) => {
|
||||
toBrowser.addEventListener("MozAfterRemotePaint", function onRemotePaint() {
|
||||
let onRemotePaint = () => {
|
||||
toBrowser.removeEventListener("MozAfterRemotePaint", onRemotePaint);
|
||||
this._hideBusySpinnerRemoteBrowser(toBrowser);
|
||||
clearTimeout(timeoutId);
|
||||
attemptTabSwitch(aResolve, aReject);
|
||||
});
|
||||
};
|
||||
toBrowser.addEventListener("MozAfterRemotePaint", onRemotePaint);
|
||||
toBrowser.QueryInterface(Ci.nsIFrameLoaderOwner)
|
||||
.frameLoader
|
||||
.requestNotifyAfterRemotePaint();
|
||||
|
@ -203,7 +203,7 @@ let LoopCallsInternal = {
|
||||
// Make the call to get the GUEST session regardless of whether the FXA
|
||||
// request fails.
|
||||
|
||||
if (channelID == LoopCalls.channelIDs.FxA && MozLoopService.userProfile) {
|
||||
if (channelID == MozLoopService.channelIDs.callsFxA && MozLoopService.userProfile) {
|
||||
this._getCalls(LOOP_SESSION_TYPE.FXA, version);
|
||||
} else {
|
||||
this._getCalls(LOOP_SESSION_TYPE.GUEST, version);
|
||||
@ -320,12 +320,6 @@ Object.freeze(LoopCallsInternal);
|
||||
* Public API
|
||||
*/
|
||||
this.LoopCalls = {
|
||||
// Channel ids that will be registered with the PushServer for notifications
|
||||
channelIDs: {
|
||||
FxA: "25389583-921f-4169-a426-a4673658944b",
|
||||
Guest: "801f754b-686b-43ec-bd83-1419bbf58388",
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback from MozLoopPushHandler - A push notification has been received from
|
||||
* the server.
|
||||
|
@ -5,21 +5,166 @@
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["LoopRooms"];
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "MozLoopService",
|
||||
"resource:///modules/loop/MozLoopService.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LOOP_SESSION_TYPE",
|
||||
"resource:///modules/loop/MozLoopService.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "MozLoopPushHandler",
|
||||
"resource:///modules/loop/MozLoopPushHandler.jsm");
|
||||
|
||||
/**
|
||||
* Public Loop Rooms API
|
||||
*/
|
||||
this.LoopRooms = Object.freeze({
|
||||
// Channel ids that will be registered with the PushServer for notifications
|
||||
channelIDs: {
|
||||
FxA: "6add272a-d316-477c-8335-f00f73dfde71",
|
||||
Guest: "19d3f799-a8f3-4328-9822-b7cd02765832",
|
||||
// Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
|
||||
XPCOMUtils.defineLazyGetter(this, "log", () => {
|
||||
let ConsoleAPI = Cu.import("resource://gre/modules/devtools/Console.jsm", {}).ConsoleAPI;
|
||||
let consoleOptions = {
|
||||
maxLogLevel: Services.prefs.getCharPref(PREF_LOG_LEVEL).toLowerCase(),
|
||||
prefix: "Loop",
|
||||
};
|
||||
return new ConsoleAPI(consoleOptions);
|
||||
});
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["LoopRooms", "roomsPushNotification"];
|
||||
|
||||
let gRoomsListFetched = false;
|
||||
let gRooms = new Map();
|
||||
|
||||
/**
|
||||
* Callback used to indicate changes to rooms data on the LoopServer.
|
||||
*
|
||||
* @param {Object} version Version number assigned to this change set.
|
||||
* @param {Object} channelID Notification channel identifier.
|
||||
*
|
||||
*/
|
||||
const roomsPushNotification = function(version, channelID) {
|
||||
return LoopRoomsInternal.onNotification(version, channelID);
|
||||
};
|
||||
|
||||
let LoopRoomsInternal = {
|
||||
getAll: function(callback) {
|
||||
Task.spawn(function*() {
|
||||
yield MozLoopService.register();
|
||||
|
||||
if (gRoomsListFetched) {
|
||||
callback(null, [...gRooms.values()]);
|
||||
return;
|
||||
}
|
||||
// Fetch the rooms from the server.
|
||||
let sessionType = MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA :
|
||||
LOOP_SESSION_TYPE.GUEST;
|
||||
let rooms = yield this.requestRoomList(sessionType);
|
||||
// Add each room to our in-memory Map using a locally unique
|
||||
// identifier.
|
||||
for (let room of rooms) {
|
||||
let id = MozLoopService.generateLocalID();
|
||||
room.localRoomID = id;
|
||||
// Next, request the detailed information for each room.
|
||||
// If the request fails the room data will not be added to the map.
|
||||
try {
|
||||
let details = yield this.requestRoomDetails(room.roomToken, sessionType);
|
||||
for (let attr in details) {
|
||||
room[attr] = details[attr]
|
||||
}
|
||||
gRooms.set(id, room);
|
||||
}
|
||||
catch (error) {log.warn("failed GETing room details for roomToken = " + room.roomToken + ": ", error)}
|
||||
}
|
||||
callback(null, [...gRooms.values()]);
|
||||
return;
|
||||
}.bind(this)).catch((error) => {log.error("getAll error:", error);
|
||||
callback(error)});
|
||||
return;
|
||||
},
|
||||
|
||||
getRoomData: function(roomID, callback) {
|
||||
if (gRooms.has(roomID)) {
|
||||
callback(null, gRooms.get(roomID));
|
||||
} else {
|
||||
callback(new Error("Room data not found or not fetched yet for room with ID " + roomID));
|
||||
}
|
||||
return;
|
||||
},
|
||||
|
||||
/**
|
||||
* Request list of all rooms associated with this account.
|
||||
*
|
||||
* @param {String} sessionType Indicates which hawkRequest endpoint to use.
|
||||
*
|
||||
* @returns {Promise} room list
|
||||
*/
|
||||
requestRoomList: function(sessionType) {
|
||||
return MozLoopService.hawkRequest(sessionType, "/rooms", "GET")
|
||||
.then(response => {
|
||||
let roomsList = JSON.parse(response.body);
|
||||
if (!Array.isArray(roomsList)) {
|
||||
// Force a reject in the returned promise.
|
||||
// To be caught by the caller using the returned Promise.
|
||||
throw new Error("Missing array of rooms in response.");
|
||||
}
|
||||
return roomsList;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Request information about a specific room from the server.
|
||||
*
|
||||
* @param {Object} token Room identifier returned from the LoopServer.
|
||||
* @param {String} sessionType Indicates which hawkRequest endpoint to use.
|
||||
*
|
||||
* @returns {Promise} room details
|
||||
*/
|
||||
requestRoomDetails: function(token, sessionType) {
|
||||
return MozLoopService.hawkRequest(sessionType, "/rooms/" + token, "GET")
|
||||
.then(response => JSON.parse(response.body));
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback used to indicate changes to rooms data on the LoopServer.
|
||||
*
|
||||
* @param {Object} version Version number assigned to this change set.
|
||||
* @param {Object} channelID Notification channel identifier.
|
||||
*
|
||||
*/
|
||||
onNotification: function(version, channelID) {
|
||||
return;
|
||||
},
|
||||
});
|
||||
};
|
||||
Object.freeze(LoopRoomsInternal);
|
||||
|
||||
/**
|
||||
* The LoopRooms class.
|
||||
*
|
||||
* Each method that is a member of this class requires the last argument to be a
|
||||
* callback Function. MozLoopAPI will cause things to break if this invariant is
|
||||
* violated. You'll notice this as well in the documentation for each method.
|
||||
*/
|
||||
this.LoopRooms = {
|
||||
/**
|
||||
* Fetch a list of rooms that the currently registered user is a member of.
|
||||
*
|
||||
* @param {Function} callback Function that will be invoked once the operation
|
||||
* finished. The first argument passed will be an
|
||||
* `Error` object or `null`. The second argument will
|
||||
* be the list of rooms, if it was fetched successfully.
|
||||
*/
|
||||
getAll: function(callback) {
|
||||
return LoopRoomsInternal.getAll(callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the current stored version of the data for the indicated room.
|
||||
*
|
||||
* @param {String} roomID Local room identifier
|
||||
* @param {Function} callback Function that will be invoked once the operation
|
||||
* finished. The first argument passed will be an
|
||||
* `Error` object or `null`. The second argument will
|
||||
* be the list of rooms, if it was fetched successfully.
|
||||
*/
|
||||
getRoomData: function(roomID, callback) {
|
||||
return LoopRoomsInternal.getRoomData(roomID, callback);
|
||||
},
|
||||
};
|
||||
Object.freeze(LoopRooms);
|
||||
|
||||
|
@ -11,6 +11,8 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/loop/LoopCalls.jsm");
|
||||
Cu.import("resource:///modules/loop/MozLoopService.jsm");
|
||||
Cu.import("resource:///modules/loop/LoopRooms.jsm");
|
||||
Cu.import("resource:///modules/loop/LoopContacts.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LoopContacts",
|
||||
"resource:///modules/loop/LoopContacts.jsm");
|
||||
@ -124,6 +126,7 @@ function injectLoopAPI(targetWindow) {
|
||||
let ringerStopper;
|
||||
let appVersionInfo;
|
||||
let contactsAPI;
|
||||
let roomsAPI;
|
||||
|
||||
let api = {
|
||||
/**
|
||||
@ -245,6 +248,21 @@ function injectLoopAPI(targetWindow) {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the rooms API.
|
||||
*
|
||||
* @returns {Object} The rooms API object
|
||||
*/
|
||||
rooms: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
if (roomsAPI) {
|
||||
return roomsAPI;
|
||||
}
|
||||
return roomsAPI = injectObjectAPI(LoopRooms, targetWindow);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Import a list of (new) contacts from an external data source.
|
||||
*
|
||||
|
@ -71,6 +71,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "LoopCalls",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LoopRooms",
|
||||
"resource:///modules/loop/LoopRooms.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "roomsPushNotification",
|
||||
"resource:///modules/loop/LoopRooms.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "MozLoopPushHandler",
|
||||
"resource:///modules/loop/MozLoopPushHandler.jsm");
|
||||
|
||||
@ -342,17 +345,18 @@ let MozLoopServiceInternal = {
|
||||
let options = mockWebSocket ? {mockWebSocket: mockWebSocket} : {};
|
||||
gPushHandler.initialize(options);
|
||||
|
||||
let callsRegGuest = registerForNotification(LoopCalls.channelIDs.Guest,
|
||||
let callsRegGuest = registerForNotification(MozLoopService.channelIDs.callsGuest,
|
||||
LoopCalls.onNotification);
|
||||
|
||||
let roomsRegGuest = registerForNotification(LoopRooms.channelIDs.Guest,
|
||||
LoopRooms.onNotification);
|
||||
|
||||
let callsRegFxA = registerForNotification(LoopCalls.channelIDs.FxA,
|
||||
|
||||
let roomsRegGuest = registerForNotification(MozLoopService.channelIDs.roomsGuest,
|
||||
roomsPushNotification);
|
||||
|
||||
let callsRegFxA = registerForNotification(MozLoopService.channelIDs.callsFxA,
|
||||
LoopCalls.onNotification);
|
||||
|
||||
let roomsRegFxA = registerForNotification(MozLoopService.channelIDs.roomsFxA,
|
||||
roomsPushNotification);
|
||||
|
||||
let roomsRegFxA = registerForNotification(LoopRooms.channelIDs.FxA,
|
||||
LoopRooms.onNotification);
|
||||
Promise.all([callsRegGuest, roomsRegGuest, callsRegFxA, roomsRegFxA])
|
||||
.then((pushUrls) => {
|
||||
return this.registerWithLoopServer(LOOP_SESSION_TYPE.GUEST,
|
||||
@ -516,7 +520,13 @@ let MozLoopServiceInternal = {
|
||||
* @return {Promise}
|
||||
*/
|
||||
registerWithLoopServer: function(sessionType, pushUrls, retry = true) {
|
||||
return this.hawkRequest(sessionType, "/registration", "POST", { simplePushURLs: pushUrls})
|
||||
// create a registration payload with a backwards compatible attribute (simplePushURL)
|
||||
// that will register only the calls notification.
|
||||
let msg = {
|
||||
simplePushURL: pushUrls.calls,
|
||||
simplePushURLs: pushUrls
|
||||
};
|
||||
return this.hawkRequest(sessionType, "/registration", "POST", msg)
|
||||
.then((response) => {
|
||||
// If this failed we got an invalid token. storeSessionToken rejects
|
||||
// the gRegisteredDeferred promise for us, so here we just need to
|
||||
@ -880,8 +890,8 @@ let gInitializeTimerFunc = (deferredInitialization, mockPushHandler, mockWebSock
|
||||
let registeredPromise =
|
||||
MozLoopServiceInternal.registerWithLoopServer(
|
||||
LOOP_SESSION_TYPE.FXA, {
|
||||
calls: gPushHandler.registeredChannels[LoopCalls.channelIDs.FxA],
|
||||
rooms: gPushHandler.registeredChannels[LoopRooms.channelIDs.FxA]
|
||||
calls: gPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA],
|
||||
rooms: gPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA]
|
||||
});
|
||||
registeredPromise.then(() => {
|
||||
deferredInitialization.resolve("initialized to logged-in status");
|
||||
@ -905,6 +915,17 @@ let gInitializeTimerFunc = (deferredInitialization, mockPushHandler, mockWebSock
|
||||
this.MozLoopService = {
|
||||
_DNSService: gDNSService,
|
||||
|
||||
get channelIDs() {
|
||||
// Channel ids that will be registered with the PushServer for notifications
|
||||
return {
|
||||
callsFxA: "25389583-921f-4169-a426-a4673658944b",
|
||||
callsGuest: "801f754b-686b-43ec-bd83-1419bbf58388",
|
||||
roomsFxA: "6add272a-d316-477c-8335-f00f73dfde71",
|
||||
roomsGuest: "19d3f799-a8f3-4328-9822-b7cd02765832",
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
set initializeTimerFunc(value) {
|
||||
gInitializeTimerFunc = value;
|
||||
},
|
||||
@ -1127,6 +1148,21 @@ this.MozLoopService = {
|
||||
return uuidgen.generateUUID().toString();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a new non-global id
|
||||
*
|
||||
* @param {Function} notUnique [optional] This function will be
|
||||
* applied to test the generated id for uniqueness
|
||||
* in the callers domain.
|
||||
*/
|
||||
generateLocalID: function(notUnique = ((id) => {return false})) {
|
||||
do {
|
||||
var id = Date.now().toString(36) + Math.floor((Math.random() * 4096)).toString(16);
|
||||
}
|
||||
while (notUnique(id));
|
||||
return id;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves MozLoopService "do not disturb" value.
|
||||
*
|
||||
@ -1265,8 +1301,8 @@ this.MozLoopService = {
|
||||
return tokenData;
|
||||
}).then(tokenData => {
|
||||
return gRegisteredDeferred.promise.then(Task.async(function*() {
|
||||
let callsUrl = gPushHandler.registeredChannels[LoopCalls.channelIDs.FxA],
|
||||
roomsUrl = gPushHandler.registeredChannels[LoopRooms.channelIDs.FxA];
|
||||
let callsUrl = gPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA],
|
||||
roomsUrl = gPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA];
|
||||
if (callsUrl && roomsUrl) {
|
||||
yield MozLoopServiceInternal.registerWithLoopServer(
|
||||
LOOP_SESSION_TYPE.FXA, {calls: callsUrl, rooms: roomsUrl});
|
||||
@ -1314,8 +1350,8 @@ this.MozLoopService = {
|
||||
log.debug("logOutFromFxA");
|
||||
let callsPushUrl, roomsPushUrl;
|
||||
if (gPushHandler) {
|
||||
callsPushUrl = gPushHandler.registeredChannels[LoopCalls.channelIDs.FxA];
|
||||
roomsPushUrl = gPushHandler.registeredChannels[LoopRooms.channelIDs.FxA];
|
||||
callsPushUrl = gPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA];
|
||||
roomsPushUrl = gPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA];
|
||||
}
|
||||
try {
|
||||
if (callsPushUrl) {
|
||||
|
@ -232,7 +232,9 @@ loop.Client = (function($) {
|
||||
this.mozLoop.hawkRequest(this.mozLoop.LOOP_SESSION_TYPE.FXA,
|
||||
"/calls", "POST", {
|
||||
calleeId: calleeIds,
|
||||
callType: callType
|
||||
callType: callType,
|
||||
channel: this.mozLoop.appVersionInfo ?
|
||||
this.mozLoop.appVersionInfo.channel : "unknown"
|
||||
},
|
||||
function (err, responseText) {
|
||||
if (err) {
|
||||
|
@ -619,8 +619,6 @@ loop.conversation = (function(mozL10n) {
|
||||
navigator.mozLoop.releaseCallData(callId);
|
||||
});
|
||||
|
||||
document.body.classList.add(loop.shared.utils.getTargetPlatform());
|
||||
|
||||
React.renderComponent(AppControllerView({
|
||||
localRoomStore: localRoomStore,
|
||||
store: conversationStore,
|
||||
|
@ -619,8 +619,6 @@ loop.conversation = (function(mozL10n) {
|
||||
navigator.mozLoop.releaseCallData(callId);
|
||||
});
|
||||
|
||||
document.body.classList.add(loop.shared.utils.getTargetPlatform());
|
||||
|
||||
React.renderComponent(<AppControllerView
|
||||
localRoomStore={localRoomStore}
|
||||
store={conversationStore}
|
||||
|
@ -717,8 +717,11 @@ loop.panel = (function(_, mozL10n) {
|
||||
UserIdentity({displayName: displayName}),
|
||||
AvailabilityDropdown(null)
|
||||
),
|
||||
AuthLink(null),
|
||||
SettingsDropdown(null)
|
||||
React.DOM.div({className: "signin-details"},
|
||||
AuthLink(null),
|
||||
React.DOM.div({className: "footer-signin-separator"}),
|
||||
SettingsDropdown(null)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -748,7 +751,6 @@ loop.panel = (function(_, mozL10n) {
|
||||
dispatcher: dispatcher}
|
||||
), document.querySelector("#main"));
|
||||
|
||||
document.body.classList.add(loop.shared.utils.getTargetPlatform());
|
||||
document.body.setAttribute("dir", mozL10n.getDirection());
|
||||
|
||||
// Notify the window that we've finished initalization and initial layout
|
||||
|
@ -717,8 +717,11 @@ loop.panel = (function(_, mozL10n) {
|
||||
<UserIdentity displayName={displayName} />
|
||||
<AvailabilityDropdown />
|
||||
</div>
|
||||
<AuthLink />
|
||||
<SettingsDropdown />
|
||||
<div className="signin-details">
|
||||
<AuthLink />
|
||||
<div className="footer-signin-separator" />
|
||||
<SettingsDropdown />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -748,7 +751,6 @@ loop.panel = (function(_, mozL10n) {
|
||||
dispatcher={dispatcher}
|
||||
/>, document.querySelector("#main"));
|
||||
|
||||
document.body.classList.add(loop.shared.utils.getTargetPlatform());
|
||||
document.body.setAttribute("dir", mozL10n.getDirection());
|
||||
|
||||
// Notify the window that we've finished initalization and initial layout
|
||||
|
@ -358,12 +358,6 @@ p {
|
||||
color: rgba(51, 51, 51, .5);
|
||||
}
|
||||
|
||||
.mac p,
|
||||
.windows p,
|
||||
.linux p {
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
/* Web panel */
|
||||
|
||||
.info-panel {
|
||||
|
@ -268,7 +268,7 @@ body {
|
||||
|
||||
.dropdown-menu {
|
||||
position: absolute;
|
||||
top: -28px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #fdfdfd;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.3);
|
||||
@ -345,6 +345,10 @@ body[dir=rtl] .dropdown-menu-item {
|
||||
.dnd-status {
|
||||
border: 1px solid transparent;
|
||||
padding: 2px 4px;
|
||||
margin: 0;
|
||||
/* Undo the start border + padding so that unhovered dnd-status is aligned
|
||||
as if there was no additional spacing. */
|
||||
-moz-margin-start: calc(-1px + -4px);
|
||||
font-size: .9em;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
@ -377,10 +381,7 @@ body[dir=rtl] .dropdown-menu-item {
|
||||
|
||||
.signin-link {
|
||||
flex: 2 1 auto;
|
||||
margin-top: 14px;
|
||||
border-right: 1px solid #aaa;
|
||||
padding-right: 1em;
|
||||
margin-right: 1em;
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@ -390,6 +391,12 @@ body[dir=rtl] .dropdown-menu-item {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.footer-signin-separator {
|
||||
border-right: 1px solid #aaa;
|
||||
height: 16px;
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
/* Settings (gear) menu */
|
||||
|
||||
.button-settings {
|
||||
@ -413,7 +420,6 @@ body[dir=rtl] .dropdown-menu-item {
|
||||
}
|
||||
|
||||
.footer .button-settings {
|
||||
margin-top: 17px; /* used to align the gear icon with the availability dropdown menu inner text */
|
||||
opacity: .6; /* used to "grey" the icon a little */
|
||||
}
|
||||
|
||||
@ -459,10 +465,22 @@ body[dir=rtl] .dropdown-menu-item {
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
align-content: stretch;
|
||||
align-items: flex-start;
|
||||
align-items: center;
|
||||
font-size: 1em;
|
||||
border-top: 1px solid #D1D1D1;
|
||||
background-color: #eaeaea;
|
||||
color: #7f7f7f;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.footer .signin-details {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
-moz-margin-start: 5px;
|
||||
}
|
||||
|
||||
.footer .user-identity {
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -29,26 +29,6 @@ loop.shared.utils = (function(mozL10n) {
|
||||
return date.toLocaleDateString(navigator.language, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for adding different styles to the panel
|
||||
* @returns {String} Corresponds to the client platform
|
||||
* */
|
||||
function getTargetPlatform() {
|
||||
var platform="unknown_platform";
|
||||
|
||||
if (navigator.platform.indexOf("Win") !== -1) {
|
||||
platform = "windows";
|
||||
}
|
||||
if (navigator.platform.indexOf("Mac") !== -1) {
|
||||
platform = "mac";
|
||||
}
|
||||
if (navigator.platform.indexOf("Linux") !== -1) {
|
||||
platform = "linux";
|
||||
}
|
||||
|
||||
return platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for getting a boolean preference. It will either use the browser preferences
|
||||
* (if navigator.mozLoop is defined) or try to get them from localStorage.
|
||||
@ -133,7 +113,6 @@ loop.shared.utils = (function(mozL10n) {
|
||||
Helper: Helper,
|
||||
composeCallUrlEmail: composeCallUrlEmail,
|
||||
formatDate: formatDate,
|
||||
getTargetPlatform: getTargetPlatform,
|
||||
getBoolPreference: getBoolPreference
|
||||
};
|
||||
})(document.mozL10n || navigator.mozL10n);
|
||||
|
@ -115,7 +115,7 @@ loop.StandaloneClient = (function($) {
|
||||
method: "POST",
|
||||
contentType: "application/json",
|
||||
dataType: "json",
|
||||
data: JSON.stringify({callType: callType})
|
||||
data: JSON.stringify({callType: callType, channel: "standalone"})
|
||||
});
|
||||
|
||||
req.done(function(sessionData) {
|
||||
|
@ -272,7 +272,23 @@ describe("loop.Client", function() {
|
||||
mozLoop.LOOP_SESSION_TYPE.FXA,
|
||||
"/calls",
|
||||
"POST",
|
||||
{ calleeId: calleeIds, callType: callType }
|
||||
{ calleeId: calleeIds, callType: callType, channel: "unknown" }
|
||||
);
|
||||
});
|
||||
|
||||
it("should include the channel when defined", function() {
|
||||
mozLoop.appVersionInfo = {
|
||||
channel: "beta"
|
||||
};
|
||||
|
||||
client.setupOutgoingCall(calleeIds, callType);
|
||||
|
||||
sinon.assert.calledOnce(hawkRequestStub);
|
||||
sinon.assert.calledWith(hawkRequestStub,
|
||||
mozLoop.LOOP_SESSION_TYPE.FXA,
|
||||
"/calls",
|
||||
"POST",
|
||||
{ calleeId: calleeIds, callType: callType, channel: "beta" }
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -256,8 +256,8 @@ add_task(function* basicAuthorizationAndRegistration() {
|
||||
|
||||
// Normally the same pushUrl would be registered but we change it in the test
|
||||
// to be able to check for success on the second registration.
|
||||
mockPushHandler.registeredChannels[LoopCalls.channelIDs.FxA] = "https://localhost/pushUrl/fxa-calls";
|
||||
mockPushHandler.registeredChannels[LoopRooms.channelIDs.FxA] = "https://localhost/pushUrl/fxa-rooms";
|
||||
mockPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA] = "https://localhost/pushUrl/fxa-calls";
|
||||
mockPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA] = "https://localhost/pushUrl/fxa-rooms";
|
||||
|
||||
statusChangedPromise = promiseObserverNotified("loop-status-changed");
|
||||
yield loadLoopPanel({loopURL: BASE_URL, stayOnline: true});
|
||||
@ -333,8 +333,8 @@ add_task(function* loginWithParams401() {
|
||||
add_task(function* logoutWithIncorrectPushURL() {
|
||||
yield resetFxA();
|
||||
let pushURL = "http://www.example.com/";
|
||||
mockPushHandler.registeredChannels[LoopCalls.channelIDs.FxA] = pushURL;
|
||||
mockPushHandler.registeredChannels[LoopRooms.channelIDs.FxA] = pushURL;
|
||||
mockPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA] = pushURL;
|
||||
mockPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA] = pushURL;
|
||||
|
||||
// Create a fake FxA hawk session token
|
||||
const fxASessionPref = MozLoopServiceInternal.getSessionTokenPrefName(LOOP_SESSION_TYPE.FXA);
|
||||
@ -343,7 +343,7 @@ add_task(function* logoutWithIncorrectPushURL() {
|
||||
yield MozLoopServiceInternal.registerWithLoopServer(LOOP_SESSION_TYPE.FXA, {calls: pushURL});
|
||||
let registrationResponse = yield promiseOAuthGetRegistration(BASE_URL);
|
||||
ise(registrationResponse.response.simplePushURLs.calls, pushURL, "Check registered push URL");
|
||||
mockPushHandler.registeredChannels[LoopCalls.channelIDs.FxA] = "http://www.example.com/invalid";
|
||||
mockPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA] = "http://www.example.com/invalid";
|
||||
let caught = false;
|
||||
yield MozLoopService.logOutFromFxA().catch((error) => {
|
||||
caught = true;
|
||||
@ -357,7 +357,7 @@ add_task(function* logoutWithIncorrectPushURL() {
|
||||
add_task(function* logoutWithNoPushURL() {
|
||||
yield resetFxA();
|
||||
let pushURL = "http://www.example.com/";
|
||||
mockPushHandler.registeredChannels[LoopCalls.channelIDs.FxA] = pushURL;
|
||||
mockPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA] = pushURL;
|
||||
|
||||
// Create a fake FxA hawk session token
|
||||
const fxASessionPref = MozLoopServiceInternal.getSessionTokenPrefName(LOOP_SESSION_TYPE.FXA);
|
||||
@ -366,8 +366,8 @@ add_task(function* logoutWithNoPushURL() {
|
||||
yield MozLoopServiceInternal.registerWithLoopServer(LOOP_SESSION_TYPE.FXA, {calls: pushURL});
|
||||
let registrationResponse = yield promiseOAuthGetRegistration(BASE_URL);
|
||||
ise(registrationResponse.response.simplePushURLs.calls, pushURL, "Check registered push URL");
|
||||
mockPushHandler.registeredChannels[LoopCalls.channelIDs.FxA] = null;
|
||||
mockPushHandler.registeredChannels[LoopRooms.channelIDs.FxA] = null;
|
||||
mockPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA] = null;
|
||||
mockPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA] = null;
|
||||
yield MozLoopService.logOutFromFxA();
|
||||
checkLoggedOutState();
|
||||
registrationResponse = yield promiseOAuthGetRegistration(BASE_URL);
|
||||
|
@ -128,7 +128,7 @@ describe("loop.StandaloneClient", function() {
|
||||
expect(requests).to.have.length.of(1);
|
||||
expect(requests[0].url).to.be.equal("http://fake.api/calls/fake");
|
||||
expect(requests[0].method).to.be.equal("POST");
|
||||
expect(requests[0].requestBody).to.be.equal('{"callType":"audio"}');
|
||||
expect(requests[0].requestBody).to.be.equal('{"callType":"audio","channel":"standalone"}');
|
||||
});
|
||||
|
||||
it("should receive call data for the given call", function() {
|
||||
|
@ -10,6 +10,7 @@ Cu.import("resource://testing-common/httpd.js");
|
||||
Cu.import("resource:///modules/loop/MozLoopService.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource:///modules/loop/LoopCalls.jsm");
|
||||
Cu.import("resource:///modules/loop/LoopRooms.jsm");
|
||||
const { MozLoopServiceInternal } = Cu.import("resource:///modules/loop/MozLoopService.jsm", {});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "MozLoopPushHandler",
|
||||
|
@ -35,7 +35,7 @@ add_test(function test_busy_2guest_calls() {
|
||||
opened++;
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, LoopCalls.channelIDs.Guest);
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsGuest);
|
||||
|
||||
waitForCondition(() => {return actionReceived && opened > 0}).then(() => {
|
||||
do_check_true(opened === 1, "should open only one chat window");
|
||||
@ -58,8 +58,8 @@ add_test(function test_busy_1fxa_1guest_calls() {
|
||||
opened++;
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, LoopCalls.channelIDs.FxA);
|
||||
mockPushHandler.notify(1, LoopCalls.channelIDs.Guest);
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA);
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsGuest);
|
||||
|
||||
waitForCondition(() => {return actionReceived && opened > 0}).then(() => {
|
||||
do_check_true(opened === 1, "should open only one chat window");
|
||||
@ -82,7 +82,7 @@ add_test(function test_busy_2fxa_calls() {
|
||||
opened++;
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, LoopCalls.channelIDs.FxA);
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA);
|
||||
|
||||
waitForCondition(() => {return actionReceived && opened > 0}).then(() => {
|
||||
do_check_true(opened === 1, "should open only one chat window");
|
||||
@ -105,8 +105,8 @@ add_test(function test_busy_1guest_1fxa_calls() {
|
||||
opened++;
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, LoopCalls.channelIDs.Guest);
|
||||
mockPushHandler.notify(1, LoopCalls.channelIDs.FxA);
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsGuest);
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA);
|
||||
|
||||
waitForCondition(() => {return actionReceived && opened > 0}).then(() => {
|
||||
do_check_true(opened === 1, "should open only one chat window");
|
||||
|
@ -37,7 +37,7 @@ add_test(function test_do_not_disturb_disabled_should_open_chat_window() {
|
||||
opened = true;
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, LoopCalls.channelIDs.Guest);
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsGuest);
|
||||
|
||||
waitForCondition(function() opened).then(() => {
|
||||
run_next_test();
|
||||
@ -56,7 +56,7 @@ add_test(function test_do_not_disturb_enabled_shouldnt_open_chat_window() {
|
||||
opened = true;
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, LoopCalls.channelIDs.Guest);
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsGuest);
|
||||
|
||||
do_timeout(500, function() {
|
||||
do_check_false(opened, "should not open a chat window");
|
||||
|
@ -16,7 +16,7 @@ add_test(function test_openChatWindow_on_notification() {
|
||||
opened = true;
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, LoopCalls.channelIDs.Guest);
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsGuest);
|
||||
|
||||
waitForCondition(function() opened).then(() => {
|
||||
do_check_true(opened, "should open a chat window");
|
||||
|
131
browser/components/loop/test/xpcshell/test_rooms_getdata.js
Normal file
131
browser/components/loop/test/xpcshell/test_rooms_getdata.js
Normal file
@ -0,0 +1,131 @@
|
||||
/* 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/. */
|
||||
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Chat",
|
||||
"resource:///modules/Chat.jsm");
|
||||
let hasTheseProps = function(a, b) {
|
||||
for (let prop in a) {
|
||||
if (a[prop] != b[prop]) {
|
||||
do_print("hasTheseProps fail: prop = " + prop);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
let openChatOrig = Chat.open;
|
||||
|
||||
add_test(function test_getAllRooms() {
|
||||
|
||||
let roomList = [
|
||||
{ roomToken: "_nxD4V4FflQ",
|
||||
roomName: "First Room Name",
|
||||
roomUrl: "http://localhost:3000/rooms/_nxD4V4FflQ",
|
||||
maxSize: 2,
|
||||
currSize: 0,
|
||||
ctime: 1405517546 },
|
||||
{ roomToken: "QzBbvGmIZWU",
|
||||
roomName: "Second Room Name",
|
||||
roomUrl: "http://localhost:3000/rooms/QzBbvGmIZWU",
|
||||
maxSize: 2,
|
||||
currSize: 0,
|
||||
ctime: 140551741 },
|
||||
{ roomToken: "3jKS_Els9IU",
|
||||
roomName: "Third Room Name",
|
||||
roomUrl: "http://localhost:3000/rooms/3jKS_Els9IU",
|
||||
maxSize: 3,
|
||||
clientMaxSize: 2,
|
||||
currSize: 1,
|
||||
ctime: 1405518241 }
|
||||
]
|
||||
|
||||
let roomDetail = {
|
||||
roomName: "First Room Name",
|
||||
roomUrl: "http://localhost:3000/rooms/_nxD4V4FflQ",
|
||||
roomOwner: "Alexis",
|
||||
maxSize: 2,
|
||||
clientMaxSize: 2,
|
||||
creationTime: 1405517546,
|
||||
expiresAt: 1405534180,
|
||||
participants: [
|
||||
{ displayName: "Alexis", account: "alexis@example.com", roomConnectionId: "2a1787a6-4a73-43b5-ae3e-906ec1e763cb" },
|
||||
{ displayName: "Adam", roomConnectionId: "781f012b-f1ea-4ce1-9105-7cfc36fb4ec7" }
|
||||
]
|
||||
}
|
||||
|
||||
loopServer.registerPathHandler("/rooms", (request, response) => {
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
response.write(JSON.stringify(roomList));
|
||||
response.processAsync();
|
||||
response.finish();
|
||||
});
|
||||
|
||||
let returnRoomDetails = function(response, roomName) {
|
||||
roomDetail.roomName = roomName;
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
response.write(JSON.stringify(roomDetail));
|
||||
response.processAsync();
|
||||
response.finish();
|
||||
}
|
||||
|
||||
loopServer.registerPathHandler("/rooms/_nxD4V4FflQ", (request, response) => {
|
||||
returnRoomDetails(response, "First Room Name");
|
||||
});
|
||||
|
||||
loopServer.registerPathHandler("/rooms/QzBbvGmIZWU", (request, response) => {
|
||||
returnRoomDetails(response, "Second Room Name");
|
||||
});
|
||||
|
||||
loopServer.registerPathHandler("/rooms/3jKS_Els9IU", (request, response) => {
|
||||
returnRoomDetails(response, "Third Room Name");
|
||||
});
|
||||
|
||||
MozLoopService.register(mockPushHandler).then(() => {
|
||||
|
||||
LoopRooms.getAll((error, rooms) => {
|
||||
do_check_false(error);
|
||||
do_check_true(rooms);
|
||||
do_check_eq(rooms.length, 3);
|
||||
do_check_eq(rooms[0].roomName, "First Room Name");
|
||||
do_check_eq(rooms[1].roomName, "Second Room Name");
|
||||
do_check_eq(rooms[2].roomName, "Third Room Name");
|
||||
|
||||
let room = rooms[0];
|
||||
do_check_true(room.localRoomID);
|
||||
do_check_true(hasTheseProps(roomList[0], room));
|
||||
delete roomDetail.roomName;
|
||||
delete room.participants;
|
||||
delete roomDetail.participants;
|
||||
do_check_true(hasTheseProps(roomDetail, room));
|
||||
|
||||
LoopRooms.getRoomData(room.localRoomID, (error, roomData) => {
|
||||
do_check_false(error);
|
||||
do_check_true(hasTheseProps(room, roomData));
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function run_test()
|
||||
{
|
||||
setupFakeLoopServer();
|
||||
mockPushHandler.registrationPushURL = kEndPointUrl;
|
||||
|
||||
loopServer.registerPathHandler("/registration", (request, response) => {
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
response.processAsync();
|
||||
response.finish();
|
||||
});
|
||||
|
||||
do_register_cleanup(function() {
|
||||
// Revert original Chat.open implementation
|
||||
Chat.open = openChatOrig;
|
||||
});
|
||||
|
||||
run_next_test();
|
||||
}
|
@ -21,3 +21,4 @@ skip-if = toolkit == 'gonk'
|
||||
[test_loopservice_token_send.js]
|
||||
[test_loopservice_token_validation.js]
|
||||
[test_loopservice_busy.js]
|
||||
[test_rooms_getdata.js]
|
||||
|
@ -21,5 +21,6 @@ navigator.mozLoop = {
|
||||
callback(null, []);
|
||||
},
|
||||
on: function() {}
|
||||
}
|
||||
},
|
||||
fxAEnabled: true
|
||||
};
|
||||
|
@ -537,10 +537,7 @@
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", function() {
|
||||
var body = document.body;
|
||||
body.className = loop.shared.utils.getTargetPlatform();
|
||||
|
||||
React.renderComponent(App(null), body);
|
||||
React.renderComponent(App(null), document.body);
|
||||
|
||||
_renderComponentsInIframes();
|
||||
|
||||
|
@ -537,10 +537,7 @@
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", function() {
|
||||
var body = document.body;
|
||||
body.className = loop.shared.utils.getTargetPlatform();
|
||||
|
||||
React.renderComponent(<App />, body);
|
||||
React.renderComponent(<App />, document.body);
|
||||
|
||||
_renderComponentsInIframes();
|
||||
|
||||
|
@ -52,6 +52,20 @@
|
||||
|
||||
<!-- Short Description -->
|
||||
<div id="errorTrailerDesc">
|
||||
<div>
|
||||
<div class="radioRestoreContainer">
|
||||
<input class="radioRestoreButton" id="radioRestoreAll" type="radio"
|
||||
name="restore" checked="checked"/>
|
||||
<label class="radioRestoreLabel" for="radioRestoreAll">&welcomeback2.label.restoreAll;</label>
|
||||
</div>
|
||||
|
||||
<div class="radioRestoreContainer">
|
||||
<input class="radioRestoreButton" id="radioRestoreChoose" type="radio"
|
||||
name="restore"/>
|
||||
<label class="radioRestoreLabel" for="radioRestoreChoose">&welcomeback2.label.restoreSome;</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<tree xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="tabList" flex="1" seltype="single" hidecolumnpicker="true"
|
||||
onclick="onListClick(event);" onkeydown="onListKeyDown(event);"
|
||||
|
@ -9,6 +9,7 @@ const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const POLARIS_ENABLED = "browser.polaris.enabled";
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
@ -397,6 +398,13 @@ BrowserGlue.prototype = {
|
||||
Services.obs.removeObserver(this, "browser-search-service");
|
||||
this._syncSearchEngines();
|
||||
break;
|
||||
case "nsPref:changed":
|
||||
if (data == POLARIS_ENABLED) {
|
||||
let enabled = Services.prefs.getBoolPref(POLARIS_ENABLED);
|
||||
Services.prefs.setBoolPref("privacy.donottrackheader.enabled", enabled);
|
||||
Services.prefs.setBoolPref("privacy.trackingprotection.enabled", enabled);
|
||||
Services.prefs.setBoolPref("privacy.trackingprotection.ui.enabled", enabled);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -443,6 +451,9 @@ BrowserGlue.prototype = {
|
||||
#endif
|
||||
os.addObserver(this, "browser-search-engine-modified", false);
|
||||
os.addObserver(this, "browser-search-service", false);
|
||||
#ifdef NIGHTLY_BUILD
|
||||
Services.prefs.addObserver(POLARIS_ENABLED, this, false);
|
||||
#endif
|
||||
},
|
||||
|
||||
// cleanup (called on application shutdown)
|
||||
@ -483,6 +494,9 @@ BrowserGlue.prototype = {
|
||||
os.removeObserver(this, "browser-search-service");
|
||||
// may have already been removed by the observer
|
||||
} catch (ex) {}
|
||||
#ifdef NIGHTLY_BUILD
|
||||
Services.prefs.removeObserver(POLARIS_ENABLED, this);
|
||||
#endif
|
||||
},
|
||||
|
||||
_onAppDefaults: function BG__onAppDefaults() {
|
||||
|
@ -20,6 +20,14 @@ window.onload = function() {
|
||||
anchor.setAttribute("href", baseURL + "troubleshooting");
|
||||
}
|
||||
|
||||
// wire up click handlers for the radio buttons if they exist.
|
||||
for (let radioId of ["radioRestoreAll", "radioRestoreChoose"]) {
|
||||
let button = document.getElementById(radioId);
|
||||
if (button) {
|
||||
button.addEventListener("click", updateTabListVisibility);
|
||||
}
|
||||
}
|
||||
|
||||
// the crashed session state is kept inside a textbox so that SessionStore picks it up
|
||||
// (for when the tab is closed or the session crashes right again)
|
||||
var sessionData = document.getElementById("sessionData");
|
||||
@ -40,7 +48,17 @@ window.onload = function() {
|
||||
document.getElementById("errorTryAgain").focus();
|
||||
};
|
||||
|
||||
function isTreeViewVisible() {
|
||||
let tabList = document.getElementById("tabList");
|
||||
return tabList.hasAttribute("available");
|
||||
}
|
||||
|
||||
function initTreeView() {
|
||||
// If we aren't visible we initialize as we are made visible (and it's OK
|
||||
// to initialize multiple times)
|
||||
if (!isTreeViewVisible()) {
|
||||
return;
|
||||
}
|
||||
var tabList = document.getElementById("tabList");
|
||||
var winLabel = tabList.getAttribute("_window_label");
|
||||
|
||||
@ -75,31 +93,42 @@ function initTreeView() {
|
||||
}
|
||||
|
||||
// User actions
|
||||
function updateTabListVisibility() {
|
||||
let tabList = document.getElementById("tabList");
|
||||
if (document.getElementById("radioRestoreChoose").checked) {
|
||||
tabList.setAttribute("available", "true");
|
||||
} else {
|
||||
tabList.removeAttribute("available");
|
||||
}
|
||||
initTreeView();
|
||||
}
|
||||
|
||||
function restoreSession() {
|
||||
document.getElementById("errorTryAgain").disabled = true;
|
||||
|
||||
if (!gTreeData.some(aItem => aItem.checked)) {
|
||||
// This should only be possible when we have no "cancel" button, and thus
|
||||
// the "Restore session" button always remains enabled. In that case and
|
||||
// when nothing is selected, we just want a new session.
|
||||
startNewSession();
|
||||
return;
|
||||
}
|
||||
if (isTreeViewVisible()) {
|
||||
if (!gTreeData.some(aItem => aItem.checked)) {
|
||||
// This should only be possible when we have no "cancel" button, and thus
|
||||
// the "Restore session" button always remains enabled. In that case and
|
||||
// when nothing is selected, we just want a new session.
|
||||
startNewSession();
|
||||
return;
|
||||
}
|
||||
|
||||
// remove all unselected tabs from the state before restoring it
|
||||
var ix = gStateObject.windows.length - 1;
|
||||
for (var t = gTreeData.length - 1; t >= 0; t--) {
|
||||
if (treeView.isContainer(t)) {
|
||||
if (gTreeData[t].checked === 0)
|
||||
// this window will be restored partially
|
||||
gStateObject.windows[ix].tabs =
|
||||
gStateObject.windows[ix].tabs.filter(function(aTabData, aIx)
|
||||
gTreeData[t].tabs[aIx].checked);
|
||||
else if (!gTreeData[t].checked)
|
||||
// this window won't be restored at all
|
||||
gStateObject.windows.splice(ix, 1);
|
||||
ix--;
|
||||
// remove all unselected tabs from the state before restoring it
|
||||
var ix = gStateObject.windows.length - 1;
|
||||
for (var t = gTreeData.length - 1; t >= 0; t--) {
|
||||
if (treeView.isContainer(t)) {
|
||||
if (gTreeData[t].checked === 0)
|
||||
// this window will be restored partially
|
||||
gStateObject.windows[ix].tabs =
|
||||
gStateObject.windows[ix].tabs.filter(function(aTabData, aIx)
|
||||
gTreeData[t].tabs[aIx].checked);
|
||||
else if (!gTreeData[t].checked)
|
||||
// this window won't be restored at all
|
||||
gStateObject.windows.splice(ix, 1);
|
||||
ix--;
|
||||
}
|
||||
}
|
||||
}
|
||||
var stateString = JSON.stringify(gStateObject);
|
||||
|
@ -57,7 +57,7 @@
|
||||
<tree xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="tabList" flex="1" seltype="single" hidecolumnpicker="true"
|
||||
onclick="onListClick(event);" onkeydown="onListKeyDown(event);"
|
||||
_window_label="&restorepage.windowLabel;">
|
||||
available="true" _window_label="&restorepage.windowLabel;">
|
||||
<treecols>
|
||||
<treecol cycler="true" id="restore" type="checkbox" label="&restorepage.restoreHeader;"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
|
@ -2,3 +2,5 @@
|
||||
|
||||
[browser_bug538331.js]
|
||||
skip-if = e10s # Bug ?????? - child process crash, but only when run as part of the suite (ie, probably not actually this tests fault!?)
|
||||
|
||||
[browser_polaris_prefs.js]
|
||||
|
57
browser/components/test/browser_polaris_prefs.js
Normal file
57
browser/components/test/browser_polaris_prefs.js
Normal file
@ -0,0 +1,57 @@
|
||||
const POLARIS_ENABLED = "browser.polaris.enabled";
|
||||
const PREF_DNT = "privacy.donottrackheader.enabled";
|
||||
const PREF_TP = "privacy.trackingprotection.enabled";
|
||||
const PREF_TPUI = "privacy.trackingprotection.ui.enabled";
|
||||
|
||||
let prefs = [PREF_DNT, PREF_TP, PREF_TPUI];
|
||||
|
||||
function spinEventLoop() {
|
||||
return new Promise((resolve) => executeSoon(resolve));
|
||||
};
|
||||
|
||||
// Spin event loop before checking so that polaris pref observer can set
|
||||
// dependent prefs.
|
||||
function* assertPref(pref, enabled) {
|
||||
yield spinEventLoop();
|
||||
let prefEnabled = Services.prefs.getBoolPref(pref);
|
||||
Assert.equal(prefEnabled, enabled, "Checking state of pref " + pref + ".");
|
||||
};
|
||||
|
||||
function* testPrefs(test) {
|
||||
for (let pref of prefs) {
|
||||
yield test(pref);
|
||||
}
|
||||
}
|
||||
|
||||
add_task(function* test_default_values() {
|
||||
Assert.ok(!Services.prefs.getBoolPref(POLARIS_ENABLED), POLARIS_ENABLED + " is disabled by default.");
|
||||
Assert.ok(!Services.prefs.getBoolPref(PREF_TPUI), PREF_TPUI + "is disabled by default.");
|
||||
});
|
||||
|
||||
add_task(function* test_changing_pref_changes_tracking() {
|
||||
function* testPref(pref) {
|
||||
Services.prefs.setBoolPref(POLARIS_ENABLED, true);
|
||||
yield assertPref(pref, true);
|
||||
Services.prefs.setBoolPref(POLARIS_ENABLED, false);
|
||||
yield assertPref(pref, false);
|
||||
Services.prefs.setBoolPref(POLARIS_ENABLED, true);
|
||||
yield assertPref(pref, true);
|
||||
}
|
||||
yield testPrefs(testPref);
|
||||
});
|
||||
|
||||
add_task(function* test_prefs_can_be_changed_individually() {
|
||||
function* testPref(pref) {
|
||||
Services.prefs.setBoolPref(POLARIS_ENABLED, true);
|
||||
yield assertPref(pref, true);
|
||||
Services.prefs.setBoolPref(pref, false);
|
||||
yield assertPref(pref, false);
|
||||
yield assertPref(POLARIS_ENABLED, true);
|
||||
Services.prefs.setBoolPref(POLARIS_ENABLED, false);
|
||||
yield assertPref(pref, false);
|
||||
Services.prefs.setBoolPref(pref, true);
|
||||
yield assertPref(pref, true);
|
||||
yield assertPref(POLARIS_ENABLED, false);
|
||||
}
|
||||
yield testPrefs(testPref);
|
||||
});
|
@ -45,6 +45,8 @@ skip-if = true # Bug 1047124
|
||||
skip-if = true # Bug 1047124
|
||||
[browser_profiler_recording-selected-02.js]
|
||||
skip-if = true # Bug 1047124
|
||||
[browser_profiler_recording-selected-03.js]
|
||||
skip-if = true # Bug 1047124
|
||||
[browser_profiler_recording-utils.js]
|
||||
skip-if = true # Bug 1047124
|
||||
[browser_profiler_recordings-clear.js]
|
||||
|
@ -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/ */
|
||||
|
||||
/**
|
||||
* Tests if the profiler UI does not forget that recording is active when
|
||||
* selected recording changes. Bug 1060885.
|
||||
*/
|
||||
|
||||
let test = Task.async(function*() {
|
||||
let [target, debuggee, panel] = yield initFrontend(SIMPLE_URL);
|
||||
let { $, EVENTS, RecordingsListView, ProfileView } = panel.panelWin;
|
||||
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel, { waitForDisplay: true });
|
||||
|
||||
yield startRecording(panel);
|
||||
yield stopRecording(panel, { waitForDisplay: true });
|
||||
|
||||
yield startRecording(panel);
|
||||
|
||||
info("Selecting recording #0 and waiting for it to be displayed.");
|
||||
let selected = panel.panelWin.once(EVENTS.RECORDING_DISPLAYED);
|
||||
RecordingsListView.selectedIndex = 0;
|
||||
yield selected;
|
||||
|
||||
ok($("#record-button").hasAttribute("checked"),
|
||||
"Button is still checked after selecting another item.");
|
||||
|
||||
ok(!$("#record-button").hasAttribute("locked"),
|
||||
"Button is not locked after selecting another item.");
|
||||
|
||||
yield teardown(panel);
|
||||
finish();
|
||||
});
|
@ -150,9 +150,10 @@ function* stopRecording(panel, { waitForDisplay }) {
|
||||
|
||||
if (waitForDisplay) {
|
||||
yield displayed;
|
||||
|
||||
ok(!button.hasAttribute("checked"),
|
||||
"The record button should not be checked anymore.");
|
||||
if (!win.RecordingsListView.getItemForPredicate(e => e.isRecording)) {
|
||||
ok(!button.hasAttribute("checked"),
|
||||
"The record button should not be checked anymore.");
|
||||
}
|
||||
ok(!button.hasAttribute("locked"),
|
||||
"The record button should not be locked anymore.");
|
||||
}
|
||||
|
@ -202,7 +202,12 @@ let RecordingsListView = Heritage.extend(WidgetMethods, {
|
||||
yield ProfileView.addTabAndPopulate(recordingData, 0, durationMillis);
|
||||
ProfileView.showTabbedBrowser();
|
||||
|
||||
$("#record-button").removeAttribute("checked");
|
||||
// Only clear the checked state if there's nothing recording.
|
||||
if (!this.getItemForPredicate(e => e.isRecording)) {
|
||||
$("#record-button").removeAttribute("checked");
|
||||
}
|
||||
|
||||
// But don't leave it locked in any case.
|
||||
$("#record-button").removeAttribute("locked");
|
||||
|
||||
window.emit(EVENTS.RECORDING_DISPLAYED);
|
||||
|
@ -6,7 +6,6 @@ const Cu = Components.utils;
|
||||
Cu.import('resource:///modules/devtools/gDevTools.jsm');
|
||||
const {require} = Cu.import('resource://gre/modules/devtools/Loader.jsm', {}).devtools;
|
||||
const {Services} = Cu.import('resource://gre/modules/Services.jsm');
|
||||
const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm");
|
||||
const {AppManager} = require('devtools/webide/app-manager');
|
||||
const {AppActorFront} = require('devtools/app-actor-front');
|
||||
const {Connection} = require('devtools/client/connection-manager');
|
||||
@ -227,8 +226,7 @@ let Monitor = {
|
||||
*/
|
||||
pollB2GInfo: function() {
|
||||
if (AppManager.selectedRuntime) {
|
||||
let id = AppManager.selectedRuntime.id;
|
||||
let device = Devices.getByName(id);
|
||||
let device = AppManager.selectedRuntime.device;
|
||||
if (device && device.shell) {
|
||||
device.shell('b2g-info').then(s => {
|
||||
let lines = s.split('\n');
|
||||
|
@ -35,12 +35,6 @@
|
||||
<input data-pref="devtools.webide.templatesURL"/>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label title="&prefs_options_enablelocalruntime_tooltip;">
|
||||
<input type="checkbox" data-pref="devtools.webide.enableLocalRuntime"/>
|
||||
<span>&prefs_options_enablelocalruntime;</span>
|
||||
</label>
|
||||
</li>
|
||||
<li>
|
||||
<label title="&prefs_options_rememberlastproject_tooltip;">
|
||||
<input type="checkbox" data-pref="devtools.webide.restoreLastProject"/>
|
||||
|
@ -7,8 +7,7 @@ const {Services} = Cu.import("resource://gre/modules/Services.jsm");
|
||||
const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
|
||||
const {AppManager} = require("devtools/webide/app-manager");
|
||||
const {Connection} = require("devtools/client/connection-manager");
|
||||
const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm");
|
||||
const {USBRuntime} = require("devtools/webide/runtimes");
|
||||
const {RuntimeTypes} = require("devtools/webide/runtimes");
|
||||
const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
|
||||
|
||||
window.addEventListener("load", function onLoad() {
|
||||
@ -86,8 +85,8 @@ function CheckLockState() {
|
||||
AppManager.connection.status == Connection.Status.CONNECTED) {
|
||||
|
||||
// ADB check
|
||||
if (AppManager.selectedRuntime instanceof USBRuntime) {
|
||||
let device = Devices.getByName(AppManager.selectedRuntime.id);
|
||||
if (AppManager.selectedRuntime.type === RuntimeTypes.USB) {
|
||||
let device = AppManager.selectedRuntime.device;
|
||||
if (device && device.summonRoot) {
|
||||
device.isRoot().then(isRoot => {
|
||||
if (isRoot) {
|
||||
@ -127,16 +126,16 @@ function CheckLockState() {
|
||||
}
|
||||
|
||||
function EnableCertApps() {
|
||||
let device = Devices.getByName(AppManager.selectedRuntime.id);
|
||||
let device = AppManager.selectedRuntime.device;
|
||||
device.shell(
|
||||
"stop b2g && " +
|
||||
"cd /data/b2g/mozilla/*.default/ && " +
|
||||
"echo 'user_pref(\"devtools.debugger.forbid-certified-apps\", false);' >> prefs.js && " +
|
||||
"start b2g"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function RootADB() {
|
||||
let device = Devices.getByName(AppManager.selectedRuntime.id);
|
||||
let device = AppManager.selectedRuntime.device;
|
||||
device.summonRoot().then(CheckLockState, (e) => console.error(e));
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ const {GetAvailableAddons} = require("devtools/webide/addons");
|
||||
const {GetTemplatesJSON, GetAddonsJSON} = require("devtools/webide/remote-resources");
|
||||
const utils = require("devtools/webide/utils");
|
||||
const Telemetry = require("devtools/shared/telemetry");
|
||||
const {RuntimeScanners, WiFiScanner} = require("devtools/webide/runtimes");
|
||||
|
||||
const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
|
||||
|
||||
@ -148,7 +149,10 @@ let UI = {
|
||||
case "list-tabs-response":
|
||||
this.updateCommands();
|
||||
break;
|
||||
case "runtime":
|
||||
case "runtime-details":
|
||||
this.updateRuntimeButton();
|
||||
break;
|
||||
case "runtime-changed":
|
||||
this.updateRuntimeButton();
|
||||
this.saveLastConnectedRuntime();
|
||||
break;
|
||||
@ -305,17 +309,17 @@ let UI = {
|
||||
/********** RUNTIME **********/
|
||||
|
||||
updateRuntimeList: function() {
|
||||
let wifiHeaderNode = document.querySelector("#runtime-header-wifi-devices");
|
||||
if (AppManager.isWiFiScanningEnabled) {
|
||||
let wifiHeaderNode = document.querySelector("#runtime-header-wifi");
|
||||
if (WiFiScanner.allowed) {
|
||||
wifiHeaderNode.removeAttribute("hidden");
|
||||
} else {
|
||||
wifiHeaderNode.setAttribute("hidden", "true");
|
||||
}
|
||||
|
||||
let USBListNode = document.querySelector("#runtime-panel-usbruntime");
|
||||
let WiFiListNode = document.querySelector("#runtime-panel-wifi-devices");
|
||||
let simulatorListNode = document.querySelector("#runtime-panel-simulators");
|
||||
let customListNode = document.querySelector("#runtime-panel-custom");
|
||||
let usbListNode = document.querySelector("#runtime-panel-usb");
|
||||
let wifiListNode = document.querySelector("#runtime-panel-wifi");
|
||||
let simulatorListNode = document.querySelector("#runtime-panel-simulator");
|
||||
let otherListNode = document.querySelector("#runtime-panel-other");
|
||||
|
||||
let noHelperNode = document.querySelector("#runtime-panel-noadbhelper");
|
||||
let noUSBNode = document.querySelector("#runtime-panel-nousbdevice");
|
||||
@ -326,25 +330,27 @@ let UI = {
|
||||
noHelperNode.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
if (AppManager.runtimeList.usb.length == 0 && Devices.helperAddonInstalled) {
|
||||
let runtimeList = AppManager.runtimeList;
|
||||
|
||||
if (runtimeList.usb.length === 0 && Devices.helperAddonInstalled) {
|
||||
noUSBNode.removeAttribute("hidden");
|
||||
} else {
|
||||
noUSBNode.setAttribute("hidden", "true");
|
||||
}
|
||||
|
||||
for (let [type, parent] of [
|
||||
["usb", USBListNode],
|
||||
["wifi", WiFiListNode],
|
||||
["usb", usbListNode],
|
||||
["wifi", wifiListNode],
|
||||
["simulator", simulatorListNode],
|
||||
["custom", customListNode],
|
||||
["other", otherListNode],
|
||||
]) {
|
||||
while (parent.hasChildNodes()) {
|
||||
parent.firstChild.remove();
|
||||
}
|
||||
for (let runtime of AppManager.runtimeList[type]) {
|
||||
for (let runtime of runtimeList[type]) {
|
||||
let panelItemNode = document.createElement("toolbarbutton");
|
||||
panelItemNode.className = "panel-item runtime-panel-item-" + type;
|
||||
panelItemNode.setAttribute("label", runtime.getName());
|
||||
panelItemNode.setAttribute("label", runtime.name);
|
||||
parent.appendChild(panelItemNode);
|
||||
let r = runtime;
|
||||
panelItemNode.addEventListener("click", () => {
|
||||
@ -366,18 +372,18 @@ let UI = {
|
||||
|
||||
type = type.toLowerCase();
|
||||
|
||||
// Local connection is mapped to AppManager.runtimeList.custom array
|
||||
// Local connection is mapped to AppManager.runtimeList.other array
|
||||
if (type == "local") {
|
||||
type = "custom";
|
||||
type = "other";
|
||||
}
|
||||
|
||||
// We support most runtimes except simulator, that needs to be manually
|
||||
// launched
|
||||
if (type == "usb" || type == "wifi" || type == "custom") {
|
||||
if (type == "usb" || type == "wifi" || type == "other") {
|
||||
for (let runtime of AppManager.runtimeList[type]) {
|
||||
// Some runtimes do not expose getID function and don't support
|
||||
// autoconnect (like remote connection)
|
||||
if (typeof(runtime.getID) == "function" && runtime.getID() == id) {
|
||||
// Some runtimes do not expose an id and don't support autoconnect (like
|
||||
// remote connection)
|
||||
if (runtime.id == id) {
|
||||
this.connectToRuntime(runtime);
|
||||
}
|
||||
}
|
||||
@ -385,10 +391,10 @@ let UI = {
|
||||
},
|
||||
|
||||
connectToRuntime: function(runtime) {
|
||||
let name = runtime.getName();
|
||||
let name = runtime.name;
|
||||
let promise = AppManager.connectToRuntime(runtime);
|
||||
promise.then(() => this.initConnectionTelemetry());
|
||||
return this.busyUntil(promise, "connecting to runtime");
|
||||
return this.busyUntil(promise, "connecting to runtime " + name);
|
||||
},
|
||||
|
||||
updateRuntimeButton: function() {
|
||||
@ -396,15 +402,16 @@ let UI = {
|
||||
if (!AppManager.selectedRuntime) {
|
||||
labelNode.setAttribute("value", Strings.GetStringFromName("runtimeButton_label"));
|
||||
} else {
|
||||
let name = AppManager.selectedRuntime.getName();
|
||||
let name = AppManager.selectedRuntime.name;
|
||||
labelNode.setAttribute("value", name);
|
||||
}
|
||||
},
|
||||
|
||||
saveLastConnectedRuntime: function () {
|
||||
if (AppManager.selectedRuntime &&
|
||||
typeof(AppManager.selectedRuntime.getID) === "function") {
|
||||
this.lastConnectedRuntime = AppManager.selectedRuntime.type + ":" + AppManager.selectedRuntime.getID();
|
||||
AppManager.selectedRuntime.id !== undefined) {
|
||||
this.lastConnectedRuntime = AppManager.selectedRuntime.type + ":" +
|
||||
AppManager.selectedRuntime.id;
|
||||
} else {
|
||||
this.lastConnectedRuntime = "";
|
||||
}
|
||||
@ -1125,7 +1132,7 @@ let Cmds = {
|
||||
},
|
||||
|
||||
showRuntimePanel: function() {
|
||||
AppManager.scanForWiFiRuntimes();
|
||||
RuntimeScanners.scan();
|
||||
|
||||
let panel = document.querySelector("#runtime-panel");
|
||||
let anchor = document.querySelector("#runtime-panel-button > .panel-button-anchor");
|
||||
|
@ -151,17 +151,17 @@
|
||||
<!-- Runtime panel -->
|
||||
<panel id="runtime-panel" type="arrow" position="bottomcenter topright" consumeoutsideclicks="true" animate="false">
|
||||
<vbox flex="1">
|
||||
<label class="panel-header">&runtimePanel_USBDevices;</label>
|
||||
<label class="panel-header">&runtimePanel_usb;</label>
|
||||
<toolbarbutton class="panel-item" label="&runtimePanel_nousbdevice;" id="runtime-panel-nousbdevice" command="cmd_showTroubleShooting"/>
|
||||
<toolbarbutton class="panel-item" label="&runtimePanel_noadbhelper;" id="runtime-panel-noadbhelper" command="cmd_showAddons"/>
|
||||
<vbox id="runtime-panel-usbruntime"></vbox>
|
||||
<label class="panel-header" id="runtime-header-wifi-devices">&runtimePanel_WiFiDevices;</label>
|
||||
<vbox id="runtime-panel-wifi-devices"></vbox>
|
||||
<label class="panel-header">&runtimePanel_simulators;</label>
|
||||
<vbox id="runtime-panel-simulators"></vbox>
|
||||
<vbox id="runtime-panel-usb"></vbox>
|
||||
<label class="panel-header" id="runtime-header-wifi">&runtimePanel_wifi;</label>
|
||||
<vbox id="runtime-panel-wifi"></vbox>
|
||||
<label class="panel-header">&runtimePanel_simulator;</label>
|
||||
<vbox id="runtime-panel-simulator"></vbox>
|
||||
<toolbarbutton class="panel-item" label="&runtimePanel_installsimulator;" id="runtime-panel-installsimulator" command="cmd_showAddons"/>
|
||||
<label class="panel-header">&runtimePanel_custom;</label>
|
||||
<vbox id="runtime-panel-custom"></vbox>
|
||||
<label class="panel-header">&runtimePanel_other;</label>
|
||||
<vbox id="runtime-panel-other"></vbox>
|
||||
<vbox flex="1" id="runtime-actions">
|
||||
<toolbarbutton class="panel-item" id="runtime-details" command="cmd_showRuntimeDetails"/>
|
||||
<toolbarbutton class="panel-item" id="runtime-permissions" command="cmd_showPermissionsTable"/>
|
||||
|
@ -7,11 +7,9 @@ const {Cu} = require("chrome");
|
||||
let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
|
||||
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm");
|
||||
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
|
||||
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm");
|
||||
const {EventEmitter} = Cu.import("resource://gre/modules/devtools/event-emitter.js");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
const {TextEncoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
|
||||
const {AppProjects} = require("devtools/app-manager/app-projects");
|
||||
const TabStore = require("devtools/webide/tab-store");
|
||||
@ -22,26 +20,20 @@ const {getDeviceFront} = require("devtools/server/actors/device");
|
||||
const {getPreferenceFront} = require("devtools/server/actors/preference");
|
||||
const {setTimeout} = require("sdk/timers");
|
||||
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
const {USBRuntime, WiFiRuntime, SimulatorRuntime,
|
||||
gLocalRuntime, gRemoteRuntime} = require("devtools/webide/runtimes");
|
||||
const discovery = require("devtools/toolkit/discovery/discovery");
|
||||
const {RuntimeScanners, RuntimeTypes} = require("devtools/webide/runtimes");
|
||||
const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
|
||||
const Telemetry = require("devtools/shared/telemetry");
|
||||
|
||||
const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
|
||||
|
||||
const WIFI_SCANNING_PREF = "devtools.remote.wifi.scan";
|
||||
|
||||
exports.AppManager = AppManager = {
|
||||
let AppManager = exports.AppManager = {
|
||||
|
||||
// FIXME: will break when devtools/app-manager will be removed:
|
||||
DEFAULT_PROJECT_ICON: "chrome://browser/skin/devtools/app-manager/default-app-icon.png",
|
||||
DEFAULT_PROJECT_NAME: "--",
|
||||
|
||||
init: function() {
|
||||
let host = Services.prefs.getCharPref("devtools.debugger.remote-host");
|
||||
let port = Services.prefs.getIntPref("devtools.debugger.remote-port");
|
||||
|
||||
this.connection = ConnectionManager.createConnection("localhost", port);
|
||||
this.onConnectionChanged = this.onConnectionChanged.bind(this);
|
||||
this.connection.on(Connection.Events.STATUS_CHANGED, this.onConnectionChanged);
|
||||
@ -52,33 +44,22 @@ exports.AppManager = AppManager = {
|
||||
this.tabStore.on("navigate", this.onTabNavigate);
|
||||
this.tabStore.on("closed", this.onTabClosed);
|
||||
|
||||
this.runtimeList = {
|
||||
usb: [],
|
||||
wifi: [],
|
||||
simulator: [],
|
||||
custom: [gRemoteRuntime]
|
||||
};
|
||||
if (Services.prefs.getBoolPref("devtools.webide.enableLocalRuntime")) {
|
||||
this.runtimeList.custom.push(gLocalRuntime);
|
||||
}
|
||||
this.trackUSBRuntimes();
|
||||
this.trackWiFiRuntimes();
|
||||
this.trackSimulatorRuntimes();
|
||||
this._clearRuntimeList();
|
||||
this._rebuildRuntimeList = this._rebuildRuntimeList.bind(this);
|
||||
RuntimeScanners.on("runtime-list-updated", this._rebuildRuntimeList);
|
||||
RuntimeScanners.enable();
|
||||
this._rebuildRuntimeList();
|
||||
|
||||
this.onInstallProgress = this.onInstallProgress.bind(this);
|
||||
|
||||
this.observe = this.observe.bind(this);
|
||||
Services.prefs.addObserver(WIFI_SCANNING_PREF, this, false);
|
||||
|
||||
this._telemetry = new Telemetry();
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
this.selectedProject = null;
|
||||
this.selectedRuntime = null;
|
||||
this.untrackUSBRuntimes();
|
||||
this.untrackWiFiRuntimes();
|
||||
this.untrackSimulatorRuntimes();
|
||||
RuntimeScanners.off("runtime-list-updated", this._rebuildRuntimeList);
|
||||
RuntimeScanners.disable();
|
||||
this.runtimeList = null;
|
||||
this.tabStore.off("navigate", this.onTabNavigate);
|
||||
this.tabStore.off("closed", this.onTabClosed);
|
||||
@ -88,17 +69,6 @@ exports.AppManager = AppManager = {
|
||||
this._listTabsResponse = null;
|
||||
this.connection.disconnect();
|
||||
this.connection = null;
|
||||
Services.prefs.removeObserver(WIFI_SCANNING_PREF, this);
|
||||
},
|
||||
|
||||
observe: function(subject, topic, data) {
|
||||
if (data !== WIFI_SCANNING_PREF) {
|
||||
return;
|
||||
}
|
||||
// Cycle WiFi tracking to reflect the new value
|
||||
this.untrackWiFiRuntimes();
|
||||
this.trackWiFiRuntimes();
|
||||
this._updateWiFiRuntimes();
|
||||
},
|
||||
|
||||
update: function(what, details) {
|
||||
@ -334,7 +304,7 @@ exports.AppManager = AppManager = {
|
||||
this.selectedProject.type == "tab")) {
|
||||
this.selectedProject = null;
|
||||
}
|
||||
this.update("runtime");
|
||||
this.update("runtime-changed");
|
||||
},
|
||||
|
||||
get selectedRuntime() {
|
||||
@ -607,89 +577,41 @@ exports.AppManager = AppManager = {
|
||||
|
||||
/* RUNTIME LIST */
|
||||
|
||||
trackUSBRuntimes: function() {
|
||||
this._updateUSBRuntimes = this._updateUSBRuntimes.bind(this);
|
||||
Devices.on("register", this._updateUSBRuntimes);
|
||||
Devices.on("unregister", this._updateUSBRuntimes);
|
||||
Devices.on("addon-status-updated", this._updateUSBRuntimes);
|
||||
this._updateUSBRuntimes();
|
||||
_clearRuntimeList: function() {
|
||||
this.runtimeList = {
|
||||
usb: [],
|
||||
wifi: [],
|
||||
simulator: [],
|
||||
other: []
|
||||
};
|
||||
},
|
||||
untrackUSBRuntimes: function() {
|
||||
Devices.off("register", this._updateUSBRuntimes);
|
||||
Devices.off("unregister", this._updateUSBRuntimes);
|
||||
Devices.off("addon-status-updated", this._updateUSBRuntimes);
|
||||
},
|
||||
_updateUSBRuntimes: function() {
|
||||
this.runtimeList.usb = [];
|
||||
for (let id of Devices.available()) {
|
||||
let r = new USBRuntime(id);
|
||||
this.runtimeList.usb.push(r);
|
||||
r.updateNameFromADB().then(
|
||||
() => {
|
||||
this.update("runtimelist");
|
||||
// Also update the runtime button label, if the currently selected
|
||||
// runtime name changes
|
||||
if (r == this.selectedRuntime) {
|
||||
this.update("runtime");
|
||||
}
|
||||
},
|
||||
() => {});
|
||||
|
||||
_rebuildRuntimeList: function() {
|
||||
let runtimes = RuntimeScanners.listRuntimes();
|
||||
this._clearRuntimeList();
|
||||
|
||||
// Reorganize runtimes by type
|
||||
for (let runtime of runtimes) {
|
||||
switch (runtime.type) {
|
||||
case RuntimeTypes.USB:
|
||||
this.runtimeList.usb.push(runtime);
|
||||
break;
|
||||
case RuntimeTypes.WIFI:
|
||||
this.runtimeList.wifi.push(runtime);
|
||||
break;
|
||||
case RuntimeTypes.SIMULATOR:
|
||||
this.runtimeList.simulator.push(runtime);
|
||||
break;
|
||||
default:
|
||||
this.runtimeList.other.push(runtime);
|
||||
}
|
||||
}
|
||||
|
||||
this.update("runtime-details");
|
||||
this.update("runtimelist");
|
||||
},
|
||||
|
||||
get isWiFiScanningEnabled() {
|
||||
return Services.prefs.getBoolPref(WIFI_SCANNING_PREF);
|
||||
},
|
||||
scanForWiFiRuntimes: function() {
|
||||
if (!this.isWiFiScanningEnabled) {
|
||||
return;
|
||||
}
|
||||
discovery.scan();
|
||||
},
|
||||
trackWiFiRuntimes: function() {
|
||||
if (!this.isWiFiScanningEnabled) {
|
||||
return;
|
||||
}
|
||||
this._updateWiFiRuntimes = this._updateWiFiRuntimes.bind(this);
|
||||
discovery.on("devtools-device-added", this._updateWiFiRuntimes);
|
||||
discovery.on("devtools-device-updated", this._updateWiFiRuntimes);
|
||||
discovery.on("devtools-device-removed", this._updateWiFiRuntimes);
|
||||
this._updateWiFiRuntimes();
|
||||
},
|
||||
untrackWiFiRuntimes: function() {
|
||||
if (!this.isWiFiScanningEnabled) {
|
||||
return;
|
||||
}
|
||||
discovery.off("devtools-device-added", this._updateWiFiRuntimes);
|
||||
discovery.off("devtools-device-updated", this._updateWiFiRuntimes);
|
||||
discovery.off("devtools-device-removed", this._updateWiFiRuntimes);
|
||||
},
|
||||
_updateWiFiRuntimes: function() {
|
||||
this.runtimeList.wifi = [];
|
||||
for (let device of discovery.getRemoteDevicesWithService("devtools")) {
|
||||
this.runtimeList.wifi.push(new WiFiRuntime(device));
|
||||
}
|
||||
this.update("runtimelist");
|
||||
},
|
||||
|
||||
trackSimulatorRuntimes: function() {
|
||||
this._updateSimulatorRuntimes = this._updateSimulatorRuntimes.bind(this);
|
||||
Simulator.on("register", this._updateSimulatorRuntimes);
|
||||
Simulator.on("unregister", this._updateSimulatorRuntimes);
|
||||
this._updateSimulatorRuntimes();
|
||||
},
|
||||
untrackSimulatorRuntimes: function() {
|
||||
Simulator.off("register", this._updateSimulatorRuntimes);
|
||||
Simulator.off("unregister", this._updateSimulatorRuntimes);
|
||||
},
|
||||
_updateSimulatorRuntimes: function() {
|
||||
this.runtimeList.simulator = [];
|
||||
for (let version of Simulator.availableVersions()) {
|
||||
this.runtimeList.simulator.push(new SimulatorRuntime(version));
|
||||
}
|
||||
this.update("runtimelist");
|
||||
},
|
||||
/* MANIFEST UTILS */
|
||||
|
||||
writeManifest: function(project) {
|
||||
if (project.type != "packaged") {
|
||||
@ -707,6 +629,6 @@ exports.AppManager = AppManager = {
|
||||
let array = encoder.encode(text);
|
||||
return OS.File.writeAtomic(manifestPath, array, {tmpPath: manifestPath + ".tmp"});
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
EventEmitter.decorate(AppManager);
|
||||
|
@ -9,50 +9,413 @@ const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm");
|
||||
const {ConnectionManager, Connection} = require("devtools/client/connection-manager");
|
||||
const {DebuggerServer} = require("resource://gre/modules/devtools/dbg-server.jsm");
|
||||
const discovery = require("devtools/toolkit/discovery/discovery");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
const promise = require("promise");
|
||||
|
||||
const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/webide.properties");
|
||||
|
||||
// These type strings are used for logging events to Telemetry
|
||||
let RuntimeTypes = {
|
||||
usb: "USB",
|
||||
wifi: "WIFI",
|
||||
simulator: "SIMULATOR",
|
||||
remote: "REMOTE",
|
||||
local: "LOCAL"
|
||||
/**
|
||||
* Runtime and Scanner API
|
||||
*
|
||||
* |RuntimeScanners| maintains a set of |Scanner| objects that produce one or
|
||||
* more |Runtime|s to connect to. Add-ons can extend the set of known runtimes
|
||||
* by registering additional |Scanner|s that emit them.
|
||||
*
|
||||
* Each |Scanner| must support the following API:
|
||||
*
|
||||
* enable()
|
||||
* Bind any event handlers and start any background work the scanner needs to
|
||||
* maintain an updated set of |Runtime|s.
|
||||
* Called when the first consumer (such as WebIDE) actively interested in
|
||||
* maintaining the |Runtime| list enables the registry.
|
||||
* disable()
|
||||
* Unbind any event handlers and stop any background work the scanner needs to
|
||||
* maintain an updated set of |Runtime|s.
|
||||
* Called when the last consumer (such as WebIDE) actively interested in
|
||||
* maintaining the |Runtime| list disables the registry.
|
||||
* emits "runtime-list-updated"
|
||||
* If the set of runtimes a |Scanner| manages has changed, it must emit this
|
||||
* event to notify consumers of changes.
|
||||
* scan()
|
||||
* Actively refreshes the list of runtimes the scanner knows about. If your
|
||||
* scanner uses an active scanning approach (as opposed to listening for
|
||||
* events when changes occur), the bulk of the work would be done here.
|
||||
* @return Promise
|
||||
* Should be resolved when scanning is complete. If scanning has no
|
||||
* well-defined end point, you can resolve immediately, as long as
|
||||
* update event is emitted later when changes are noticed.
|
||||
* listRuntimes()
|
||||
* Return the current list of runtimes known to the |Scanner| instance.
|
||||
* @return Iterable
|
||||
*
|
||||
* Each |Runtime| must support the following API:
|
||||
*
|
||||
* |type| field
|
||||
* The |type| must be one of the values from the |RuntimeTypes| object. This
|
||||
* is used for Telemetry and to support displaying sets of |Runtime|s
|
||||
* categorized by type.
|
||||
* |id| field
|
||||
* An identifier that is unique in the set of all runtimes with the same
|
||||
* |type|. WebIDE tries to save the last used runtime via type + id, and
|
||||
* tries to locate it again in the next session, so this value should attempt
|
||||
* to be stable across Firefox sessions.
|
||||
* |name| field
|
||||
* A user-visible label to identify the runtime that will be displayed in a
|
||||
* runtime list.
|
||||
* connect()
|
||||
* Configure the passed |connection| object with any settings need to
|
||||
* successfully connect to the runtime, and call the |connection|'s connect()
|
||||
* method.
|
||||
* @param Connection connection
|
||||
* A |Connection| object from the DevTools |ConnectionManager|.
|
||||
* @return Promise
|
||||
* Resolved once you've called the |connection|'s connect() method.
|
||||
*/
|
||||
|
||||
/* SCANNER REGISTRY */
|
||||
|
||||
let RuntimeScanners = {
|
||||
|
||||
_enabledCount: 0,
|
||||
_scanners: new Set(),
|
||||
|
||||
get enabled() {
|
||||
return !!this._enabledCount;
|
||||
},
|
||||
|
||||
add(scanner) {
|
||||
if (this.enabled) {
|
||||
// Enable any scanner added while globally enabled
|
||||
this._enableScanner(scanner);
|
||||
}
|
||||
this._scanners.add(scanner);
|
||||
this._emitUpdated();
|
||||
},
|
||||
|
||||
remove(scanner) {
|
||||
this._scanners.delete(scanner);
|
||||
if (this.enabled) {
|
||||
// Disable any scanner removed while globally enabled
|
||||
this._disableScanner(scanner);
|
||||
}
|
||||
this._emitUpdated();
|
||||
},
|
||||
|
||||
has(scanner) {
|
||||
return this._scanners.has(scanner);
|
||||
},
|
||||
|
||||
scan() {
|
||||
if (!this.enabled) {
|
||||
return promise.resolve();
|
||||
}
|
||||
|
||||
if (this._scanPromise) {
|
||||
return this._scanPromise;
|
||||
}
|
||||
|
||||
let promises = [];
|
||||
|
||||
for (let scanner of this._scanners) {
|
||||
promises.push(scanner.scan());
|
||||
}
|
||||
|
||||
this._scanPromise = promise.all(promises);
|
||||
|
||||
// Reset pending promise
|
||||
this._scanPromise.then(() => {
|
||||
this._scanPromise = null;
|
||||
}, () => {
|
||||
this._scanPromise = null;
|
||||
});
|
||||
|
||||
return this._scanPromise;
|
||||
},
|
||||
|
||||
listRuntimes: function*() {
|
||||
for (let scanner of this._scanners) {
|
||||
for (let runtime of scanner.listRuntimes()) {
|
||||
yield runtime;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_emitUpdated() {
|
||||
this.emit("runtime-list-updated");
|
||||
},
|
||||
|
||||
enable() {
|
||||
if (this._enabledCount++ !== 0) {
|
||||
// Already enabled scanners during a previous call
|
||||
return;
|
||||
}
|
||||
this._emitUpdated = this._emitUpdated.bind(this);
|
||||
for (let scanner of this._scanners) {
|
||||
this._enableScanner(scanner);
|
||||
}
|
||||
},
|
||||
|
||||
_enableScanner(scanner) {
|
||||
scanner.enable();
|
||||
scanner.on("runtime-list-updated", this._emitUpdated);
|
||||
},
|
||||
|
||||
disable() {
|
||||
if (--this._enabledCount !== 0) {
|
||||
// Already disabled scanners during a previous call
|
||||
return;
|
||||
}
|
||||
for (let scanner of this._scanners) {
|
||||
this._disableScanner(scanner);
|
||||
}
|
||||
},
|
||||
|
||||
_disableScanner(scanner) {
|
||||
scanner.off("runtime-list-updated", this._emitUpdated);
|
||||
scanner.disable();
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
function USBRuntime(id) {
|
||||
this.id = id;
|
||||
EventEmitter.decorate(RuntimeScanners);
|
||||
|
||||
exports.RuntimeScanners = RuntimeScanners;
|
||||
|
||||
/* SCANNERS */
|
||||
|
||||
let SimulatorScanner = {
|
||||
|
||||
_runtimes: [],
|
||||
|
||||
enable() {
|
||||
this._updateRuntimes = this._updateRuntimes.bind(this);
|
||||
Simulator.on("register", this._updateRuntimes);
|
||||
Simulator.on("unregister", this._updateRuntimes);
|
||||
this._updateRuntimes();
|
||||
},
|
||||
|
||||
disable() {
|
||||
Simulator.off("register", this._updateRuntimes);
|
||||
Simulator.off("unregister", this._updateRuntimes);
|
||||
},
|
||||
|
||||
_emitUpdated() {
|
||||
this.emit("runtime-list-updated");
|
||||
},
|
||||
|
||||
_updateRuntimes() {
|
||||
this._runtimes = [];
|
||||
for (let version of Simulator.availableVersions()) {
|
||||
this._runtimes.push(new SimulatorRuntime(version));
|
||||
}
|
||||
this._emitUpdated();
|
||||
},
|
||||
|
||||
scan() {
|
||||
return promise.resolve();
|
||||
},
|
||||
|
||||
listRuntimes: function() {
|
||||
return this._runtimes;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
EventEmitter.decorate(SimulatorScanner);
|
||||
RuntimeScanners.add(SimulatorScanner);
|
||||
|
||||
/**
|
||||
* TODO: Remove this comaptibility layer in the future (bug 1085393)
|
||||
* This runtime exists to support the ADB Helper add-on below version 0.7.0.
|
||||
*
|
||||
* This scanner will list all ADB devices as runtimes, even if they may or may
|
||||
* not actually connect (since the |DeprecatedUSBRuntime| assumes a Firefox OS
|
||||
* device).
|
||||
*/
|
||||
let DeprecatedAdbScanner = {
|
||||
|
||||
_runtimes: [],
|
||||
|
||||
enable() {
|
||||
this._updateRuntimes = this._updateRuntimes.bind(this);
|
||||
Devices.on("register", this._updateRuntimes);
|
||||
Devices.on("unregister", this._updateRuntimes);
|
||||
Devices.on("addon-status-updated", this._updateRuntimes);
|
||||
this._updateRuntimes();
|
||||
},
|
||||
|
||||
disable() {
|
||||
Devices.off("register", this._updateRuntimes);
|
||||
Devices.off("unregister", this._updateRuntimes);
|
||||
Devices.off("addon-status-updated", this._updateRuntimes);
|
||||
},
|
||||
|
||||
_emitUpdated() {
|
||||
this.emit("runtime-list-updated");
|
||||
},
|
||||
|
||||
_updateRuntimes() {
|
||||
this._runtimes = [];
|
||||
for (let id of Devices.available()) {
|
||||
let runtime = new DeprecatedUSBRuntime(id);
|
||||
this._runtimes.push(runtime);
|
||||
runtime.updateNameFromADB().then(() => {
|
||||
this._emitUpdated();
|
||||
}, () => {});
|
||||
}
|
||||
this._emitUpdated();
|
||||
},
|
||||
|
||||
scan() {
|
||||
return promise.resolve();
|
||||
},
|
||||
|
||||
listRuntimes: function() {
|
||||
return this._runtimes;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
EventEmitter.decorate(DeprecatedAdbScanner);
|
||||
RuntimeScanners.add(DeprecatedAdbScanner);
|
||||
|
||||
// ADB Helper 0.7.0 and later will replace this scanner on startup
|
||||
exports.DeprecatedAdbScanner = DeprecatedAdbScanner;
|
||||
|
||||
let WiFiScanner = {
|
||||
|
||||
_runtimes: [],
|
||||
|
||||
init() {
|
||||
this.updateRegistration();
|
||||
Services.prefs.addObserver(this.ALLOWED_PREF, this, false);
|
||||
},
|
||||
|
||||
enable() {
|
||||
this._updateRuntimes = this._updateRuntimes.bind(this);
|
||||
discovery.on("devtools-device-added", this._updateRuntimes);
|
||||
discovery.on("devtools-device-updated", this._updateRuntimes);
|
||||
discovery.on("devtools-device-removed", this._updateRuntimes);
|
||||
this._updateRuntimes();
|
||||
},
|
||||
|
||||
disable() {
|
||||
discovery.off("devtools-device-added", this._updateRuntimes);
|
||||
discovery.off("devtools-device-updated", this._updateRuntimes);
|
||||
discovery.off("devtools-device-removed", this._updateRuntimes);
|
||||
},
|
||||
|
||||
_emitUpdated() {
|
||||
this.emit("runtime-list-updated");
|
||||
},
|
||||
|
||||
_updateRuntimes() {
|
||||
this._runtimes = [];
|
||||
for (let device of discovery.getRemoteDevicesWithService("devtools")) {
|
||||
this._runtimes.push(new WiFiRuntime(device));
|
||||
}
|
||||
this._emitUpdated();
|
||||
},
|
||||
|
||||
scan() {
|
||||
discovery.scan();
|
||||
return promise.resolve();
|
||||
},
|
||||
|
||||
listRuntimes: function() {
|
||||
return this._runtimes;
|
||||
},
|
||||
|
||||
ALLOWED_PREF: "devtools.remote.wifi.scan",
|
||||
|
||||
get allowed() {
|
||||
return Services.prefs.getBoolPref(this.ALLOWED_PREF);
|
||||
},
|
||||
|
||||
updateRegistration() {
|
||||
if (this.allowed) {
|
||||
RuntimeScanners.add(WiFiScanner);
|
||||
} else {
|
||||
RuntimeScanners.remove(WiFiScanner);
|
||||
}
|
||||
this._emitUpdated();
|
||||
},
|
||||
|
||||
observe(subject, topic, data) {
|
||||
if (data !== WiFiScanner.ALLOWED_PREF) {
|
||||
return;
|
||||
}
|
||||
WiFiScanner.updateRegistration();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
EventEmitter.decorate(WiFiScanner);
|
||||
WiFiScanner.init();
|
||||
|
||||
exports.WiFiScanner = WiFiScanner;
|
||||
|
||||
let StaticScanner = {
|
||||
enable() {},
|
||||
disable() {},
|
||||
scan() { return promise.resolve(); },
|
||||
listRuntimes() { return [gRemoteRuntime, gLocalRuntime]; }
|
||||
};
|
||||
|
||||
EventEmitter.decorate(StaticScanner);
|
||||
RuntimeScanners.add(StaticScanner);
|
||||
|
||||
/* RUNTIMES */
|
||||
|
||||
// These type strings are used for logging events to Telemetry.
|
||||
// You must update Histograms.json if new types are added.
|
||||
let RuntimeTypes = exports.RuntimeTypes = {
|
||||
USB: "USB",
|
||||
WIFI: "WIFI",
|
||||
SIMULATOR: "SIMULATOR",
|
||||
REMOTE: "REMOTE",
|
||||
LOCAL: "LOCAL",
|
||||
OTHER: "OTHER"
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO: Remove this comaptibility layer in the future (bug 1085393)
|
||||
* This runtime exists to support the ADB Helper add-on below version 0.7.0.
|
||||
*
|
||||
* This runtime assumes it is connecting to a Firefox OS device.
|
||||
*/
|
||||
function DeprecatedUSBRuntime(id) {
|
||||
this._id = id;
|
||||
}
|
||||
|
||||
USBRuntime.prototype = {
|
||||
type: RuntimeTypes.usb,
|
||||
DeprecatedUSBRuntime.prototype = {
|
||||
type: RuntimeTypes.USB,
|
||||
get device() {
|
||||
return Devices.getByName(this._id);
|
||||
},
|
||||
connect: function(connection) {
|
||||
let device = Devices.getByName(this.id);
|
||||
if (!device) {
|
||||
return promise.reject("Can't find device: " + this.getName());
|
||||
if (!this.device) {
|
||||
return promise.reject("Can't find device: " + this.name);
|
||||
}
|
||||
return device.connect().then((port) => {
|
||||
return this.device.connect().then((port) => {
|
||||
connection.host = "localhost";
|
||||
connection.port = port;
|
||||
connection.connect();
|
||||
});
|
||||
},
|
||||
getID: function() {
|
||||
return this.id;
|
||||
get id() {
|
||||
return this._id;
|
||||
},
|
||||
getName: function() {
|
||||
return this._productModel || this.id;
|
||||
get name() {
|
||||
return this._productModel || this._id;
|
||||
},
|
||||
updateNameFromADB: function() {
|
||||
if (this._productModel) {
|
||||
return promise.resolve();
|
||||
return promise.reject();
|
||||
}
|
||||
let device = Devices.getByName(this.id);
|
||||
let deferred = promise.defer();
|
||||
if (device && device.shell) {
|
||||
device.shell("getprop ro.product.model").then(stdout => {
|
||||
if (this.device && this.device.shell) {
|
||||
this.device.shell("getprop ro.product.model").then(stdout => {
|
||||
this._productModel = stdout;
|
||||
deferred.resolve();
|
||||
}, () => {});
|
||||
@ -62,43 +425,49 @@ USBRuntime.prototype = {
|
||||
}
|
||||
return deferred.promise;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// For testing use only
|
||||
exports._DeprecatedUSBRuntime = DeprecatedUSBRuntime;
|
||||
|
||||
function WiFiRuntime(deviceName) {
|
||||
this.deviceName = deviceName;
|
||||
}
|
||||
|
||||
WiFiRuntime.prototype = {
|
||||
type: RuntimeTypes.wifi,
|
||||
type: RuntimeTypes.WIFI,
|
||||
connect: function(connection) {
|
||||
let service = discovery.getRemoteService("devtools", this.deviceName);
|
||||
if (!service) {
|
||||
return promise.reject("Can't find device: " + this.getName());
|
||||
return promise.reject("Can't find device: " + this.name);
|
||||
}
|
||||
connection.host = service.host;
|
||||
connection.port = service.port;
|
||||
connection.connect();
|
||||
return promise.resolve();
|
||||
},
|
||||
getID: function() {
|
||||
get id() {
|
||||
return this.deviceName;
|
||||
},
|
||||
getName: function() {
|
||||
get name() {
|
||||
return this.deviceName;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// For testing use only
|
||||
exports._WiFiRuntime = WiFiRuntime;
|
||||
|
||||
function SimulatorRuntime(version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
SimulatorRuntime.prototype = {
|
||||
type: RuntimeTypes.simulator,
|
||||
type: RuntimeTypes.SIMULATOR,
|
||||
connect: function(connection) {
|
||||
let port = ConnectionManager.getFreeTCPPort();
|
||||
let simulator = Simulator.getByVersion(this.version);
|
||||
if (!simulator || !simulator.launch) {
|
||||
return promise.reject("Can't find simulator: " + this.getName());
|
||||
return promise.reject("Can't find simulator: " + this.name);
|
||||
}
|
||||
return simulator.launch({port: port}).then(() => {
|
||||
connection.host = "localhost";
|
||||
@ -108,16 +477,23 @@ SimulatorRuntime.prototype = {
|
||||
connection.connect();
|
||||
});
|
||||
},
|
||||
getID: function() {
|
||||
get id() {
|
||||
return this.version;
|
||||
},
|
||||
getName: function() {
|
||||
get name() {
|
||||
let simulator = Simulator.getByVersion(this.version);
|
||||
if (!simulator) {
|
||||
return "Unknown";
|
||||
}
|
||||
return Simulator.getByVersion(this.version).appinfo.label;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
// For testing use only
|
||||
exports._SimulatorRuntime = SimulatorRuntime;
|
||||
|
||||
let gLocalRuntime = {
|
||||
type: RuntimeTypes.local,
|
||||
type: RuntimeTypes.LOCAL,
|
||||
connect: function(connection) {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
@ -128,16 +504,19 @@ let gLocalRuntime = {
|
||||
connection.connect();
|
||||
return promise.resolve();
|
||||
},
|
||||
getName: function() {
|
||||
get id() {
|
||||
return "local";
|
||||
},
|
||||
get name() {
|
||||
return Strings.GetStringFromName("local_runtime");
|
||||
},
|
||||
getID: function () {
|
||||
return "local";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// For testing use only
|
||||
exports._gLocalRuntime = gLocalRuntime;
|
||||
|
||||
let gRemoteRuntime = {
|
||||
type: RuntimeTypes.remote,
|
||||
type: RuntimeTypes.REMOTE,
|
||||
connect: function(connection) {
|
||||
let win = Services.wm.getMostRecentWindow("devtools:webide");
|
||||
if (!win) {
|
||||
@ -159,13 +538,10 @@ let gRemoteRuntime = {
|
||||
connection.connect();
|
||||
return promise.resolve();
|
||||
},
|
||||
getName: function() {
|
||||
get name() {
|
||||
return Strings.GetStringFromName("remote_runtime");
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
exports.USBRuntime = USBRuntime;
|
||||
exports.WiFiRuntime = WiFiRuntime;
|
||||
exports.SimulatorRuntime = SimulatorRuntime;
|
||||
exports.gRemoteRuntime = gRemoteRuntime;
|
||||
exports.gLocalRuntime = gLocalRuntime;
|
||||
// For testing use only
|
||||
exports._gRemoteRuntime = gRemoteRuntime;
|
||||
|
@ -43,7 +43,7 @@ function connectToLocal(win) {
|
||||
win.AppManager.connection.once(
|
||||
win.Connection.Events.CONNECTED,
|
||||
() => deferred.resolve());
|
||||
win.document.querySelectorAll(".runtime-panel-item-custom")[1].click();
|
||||
win.document.querySelectorAll(".runtime-panel-item-other")[1].click();
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ if (window.location === "chrome://browser/content/browser.xul") {
|
||||
}
|
||||
|
||||
Services.prefs.setBoolPref("devtools.webide.enabled", true);
|
||||
Services.prefs.setBoolPref("devtools.webide.enableLocalRuntime", true);
|
||||
|
||||
Services.prefs.setCharPref("devtools.webide.addonsURL", TEST_BASE + "addons/simulators.json");
|
||||
Services.prefs.setCharPref("devtools.webide.simulatorAddonsURL", TEST_BASE + "addons/fxos_#SLASHED_VERSION#_simulator-#OS#.xpi");
|
||||
@ -33,7 +32,6 @@ Services.prefs.setCharPref("devtools.webide.templatesURL", TEST_BASE + "template
|
||||
|
||||
SimpleTest.registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.webide.enabled");
|
||||
Services.prefs.clearUserPref("devtools.webide.enableLocalRuntime");
|
||||
Services.prefs.clearUserPref("devtools.webide.autoinstallADBHelper");
|
||||
Services.prefs.clearUserPref("devtools.webide.autoinstallFxdtAdapters");
|
||||
});
|
||||
|
@ -35,11 +35,11 @@
|
||||
return promise.resolve();
|
||||
},
|
||||
|
||||
getID: function() {
|
||||
get id() {
|
||||
return "fakeRuntime";
|
||||
},
|
||||
|
||||
getName: function() {
|
||||
get name() {
|
||||
return "fakeRuntime";
|
||||
}
|
||||
};
|
||||
|
@ -34,11 +34,11 @@
|
||||
yield documentIsLoaded(permIframe.contentWindow.document);
|
||||
yield documentIsLoaded(infoIframe.contentWindow.document);
|
||||
|
||||
win.AppManager.update("runtimelist");
|
||||
win.AppManager._rebuildRuntimeList();
|
||||
|
||||
let panelNode = win.document.querySelector("#runtime-panel");
|
||||
let items = panelNode.querySelectorAll(".runtime-panel-item-custom");
|
||||
is(items.length, 2, "Found 2 custom runtimes button");
|
||||
let items = panelNode.querySelectorAll(".runtime-panel-item-other");
|
||||
is(items.length, 2, "Found 2 other runtimes button");
|
||||
|
||||
let deferred = promise.defer();
|
||||
win.AppManager.on("app-manager-update", function onUpdate(e,w) {
|
||||
|
@ -57,7 +57,7 @@
|
||||
return promise.resolve();
|
||||
},
|
||||
|
||||
getName: function() {
|
||||
get name() {
|
||||
return "fakeRuntime";
|
||||
}
|
||||
});
|
||||
@ -110,7 +110,7 @@
|
||||
ok(!isPlayActive(), "play button is disabled 4");
|
||||
ok(!isStopActive(), "stop button is disabled 4");
|
||||
|
||||
win.document.querySelectorAll(".runtime-panel-item-custom")[1].click();
|
||||
win.document.querySelectorAll(".runtime-panel-item-other")[1].click();
|
||||
|
||||
yield waitForUpdate(win, "list-tabs-response");
|
||||
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
<script type="application/javascript;version=1.8">
|
||||
const Telemetry = require("devtools/shared/telemetry");
|
||||
const { USBRuntime, WiFiRuntime, SimulatorRuntime, gRemoteRuntime,
|
||||
gLocalRuntime } = require("devtools/webide/runtimes");
|
||||
const { _DeprecatedUSBRuntime, _WiFiRuntime, _SimulatorRuntime,
|
||||
_gRemoteRuntime, _gLocalRuntime, RuntimeTypes }
|
||||
= require("devtools/webide/runtimes");
|
||||
|
||||
// Because we need to gather stats for the period of time that a tool has
|
||||
// been opened we make use of setTimeout() to create tool active times.
|
||||
@ -55,7 +56,7 @@
|
||||
// We use the real runtimes here (and switch out some functionality)
|
||||
// so we can ensure that logging happens as it would in real use.
|
||||
|
||||
let usb = new USBRuntime("fakeUSB");
|
||||
let usb = new _DeprecatedUSBRuntime("fakeUSB");
|
||||
// Use local pipe instead
|
||||
usb.connect = function(connection) {
|
||||
ok(connection, win.AppManager.connection, "connection is valid");
|
||||
@ -65,7 +66,7 @@
|
||||
};
|
||||
win.AppManager.runtimeList.usb.push(usb);
|
||||
|
||||
let wifi = new WiFiRuntime("fakeWiFi");
|
||||
let wifi = new _WiFiRuntime("fakeWiFi");
|
||||
// Use local pipe instead
|
||||
wifi.connect = function(connection) {
|
||||
ok(connection, win.AppManager.connection, "connection is valid");
|
||||
@ -75,7 +76,7 @@
|
||||
};
|
||||
win.AppManager.runtimeList.wifi.push(wifi);
|
||||
|
||||
let sim = new SimulatorRuntime("fakeSimulator");
|
||||
let sim = new _SimulatorRuntime("fakeSimulator");
|
||||
// Use local pipe instead
|
||||
sim.connect = function(connection) {
|
||||
ok(connection, win.AppManager.connection, "connection is valid");
|
||||
@ -83,12 +84,14 @@
|
||||
connection.connect();
|
||||
return promise.resolve();
|
||||
};
|
||||
sim.getName = function() {
|
||||
return this.version;
|
||||
};
|
||||
Object.defineProperty(sim, "name", {
|
||||
get() {
|
||||
return this.version;
|
||||
}
|
||||
});
|
||||
win.AppManager.runtimeList.simulator.push(sim);
|
||||
|
||||
let remote = gRemoteRuntime;
|
||||
let remote = _gRemoteRuntime;
|
||||
// Use local pipe instead
|
||||
remote.connect = function(connection) {
|
||||
ok(connection, win.AppManager.connection, "connection is valid");
|
||||
@ -96,8 +99,12 @@
|
||||
connection.connect();
|
||||
return promise.resolve();
|
||||
};
|
||||
let local = gLocalRuntime;
|
||||
win.AppManager.runtimeList.custom = [gRemoteRuntime, gLocalRuntime];
|
||||
let local = _gLocalRuntime;
|
||||
|
||||
let other = Object.create(_gLocalRuntime);
|
||||
other.type = RuntimeTypes.OTHER;
|
||||
|
||||
win.AppManager.runtimeList.other = [remote, local, other];
|
||||
|
||||
win.AppManager.update("runtimelist");
|
||||
}
|
||||
@ -164,7 +171,7 @@
|
||||
|
||||
ok(okay, "All " + histId + " entries have time > 0");
|
||||
} else if (histId === "DEVTOOLS_WEBIDE_CONNECTION_RESULT") {
|
||||
ok(value.length === 5, histId + " has 5 connection results");
|
||||
ok(value.length === 6, histId + " has 6 connection results");
|
||||
|
||||
let okay = value.every(function(element) {
|
||||
return !!element;
|
||||
@ -175,7 +182,7 @@
|
||||
ok(value.length === 1 && !!value[0],
|
||||
histId + " has 1 successful connection");
|
||||
} else if (histId === "DEVTOOLS_WEBIDE_CONNECTION_TIME_SECONDS") {
|
||||
ok(value.length === 5, histId + " has 5 connection results");
|
||||
ok(value.length === 6, histId + " has 6 connection results");
|
||||
|
||||
let okay = value.every(function(element) {
|
||||
return element > 0;
|
||||
@ -183,7 +190,7 @@
|
||||
|
||||
ok(okay, "All " + histId + " connections have time > 0");
|
||||
} else if (histId.endsWith("USED")) {
|
||||
ok(value.length === 5, histId + " has 5 connection actions");
|
||||
ok(value.length === 6, histId + " has 6 connection actions");
|
||||
|
||||
let okay = value.every(function(element) {
|
||||
return !element;
|
||||
@ -239,9 +246,11 @@
|
||||
yield waitForTime(TOOL_DELAY);
|
||||
yield connectToRuntime(win, "simulator");
|
||||
yield waitForTime(TOOL_DELAY);
|
||||
yield connectToRuntime(win, "custom", 0 /* remote */);
|
||||
yield connectToRuntime(win, "other", 0 /* remote */);
|
||||
yield waitForTime(TOOL_DELAY);
|
||||
yield connectToRuntime(win, "custom", 1 /* local */);
|
||||
yield connectToRuntime(win, "other", 1 /* local */);
|
||||
yield waitForTime(TOOL_DELAY);
|
||||
yield connectToRuntime(win, "other", 2 /* other */);
|
||||
yield waitForTime(TOOL_DELAY);
|
||||
yield closeWebIDE(win);
|
||||
|
||||
|
@ -209,7 +209,7 @@ panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
padding: 12px 0 0;
|
||||
}
|
||||
|
||||
#runtime-panel-custom {
|
||||
#runtime-panel-other {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
#runtime-panel-installsimulator,
|
||||
.runtime-panel-item-usb,
|
||||
.runtime-panel-item-wifi,
|
||||
.runtime-panel-item-custom,
|
||||
.runtime-panel-item-other,
|
||||
.runtime-panel-item-simulator {
|
||||
list-style-image: url("icons.png");
|
||||
}
|
||||
@ -236,7 +236,7 @@ panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
#runtime-panel-installsimulator { -moz-image-region: rect(0px,438px,26px,412px) }
|
||||
.runtime-panel-item-usb { -moz-image-region: rect(52px,438px,78px,412px) }
|
||||
.runtime-panel-item-wifi { -moz-image-region: rect(208px,438px,234px,412px) }
|
||||
.runtime-panel-item-custom { -moz-image-region: rect(26px,438px,52px,412px) }
|
||||
.runtime-panel-item-other { -moz-image-region: rect(26px,438px,52px,412px) }
|
||||
.runtime-panel-item-simulator { -moz-image-region: rect(0px,438px,26px,412px) }
|
||||
|
||||
#runtime-actions {
|
||||
|
@ -8,7 +8,6 @@ pref("devtools.webide.templatesURL", "https://code.cdn.mozilla.net/templates/lis
|
||||
pref("devtools.webide.autoinstallADBHelper", true);
|
||||
pref("devtools.webide.autoinstallFxdtAdapters", false);
|
||||
pref("devtools.webide.restoreLastProject", true);
|
||||
pref("devtools.webide.enableLocalRuntime", true);
|
||||
pref("devtools.webide.addonsURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/index.json");
|
||||
pref("devtools.webide.simulatorAddonsURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/#VERSION#/#OS#/fxos_#SLASHED_VERSION#_simulator-#OS#-latest.xpi");
|
||||
pref("devtools.webide.simulatorAddonID", "fxos_#SLASHED_VERSION#_simulator@mozilla.org");
|
||||
|
@ -63,10 +63,10 @@
|
||||
<!ENTITY projectPanel_myProjects "My Projects">
|
||||
<!ENTITY projectPanel_runtimeApps "Runtime Apps">
|
||||
<!ENTITY projectPanel_tabs "Tabs">
|
||||
<!ENTITY runtimePanel_USBDevices "USB Devices">
|
||||
<!ENTITY runtimePanel_WiFiDevices "Wi-Fi Devices">
|
||||
<!ENTITY runtimePanel_simulators "Simulators">
|
||||
<!ENTITY runtimePanel_custom "Custom">
|
||||
<!ENTITY runtimePanel_usb "USB Devices">
|
||||
<!ENTITY runtimePanel_wifi "Wi-Fi Devices">
|
||||
<!ENTITY runtimePanel_simulator "Simulators">
|
||||
<!ENTITY runtimePanel_other "Other">
|
||||
<!ENTITY runtimePanel_installsimulator "Install Simulator">
|
||||
<!ENTITY runtimePanel_noadbhelper "Install ADB Helper">
|
||||
<!ENTITY runtimePanel_nousbdevice "Can't see your device?">
|
||||
@ -101,8 +101,6 @@
|
||||
<!ENTITY prefs_general_title "General">
|
||||
<!ENTITY prefs_restore "Restore Defaults">
|
||||
<!ENTITY prefs_simulators "Manage Simulators">
|
||||
<!ENTITY prefs_options_enablelocalruntime "Enable local runtime">
|
||||
<!ENTITY prefs_options_enablelocalruntime_tooltip "Allow WebIDE to connect to its own runtime (running browser instance)">
|
||||
<!ENTITY prefs_options_rememberlastproject "Remember last project">
|
||||
<!ENTITY prefs_options_rememberlastproject_tooltip "Restore previous project when WebIDE starts">
|
||||
<!ENTITY prefs_options_templatesurl "Templates URL">
|
||||
|
@ -14,7 +14,7 @@ const Cu = Components.utils;
|
||||
|
||||
// The minimum sizes for the auto-resize panel code, minimum size necessary to
|
||||
// properly show the error page in the panel.
|
||||
const PANEL_MIN_HEIGHT = 200;
|
||||
const PANEL_MIN_HEIGHT = 190;
|
||||
const PANEL_MIN_WIDTH = 330;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
@ -187,6 +187,9 @@ browser.jar:
|
||||
skin/classic/browser/tabbrowser/tab-stroke-start.png (tabbrowser/tab-stroke-start.png)
|
||||
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
|
||||
skin/classic/browser/tabbrowser/tab-separator.png (tabbrowser/tab-separator.png)
|
||||
|
||||
skin/classic/browser/tabbrowser/pendingpaint.png (../shared/tabbrowser/pendingpaint.png)
|
||||
|
||||
skin/classic/browser/tabview/edit-light.png (tabview/edit-light.png)
|
||||
skin/classic/browser/tabview/search.png (tabview/search.png)
|
||||
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)
|
||||
|
@ -302,6 +302,8 @@ browser.jar:
|
||||
skin/classic/browser/tabbrowser/tab-background-start@2x.png (tabbrowser/tab-background-start@2x.png)
|
||||
skin/classic/browser/tabbrowser/tab-overflow-indicator.png (../shared/tabbrowser/tab-overflow-indicator.png)
|
||||
|
||||
skin/classic/browser/tabbrowser/pendingpaint.png (../shared/tabbrowser/pendingpaint.png)
|
||||
|
||||
# NOTE: The following two files (tab-selected-end.svg, tab-selected-start.svg) get pre-processed in
|
||||
# Makefile.in with a non-default marker of "%" and the result of that gets packaged.
|
||||
skin/classic/browser/tabbrowser/tab-selected-end.svg (tab-selected-end.svg)
|
||||
|
@ -3,6 +3,7 @@ body {
|
||||
margin-top: 2em;
|
||||
font: message-box;
|
||||
font-size: 100%;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
p {
|
||||
|
@ -4,4 +4,39 @@
|
||||
|
||||
#errorPageContainer {
|
||||
background-image: url("chrome://global/skin/icons/information-64.png");
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* tablist starts out hidden, but JS may make it visible in response to
|
||||
clicks on the radio buttons by setting an "available" attribute.
|
||||
*/
|
||||
#tabList {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#tabList[available] {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
.radioRestoreContainer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.radioRestoreButton {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.radioRestoreButton:-moz-focusring {
|
||||
outline: 1px dotted black;
|
||||
}
|
||||
|
||||
.radioChooseLabel {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
/* We want errorTrailerDesc to have the same padding-top as errorShortDesc
|
||||
has padding-bottom
|
||||
*/
|
||||
#errorTrailerDesc {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
BIN
browser/themes/shared/tabbrowser/pendingpaint.png
Normal file
BIN
browser/themes/shared/tabbrowser/pendingpaint.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 155 KiB |
@ -208,6 +208,8 @@ browser.jar:
|
||||
skin/classic/browser/tabbrowser/tab-background-end@2x.png (tabbrowser/tab-background-end@2x.png)
|
||||
skin/classic/browser/tabbrowser/tab-overflow-indicator.png (../shared/tabbrowser/tab-overflow-indicator.png)
|
||||
|
||||
skin/classic/browser/tabbrowser/pendingpaint.png (../shared/tabbrowser/pendingpaint.png)
|
||||
|
||||
# NOTE: The following two files (tab-selected-end.svg, tab-selected-start.svg) get pre-processed in
|
||||
# Makefile.in with a non-default marker of "%" and the result of that gets packaged.
|
||||
skin/classic/browser/tabbrowser/tab-selected-end.svg (tab-selected-end.svg)
|
||||
|
@ -61,6 +61,9 @@ ROBOCOP_FILES := \
|
||||
$(wildcard $(TESTPATH)/test*.js) \
|
||||
$(wildcard $(TESTPATH)/robocop*.js) \
|
||||
$(wildcard $(TESTPATH)/*.xml) \
|
||||
$(wildcard $(TESTPATH)/*.ogg) \
|
||||
$(wildcard $(TESTPATH)/*.mp4) \
|
||||
$(wildcard $(TESTPATH)/*.webm) \
|
||||
$(wildcard $(TESTPATH)/*.swf) \
|
||||
$(NULL)
|
||||
|
||||
|
@ -107,6 +107,7 @@ function _setAppProperties(aObj, aApp) {
|
||||
aObj.redirects = aApp.redirects;
|
||||
aObj.widgetPages = aApp.widgetPages || [];
|
||||
aObj.kind = aApp.kind;
|
||||
aObj.enabled = aApp.enabled !== undefined ? aApp.enabled : true;
|
||||
}
|
||||
|
||||
this.AppsUtils = {
|
||||
|
@ -424,6 +424,10 @@ WebappsApplication.prototype = {
|
||||
return new this._window.DOMError(this._proxy.downloadError);
|
||||
},
|
||||
|
||||
get enabled() {
|
||||
return this._proxy.enabled;
|
||||
},
|
||||
|
||||
download: function() {
|
||||
cpmm.sendAsyncMessage("Webapps:Download",
|
||||
{ manifestURL: this.manifestURL });
|
||||
@ -613,7 +617,7 @@ WebappsApplication.prototype = {
|
||||
case "Webapps:Launch:Return:KO":
|
||||
this.removeMessageListeners(["Webapps:Launch:Return:OK",
|
||||
"Webapps:Launch:Return:KO"]);
|
||||
Services.DOMRequest.fireError(req, "APP_INSTALL_PENDING");
|
||||
Services.DOMRequest.fireError(req, msg.error);
|
||||
break;
|
||||
case "Webapps:Launch:Return:OK":
|
||||
this.removeMessageListeners(["Webapps:Launch:Return:OK",
|
||||
@ -722,12 +726,14 @@ WebappsApplicationMgmt.prototype = {
|
||||
"Webapps:Install:Return:OK",
|
||||
"Webapps:GetNotInstalled:Return:OK",
|
||||
"Webapps:Import:Return",
|
||||
"Webapps:ExtractManifest:Return"]);
|
||||
"Webapps:ExtractManifest:Return",
|
||||
"Webapps:SetEnabled:Return"]);
|
||||
cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
|
||||
{
|
||||
messages: ["Webapps:Install:Return:OK",
|
||||
"Webapps:Uninstall:Return:OK",
|
||||
"Webapps:Uninstall:Broadcast:Return:OK"]
|
||||
"Webapps:Uninstall:Broadcast:Return:OK",
|
||||
"Webapps:SetEnabled:Return"]
|
||||
}
|
||||
);
|
||||
},
|
||||
@ -736,7 +742,8 @@ WebappsApplicationMgmt.prototype = {
|
||||
cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
|
||||
["Webapps:Install:Return:OK",
|
||||
"Webapps:Uninstall:Return:OK",
|
||||
"Webapps:Uninstall:Broadcast:Return:OK"]);
|
||||
"Webapps:Uninstall:Broadcast:Return:OK",
|
||||
"Webapps:SetEnabled:Return"]);
|
||||
},
|
||||
|
||||
applyDownload: function(aApp) {
|
||||
@ -804,6 +811,12 @@ WebappsApplicationMgmt.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
setEnabled: function(aApp, aValue) {
|
||||
cpmm.sendAsyncMessage("Webapps:SetEnabled",
|
||||
{ manifestURL: aApp.manifestURL,
|
||||
enabled: aValue });
|
||||
},
|
||||
|
||||
get oninstall() {
|
||||
return this.__DOM_IMPL__.getEventHandler("oninstall");
|
||||
},
|
||||
@ -812,6 +825,10 @@ WebappsApplicationMgmt.prototype = {
|
||||
return this.__DOM_IMPL__.getEventHandler("onuninstall");
|
||||
},
|
||||
|
||||
get onenabledstatechange() {
|
||||
return this.__DOM_IMPL__.getEventHandler("onenabledstatechange");
|
||||
},
|
||||
|
||||
set oninstall(aCallback) {
|
||||
this.__DOM_IMPL__.setEventHandler("oninstall", aCallback);
|
||||
},
|
||||
@ -820,9 +837,14 @@ WebappsApplicationMgmt.prototype = {
|
||||
this.__DOM_IMPL__.setEventHandler("onuninstall", aCallback);
|
||||
},
|
||||
|
||||
set onenabledstatechange(aCallback) {
|
||||
this.__DOM_IMPL__.setEventHandler("onenabledstatechange", aCallback);
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
let msg = aMessage.data;
|
||||
let req;
|
||||
|
||||
if (["Webapps:Import:Return",
|
||||
"Webapps:ExtractManifest:Return"]
|
||||
.indexOf(aMessage.name) != -1) {
|
||||
@ -831,11 +853,13 @@ WebappsApplicationMgmt.prototype = {
|
||||
req = this.getRequest(msg.requestID);
|
||||
}
|
||||
|
||||
// We want Webapps:Install:Return:OK and Webapps:Uninstall:Broadcast:Return:OK
|
||||
// We want Webapps:Install:Return:OK, Webapps:Uninstall:Broadcast:Return:OK
|
||||
// and Webapps:SetEnabled:Return
|
||||
// to be broadcasted to all instances of mozApps.mgmt.
|
||||
if (!((msg.oid == this._id && req) ||
|
||||
aMessage.name == "Webapps:Install:Return:OK" ||
|
||||
aMessage.name == "Webapps:Uninstall:Broadcast:Return:OK")) {
|
||||
aMessage.name == "Webapps:Uninstall:Broadcast:Return:OK" ||
|
||||
aMessage.name == "Webapps:SetEnabled:Return")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -879,6 +903,14 @@ WebappsApplicationMgmt.prototype = {
|
||||
req.reject(new this._window.DOMError(msg.error || ""));
|
||||
}
|
||||
break;
|
||||
case "Webapps:SetEnabled:Return":
|
||||
{
|
||||
let app = createContentApplicationObject(this._window, msg);
|
||||
let event =
|
||||
new this._window.MozApplicationEvent("enabledstatechange", { application : app });
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (aMessage.name !== "Webapps:Uninstall:Broadcast:Return:OK") {
|
||||
this.removeRequest(msg.requestID);
|
||||
|
@ -173,20 +173,30 @@ this.DOMApplicationRegistry = {
|
||||
dirKey: DIRECTORY_NAME,
|
||||
|
||||
init: function() {
|
||||
this.messages = ["Webapps:Install", "Webapps:Uninstall",
|
||||
"Webapps:GetSelf", "Webapps:CheckInstalled",
|
||||
"Webapps:GetInstalled", "Webapps:GetNotInstalled",
|
||||
this.messages = ["Webapps:Install",
|
||||
"Webapps:Uninstall",
|
||||
"Webapps:GetSelf",
|
||||
"Webapps:CheckInstalled",
|
||||
"Webapps:GetInstalled",
|
||||
"Webapps:GetNotInstalled",
|
||||
"Webapps:Launch",
|
||||
"Webapps:InstallPackage",
|
||||
"Webapps:GetList", "Webapps:RegisterForMessages",
|
||||
"Webapps:GetList",
|
||||
"Webapps:RegisterForMessages",
|
||||
"Webapps:UnregisterForMessages",
|
||||
"Webapps:CancelDownload", "Webapps:CheckForUpdate",
|
||||
"Webapps:Download", "Webapps:ApplyDownload",
|
||||
"Webapps:Install:Return:Ack", "Webapps:AddReceipt",
|
||||
"Webapps:RemoveReceipt", "Webapps:ReplaceReceipt",
|
||||
"Webapps:CancelDownload",
|
||||
"Webapps:CheckForUpdate",
|
||||
"Webapps:Download",
|
||||
"Webapps:ApplyDownload",
|
||||
"Webapps:Install:Return:Ack",
|
||||
"Webapps:AddReceipt",
|
||||
"Webapps:RemoveReceipt",
|
||||
"Webapps:ReplaceReceipt",
|
||||
"Webapps:RegisterBEP",
|
||||
"Webapps:Export", "Webapps:Import",
|
||||
"Webapps:Export",
|
||||
"Webapps:Import",
|
||||
"Webapps:ExtractManifest",
|
||||
"Webapps:SetEnabled",
|
||||
"child-process-shutdown"];
|
||||
|
||||
this.frameMessages = ["Webapps:ClearBrowserData"];
|
||||
@ -283,6 +293,10 @@ this.DOMApplicationRegistry = {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (app.enabled === undefined) {
|
||||
app.enabled = true;
|
||||
}
|
||||
|
||||
// At startup we can't be downloading, and the $TMP directory
|
||||
// will be empty so we can't just apply a staged update.
|
||||
app.downloading = false;
|
||||
@ -1181,13 +1195,14 @@ this.DOMApplicationRegistry = {
|
||||
Services.prefs.setBoolPref("dom.mozApps.used", true);
|
||||
|
||||
// We need to check permissions for calls coming from mozApps.mgmt.
|
||||
// These are: getNotInstalled(), applyDownload(), uninstall(), import() and
|
||||
// extractManifest().
|
||||
// These are: getNotInstalled(), applyDownload(), uninstall(), import(),
|
||||
// extractManifest(), setEnabled().
|
||||
if (["Webapps:GetNotInstalled",
|
||||
"Webapps:ApplyDownload",
|
||||
"Webapps:Uninstall",
|
||||
"Webapps:Import",
|
||||
"Webapps:ExtractManifest"].indexOf(aMessage.name) != -1) {
|
||||
"Webapps:ExtractManifest",
|
||||
"Webapps:SetEnabled"].indexOf(aMessage.name) != -1) {
|
||||
if (!aMessage.target.assertPermission("webapps-manage")) {
|
||||
debug("mozApps message " + aMessage.name +
|
||||
" from a content process with no 'webapps-manage' privileges.");
|
||||
@ -1322,6 +1337,9 @@ this.DOMApplicationRegistry = {
|
||||
case "Webapps:ExtractManifest":
|
||||
this.doExtractManifest(msg, mm);
|
||||
break;
|
||||
case "Webapps:SetEnabled":
|
||||
this.setEnabled(msg);
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -1534,6 +1552,7 @@ this.DOMApplicationRegistry = {
|
||||
aMm.sendAsyncMessage("Webapps:Launch:Return:OK", aData);
|
||||
},
|
||||
function onfailure(reason) {
|
||||
aData.error = reason;
|
||||
aMm.sendAsyncMessage("Webapps:Launch:Return:KO", aData);
|
||||
}
|
||||
);
|
||||
@ -4299,6 +4318,25 @@ this.DOMApplicationRegistry = {
|
||||
});
|
||||
},
|
||||
|
||||
setEnabled: function(aData) {
|
||||
debug("setEnabled " + aData.manifestURL + " : " + aData.enabled);
|
||||
let id = this._appIdForManifestURL(aData.manifestURL);
|
||||
if (!id || !this.webapps[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
debug("Enabling " + id);
|
||||
let app = this.webapps[id];
|
||||
app.enabled = aData.enabled;
|
||||
this._saveApps().then(() => {
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
id: app.id
|
||||
});
|
||||
this.broadcastMessage("Webapps:SetEnabled:Return", app);
|
||||
});
|
||||
},
|
||||
|
||||
getManifestFor: function(aManifestURL) {
|
||||
let id = this._appIdForManifestURL(aManifestURL);
|
||||
let app = this.webapps[id];
|
||||
|
@ -22,6 +22,7 @@ support-files =
|
||||
marketplace/*
|
||||
pkg_install_iframe.html
|
||||
|
||||
[test_app_enabled.html]
|
||||
[test_app_update.html]
|
||||
[test_bug_795164.html]
|
||||
[test_import_export.html]
|
||||
|
129
dom/apps/tests/test_app_enabled.html
Normal file
129
dom/apps/tests/test_app_enabled.html
Normal file
@ -0,0 +1,129 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id={1XXXXXX}
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug {1072090}</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" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1072090}">Mozilla Bug {1072090}</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript;version=1.7">
|
||||
|
||||
var gManifestURL = "http://test/tests/dom/apps/tests/file_app.sjs?apptype=hosted&getmanifest=true";
|
||||
var gGenerator = runTest();
|
||||
|
||||
function go() {
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "webapps-manage", "allow": 1, "context": document }],
|
||||
function() { gGenerator.next() });
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
try {
|
||||
gGenerator.next();
|
||||
} catch (e if e instanceof StopIteration) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function finish() {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function cbError(aEvent) {
|
||||
ok(false, "Error callback invoked " +
|
||||
aEvent.target.error.name + " " + aEvent.target.error.message);
|
||||
finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/**
|
||||
* Flip the `enabled` state of an app back and forth.
|
||||
*/
|
||||
function runTest() {
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
|
||||
SpecialPowers.autoConfirmAppInstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.autoConfirmAppUninstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
request = navigator.mozApps.mgmt.getAll();
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
var initialAppsCount = request.result.length;
|
||||
info("Starting with " + initialAppsCount + " apps installed.");
|
||||
|
||||
var request = navigator.mozApps.install(gManifestURL, { });
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
|
||||
var app = request.result;
|
||||
ok(app, "App is non-null");
|
||||
is(app.manifestURL, gManifestURL, "App manifest url is correct.");
|
||||
is(app.enabled, true, "App is enabled by default after install.");
|
||||
|
||||
// Switch the app to disabled.
|
||||
navigator.mozApps.mgmt.onenabledstatechange = function(event) {
|
||||
ok(true, "onenabledstatechange received");
|
||||
is(event.application.enabled, false, "Application is disabled");
|
||||
is(app.enabled, false, "Application is disabled");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
navigator.mozApps.mgmt.setEnabled(app, false);
|
||||
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(app.enabled, true, "Application is enabled");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
navigator.mozApps.mgmt.setEnabled(app, true);
|
||||
yield undefined;
|
||||
|
||||
navigator.mozApps.mgmt.onuninstall = function(event) {
|
||||
var app = event.application;
|
||||
is(app.manifestURL, gManifestURL, "App uninstall event ok.");
|
||||
is(app.manifest.name, "Really Rapid Release (hosted)",
|
||||
"App uninstall manifest ok.");
|
||||
continueTest();
|
||||
}
|
||||
request = navigator.mozApps.mgmt.uninstall(app);
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
yield undefined;
|
||||
is(request.result, gManifestURL, "App uninstalled.");
|
||||
navigator.mozApps.mgmt.onuninstall = null;
|
||||
|
||||
request = navigator.mozApps.mgmt.getAll();
|
||||
request.onerror = cbError;
|
||||
request.onsuccess = continueTest;
|
||||
yield undefined;
|
||||
is(request.result.length, initialAppsCount, "All apps are uninstalled.");
|
||||
}
|
||||
|
||||
addLoadEvent(go);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -77,7 +77,7 @@ function cbError(aEvent) {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/**
|
||||
* Install 2 apps from the same origin and uninstall them.
|
||||
* Test exporting and importing hosted and packaged apps.
|
||||
*/
|
||||
function runTest() {
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
|
@ -17,6 +17,16 @@ ASSERT_NETWORK_SELECTION_MODE_EQUALITY(Manual, NETWORK_SELECTION_MODE_MANUAL);
|
||||
|
||||
#undef ASSERT_NETWORK_SELECTION_MODE_EQUALITY
|
||||
|
||||
#define ASSERT_MOBILE_RADIO_STATE_EQUALITY(webidlState, xpidlState) \
|
||||
static_assert(static_cast<int32_t>(MobileRadioState::webidlState) == nsIMobileConnection::xpidlState, \
|
||||
"MobileRadioState::" #webidlState " should equal to nsIMobileConnection::" #xpidlState)
|
||||
|
||||
ASSERT_MOBILE_RADIO_STATE_EQUALITY(Enabling, MOBILE_RADIO_STATE_ENABLING);
|
||||
ASSERT_MOBILE_RADIO_STATE_EQUALITY(Enabled, MOBILE_RADIO_STATE_ENABLED);
|
||||
ASSERT_MOBILE_RADIO_STATE_EQUALITY(Disabling, MOBILE_RADIO_STATE_DISABLING);
|
||||
ASSERT_MOBILE_RADIO_STATE_EQUALITY(Disabled, MOBILE_RADIO_STATE_DISABLED);
|
||||
|
||||
#undef ASSERT_MOBILE_RADIO_STATE_EQUALITY
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -368,9 +368,12 @@ MobileConnection::GetRadioState() const
|
||||
return retVal;
|
||||
}
|
||||
|
||||
nsAutoString state;
|
||||
mMobileConnection->GetRadioState(state);
|
||||
CONVERT_STRING_TO_NULLABLE_ENUM(state, MobileRadioState, retVal);
|
||||
int32_t state = nsIMobileConnection::MOBILE_RADIO_STATE_UNKNOWN;
|
||||
if (NS_SUCCEEDED(mMobileConnection->GetRadioState(&state)) &&
|
||||
state != nsIMobileConnection::MOBILE_RADIO_STATE_UNKNOWN) {
|
||||
MOZ_ASSERT(state < static_cast<int32_t>(MobileRadioState::EndGuard_));
|
||||
retVal.SetValue(static_cast<MobileRadioState>(state));
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ MobileConnectionProvider.prototype = {
|
||||
data: null,
|
||||
iccId: null,
|
||||
networkSelectionMode: Ci.nsIMobileConnection.NETWORK_SELECTION_MODE_UNKNOWN,
|
||||
radioState: null,
|
||||
radioState: Ci.nsIMobileConnection.MOBILE_RADIO_STATE_UNKNOWN,
|
||||
lastKnownNetwork: null,
|
||||
lastKnownHomeNetwork: null,
|
||||
supportedNetworkTypes: null,
|
||||
@ -743,7 +743,7 @@ MobileConnectionProvider.prototype = {
|
||||
},
|
||||
|
||||
setPreferredNetworkType: function(aType, aCallback) {
|
||||
if (this.radioState !== RIL.GECKO_RADIOSTATE_ENABLED) {
|
||||
if (this.radioState !== Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED) {
|
||||
this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
@ -762,7 +762,7 @@ MobileConnectionProvider.prototype = {
|
||||
},
|
||||
|
||||
getPreferredNetworkType: function(aCallback) {
|
||||
if (this.radioState !== RIL.GECKO_RADIOSTATE_ENABLED) {
|
||||
if (this.radioState !== Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED) {
|
||||
this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
@ -984,7 +984,7 @@ MobileConnectionProvider.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.radioState !== RIL.GECKO_RADIOSTATE_ENABLED) {
|
||||
if (this.radioState !== Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED) {
|
||||
this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
@ -1003,7 +1003,7 @@ MobileConnectionProvider.prototype = {
|
||||
},
|
||||
|
||||
getCallingLineIdRestriction: function(aCallback) {
|
||||
if (this.radioState !== RIL.GECKO_RADIOSTATE_ENABLED) {
|
||||
if (this.radioState !== Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED) {
|
||||
this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
"@mozilla.org/mobileconnection/gonkmobileconnectionservice;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(2d574f0e-4a02-11e4-b1b3-cbc14b7608ce)]
|
||||
[scriptable, uuid(7322619d-9abd-4410-99ce-207da80f9879)]
|
||||
interface nsIGonkMobileConnectionService : nsIMobileConnectionService
|
||||
{
|
||||
void notifyNetworkInfoChanged(in unsigned long clientId, in jsval networkInfo);
|
||||
@ -27,7 +27,7 @@ interface nsIGonkMobileConnectionService : nsIMobileConnectionService
|
||||
void notifyOtaStatusChanged(in unsigned long clientId, in DOMString status);
|
||||
|
||||
void notifyRadioStateChanged(in unsigned long clientId,
|
||||
in DOMString radioState);
|
||||
in long radioState);
|
||||
|
||||
void notifyUssdReceived(in unsigned long clientId,
|
||||
in DOMString message,
|
||||
|
@ -236,7 +236,7 @@ already_AddRefed<nsIMobileConnectionService>
|
||||
NS_CreateMobileConnectionService();
|
||||
%}
|
||||
|
||||
[scriptable, uuid(cfc7d15b-d2c2-4f28-ad9f-b250030c3073)]
|
||||
[scriptable, uuid(99818dc7-e770-4249-87e2-2de0a928ed08)]
|
||||
interface nsIMobileConnection : nsISupports
|
||||
{
|
||||
/*
|
||||
@ -304,6 +304,15 @@ interface nsIMobileConnection : nsISupports
|
||||
const long NETWORK_SELECTION_MODE_AUTOMATIC = 0;
|
||||
const long NETWORK_SELECTION_MODE_MANUAL = 1;
|
||||
|
||||
/**
|
||||
* Mobile Radio State.
|
||||
*/
|
||||
const long MOBILE_RADIO_STATE_UNKNOWN = -1;
|
||||
const long MOBILE_RADIO_STATE_ENABLING = 0;
|
||||
const long MOBILE_RADIO_STATE_ENABLED = 1;
|
||||
const long MOBILE_RADIO_STATE_DISABLING = 2;
|
||||
const long MOBILE_RADIO_STATE_DISABLED = 3;
|
||||
|
||||
readonly attribute unsigned long serviceId;
|
||||
|
||||
/**
|
||||
@ -347,10 +356,10 @@ interface nsIMobileConnection : nsISupports
|
||||
readonly attribute long networkSelectionMode;
|
||||
|
||||
/**
|
||||
* Current radio state. Possible values are 'enabling', 'enabled',
|
||||
* 'disabling', 'disabled', null (unknown).
|
||||
* Current radio state. One of the nsIMobileConnection.MOBILE_RADIO_STATE_*
|
||||
* values.
|
||||
*/
|
||||
readonly attribute DOMString radioState;
|
||||
readonly attribute long radioState;
|
||||
|
||||
/**
|
||||
* The network types supported by this radio.
|
||||
|
@ -106,9 +106,9 @@ MobileConnectionChild::GetIccId(nsAString& aIccId)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionChild::GetRadioState(nsAString& aRadioState)
|
||||
MobileConnectionChild::GetRadioState(int32_t* aRadioState)
|
||||
{
|
||||
aRadioState = mRadioState;
|
||||
*aRadioState = mRadioState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -488,9 +488,9 @@ MobileConnectionChild::RecvNotifyIccChanged(const nsString& aIccId)
|
||||
}
|
||||
|
||||
bool
|
||||
MobileConnectionChild::RecvNotifyRadioStateChanged(const nsString& aRadioState)
|
||||
MobileConnectionChild::RecvNotifyRadioStateChanged(const int32_t& aRadioState)
|
||||
{
|
||||
mRadioState.Assign(aRadioState);
|
||||
mRadioState = aRadioState;
|
||||
|
||||
for (int32_t i = 0; i < mListeners.Count(); i++) {
|
||||
mListeners[i]->NotifyRadioStateChanged();
|
||||
|
@ -92,7 +92,7 @@ protected:
|
||||
RecvNotifyIccChanged(const nsString& aIccId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvNotifyRadioStateChanged(const nsString& aRadioState) MOZ_OVERRIDE;
|
||||
RecvNotifyRadioStateChanged(const int32_t& aRadioState) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvNotifyClirModeChanged(const uint32_t& aMode) MOZ_OVERRIDE;
|
||||
@ -113,7 +113,7 @@ private:
|
||||
nsRefPtr<MobileConnectionInfo> mVoice;
|
||||
nsRefPtr<MobileConnectionInfo> mData;
|
||||
nsString mIccId;
|
||||
nsString mRadioState;
|
||||
int32_t mRadioState;
|
||||
nsString mLastNetwork;
|
||||
nsString mLastHomeNetwork;
|
||||
int32_t mNetworkSelectionMode;
|
||||
|
@ -130,7 +130,7 @@ MobileConnectionParent::RecvInit(nsMobileConnectionInfo* aVoice,
|
||||
nsString* aLastKnownHomeNetwork,
|
||||
nsString* aIccId,
|
||||
int32_t* aNetworkSelectionMode,
|
||||
nsString* aRadioState,
|
||||
int32_t* aRadioState,
|
||||
nsTArray<nsString>* aSupportedNetworkTypes)
|
||||
{
|
||||
NS_ENSURE_TRUE(mMobileConnection, false);
|
||||
@ -141,7 +141,7 @@ MobileConnectionParent::RecvInit(nsMobileConnectionInfo* aVoice,
|
||||
NS_ENSURE_SUCCESS(mMobileConnection->GetLastKnownHomeNetwork(*aLastKnownHomeNetwork), false);
|
||||
NS_ENSURE_SUCCESS(mMobileConnection->GetIccId(*aIccId), false);
|
||||
NS_ENSURE_SUCCESS(mMobileConnection->GetNetworkSelectionMode(aNetworkSelectionMode), false);
|
||||
NS_ENSURE_SUCCESS(mMobileConnection->GetRadioState(*aRadioState), false);
|
||||
NS_ENSURE_SUCCESS(mMobileConnection->GetRadioState(aRadioState), false);
|
||||
|
||||
char16_t** types = nullptr;
|
||||
uint32_t length = 0;
|
||||
@ -262,8 +262,8 @@ MobileConnectionParent::NotifyRadioStateChanged()
|
||||
NS_ENSURE_TRUE(mLive, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv;
|
||||
nsAutoString radioState;
|
||||
rv = mMobileConnection->GetRadioState(radioState);
|
||||
int32_t radioState;
|
||||
rv = mMobileConnection->GetRadioState(&radioState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return SendNotifyRadioStateChanged(radioState) ? NS_OK : NS_ERROR_FAILURE;
|
||||
|
@ -52,7 +52,7 @@ protected:
|
||||
RecvInit(nsMobileConnectionInfo* aVoice, nsMobileConnectionInfo* aData,
|
||||
nsString* aLastKnownNetwork, nsString* aLastKnownHomeNetwork,
|
||||
nsString* aIccId, int32_t* aNetworkSelectionMode,
|
||||
nsString* aRadioState, nsTArray<nsString>* aSupportedNetworkTypes) MOZ_OVERRIDE;
|
||||
int32_t* aRadioState, nsTArray<nsString>* aSupportedNetworkTypes) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIMobileConnection> mMobileConnection;
|
||||
|
@ -28,7 +28,7 @@ child:
|
||||
NotifyEmergencyCbModeChanged(bool aActive, uint32_t aTimeoutMs);
|
||||
NotifyOtaStatusChanged(nsString aStatus);
|
||||
NotifyIccChanged(nsString aIccId);
|
||||
NotifyRadioStateChanged(nsString aRadioState);
|
||||
NotifyRadioStateChanged(int32_t aRadioState);
|
||||
NotifyClirModeChanged(uint32_t aMode);
|
||||
NotifyLastNetworkChanged(nsString aNetwork);
|
||||
NotifyLastHomeNetworkChanged(nsString aNetwork);
|
||||
@ -52,7 +52,7 @@ parent:
|
||||
returns (nsMobileConnectionInfo aVoice, nsMobileConnectionInfo aData,
|
||||
nsString aLastKnownNetwork, nsString aLastKnownHomeNetwork,
|
||||
nsString aIccId, int32_t aNetworkSelectionMode,
|
||||
nsString aRadioState, nsString[] aSupportedNetworkTypes);
|
||||
int32_t aRadioState, nsString[] aSupportedNetworkTypes);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -504,13 +504,15 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
|
||||
},
|
||||
|
||||
_isValidStateForSetRadioEnabled: function(radioState) {
|
||||
return radioState == RIL.GECKO_RADIOSTATE_ENABLED ||
|
||||
radioState == RIL.GECKO_RADIOSTATE_DISABLED;
|
||||
return radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED ||
|
||||
radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_DISABLED;
|
||||
},
|
||||
|
||||
_isDummyForSetRadioEnabled: function(radioState, data) {
|
||||
return (radioState == RIL.GECKO_RADIOSTATE_ENABLED && data.enabled) ||
|
||||
(radioState == RIL.GECKO_RADIOSTATE_DISABLED && !data.enabled);
|
||||
return (radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED &&
|
||||
data.enabled) ||
|
||||
(radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_DISABLED &&
|
||||
!data.enabled);
|
||||
},
|
||||
|
||||
_handleMessage: function(message) {
|
||||
@ -573,15 +575,15 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
|
||||
let radioInterface = _ril.getRadioInterface(clientId);
|
||||
|
||||
this.notifyRadioStateChanged(clientId,
|
||||
enabled ? RIL.GECKO_RADIOSTATE_ENABLING
|
||||
: RIL.GECKO_RADIOSTATE_DISABLING);
|
||||
enabled ? Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLING
|
||||
: Ci.nsIMobileConnection.MOBILE_RADIO_STATE_DISABLING);
|
||||
radioInterface.workerMessenger.send("setRadioEnabled", message.data,
|
||||
(function(response) {
|
||||
if (response.errorMsg) {
|
||||
// Request fails. Rollback to the original radioState.
|
||||
this.notifyRadioStateChanged(clientId,
|
||||
enabled ? RIL.GECKO_RADIOSTATE_DISABLED
|
||||
: RIL.GECKO_RADIOSTATE_ENABLED);
|
||||
enabled ? Ci.nsIMobileConnection.MOBILE_RADIO_STATE_DISABLED
|
||||
: Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED);
|
||||
}
|
||||
message.callback(response);
|
||||
return false;
|
||||
@ -1197,7 +1199,7 @@ DataConnectionHandler.prototype = {
|
||||
// This check avoids data call connection if the radio is not ready
|
||||
// yet after toggling off airplane mode.
|
||||
let radioState = connection && connection.radioState;
|
||||
if (radioState != RIL.GECKO_RADIOSTATE_ENABLED) {
|
||||
if (radioState != Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED) {
|
||||
if (DEBUG) {
|
||||
this.debug("RIL is not ready for data connection: radio's not ready");
|
||||
}
|
||||
@ -3525,8 +3527,8 @@ RadioInterface.prototype = {
|
||||
if (DEBUG) this.debug("Error! Address is invalid when sending SMS: " +
|
||||
options.number);
|
||||
errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR;
|
||||
} else if (radioState == null ||
|
||||
radioState == RIL.GECKO_RADIOSTATE_DISABLED) {
|
||||
} else if (radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_UNKNOWN ||
|
||||
radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_DISABLED) {
|
||||
if (DEBUG) this.debug("Error! Radio is disabled when sending SMS.");
|
||||
errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR;
|
||||
} else if (this.rilContext.cardState != Ci.nsIIccProvider.CARD_STATE_READY) {
|
||||
|
@ -2490,12 +2490,12 @@ this.CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242;
|
||||
this.CALL_FAIL_IMEI_NOT_ACCEPTED = 243;
|
||||
this.CALL_FAIL_ERROR_UNSPECIFIED = 0xffff;
|
||||
|
||||
// Other Gecko-specific constants
|
||||
this.GECKO_RADIOSTATE_UNKNOWN = null;
|
||||
this.GECKO_RADIOSTATE_ENABLING = "enabling";
|
||||
this.GECKO_RADIOSTATE_ENABLED = "enabled";
|
||||
this.GECKO_RADIOSTATE_DISABLING = "disabling";
|
||||
this.GECKO_RADIOSTATE_DISABLED = "disabled";
|
||||
// See nsIMobileConnection::MOBILE_RADIO_STATE_*
|
||||
this.GECKO_RADIOSTATE_UNKNOWN = -1;
|
||||
this.GECKO_RADIOSTATE_ENABLING = 0;
|
||||
this.GECKO_RADIOSTATE_ENABLED = 1;
|
||||
this.GECKO_RADIOSTATE_DISABLING = 2;
|
||||
this.GECKO_RADIOSTATE_DISABLED = 3;
|
||||
|
||||
// Only used in ril_worker.js
|
||||
this.GECKO_CARDSTATE_UNINITIALIZED = 4294967294; // UINT32_MAX - 1
|
||||
|
@ -44,11 +44,13 @@ var mgmtProps = {
|
||||
uninstall: "function",
|
||||
oninstall: "object",
|
||||
onuninstall: "object",
|
||||
onenabledstatechange: "object",
|
||||
ownerGlobal: "object",
|
||||
removeEventListener: "function",
|
||||
setEventHandler: "function",
|
||||
extractManifest: "function",
|
||||
import: "function"
|
||||
import: "function",
|
||||
setEnabled: "function"
|
||||
};
|
||||
|
||||
isDeeply([p for (p in navigator.mozApps.mgmt)].sort(),
|
||||
|
@ -32,6 +32,7 @@ interface DOMApplication : EventTarget {
|
||||
readonly attribute DOMString installOrigin;
|
||||
readonly attribute DOMTimeStamp installTime;
|
||||
readonly attribute boolean removable;
|
||||
readonly attribute boolean enabled;
|
||||
|
||||
[Cached, Pure]
|
||||
readonly attribute sequence<DOMString> receipts;
|
||||
@ -96,6 +97,9 @@ interface DOMApplicationsManager : EventTarget {
|
||||
Promise<DOMApplication> import(Blob blob);
|
||||
Promise<any> extractManifest(Blob blob);
|
||||
|
||||
void setEnabled(DOMApplication app, boolean state);
|
||||
|
||||
attribute EventHandler oninstall;
|
||||
attribute EventHandler onuninstall;
|
||||
attribute EventHandler onenabledstatechange;
|
||||
};
|
||||
|
@ -1347,6 +1347,7 @@ ParentImpl::CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aCtx->GetContentParent());
|
||||
|
||||
const ProtocolId protocolId = GetProtocolId();
|
||||
|
||||
@ -1363,7 +1364,7 @@ ParentImpl::CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
|
||||
}
|
||||
|
||||
PBackgroundParent* clonedActor =
|
||||
Alloc(mContent, transport, base::GetProcId(aPeerProcess));
|
||||
Alloc(aCtx->GetContentParent(), transport, base::GetProcId(aPeerProcess));
|
||||
MOZ_ASSERT(clonedActor);
|
||||
|
||||
clonedActor->CloneManagees(this, aCtx);
|
||||
|
@ -19,6 +19,7 @@ import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
@ -134,6 +135,13 @@ public final class ANRReporter extends BroadcastReceiver
|
||||
|
||||
// Return the "traces.txt" file, or null if there is no such file
|
||||
private static File getTracesFile() {
|
||||
// Check most common location first.
|
||||
File tracesFile = new File("/data/anr/traces.txt");
|
||||
if (tracesFile.isFile() && tracesFile.canRead()) {
|
||||
return tracesFile;
|
||||
}
|
||||
|
||||
// Find the traces file name if we can.
|
||||
try {
|
||||
// getprop [prop-name [default-value]]
|
||||
Process propProc = (new ProcessBuilder())
|
||||
@ -150,7 +158,7 @@ public final class ANRReporter extends BroadcastReceiver
|
||||
// getprop can return empty string when the prop value is empty
|
||||
// or prop is undefined, treat both cases the same way
|
||||
if (propVal != null && propVal.length() != 0) {
|
||||
File tracesFile = new File(propVal);
|
||||
tracesFile = new File(propVal);
|
||||
if (tracesFile.isFile() && tracesFile.canRead()) {
|
||||
return tracesFile;
|
||||
} else if (DEBUG) {
|
||||
@ -167,11 +175,6 @@ public final class ANRReporter extends BroadcastReceiver
|
||||
} catch (ClassCastException e) {
|
||||
Log.w(LOGTAG, e); // Bug 975436
|
||||
}
|
||||
// Check most common location one last time just in case
|
||||
File tracesFile = new File("/data/anr/traces.txt");
|
||||
if (tracesFile.isFile() && tracesFile.canRead()) {
|
||||
return tracesFile;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -407,14 +410,11 @@ public final class ANRReporter extends BroadcastReceiver
|
||||
return total;
|
||||
}
|
||||
|
||||
private static void fillPingFooter(OutputStream ping,
|
||||
boolean haveNativeStack)
|
||||
throws IOException {
|
||||
|
||||
// We are at the end of ANR data
|
||||
|
||||
int total = writePingPayload(ping, ("\"," +
|
||||
"\"androidLogcat\":\""));
|
||||
private static void fillLogcat(final OutputStream ping) {
|
||||
if (Versions.preJB) {
|
||||
// Logcat retrieval is not supported on pre-JB devices.
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// get the last 200 lines of logcat
|
||||
@ -435,6 +435,17 @@ public final class ANRReporter extends BroadcastReceiver
|
||||
// ignore because logcat is not essential
|
||||
Log.w(LOGTAG, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void fillPingFooter(OutputStream ping,
|
||||
boolean haveNativeStack)
|
||||
throws IOException {
|
||||
|
||||
// We are at the end of ANR data
|
||||
|
||||
int total = writePingPayload(ping, ("\"," +
|
||||
"\"androidLogcat\":\""));
|
||||
fillLogcat(ping);
|
||||
|
||||
if (haveNativeStack) {
|
||||
total += writePingPayload(ping, ("\"," +
|
||||
|
@ -501,6 +501,7 @@ public class BrowserApp extends GeckoApp
|
||||
mMediaCastingBar = (MediaCastingBar) findViewById(R.id.media_casting);
|
||||
|
||||
EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener)this,
|
||||
"Menu:Open",
|
||||
"Menu:Update",
|
||||
"Search:Keyword",
|
||||
"Prompt:ShowTop",
|
||||
@ -1047,6 +1048,7 @@ public class BrowserApp extends GeckoApp
|
||||
}
|
||||
|
||||
EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventListener)this,
|
||||
"Menu:Open",
|
||||
"Menu:Update",
|
||||
"Search:Keyword",
|
||||
"Prompt:ShowTop",
|
||||
@ -1482,7 +1484,13 @@ public class BrowserApp extends GeckoApp
|
||||
@Override
|
||||
public void handleMessage(String event, JSONObject message) {
|
||||
try {
|
||||
if (event.equals("Menu:Update")) {
|
||||
if (event.equals("Menu:Open")) {
|
||||
if (mBrowserToolbar.isEditing()) {
|
||||
mBrowserToolbar.cancelEdit();
|
||||
}
|
||||
|
||||
openOptionsMenu();
|
||||
} else if (event.equals("Menu:Update")) {
|
||||
final int id = message.getInt("id") + ADDON_MENU_OFFSET;
|
||||
final JSONObject options = message.getJSONObject("options");
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
|
@ -180,8 +180,10 @@ class CrashHandler implements Thread.UncaughtExceptionHandler {
|
||||
}
|
||||
|
||||
protected String getAppPackageName() {
|
||||
if (appContext != null) {
|
||||
return appContext.getPackageName();
|
||||
final Context context = getAppContext();
|
||||
|
||||
if (context != null) {
|
||||
return context.getPackageName();
|
||||
}
|
||||
|
||||
try {
|
||||
@ -206,6 +208,10 @@ class CrashHandler implements Thread.UncaughtExceptionHandler {
|
||||
return getJavaPackageName();
|
||||
}
|
||||
|
||||
protected Context getAppContext() {
|
||||
return appContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the crash "extras" to be reported.
|
||||
*
|
||||
@ -213,8 +219,8 @@ class CrashHandler implements Thread.UncaughtExceptionHandler {
|
||||
* @param exc An exception
|
||||
* @return "Extras" in the from of a Bundle
|
||||
*/
|
||||
protected Bundle getCrashExtras(final Thread thread, final Throwable exc,
|
||||
final Context appContext) {
|
||||
protected Bundle getCrashExtras(final Thread thread, final Throwable exc) {
|
||||
final Context context = getAppContext();
|
||||
final Bundle extras = new Bundle();
|
||||
final String pkgName = getAppPackageName();
|
||||
|
||||
@ -222,8 +228,8 @@ class CrashHandler implements Thread.UncaughtExceptionHandler {
|
||||
extras.putLong("CrashTime", getCrashTime());
|
||||
extras.putLong("StartupTime", getStartupTime());
|
||||
|
||||
if (appContext != null) {
|
||||
final PackageManager pkgMgr = appContext.getPackageManager();
|
||||
if (context != null) {
|
||||
final PackageManager pkgMgr = context.getPackageManager();
|
||||
try {
|
||||
final PackageInfo pkgInfo = pkgMgr.getPackageInfo(pkgName, 0);
|
||||
extras.putString("Version", pkgInfo.versionName);
|
||||
@ -277,17 +283,18 @@ class CrashHandler implements Thread.UncaughtExceptionHandler {
|
||||
*/
|
||||
protected boolean launchCrashReporter(final String dumpFile, final String extraFile) {
|
||||
try {
|
||||
final Context context = getAppContext();
|
||||
final String javaPkg = getJavaPackageName();
|
||||
final String pkg = getAppPackageName();
|
||||
final String component = javaPkg + ".CrashReporter";
|
||||
final String action = javaPkg + ".reportCrash";
|
||||
final ProcessBuilder pb;
|
||||
|
||||
if (appContext != null) {
|
||||
if (context != null) {
|
||||
final Intent intent = new Intent(action);
|
||||
intent.setComponent(new ComponentName(pkg, component));
|
||||
intent.putExtra("minidumpPath", dumpFile);
|
||||
appContext.startActivity(intent);
|
||||
context.startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -329,12 +336,13 @@ class CrashHandler implements Thread.UncaughtExceptionHandler {
|
||||
* @return Whether the exception was successfully reported
|
||||
*/
|
||||
protected boolean reportException(final Thread thread, final Throwable exc) {
|
||||
final Context context = getAppContext();
|
||||
final String id = UUID.randomUUID().toString();
|
||||
|
||||
// Use the cache directory under the app directory to store crash files.
|
||||
final File dir;
|
||||
if (appContext != null) {
|
||||
dir = appContext.getCacheDir();
|
||||
if (context != null) {
|
||||
dir = context.getCacheDir();
|
||||
} else {
|
||||
dir = new File("/data/data/" + getAppPackageName() + "/cache");
|
||||
}
|
||||
@ -366,7 +374,7 @@ class CrashHandler implements Thread.UncaughtExceptionHandler {
|
||||
try {
|
||||
// Write out crash extra file as text.
|
||||
|
||||
final Bundle extras = getCrashExtras(thread, exc, appContext);
|
||||
final Bundle extras = getCrashExtras(thread, exc);
|
||||
final String url = getServerUrl(extras);
|
||||
extras.putString("ServerURL", url);
|
||||
|
||||
|
@ -21,6 +21,8 @@ import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
@ -395,7 +397,7 @@ public class CrashReporter extends Activity
|
||||
Log.e(LOGTAG, "Exception while sending SDK version 8 keys", ex);
|
||||
}
|
||||
sendPart(os, boundary, "Android_Version", Build.VERSION.SDK_INT + " (" + Build.VERSION.CODENAME + ")");
|
||||
if (Build.VERSION.SDK_INT >= 16 && includeURLCheckbox.isChecked()) {
|
||||
if (Versions.feature16Plus && includeURLCheckbox.isChecked()) {
|
||||
sendPart(os, boundary, "Android_Logcat", readLogcat());
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user