From 91e06b8496f78df05ebde39e9c06ef7dda11f25e Mon Sep 17 00:00:00 2001
From: Hans-Christoph Steiner <hans@eds.org>
Date: Wed, 28 May 2014 15:29:04 -0400
Subject: [PATCH] new Wifi event cancels active processing of previous event

If a new "wifi connected" event comes in while a previous one is still
being processed, then cancel the current one as soon as possible.  This
prevents the events from being processed in an interleaved manner, causing
chaos and crashes.  Hopefully this will fix the jmdns crashes, since that
is triggered by onPostExecute() via FDroidApp.restartLocalRepoService().

java.lang.IllegalStateException: A service information can only be registered with a single instamce of JmDNS.
   at javax.jmdns.impl.JmDNSImpl.registerService(JmDNSImpl.java:1005)
   at org.fdroid.fdroid.localrepo.LocalRepoService$5.run(LocalRepoService.java:239)
   at java.lang.Thread.run(Thread.java:856)
---
 .../fdroid/net/WifiStateChangeService.java    | 23 ++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/src/org/fdroid/fdroid/net/WifiStateChangeService.java b/src/org/fdroid/fdroid/net/WifiStateChangeService.java
index c24271ff9..6b4fda481 100644
--- a/src/org/fdroid/fdroid/net/WifiStateChangeService.java
+++ b/src/org/fdroid/fdroid/net/WifiStateChangeService.java
@@ -23,9 +23,14 @@ import java.util.Locale;
 public class WifiStateChangeService extends Service {
     public static final String BROADCAST = "org.fdroid.fdroid.action.WIFI_CHANGE";
 
+    private static WaitForWifiAsyncTask asyncTask;
+
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        new WaitForWifiAsyncTask().execute();
+        if (asyncTask != null)
+            asyncTask.cancel(true);
+        asyncTask = new WaitForWifiAsyncTask();
+        asyncTask.execute();
         return START_NOT_STICKY;
     }
 
@@ -38,15 +43,21 @@ public class WifiStateChangeService extends Service {
             wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
             try {
                 while (!wifiManager.isWifiEnabled()) {
+                    if (isCancelled())
+                        return null;
                     Log.i(TAG, "waiting for the wifi to be enabled...");
-                    Thread.sleep(3000);
+                    Thread.sleep(1000);
                 }
                 int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
                 while (ipAddress == 0) {
+                    if (isCancelled())
+                        return null;
                     Log.i(TAG, "waiting for an IP address...");
-                    Thread.sleep(3000);
+                    Thread.sleep(1000);
                     ipAddress = wifiManager.getConnectionInfo().getIpAddress();
                 }
+                if (isCancelled())
+                    return null;
                 WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                 ipAddress = wifiInfo.getIpAddress();
                 FDroidApp.ipAddressString = String.format(Locale.ENGLISH, "%d.%d.%d.%d",
@@ -67,6 +78,9 @@ public class WifiStateChangeService extends Service {
                 FDroidApp.repo.address = String.format(Locale.ENGLISH, "%s://%s:%d/fdroid/repo",
                         scheme, FDroidApp.ipAddressString, FDroidApp.port);
 
+                if (isCancelled())
+                    return null;
+
                 Context context = WifiStateChangeService.this.getApplicationContext();
                 LocalRepoKeyStore localRepoKeyStore = LocalRepoKeyStore.get(context);
                 Certificate localCert = localRepoKeyStore.getCertificate();
@@ -75,6 +89,9 @@ public class WifiStateChangeService extends Service {
                 lrm.setUriString(FDroidApp.repo.address);
                 lrm.writeIndexPage(Utils.getSharingUri(context, FDroidApp.repo).toString());
 
+                if (isCancelled())
+                    return null;
+
                 /*
                  * Once the IP address is known we need to generate a self
                  * signed certificate to use for HTTPS that has a CN field set