diff --git a/app/src/main/java/at/bitfire/davdroid/App.java b/app/src/main/java/at/bitfire/davdroid/App.java index 3d379065..f7fa1871 100644 --- a/app/src/main/java/at/bitfire/davdroid/App.java +++ b/app/src/main/java/at/bitfire/davdroid/App.java @@ -49,7 +49,13 @@ public class App extends Application { public static final String DISTRUST_SYSTEM_CERTIFICATES = "distrustSystemCerts", - LOG_TO_EXTERNAL_STORAGE = "logToExternalStorage"; + LOG_TO_EXTERNAL_STORAGE = "logToExternalStorage", + OVERRIDE_PROXY = "overrideProxy", + OVERRIDE_PROXY_HOST = "overrideProxyHost", + OVERRIDE_PROXY_PORT = "overrideProxyPort"; + + public static final String OVERRIDE_PROXY_HOST_DEFAULT = "localhost"; + public static final int OVERRIDE_PROXY_PORT_DEFAULT = 8118; @Getter private CustomCertManager certManager; diff --git a/app/src/main/java/at/bitfire/davdroid/HttpClient.java b/app/src/main/java/at/bitfire/davdroid/HttpClient.java index 2c40483e..2da5aa30 100644 --- a/app/src/main/java/at/bitfire/davdroid/HttpClient.java +++ b/app/src/main/java/at/bitfire/davdroid/HttpClient.java @@ -10,11 +10,14 @@ package at.bitfire.davdroid; import android.accounts.Account; import android.content.Context; +import android.database.sqlite.SQLiteOpenHelper; import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -23,6 +26,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import at.bitfire.dav4android.BasicDigestAuthHandler; +import at.bitfire.davdroid.model.ServiceDB; +import at.bitfire.davdroid.model.Settings; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -85,6 +90,28 @@ public class HttpClient { // don't allow redirects, because it would break PROPFIND handling builder.followRedirects(false); + // custom proxy support + if (context != null) { + SQLiteOpenHelper dbHelper = new ServiceDB.OpenHelper(context); + try { + Settings settings = new Settings(dbHelper.getReadableDatabase()); + if (settings.getBoolean(App.OVERRIDE_PROXY, false)) { + InetSocketAddress address = new InetSocketAddress( + settings.getString(App.OVERRIDE_PROXY_HOST, App.OVERRIDE_PROXY_HOST_DEFAULT), + settings.getInt(App.OVERRIDE_PROXY_PORT, App.OVERRIDE_PROXY_PORT_DEFAULT) + ); + + Proxy proxy = new Proxy(Proxy.Type.HTTP, address); + builder.proxy(proxy); + App.log.log(Level.INFO, "Using proxy", proxy); + } + } catch(IllegalArgumentException|NullPointerException e) { + App.log.log(Level.SEVERE, "Can't set proxy, ignoring", e); + } finally { + dbHelper.close(); + } + } + // add User-Agent to every request builder.addNetworkInterceptor(userAgentInterceptor); diff --git a/app/src/main/java/at/bitfire/davdroid/model/Settings.java b/app/src/main/java/at/bitfire/davdroid/model/Settings.java index 3933f477..858a715e 100644 --- a/app/src/main/java/at/bitfire/davdroid/model/Settings.java +++ b/app/src/main/java/at/bitfire/davdroid/model/Settings.java @@ -11,6 +11,7 @@ package at.bitfire.davdroid.model; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.support.annotation.Nullable; import lombok.Cleanup; @@ -22,10 +23,11 @@ public class Settings { this.db = db; } + public boolean getBoolean(String name, boolean defaultValue) { @Cleanup Cursor cursor = db.query(ServiceDB.Settings._TABLE, new String[] { ServiceDB.Settings.VALUE }, ServiceDB.Settings.NAME + "=?", new String[] { name }, null, null, null); - if (cursor.moveToNext()) + if (cursor.moveToNext() && !cursor.isNull(0)) return cursor.getInt(0) != 0; else return defaultValue; @@ -38,6 +40,42 @@ public class Settings { db.insertWithOnConflict(ServiceDB.Settings._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE); } + + public int getInt(String name, int defaultValue) { + @Cleanup Cursor cursor = db.query(ServiceDB.Settings._TABLE, new String[] { ServiceDB.Settings.VALUE }, + ServiceDB.Settings.NAME + "=?", new String[] { name }, null, null, null); + if (cursor.moveToNext() && !cursor.isNull(0)) + return cursor.isNull(0) ? defaultValue : cursor.getInt(0); + else + return defaultValue; + } + + public void putInt(String name, int value) { + ContentValues values = new ContentValues(2); + values.put(ServiceDB.Settings.NAME, name); + values.put(ServiceDB.Settings.VALUE, value); + db.insertWithOnConflict(ServiceDB.Settings._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE); + } + + + @Nullable + public String getString(String name, @Nullable String defaultValue) { + @Cleanup Cursor cursor = db.query(ServiceDB.Settings._TABLE, new String[] { ServiceDB.Settings.VALUE }, + ServiceDB.Settings.NAME + "=?", new String[] { name }, null, null, null); + if (cursor.moveToNext()) + return cursor.getString(0); + else + return defaultValue; + } + + public void putString(String name, @Nullable String value) { + ContentValues values = new ContentValues(2); + values.put(ServiceDB.Settings.NAME, name); + values.put(ServiceDB.Settings.VALUE, value); + db.insertWithOnConflict(ServiceDB.Settings._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE); + } + + public void remove(String name) { db.delete(ServiceDB.Settings._TABLE, ServiceDB.Settings.NAME + "=?", new String[] { name }); } diff --git a/app/src/main/java/at/bitfire/davdroid/ui/AppSettingsActivity.java b/app/src/main/java/at/bitfire/davdroid/ui/AppSettingsActivity.java index 41153c0b..9d93a1f4 100644 --- a/app/src/main/java/at/bitfire/davdroid/ui/AppSettingsActivity.java +++ b/app/src/main/java/at/bitfire/davdroid/ui/AppSettingsActivity.java @@ -12,10 +12,14 @@ import android.content.Intent; import android.os.Bundle; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; +import android.support.v7.preference.EditTextPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceFragmentCompat; import android.support.v7.preference.SwitchPreferenceCompat; +import java.net.URI; +import java.net.URISyntaxException; + import at.bitfire.davdroid.App; import at.bitfire.davdroid.R; import at.bitfire.davdroid.model.ServiceDB; @@ -43,9 +47,14 @@ public class AppSettingsActivity extends AppCompatActivity { prefResetHints, prefResetCertificates; SwitchPreferenceCompat + prefOverrideProxy, prefDistrustSystemCerts, prefLogToExternalStorage; + EditTextPreference + prefProxyHost, + prefProxyPort; + @Override public void onCreate(Bundle savedInstanceState) { dbHelper = new ServiceDB.OpenHelper(getContext()); @@ -66,6 +75,56 @@ public class AppSettingsActivity extends AppCompatActivity { prefResetHints = findPreference("reset_hints"); + prefOverrideProxy = (SwitchPreferenceCompat)findPreference("override_proxy"); + prefOverrideProxy.setChecked(settings.getBoolean(App.OVERRIDE_PROXY, false)); + prefOverrideProxy.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + settings.putBoolean(App.OVERRIDE_PROXY, (boolean)newValue); + return true; + } + }); + + prefProxyHost = (EditTextPreference)findPreference("proxy_host"); + String proxyHost = settings.getString(App.OVERRIDE_PROXY_HOST, App.OVERRIDE_PROXY_HOST_DEFAULT); + prefProxyHost.setText(proxyHost); + prefProxyHost.setSummary(proxyHost); + prefProxyHost.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + String host = (String)newValue; + try { + URI uri = new URI(null, host, null, null); + } catch(URISyntaxException e) { + Snackbar.make(getView(), e.getLocalizedMessage(), Snackbar.LENGTH_LONG).show(); + return false; + } + settings.putString(App.OVERRIDE_PROXY_HOST, host); + prefProxyHost.setSummary(host); + return true; + } + }); + + prefProxyPort = (EditTextPreference)findPreference("proxy_port"); + String proxyPort = settings.getString(App.OVERRIDE_PROXY_PORT, String.valueOf(App.OVERRIDE_PROXY_PORT_DEFAULT)); + prefProxyPort.setText(proxyPort); + prefProxyPort.setSummary(proxyPort); + prefProxyPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + int port; + try { + port = Integer.parseInt((String)newValue); + } catch(NumberFormatException e) { + port = App.OVERRIDE_PROXY_PORT_DEFAULT; + } + settings.putInt(App.OVERRIDE_PROXY_PORT, port); + prefProxyPort.setText(String.valueOf(port)); + prefProxyPort.setSummary(String.valueOf(port)); + return true; + } + }); + prefDistrustSystemCerts = (SwitchPreferenceCompat)findPreference("distrust_system_certs"); prefDistrustSystemCerts.setChecked(settings.getBoolean(App.DISTRUST_SYSTEM_CERTIFICATES, false)); diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c62c4d23..d96b32db 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -56,6 +56,12 @@ Hinweise zurücksetzen Hinweise, die deaktiviert wurden, wieder anzeigen Alle Hinweise werden wieder angezeigt + Verbindung + Proxy-Einstellungen überschreiben + Eigene Proxy-Einstellungen werden verwendet + System-Proxy-Einstellungen werden verwendet + HTTP-Proxy-Rechnername + HTTP-Proxy-Port Sicherheit Systemzertifikaten nicht vertrauen System- und installierten CAs wird nicht vertraut diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2840055a..de206ac4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -72,6 +72,12 @@ Reset hints Re-enables hints which have been dismissed previously All hints will be shown again + Connection + Override proxy settings + Use custom proxy settings + Use system default proxy settings + HTTP proxy host name + HTTP proxy port Security Distrust system certificates System and user-added CAs won\'t be trusted diff --git a/app/src/main/res/xml/settings_app.xml b/app/src/main/res/xml/settings_app.xml index 4aa244a5..35ccea82 100644 --- a/app/src/main/res/xml/settings_app.xml +++ b/app/src/main/res/xml/settings_app.xml @@ -10,30 +10,59 @@ + + + + + + + + + + + + + + + + + @@ -41,6 +70,7 @@ android:targetPackage="at.bitfire.davdroid" android:targetClass="at.bitfire.davdroid.ui.DebugInfoActivity"/> + \ No newline at end of file diff --git a/ical4android b/ical4android index 1e326a6a..439f7277 160000 --- a/ical4android +++ b/ical4android @@ -1 +1 @@ -Subproject commit 1e326a6a729f633504db4410aeb4269199fe999e +Subproject commit 439f727777292f52bd041b4a145c3ae348df1120 diff --git a/vcard4android b/vcard4android index 32e2966b..bc41e36c 160000 --- a/vcard4android +++ b/vcard4android @@ -1 +1 @@ -Subproject commit 32e2966b5af1146f9fd5758c7dc6d19297345005 +Subproject commit bc41e36cc75c25ae49106120572cb9fecaf7430f