Cache available debug facilities and fall back to hardcoded list (fixes #1113, fixes #504)

This commit is contained in:
Catfriend1 2018-06-01 23:02:37 +02:00 committed by Audrius Butkevicius
parent d1cb58fc7e
commit 6a4c99848d
4 changed files with 90 additions and 26 deletions

View File

@ -17,6 +17,7 @@ import java.util.Map;
public class GetRequest extends ApiRequest { public class GetRequest extends ApiRequest {
public static final String URI_CONFIG = "/rest/system/config"; public static final String URI_CONFIG = "/rest/system/config";
public static final String URI_DEBUG = "/rest/system/debug";
public static final String URI_VERSION = "/rest/system/version"; public static final String URI_VERSION = "/rest/system/version";
public static final String URI_SYSTEM = "/rest/system/status"; public static final String URI_SYSTEM = "/rest/system/status";
public static final String URI_CONNECTIONS = "/rest/system/connections"; public static final String URI_CONNECTIONS = "/rest/system/connections";

View File

@ -23,6 +23,12 @@ public class Constants {
public static final String PREF_SOCKS_PROXY_ADDRESS = "socks_proxy_address"; public static final String PREF_SOCKS_PROXY_ADDRESS = "socks_proxy_address";
public static final String PREF_HTTP_PROXY_ADDRESS = "http_proxy_address"; public static final String PREF_HTTP_PROXY_ADDRESS = "http_proxy_address";
/**
* Available options cache for preference {@link app_settings#sttrace}
* Read via REST API call in {@link RestApi#updateDebugFacilitiesCache} after first successful binary startup.
*/
public static final String PREF_STTRACE_AVAILABLE_OPTIONS = "sttrace_available_options";
/** /**
* On Android 8.1, ACCESS_COARSE_LOCATION is required to access WiFi SSID. * On Android 8.1, ACCESS_COARSE_LOCATION is required to access WiFi SSID.
* This is the request code used when requesting the permission. * This is the request code used when requesting the permission.

View File

@ -33,15 +33,18 @@ import com.nutomic.syncthingandroid.model.FolderStatus;
import com.nutomic.syncthingandroid.model.Options; import com.nutomic.syncthingandroid.model.Options;
import com.nutomic.syncthingandroid.model.SystemInfo; import com.nutomic.syncthingandroid.model.SystemInfo;
import com.nutomic.syncthingandroid.model.SystemVersion; import com.nutomic.syncthingandroid.model.SystemVersion;
import com.nutomic.syncthingandroid.service.Constants;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Inject; import javax.inject.Inject;
@ -145,6 +148,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
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();
updateDebugFacilitiesCache();
}); });
new GetRequest(mContext, mUrl, GetRequest.URI_CONFIG, mApiKey, null, result -> { new GetRequest(mContext, mUrl, GetRequest.URI_CONFIG, mApiKey, null, result -> {
onReloadConfigComplete(result); onReloadConfigComplete(result);
@ -171,6 +175,40 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
mCompletion.updateFromConfig(getDevices(true), getFolders()); mCompletion.updateFromConfig(getDevices(true), getFolders());
} }
/**
* Queries debug facilities available from the currently running syncthing binary
* if the syncthing binary version changed. First launch of the binary is also
* considered as a version change.
* Precondition: {@link #mVersion} read from REST
*/
private void updateDebugFacilitiesCache() {
final String PREF_LAST_BINARY_VERSION = "lastBinaryVersion";
if (!mVersion.equals(PreferenceManager.getDefaultSharedPreferences(mContext).getString(PREF_LAST_BINARY_VERSION, ""))) {
// First binary launch or binary upgraded case.
new GetRequest(mContext, mUrl, GetRequest.URI_DEBUG, mApiKey, null, result -> {
try {
Set<String> facilitiesToStore = new HashSet<String>();
JsonObject json = new JsonParser().parse(result).getAsJsonObject();
JsonObject jsonFacilities = json.getAsJsonObject("facilities");
for (String facilityName : jsonFacilities.keySet()) {
facilitiesToStore.add(facilityName);
}
PreferenceManager.getDefaultSharedPreferences(mContext).edit()
.putStringSet(Constants.PREF_STTRACE_AVAILABLE_OPTIONS, facilitiesToStore)
.apply();
// Store current binary version so we will only store this information again
// after a binary update.
PreferenceManager.getDefaultSharedPreferences(mContext).edit()
.putString(PREF_LAST_BINARY_VERSION, mVersion)
.apply();
} catch (Exception e) {
Log.w(TAG, "updateDebugFacilitiesCache: Failed to get debug facilities. result=" + result);
}
});
}
}
/** /**
* Increments mAvailableCount by one, and, if it reached TOTAL_STARTUP_CALLS, * Increments mAvailableCount by one, and, if it reached TOTAL_STARTUP_CALLS,
* calls {@link SyncthingService#onApiChange}. * calls {@link SyncthingService#onApiChange}.

View File

@ -8,6 +8,9 @@ import android.preference.MultiSelectListPreference;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log;
import com.nutomic.syncthingandroid.service.Constants;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -30,6 +33,8 @@ import java.util.TreeSet;
*/ */
public class SttracePreference extends MultiSelectListPreference { public class SttracePreference extends MultiSelectListPreference {
private final String TAG = "SttracePreference";
public SttracePreference(Context context, AttributeSet attrs) { public SttracePreference(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
setDefaultValue(new TreeSet<String>()); setDefaultValue(new TreeSet<String>());
@ -69,32 +74,46 @@ public class SttracePreference extends MultiSelectListPreference {
* Returns all debug facilities available in the currently syncthing version. * Returns all debug facilities available in the currently syncthing version.
*/ */
private CharSequence[] getDebugFacilities() { private CharSequence[] getDebugFacilities() {
// Syncthing v0.14.47 debug facilities. List<String> retDebugFacilities = new ArrayList<String>();
List<String> debugFacilities = new ArrayList<String>(); Set<String> availableDebugFacilities = getSharedPreferences().getStringSet(Constants.PREF_STTRACE_AVAILABLE_OPTIONS, new HashSet<>());
debugFacilities.add("beacon"); // from JavaDoc: Note that you must not modify the set instance returned by this call.
debugFacilities.add("config"); // therefore required to make a defensive copy of the elements
debugFacilities.add("connections"); availableDebugFacilities = new HashSet<>(availableDebugFacilities);
debugFacilities.add("db"); if (!availableDebugFacilities.isEmpty()) {
debugFacilities.add("dialer"); for (String facilityName : availableDebugFacilities) {
debugFacilities.add("discover"); retDebugFacilities.add(facilityName);
debugFacilities.add("events"); }
debugFacilities.add("fs"); } else {
debugFacilities.add("http"); Log.w(TAG, "getDebugFacilities: Failed to get facilities from prefs, falling back to hardcoded list.");
debugFacilities.add("main");
debugFacilities.add("model"); // Syncthing v0.14.47 debug facilities.
debugFacilities.add("nat"); retDebugFacilities.add("beacon");
debugFacilities.add("pmp"); retDebugFacilities.add("config");
debugFacilities.add("protocol"); retDebugFacilities.add("connections");
debugFacilities.add("scanner"); retDebugFacilities.add("db");
debugFacilities.add("sha256"); retDebugFacilities.add("dialer");
debugFacilities.add("stats"); retDebugFacilities.add("discover");
debugFacilities.add("sync"); retDebugFacilities.add("events");
debugFacilities.add("upgrade"); retDebugFacilities.add("fs");
debugFacilities.add("upnp"); retDebugFacilities.add("http");
debugFacilities.add("versioner"); retDebugFacilities.add("main");
debugFacilities.add("walkfs"); retDebugFacilities.add("model");
debugFacilities.add("watchaggregator"); retDebugFacilities.add("nat");
return debugFacilities.toArray(new CharSequence[debugFacilities.size()]); retDebugFacilities.add("pmp");
retDebugFacilities.add("protocol");
retDebugFacilities.add("scanner");
retDebugFacilities.add("sha256");
retDebugFacilities.add("stats");
retDebugFacilities.add("sync");
retDebugFacilities.add("upgrade");
retDebugFacilities.add("upnp");
retDebugFacilities.add("versioner");
retDebugFacilities.add("walkfs");
retDebugFacilities.add("watchaggregator");
}
CharSequence[] retDebugFacilitiesArray = retDebugFacilities.toArray(new CharSequence[retDebugFacilities.size()]);
Arrays.sort(retDebugFacilitiesArray);
return retDebugFacilitiesArray;
} }
} }