summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java323
1 files changed, 323 insertions, 0 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
new file mode 100644
index 000000000..d745bb51c
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/ProxyDialog.java
@@ -0,0 +1,323 @@
+package de.danoeh.antennapod.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.v4.content.ContextCompat;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.Patterns;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import com.afollestad.materialdialogs.DialogAction;
+import com.afollestad.materialdialogs.MaterialDialog;
+import com.afollestad.materialdialogs.internal.MDButton;
+import com.squareup.okhttp.Credentials;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.SocketAddress;
+import java.util.concurrent.TimeUnit;
+
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
+import de.danoeh.antennapod.core.service.download.ProxyConfig;
+import rx.Observable;
+import rx.Subscriber;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.schedulers.Schedulers;
+
+public class ProxyDialog {
+
+ private static final String TAG = "ProxyDialog";
+
+ private Context context;
+
+ private MaterialDialog dialog;
+
+ private Spinner spType;
+ private EditText etHost;
+ private EditText etPort;
+ private EditText etUsername;
+ private EditText etPassword;
+
+ private boolean testSuccessful = false;
+ private TextView txtvMessage;
+ private Subscription subscription;
+
+ public ProxyDialog(Context context) {
+ this.context = context;
+ }
+
+ public Dialog createDialog() {
+ dialog = new MaterialDialog.Builder(context)
+ .title(R.string.pref_proxy_title)
+ .customView(R.layout.proxy_settings, true)
+ .positiveText(R.string.proxy_test_label)
+ .negativeText(R.string.cancel_label)
+ .onPositive((dialog1, which) -> {
+ if(!testSuccessful) {
+ dialog.getActionButton(DialogAction.POSITIVE).setEnabled(false);
+ test();
+ return;
+ }
+ String type = (String) ((Spinner) dialog1.findViewById(R.id.spType)).getSelectedItem();
+ ProxyConfig proxy;
+ if(Proxy.Type.valueOf(type) == Proxy.Type.DIRECT) {
+ proxy = ProxyConfig.direct();
+ } else {
+ String host = etHost.getText().toString();
+ String port = etPort.getText().toString();
+ String username = etUsername.getText().toString();
+ if(TextUtils.isEmpty(username)) {
+ username = null;
+ }
+ String password = etPassword.getText().toString();
+ if(TextUtils.isEmpty(password)) {
+ password = null;
+ }
+ int portValue = 0;
+ if(!TextUtils.isEmpty(port)) {
+ portValue = Integer.valueOf(port);
+ }
+ proxy = ProxyConfig.http(host, portValue, username, password);
+ }
+ UserPreferences.setProxyConfig(proxy);
+ AntennapodHttpClient.reinit();
+ dialog.dismiss();
+ })
+ .onNegative((dialog1, which) -> {
+ dialog1.dismiss();
+ })
+ .autoDismiss(false)
+ .build();
+ View view = dialog.getCustomView();
+ spType = (Spinner) view.findViewById(R.id.spType);
+ String[] types = { Proxy.Type.DIRECT.name(), Proxy.Type.HTTP.name() };
+ ArrayAdapter<String> adapter = new ArrayAdapter<>(context,
+ android.R.layout.simple_spinner_item, types);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spType.setAdapter(adapter);
+ ProxyConfig proxyConfig = UserPreferences.getProxyConfig();
+ spType.setSelection(adapter.getPosition(proxyConfig.type.name()));
+ etHost = (EditText) view.findViewById(R.id.etHost);
+ if(!TextUtils.isEmpty(proxyConfig.host)) {
+ etHost.setText(proxyConfig.host);
+ }
+ etHost.addTextChangedListener(requireTestOnChange);
+ etPort = (EditText) view.findViewById(R.id.etPort);
+ if(proxyConfig.port > 0) {
+ etPort.setText(String.valueOf(proxyConfig.port));
+ }
+ etPort.addTextChangedListener(requireTestOnChange);
+ etUsername = (EditText) view.findViewById(R.id.etUsername);
+ if(!TextUtils.isEmpty(proxyConfig.username)) {
+ etUsername.setText(proxyConfig.username);
+ }
+ etUsername.addTextChangedListener(requireTestOnChange);
+ etPassword = (EditText) view.findViewById(R.id.etPassword);
+ if(!TextUtils.isEmpty(proxyConfig.password)) {
+ etPassword.setText(proxyConfig.username);
+ }
+ etPassword.addTextChangedListener(requireTestOnChange);
+ if(proxyConfig.type == Proxy.Type.DIRECT) {
+ enableSettings(false);
+ setTestRequired(false);
+ }
+ spType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ enableSettings(position > 0);
+ setTestRequired(position > 0);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ enableSettings(false);
+ }
+ });
+ txtvMessage = (TextView) view.findViewById(R.id.txtvMessage);
+ checkValidity();
+ return dialog;
+ }
+
+ private final TextWatcher requireTestOnChange = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ setTestRequired(true);
+ }
+ };
+
+ private void enableSettings(boolean enable) {
+ etHost.setEnabled(enable);
+ etPort.setEnabled(enable);
+ etUsername.setEnabled(enable);
+ etPassword.setEnabled(enable);
+ }
+
+ private boolean checkValidity() {
+ boolean valid = true;
+ if(spType.getSelectedItemPosition() > 0) {
+ valid &= checkHost();
+ }
+ valid &= checkPort();
+ return valid;
+ }
+
+ private boolean checkHost() {
+ String host = etHost.getText().toString();
+ if(host.length() == 0) {
+ etHost.setError(context.getString(R.string.proxy_host_empty_error));
+ return false;
+ }
+ if(!"localhost".equals(host) && !Patterns.DOMAIN_NAME.matcher(host).matches()) {
+ etHost.setError(context.getString(R.string.proxy_host_invalid_error));
+ return false;
+ }
+ return true;
+ }
+
+ private boolean checkPort() {
+ int port = getPort();
+ if(port < 0 && port > 65535) {
+ etPort.setError(context.getString(R.string.proxy_port_invalid_error));
+ return false;
+ }
+ return true;
+ }
+
+ private int getPort() {
+ String port = etPort.getText().toString();
+ if(port.length() > 0) {
+ try {
+ int portValue = Integer.parseInt(port);
+ return portValue;
+ } catch(NumberFormatException e) {
+ // ignore
+ }
+ }
+ return 0;
+ }
+
+ private void setTestRequired(boolean required) {
+ if(required) {
+ testSuccessful = false;
+ MDButton button = dialog.getActionButton(DialogAction.POSITIVE);
+ button.setText(context.getText(R.string.proxy_test_label));
+ button.setEnabled(true);
+ } else {
+ testSuccessful = true;
+ MDButton button = dialog.getActionButton(DialogAction.POSITIVE);
+ button.setText(context.getText(android.R.string.ok));
+ button.setEnabled(true);
+ }
+ }
+
+ private void test() {
+ if(subscription != null) {
+ subscription.unsubscribe();
+ }
+ if(!checkValidity()) {
+ setTestRequired(true);
+ return;
+ }
+ TypedArray res = context.getTheme().obtainStyledAttributes(new int[] { android.R.attr.textColorPrimary });
+ int textColorPrimary = res.getColor(0, 0);
+ res.recycle();
+ String checking = context.getString(R.string.proxy_checking);
+ txtvMessage.setTextColor(textColorPrimary);
+ txtvMessage.setText("{fa-circle-o-notch spin} " + checking);
+ txtvMessage.setVisibility(View.VISIBLE);
+ subscription = Observable.create(new Observable.OnSubscribe<Response>() {
+ @Override
+ public void call(Subscriber<? super Response> subscriber) {
+ String type = (String) spType.getSelectedItem();
+ String host = etHost.getText().toString();
+ String port = etPort.getText().toString();
+ String username = etUsername.getText().toString();
+ String password = etPassword.getText().toString();
+ int portValue = 8080;
+ if(!TextUtils.isEmpty(port)) {
+ portValue = Integer.valueOf(port);
+ }
+ SocketAddress address = InetSocketAddress.createUnresolved(host, portValue);
+ Proxy.Type proxyType = Proxy.Type.valueOf(type.toUpperCase());
+ Proxy proxy = new Proxy(proxyType, address);
+ OkHttpClient client = AntennapodHttpClient.newHttpClient();
+ client.setConnectTimeout(10, TimeUnit.SECONDS);
+ client.setProxy(proxy);
+ client.interceptors().clear();
+ if(!TextUtils.isEmpty(username)) {
+ String credentials = Credentials.basic(username, password);
+ client.interceptors().add(chain -> {
+ Request request = chain.request().newBuilder()
+ .header("Proxy-Authorization", credentials).build();
+ return chain.proceed(request);
+ });
+ }
+ Request request = new Request.Builder()
+ .url("http://www.google.com")
+ .head()
+ .build();
+ try {
+ Response response = client.newCall(request).execute();
+ subscriber.onNext(response);
+ } catch(IOException e) {
+ subscriber.onError(e);
+ }
+ subscriber.onCompleted();
+ }
+ })
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ response -> {
+ int colorId;
+ String icon;
+ String result;
+ if(response.isSuccessful()) {
+ colorId = R.color.download_success_green;
+ icon = "{fa-check}";
+ result = context.getString(R.string.proxy_test_successful);
+ } else {
+ colorId = R.color.download_failed_red;
+ icon = "{fa-close}";
+ result = context.getString(R.string.proxy_test_failed);
+ }
+ int color = ContextCompat.getColor(context, colorId);
+ txtvMessage.setTextColor(color);
+ String message = String.format("%s %s: %s", icon, result, response.message());
+ txtvMessage.setText(message);
+ setTestRequired(!response.isSuccessful());
+ },
+ error -> {
+ String icon = "{fa-close}";
+ String result = context.getString(R.string.proxy_test_failed);
+ int color = ContextCompat.getColor(context, R.color.download_failed_red);
+ txtvMessage.setTextColor(color);
+ String message = String.format("%s %s: %s", icon, result, error.getMessage());
+ txtvMessage.setText(message);
+ setTestRequired(true);
+ }
+ );
+ }
+
+}