diff --git a/src/main/jni/iptables b/src/main/jni/iptables
index 67560ab1..177a84bc 160000
--- a/src/main/jni/iptables
+++ b/src/main/jni/iptables
@@ -1 +1 @@
-Subproject commit 67560ab12c1ff3413f971f9f1ba59ff28cb052ce
+Subproject commit 177a84bc6b77c53e1ccc22b97170928d54c1ce92
diff --git a/src/main/jni/shadowsocks-libev b/src/main/jni/shadowsocks-libev
index 772de6fd..890e880d 160000
--- a/src/main/jni/shadowsocks-libev
+++ b/src/main/jni/shadowsocks-libev
@@ -1 +1 @@
-Subproject commit 772de6fdeb15fd7d2b7853b4d3e0372713f16b81
+Subproject commit 890e880dc61ad4f2e9a340a78c797c4aabee6429
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 1441ee7f..9f5f6450 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -4,12 +4,13 @@
Shadowsocks
shadowsocks
-
+
Global Settings
+ Misc
Profile
Switch to another profile
- NAT mode
- Use NAT/VPN mode.
+ NAT mode (deprecated)
+ Use NAT mode instead of VPN mode.
NAT mode is disabled without root.
diff --git a/src/main/res/xml/pref_all.xml b/src/main/res/xml/pref_all.xml
index aac00ed7..c08688de 100644
--- a/src/main/res/xml/pref_all.xml
+++ b/src/main/res/xml/pref_all.xml
@@ -2,12 +2,21 @@
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
-
+ android:summary="@string/flush_dnscache_summary"/>
+
diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala
index 7c8b81f5..26602118 100644
--- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala
+++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala
@@ -43,11 +43,11 @@ import java.util
import java.util.Locale
import android.app.backup.BackupManager
-import android.app.{Activity, AlertDialog, ProgressDialog}
+import android.app.{Activity, ProgressDialog}
import android.content._
import android.content.res.AssetManager
import android.graphics.Typeface
-import android.net.{Uri, VpnService}
+import android.net.VpnService
import android.os._
import android.preference.{Preference, SwitchPreference}
import android.support.design.widget.{FloatingActionButton, Snackbar}
@@ -56,7 +56,6 @@ import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.util.Log
import android.view.{View, ViewGroup, ViewParent}
-import android.webkit.{WebView, WebViewClient}
import android.widget._
import com.github.jorgecastilloprz.FABProgressCircle
import com.github.shadowsocks.aidl.{IShadowsocksService, IShadowsocksServiceCallback}
@@ -97,7 +96,7 @@ object Shadowsocks {
val REQUEST_CONNECT = 1
val PREFS_NAME = "Shadowsocks"
- val PROXY_PREFS = Array(Key.proxy, Key.remotePort, Key.localPort, Key.sitekey, Key.encMethod)
+ val PROXY_PREFS = Array(Key.profileName, Key.proxy, Key.remotePort, Key.localPort, Key.sitekey, Key.encMethod)
val FEATURE_PREFS = Array(Key.route, Key.isGlobalProxy, Key.proxyedApps, Key.isUdpDns, Key.isAuth, Key.isIpv6)
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL,
Executable.TUN2SOCKS)
@@ -141,7 +140,6 @@ object Shadowsocks {
class Shadowsocks
extends AppCompatActivity {
- import Shadowsocks._
// Variables
private var serviceStarted = false
@@ -377,10 +375,6 @@ class Shadowsocks
val title: TextView = field.get(toolbar).asInstanceOf[TextView]
val tf: Typeface = Typefaces.get(this, "fonts/Iceland.ttf")
if (tf != null) title.setTypeface(tf)
- title.setOnClickListener((view: View) => {
- ShadowsocksApplication.track(TAG, "about")
- showAbout()
- })
fab = findViewById(R.id.fab).asInstanceOf[FloatingActionButton]
fabProgressCircle = findViewById(R.id.fabProgressCircle).asInstanceOf[FABProgressCircle]
@@ -496,6 +490,7 @@ class Shadowsocks
}
private def setPreferenceEnabled(enabled: Boolean) {
+ preferences.findPreference(Key.profiles).setEnabled(enabled)
preferences.findPreference(Key.isNAT).setEnabled(enabled)
for (name <- Shadowsocks.PROXY_PREFS) {
val pref = preferences.findPreference(name)
@@ -518,7 +513,6 @@ class Shadowsocks
private def updatePreferenceScreen() {
val profile = currentProfile
- Shadowsocks.updatePreference(preferences.findPreference(Key.profileName), Key.profileName, profile)
for (name <- Shadowsocks.PROXY_PREFS) {
val pref = preferences.findPreference(name)
Shadowsocks.updatePreference(pref, name, profile)
@@ -636,26 +630,6 @@ class Shadowsocks
}
}
- private def showAbout() {
- val web = new WebView(this)
- web.loadUrl("file:///android_asset/pages/about.html")
- web.setWebViewClient(new WebViewClient() {
- override def shouldOverrideUrlLoading(view: WebView, url: String): Boolean = {
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)))
- true
- }
- })
-
- new AlertDialog.Builder(this)
- .setTitle(getString(R.string.about_title).formatLocal(Locale.ENGLISH, ShadowsocksApplication.getVersionName))
- .setCancelable(false)
- .setNegativeButton(getString(android.R.string.ok),
- ((dialog: DialogInterface, id: Int) => dialog.cancel()): DialogInterface.OnClickListener)
- .setView(web)
- .create()
- .show()
- }
-
def clearDialog() {
if (progressDialog != null) {
progressDialog.dismiss()
diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksSettings.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksSettings.scala
index 6869bfa1..e7f9dfd6 100644
--- a/src/main/scala/com/github/shadowsocks/ShadowsocksSettings.scala
+++ b/src/main/scala/com/github/shadowsocks/ShadowsocksSettings.scala
@@ -1,7 +1,13 @@
package com.github.shadowsocks
+import java.util.Locale
+
+import android.app.AlertDialog
+import android.content.{DialogInterface, Intent}
+import android.net.Uri
import android.os.Bundle
import android.preference.{Preference, PreferenceFragment}
+import android.webkit.{WebViewClient, WebView}
import com.github.shadowsocks.utils.Key
// TODO: Move related logic here
@@ -11,20 +17,45 @@ class ShadowsocksSettings extends PreferenceFragment {
override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
addPreferencesFromResource(R.xml.pref_all)
+
findPreference(Key.isNAT).setOnPreferenceChangeListener((preference: Preference, newValue: Any) =>
if (ShadowsocksApplication.isRoot) activity.handler.post(() => {
activity.deattachService()
activity.attachService()
}) else false)
+
findPreference("recovery").setOnPreferenceClickListener((preference: Preference) => {
ShadowsocksApplication.track(Shadowsocks.TAG, "reset")
activity.recovery()
true
})
+
findPreference("flush_dnscache").setOnPreferenceClickListener((preference: Preference) => {
ShadowsocksApplication.track(Shadowsocks.TAG, "flush_dnscache")
activity.flushDnsCache()
true
})
+
+ findPreference("about").setOnPreferenceClickListener((preference: Preference) => {
+ ShadowsocksApplication.track(Shadowsocks.TAG, "about")
+ val web = new WebView(activity)
+ web.loadUrl("file:///android_asset/pages/about.html")
+ web.setWebViewClient(new WebViewClient() {
+ override def shouldOverrideUrlLoading(view: WebView, url: String): Boolean = {
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)))
+ true
+ }
+ })
+
+ new AlertDialog.Builder(activity)
+ .setTitle(getString(R.string.about_title).formatLocal(Locale.ENGLISH, ShadowsocksApplication.getVersionName))
+ .setCancelable(false)
+ .setNegativeButton(getString(android.R.string.ok),
+ ((dialog: DialogInterface, id: Int) => dialog.cancel()): DialogInterface.OnClickListener)
+ .setView(web)
+ .create()
+ .show()
+ true
+ })
}
}
diff --git a/src/main/scala/com/github/shadowsocks/utils/Constants.scala b/src/main/scala/com/github/shadowsocks/utils/Constants.scala
index 1b1f621e..a2c6a860 100644
--- a/src/main/scala/com/github/shadowsocks/utils/Constants.scala
+++ b/src/main/scala/com/github/shadowsocks/utils/Constants.scala
@@ -65,6 +65,7 @@ object Key {
val proxied = "Proxyed"
+ val profiles = "profiles"
val isNAT = "isNAT"
val proxyedApps = "proxyedApps"
val route = "route"