From 030ef4ee7b61e5237b975325f6f45df59fa19151 Mon Sep 17 00:00:00 2001 From: Catfriend1 Date: Sun, 29 Apr 2018 17:49:59 +0200 Subject: [PATCH] Add proxy settings to settings UI (fixes #766) --- .../activities/SettingsActivity.java | 85 ++++++++++++++++++- .../syncthingandroid/service/Constants.java | 2 + .../service/SyncthingRunnable.java | 11 +++ app/src/main/res/values/strings.xml | 21 ++++- app/src/main/res/xml/app_settings.xml | 12 +++ 5 files changed, 127 insertions(+), 4 deletions(-) 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 a3ce75ff..fab8603d 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java @@ -13,6 +13,7 @@ import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; import android.preference.PreferenceScreen; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -107,7 +108,11 @@ public class SettingsActivity extends SyncthingActivity { private Preference mCategoryBackup; + /* Experimental options */ private CheckBoxPreference mUseRoot; + private CheckBoxPreference mUseTor; + private EditTextPreference mSocksProxyAddress; + private EditTextPreference mHttpProxyAddress; private Preference mSyncthingVersion; @@ -191,8 +196,10 @@ public class SettingsActivity extends SyncthingActivity { Preference stResetDeltas = findPreference("st_reset_deltas"); mUseRoot = (CheckBoxPreference) findPreference(Constants.PREF_USE_ROOT); - Preference useWakelock = findPreference(Constants.PREF_USE_WAKE_LOCK); - Preference useTor = findPreference(Constants.PREF_USE_TOR); + Preference useWakelock = (CheckBoxPreference) findPreference(Constants.PREF_USE_WAKE_LOCK); + mUseTor = (CheckBoxPreference) findPreference(Constants.PREF_USE_TOR); + mSocksProxyAddress = (EditTextPreference) findPreference(Constants.PREF_SOCKS_PROXY_ADDRESS); + mHttpProxyAddress = (EditTextPreference) findPreference(Constants.PREF_HTTP_PROXY_ADDRESS); mSyncthingVersion = findPreference("syncthing_version"); Preference appVersion = screen.findPreference("app_version"); @@ -211,9 +218,20 @@ public class SettingsActivity extends SyncthingActivity { stResetDatabase.setOnPreferenceClickListener(this); stResetDeltas.setOnPreferenceClickListener(this); + /* Experimental options */ mUseRoot.setOnPreferenceClickListener(this); useWakelock.setOnPreferenceChangeListener((p, o) -> requireRestart()); - useTor.setOnPreferenceChangeListener((p, o) -> requireRestart()); + mUseTor.setOnPreferenceChangeListener(this); + + mSocksProxyAddress.setEnabled(!(Boolean) mUseTor.isChecked()); + mSocksProxyAddress.setOnPreferenceChangeListener(this); + mHttpProxyAddress.setEnabled(!(Boolean) mUseTor.isChecked()); + mHttpProxyAddress.setOnPreferenceChangeListener(this); + + /* Initialize summaries */ + mPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); + handleSocksProxyPreferenceChange(screen.findPreference(Constants.PREF_SOCKS_PROXY_ADDRESS), mPreferences.getString(Constants.PREF_SOCKS_PROXY_ADDRESS, "")); + handleHttpProxyPreferenceChange(screen.findPreference(Constants.PREF_HTTP_PROXY_ADDRESS), mPreferences.getString(Constants.PREF_HTTP_PROXY_ADDRESS, "")); try { appVersion.setSummary(getActivity().getPackageManager() @@ -392,6 +410,29 @@ public class SettingsActivity extends SyncthingActivity { return false; } break; + case Constants.PREF_USE_TOR: + mSocksProxyAddress.setEnabled(!(Boolean) o); + mHttpProxyAddress.setEnabled(!(Boolean) o); + requireRestart(); + break; + case Constants.PREF_SOCKS_PROXY_ADDRESS: + if (o.toString().trim().equals(mPreferences.getString(Constants.PREF_SOCKS_PROXY_ADDRESS, ""))) + return false; + if (handleSocksProxyPreferenceChange(preference, o.toString().trim())) { + requireRestart(); + } else { + return false; + } + break; + case Constants.PREF_HTTP_PROXY_ADDRESS: + if (o.toString().trim().equals(mPreferences.getString(Constants.PREF_HTTP_PROXY_ADDRESS, ""))) + return false; + if (handleHttpProxyPreferenceChange(preference, o.toString().trim())) { + requireRestart(); + } else { + return false; + } + break; } return true; @@ -512,5 +553,43 @@ public class SettingsActivity extends SyncthingActivity { } } } + + /** + * Handles a new user input for the SOCKS proxy preference. + * Returns if the changed setting requires a restart. + */ + private boolean handleSocksProxyPreferenceChange(Preference preference, String newValue) { + // Valid input is either a proxy address or an empty field to disable the proxy. + if (newValue.equals("")) { + preference.setSummary(getString(R.string.do_not_use_proxy) + " " + getString(R.string.generic_example) + ": " + getString(R.string.socks_proxy_address_example)); + return true; + } else if (newValue.matches("^socks5://.*:\\d{1,5}$")) { + preference.setSummary(getString(R.string.use_proxy) + " " + newValue); + return true; + } else { + Toast.makeText(getActivity(), R.string.toast_invalid_socks_proxy_address, Toast.LENGTH_SHORT) + .show(); + return false; + } + } + + /** + * Handles a new user input for the HTTP(S) proxy preference. + * Returns if the changed setting requires a restart. + */ + private boolean handleHttpProxyPreferenceChange(Preference preference, String newValue) { + // Valid input is either a proxy address or an empty field to disable the proxy. + if (newValue.equals("")) { + preference.setSummary(getString(R.string.do_not_use_proxy) + " " + getString(R.string.generic_example) + ": " + getString(R.string.http_proxy_address_example)); + return true; + } else if (newValue.matches("^http://.*:\\d{1,5}$")) { + preference.setSummary(getString(R.string.use_proxy) + " " + newValue); + return true; + } else { + Toast.makeText(getActivity(), R.string.toast_invalid_http_proxy_address, Toast.LENGTH_SHORT) + .show(); + return false; + } + } } } diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/Constants.java b/app/src/main/java/com/nutomic/syncthingandroid/service/Constants.java index a2ead0f3..d70db660 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/Constants.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/Constants.java @@ -17,6 +17,8 @@ public class Constants { public static final String PREF_NOTIFICATION_TYPE = "notification_type"; public static final String PREF_USE_WAKE_LOCK = "wakelock_while_binary_running"; public static final String PREF_USE_TOR = "use_tor"; + public static final String PREF_SOCKS_PROXY_ADDRESS = "socks_proxy_address"; + public static final String PREF_HTTP_PROXY_ADDRESS = "http_proxy_address"; /** * On Android 8.1, ACCESS_COARSE_LOCATION is required to access WiFi SSID. 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 0becf4cc..54b810da 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java @@ -376,6 +376,17 @@ public class SyncthingRunnable implements Runnable { if (mPreferences.getBoolean(Constants.PREF_USE_TOR, false)) { targetEnv.put("all_proxy", "socks5://localhost:9050"); targetEnv.put("ALL_PROXY_NO_FALLBACK", "1"); + } else { + String socksProxyAddress = mPreferences.getString(Constants.PREF_SOCKS_PROXY_ADDRESS, ""); + if (!socksProxyAddress.equals("")) { + targetEnv.put("all_proxy", socksProxyAddress); + } + + String httpProxyAddress = mPreferences.getString(Constants.PREF_HTTP_PROXY_ADDRESS, ""); + if (!httpProxyAddress.equals("")) { + targetEnv.put("http_proxy", httpProxyAddress); + targetEnv.put("https_proxy", httpProxyAddress); + } } if (mPreferences.getBoolean("use_legacy_hashing", false)) targetEnv.put("STHASHING", "standard"); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 12e3d25d..56506770 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -18,6 +18,9 @@ Please report any problems you encounter via Github. Continue + + Example + @@ -337,13 +340,29 @@ Please report any problems you encounter via Github. Export Configuration + + Connect through a proxy + Do not connect through a proxy + Keep the CPU awake while Syncthing is running Use this setting if you experience unexpected disconnects while operating on battery. This will result in increased battery consumption. Use Tor - Force all traffic through Tor for increased privacy. Requires Orbot + Force all traffic through Tor for increased privacy. Requires Orbot. Disables proxy options. + + SOCKS5 proxy + socks5://192.168.0.1:1080 + + + Input violates proxy syntax \'socks5://[IP/HOSTNAME]:[PORT]\' + + HTTP(S) proxy + http://192.168.0.1:8080 + + + Input violates proxy syntax \'http://[IP/HOSTNAME]:[PORT]\' Use legacy hashing diff --git a/app/src/main/res/xml/app_settings.xml b/app/src/main/res/xml/app_settings.xml index 4a870995..b736ee54 100644 --- a/app/src/main/res/xml/app_settings.xml +++ b/app/src/main/res/xml/app_settings.xml @@ -212,6 +212,18 @@ android:title="@string/use_tor_title" android:summary="@string/use_tor_summary" /> + + + +