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