1
0
Fork 0
mirror of https://github.com/syncthing/syncthing-android.git synced 2024-11-26 22:31:16 +00:00

Use volley for API requests (fixes #827)

This commit is contained in:
Felix Ableitner 2017-01-08 16:38:49 +09:00
parent 71546fb160
commit 618945c5bf
11 changed files with 202 additions and 243 deletions

View file

@ -27,6 +27,7 @@ dependencies {
compile 'org.mindrot:jbcrypt:0.3m' compile 'org.mindrot:jbcrypt:0.3m'
compile 'com.google.guava:guava:20.0' compile 'com.google.guava:guava:20.0'
compile 'com.annimon:stream:1.1.4' compile 'com.annimon:stream:1.1.4'
compile 'com.android.volley:volley:1.0.0'
androidTestCompile 'com.android.support.test:rules:0.5' androidTestCompile 'com.android.support.test:rules:0.5'
} }

View file

@ -2,13 +2,19 @@ package com.nutomic.syncthingandroid.http;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
import android.util.Pair;
import com.google.common.base.Charsets; import com.android.volley.AuthFailureError;
import com.google.common.io.ByteSource; import com.android.volley.RequestQueue;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HurlStack;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -27,16 +33,17 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Map; import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
public abstract class RestTask extends public abstract class ApiRequest {
AsyncTask<Void, Void, Pair<Boolean, String>> {
private static final String TAG = "RestTask"; private static final String TAG = "ApiRequest";
/** /**
* The name of the HTTP header used for the syncthing API key. * The name of the HTTP header used for the syncthing API key.
@ -47,74 +54,91 @@ public abstract class RestTask extends
public void onSuccess(String result); public void onSuccess(String result);
} }
public interface OnErrorListener {
public void onError(VolleyError error);
}
private static RequestQueue sVolleyQueue;
private RequestQueue getVolleyQueue() {
if (sVolleyQueue == null) {
Context context = mContext.getApplicationContext();
sVolleyQueue = Volley.newRequestQueue(context, new NetworkStack());
}
return sVolleyQueue;
}
private final Context mContext;
private final URL mUrl; private final URL mUrl;
protected final String mPath; protected final String mPath;
private final String mHttpsCertPath; private final String mHttpsCertPath;
private final String mApiKey; private final String mApiKey;
private final OnSuccessListener mListener;
public RestTask(URL url, String path, String httpsCertPath, String apiKey, public ApiRequest(Context context, URL url, String path, String httpsCertPath, String apiKey) {
OnSuccessListener listener) { mContext = context;
mUrl = url; mUrl = url;
mPath = path; mPath = path;
mHttpsCertPath = httpsCertPath; mHttpsCertPath = httpsCertPath;
mApiKey = apiKey; mApiKey = apiKey;
mListener = listener;
} }
protected HttpsURLConnection openConnection(Map<String, String> params) throws IOException { protected Uri buildUri(Map<String, String> params) {
Uri.Builder uriBuilder = Uri.parse(mUrl.toString()) Uri.Builder uriBuilder = Uri.parse(mUrl.toString())
.buildUpon() .buildUpon()
.path(mPath); .path(mPath);
for (Map.Entry<String, String> entry : params.entrySet()) { for (Map.Entry<String, String> entry : params.entrySet()) {
uriBuilder.appendQueryParameter(entry.getKey(), entry.getValue()); uriBuilder.appendQueryParameter(entry.getKey(), entry.getValue());
} }
URL url = new URL(uriBuilder.build().toString()); return uriBuilder.build();
Log.v(TAG, "Calling Rest API at " + url);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestProperty(HEADER_API_KEY, mApiKey);
connection.setHostnameVerifier((h, s) -> true);
connection.setSSLSocketFactory(getSslSocketFactory());
return connection;
} }
/** /**
* Opens the connection, then returns success status and response string. * Opens the connection, then returns success status and response string.
*/ */
protected Pair<Boolean, String> connect(HttpsURLConnection connection) throws IOException { protected void connect(int requestMethod, Uri uri, @Nullable String requestBody,
connection.connect(); @Nullable OnSuccessListener listener, @Nullable OnErrorListener errorListener) {
Pair<Boolean, String> result; StringRequest request = new StringRequest(requestMethod, uri.toString(), reply -> {
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { if (listener != null)
int responseCode = connection.getResponseCode(); listener.onSuccess(reply);
String responseMessage = connection.getResponseMessage(); }, error -> {
Log.i(TAG, "Request to " + connection.getURL() + " failed, code: " + responseCode + if (errorListener != null)
", message: " + responseMessage); errorListener.onError(error);
result = new Pair<>(false, streamToString(connection.getErrorStream()));
} Log.w(TAG, "Request to " + uri + " failed: " + error.getMessage());
else { }) {
result = new Pair<>(true, streamToString(connection.getInputStream())); @Override
} public Map<String, String> getHeaders() throws AuthFailureError {
connection.disconnect(); return ImmutableMap.of(HEADER_API_KEY, mApiKey);
return result;
} }
private String streamToString(InputStream is) throws IOException {
ByteSource byteSource = new ByteSource() {
@Override @Override
public InputStream openStream() throws IOException { public byte[] getBody() throws AuthFailureError {
return is; return Optional.fromNullable(requestBody).transform(String::getBytes).orNull();
} }
}; };
return byteSource.asCharSource(Charsets.UTF_8).read(); getVolleyQueue().add(request);
} }
/**
* Extends {@link HurlStack}, uses {@link #getSslSocketFactory()} and disables hostname
* verification.
*/
private class NetworkStack extends HurlStack {
protected void onPostExecute(Pair<Boolean, String> result) { public NetworkStack() {
if (mListener == null || !result.first) super(null, getSslSocketFactory());
return; }
@Override
mListener.onSuccess(result.second); protected HttpURLConnection createConnection(URL url) throws IOException {
HttpsURLConnection connection = (HttpsURLConnection) super.createConnection(url);
connection.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
return connection;
}
} }
private SSLSocketFactory getSslSocketFactory() { private SSLSocketFactory getSslSocketFactory() {

View file

@ -0,0 +1,36 @@
package com.nutomic.syncthingandroid.http;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.Nullable;
import com.android.volley.Request;
import com.google.common.base.Optional;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
/**
* Performs a GET request to the Syncthing API
*/
public class GetRequest extends ApiRequest {
public static final String URI_CONFIG = "/rest/system/config";
public static final String URI_VERSION = "/rest/system/version";
public static final String URI_SYSTEM = "/rest/system/status";
public static final String URI_CONNECTIONS = "/rest/system/connections";
public static final String URI_MODEL = "/rest/db/status";
public static final String URI_DEVICEID = "/rest/svc/deviceid";
public static final String URI_REPORT = "/rest/svc/report";
public static final String URI_EVENTS = "/rest/events";
public GetRequest(Context context, URL url, String path, String httpsCertPath, String apiKey,
@Nullable Map<String, String> params, OnSuccessListener listener) {
super(context, url, path, httpsCertPath, apiKey);
Map<String, String> safeParams = Optional.fromNullable(params).or(Collections.emptyMap());
Uri uri = buildUri(safeParams);
connect(Request.Method.GET, uri, null, listener, null);
}
}

View file

@ -1,54 +0,0 @@
package com.nutomic.syncthingandroid.http;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.Pair;
import com.google.common.base.Optional;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
/**
* Performs a GET request to the Syncthing API
* Performs a GET request with no parameters to the URL in uri[0] with the path in uri[1] and
* returns the result as a String.
*/
public class GetTask extends RestTask {
private static final String TAG = "GetTask";
public static final String URI_CONFIG = "/rest/system/config";
public static final String URI_VERSION = "/rest/system/version";
public static final String URI_SYSTEM = "/rest/system/status";
public static final String URI_CONNECTIONS = "/rest/system/connections";
public static final String URI_MODEL = "/rest/db/status";
public static final String URI_DEVICEID = "/rest/svc/deviceid";
public static final String URI_REPORT = "/rest/svc/report";
public static final String URI_EVENTS = "/rest/events";
private final Map<String, String> mParams;
public GetTask(URL url, String path, String httpsCertPath, String apiKey,
@Nullable Map<String, String> params, OnSuccessListener listener) {
super(url, path, httpsCertPath, apiKey, listener);
mParams = Optional.fromNullable(params).or(Collections.emptyMap());
}
@Override
protected Pair<Boolean, String> doInBackground(Void... aVoid) {
try {
HttpsURLConnection connection = openConnection(mParams);
Log.v(TAG, "Calling Rest API at " + connection.getURL());
return connect(connection);
} catch (IOException e) {
Log.w(TAG, "Failed to call rest api", e);
return new Pair<>(false, null);
}
}
}

View file

@ -1,21 +1,20 @@
package com.nutomic.syncthingandroid.http; package com.nutomic.syncthingandroid.http;
import android.util.Log; import android.content.Context;
import android.util.Pair; import android.net.Uri;
import android.os.Handler;
import com.google.common.collect.Maps; import com.android.volley.Request;
import com.android.volley.VolleyError;
import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import javax.net.ssl.HttpsURLConnection;
/** /**
* Polls to load the web interface, until we receive http status 200. * Polls to load the web interface, until it is available.
*/ */
public class PollWebGuiAvailableTask extends RestTask { public class PollWebGuiAvailableTask extends ApiRequest {
private static final String TAG = "PollWebGuiAvailableTask"; private static final String TAG = "PollWebGuiAvailableTask";
@ -25,29 +24,23 @@ public class PollWebGuiAvailableTask extends RestTask {
*/ */
private static final long WEB_GUI_POLL_INTERVAL = 100; private static final long WEB_GUI_POLL_INTERVAL = 100;
public PollWebGuiAvailableTask(URL url, String httpsCertPath, String apiKey, private final OnSuccessListener mListener;
private final Handler mHandler = new Handler();
public PollWebGuiAvailableTask(Context context, URL url, String httpsCertPath, String apiKey,
OnSuccessListener listener) { OnSuccessListener listener) {
super(url, "", httpsCertPath, apiKey, listener); super(context, url, "", httpsCertPath, apiKey);
mListener = listener;
performRequest();
} }
@Override private void performRequest() {
protected Pair<Boolean, String> doInBackground(Void... aVoid) { Uri uri = buildUri(Collections.emptyMap());
int status = 0; connect(Request.Method.GET, uri, null, mListener, this::onError);
do {
try {
HttpsURLConnection connection = openConnection(Collections.emptyMap());
connection.connect();
status = connection.getResponseCode();
} catch (IOException e) {
// We catch this in every call, as long as the service is not online, so we ignore and continue.
try {
Thread.sleep(WEB_GUI_POLL_INTERVAL);
} catch (InterruptedException e2) {
Log.w(TAG, "Failed to sleep", e2);
} }
}
} while (status != HttpsURLConnection.HTTP_OK); private void onError(VolleyError error) {
return new Pair<>(true, null); mHandler.postDelayed(this::performRequest, WEB_GUI_POLL_INTERVAL);
} }
} }

View file

@ -0,0 +1,22 @@
package com.nutomic.syncthingandroid.http;
import android.content.Context;
import android.net.Uri;
import com.android.volley.Request;
import java.net.URL;
import java.util.Collections;
public class PostConfigRequest extends ApiRequest {
private static final String URI_CONFIG = "/rest/system/config";
public PostConfigRequest(Context context, URL url, String httpsCertPath, String apiKey, String config,
OnSuccessListener listener) {
super(context, url, URI_CONFIG, httpsCertPath, apiKey);
Uri uri = buildUri(Collections.emptyMap());
connect(Request.Method.POST, uri, config, listener, null);
}
}

View file

@ -1,43 +0,0 @@
package com.nutomic.syncthingandroid.http;
import android.util.Log;
import android.util.Pair;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.Collections;
import javax.net.ssl.HttpsURLConnection;
public class PostConfigTask extends RestTask {
private static final String TAG = "PostConfigTask";
private static final String URI_CONFIG = "/rest/system/config";
private final String mConfig;
public PostConfigTask(URL url, String httpsCertPath, String apiKey, String config,
OnSuccessListener listener) {
super(url, URI_CONFIG, httpsCertPath, apiKey, listener);
mConfig = config;
}
@Override
protected Pair<Boolean, String> doInBackground(Void... params) {
try {
HttpsURLConnection connection = openConnection(Collections.emptyMap());
connection.setRequestMethod("POST");
Log.v(TAG, "Calling Rest API at " + connection.getURL());
OutputStream os = connection.getOutputStream();
os.write(mConfig.getBytes("UTF-8"));
return connect(connection);
} catch (IOException e) {
Log.w(TAG, "Failed to call rest api", e);
return new Pair<>(false, null);
}
}
}

View file

@ -0,0 +1,22 @@
package com.nutomic.syncthingandroid.http;
import android.content.Context;
import android.net.Uri;
import com.android.volley.Request;
import com.google.common.collect.ImmutableMap;
import java.net.URL;
public class PostScanRequest extends ApiRequest {
private static final String URI_SCAN = "/rest/db/scan";
public PostScanRequest(Context context, URL url, String httpsCertPath, String apiKey,
String folder, String sub) {
super(context, url, URI_SCAN, httpsCertPath, apiKey);
Uri uri = buildUri(ImmutableMap.of("folder", folder, "sub", sub));
connect(Request.Method.POST, uri, null, null, null);
}
}

View file

@ -1,40 +0,0 @@
package com.nutomic.syncthingandroid.http;
import android.util.Log;
import android.util.Pair;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class PostScanTask extends RestTask {
private static final String TAG = "PostScanTask";
private static final String URI_SCAN = "/rest/db/scan";
private final String mFolder;
private final String mSub;
public PostScanTask(URL url, String httpsCertPath, String apiKey, String folder, String sub) {
super(url, URI_SCAN, httpsCertPath, apiKey, null);
mFolder = folder;
mSub = sub;
}
@Override
protected Pair<Boolean, String> doInBackground(Void... params) {
try {
HttpsURLConnection connection = openConnection(ImmutableMap.of("folder", mFolder, "sub", mSub));
connection.setRequestMethod("POST");
return connect(connection);
} catch (IOException e) {
Log.w(TAG, "Failed to call rest api", e);
return new Pair<>(false, null);
}
}
}

View file

@ -18,9 +18,9 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.nutomic.syncthingandroid.BuildConfig; import com.nutomic.syncthingandroid.BuildConfig;
import com.nutomic.syncthingandroid.activities.RestartActivity; import com.nutomic.syncthingandroid.activities.RestartActivity;
import com.nutomic.syncthingandroid.http.GetTask; import com.nutomic.syncthingandroid.http.GetRequest;
import com.nutomic.syncthingandroid.http.PostConfigTask; import com.nutomic.syncthingandroid.http.PostConfigRequest;
import com.nutomic.syncthingandroid.http.PostScanTask; import com.nutomic.syncthingandroid.http.PostScanRequest;
import com.nutomic.syncthingandroid.model.Config; import com.nutomic.syncthingandroid.model.Config;
import com.nutomic.syncthingandroid.model.Connections; import com.nutomic.syncthingandroid.model.Connections;
import com.nutomic.syncthingandroid.model.Device; import com.nutomic.syncthingandroid.model.Device;
@ -71,13 +71,13 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
private boolean mRestartPostponed = false; private boolean mRestartPostponed = false;
/** /**
* Stores the result of the last successful request to {@link GetTask#URI_CONNECTIONS}, * Stores the result of the last successful request to {@link GetRequest#URI_CONNECTIONS},
* or an empty Map. * or an empty Map.
*/ */
private Optional<Connections> mPreviousConnections = Optional.absent(); private Optional<Connections> mPreviousConnections = Optional.absent();
/** /**
* Stores the timestamp of the last successful request to {@link GetTask#URI_CONNECTIONS}. * Stores the timestamp of the last successful request to {@link GetRequest#URI_CONNECTIONS}.
*/ */
private long mPreviousConnectionTime = 0; private long mPreviousConnectionTime = 0;
@ -121,16 +121,16 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
@Override @Override
public void onWebGuiAvailable() { public void onWebGuiAvailable() {
mAvailableCount.set(0); mAvailableCount.set(0);
new GetTask(mUrl, GetTask.URI_VERSION, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_VERSION, mHttpsCertPath, mApiKey, null, result -> {
JsonObject json = new JsonParser().parse(result).getAsJsonObject(); JsonObject json = new JsonParser().parse(result).getAsJsonObject();
mVersion = json.get("version").getAsString(); mVersion = json.get("version").getAsString();
Log.i(TAG, "Syncthing version is " + mVersion); Log.i(TAG, "Syncthing version is " + mVersion);
tryIsAvailable(); tryIsAvailable();
}).execute(); });
new GetTask(mUrl, GetTask.URI_CONFIG, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_CONFIG, mHttpsCertPath, mApiKey, null, result -> {
mConfig = new Gson().fromJson(result, Config.class); mConfig = new Gson().fromJson(result, Config.class);
tryIsAvailable(); tryIsAvailable();
}).execute(); });
getSystemInfo(info -> { getSystemInfo(info -> {
mLocalDeviceId = info.myID; mLocalDeviceId = info.myID;
tryIsAvailable(); tryIsAvailable();
@ -168,19 +168,18 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
* Sends current config to Syncthing. * Sends current config to Syncthing.
*/ */
private void sendConfig() { private void sendConfig() {
new PostConfigTask(mUrl, mHttpsCertPath, mApiKey, new Gson().toJson(mConfig), null) new PostConfigRequest(mContext, mUrl, mHttpsCertPath, mApiKey, new Gson().toJson(mConfig), null);
.execute();
} }
/** /**
* Sends current config and restarts Syncthing. * Sends current config and restarts Syncthing.
*/ */
public void restart() { public void restart() {
new PostConfigTask(mUrl, mHttpsCertPath, mApiKey, new Gson().toJson(mConfig), result -> { new PostConfigRequest(mContext, mUrl, mHttpsCertPath, mApiKey, new Gson().toJson(mConfig), result -> {
Intent intent = new Intent(mContext, SyncthingService.class) Intent intent = new Intent(mContext, SyncthingService.class)
.setAction(SyncthingService.ACTION_RESTART); .setAction(SyncthingService.ACTION_RESTART);
mContext.startService(intent); mContext.startService(intent);
}).execute(); });
} }
/** /**
@ -312,9 +311,9 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
* Requests and parses information about current system status and resource usage. * Requests and parses information about current system status and resource usage.
*/ */
public void getSystemInfo(OnResultListener1<SystemInfo> listener) { public void getSystemInfo(OnResultListener1<SystemInfo> listener) {
new GetTask(mUrl, GetTask.URI_SYSTEM, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_SYSTEM, mHttpsCertPath, mApiKey, null, result -> {
listener.onResult(new Gson().fromJson(result, SystemInfo.class)); listener.onResult(new Gson().fromJson(result, SystemInfo.class));
}).execute(); });
} }
public boolean isConfigLoaded() { public boolean isConfigLoaded() {
@ -325,17 +324,17 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
* Requests and parses system version information. * Requests and parses system version information.
*/ */
public void getSystemVersion(OnResultListener1<SystemVersion> listener) { public void getSystemVersion(OnResultListener1<SystemVersion> listener) {
new GetTask(mUrl, GetTask.URI_VERSION, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_VERSION, mHttpsCertPath, mApiKey, null, result -> {
SystemVersion systemVersion = new Gson().fromJson(result, SystemVersion.class); SystemVersion systemVersion = new Gson().fromJson(result, SystemVersion.class);
listener.onResult(systemVersion); listener.onResult(systemVersion);
}).execute(); });
} }
/** /**
* Returns connection info for the local device and all connected devices. * Returns connection info for the local device and all connected devices.
*/ */
public void getConnections(final OnResultListener1<Connections> listener) { public void getConnections(final OnResultListener1<Connections> listener) {
new GetTask(mUrl, GetTask.URI_CONNECTIONS, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_CONNECTIONS, mHttpsCertPath, mApiKey, null, result -> {
Long now = System.currentTimeMillis(); Long now = System.currentTimeMillis();
Long msElapsed = now - mPreviousConnectionTime; Long msElapsed = now - mPreviousConnectionTime;
if (msElapsed < SyncthingService.GUI_UPDATE_INTERVAL) { if (msElapsed < SyncthingService.GUI_UPDATE_INTERVAL) {
@ -359,7 +358,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
connections.total.setTransferRate(prev, msElapsed); connections.total.setTransferRate(prev, msElapsed);
mPreviousConnections = Optional.of(connections); mPreviousConnections = Optional.of(connections);
listener.onResult(deepCopy(connections, Connections.class)); listener.onResult(deepCopy(connections, Connections.class));
}).execute(); });
} }
/** /**
@ -398,12 +397,12 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
* Returns status information about the folder with the given id. * Returns status information about the folder with the given id.
*/ */
public void getModel(final String folderId, final OnResultListener2<String, Model> listener) { public void getModel(final String folderId, final OnResultListener2<String, Model> listener) {
new GetTask(mUrl, GetTask.URI_MODEL, mHttpsCertPath, mApiKey, new GetRequest(mContext, mUrl, GetRequest.URI_MODEL, mHttpsCertPath, mApiKey,
ImmutableMap.of("folder", folderId), result -> { ImmutableMap.of("folder", folderId), result -> {
Model m = new Gson().fromJson(result, Model.class); Model m = new Gson().fromJson(result, Model.class);
mCachedModelInfo.put(folderId, m); mCachedModelInfo.put(folderId, m);
listener.onResult(folderId, m); listener.onResult(folderId, m);
}).execute(); });
} }
/** /**
@ -431,7 +430,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
public final void getEvents(final long sinceId, final long limit, final OnReceiveEventListener listener) { public final void getEvents(final long sinceId, final long limit, final OnReceiveEventListener listener) {
Map<String, String> params = Map<String, String> params =
ImmutableMap.of("since", String.valueOf(sinceId), "limit", String.valueOf(limit)); ImmutableMap.of("since", String.valueOf(sinceId), "limit", String.valueOf(limit));
new GetTask(mUrl, GetTask.URI_EVENTS, mHttpsCertPath, mApiKey, params, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_EVENTS, mHttpsCertPath, mApiKey, params, result -> {
JsonArray jsonEvents = new JsonParser().parse(result).getAsJsonArray(); JsonArray jsonEvents = new JsonParser().parse(result).getAsJsonArray();
long lastId = 0; long lastId = 0;
@ -446,7 +445,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
} }
listener.onDone(lastId); listener.onDone(lastId);
}).execute(); });
} }
/** /**
@ -454,8 +453,8 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
*/ */
public void normalizeDeviceId(String id, OnResultListener1<String> listener, public void normalizeDeviceId(String id, OnResultListener1<String> listener,
OnResultListener1<String> errorListener) { OnResultListener1<String> errorListener) {
new GetTask(mUrl, GetTask.URI_DEVICEID, mHttpsCertPath, mApiKey, ImmutableMap.of("id", id), new GetRequest(mContext, mUrl, GetRequest.URI_DEVICEID, mHttpsCertPath, mApiKey,
result -> { ImmutableMap.of("id", id), result -> {
JsonObject json = new JsonParser().parse(result).getAsJsonObject(); JsonObject json = new JsonParser().parse(result).getAsJsonObject();
JsonElement normalizedId = json.get("id"); JsonElement normalizedId = json.get("id");
JsonElement error = json.get("error"); JsonElement error = json.get("error");
@ -463,7 +462,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
listener.onResult(normalizedId.getAsString()); listener.onResult(normalizedId.getAsString());
if (error != null) if (error != null)
errorListener.onResult(error.getAsString()); errorListener.onResult(error.getAsString());
}).execute(); });
} }
/** /**
@ -471,19 +470,18 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
*/ */
@Override @Override
public void onFolderFileChange(String folderId, String relativePath) { public void onFolderFileChange(String folderId, String relativePath) {
new PostScanTask(mUrl, mHttpsCertPath, mApiKey, folderId, relativePath) new PostScanRequest(mContext, mUrl, mHttpsCertPath, mApiKey, folderId, relativePath);
.execute();
} }
/** /**
* Returns prettyfied usage report. * Returns prettyfied usage report.
*/ */
public void getUsageReport(final OnResultListener1<String> listener) { public void getUsageReport(final OnResultListener1<String> listener) {
new GetTask(mUrl, GetTask.URI_REPORT, mHttpsCertPath, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_REPORT, mHttpsCertPath, mApiKey, null, result -> {
JsonElement json = new JsonParser().parse(result); JsonElement json = new JsonParser().parse(result);
Gson gson = new GsonBuilder().setPrettyPrinting().create(); Gson gson = new GsonBuilder().setPrettyPrinting().create();
listener.onResult(gson.toJson(json)); listener.onResult(gson.toJson(json));
}).execute(); });
} }
public void setRestartPostponed() { public void setRestartPostponed() {

View file

@ -491,7 +491,7 @@ public class SyncthingService extends Service implements
* for SyncthingService.onDestroy for details. * for SyncthingService.onDestroy for details.
*/ */
private void pollWebGui() { private void pollWebGui() {
new PollWebGuiAvailableTask(getWebGuiUrl(), getFilesDir() + "/" + HTTPS_CERT_FILE, new PollWebGuiAvailableTask(this, getWebGuiUrl(), getFilesDir() + "/" + HTTPS_CERT_FILE,
mConfig.getApiKey(), result -> { mConfig.getApiKey(), result -> {
synchronized (stateLock) { synchronized (stateLock) {
if (mStopScheduled) { if (mStopScheduled) {
@ -510,7 +510,7 @@ public class SyncthingService extends Service implements
listener.onWebGuiAvailable(); listener.onWebGuiAvailable();
} }
mOnWebGuiAvailableListeners.clear(); mOnWebGuiAvailableListeners.clear();
}).execute(); });
} }
/** /**