mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-11-22 12:21:15 +00:00
Improved polling for web gui (fixes #7).
This commit is contained in:
parent
a2a3f189b3
commit
7576e2a47d
2 changed files with 109 additions and 29 deletions
|
@ -8,7 +8,6 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
|
@ -30,7 +29,7 @@ import java.io.InputStream;
|
|||
/**
|
||||
* Holds a WebView that shows the web ui of the local syncthing instance.
|
||||
*/
|
||||
public class WebGuiActivity extends Activity {
|
||||
public class WebGuiActivity extends Activity implements SyncthingService.OnWebGuiAvailableListener {
|
||||
|
||||
private static final String TAG = "WebGuiActivity";
|
||||
|
||||
|
@ -54,6 +53,7 @@ public class WebGuiActivity extends Activity {
|
|||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
SyncthingServiceBinder binder = (SyncthingServiceBinder) service;
|
||||
mSyncthingService = binder.getService();
|
||||
mSyncthingService.registerOnWebGuiAvailableListener(WebGuiActivity.this);
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
|
@ -62,32 +62,14 @@ public class WebGuiActivity extends Activity {
|
|||
};
|
||||
|
||||
/**
|
||||
* Retries loading every second until the web UI becomes available.
|
||||
* Hides the loading screen and shows the WebView once it is fully loaded.
|
||||
*/
|
||||
private WebViewClient mWebViewClient = new WebViewClient() {
|
||||
|
||||
private int mError = 0;
|
||||
|
||||
@Override
|
||||
public void onReceivedError(WebView view, int errorCode, String description,
|
||||
String failingUrl) {
|
||||
mError = errorCode;
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mError = 0;
|
||||
mWebView.loadUrl(SyncthingService.SYNCTHING_URL);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
if (mError == 0) {
|
||||
mWebView.setVisibility(View.VISIBLE);
|
||||
mLoadingView.setVisibility(View.GONE);
|
||||
}
|
||||
mWebView.setVisibility(View.VISIBLE);
|
||||
mLoadingView.setVisibility(View.GONE);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -100,11 +82,6 @@ public class WebGuiActivity extends Activity {
|
|||
@SuppressLint("SetJavaScriptEnabled")
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getApplicationContext().startService(
|
||||
new Intent(this, SyncthingService.class));
|
||||
getApplicationContext().bindService(
|
||||
new Intent(this, SyncthingService.class),
|
||||
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
setContentView(R.layout.main);
|
||||
|
||||
|
@ -115,7 +92,6 @@ public class WebGuiActivity extends Activity {
|
|||
mWebView = (WebView) findViewById(R.id.webview);
|
||||
mWebView.getSettings().setJavaScriptEnabled(true);
|
||||
mWebView.setWebViewClient(mWebViewClient);
|
||||
mWebView.loadUrl(SyncthingService.SYNCTHING_URL);
|
||||
|
||||
// Handle first start.
|
||||
File config = new File(getApplicationInfo().dataDir, CONFIG_FILE);
|
||||
|
@ -130,8 +106,23 @@ public class WebGuiActivity extends Activity {
|
|||
.setNeutralButton(android.R.string.ok, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
getApplicationContext().startService(
|
||||
new Intent(this, SyncthingService.class));
|
||||
getApplicationContext().bindService(
|
||||
new Intent(this, SyncthingService.class),
|
||||
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and shows WebView, hides loading view.
|
||||
*/
|
||||
@Override
|
||||
public void onWebGuiAvailable() {
|
||||
mWebView.loadUrl(SyncthingService.SYNCTHING_URL);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Notification;
|
|||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
|
@ -11,10 +12,21 @@ import android.util.Log;
|
|||
import com.nutomic.syncthingandroid.R;
|
||||
import com.nutomic.syncthingandroid.WebGuiActivity;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpHead;
|
||||
import org.apache.http.conn.HttpHostConnectException;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Holds the native syncthing instance and provides an API to access it.
|
||||
|
@ -35,8 +47,26 @@ public class SyncthingService extends Service {
|
|||
*/
|
||||
public static final String SYNCTHING_URL = "http://127.0.0.1:8080";
|
||||
|
||||
/**
|
||||
* Interval in ms, at which connections to the web gui are performed on first start
|
||||
* to find out if it's online.
|
||||
*/
|
||||
private static final long WEB_GUI_POLL_INTERVAL = 100;
|
||||
|
||||
private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);
|
||||
|
||||
/**
|
||||
* Callback for when the Syncthing web interface becomes first available after service start.
|
||||
*/
|
||||
public interface OnWebGuiAvailableListener {
|
||||
public void onWebGuiAvailable();
|
||||
}
|
||||
|
||||
private LinkedList<OnWebGuiAvailableListener> mOnWebGuiAvailableListeners =
|
||||
new LinkedList<OnWebGuiAvailableListener>();
|
||||
|
||||
private boolean mIsWebGuiAvailable = false;
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
return START_STICKY;
|
||||
|
@ -100,6 +130,48 @@ public class SyncthingService extends Service {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls SYNCTHING_URL until it returns HTTP status OK, then calls all listeners
|
||||
* in mOnWebGuiAvailableListeners and clears it.
|
||||
*/
|
||||
private class PollWebGuiAvailableTask extends AsyncTask<Void, Void, Void> {
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
int status = 0;
|
||||
HttpClient httpclient = new DefaultHttpClient();
|
||||
HttpHead head = new HttpHead(SYNCTHING_URL);
|
||||
do {
|
||||
try {
|
||||
Thread.sleep(WEB_GUI_POLL_INTERVAL);
|
||||
HttpResponse response = httpclient.execute(head);
|
||||
// NOTE: status is not really needed, as HttpHostConnectException is thrown
|
||||
// earlier.
|
||||
status = response.getStatusLine().getStatusCode();
|
||||
}
|
||||
catch (HttpHostConnectException e) {
|
||||
// We catch this in every call, as long as the service is not online,
|
||||
// so we ignore and continue.
|
||||
}
|
||||
catch (IOException e) {
|
||||
Log.d(TAG, "Failed to poll for web interface", e);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Log.d(TAG, "Failed to poll for web interface", e);
|
||||
}
|
||||
} while(status != HttpStatus.SC_OK);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
mIsWebGuiAvailable = true;
|
||||
for (OnWebGuiAvailableListener listener : mOnWebGuiAvailableListeners) {
|
||||
listener.onWebGuiAvailable();
|
||||
}
|
||||
mOnWebGuiAvailableListeners.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates notification, starts native binary.
|
||||
|
@ -118,6 +190,8 @@ public class SyncthingService extends Service {
|
|||
startForeground(NOTIFICATION_ID, n);
|
||||
|
||||
new Thread(new NativeSyncthingRunnable()).start();
|
||||
|
||||
new PollWebGuiAvailableTask().execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -134,4 +208,19 @@ public class SyncthingService extends Service {
|
|||
new PostTask().execute(PostTask.URI_SHUTDOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a listener for the web gui becoming available..
|
||||
*
|
||||
* If the web gui is already available, listener will be called immediately.
|
||||
* Listeners are unregistered automatically after being called.
|
||||
*/
|
||||
public void registerOnWebGuiAvailableListener(OnWebGuiAvailableListener listener) {
|
||||
if (mIsWebGuiAvailable) {
|
||||
listener.onWebGuiAvailable();
|
||||
}
|
||||
else {
|
||||
mOnWebGuiAvailableListeners.addLast(listener);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue