Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ec8117e1c | ||
|
|
3c68a26794 | ||
|
|
fda89933d0 | ||
|
|
d8f721db3b | ||
|
|
28339ce7c1 | ||
|
|
edda3179dd | ||
|
|
1d79990656 | ||
|
|
2a47362195 | ||
|
|
02d5951f8b | ||
|
|
b126c62365 | ||
|
|
bbaf1779ea | ||
|
|
65ddd6f5d8 |
@@ -31,8 +31,8 @@ resolvers += Resolver.jcenterRepo
|
|||||||
useSupportVectors
|
useSupportVectors
|
||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"com.android.support" % "design" % "24.2.0",
|
"com.android.support" % "design" % "24.2.1",
|
||||||
"com.android.support" % "gridlayout-v7" % "24.2.0",
|
"com.android.support" % "gridlayout-v7" % "24.2.1",
|
||||||
"com.github.clans" % "fab" % "1.6.4",
|
"com.github.clans" % "fab" % "1.6.4",
|
||||||
"com.github.jorgecastilloprz" % "fabprogresscircle" % "1.01",
|
"com.github.jorgecastilloprz" % "fabprogresscircle" % "1.01",
|
||||||
"com.github.kevinsawicki" % "http-request" % "6.0",
|
"com.github.kevinsawicki" % "http-request" % "6.0",
|
||||||
@@ -41,7 +41,7 @@ libraryDependencies ++= Seq(
|
|||||||
"com.j256.ormlite" % "ormlite-android" % "5.0",
|
"com.j256.ormlite" % "ormlite-android" % "5.0",
|
||||||
"com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2",
|
"com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2",
|
||||||
"dnsjava" % "dnsjava" % "2.1.7",
|
"dnsjava" % "dnsjava" % "2.1.7",
|
||||||
"eu.chainfire" % "libsuperuser" % "1.0.0.201607041850",
|
"eu.chainfire" % "libsuperuser" % "1.0.0.201608240809",
|
||||||
"me.dm7.barcodescanner" % "zxing" % "1.9",
|
"me.dm7.barcodescanner" % "zxing" % "1.9",
|
||||||
"net.glxn.qrgen" % "android" % "2.0"
|
"net.glxn.qrgen" % "android" % "2.0"
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
addSbtPlugin("org.scala-android" % "sbt-android" % "1.6.17")
|
addSbtPlugin("org.scala-android" % "sbt-android" % "1.6.18")
|
||||||
|
|
||||||
addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.1.10")
|
addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.1.10")
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" package="com.github.shadowsocks"
|
xmlns:tools="http://schemas.android.com/tools" package="com.github.shadowsocks"
|
||||||
android:versionCode="155"
|
android:versionCode="157"
|
||||||
android:versionName="3.1.3">
|
android:versionName="3.1.5">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.github.shadowsocks.aidl.IShadowsocksServiceCallback;
|
|||||||
|
|
||||||
interface IShadowsocksService {
|
interface IShadowsocksService {
|
||||||
int getState();
|
int getState();
|
||||||
|
String getProfileName();
|
||||||
|
|
||||||
oneway void registerCallback(IShadowsocksServiceCallback cb);
|
oneway void registerCallback(IShadowsocksServiceCallback cb);
|
||||||
oneway void unregisterCallback(IShadowsocksServiceCallback cb);
|
oneway void unregisterCallback(IShadowsocksServiceCallback cb);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.github.shadowsocks.aidl;
|
package com.github.shadowsocks.aidl;
|
||||||
|
|
||||||
interface IShadowsocksServiceCallback {
|
interface IShadowsocksServiceCallback {
|
||||||
oneway void stateChanged(int state, String msg);
|
oneway void stateChanged(int state, String profileName, String msg);
|
||||||
oneway void trafficUpdated(long txRate, long rxRate, long txTotal, long rxTotal);
|
oneway void trafficUpdated(long txRate, long rxRate, long txTotal, long rxTotal);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,7 +371,9 @@ PDNSD_SOURCES := $(wildcard $(LOCAL_PATH)/pdnsd/src/*.c)
|
|||||||
LOCAL_MODULE := pdnsd
|
LOCAL_MODULE := pdnsd
|
||||||
LOCAL_SRC_FILES := $(PDNSD_SOURCES:$(LOCAL_PATH)/%=%)
|
LOCAL_SRC_FILES := $(PDNSD_SOURCES:$(LOCAL_PATH)/%=%)
|
||||||
LOCAL_CFLAGS := -DANDROID -Wall -O2 -I$(LOCAL_PATH)/pdnsd \
|
LOCAL_CFLAGS := -DANDROID -Wall -O2 -I$(LOCAL_PATH)/pdnsd \
|
||||||
-I$(LOCAL_PATH)/include/pdnsd
|
-I$(LOCAL_PATH)/include/pdnsd -I$(LOCAL_PATH)/libancillary
|
||||||
|
LOCAL_STATIC_LIBRARIES := libancillary
|
||||||
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
|
|||||||
+1
-1
Submodule src/main/jni/pdnsd updated: 7a76962795...698275907b
Submodule src/main/jni/shadowsocks-libev updated: 6e48d25eab...2868e7e7b2
@@ -46,6 +46,13 @@
|
|||||||
<string name="auto_set_gfwlist">CHN Маршрут</string>
|
<string name="auto_set_gfwlist">CHN Маршрут</string>
|
||||||
<string name="auto_set_gfwlist_summary">Игнорировать все сайты находящиеся в Китае</string>
|
<string name="auto_set_gfwlist_summary">Игнорировать все сайты находящиеся в Китае</string>
|
||||||
<string name="route_list">Маршрут</string>
|
<string name="route_list">Маршрут</string>
|
||||||
|
<string-array name="route_entry">
|
||||||
|
<item>Все</item>
|
||||||
|
<item>Обход LAN</item>
|
||||||
|
<item>Обходной Китай</item>
|
||||||
|
<item>Обход LAN и Китай</item>
|
||||||
|
<item>Список GFW</item>
|
||||||
|
</string-array>
|
||||||
<string name="proxied_apps">Прокси для выбранных приложений</string>
|
<string name="proxied_apps">Прокси для выбранных приложений</string>
|
||||||
<string name="proxied_apps_summary">Установить прокси для выбранных приложений, требует режим NAT под Android 4.x</string>
|
<string name="proxied_apps_summary">Установить прокси для выбранных приложений, требует режим NAT под Android 4.x</string>
|
||||||
<string name="on">Вкл</string>
|
<string name="on">Вкл</string>
|
||||||
|
|||||||
@@ -110,7 +110,8 @@
|
|||||||
<item>绕过局域网地址</item>
|
<item>绕过局域网地址</item>
|
||||||
<item>绕过中国大陆地址</item>
|
<item>绕过中国大陆地址</item>
|
||||||
<item>绕过局域网及中国大陆地址</item>
|
<item>绕过局域网及中国大陆地址</item>
|
||||||
<item>仅代理国内无法访问的地址</item>
|
<item>仅代理中国大陆无法访问的地址</item>
|
||||||
|
<item>仅代理中国大陆地址</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string name="action_apply_all">应用设置到所有配置文件</string>
|
<string name="action_apply_all">应用设置到所有配置文件</string>
|
||||||
|
|||||||
@@ -113,6 +113,7 @@
|
|||||||
<item>略過中國大陸位址</item>
|
<item>略過中國大陸位址</item>
|
||||||
<item>略過區域網路及中國大陸位址</item>
|
<item>略過區域網路及中國大陸位址</item>
|
||||||
<item>僅代理大陸屏蔽位址</item>
|
<item>僅代理大陸屏蔽位址</item>
|
||||||
|
<item>僅代理大陸位址</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string name="action_apply_all">應用設置到所有配置文件</string>
|
<string name="action_apply_all">應用設置到所有配置文件</string>
|
||||||
|
|||||||
@@ -38,20 +38,13 @@
|
|||||||
<item>chacha20-ietf</item>
|
<item>chacha20-ietf</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="route_entry">
|
|
||||||
<item>All</item>
|
|
||||||
<item>Bypass LAN</item>
|
|
||||||
<item>Bypass China</item>
|
|
||||||
<item>Bypass LAN & China</item>
|
|
||||||
<item>GFW List</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="route_value">
|
<string-array name="route_value">
|
||||||
<item>all</item>
|
<item>all</item>
|
||||||
<item>bypass-lan</item>
|
<item>bypass-lan</item>
|
||||||
<item>bypass-china</item>
|
<item>bypass-china</item>
|
||||||
<item>bypass-lan-china</item>
|
<item>bypass-lan-china</item>
|
||||||
<item>gfwlist</item>
|
<item>gfwlist</item>
|
||||||
|
<item>china-list</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="private_route">
|
<string-array name="private_route">
|
||||||
|
|||||||
@@ -52,6 +52,14 @@
|
|||||||
<string name="auto_set_gfwlist_summary">Bypass all sites located in China
|
<string name="auto_set_gfwlist_summary">Bypass all sites located in China
|
||||||
</string>
|
</string>
|
||||||
<string name="route_list">Route</string>
|
<string name="route_list">Route</string>
|
||||||
|
<string-array name="route_entry">
|
||||||
|
<item>All</item>
|
||||||
|
<item>Bypass LAN</item>
|
||||||
|
<item>Bypass China</item>
|
||||||
|
<item>Bypass LAN & China</item>
|
||||||
|
<item>GFW List</item>
|
||||||
|
<item>China List</item>
|
||||||
|
</string-array>
|
||||||
<string name="proxied_apps">Per-App Proxy</string>
|
<string name="proxied_apps">Per-App Proxy</string>
|
||||||
<string name="proxied_apps_summary">Set proxy for selected apps, requires NAT mode under Android 4.x</string>
|
<string name="proxied_apps_summary">Set proxy for selected apps, requires NAT mode under Android 4.x</string>
|
||||||
<string name="on">On</string>
|
<string name="on">On</string>
|
||||||
|
|||||||
@@ -46,14 +46,13 @@ import android.content._
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.{Bundle, Handler}
|
import android.os.{Bundle, Handler}
|
||||||
import android.preference.PreferenceManager
|
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.widget.Toolbar.OnMenuItemClickListener
|
import android.support.v7.widget.Toolbar.OnMenuItemClickListener
|
||||||
import android.support.v7.widget.{DefaultItemAnimator, LinearLayoutManager, RecyclerView, Toolbar}
|
import android.support.v7.widget.{DefaultItemAnimator, LinearLayoutManager, RecyclerView, Toolbar}
|
||||||
import android.view._
|
import android.view._
|
||||||
import android.widget._
|
import android.widget._
|
||||||
import com.github.shadowsocks.utils.{Key, Utils}
|
|
||||||
import com.github.shadowsocks.ShadowsocksApplication.app
|
import com.github.shadowsocks.ShadowsocksApplication.app
|
||||||
|
import com.github.shadowsocks.utils.{Key, Utils}
|
||||||
|
|
||||||
import scala.collection.JavaConversions._
|
import scala.collection.JavaConversions._
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
@@ -143,7 +142,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
|
|||||||
private var loadingView: View = _
|
private var loadingView: View = _
|
||||||
private val appsLoading = new AtomicBoolean
|
private val appsLoading = new AtomicBoolean
|
||||||
private var handler: Handler = _
|
private var handler: Handler = _
|
||||||
private val profile = app.currentProfile.get
|
private val profile = app.currentProfile.orNull
|
||||||
|
|
||||||
private def initProxiedApps(str: String = profile.individual) = proxiedApps = str.split('\n').to[mutable.HashSet]
|
private def initProxiedApps(str: String = profile.individual) = proxiedApps = str.split('\n').to[mutable.HashSet]
|
||||||
|
|
||||||
@@ -213,6 +212,8 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
|
|||||||
protected override def onCreate(savedInstanceState: Bundle) {
|
protected override def onCreate(savedInstanceState: Bundle) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
if (profile == null) finish()
|
||||||
|
|
||||||
handler = new Handler()
|
handler = new Handler()
|
||||||
|
|
||||||
this.setContentView(R.layout.layout_apps)
|
this.setContentView(R.layout.layout_apps)
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ trait BaseService extends Service {
|
|||||||
state
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def getProfileName: String = if (profile == null) null else profile.name
|
||||||
|
|
||||||
override def unregisterCallback(cb: IShadowsocksServiceCallback) {
|
override def unregisterCallback(cb: IShadowsocksServiceCallback) {
|
||||||
if (cb != null && callbacks.unregister(cb)) {
|
if (cb != null && callbacks.unregister(cb)) {
|
||||||
callbacksCount -= 1
|
callbacksCount -= 1
|
||||||
@@ -282,7 +284,7 @@ trait BaseService extends Service {
|
|||||||
val n = callbacks.beginBroadcast()
|
val n = callbacks.beginBroadcast()
|
||||||
for (i <- 0 until n) {
|
for (i <- 0 until n) {
|
||||||
try {
|
try {
|
||||||
callbacks.getBroadcastItem(i).stateChanged(s, msg)
|
callbacks.getBroadcastItem(i).stateChanged(s, binder.getProfileName, msg)
|
||||||
} catch {
|
} catch {
|
||||||
case _: Exception => // Ignore
|
case _: Exception => // Ignore
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
|
|||||||
}).attachToRecyclerView(profilesList)
|
}).attachToRecyclerView(profilesList)
|
||||||
|
|
||||||
attachService(new IShadowsocksServiceCallback.Stub {
|
attachService(new IShadowsocksServiceCallback.Stub {
|
||||||
def stateChanged(state: Int, msg: String) = () // ignore
|
def stateChanged(state: Int, profileName: String, msg: String) = () // ignore
|
||||||
def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) =
|
def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) =
|
||||||
if (selectedItem != null) selectedItem.updateText(txTotal, rxTotal)
|
if (selectedItem != null) selectedItem.updateText(txTotal, rxTotal)
|
||||||
})
|
})
|
||||||
@@ -276,7 +276,7 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
|
|||||||
updateNfcState()
|
updateNfcState()
|
||||||
}
|
}
|
||||||
|
|
||||||
override def onNewIntent(intent: Intent): Unit ={
|
override def onNewIntent(intent: Intent) {
|
||||||
super.onNewIntent(intent)
|
super.onNewIntent(intent)
|
||||||
handleShareIntent(intent)
|
handleShareIntent(intent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
|
|||||||
|
|
||||||
// Services
|
// Services
|
||||||
private val callback = new IShadowsocksServiceCallback.Stub {
|
private val callback = new IShadowsocksServiceCallback.Stub {
|
||||||
def stateChanged(s: Int, m: String) {
|
def stateChanged(s: Int, profileName: String, m: String) {
|
||||||
handler.post(() => {
|
handler.post(() => {
|
||||||
s match {
|
s match {
|
||||||
case State.CONNECTING =>
|
case State.CONNECTING =>
|
||||||
@@ -186,8 +186,8 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
|
|||||||
snackbar.show
|
snackbar.show
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!app.settings.getBoolean(BuildConfig.VERSION_NAME, false)) {
|
if (app.settings.getInt(Key.currentVersionCode, -1) != BuildConfig.VERSION_CODE) {
|
||||||
app.editor.putBoolean(BuildConfig.VERSION_NAME, true).apply()
|
app.editor.putInt(Key.currentVersionCode, BuildConfig.VERSION_CODE).apply()
|
||||||
|
|
||||||
recovery()
|
recovery()
|
||||||
|
|
||||||
|
|||||||
@@ -72,14 +72,16 @@ class ShadowsocksNatService extends BaseService {
|
|||||||
|
|
||||||
def startShadowsocksDaemon() {
|
def startShadowsocksDaemon() {
|
||||||
if (profile.route != Route.ALL && profile.route != Route.GFWLIST) {
|
if (profile.route != Route.ALL && profile.route != Route.GFWLIST) {
|
||||||
val acl: Array[Array[String]] = profile.route match {
|
val acl: Array[String] = profile.route match {
|
||||||
case Route.BYPASS_LAN => Array(getResources.getStringArray(R.array.private_route))
|
case Route.BYPASS_LAN => getResources.getStringArray(R.array.private_route)
|
||||||
case Route.BYPASS_CHN => Array(getResources.getStringArray(R.array.chn_route))
|
case Route.BYPASS_CHN => getResources.getStringArray(R.array.chn_route)
|
||||||
case Route.BYPASS_LAN_CHN =>
|
case Route.BYPASS_LAN_CHN =>
|
||||||
Array(getResources.getStringArray(R.array.private_route), getResources.getStringArray(R.array.chn_route))
|
getResources.getStringArray(R.array.private_route) ++ getResources.getStringArray(R.array.chn_route)
|
||||||
|
case Route.CHINALIST =>
|
||||||
|
Array("[bypass_all]", "[white_list]") ++ getResources.getStringArray(R.array.chn_route)
|
||||||
}
|
}
|
||||||
Utils.printToFile(new File(getApplicationInfo.dataDir + "/acl.list"))(p => {
|
Utils.printToFile(new File(getApplicationInfo.dataDir + "/acl.list"))(p => {
|
||||||
acl.flatten.foreach(p.println)
|
acl.foreach(p.println)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,10 +190,18 @@ class ShadowsocksNatService extends BaseService {
|
|||||||
def startDnsDaemon() {
|
def startDnsDaemon() {
|
||||||
|
|
||||||
val conf = profile.route match {
|
val conf = profile.route match {
|
||||||
case Route.BYPASS_CHN | Route.BYPASS_LAN_CHN | Route.GFWLIST => {
|
case Route.BYPASS_CHN | Route.BYPASS_LAN_CHN => {
|
||||||
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
||||||
"127.0.0.1", profile.localPort + 53, getBlackList, profile.localPort + 63, "")
|
"127.0.0.1", profile.localPort + 53, getBlackList, profile.localPort + 63, "")
|
||||||
}
|
}
|
||||||
|
case Route.GFWLIST => {
|
||||||
|
ConfigUtils.PDNSD_UDP.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
||||||
|
"127.0.0.1", profile.localPort + 53, "1.2.4.8, 208.67.222.222", profile.localPort + 63, "")
|
||||||
|
}
|
||||||
|
case Route.CHINALIST => {
|
||||||
|
ConfigUtils.PDNSD_UDP.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
||||||
|
"127.0.0.1", profile.localPort + 53, "8.8.8.8, 208.67.222.222", profile.localPort + 63, "")
|
||||||
|
}
|
||||||
case _ => {
|
case _ => {
|
||||||
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
||||||
"127.0.0.1", profile.localPort + 53, profile.localPort + 63, "")
|
"127.0.0.1", profile.localPort + 53, profile.localPort + 63, "")
|
||||||
@@ -304,23 +314,15 @@ class ShadowsocksNatService extends BaseService {
|
|||||||
su.addCommand((init_sb ++ http_sb).toArray)
|
su.addCommand((init_sb ++ http_sb).toArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def startRunner(profile: Profile) = if (su == null) {
|
override def startRunner(profile: Profile) = if (su == null)
|
||||||
su = new Shell.Builder().useSU().setWantSTDERR(true).setWatchdogTimeout(10).open((_, exitCode, _) =>
|
su = new Shell.Builder().useSU().setWantSTDERR(true).setWatchdogTimeout(10).open((_, exitCode, _) =>
|
||||||
if (exitCode == 0) super.startRunner(profile) else {
|
if (exitCode == 0) super.startRunner(profile) else {
|
||||||
if (su != null) {
|
if (su != null) {
|
||||||
Log.wtf(TAG, "libsuperuser#55 has been fixed. Please remove the redundant code.")
|
|
||||||
su.close()
|
su.close()
|
||||||
su = null
|
su = null
|
||||||
}
|
}
|
||||||
super.stopRunner(true, getString(R.string.nat_no_root))
|
super.stopRunner(true, getString(R.string.nat_no_root))
|
||||||
})
|
})
|
||||||
su.waitForIdle()
|
|
||||||
if (!su.isRunning) {
|
|
||||||
su.close()
|
|
||||||
su = null
|
|
||||||
super.stopRunner(true, getString(R.string.nat_no_root))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override def connect() {
|
override def connect() {
|
||||||
super.connect()
|
super.connect()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
|
|||||||
private val keyGuard = service.getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
|
private val keyGuard = service.getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
|
||||||
private lazy val nm = service.getSystemService(Context.NOTIFICATION_SERVICE).asInstanceOf[NotificationManager]
|
private lazy val nm = service.getSystemService(Context.NOTIFICATION_SERVICE).asInstanceOf[NotificationManager]
|
||||||
private lazy val callback = new Stub {
|
private lazy val callback = new Stub {
|
||||||
override def stateChanged(state: Int, msg: String) = () // ignore
|
override def stateChanged(state: Int, profileName: String, msg: String) = () // ignore
|
||||||
override def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) {
|
override def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) {
|
||||||
val txr = TrafficMonitor.formatTraffic(txRate)
|
val txr = TrafficMonitor.formatTraffic(txRate)
|
||||||
val rxr = TrafficMonitor.formatTraffic(rxRate)
|
val rxr = TrafficMonitor.formatTraffic(rxRate)
|
||||||
|
|||||||
@@ -207,21 +207,18 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
|
|||||||
}
|
}
|
||||||
|
|
||||||
def refreshProfile() {
|
def refreshProfile() {
|
||||||
val profile = app.currentProfile match {
|
profile = app.currentProfile match {
|
||||||
case Some(profile) => profile
|
case Some(p) => p
|
||||||
case None => {
|
case None =>
|
||||||
app.profileManager.getFirstProfile match {
|
app.profileManager.getFirstProfile match {
|
||||||
case Some(profile) => {
|
case Some(p) =>
|
||||||
app.profileId(profile.id)
|
app.profileId(p.id)
|
||||||
profile
|
p
|
||||||
}
|
case None =>
|
||||||
case None => {
|
|
||||||
val default = app.profileManager.createDefault()
|
val default = app.profileManager.createDefault()
|
||||||
app.profileId(default.id)
|
app.profileId(default.id)
|
||||||
default
|
default
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
isProxyApps.setChecked(profile.proxyApps)
|
isProxyApps.setChecked(profile.proxyApps)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import android.graphics.drawable.Icon
|
|||||||
import android.service.quicksettings.{Tile, TileService}
|
import android.service.quicksettings.{Tile, TileService}
|
||||||
import com.github.shadowsocks.aidl.IShadowsocksServiceCallback
|
import com.github.shadowsocks.aidl.IShadowsocksServiceCallback
|
||||||
import com.github.shadowsocks.utils.{State, Utils}
|
import com.github.shadowsocks.utils.{State, Utils}
|
||||||
import com.github.shadowsocks.ShadowsocksApplication.app
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Mygod
|
* @author Mygod
|
||||||
@@ -23,7 +22,7 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
|
|||||||
private lazy val iconConnected = Icon.createWithResource(this, R.drawable.ic_start_connected)
|
private lazy val iconConnected = Icon.createWithResource(this, R.drawable.ic_start_connected)
|
||||||
private lazy val callback = new IShadowsocksServiceCallback.Stub {
|
private lazy val callback = new IShadowsocksServiceCallback.Stub {
|
||||||
def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) = ()
|
def trafficUpdated(txRate: Long, rxRate: Long, txTotal: Long, rxTotal: Long) = ()
|
||||||
def stateChanged(state: Int, msg: String) {
|
def stateChanged(state: Int, profileName: String, msg: String) {
|
||||||
val tile = getQsTile
|
val tile = getQsTile
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
state match {
|
state match {
|
||||||
@@ -33,10 +32,7 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
|
|||||||
tile.setState(Tile.STATE_INACTIVE)
|
tile.setState(Tile.STATE_INACTIVE)
|
||||||
case State.CONNECTED =>
|
case State.CONNECTED =>
|
||||||
tile.setIcon(iconConnected)
|
tile.setIcon(iconConnected)
|
||||||
tile.setLabel(app.currentProfile match {
|
tile.setLabel(if (profileName == null) getString(R.string.app_name) else profileName)
|
||||||
case Some(profile) => profile.name
|
|
||||||
case None => getString(R.string.app_name)
|
|
||||||
})
|
|
||||||
tile.setState(Tile.STATE_ACTIVE)
|
tile.setState(Tile.STATE_ACTIVE)
|
||||||
case _ =>
|
case _ =>
|
||||||
tile.setIcon(iconBusy)
|
tile.setIcon(iconBusy)
|
||||||
@@ -48,7 +44,7 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def onServiceConnected() = callback.stateChanged(bgService.getState, null)
|
override def onServiceConnected() = callback.stateChanged(bgService.getState, bgService.getProfileName, null)
|
||||||
|
|
||||||
override def onCreate {
|
override def onCreate {
|
||||||
super.onCreate
|
super.onCreate
|
||||||
|
|||||||
@@ -227,14 +227,16 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
|
|
||||||
def startShadowsocksDaemon() {
|
def startShadowsocksDaemon() {
|
||||||
if (profile.route != Route.ALL && profile.route != Route.GFWLIST) {
|
if (profile.route != Route.ALL && profile.route != Route.GFWLIST) {
|
||||||
val acl: Array[Array[String]] = profile.route match {
|
val acl: Array[String] = profile.route match {
|
||||||
case Route.BYPASS_LAN => Array(getResources.getStringArray(R.array.private_route))
|
case Route.BYPASS_LAN => getResources.getStringArray(R.array.private_route)
|
||||||
case Route.BYPASS_CHN => Array(getResources.getStringArray(R.array.chn_route))
|
case Route.BYPASS_CHN => getResources.getStringArray(R.array.chn_route)
|
||||||
case Route.BYPASS_LAN_CHN =>
|
case Route.BYPASS_LAN_CHN =>
|
||||||
Array(getResources.getStringArray(R.array.private_route), getResources.getStringArray(R.array.chn_route))
|
getResources.getStringArray(R.array.private_route) ++ getResources.getStringArray(R.array.chn_route)
|
||||||
|
case Route.CHINALIST =>
|
||||||
|
Array("[bypass_all]", "[white_list]") ++ getResources.getStringArray(R.array.chn_route)
|
||||||
}
|
}
|
||||||
Utils.printToFile(new File(getApplicationInfo.dataDir + "/acl.list"))(p => {
|
Utils.printToFile(new File(getApplicationInfo.dataDir + "/acl.list"))(p => {
|
||||||
acl.flatten.foreach(p.println)
|
acl.foreach(p.println)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,10 +309,18 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
def startDnsDaemon() {
|
def startDnsDaemon() {
|
||||||
val ipv6 = if (profile.ipv6) "" else "reject = ::/0;"
|
val ipv6 = if (profile.ipv6) "" else "reject = ::/0;"
|
||||||
val conf = profile.route match {
|
val conf = profile.route match {
|
||||||
case Route.BYPASS_CHN | Route.BYPASS_LAN_CHN | Route.GFWLIST => {
|
case Route.BYPASS_CHN | Route.BYPASS_LAN_CHN => {
|
||||||
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
||||||
"0.0.0.0", profile.localPort + 53, getBlackList, profile.localPort + 63, ipv6)
|
"0.0.0.0", profile.localPort + 53, getBlackList, profile.localPort + 63, ipv6)
|
||||||
}
|
}
|
||||||
|
case Route.GFWLIST => {
|
||||||
|
ConfigUtils.PDNSD_UDP.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
||||||
|
"0.0.0.0", profile.localPort + 53, "1.2.4.8, 208.67.222.222", profile.localPort + 63, "")
|
||||||
|
}
|
||||||
|
case Route.CHINALIST => {
|
||||||
|
ConfigUtils.PDNSD_UDP.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
||||||
|
"0.0.0.0", profile.localPort + 53, "8.8.8.8, 208.67.222.222", profile.localPort + 63, ipv6)
|
||||||
|
}
|
||||||
case _ => {
|
case _ => {
|
||||||
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
|
||||||
"0.0.0.0", profile.localPort + 53, profile.localPort + 63, ipv6)
|
"0.0.0.0", profile.localPort + 53, profile.localPort + 63, ipv6)
|
||||||
@@ -334,7 +344,8 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
.setSession(profile.name)
|
.setSession(profile.name)
|
||||||
.setMtu(VPN_MTU)
|
.setMtu(VPN_MTU)
|
||||||
.addAddress(PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), 24)
|
.addAddress(PRIVATE_VLAN.formatLocal(Locale.ENGLISH, "1"), 24)
|
||||||
.addDnsServer("8.8.8.8")
|
|
||||||
|
builder.addDnsServer("8.8.8.8")
|
||||||
|
|
||||||
if (profile.ipv6) {
|
if (profile.ipv6) {
|
||||||
builder.addAddress(PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "1"), 126)
|
builder.addAddress(PRIVATE_VLAN6.formatLocal(Locale.ENGLISH, "1"), 126)
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ object ConfigUtils {
|
|||||||
|
|
|
|
||||||
|server {
|
|server {
|
||||||
| label = "china-servers";
|
| label = "china-servers";
|
||||||
| ip = 114.114.114.114, 112.124.47.27;
|
| ip = 1.2.4.8, 208.67.222.222, 114.114.114.114;
|
||||||
| timeout = 4;
|
| timeout = 4;
|
||||||
| exclude = %s;
|
| exclude = %s;
|
||||||
| policy = included;
|
| policy = included;
|
||||||
@@ -141,6 +141,47 @@ object ConfigUtils {
|
|||||||
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|
||||||
|}
|
|}
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
|
|
||||||
|
val PDNSD_UDP =
|
||||||
|
"""
|
||||||
|
|global {
|
||||||
|
| perm_cache = 2048;
|
||||||
|
| cache_dir = "%s";
|
||||||
|
| server_ip = %s;
|
||||||
|
| server_port = %d;
|
||||||
|
| query_method = udp_tcp;
|
||||||
|
| run_ipv4 = on;
|
||||||
|
| min_ttl = 15m;
|
||||||
|
| max_ttl = 1w;
|
||||||
|
| timeout = 10;
|
||||||
|
| daemon = off;
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
|server {
|
||||||
|
| label = "remote-servers";
|
||||||
|
| ip = %s;
|
||||||
|
| timeout = 5;
|
||||||
|
| uptest = none;
|
||||||
|
| preset = on;
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
|server {
|
||||||
|
| label = "local-server";
|
||||||
|
| ip = 127.0.0.1;
|
||||||
|
| port = %d;
|
||||||
|
| %s
|
||||||
|
| reject_policy = negate;
|
||||||
|
| reject_recursively = on;
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
|rr {
|
||||||
|
| name=localhost;
|
||||||
|
| reverse=on;
|
||||||
|
| a=127.0.0.1;
|
||||||
|
| owner=localhost;
|
||||||
|
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|
||||||
|
|}
|
||||||
|
""".stripMargin
|
||||||
}
|
}
|
||||||
|
|
||||||
object Key {
|
object Key {
|
||||||
@@ -173,6 +214,7 @@ object Key {
|
|||||||
val kcpcli = "kcpcli"
|
val kcpcli = "kcpcli"
|
||||||
|
|
||||||
val tfo = "tcp_fastopen"
|
val tfo = "tcp_fastopen"
|
||||||
|
val currentVersionCode = "currentVersionCode"
|
||||||
}
|
}
|
||||||
|
|
||||||
object State {
|
object State {
|
||||||
@@ -195,4 +237,5 @@ object Route {
|
|||||||
val BYPASS_CHN = "bypass-china"
|
val BYPASS_CHN = "bypass-china"
|
||||||
val BYPASS_LAN_CHN = "bypass-lan-china"
|
val BYPASS_LAN_CHN = "bypass-lan-china"
|
||||||
val GFWLIST = "gfwlist"
|
val GFWLIST = "gfwlist"
|
||||||
|
val CHINALIST = "china-list"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user