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)
This commit is contained in:
Hans-Christoph Steiner 2014-05-28 15:29:04 -04:00
parent f51d192e13
commit 91e06b8496

View File

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