diff --git a/Clover/app/src/main/java/org/floens/chan/Chan.java b/Clover/app/src/main/java/org/floens/chan/Chan.java index 5d0c3c95..2a9aee84 100644 --- a/Clover/app/src/main/java/org/floens/chan/Chan.java +++ b/Clover/app/src/main/java/org/floens/chan/Chan.java @@ -35,6 +35,7 @@ import org.floens.chan.core.http.ReplyManager; import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.manager.WatchManager; import org.floens.chan.core.net.BitmapLruImageCache; +import org.floens.chan.core.net.ProxiedHurlStack; import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.Logger; @@ -150,7 +151,8 @@ public class Chan extends Application { replyManager = new ReplyManager(this); - volleyRequestQueue = Volley.newRequestQueue(this, getUserAgent(), null, new File(cacheDir, Volley.DEFAULT_CACHE_DIR), VOLLEY_CACHE_SIZE); + String userAgent = getUserAgent(); + volleyRequestQueue = Volley.newRequestQueue(this, userAgent, new ProxiedHurlStack(userAgent), new File(cacheDir, Volley.DEFAULT_CACHE_DIR), VOLLEY_CACHE_SIZE); final int runtimeMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); final int lruImageCacheSize = runtimeMemory / 8; diff --git a/Clover/app/src/main/java/org/floens/chan/core/cache/FileCache.java b/Clover/app/src/main/java/org/floens/chan/core/cache/FileCache.java index 2b0af178..6a298ea7 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/cache/FileCache.java +++ b/Clover/app/src/main/java/org/floens/chan/core/cache/FileCache.java @@ -25,6 +25,7 @@ import com.squareup.okhttp.Response; import com.squareup.okhttp.ResponseBody; import com.squareup.okhttp.internal.Util; +import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.Logger; import org.floens.chan.utils.Time; @@ -35,6 +36,8 @@ import java.io.File; import java.io.FileOutputStream; import java.io.InterruptedIOException; import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Proxy; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -419,6 +422,15 @@ public class FileCache { .header("User-Agent", userAgent) .build(); + Proxy proxy = null; + if (ChanSettings.proxyEnabled.get()) + { + proxy = new Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved( + ChanSettings.proxyAddress.get(), + ChanSettings.proxyPort.get())); + } + fileCache.httpClient.setProxy(proxy); + call = fileCache.httpClient.newCall(request); Response response = call.execute(); if (!response.isSuccessful()) { diff --git a/Clover/app/src/main/java/org/floens/chan/core/net/ProxiedHurlStack.java b/Clover/app/src/main/java/org/floens/chan/core/net/ProxiedHurlStack.java new file mode 100644 index 00000000..ec63a07f --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/core/net/ProxiedHurlStack.java @@ -0,0 +1,32 @@ +package org.floens.chan.core.net; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.URL; +import com.android.volley.toolbox.HurlStack; +import org.floens.chan.core.settings.ChanSettings; + +public class ProxiedHurlStack extends HurlStack { + + public ProxiedHurlStack(String userAgent) { + super(userAgent, null); + } + + @Override + protected HttpURLConnection createConnection(URL url) throws IOException { + // Start the connection by specifying a proxy server + if (ChanSettings.proxyEnabled.get()) + { + Proxy proxy = new Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved( + ChanSettings.proxyAddress.get(), + ChanSettings.proxyPort.get())); + return (HttpURLConnection) url.openConnection(proxy); + } + else + { + return (HttpURLConnection) url.openConnection(); + } + } +} \ No newline at end of file diff --git a/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java b/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java index 9f56d646..91f38ca6 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java +++ b/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java @@ -97,6 +97,10 @@ public class ChanSettings { public static final BooleanSetting historyEnabled; + public static final BooleanSetting proxyEnabled; + public static final StringSetting proxyAddress; + public static final IntegerSetting proxyPort; + static { SharedPreferences p = AndroidUtils.getPreferences(); @@ -161,6 +165,10 @@ public class ChanSettings { historyEnabled = new BooleanSetting(p, "preference_history_enabled", true); + proxyEnabled = new BooleanSetting(p, "preference_proxy_enabled", false); + proxyAddress = new StringSetting(p, "preference_proxy_address", ""); + proxyPort = new IntegerSetting(p, "preference_proxy_port", 80); + // Old (but possibly still in some users phone) // preference_board_view_mode default "list" // preference_board_editor_filler default false diff --git a/Clover/app/src/main/java/org/floens/chan/core/settings/IntegerSetting.java b/Clover/app/src/main/java/org/floens/chan/core/settings/IntegerSetting.java new file mode 100644 index 00000000..19839fd7 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/core/settings/IntegerSetting.java @@ -0,0 +1,39 @@ +package org.floens.chan.core.settings; + +import android.content.SharedPreferences; + +/** + * Created by Zetsubou on 02.07.2015. + */ +public class IntegerSetting extends Setting { + private boolean hasCached = false; + private Integer cached; + + public IntegerSetting(SharedPreferences sharedPreferences, String key, Integer def) { + super(sharedPreferences, key, def); + } + + public IntegerSetting(SharedPreferences sharedPreferences, String key, Integer def, SettingCallback callback) { + super(sharedPreferences, key, def, callback); + } + + @Override + public Integer get() { + if (hasCached) { + return cached; + } else { + cached = sharedPreferences.getInt(key, def); + hasCached = true; + return cached; + } + } + + @Override + public void set(Integer value) { + if (!value.equals(get())) { + sharedPreferences.edit().putInt(key, value).apply(); + cached = value; + onValueChanged(); + } + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/AdvancedSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/AdvancedSettingsController.java index 5e81d5b0..d0d5fedf 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/AdvancedSettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/AdvancedSettingsController.java @@ -27,9 +27,11 @@ import org.floens.chan.R; import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.ui.fragment.FolderPickFragment; import org.floens.chan.ui.settings.BooleanSettingView; +import org.floens.chan.ui.settings.IntegerSettingView; import org.floens.chan.ui.settings.LinkSettingView; import org.floens.chan.ui.settings.SettingsController; import org.floens.chan.ui.settings.SettingsGroup; +import org.floens.chan.ui.settings.StringSettingView; import java.io.File; @@ -92,6 +94,12 @@ public class AdvancedSettingsController extends SettingsController { settings.add(new BooleanSettingView(this, ChanSettings.tapNoReply, string(R.string.setting_tap_no_rely), null)); groups.add(settings); + + SettingsGroup proxy = new SettingsGroup(string(R.string.settings_group_proxy)); + proxy.add(new BooleanSettingView(this, ChanSettings.proxyEnabled, string(R.string.setting_proxy_enabled), null)); + proxy.add(new StringSettingView(this, ChanSettings.proxyAddress, string(R.string.setting_proxy_address), string(R.string.setting_proxy_address))); + proxy.add(new IntegerSettingView(this, ChanSettings.proxyPort, string(R.string.setting_proxy_port), string(R.string.setting_proxy_port))); + groups.add(proxy); } private void setSaveLocationDescription() { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/settings/IntegerSettingView.java b/Clover/app/src/main/java/org/floens/chan/ui/settings/IntegerSettingView.java new file mode 100644 index 00000000..007c83c9 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/settings/IntegerSettingView.java @@ -0,0 +1,74 @@ +package org.floens.chan.ui.settings; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.text.InputType; +import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.EditText; +import android.widget.LinearLayout; + +import org.floens.chan.R; +import org.floens.chan.core.settings.Setting; + +import static org.floens.chan.utils.AndroidUtils.dp; + +/** + * Created by Zetsubou on 02.07.2015. + */ +public class IntegerSettingView extends SettingView implements View.OnClickListener { + private final Setting setting; + private final String dialogTitle; + + public IntegerSettingView(SettingsController settingsController, Setting setting, String name, String dialogTitle) { + super(settingsController, name); + this.setting = setting; + this.dialogTitle = dialogTitle; + } + + @Override + public void setView(View view) { + super.setView(view); + view.setOnClickListener(this); + } + + @Override + public String getBottomDescription() { + return setting.get() != null ? setting.get().toString() : null; + } + + @Override + public void onClick(View v) { + LinearLayout container = new LinearLayout(v.getContext()); + container.setPadding(dp(24), dp(8), dp(24), 0); + + final EditText editText = new EditText(v.getContext()); + editText.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN); + editText.setText(setting.get().toString()); + editText.setInputType(InputType.TYPE_CLASS_NUMBER); + editText.setSingleLine(true); + + container.addView(editText, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + + AlertDialog dialog = new AlertDialog.Builder(v.getContext()) + .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface d, int which) { + try { + setting.set(Integer.parseInt(editText.getText().toString())); + } catch (Exception e) { + setting.set(setting.getDefault()); + } + + settingsController.onPreferenceChange(IntegerSettingView.this); + } + }) + .setNegativeButton(R.string.cancel, null) + .setTitle(dialogTitle) + .setView(container) + .create(); + dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + dialog.show(); + } +} \ No newline at end of file diff --git a/Clover/app/src/main/java/org/floens/chan/ui/settings/SettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/settings/SettingsController.java index f8a55926..2d23dc86 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/settings/SettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/settings/SettingsController.java @@ -65,7 +65,10 @@ public class SettingsController extends Controller implements AndroidUtils.OnMea } public void onPreferenceChange(SettingView item) { - if ((item instanceof ListSettingView) || (item instanceof StringSettingView) || (item instanceof LinkSettingView)) { + if ((item instanceof ListSettingView) + || (item instanceof StringSettingView) + || (item instanceof IntegerSettingView) + || (item instanceof LinkSettingView)) { setDescriptionText(item.view, item.getTopDescription(), item.getBottomDescription()); } } @@ -130,7 +133,11 @@ public class SettingsController extends Controller implements AndroidUtils.OnMea String topValue = settingView.getTopDescription(); String bottomValue = settingView.getBottomDescription(); - if ((settingView instanceof ListSettingView) || (settingView instanceof LinkSettingView) || (settingView instanceof StringSettingView)) { + if ((settingView instanceof ListSettingView) + || (settingView instanceof LinkSettingView) + || (settingView instanceof StringSettingView) + || (settingView instanceof IntegerSettingView) ) + { preferenceView = (ViewGroup) inf.inflate(R.layout.setting_link, groupLayout, false); } else if (settingView instanceof BooleanSettingView) { preferenceView = (ViewGroup) inf.inflate(R.layout.setting_boolean, groupLayout, false); diff --git a/Clover/app/src/main/res/values/strings.xml b/Clover/app/src/main/res/values/strings.xml index e1c9c0a0..daf7b57f 100644 --- a/Clover/app/src/main/res/values/strings.xml +++ b/Clover/app/src/main/res/values/strings.xml @@ -310,6 +310,11 @@ If the pattern matches then the post can be hidden or highlighted.<br> Confirm exit Tap the post number to reply + HTTP Proxy + Enable proxy + Proxy server address + Proxy server port + Watcher settings Watcher settings To watch pins for new posts, turn the thread watcher on.