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 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_SYSTEM = "/rest/system/status";
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_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.
* 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.SystemInfo;
import com.nutomic.syncthingandroid.model.SystemVersion;
import com.nutomic.syncthingandroid.service.Constants;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Inject;
@ -145,6 +148,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
mVersion = json.get("version").getAsString();
Log.i(TAG, "Syncthing version is " + mVersion);
tryIsAvailable();
updateDebugFacilitiesCache();
});
new GetRequest(mContext, mUrl, GetRequest.URI_CONFIG, mApiKey, null, result -> {
onReloadConfigComplete(result);
@ -171,6 +175,40 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
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,
* calls {@link SyncthingService#onApiChange}.

View File

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