From f937a8f54c7f1c0555f39f2cfb575cecd2be7656 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Thu, 15 Aug 2013 15:51:25 -0700 Subject: [PATCH 01/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/1895155057c8 Author: James Lal Desc: Merge pull request #11360 from ganesh7/icalGmtParser ical Gmt parser fix ======== https://hg.mozilla.org/integration/gaia-central/rev/2fa181078cfc Author: gghosh Desc: Bug 881214 - when importing caldav calendar repeated events are ignored --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 85bf45de6ff..fe775738d19 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "340f6676fc5dc34f1b9ab0c40169c0c4fd744587", + "revision": "1895155057c87d3d496c7c3a5e4b80daddb0d934", "repo_path": "/integration/gaia-central" } From 2a589f1c5d05645bb58d6b7a4df382a28ab1af98 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Thu, 15 Aug 2013 17:35:24 -0700 Subject: [PATCH 02/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/a768710558aa Author: Kevin Grandon Desc: Merge pull request #11565 from lightsofapollo/turn-off-horrible-strict Bug 905868 - Turn off options.strict r=kgrandon ======== https://hg.mozilla.org/integration/gaia-central/rev/131bc8e79c59 Author: James Lal Desc: Bug 905868 - Turn off options.strict --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index fe775738d19..aa988b6e775 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "1895155057c87d3d496c7c3a5e4b80daddb0d934", + "revision": "a768710558aa825eb4fda59368d1698367f82f0d", "repo_path": "/integration/gaia-central" } From 4ad5a69b47e1d002ec545abaff4a801c1b3c26d8 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Thu, 15 Aug 2013 19:05:25 -0700 Subject: [PATCH 03/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/00c39a36e9b2 Author: Gareth Aye Desc: Merge pull request #11564 from lightsofapollo/travis-mc Bug 905875 - Switch unit tests to mozilla-central ======== https://hg.mozilla.org/integration/gaia-central/rev/46c69dda00db Author: James Lal Desc: Bug 905875- Switch unit tests to mozilla-central --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index aa988b6e775..32680241abd 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "a768710558aa825eb4fda59368d1698367f82f0d", + "revision": "00c39a36e9b279e724bd628f78c63849612c0e86", "repo_path": "/integration/gaia-central" } From 7f43aee6e603ce1d2e3ad9bd0ef22c087cab890b Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Thu, 15 Aug 2013 19:15:24 -0700 Subject: [PATCH 04/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/c7cc7f2cd0af Author: James Lal Desc: Merge pull request #11445 from gaye/bug-903220 Bug 903220 - Write a marionette test for creating a calendar event a=test-only r=lightsofapollo ======== https://hg.mozilla.org/integration/gaia-central/rev/1bff6b89fbd9 Author: gaye Desc: Bug 903220 - Write a marionette test for creating a calendar event a=test-only r=lightsofapollo --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 32680241abd..5e9fde461db 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "00c39a36e9b279e724bd628f78c63849612c0e86", + "revision": "c7cc7f2cd0af679058ae7a44d52c2bb012809a62", "repo_path": "/integration/gaia-central" } From a6e48882f8c21242b95fc046e51f6c850d776873 Mon Sep 17 00:00:00 2001 From: Vincent Chang Date: Mon, 29 Jul 2013 17:59:53 +0800 Subject: [PATCH 05/27] Bug 897871 - Wifi - Improve wifi startup time. r=mrbkap --- dom/wifi/WifiWorker.js | 272 +++++++++++++++++++++++------------------ 1 file changed, 151 insertions(+), 121 deletions(-) diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js index 2f7fe5bf6a9..a0f6f0686db 100644 --- a/dom/wifi/WifiWorker.js +++ b/dom/wifi/WifiWorker.js @@ -10,6 +10,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/systemlibs.js"); var DEBUG = false; // set to true to show debug messages. @@ -67,6 +68,15 @@ const WIFI_SECURITY_TYPE_WPA2_PSK = "wpa2-psk"; const NETWORK_INTERFACE_UP = "up"; const NETWORK_INTERFACE_DOWN = "down"; +const DEFAULT_WLAN_INTERFACE = "wlan0"; + +const DRIVER_READY_WAIT = 2000; + +const SUPP_PROP = "init.svc.wpa_supplicant"; +const WPA_SUPPLICANT = "wpa_supplicant"; +const DHCP_PROP = "init.svc.dhcpcd"; +const DHCP = "dhcpcd"; + XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager", "@mozilla.org/network/manager;1", "nsINetworkManager"); @@ -84,21 +94,28 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", // expected results). var WifiManager = (function() { function getStartupPrefs() { - Cu.import("resource://gre/modules/systemlibs.js"); return { sdkVersion: parseInt(libcutils.property_get("ro.build.version.sdk"), 10), unloadDriverEnabled: libcutils.property_get("ro.moz.wifi.unloaddriver") === "1", - schedScanRecovery: libcutils.property_get("ro.moz.wifi.sched_scan_recover") === "false" ? false : true + schedScanRecovery: libcutils.property_get("ro.moz.wifi.sched_scan_recover") === "false" ? false : true, + driverDelay: libcutils.property_get("ro.moz.wifi.driverDelay"), + ifname: libcutils.property_get("wifi.interface") }; } - let {sdkVersion, unloadDriverEnabled, schedScanRecovery} = getStartupPrefs(); + let {sdkVersion, unloadDriverEnabled, schedScanRecovery, driverDelay, ifname} = getStartupPrefs(); var controlWorker = new ChromeWorker(WIFIWORKER_WORKER); var eventWorker = new ChromeWorker(WIFIWORKER_WORKER); var manager = {}; + manager.ifname = ifname; + if (!ifname) { + debug("Can't get wifi interface name, please debug it."); + manager.ifname = DEFAULT_WLAN_INTERFACE; + } manager.schedScanRecovery = schedScanRecovery; + manager.driverDelay = driverDelay ? parseInt(driverDelay, 10) : DRIVER_READY_WAIT; // Callbacks to invoke when a reply arrives from the controlWorker. var controlCallbacks = Object.create(null); @@ -704,12 +721,38 @@ var WifiManager = (function() { }); } + function stopProcess(service, process, callback) { + var count = 0; + var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + function tick() { + let result = libcutils.property_get(service); + if (result === null) { + callback(); + return; + } + if (result === "stopped" || ++count >= 5) { + // Either we succeeded or ran out of time. + timer = null; + callback(); + return; + } + + // Else it's still running, continue waiting. + timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); + } + + setProperty("ctl.stop", process, tick); + } + function stopDhcp(ifname, callback) { - controlMessage({ cmd: "dhcp_stop", ifname: ifname }, function(data) { - dhcpInfo = null; - notify("dhcplost"); - callback(!data.status); - }); + // This function does exactly what dhcp_stop does. Unforunately, if we call + // this function twice before the previous callback is returned. We may block + // our self waiting for the callback. It slows down the wifi startup procedure. + // Therefore, we have to roll our own version here. + let dhcpService = DHCP_PROP + "_" + ifname; + let suffix = (ifname.substr(0, 3) === "p2p") ? "p2p" : ifname; + let processName = DHCP + "_" + suffix; + stopProcess(dhcpService, processName, callback); } function releaseDhcpLease(ifname, callback) { @@ -1107,34 +1150,13 @@ var WifiManager = (function() { return true; } - const SUPP_PROP = "init.svc.wpa_supplicant"; function killSupplicant(callback) { // It is interesting to note that this function does exactly what // wifi_stop_supplicant does. Unforunately, on the Galaxy S2, Samsung // changed that function in a way that means that it doesn't recognize // wpa_supplicant as already running. Therefore, we have to roll our own // version here. - var count = 0; - var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - function tick() { - getProperty(SUPP_PROP, "stopped", function (result) { - if (result === null) { - callback(); - return; - } - if (result === "stopped" || ++count >= 5) { - // Either we succeeded or ran out of time. - timer = null; - callback(); - return; - } - - // Else it's still running, continue waiting. - timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); - }); - } - - setProperty("ctl.stop", "wpa_supplicant", tick); + stopProcess(SUPP_PROP, WPA_SUPPLICANT, callback); } function didConnectSupplicant(callback) { @@ -1152,10 +1174,24 @@ var WifiManager = (function() { } function prepareForStartup(callback) { + let status = libcutils.property_get(DHCP_PROP + "_" + manager.ifname); + if (status !== "running") { + tryStopSupplicant(); + return; + } manager.connectionDropped(function() { - // Ignore any errors and kill any currently-running supplicants. On some - // phones, stopSupplicant won't work for a supplicant that we didn't - // start, so we hand-roll it here. + tryStopSupplicant(); + }); + + // Ignore any errors and kill any currently-running supplicants. On some + // phones, stopSupplicant won't work for a supplicant that we didn't + // start, so we hand-roll it here. + function tryStopSupplicant () { + let status = libcutils.property_get(SUPP_PROP); + if (status !== "running") { + callback(); + return; + } suppressEvents = true; killSupplicant(function() { disableInterface(manager.ifname, function (ok) { @@ -1163,7 +1199,7 @@ var WifiManager = (function() { callback(); }); }); - }); + } } // Initial state. @@ -1175,7 +1211,6 @@ var WifiManager = (function() { manager.authenticationFailuresCount = 0; manager.loopDetectionCount = 0; - const DRIVER_READY_WAIT = 2000; var waitForDriverReadyTimer = null; function cancelWaitForDriverReadyTimer() { if (waitForDriverReadyTimer) { @@ -1186,7 +1221,7 @@ var WifiManager = (function() { function createWaitForDriverReadyTimer(onTimeout) { waitForDriverReadyTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); waitForDriverReadyTimer.initWithCallback(onTimeout, - DRIVER_READY_WAIT, + manager.driverDelay, Ci.nsITimer.TYPE_ONE_SHOT); }; @@ -1199,71 +1234,64 @@ var WifiManager = (function() { if (enable) { manager.state = "INITIALIZING"; - // Kill any existing connections if necessary. - getProperty("wifi.interface", "tiwlan0", function (ifname) { - if (!ifname) { - callback(-1); - manager.state = "UNINITIALIZED"; - return; - } - manager.ifname = ifname; - - // Register as network interface. - WifiNetworkInterface.name = ifname; - if (!WifiNetworkInterface.registered) { - gNetworkManager.registerNetworkInterface(WifiNetworkInterface); - WifiNetworkInterface.registered = true; - } - WifiNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED; - WifiNetworkInterface.ip = null; - WifiNetworkInterface.netmask = null; - WifiNetworkInterface.broadcast = null; - WifiNetworkInterface.gateway = null; - WifiNetworkInterface.dns1 = null; - WifiNetworkInterface.dns2 = null; - Services.obs.notifyObservers(WifiNetworkInterface, - kNetworkInterfaceStateChangedTopic, - null); - - prepareForStartup(function() { - loadDriver(function (status) { + // Register as network interface. + WifiNetworkInterface.name = manager.ifname; + if (!WifiNetworkInterface.registered) { + gNetworkManager.registerNetworkInterface(WifiNetworkInterface); + WifiNetworkInterface.registered = true; + } + WifiNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED; + WifiNetworkInterface.ip = null; + WifiNetworkInterface.netmask = null; + WifiNetworkInterface.broadcast = null; + WifiNetworkInterface.gateway = null; + WifiNetworkInterface.dns1 = null; + WifiNetworkInterface.dns2 = null; + Services.obs.notifyObservers(WifiNetworkInterface, + kNetworkInterfaceStateChangedTopic, + null); + prepareForStartup(function() { + loadDriver(function (status) { + if (status < 0) { + callback(status); + manager.state = "UNINITIALIZED"; + return; + } + gNetworkManager.setWifiOperationMode(ifname, + WIFI_FIRMWARE_STATION, + function (status) { if (status) { callback(status); manager.state = "UNINITIALIZED"; return; } - gNetworkManager.setWifiOperationMode(ifname, - WIFI_FIRMWARE_STATION, - function (status) { - if (status < 0) { - callback(status); - manager.state = "UNINITIALIZED"; - return; - } - function doStartSupplicant() { - cancelWaitForDriverReadyTimer(); - startSupplicant(function (status) { - if (status < 0) { - unloadDriver(function() { - callback(status); - }); - manager.state = "UNINITIALIZED"; - return; - } + function doStartSupplicant() { + cancelWaitForDriverReadyTimer(); + startSupplicant(function (status) { + if (status < 0) { + unloadDriver(function() { + callback(status); - manager.supplicantStarted = true; - enableInterface(ifname, function (ok) { - callback(ok ? 0 : -1); }); - }); - } + manager.state = "UNINITIALIZED"; + return; + } - // Driver startup on certain platforms takes longer than it takes for us - // to return from loadDriver, so wait 2 seconds before starting - // the supplicant to give it a chance to start. + manager.supplicantStarted = true; + enableInterface(ifname, function (ok) { + callback(ok ? 0 : -1); + }); + }); + } + // Driver startup on certain platforms takes longer than it takes for us + // to return from loadDriver, so wait 2 seconds before starting + // the supplicant to give it a chance to start. + if (manager.driverDelay > 0) { createWaitForDriverReadyTimer(doStartSupplicant); - }); + } else { + doStartSupplicant(); + } }); }); }); @@ -1290,42 +1318,34 @@ var WifiManager = (function() { manager.setWifiApEnabled = function(enabled, configuration, callback) { if (enabled) { manager.tetheringState = "INITIALIZING"; - getProperty("wifi.interface", "tiwlan0", function (ifname) { - if (!ifname) { + loadDriver(function (status) { + if (status < 0) { callback(); manager.tetheringState = "UNINITIALIZED"; return; } - manager.ifname = ifname; - loadDriver(function (status) { - if (status < 0) { + + function doStartWifiTethering() { + cancelWaitForDriverReadyTimer(); + WifiNetworkInterface.name = manager.ifname; + gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface, + configuration, function(result) { + if (result) { + manager.tetheringState = "UNINITIALIZED"; + } else { + manager.tetheringState = "COMPLETED"; + } + // Pop out current request. callback(); - manager.tetheringState = "UNINITIALIZED"; - return; - } + // Should we fire a dom event if we fail to set wifi tethering ? + debug("Enable Wifi tethering result: " + (result ? result : "successfully")); + }); + } - function doStartWifiTethering() { - cancelWaitForDriverReadyTimer(); - WifiNetworkInterface.name = manager.ifname; - gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface, - configuration, function(result) { - if (result) { - manager.tetheringState = "UNINITIALIZED"; - } else { - manager.tetheringState = "COMPLETED"; - } - // Pop out current request. - callback(); - // Should we fire a dom event if we fail to set wifi tethering ? - debug("Enable Wifi tethering result: " + (result ? result : "successfully")); - }); - } - - // Driver startup on certain platforms takes longer than it takes - // for us to return from loadDriver, so wait 2 seconds before - // turning on Wifi tethering. - createWaitForDriverReadyTimer(doStartWifiTethering); - }); + // Driver startup on certain platforms takes longer than it takes + // for us to return from loadDriver, so wait 2 seconds before + // turning on Wifi tethering. + createWaitForDriverReadyTimer(doStartWifiTethering); }); } else { gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface, @@ -2153,6 +2173,16 @@ function WifiWorker() { self.currentNetwork.bssid = WifiManager.connectionInfo.bssid; break; case "DISCONNECTED": + // wpa_supplicant may give us a "DISCONNECTED" event even if + // we are already in "DISCONNECTED" state. + if (this.prevState === "INITIALIZING" || + this.prevState === "DISCONNECTED" || + this.prevState === "INTERFACE_DISABLED" || + this.prevState === "INACTIVE" || + this.prevState === "UNINITIALIZED") { + return; + } + self._fireEvent("ondisconnect", {}); self.currentNetwork = null; self.ipAddress = ""; From f585208327db5c25fe7bc44bf71fcabca8dc3193 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Thu, 15 Aug 2013 22:05:25 -0700 Subject: [PATCH 06/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/a4f204058209 Author: James Lal Desc: Merge pull request #11551 from KevinGrandon/bug_817564_remove_day_label Bug 817564 - Remove day header label ======== https://hg.mozilla.org/integration/gaia-central/rev/913973b11d58 Author: Kevin Grandon Desc: Bug 817564 - Remove day header label --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 5e9fde461db..d88bf6aebe2 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "c7cc7f2cd0af679058ae7a44d52c2bb012809a62", + "revision": "a4f204058209a0f1dcb80c628362f1b7226b6d4a", "repo_path": "/integration/gaia-central" } From 94c100a1e7e220abac55d48e939cee4937a314f9 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Thu, 15 Aug 2013 23:35:23 -0700 Subject: [PATCH 07/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/96e8482e036f Author: Arthur Chen Desc: Merge pull request #11518 from crh0716/886002 Bug 886002 - Reset the stack bar everytime we are trying to refresh it r=evelyn ======== https://hg.mozilla.org/integration/gaia-central/rev/780f28b582ee Author: crh0716 Desc: Bug 886002 - Reset the stack bar everytime we are trying to refresh it --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index d88bf6aebe2..1c466fb7d9a 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "a4f204058209a0f1dcb80c628362f1b7226b6d4a", + "revision": "96e8482e036ff46d6f0ae11a9622e21a80852541", "repo_path": "/integration/gaia-central" } From 6b2c6e0f3db20b760a1b3ff670c7e382cc92bcb9 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Fri, 16 Aug 2013 10:45:14 +0100 Subject: [PATCH 08/27] Backed out changeset 1a2f028d66cf (bug 897871) for Marionette failures --- dom/wifi/WifiWorker.js | 272 ++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 151 deletions(-) diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js index a0f6f0686db..2f7fe5bf6a9 100644 --- a/dom/wifi/WifiWorker.js +++ b/dom/wifi/WifiWorker.js @@ -10,7 +10,6 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/systemlibs.js"); var DEBUG = false; // set to true to show debug messages. @@ -68,15 +67,6 @@ const WIFI_SECURITY_TYPE_WPA2_PSK = "wpa2-psk"; const NETWORK_INTERFACE_UP = "up"; const NETWORK_INTERFACE_DOWN = "down"; -const DEFAULT_WLAN_INTERFACE = "wlan0"; - -const DRIVER_READY_WAIT = 2000; - -const SUPP_PROP = "init.svc.wpa_supplicant"; -const WPA_SUPPLICANT = "wpa_supplicant"; -const DHCP_PROP = "init.svc.dhcpcd"; -const DHCP = "dhcpcd"; - XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager", "@mozilla.org/network/manager;1", "nsINetworkManager"); @@ -94,28 +84,21 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService", // expected results). var WifiManager = (function() { function getStartupPrefs() { + Cu.import("resource://gre/modules/systemlibs.js"); return { sdkVersion: parseInt(libcutils.property_get("ro.build.version.sdk"), 10), unloadDriverEnabled: libcutils.property_get("ro.moz.wifi.unloaddriver") === "1", - schedScanRecovery: libcutils.property_get("ro.moz.wifi.sched_scan_recover") === "false" ? false : true, - driverDelay: libcutils.property_get("ro.moz.wifi.driverDelay"), - ifname: libcutils.property_get("wifi.interface") + schedScanRecovery: libcutils.property_get("ro.moz.wifi.sched_scan_recover") === "false" ? false : true }; } - let {sdkVersion, unloadDriverEnabled, schedScanRecovery, driverDelay, ifname} = getStartupPrefs(); + let {sdkVersion, unloadDriverEnabled, schedScanRecovery} = getStartupPrefs(); var controlWorker = new ChromeWorker(WIFIWORKER_WORKER); var eventWorker = new ChromeWorker(WIFIWORKER_WORKER); var manager = {}; - manager.ifname = ifname; - if (!ifname) { - debug("Can't get wifi interface name, please debug it."); - manager.ifname = DEFAULT_WLAN_INTERFACE; - } manager.schedScanRecovery = schedScanRecovery; - manager.driverDelay = driverDelay ? parseInt(driverDelay, 10) : DRIVER_READY_WAIT; // Callbacks to invoke when a reply arrives from the controlWorker. var controlCallbacks = Object.create(null); @@ -721,38 +704,12 @@ var WifiManager = (function() { }); } - function stopProcess(service, process, callback) { - var count = 0; - var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - function tick() { - let result = libcutils.property_get(service); - if (result === null) { - callback(); - return; - } - if (result === "stopped" || ++count >= 5) { - // Either we succeeded or ran out of time. - timer = null; - callback(); - return; - } - - // Else it's still running, continue waiting. - timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); - } - - setProperty("ctl.stop", process, tick); - } - function stopDhcp(ifname, callback) { - // This function does exactly what dhcp_stop does. Unforunately, if we call - // this function twice before the previous callback is returned. We may block - // our self waiting for the callback. It slows down the wifi startup procedure. - // Therefore, we have to roll our own version here. - let dhcpService = DHCP_PROP + "_" + ifname; - let suffix = (ifname.substr(0, 3) === "p2p") ? "p2p" : ifname; - let processName = DHCP + "_" + suffix; - stopProcess(dhcpService, processName, callback); + controlMessage({ cmd: "dhcp_stop", ifname: ifname }, function(data) { + dhcpInfo = null; + notify("dhcplost"); + callback(!data.status); + }); } function releaseDhcpLease(ifname, callback) { @@ -1150,13 +1107,34 @@ var WifiManager = (function() { return true; } + const SUPP_PROP = "init.svc.wpa_supplicant"; function killSupplicant(callback) { // It is interesting to note that this function does exactly what // wifi_stop_supplicant does. Unforunately, on the Galaxy S2, Samsung // changed that function in a way that means that it doesn't recognize // wpa_supplicant as already running. Therefore, we have to roll our own // version here. - stopProcess(SUPP_PROP, WPA_SUPPLICANT, callback); + var count = 0; + var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + function tick() { + getProperty(SUPP_PROP, "stopped", function (result) { + if (result === null) { + callback(); + return; + } + if (result === "stopped" || ++count >= 5) { + // Either we succeeded or ran out of time. + timer = null; + callback(); + return; + } + + // Else it's still running, continue waiting. + timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT); + }); + } + + setProperty("ctl.stop", "wpa_supplicant", tick); } function didConnectSupplicant(callback) { @@ -1174,24 +1152,10 @@ var WifiManager = (function() { } function prepareForStartup(callback) { - let status = libcutils.property_get(DHCP_PROP + "_" + manager.ifname); - if (status !== "running") { - tryStopSupplicant(); - return; - } manager.connectionDropped(function() { - tryStopSupplicant(); - }); - - // Ignore any errors and kill any currently-running supplicants. On some - // phones, stopSupplicant won't work for a supplicant that we didn't - // start, so we hand-roll it here. - function tryStopSupplicant () { - let status = libcutils.property_get(SUPP_PROP); - if (status !== "running") { - callback(); - return; - } + // Ignore any errors and kill any currently-running supplicants. On some + // phones, stopSupplicant won't work for a supplicant that we didn't + // start, so we hand-roll it here. suppressEvents = true; killSupplicant(function() { disableInterface(manager.ifname, function (ok) { @@ -1199,7 +1163,7 @@ var WifiManager = (function() { callback(); }); }); - } + }); } // Initial state. @@ -1211,6 +1175,7 @@ var WifiManager = (function() { manager.authenticationFailuresCount = 0; manager.loopDetectionCount = 0; + const DRIVER_READY_WAIT = 2000; var waitForDriverReadyTimer = null; function cancelWaitForDriverReadyTimer() { if (waitForDriverReadyTimer) { @@ -1221,7 +1186,7 @@ var WifiManager = (function() { function createWaitForDriverReadyTimer(onTimeout) { waitForDriverReadyTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); waitForDriverReadyTimer.initWithCallback(onTimeout, - manager.driverDelay, + DRIVER_READY_WAIT, Ci.nsITimer.TYPE_ONE_SHOT); }; @@ -1234,64 +1199,71 @@ var WifiManager = (function() { if (enable) { manager.state = "INITIALIZING"; - // Register as network interface. - WifiNetworkInterface.name = manager.ifname; - if (!WifiNetworkInterface.registered) { - gNetworkManager.registerNetworkInterface(WifiNetworkInterface); - WifiNetworkInterface.registered = true; - } - WifiNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED; - WifiNetworkInterface.ip = null; - WifiNetworkInterface.netmask = null; - WifiNetworkInterface.broadcast = null; - WifiNetworkInterface.gateway = null; - WifiNetworkInterface.dns1 = null; - WifiNetworkInterface.dns2 = null; - Services.obs.notifyObservers(WifiNetworkInterface, - kNetworkInterfaceStateChangedTopic, - null); - prepareForStartup(function() { - loadDriver(function (status) { - if (status < 0) { - callback(status); - manager.state = "UNINITIALIZED"; - return; - } - gNetworkManager.setWifiOperationMode(ifname, - WIFI_FIRMWARE_STATION, - function (status) { + // Kill any existing connections if necessary. + getProperty("wifi.interface", "tiwlan0", function (ifname) { + if (!ifname) { + callback(-1); + manager.state = "UNINITIALIZED"; + return; + } + manager.ifname = ifname; + + // Register as network interface. + WifiNetworkInterface.name = ifname; + if (!WifiNetworkInterface.registered) { + gNetworkManager.registerNetworkInterface(WifiNetworkInterface); + WifiNetworkInterface.registered = true; + } + WifiNetworkInterface.state = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED; + WifiNetworkInterface.ip = null; + WifiNetworkInterface.netmask = null; + WifiNetworkInterface.broadcast = null; + WifiNetworkInterface.gateway = null; + WifiNetworkInterface.dns1 = null; + WifiNetworkInterface.dns2 = null; + Services.obs.notifyObservers(WifiNetworkInterface, + kNetworkInterfaceStateChangedTopic, + null); + + prepareForStartup(function() { + loadDriver(function (status) { if (status) { callback(status); manager.state = "UNINITIALIZED"; return; } + gNetworkManager.setWifiOperationMode(ifname, + WIFI_FIRMWARE_STATION, + function (status) { + if (status < 0) { + callback(status); + manager.state = "UNINITIALIZED"; + return; + } - function doStartSupplicant() { - cancelWaitForDriverReadyTimer(); - startSupplicant(function (status) { - if (status < 0) { - unloadDriver(function() { - callback(status); + function doStartSupplicant() { + cancelWaitForDriverReadyTimer(); + startSupplicant(function (status) { + if (status < 0) { + unloadDriver(function() { + callback(status); + }); + manager.state = "UNINITIALIZED"; + return; + } + manager.supplicantStarted = true; + enableInterface(ifname, function (ok) { + callback(ok ? 0 : -1); }); - manager.state = "UNINITIALIZED"; - return; - } - - manager.supplicantStarted = true; - enableInterface(ifname, function (ok) { - callback(ok ? 0 : -1); }); - }); - } - // Driver startup on certain platforms takes longer than it takes for us - // to return from loadDriver, so wait 2 seconds before starting - // the supplicant to give it a chance to start. - if (manager.driverDelay > 0) { + } + + // Driver startup on certain platforms takes longer than it takes for us + // to return from loadDriver, so wait 2 seconds before starting + // the supplicant to give it a chance to start. createWaitForDriverReadyTimer(doStartSupplicant); - } else { - doStartSupplicant(); - } + }); }); }); }); @@ -1318,34 +1290,42 @@ var WifiManager = (function() { manager.setWifiApEnabled = function(enabled, configuration, callback) { if (enabled) { manager.tetheringState = "INITIALIZING"; - loadDriver(function (status) { - if (status < 0) { + getProperty("wifi.interface", "tiwlan0", function (ifname) { + if (!ifname) { callback(); manager.tetheringState = "UNINITIALIZED"; return; } - - function doStartWifiTethering() { - cancelWaitForDriverReadyTimer(); - WifiNetworkInterface.name = manager.ifname; - gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface, - configuration, function(result) { - if (result) { - manager.tetheringState = "UNINITIALIZED"; - } else { - manager.tetheringState = "COMPLETED"; - } - // Pop out current request. + manager.ifname = ifname; + loadDriver(function (status) { + if (status < 0) { callback(); - // Should we fire a dom event if we fail to set wifi tethering ? - debug("Enable Wifi tethering result: " + (result ? result : "successfully")); - }); - } + manager.tetheringState = "UNINITIALIZED"; + return; + } - // Driver startup on certain platforms takes longer than it takes - // for us to return from loadDriver, so wait 2 seconds before - // turning on Wifi tethering. - createWaitForDriverReadyTimer(doStartWifiTethering); + function doStartWifiTethering() { + cancelWaitForDriverReadyTimer(); + WifiNetworkInterface.name = manager.ifname; + gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface, + configuration, function(result) { + if (result) { + manager.tetheringState = "UNINITIALIZED"; + } else { + manager.tetheringState = "COMPLETED"; + } + // Pop out current request. + callback(); + // Should we fire a dom event if we fail to set wifi tethering ? + debug("Enable Wifi tethering result: " + (result ? result : "successfully")); + }); + } + + // Driver startup on certain platforms takes longer than it takes + // for us to return from loadDriver, so wait 2 seconds before + // turning on Wifi tethering. + createWaitForDriverReadyTimer(doStartWifiTethering); + }); }); } else { gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface, @@ -2173,16 +2153,6 @@ function WifiWorker() { self.currentNetwork.bssid = WifiManager.connectionInfo.bssid; break; case "DISCONNECTED": - // wpa_supplicant may give us a "DISCONNECTED" event even if - // we are already in "DISCONNECTED" state. - if (this.prevState === "INITIALIZING" || - this.prevState === "DISCONNECTED" || - this.prevState === "INTERFACE_DISABLED" || - this.prevState === "INACTIVE" || - this.prevState === "UNINITIALIZED") { - return; - } - self._fireEvent("ondisconnect", {}); self.currentNetwork = null; self.ipAddress = ""; From 088309d9122037f8d484bbe9adbb34695ab9eaa4 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 16 Aug 2013 11:48:31 +0200 Subject: [PATCH 09/27] Bug 903422: Cleanup GetPropertiesInternal, r=echou This patch moves some logic from GetPropertiesInternal to a separate function. This will simplify the following patches a bit. --- dom/bluetooth/linux/BluetoothDBusService.cpp | 42 ++++++++++++-------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/dom/bluetooth/linux/BluetoothDBusService.cpp b/dom/bluetooth/linux/BluetoothDBusService.cpp index e86afac9b21..f74b860e874 100644 --- a/dom/bluetooth/linux/BluetoothDBusService.cpp +++ b/dom/bluetooth/linux/BluetoothDBusService.cpp @@ -766,6 +766,26 @@ UnpackManagerPropertiesMessage(DBusMessage* aMsg, DBusError* aErr, ArrayLength(sManagerProperties)); } +static bool +UnpackPropertiesMessage(DBusMessage* aMsg, DBusError* aErr, + BluetoothValue& aValue, + const char* aIface) +{ + nsAutoString replyError; + + if (!strcmp(aIface, DBUS_DEVICE_IFACE)) { + UnpackDevicePropertiesMessage(aMsg, aErr, aValue, replyError); + } else if (!strcmp(aIface, DBUS_ADAPTER_IFACE)) { + UnpackAdapterPropertiesMessage(aMsg, aErr, aValue, replyError); + } else if (!strcmp(aIface, DBUS_MANAGER_IFACE)) { + UnpackManagerPropertiesMessage(aMsg, aErr, aValue, replyError); + } else { + return false; + } + + return replyError.IsEmpty(); +} + static void ParsePropertyChange(DBusMessage* aMsg, BluetoothValue& aValue, nsAString& aErrorStr, Properties* aPropertyTypes, @@ -809,27 +829,17 @@ GetPropertiesInternal(const nsAString& aPath, "GetProperties", DBUS_TYPE_INVALID); - nsAutoString replyError; - if (!strcmp(aIface, DBUS_DEVICE_IFACE)) { - UnpackDevicePropertiesMessage(msg, &err, aValue, replyError); - } else if (!strcmp(aIface, DBUS_ADAPTER_IFACE)) { - UnpackAdapterPropertiesMessage(msg, &err, aValue, replyError); - } else if (!strcmp(aIface, DBUS_MANAGER_IFACE)) { - UnpackManagerPropertiesMessage(msg, &err, aValue, replyError); - } else { - NS_WARNING("Unknown interface for GetProperties!"); - return false; - } - - if (!replyError.IsEmpty()) { - NS_WARNING("Failed to get device properties"); - return false; - } + bool success = UnpackPropertiesMessage(msg, &err, aValue, aIface); if (msg) { dbus_message_unref(msg); } + if (!success) { + BT_WARNING("Failed to get device properties"); + return false; + } + return true; } From c046fc4086fe30ba5f9bb0d217688300c32b8f55 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 16 Aug 2013 11:48:42 +0200 Subject: [PATCH 10/27] Bug 903422: Replace AppendDeviceNameRunnable by non-blocking implementation, r=echou,gyeh AppendDeviceNameRunnable currently block on the Bluetooth command thread for a DBus reply. This patch refactors the code to not block during the DBus call. The classes AppendDeviceNameHandler and AppendDeviceNameRunnable are being removed, and the DBus interaction is done directly in the DBus thread. --- dom/bluetooth/linux/BluetoothDBusService.cpp | 145 ++++++++++++------- 1 file changed, 89 insertions(+), 56 deletions(-) diff --git a/dom/bluetooth/linux/BluetoothDBusService.cpp b/dom/bluetooth/linux/BluetoothDBusService.cpp index f74b860e874..6820f6b8e91 100644 --- a/dom/bluetooth/linux/BluetoothDBusService.cpp +++ b/dom/bluetooth/linux/BluetoothDBusService.cpp @@ -843,39 +843,73 @@ GetPropertiesInternal(const nsAString& aPath, return true; } -class AppendDeviceNameRunnable : public nsRunnable +class GetPropertiesReplyHandler : public DBusReplyHandler { public: - AppendDeviceNameRunnable(const BluetoothSignal& aSignal) - : mSignal(aSignal) + GetPropertiesReplyHandler(const nsCString& aIface) + : mIface(aIface) { + MOZ_ASSERT(!mIface.IsEmpty()); } - nsresult Run() + const nsCString& GetInterface() const { - MOZ_ASSERT(!NS_IsMainThread()); + return mIface; + } - InfallibleTArray& arr = - mSignal.value().get_ArrayOfBluetoothNamedValue(); - nsString devicePath = arr[0].value().get_nsString(); +private: + nsCString mIface; +}; + +class AppendDeviceNameReplyHandler: public GetPropertiesReplyHandler +{ +public: + AppendDeviceNameReplyHandler(const nsCString& aIface, + const nsString& aDevicePath, + const BluetoothSignal& aSignal) + : GetPropertiesReplyHandler(aIface) + , mDevicePath(aDevicePath) + , mSignal(aSignal) + { + MOZ_ASSERT(!mDevicePath.IsEmpty()); + } + + void Handle(DBusMessage* aReply) MOZ_OVERRIDE + { + MOZ_ASSERT(!NS_IsMainThread()); // DBus thread + + if (!aReply || (dbus_message_get_type(aReply) == DBUS_MESSAGE_TYPE_ERROR)) { + return; + } + + // Get device properties from result of GetProperties + + DBusError err; + dbus_error_init(&err); + + BluetoothValue deviceProperties; + + bool success = UnpackPropertiesMessage(aReply, &err, deviceProperties, + GetInterface().get()); + if (!success) { + BT_WARNING("Failed to get device properties"); + return; + } + + // First we replace object path with device address. - // Replace object path with device address InfallibleTArray& parameters = mSignal.value().get_ArrayOfBluetoothNamedValue(); - nsString address = GetAddressFromObjectPath(devicePath); + nsString address = + GetAddressFromObjectPath(mDevicePath); parameters[0].name().AssignLiteral("address"); parameters[0].value() = address; - BluetoothValue prop; - if(!GetPropertiesInternal(devicePath, DBUS_DEVICE_IFACE, prop)) { - return NS_ERROR_FAILURE; - } + // Then we append the device's name to the original signal's data. - // Get device name from result of GetPropertiesInternal and append to - // original signal InfallibleTArray& properties = - prop.get_ArrayOfBluetoothNamedValue(); - uint8_t i; + deviceProperties.get_ArrayOfBluetoothNamedValue(); + InfallibleTArray::size_type i; for (i = 0; i < properties.Length(); i++) { if (properties[i].name().EqualsLiteral("Name")) { properties[i].name().AssignLiteral("name"); @@ -888,53 +922,54 @@ public: nsRefPtr task = new DistributeBluetoothSignalTask(mSignal); NS_DispatchToMainThread(task); - - return NS_OK; } private: + nsString mDevicePath; BluetoothSignal mSignal; }; -class AppendDeviceNameHandler : public nsRunnable +static void +AppendDeviceName(BluetoothSignal& aSignal) { -public: - AppendDeviceNameHandler(const BluetoothSignal& aSignal) - : mSignal(aSignal) - { + BluetoothValue v = aSignal.value(); + if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue || + v.get_ArrayOfBluetoothNamedValue().Length() == 0) { + BT_WARNING("Invalid argument type for AppendDeviceNameRunnable"); + return; + } + const InfallibleTArray& arr = + v.get_ArrayOfBluetoothNamedValue(); + + // Device object path should be put in the first element + if (!arr[0].name().EqualsLiteral("path") || + arr[0].value().type() != BluetoothValue::TnsString) { + BT_WARNING("Invalid object path for AppendDeviceNameRunnable"); + return; } - nsresult Run() - { - MOZ_ASSERT(NS_IsMainThread()); - BluetoothService* bs = BluetoothService::Get(); - NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE); + nsString devicePath = arr[0].value().get_nsString(); - BluetoothValue v = mSignal.value(); - if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue || - v.get_ArrayOfBluetoothNamedValue().Length() == 0) { - NS_WARNING("Invalid argument type for AppendDeviceNameHandler"); - return NS_ERROR_FAILURE; - } - const InfallibleTArray& arr = - v.get_ArrayOfBluetoothNamedValue(); + nsRefPtr threadConnection = gThreadConnection; - // Device object path should be put in the first element - if (!arr[0].name().EqualsLiteral("path") || - arr[0].value().type() != BluetoothValue::TnsString) { - NS_WARNING("Invalid object path for AppendDeviceNameHandler"); - return NS_ERROR_FAILURE; - } - - nsRefPtr func(new AppendDeviceNameRunnable(mSignal)); - bs->DispatchToCommandThread(func); - - return NS_OK; + if (!threadConnection.get()) { + BT_WARNING("%s: DBus connection has been closed.", __FUNCTION__); + return; } -private: - BluetoothSignal mSignal; -}; + nsRefPtr handler = + new AppendDeviceNameReplyHandler(nsCString(DBUS_DEVICE_IFACE), + devicePath, aSignal); + bool success = dbus_func_args_async(threadConnection->GetConnection(), 1000, + AppendDeviceNameReplyHandler::Callback, + handler.get(), + NS_ConvertUTF16toUTF8(devicePath).get(), + DBUS_DEVICE_IFACE, "GetProperties", + DBUS_TYPE_INVALID); + NS_ENSURE_TRUE_VOID(success); + + handler.forget(); +} static DBusHandlerResult AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data) @@ -957,7 +992,6 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data) nsString errorStr; BluetoothValue v; InfallibleTArray parameters; - nsRefPtr handler; bool isPairingReq = false; BluetoothSignal signal(signalName, signalPath, v); char *objectPath; @@ -1132,11 +1166,10 @@ AgentEventFilter(DBusConnection *conn, DBusMessage *msg, void *data) // It'll be unrefed when set*Internal() is called. dbus_message_ref(msg); - handler = new AppendDeviceNameHandler(signal); + AppendDeviceName(signal); } else { - handler = new DistributeBluetoothSignalTask(signal); + NS_DispatchToMainThread(new DistributeBluetoothSignalTask(signal)); } - NS_DispatchToMainThread(handler); return DBUS_HANDLER_RESULT_HANDLED; From 6894ba634a4058cff745c5142375dc0392213651 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 16 Aug 2013 11:48:57 +0200 Subject: [PATCH 11/27] Bug 903422: Cleanup UnpackPropertiesMessage, r=echou This patch cleans up the various funtions that are related to UnpackPropertiesMessage. The original function UnpackPropertiesMessage now returns success or failure as a boolean value. All other functions have been into this one. And the code has been cleaned up to be more readable. --- dom/bluetooth/linux/BluetoothDBusService.cpp | 79 ++++++-------------- 1 file changed, 24 insertions(+), 55 deletions(-) diff --git a/dom/bluetooth/linux/BluetoothDBusService.cpp b/dom/bluetooth/linux/BluetoothDBusService.cpp index 6820f6b8e91..06cfcea1254 100644 --- a/dom/bluetooth/linux/BluetoothDBusService.cpp +++ b/dom/bluetooth/linux/BluetoothDBusService.cpp @@ -718,72 +718,41 @@ ParseProperties(DBusMessageIter* aIter, aValue = props; } -static void -UnpackPropertiesMessage(DBusMessage* aMsg, DBusError* aErr, - BluetoothValue& aValue, nsAString& aErrorStr, - Properties* aPropertyTypes, - const int aPropertyTypeLen) -{ - if (!IsDBusMessageError(aMsg, aErr, aErrorStr) && - dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { - DBusMessageIter iter; - if (!dbus_message_iter_init(aMsg, &iter)) { - aErrorStr.AssignLiteral("Cannot create dbus message iter!"); - } else { - ParseProperties(&iter, aValue, aErrorStr, aPropertyTypes, - aPropertyTypeLen); - } - } -} - -static void -UnpackAdapterPropertiesMessage(DBusMessage* aMsg, DBusError* aErr, - BluetoothValue& aValue, - nsAString& aErrorStr) -{ - UnpackPropertiesMessage(aMsg, aErr, aValue, aErrorStr, - sAdapterProperties, - ArrayLength(sAdapterProperties)); -} - -static void -UnpackDevicePropertiesMessage(DBusMessage* aMsg, DBusError* aErr, - BluetoothValue& aValue, - nsAString& aErrorStr) -{ - UnpackPropertiesMessage(aMsg, aErr, aValue, aErrorStr, - sDeviceProperties, - ArrayLength(sDeviceProperties)); -} - -static void -UnpackManagerPropertiesMessage(DBusMessage* aMsg, DBusError* aErr, - BluetoothValue& aValue, - nsAString& aErrorStr) -{ - UnpackPropertiesMessage(aMsg, aErr, aValue, aErrorStr, - sManagerProperties, - ArrayLength(sManagerProperties)); -} - static bool UnpackPropertiesMessage(DBusMessage* aMsg, DBusError* aErr, - BluetoothValue& aValue, - const char* aIface) + BluetoothValue& aValue, const char* aIface) { - nsAutoString replyError; + Properties* propertyTypes; + int propertyTypesLength; + + nsAutoString errorStr; + if (IsDBusMessageError(aMsg, aErr, errorStr) || + dbus_message_get_type(aMsg) != DBUS_MESSAGE_TYPE_METHOD_RETURN) { + return true; + } + + DBusMessageIter iter; + if (!dbus_message_iter_init(aMsg, &iter)) { + BT_WARNING("Cannot create dbus message iter!"); + return false; + } if (!strcmp(aIface, DBUS_DEVICE_IFACE)) { - UnpackDevicePropertiesMessage(aMsg, aErr, aValue, replyError); + propertyTypes = sDeviceProperties; + propertyTypesLength = ArrayLength(sDeviceProperties); } else if (!strcmp(aIface, DBUS_ADAPTER_IFACE)) { - UnpackAdapterPropertiesMessage(aMsg, aErr, aValue, replyError); + propertyTypes = sAdapterProperties; + propertyTypesLength = ArrayLength(sAdapterProperties); } else if (!strcmp(aIface, DBUS_MANAGER_IFACE)) { - UnpackManagerPropertiesMessage(aMsg, aErr, aValue, replyError); + propertyTypes = sManagerProperties; + propertyTypesLength = ArrayLength(sManagerProperties); } else { return false; } - return replyError.IsEmpty(); + ParseProperties(&iter, aValue, errorStr, propertyTypes, + propertyTypesLength); + return true; } static void From 063bf63771a950f4307b7c5f42eda662470c5b79 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Fri, 16 Aug 2013 03:05:23 -0700 Subject: [PATCH 12/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/8ef9b6d92efd Author: Fernando Campo Desc: Merge pull request #11507 from fcampo/contactActivity-900446 Bug 900446 - Pick Contact Activity filtered by webcontact/tel should return filtered tel info and contact data (r=arcturus) ======== https://hg.mozilla.org/integration/gaia-central/rev/f23fe3f3ceb7 Author: Fernando Campo Desc: Bug 900446 - Pick Contact Activity filtered by webcontact/tel should return filtered tel info and contact data --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 1c466fb7d9a..96db9809c00 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "96e8482e036ff46d6f0ae11a9622e21a80852541", + "revision": "8ef9b6d92efd660eeee72518902c888774f6c11c", "repo_path": "/integration/gaia-central" } From 42458861864e630113c33072e1529ce09f76cbca Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Fri, 16 Aug 2013 03:30:26 -0700 Subject: [PATCH 13/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/c531ac4a3ebe Author: Rudy Lu Desc: Merge pull request #11548 from RudyLu/keyboard/Bug902352-placeholder_as_word_separator Bug 902352 - Make Gaia keyboard treats the placeholder r=timdream ======== https://hg.mozilla.org/integration/gaia-central/rev/8f7ba73087f4 Author: Rudy Lu Desc: Bug 902352 - Make Gaia keyboard treats the placeholder character U+FFFC as word separator. --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 96db9809c00..766f07284fa 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "8ef9b6d92efd660eeee72518902c888774f6c11c", + "revision": "c531ac4a3ebe431066d40a969f55ec9aea323530", "repo_path": "/integration/gaia-central" } From 09054e249d9b0292718005ce9d530443a10f7723 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Fri, 16 Aug 2013 04:25:24 -0700 Subject: [PATCH 14/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/ae6c71b5ee28 Author: Arthur Chen Desc: Merge pull request #10818 from crh0716/874313_1 Bug 874313 - Modify messages for the case of unavaliable media storage r=dkuo, dale ======== https://hg.mozilla.org/integration/gaia-central/rev/4f3a8923c73c Author: crh0716 Desc: Bug 874313 - Display a dialog in media apps when the default storage is unavailable. --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 766f07284fa..f4f825eae27 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "c531ac4a3ebe431066d40a969f55ec9aea323530", + "revision": "ae6c71b5ee283cb0f6cb963889ec3ca8983281ce", "repo_path": "/integration/gaia-central" } From 33ad1bd6441c1adb28a0a0938f1a64dcce872a0c Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Fri, 16 Aug 2013 04:35:24 -0700 Subject: [PATCH 15/27] Bumping gaia.json for 2 gaia-central revision(s) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ======== https://hg.mozilla.org/integration/gaia-central/rev/8a453b73839b Author: Mihai Cîrlănaru Desc: Merge pull request #11568 from mcirlanaru/bug_899236 Bug 899236 - [Lockscreen] Reintroduce camera button for... r=@alivedise ======== https://hg.mozilla.org/integration/gaia-central/rev/f7f67845c67c Author: Mihai Cirlanaru Desc: Bug 899236 - [Lockscreen] Reintroduce camera button for passcode input screen. r=alive --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index f4f825eae27..59dcf4cfd53 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "ae6c71b5ee283cb0f6cb963889ec3ca8983281ce", + "revision": "8a453b73839bbf5a0b8904c86cef22064640d461", "repo_path": "/integration/gaia-central" } From 012d649764e844520a5ba5f87e1f4a3151ab29b9 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Fri, 16 Aug 2013 05:00:26 -0700 Subject: [PATCH 16/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/babf9d902c9d Author: Sam Joch Desc: Merge pull request #10767 from samjoch/bug-878851-UpdateStatusBarAlphanumericIconsToUseFeuraSans Bug 878851 - Update status bar alphanumeric icons to use Feura Sans r=etienne ======== https://hg.mozilla.org/integration/gaia-central/rev/5b1561082afd Author: Sam Joch Desc: Bug 878851 - Update status bar alphanumeric icons to use Feura Sans --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 59dcf4cfd53..18f34bd3cfb 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "8a453b73839bbf5a0b8904c86cef22064640d461", + "revision": "babf9d902c9d5bb398e0a919d583930395e34437", "repo_path": "/integration/gaia-central" } From 7fc2ae4f98e297eaf432bcc9d2c5f7fb9793d672 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Fri, 16 Aug 2013 05:20:23 -0700 Subject: [PATCH 17/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/629003f982d7 Author: Ben Francis Desc: Merge pull request #11571 from gasolin/issue-903049 Bug 903049 - [Browser] Top Sites are Blurry r=benfrancis ======== https://hg.mozilla.org/integration/gaia-central/rev/3cd030925e41 Author: gasolin Desc: Bug 903049 - [Browser] Top Sites are Blurry --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 18f34bd3cfb..80aaaef6fb0 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "babf9d902c9d5bb398e0a919d583930395e34437", + "revision": "629003f982d703c74cb6d1864fa1007d78f44b0a", "repo_path": "/integration/gaia-central" } From 2ac8e9a4682c6ecbdde99d07b41b898ce752730c Mon Sep 17 00:00:00 2001 From: Chuck Lee Date: Thu, 15 Aug 2013 10:58:45 +0800 Subject: [PATCH 18/27] Bug 900855 - Wait driver load and unload complete before proceed next request. r=mrbkap --- dom/wifi/WifiWorker.js | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js index 2f7fe5bf6a9..c1d45aa8041 100644 --- a/dom/wifi/WifiWorker.js +++ b/dom/wifi/WifiWorker.js @@ -163,6 +163,9 @@ var WifiManager = (function() { } var driverLoaded = false; + + manager.getDriverLoaded = function() { return driverLoaded; } + function loadDriver(callback) { if (driverLoaded) { callback(0); @@ -2840,6 +2843,7 @@ WifiWorker.prototype = { // First, notify all of the requests that were trying to make this change. let state = this._stateRequests[0].enabled; + let driverLoaded = WifiManager.getDriverLoaded(); // It is callback function's responsibility to handle the pending request. // So we just return here. @@ -2848,9 +2852,12 @@ WifiWorker.prototype = { return; } - // If the new state is not the same as state, then we weren't processing - // the first request (we were racing somehow) so don't notify. - if (!success || state === newState) { + // If the new state is not the same as state or new state is not the same as + // driver loaded state, then we weren't processing the first request (we + // were racing somehow) so don't notify. + // For newState is false(disable), we expect driverLoaded is false(driver unloaded) + // to proceed, and vice versa. + if (!success || (newState === driverLoaded && state === newState)) { do { if (!("callback" in this._stateRequests[0])) { this._stateRequests.shift(); @@ -2864,16 +2871,27 @@ WifiWorker.prototype = { // If there were requests queued after this one, run them. if (this._stateRequests.length > 0) { let self = this; + let callback = null; this._callbackTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - this._callbackTimer.initWithCallback(function(timer) { - if ("callback" in self._stateRequests[0]) { - self._stateRequests[0].callback.call(self, self._stateRequests[0].enabled); - } else { - WifiManager.setWifiEnabled(self._stateRequests[0].enabled, - self._setWifiEnabledCallback.bind(this)); - } - timer = null; - }, 1000, Ci.nsITimer.TYPE_ONE_SHOT); + if (newState === driverLoaded) { + // Driver status is as same as new state, proceed next request. + callback = function(timer) { + if ("callback" in self._stateRequests[0]) { + self._stateRequests[0].callback.call(self, self._stateRequests[0].enabled); + } else { + WifiManager.setWifiEnabled(self._stateRequests[0].enabled, + self._setWifiEnabledCallback.bind(this)); + } + timer = null; + }; + } else { + // Driver status is not as same as new state, wait driver. + callback = function(timer) { + self._notifyAfterStateChange(success, newState); + timer = null; + }; + } + this._callbackTimer.initWithCallback(callback, 1000, Ci.nsITimer.TYPE_ONE_SHOT); } }, From d9ebfce7493913df06e6633335ba43772cae9073 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Thu, 8 Aug 2013 15:56:08 -0400 Subject: [PATCH 19/27] Bug 895905 - B2G mechanism for content to inform APZC about scroll events. Handles multi-APZC. r=kats --- dom/ipc/PBrowser.ipdl | 8 ++ dom/ipc/TabChild.cpp | 106 +++++++++++++++++++--- dom/ipc/TabChild.h | 3 - dom/ipc/TabParent.cpp | 11 +++ dom/ipc/TabParent.h | 1 + gfx/layers/ipc/AsyncPanZoomController.cpp | 10 +- layout/base/nsDisplayList.cpp | 2 +- layout/base/nsLayoutUtils.cpp | 18 +++- layout/base/nsLayoutUtils.h | 8 +- layout/ipc/RenderFrameParent.cpp | 9 ++ layout/ipc/RenderFrameParent.h | 4 + 11 files changed, 150 insertions(+), 30 deletions(-) diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 1f944966fd1..88cec70b624 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -31,6 +31,7 @@ using gfxMatrix; using gfxSize; using CSSRect; using mozilla::layers::FrameMetrics; +using FrameMetrics::ViewID; using mozilla::layout::ScrollingBehavior; using mozilla::void_t; using mozilla::WindowsHandle; @@ -288,6 +289,13 @@ parent: */ UpdateZoomConstraints(bool aAllowZoom, float aMinZoom, float aMaxZoom); + /** + * Notifies the parent about a scroll event. The pres shell ID and + * view ID identify which scrollable (sub-)frame was scrolled, and + * the new scroll offset for that frame is sent. + */ + UpdateScrollOffset(uint32_t aPresShellId, ViewID aViewId, CSSIntPoint aScrollOffset); + __delete__(); child: diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 72d2c50d169..97457add869 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -299,6 +299,29 @@ TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t printf("creating %d!\n", NS_IsMainThread()); } +// Get the DOMWindowUtils for the window corresponding to the given document. +static already_AddRefed GetDOMWindowUtils(nsIDocument* doc) +{ + nsCOMPtr utils; + nsCOMPtr window = doc->GetDefaultView(); + if (window) { + utils = do_GetInterface(window); + } + return utils.forget(); +} + +// Get the DOMWindowUtils for the window corresponding to the givent content +// element. This might be an iframe inside the tab, for instance. +static already_AddRefed GetDOMWindowUtils(nsIContent* content) +{ + nsCOMPtr utils; + nsIDocument* doc = content->GetCurrentDoc(); + if (doc) { + utils = GetDOMWindowUtils(doc); + } + return utils.forget(); +} + NS_IMETHODIMP TabChild::HandleEvent(nsIDOMEvent* aEvent) { @@ -308,6 +331,63 @@ TabChild::HandleEvent(nsIDOMEvent* aEvent) // This meta data may or may not have been a meta viewport tag. If it was, // we should handle it immediately. HandlePossibleViewportChange(); + } else if (eventType.EqualsLiteral("scroll")) { + nsCOMPtr target; + aEvent->GetTarget(getter_AddRefs(target)); + + ViewID viewId; + uint32_t presShellId; + nsIScrollableFrame* scrollFrame = nullptr; + + nsCOMPtr doc; + nsCOMPtr content; + + if ((doc = do_QueryInterface(target))) { + nsCOMPtr presShell = doc->GetShell(); + if (!presShell) + return NS_OK; + + presShellId = presShell->GetPresShellId(); + if (presShell->GetPresContext()->IsRootContentDocument()) { + // Case 1: Root content document. + viewId = FrameMetrics::ROOT_SCROLL_ID; + scrollFrame = presShell->GetRootScrollFrameAsScrollable(); + } else { + // Case 2: Other document. + if (!nsLayoutUtils::FindIDFor(doc->GetDocumentElement(), &viewId)) + return NS_ERROR_UNEXPECTED; + scrollFrame = nsLayoutUtils::FindScrollableFrameFor(viewId); + } + } else if ((content = do_QueryInterface(target))) { + // Case 3: Content. + nsCOMPtr utils = ::GetDOMWindowUtils(content); + utils->GetPresShellId(&presShellId); + if (!nsLayoutUtils::FindIDFor(content, &viewId)) + return NS_ERROR_UNEXPECTED; + scrollFrame = nsLayoutUtils::FindScrollableFrameFor(viewId); + } + + if (scrollFrame) { + CSSIntPoint scrollOffset = scrollFrame->GetScrollPositionCSSPixels(); + + // For the root frame, we store the last metrics, including the last + // scroll offset, sent by APZC. (This is updated in ProcessUpdateFrame()). + // We use this here to avoid sending APZC back a scroll event that + // originally came from APZC (besides being unnecessary, the event might + // be slightly out of date by the time it reaches APZC). + // We should probably do this for subframes, too. + if (viewId == FrameMetrics::ROOT_SCROLL_ID) { + if (RoundedToInt(mLastMetrics.mScrollOffset) == scrollOffset) + return NS_OK; + else + // Update the last scroll offset now, otherwise RecvUpdateDimensions() + // might trigger a scroll to the old offset before RecvUpdateFrame() + // gets a chance to update it. + mLastMetrics.mScrollOffset = scrollOffset; + } + + SendUpdateScrollOffset(presShellId, viewId, scrollOffset); + } } return NS_OK; @@ -1039,20 +1119,6 @@ TabChild::GetDOMWindowUtils() return utils.forget(); } -already_AddRefed -TabChild::GetDOMWindowUtils(nsIContent* content) -{ - nsCOMPtr utils; - nsIDocument* doc = content->GetCurrentDoc(); - if (doc) { - nsCOMPtr window = doc->GetDefaultView(); - if (window) { - utils = do_GetInterface(window); - } - } - return utils.forget(); -} - static nsInterfaceHashtable, nsIDialogParamBlock> gActiveDialogs; NS_IMETHODIMP @@ -1586,6 +1652,15 @@ TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics) } mLastMetrics = aFrameMetrics; + + // ScrollWindowTo() can make some small adjustments to the offset before + // actually scrolling the window. To ensure that the scroll offset stored + // in mLastMetrics is the same as the offset stored in the window, + // re-query the latter. + CSSIntPoint actualScrollOffset; + utils->GetScrollXY(false, &actualScrollOffset.x, &actualScrollOffset.y); + mLastMetrics.mScrollOffset = actualScrollOffset; + return true; } @@ -1599,7 +1674,7 @@ TabChild::ProcessUpdateSubframe(nsIContent* aContent, scrollFrame->ScrollToCSSPixelsApproximate(aMetrics.mScrollOffset); } - nsCOMPtr utils(GetDOMWindowUtils(aContent)); + nsCOMPtr utils(::GetDOMWindowUtils(aContent)); nsCOMPtr element = do_QueryInterface(aContent); if (utils && element) { // and set the display port @@ -2190,6 +2265,7 @@ TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading) root->SetParentTarget(scope); chromeHandler->AddEventListener(NS_LITERAL_STRING("DOMMetaAdded"), this, false); + chromeHandler->AddEventListener(NS_LITERAL_STRING("scroll"), this, false); } if (aScriptLoading != DONT_LOAD_SCRIPTS && !mTriedBrowserInit) { diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 34fcd056d8a..d3bcf971928 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -436,9 +436,6 @@ private: // Get the DOMWindowUtils for the top-level window in this tab. already_AddRefed GetDOMWindowUtils(); - // Get the DOMWindowUtils for the window corresponding to the givent content - // element. This might be an iframe inside the tab, for instance. - already_AddRefed GetDOMWindowUtils(nsIContent* aContent); class CachedFileDescriptorInfo; class CachedFileDescriptorCallbackRunnable; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index e66ba212c0e..96da06b1655 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1561,6 +1561,17 @@ TabParent::RecvUpdateZoomConstraints(const bool& aAllowZoom, return true; } +bool +TabParent::RecvUpdateScrollOffset(const uint32_t& aPresShellId, + const ViewID& aViewId, + const CSSIntPoint& aScrollOffset) +{ + if (RenderFrameParent* rfp = GetRenderFrame()) { + rfp->UpdateScrollOffset(aPresShellId, aViewId, aScrollOffset); + } + return true; +} + bool TabParent::RecvContentReceivedTouch(const bool& aPreventDefault) { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 16df7ca4425..002bbe30aa1 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -161,6 +161,7 @@ public: virtual bool RecvUpdateZoomConstraints(const bool& aAllowZoom, const float& aMinZoom, const float& aMaxZoom); + virtual bool RecvUpdateScrollOffset(const uint32_t& aPresShellId, const ViewID& aViewId, const CSSIntPoint& aScrollOffset); virtual bool RecvContentReceivedTouch(const bool& aPreventDefault); virtual PContentDialogParent* AllocPContentDialogParent(const uint32_t& aType, const nsCString& aName, diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index 1f79ccec96d..338fa9326e9 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -1116,8 +1116,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri mFrameMetrics.mMayHaveTouchListeners = aLayerMetrics.mMayHaveTouchListeners; // TODO: Once a mechanism for calling UpdateScrollOffset() when content does - // a scrollTo() is implemented for B2G (bug 895905), this block can be removed. -#ifndef MOZ_WIDGET_ANDROID + // a scrollTo() is implemented for metro (bug 898580), this block can be removed. +#ifdef MOZ_METRO if (!mPaintThrottler.IsOutstanding()) { // No paint was requested, but we got one anyways. One possible cause of this // is that content could have fired a scrollTo(). In this case, we should take @@ -1418,9 +1418,9 @@ void AsyncPanZoomController::UpdateScrollOffset(const CSSPoint& aScrollOffset) bool AsyncPanZoomController::Matches(const ScrollableLayerGuid& aGuid) { - // TODO: also check the presShellId and mScrollId, once those are - // fully propagated everywhere in RenderFrameParent and AndroidJNI. - return aGuid.mLayersId == mLayersId; + // TODO: also check the presShellId, once that is fully propagated + // everywhere in RenderFrameParent and AndroidJNI. + return aGuid.mLayersId == mLayersId && aGuid.mScrollId == mFrameMetrics.mScrollId; } } diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 324141dc62c..3b370d33c2d 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -3213,7 +3213,7 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder, // Get the already set unique ID for scrolling this content remotely. // Or, if not set, generate a new ID. nsIContent* content = mScrolledFrame->GetContent(); - ViewID scrollId = nsLayoutUtils::FindIDFor(content); + ViewID scrollId = nsLayoutUtils::FindOrCreateIDFor(content); nsRect viewport = mScrollFrame->GetRect() - mScrollFrame->GetPosition() + diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 4f2eef07317..4a892cc664e 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -434,15 +434,23 @@ static void DestroyViewID(void* aObject, nsIAtom* aPropertyName, * A namespace class for static layout utilities. */ +bool +nsLayoutUtils::FindIDFor(nsIContent* aContent, ViewID* aOutViewId) +{ + void* scrollIdProperty = aContent->GetProperty(nsGkAtoms::RemoteId); + if (scrollIdProperty) { + *aOutViewId = *static_cast(scrollIdProperty); + return true; + } + return false; +} + ViewID -nsLayoutUtils::FindIDFor(nsIContent* aContent) +nsLayoutUtils::FindOrCreateIDFor(nsIContent* aContent) { ViewID scrollId; - void* scrollIdProperty = aContent->GetProperty(nsGkAtoms::RemoteId); - if (scrollIdProperty) { - scrollId = *static_cast(scrollIdProperty); - } else { + if (!FindIDFor(aContent, &scrollId)) { scrollId = sScrollIdCounter++; aContent->SetProperty(nsGkAtoms::RemoteId, new ViewID(scrollId), DestroyViewID); diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 00b40b6c194..103e879494f 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -66,11 +66,17 @@ class nsLayoutUtils public: typedef mozilla::layers::FrameMetrics::ViewID ViewID; + /** + * Finds previously assigned ViewID for the given content element, if any. + * Returns whether a ViewID was previously assigned. + */ + static bool FindIDFor(nsIContent* aContent, ViewID* aOutViewId); + /** * Finds previously assigned or generates a unique ViewID for the given * content element. */ - static ViewID FindIDFor(nsIContent* aContent); + static ViewID FindOrCreateIDFor(nsIContent* aContent); /** * Find content for given ID. diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 67b7c991a0e..841426df632 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -1016,6 +1016,15 @@ RenderFrameParent::UpdateZoomConstraints(bool aAllowZoom, float aMinZoom, float } } +void +RenderFrameParent::UpdateScrollOffset(uint32_t aPresShellId, ViewID aViewId, const CSSIntPoint& aScrollOffset) +{ + if (GetApzcTreeManager()) { + GetApzcTreeManager()->UpdateScrollOffset(ScrollableLayerGuid(mLayersId, aPresShellId, aViewId), + aScrollOffset); + } +} + bool RenderFrameParent::HitTest(const nsRect& aRect) { diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h index 2e684984ba9..42445b5eca5 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -104,6 +104,10 @@ public: void UpdateZoomConstraints(bool aAllowZoom, float aMinZoom, float aMaxZoom); + void UpdateScrollOffset(uint32_t aPresShellId, + ViewID aViewId, + const CSSIntPoint& aScrollOffset); + bool HitTest(const nsRect& aRect); protected: From 27043f6de7a359b26c397036513c78edb10e3b87 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Thu, 8 Aug 2013 15:56:08 -0400 Subject: [PATCH 20/27] Bug 895905 - Eliminate some of the special handling of ROOT_SCROLL_ID. r=kats, r=tn --- dom/ipc/TabChild.cpp | 33 +++++++++------------------------ layout/base/nsDisplayList.cpp | 7 +++++++ layout/base/nsLayoutUtils.cpp | 9 ++++----- layout/base/nsLayoutUtils.h | 8 +++++--- 4 files changed, 25 insertions(+), 32 deletions(-) diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 97457add869..2082551edb1 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -339,34 +339,19 @@ TabChild::HandleEvent(nsIDOMEvent* aEvent) uint32_t presShellId; nsIScrollableFrame* scrollFrame = nullptr; - nsCOMPtr doc; nsCOMPtr content; + if (nsCOMPtr doc = do_QueryInterface(target)) + content = doc->GetDocumentElement(); + else + content = do_QueryInterface(target); - if ((doc = do_QueryInterface(target))) { - nsCOMPtr presShell = doc->GetShell(); - if (!presShell) - return NS_OK; + nsCOMPtr utils = ::GetDOMWindowUtils(content); + utils->GetPresShellId(&presShellId); - presShellId = presShell->GetPresShellId(); - if (presShell->GetPresContext()->IsRootContentDocument()) { - // Case 1: Root content document. - viewId = FrameMetrics::ROOT_SCROLL_ID; - scrollFrame = presShell->GetRootScrollFrameAsScrollable(); - } else { - // Case 2: Other document. - if (!nsLayoutUtils::FindIDFor(doc->GetDocumentElement(), &viewId)) - return NS_ERROR_UNEXPECTED; - scrollFrame = nsLayoutUtils::FindScrollableFrameFor(viewId); - } - } else if ((content = do_QueryInterface(target))) { - // Case 3: Content. - nsCOMPtr utils = ::GetDOMWindowUtils(content); - utils->GetPresShellId(&presShellId); - if (!nsLayoutUtils::FindIDFor(content, &viewId)) - return NS_ERROR_UNEXPECTED; - scrollFrame = nsLayoutUtils::FindScrollableFrameFor(viewId); - } + if (!nsLayoutUtils::FindIDFor(content, &viewId)) + return NS_ERROR_UNEXPECTED; + scrollFrame = nsLayoutUtils::FindScrollableFrameFor(viewId); if (scrollFrame) { CSSIntPoint scrollOffset = scrollFrame->GetScrollPositionCSSPixels(); diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 3b370d33c2d..daae18ab193 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1156,6 +1156,13 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder, usingDisplayport = nsLayoutUtils::GetDisplayPort(content, &displayport); usingCriticalDisplayport = nsLayoutUtils::GetCriticalDisplayPort(content, &criticalDisplayport); + + if (id == FrameMetrics::ROOT_SCROLL_ID) { + // Record the mapping between the root scroll frame's content and + // ROOT_SCROLL_ID so that users of nsLayoutUtils::FindIDFor() and + // nsLayoutUtils::FindContentFor() don't have to special-case the root. + nsLayoutUtils::FindOrCreateIDFor(content, true); + } } } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 4a892cc664e..6c2ab41f443 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -446,12 +446,12 @@ nsLayoutUtils::FindIDFor(nsIContent* aContent, ViewID* aOutViewId) } ViewID -nsLayoutUtils::FindOrCreateIDFor(nsIContent* aContent) +nsLayoutUtils::FindOrCreateIDFor(nsIContent* aContent, bool aRoot) { ViewID scrollId; if (!FindIDFor(aContent, &scrollId)) { - scrollId = sScrollIdCounter++; + scrollId = aRoot ? FrameMetrics::ROOT_SCROLL_ID : sScrollIdCounter++; aContent->SetProperty(nsGkAtoms::RemoteId, new ViewID(scrollId), DestroyViewID); GetContentMap().Put(scrollId, aContent); @@ -463,9 +463,8 @@ nsLayoutUtils::FindOrCreateIDFor(nsIContent* aContent) nsIContent* nsLayoutUtils::FindContentFor(ViewID aId) { - NS_ABORT_IF_FALSE(aId != FrameMetrics::NULL_SCROLL_ID && - aId != FrameMetrics::ROOT_SCROLL_ID, - "Cannot find a content element in map for null or root IDs."); + NS_ABORT_IF_FALSE(aId != FrameMetrics::NULL_SCROLL_ID, + "Cannot find a content element in map for null IDs."); nsIContent* content; bool exists = GetContentMap().Get(aId, &content); diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 103e879494f..289b8d779f0 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -64,7 +64,8 @@ class nsLayoutUtils typedef gfxPattern::GraphicsFilter GraphicsFilter; public: - typedef mozilla::layers::FrameMetrics::ViewID ViewID; + typedef mozilla::layers::FrameMetrics FrameMetrics; + typedef FrameMetrics::ViewID ViewID; /** * Finds previously assigned ViewID for the given content element, if any. @@ -74,9 +75,10 @@ public: /** * Finds previously assigned or generates a unique ViewID for the given - * content element. + * content element. If aRoot is true, the special ID + * FrameMetrics::ROOT_SCROLL_ID is used. */ - static ViewID FindOrCreateIDFor(nsIContent* aContent); + static ViewID FindOrCreateIDFor(nsIContent* aContent, bool aRoot = false); /** * Find content for given ID. From 728be070e1056c769f39c395588ccd9ed1481440 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Thu, 8 Aug 2013 15:56:09 -0400 Subject: [PATCH 21/27] Bug 895905 - Fixed a compiler error on GCC 4.7. r=Bas --- gfx/2d/Point.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gfx/2d/Point.h b/gfx/2d/Point.h index 026b44604c4..262830c4536 100644 --- a/gfx/2d/Point.h +++ b/gfx/2d/Point.h @@ -10,6 +10,8 @@ #include "BasePoint.h" #include "BaseSize.h" +#include + namespace mozilla { namespace gfx { @@ -63,8 +65,8 @@ typedef PointTyped Point; template IntPointTyped RoundedToInt(const PointTyped& aPoint) { - return IntPointTyped(NS_lround(aPoint.x), - NS_lround(aPoint.y)); + return IntPointTyped(int32_t(floorf(aPoint.x + 0.5f)), + int32_t(floorf(aPoint.y + 0.5f))); } template From a2220a799009386999fc9888eb05502ba15872e0 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Thu, 8 Aug 2013 15:56:09 -0400 Subject: [PATCH 22/27] Bug 895905 - Document that ns[Int]Point stores coordinates in app units. r=tn --- gfx/src/nsPoint.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gfx/src/nsPoint.h b/gfx/src/nsPoint.h index 8d732ec6b29..042daa8bf9d 100644 --- a/gfx/src/nsPoint.h +++ b/gfx/src/nsPoint.h @@ -13,6 +13,8 @@ struct nsIntPoint; +// nsPoint represents a point in app units. + struct nsPoint : public mozilla::gfx::BasePoint { typedef mozilla::gfx::BasePoint Super; @@ -28,6 +30,10 @@ struct nsPoint : public mozilla::gfx::BasePoint { inline nsPoint ConvertAppUnits(int32_t aFromAPP, int32_t aToAPP) const; }; +// nsIntPoint represents a point in one of the types of pixels. +// Uses of nsIntPoint should eventually be converted to CSSIntPoint, +// LayoutDeviceIntPoint, etc. (see layout/base/Units.h). + struct nsIntPoint : public mozilla::gfx::BasePoint { typedef mozilla::gfx::BasePoint Super; From 30762abd4d6a5e7d6361ddb0bf48d45fd64bfe0d Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Fri, 16 Aug 2013 05:55:23 -0700 Subject: [PATCH 23/27] Bumping gaia.json for 11 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/6e16c7e87fba Author: Ryan VanderMeulen Desc: Merge pull request #11345 from karlcow/master Bug 901501 - Remove UA override for b92.net, nba.com, etsy.com ======== https://hg.mozilla.org/integration/gaia-central/rev/42a1cccf6315 Author: karl Desc: Remove UA override for flickr.com, as.com, elconfidencial.com, rincondelvago.com, bet365.com, o2.pl, tvn24.pl, tablica.pl, wp.pl ======== https://hg.mozilla.org/integration/gaia-central/rev/bc61576a7756 Author: karl Desc: The issue is not solve by UA override 878651 - b92.net doesn't recognize B2G UA as mobile ======== https://hg.mozilla.org/integration/gaia-central/rev/64049b6ebdad Author: karl Desc: The issue is not solve by UA override 843154 - nba.com doesn't recognize B2G UA as mobile ======== https://hg.mozilla.org/integration/gaia-central/rev/1d37aba55301 Author: karl Desc: closed 843170 - etsy.com doesn't recognize B2G UA as mobile ======== https://hg.mozilla.org/integration/gaia-central/rev/c24d2336a294 Author: karl Desc: Revert "closed 878226 - bet365.com doesn't recognize B2G UA as mobile" This reverts commit 5dbed9e8aec141079ca94f1acc0da5017012e2a6. ======== https://hg.mozilla.org/integration/gaia-central/rev/49ee121b59e4 Author: karl Desc: closed 878226 - bet365.com doesn't recognize B2G UA as mobile ======== https://hg.mozilla.org/integration/gaia-central/rev/b21b63c97982 Author: karl Desc: Revert "Remove UA override for bet365.com" This reverts commit c44e7859e82e289067ab613a3cc79ccdf11b2ee6. ======== https://hg.mozilla.org/integration/gaia-central/rev/2bb4a410734c Author: karl Desc: Remove UA override for bet365.com ======== https://hg.mozilla.org/integration/gaia-central/rev/68b066658885 Author: Ryan VanderMeulen Desc: Merge pull request #11315 from pauljt/bug888911 Bug 888911 - Implement an increasing lockout delay to prevent passcode ======== https://hg.mozilla.org/integration/gaia-central/rev/7702cf513c05 Author: Paul Theriault Desc: Bug 888911 - Implement an increasing lockout delay to prevent passcode guessing --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 80aaaef6fb0..7fff3711199 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "629003f982d703c74cb6d1864fa1007d78f44b0a", + "revision": "6e16c7e87fbacb4a9766eb1785e688c63f5e2816", "repo_path": "/integration/gaia-central" } From b2aa4128a4976e8ba38a597a61f17544b3b48a21 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Fri, 16 Aug 2013 06:05:24 -0700 Subject: [PATCH 24/27] Bumping gaia.json for 1 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/7fc6b301a39c Author: Ryan VanderMeulen Desc: Revert "Merge pull request #11315 from pauljt/bug888911" due to Travis CI failures. This reverts commit 28a93e5eebada09920ab940252454326fc321c8f, reversing changes made to 4c57c9b72f0277b5d0d9e4a7c5a13ac1eb7a1732. --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 7fff3711199..c27989c5711 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "6e16c7e87fbacb4a9766eb1785e688c63f5e2816", + "revision": "7fc6b301a39cf78e3049f15bf13c2817155e3e3c", "repo_path": "/integration/gaia-central" } From a1acd54c060c8498aeebdd735c1f33375662eb2a Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Fri, 16 Aug 2013 10:35:23 -0700 Subject: [PATCH 25/27] Bumping gaia.json for 2 gaia-central revision(s) ======== https://hg.mozilla.org/integration/gaia-central/rev/10a9cab9cf34 Author: Gregor Wagner Desc: Merge pull request #11540 from gregorwagner/lockscreen Bug 903563 - JavaScript errors evt.target.dataset is undefined ======== https://hg.mozilla.org/integration/gaia-central/rev/86a4b98299e9 Author: Gregor Wagner Desc: Bug 903563 - JavaScript errors evt.target.dataset is undefined --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index c27989c5711..a5801a93028 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "7fc6b301a39cf78e3049f15bf13c2817155e3e3c", + "revision": "10a9cab9cf34cc34b34e1ee2c83ba2bf0af6d6f1", "repo_path": "/integration/gaia-central" } From ed89ea95d8528d1a644c9d69dc601336edd3fb2a Mon Sep 17 00:00:00 2001 From: Alexandre Lissy Date: Fri, 16 Aug 2013 11:08:00 -0700 Subject: [PATCH 26/27] Bug 903362 - Permission upgrade might fail at removal r=fabrice --- dom/apps/src/Webapps.jsm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/apps/src/Webapps.jsm b/dom/apps/src/Webapps.jsm index 143b8c6abaf..c4804646b74 100644 --- a/dom/apps/src/Webapps.jsm +++ b/dom/apps/src/Webapps.jsm @@ -420,7 +420,7 @@ this.DOMApplicationRegistry = { let localId = this.webapps[id].localId; let permMgr = Cc["@mozilla.org/permissionmanager;1"] .getService(Ci.nsIPermissionManager); - permMgr.RemovePermissionsForApp(localId, false); + permMgr.removePermissionsForApp(localId, false); Services.cookies.removeCookiesForApp(localId, false); this._clearPrivateData(localId, false); delete this.webapps[id]; From a884f963e9d7761483e458bbc0142d9b499bcd33 Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Fri, 16 Aug 2013 11:08:03 -0700 Subject: [PATCH 27/27] Bug 904462 - Clean up warnings and errors when starting B2G on the mac r=fabrice --- accessible/src/jsat/AccessFu.jsm | 4 ++-- b2g/chrome/content/shell.js | 8 ++++++-- dom/apps/src/AppsUtils.jsm | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/accessible/src/jsat/AccessFu.jsm b/accessible/src/jsat/AccessFu.jsm index 30905dcfec9..7bb58d964c5 100644 --- a/accessible/src/jsat/AccessFu.jsm +++ b/accessible/src/jsat/AccessFu.jsm @@ -29,8 +29,8 @@ this.AccessFu = { Utils.init(aWindow); try { - Cc['@mozilla.org/android/bridge;1']. - getService(Ci.nsIAndroidBridge).handleGeckoMessage( + let bridgeCc = Cc['@mozilla.org/android/bridge;1']; + bridgeCc.getService(Ci.nsIAndroidBridge).handleGeckoMessage( JSON.stringify({ type: 'Accessibility:Ready' })); Services.obs.addObserver(this, 'Accessibility:Settings', false); } catch (x) { diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index b7771eb6940..cc082b7ebdc 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -1103,8 +1103,12 @@ window.addEventListener('ContentStart', function cr_onContentStart() { }); window.addEventListener('ContentStart', function update_onContentStart() { - let updatePrompt = Cc["@mozilla.org/updates/update-prompt;1"] - .createInstance(Ci.nsIUpdatePrompt); + let promptCc = Cc["@mozilla.org/updates/update-prompt;1"]; + if (!promptCc) { + return; + } + + let updatePrompt = promptCc.createInstance(Ci.nsIUpdatePrompt); if (!updatePrompt) { return; } diff --git a/dom/apps/src/AppsUtils.jsm b/dom/apps/src/AppsUtils.jsm index 57de5cc0f3e..4ab81234fed 100644 --- a/dom/apps/src/AppsUtils.jsm +++ b/dom/apps/src/AppsUtils.jsm @@ -199,7 +199,7 @@ this.AppsUtils = { #ifdef MOZ_WIDGET_GONK isCoreApp = app.basePath == this.getCoreAppsBasePath(); #endif - debug(app.name + " isCoreApp: " + isCoreApp); + debug(app.basePath + " isCoreApp: " + isCoreApp); return { "basePath": app.basePath + "/", "isCoreApp": isCoreApp }; },