diff --git a/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java b/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java index d1321cb2..e43c77fd 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java @@ -416,13 +416,7 @@ public class SettingsActivity extends SyncthingActivity { mSyncOnlyOnSSIDs.setEnabled((Boolean) o); break; case KEY_STTRACE: - if (((String) o).matches("[0-9a-z, ]*")) - mRequireRestart = true; - else { - Toast.makeText(getActivity(), R.string.toast_invalid_sttrace, Toast.LENGTH_SHORT) - .show(); - return false; - } + mRequireRestart = true; break; case Constants.PREF_ENVIRONMENT_VARIABLES: if (((String) o).matches("^(\\w+=[\\w:/\\.]+)?( \\w+=[\\w:/\\.]+)*$")) { diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java index 66b3ade1..9dfa0261 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java @@ -27,6 +27,7 @@ import java.io.LineNumberReader; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -437,7 +438,7 @@ public class SyncthingRunnable implements Runnable { HashMap targetEnv = new HashMap<>(); // Set home directory to data folder for web GUI folder picker. targetEnv.put("HOME", Environment.getExternalStorageDirectory().getAbsolutePath()); - targetEnv.put("STTRACE", mPreferences.getString("sttrace", "")); + targetEnv.put("STTRACE", TextUtils.join(" ", mPreferences.getStringSet("sttrace", new HashSet<>()))); File externalFilesDir = mContext.getExternalFilesDir(null); if (externalFilesDir != null) targetEnv.put("STGUIASSETS", externalFilesDir.getAbsolutePath() + "/gui"); diff --git a/app/src/main/java/com/nutomic/syncthingandroid/views/SttracePreference.java b/app/src/main/java/com/nutomic/syncthingandroid/views/SttracePreference.java new file mode 100644 index 00000000..fd8ebc3d --- /dev/null +++ b/app/src/main/java/com/nutomic/syncthingandroid/views/SttracePreference.java @@ -0,0 +1,100 @@ +package com.nutomic.syncthingandroid.views; + +import android.Manifest; +import android.content.Context; +import android.os.Build; +import android.os.Bundle; +import android.preference.MultiSelectListPreference; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.util.AttributeSet; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +/** + * SttracePreference which allows the user to select which debug facilities + * are enabled. + * + * Setting can be "no debug facility" (none selected), or selecting individual debug facilities. + * + * The preference is stored as Set<String> where an empty set represents + * "no debug facility". + * + * Debug facilities are documented in https://docs.syncthing.net/dev/debugging.html + * + */ +public class SttracePreference extends MultiSelectListPreference { + + public SttracePreference(Context context, AttributeSet attrs) { + super(context, attrs); + setDefaultValue(new TreeSet()); + } + + public SttracePreference(Context context) { + this(context, null); + } + + /** + * Show the dialog. + */ + @Override + protected void showDialog(Bundle state) { + Set selected = getSharedPreferences().getStringSet(getKey(), 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 + selected = new HashSet<>(selected); + CharSequence[] all = getDebugFacilities(); + filterRemovedDebugFacilities(selected, all); + setEntries(all); // display without surrounding quotes + setEntryValues(all); // the value of the entry is the debug facility "as is" + setValues(selected); // the currently selected values + super.showDialog(state); + } + + /** + * Removes any debug facility that is no longer present in the current syncthing version. + * Otherwise it will never be removed from the enabled facilities set by MultiSelectListPreference. + */ + private void filterRemovedDebugFacilities(Set selected, CharSequence[] all) { + HashSet availableDebugFacilities = new HashSet<>(Arrays.asList(all)); + selected.retainAll(availableDebugFacilities); + } + + /** + * Returns all debug facilities available in the currently syncthing version. + */ + private CharSequence[] getDebugFacilities() { + // Syncthing v0.14.47 debug facilities. + List debugFacilities = new ArrayList(); + 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()]); + } + +} diff --git a/app/src/main/res/xml/app_settings.xml b/app/src/main/res/xml/app_settings.xml index b736ee54..3b8164c7 100644 --- a/app/src/main/res/xml/app_settings.xml +++ b/app/src/main/res/xml/app_settings.xml @@ -167,11 +167,9 @@ android:title="@string/notify_crashes_title" android:summary="@string/notify_crashes_summary"/> - + android:title="@string/sttrace_title" />