Don't say wifi is connected until both wifi + bonjour are ready.

Although I can't reproduce reliably, I am hopeful that this will resolve
a lot of the errors such as #557.
This commit is contained in:
Peter Serwylo 2016-02-26 09:32:40 +11:00
parent cd3a064a5a
commit 3dd0589b08

View File

@ -19,6 +19,13 @@ import java.io.IOException;
import java.net.BindException; import java.net.BindException;
import java.util.Random; import java.util.Random;
import rx.Single;
import rx.SingleSubscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func2;
import rx.schedulers.Schedulers;
public class WifiSwap extends SwapType { public class WifiSwap extends SwapType {
private static final String TAG = "WifiSwap"; private static final String TAG = "WifiSwap";
@ -50,7 +57,58 @@ public class WifiSwap extends SwapType {
setConnected(false); setConnected(false);
} }
Runnable webServer = new Runnable() { Single.zip(
Single.create(getWebServerTask()),
Single.create(getBonjourTask()),
new Func2<Boolean, Boolean, Boolean>() {
@Override
public Boolean call(Boolean webServerTask, Boolean bonjourServiceTask) {
return bonjourServiceTask && webServerTask;
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean success) {
setConnected(success);
}
},
new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
setConnected(false);
}
});
}
/**
* A task which starts the {@link WifiSwap#bonjourBroadcast} and then emits a `true` value at
* the end.
*/
private Single.OnSubscribe<Boolean> getBonjourTask() {
return new Single.OnSubscribe<Boolean>() {
@Override
public void call(SingleSubscriber<? super Boolean> singleSubscriber) {
bonjourBroadcast.start();
// TODO: Be more intelligent about failures here so that we can invoke
// singleSubscriber.onError() in the appropriate circumstances.
singleSubscriber.onSuccess(true);
}
};
}
/**
* Constructs a new {@link Thread} for the webserver to run on. If successful, it will also
* populate the webServerThreadHandler property and bind it to that particular thread. This
* allows messages to be sent to the webserver thread by posting messages to that handler.
*/
private Single.OnSubscribe<Boolean> getWebServerTask() {
return new Single.OnSubscribe<Boolean>() {
@Override
public void call(final SingleSubscriber<? super Boolean> singleSubscriber) {
new Thread(new Runnable() {
// Tell Eclipse this is not a leak because of Looper use. // Tell Eclipse this is not a leak because of Looper use.
@SuppressLint("HandlerLeak") @SuppressLint("HandlerLeak")
@Override @Override
@ -67,7 +125,6 @@ public class WifiSwap extends SwapType {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
Log.i(TAG, "we've been asked to stop the webserver: " + msg.obj); Log.i(TAG, "we've been asked to stop the webserver: " + msg.obj);
setConnected(false);
localHttpd.stop(); localHttpd.stop();
Looper looper = Looper.myLooper(); Looper looper = Looper.myLooper();
if (looper == null) { if (looper == null) {
@ -80,23 +137,22 @@ public class WifiSwap extends SwapType {
try { try {
Utils.debugLog(TAG, "Starting swap webserver..."); Utils.debugLog(TAG, "Starting swap webserver...");
localHttpd.start(); localHttpd.start();
setConnected(true);
Utils.debugLog(TAG, "Swap webserver started."); Utils.debugLog(TAG, "Swap webserver started.");
singleSubscriber.onSuccess(true);
} catch (BindException e) { } catch (BindException e) {
int prev = FDroidApp.port; int prev = FDroidApp.port;
FDroidApp.port = FDroidApp.port + new Random().nextInt(1111); FDroidApp.port = FDroidApp.port + new Random().nextInt(1111);
setConnected(false);
Log.w(TAG, "port " + prev + " occupied, trying on " + FDroidApp.port + "!");
context.startService(new Intent(context, WifiStateChangeService.class)); context.startService(new Intent(context, WifiStateChangeService.class));
singleSubscriber.onError(new Exception("port " + prev + " occupied, trying on " + FDroidApp.port + "!"));
} catch (IOException e) { } catch (IOException e) {
setConnected(false);
Log.e(TAG, "Could not start local repo HTTP server", e); Log.e(TAG, "Could not start local repo HTTP server", e);
singleSubscriber.onError(e);
} }
Looper.loop(); // start the message receiving loop Looper.loop(); // start the message receiving loop
} }
}).start();
}
}; };
new Thread(webServer).start();
bonjourBroadcast.start();
} }
@Override @Override