Bug 727690 - Kill any existing connections on startup so we can successfully reconnect after we've been killed. r=gal
authorBlake Kaplan <mrbkap@gmail.com>
Mon, 20 Feb 2012 13:01:53 +0100
changeset 88711 64d8bba7047f004dc6acbf4a7025fd04e6b71b88
parent 88710 b8e7474374d533d84d5dbac3e9afa426b93ac945
child 88712 5b8195516c117120837021c21932c591a04447b7
push id975
push userffxbld
push dateTue, 13 Mar 2012 21:39:16 +0000
treeherdermozilla-aurora@99faebf9dc36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal
bugs727690
milestone13.0a1
Bug 727690 - Kill any existing connections on startup so we can successfully reconnect after we've been killed. r=gal
dom/wifi/nsWifiWorker.js
--- a/dom/wifi/nsWifiWorker.js
+++ b/dom/wifi/nsWifiWorker.js
@@ -635,45 +635,86 @@ var WifiManager = (function() {
       debug("Notifying of scan results available");
       notify("scanresultsavailable");
       return true;
     }
     // unknown event
     return true;
   }
 
+  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("init.svc.wpa_supplicant", "stopped", function (result) {
+        if (result === null) {
+          callback(false);
+          return;
+        }
+        if (result === "stopped" || ++count >= 5) {
+          // Either we succeeded or ran out of time.
+          timer = null;
+          callback(count < 5);
+          return;
+        }
+
+        // Else it's still running, continue waiting.
+        timer.initWithCallback(tick, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
+      });
+    }
+
+    setProperty("ctl.stop", "wpa_supplicant", tick);
+  }
+
+  function prepareForStartup(callback) {
+    stopDhcp(manager.ifname, function() {
+      // Ignore any errors.
+      killSupplicant(callback);
+    });
+  }
+
   // Initial state
   var airplaneMode = false;
 
   // Public interface of the wifi service
   manager.setWifiEnabled = function(enable, callback) {
     var targetState = enable ? "ENABLED" : "DISABLED";
     if (enable == targetState)
       return true;
     if (enable && airplaneMode)
       return false;
     if (enable) {
-      loadDriver(function (status) {
-        if (status < 0) {
-          callback(status);
+      // Kill any existing connections if necessary.
+      getProperty("wifi.interface", "tiwlan0", function (ifname) {
+        if (!ifname) {
+          callback(-1);
           return;
         }
-        startSupplicant(function (status) {
-          if (status < 0) {
-            callback(status);
-            return;
-          }
-          getProperty("wifi.interface", "tiwlan0", function (ifname) {
-            if (!ifname) {
-              callback(-1);
+        manager.ifname = ifname;
+
+        prepareForStartup(function() {
+          // Ignore errors...
+          loadDriver(function (status) {
+            if (status < 0) {
+              callback(status);
               return;
             }
-            manager.ifname = ifname;
-            enableInterface(ifname, function (ok) {
-              callback(ok ? 0 : -1);
+            startSupplicant(function (status) {
+              if (status < 0) {
+                callback(status);
+                return;
+              }
+              enableInterface(ifname, function (ok) {
+                callback(ok ? 0 : -1);
+              });
             });
           });
         });
       });
     } else {
       stopSupplicant(function (status) {
         if (ok < 0) {
           callback(-1);