Compare commits

...
13 Commits
Author SHA1 Message Date
Max Lv 55f25d3272 disable NAT mode on lollipop for now 2014-10-19 14:09:27 +08:00
Max Lv 93273cbc44 fix an issue on lollipop 2014-10-19 13:58:19 +08:00
Max Lv c0514ee169 disable bypass feature of pdnsd 2014-10-18 10:46:54 +08:00
Max Lv 06d736b22d fix all issues for lollipop 2014-10-18 09:58:40 +08:00
Max Lv e34d5675eb update shadowsocks-libev 2014-10-14 12:58:09 +08:00
Max Lv 94c7ffb788 remove large icon 2014-09-30 12:59:15 +08:00
Max Lv 0647ef4c6d fix #121 2014-09-19 14:17:45 +08:00
Max Lv 97c6ff95cd fix an issue in the build scripts 2014-09-18 08:24:39 +08:00
Max Lv 971ef22186 fix a data race 2014-09-15 12:52:29 +08:00
Max Lv c35a92a927 fix a crash 2014-09-14 15:39:03 +08:00
Max Lv c05a63a75b fix #116 2014-09-13 17:18:25 +08:00
Max Lv 6074a99eb6 fix an issue 2014-09-11 20:55:57 +08:00
Max Lv e52719d1be back to old play services 2014-09-09 21:58:34 +08:00
13 changed files with 153 additions and 205 deletions
+18 -28
View File
@@ -1,38 +1,28 @@
#!/bin/bash
# Target 9
cp jni/Application.mk.9 jni/Application.mk
ndk-build clean
ndk-build
rm -rf src/main/assets/armeabi
function try () {
"$@" || exit -1
}
# Build
try ndk-build clean
try ndk-build
# copy executables
rm -rf src/main/assets/armeabi-v7a
rm -rf src/main/assets/x86
mkdir -p src/main/assets/armeabi
mkdir -p src/main/assets/armeabi-v7a
mkdir -p src/main/assets/x86
for app in pdnsd redsocks
do
mv libs/armeabi/$app src/main/assets/armeabi/
mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/
mv libs/x86/$app src/main/assets/x86/
done
rm -rf src/main/jni
mv libs src/main/jni
# Target 16
cp jni/Application.mk.16 jni/Application.mk
ndk-build clean
ndk-build
rm -rf src/main/assets/api-16/armeabi
rm -rf src/main/assets/api-16/armeabi-v7a
rm -rf src/main/assets/api-16/x86
mkdir -p src/main/assets/api-16/armeabi
mkdir -p src/main/assets/api-16/armeabi-v7a
mkdir -p src/main/assets/api-16/x86
for app in pdnsd redsocks
do
mv libs/armeabi/$app src/main/assets/api-16/armeabi/
mv libs/armeabi-v7a/$app src/main/assets/api-16/armeabi-v7a/
mv libs/x86/$app src/main/assets/api-16/x86/
try mv libs/armeabi-v7a/$app src/main/assets/armeabi-v7a/
try mv libs/x86/$app src/main/assets/x86/
done
# copy libraries
rm -rf src/main/jni/armeabi-v7a
rm -rf src/main/jni/x86
mkdir -p src/main/jni/armeabi-v7a
mkdir -p src/main/jni/x86
try mv libs/armeabi-v7a/*.so src/main/jni/armeabi-v7a/
try mv libs/x86/*.so src/main/jni/x86/
+3 -3
View File
@@ -4,7 +4,7 @@ import android.Dependencies.{apklib,aar}
android.Plugin.androidBuild
platformTarget in Android := "android-19"
platformTarget in Android := "android-21"
name := "shadowsocks"
@@ -23,12 +23,12 @@ libraryDependencies ++= Seq(
libraryDependencies ++= Seq(
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
"com.google.android.gms" % "play-services" % "5.2.08",
"com.google.android.gms" % "play-services" % "5.0.89",
"com.android.support" % "support-v4" % "19.1.0"
)
libraryDependencies ++= Seq(
"de.keyboardsurfer.android.widget" % "crouton" % "1.8.1" exclude("com.google.android", "support-v4"),
"de.keyboardsurfer.android.widget" % "crouton" % "1.8.4" exclude("com.google.android", "support-v4"),
"com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4",
"com.j256.ormlite" % "ormlite-core" % "4.47",
"com.j256.ormlite" % "ormlite-android" % "4.47"
+1 -1
View File
@@ -1,4 +1,4 @@
APP_ABI := armeabi armeabi-v7a x86
APP_ABI := armeabi-v7a x86
APP_PLATFORM := android-16
APP_STL := stlport_static
NDK_TOOLCHAIN_VERSION := 4.8
-4
View File
@@ -1,4 +0,0 @@
APP_ABI := armeabi armeabi-v7a x86
APP_PLATFORM := android-9
APP_STL := stlport_static
NDK_TOOLCHAIN_VERSION := 4.8
+5 -5
View File
@@ -21,11 +21,11 @@ jstring Java_com_github_shadowsocks_system_getabi(JNIEnv *env, jobject thiz) {
} else if (family == ANDROID_CPU_FAMILY_MIPS) {
abi = "mips";
} else if (family == ANDROID_CPU_FAMILY_ARM) {
if (features & ANDROID_CPU_ARM_FEATURE_ARMv7) {
abi = "armeabi-v7a";
} else {
abi = "armeabi";
}
// if (features & ANDROID_CPU_ARM_FEATURE_ARMv7) {
abi = "armeabi-v7a";
// } else {
// abi = "armeabi";
// }
}
return env->NewStringUTF(abi);
}
+4 -4
View File
@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.shadowsocks"
android:versionCode="70"
android:versionName="2.2.2">
android:versionCode="75"
android:versionName="2.3.0">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
@@ -15,8 +15,8 @@
android:required="false"/>
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19"/>
android:minSdkVersion="16"
android:targetSdkVersion="21"/>
<application
android:allowBackup="true"
+1 -1
View File
@@ -44,7 +44,7 @@
<string name="forward_stop">后台服务已停止。</string>
<string name="service_failed">请检查你的网络状态后并重试。</string>
<string name="stop">停止服务</string>
<string name="vpn_error">无法启动 VPN 服务:\"%s\"。看来和你的设备存在兼容性问题,请使用 Root 模式。</string>
<string name="vpn_error">无法启动服务:\"%s\"。</string>
<string name="ok_iknow">确定</string>
<string name="port_alert">端口号应大于1024</string>
<string name="port_empty">端口号不能为空</string>
+1 -1
View File
@@ -57,7 +57,7 @@
<string name="forward_stop">Shadowsocks stopped.</string>
<string name="service_failed">Please check your network status and try again.</string>
<string name="stop">Stop the service</string>
<string name="vpn_error">Unable to start VPN service: "%s". It seems to be a compatibility issue with your device. Please consider using ROOT mode instead.</string>
<string name="vpn_error">Unable to start service: "%s".</string>
<!-- alert category -->
<string name="ok_iknow">OK</string>
@@ -213,6 +213,8 @@ class Shadowsocks
setPreferenceEnabled(enabled = false)
}
state = bgService.getState
// set the listener
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
}
override def onServiceDisconnected(name: ComponentName) {
@@ -746,14 +748,13 @@ class Shadowsocks
changeSwitch(checked = false)
}
state = bgService.getState
// set the listener
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
}
// set the listener
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
ConfigUtils.refresh(this)
}
private def setPreferenceEnabled(enabled: Boolean) {
val isRoot = status.getBoolean(Key.isRoot, false)
for (name <- Shadowsocks.PROXY_PREFS) {
val pref = findPreference(name)
if (pref != null) {
@@ -765,7 +766,7 @@ class Shadowsocks
if (pref != null) {
if (Seq(Key.isGlobalProxy, Key.isTrafficStat, Key.proxyedApps)
.contains(name)) {
pref.setEnabled(enabled && isRoot)
pref.setEnabled(enabled && !isVpnEnabled)
} else {
pref.setEnabled(enabled)
}
@@ -823,15 +824,7 @@ class Shadowsocks
crash_recovery()
if (Build.VERSION.SDK_INT >= 16) {
copyAssets("api-16/" + System.getABI)
} else {
copyAssets(System.getABI)
}
if (Build.VERSION.SDK_INT >= 20) {
copyToSystem()
}
copyAssets(System.getABI)
val ab = new ArrayBuffer[String]
for (executable <- Shadowsocks.EXECUTABLES) {
@@ -881,8 +874,8 @@ class Shadowsocks
def isVpnEnabled: Boolean = {
if (vpnEnabled < 0) {
vpnEnabled = if (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.ICE_CREAM_SANDWICH && !status.getBoolean(Key.isRoot, false)) {
vpnEnabled = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
|| !status.getBoolean(Key.isRoot, false)) {
1
} else {
0
@@ -930,8 +923,6 @@ class Shadowsocks
bgService.start(ConfigUtils.load(settings))
if (isVpnEnabled) {
val style = new Style.Builder().setBackgroundColorValue(Style.holoBlueLight).build()
val config = new Configuration.Builder().setDuration(Configuration.DURATION_LONG).build()
changeSwitch(checked = false)
}
true
@@ -997,7 +988,6 @@ class Shadowsocks
changeSwitch(checked = false)
Crouton.cancelAllCroutons()
if (m != null) {
Crouton.cancelAllCroutons()
val style = new Style.Builder().setBackgroundColorValue(Style.holoRedLight).build()
val config = new Configuration.Builder()
.setDuration(Configuration.DURATION_LONG)
@@ -114,49 +114,52 @@ class ShadowsocksNatService extends Service with BaseService {
})
}
val raw_args = ("ss-local -b 127.0.0.1 -s %s -p %d -l %d -k %s -m %s -f " +
Path.BASE + "ss-local.pid")
.format(config.proxy, config.remotePort, config.localPort, config.sitekey, config.encMethod)
val args = if (Build.VERSION.SDK_INT >= 20) {
raw_args
} else {
Path.BASE + raw_args
}
val cmd = if (config.isGFWList && isACLEnabled) args + " --acl " + Path.BASE + "chn.acl" else args
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
val cmd = new ArrayBuffer[String]
cmd += ("ss-local"
, "-b" , "127.0.0.1"
, "-s" , config.proxy
, "-p" , config.remotePort.toString
, "-l" , config.localPort.toString
, "-k" , config.sitekey
, "-m" , config.encMethod
, "-f" , (Path.BASE + "ss-local.pid"))
Core.sslocal(cmd.split(" "))
if (config.isGFWList && isACLEnabled) {
cmd += "--acl"
cmd += (Path.BASE + "chn.acl")
}
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
Core.sslocal(cmd.toArray)
}
def startDnsDaemon() {
val args = if (config.isUdpDns) {
("ss-tunnel -b 127.0.0.1 -s %s -p %d -l %d -k %s -m %s -L 8.8.8.8:53 -u -f " +
Path.BASE + "ss-tunnel.pid")
.format(config.proxy, config.remotePort, 8153, config.sitekey, config.encMethod)
if (config.isUdpDns) {
val cmd = new ArrayBuffer[String]
cmd += ("ss-tunnel" , "-u"
, "-b" , "127.0.0.1"
, "-l" , "8153"
, "-L" , "8.8.8.8:53"
, "-s" , config.proxy
, "-p" , config.remotePort.toString
, "-k" , config.sitekey
, "-m" , config.encMethod
, "-f" , (Path.BASE + "ss-tunnel.pid"))
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
Core.sstunnel(cmd.toArray)
} else {
val conf = {
if (config.isGFWList)
ConfigUtils.PDNSD_BYPASS.format("127.0.0.1", getString(R.string.exclude))
else
ConfigUtils.PDNSD.format("127.0.0.1")
ConfigUtils.PDNSD.format("127.0.0.1")
}
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => {
p.println(conf)
})
"pdnsd -c " + Path.BASE + "pdnsd.conf"
}
val cmd = if (Build.VERSION.SDK_INT >= 20) {
"/system/bin/" + args
} else {
Path.BASE + args
}
val args = "pdnsd -c " + Path.BASE + "pdnsd.conf"
val cmd = Path.BASE + args
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
if (config.isUdpDns) {
Core.sstunnel(cmd.split(" "))
} else {
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
Console.runRootCommand(cmd)
}
}
@@ -180,11 +183,7 @@ class ShadowsocksNatService extends Service with BaseService {
ConfigUtils.printToFile(new File(Path.BASE + "redsocks.conf"))(p => {
p.println(conf)
})
val cmd = if (Build.VERSION.SDK_INT >= 20) {
"/system/bin/" + args
} else {
Path.BASE + args
}
val cmd = Path.BASE + args
Console.runRootCommand(cmd)
}
@@ -225,10 +224,6 @@ class ShadowsocksNatService extends Service with BaseService {
val icon = getResources.getDrawable(R.drawable.ic_stat_shadowsocks)
if (rate >= 0) {
val bitmap = Utils
.getBitmap(rate.toString, icon.getIntrinsicWidth * 4, icon.getIntrinsicHeight * 4,
Color.TRANSPARENT)
builder.setLargeIcon(bitmap)
if (rate < 1000) {
builder.setSmallIcon(R.drawable.ic_stat_speed, rate)
@@ -254,22 +249,6 @@ class ShadowsocksNatService extends Service with BaseService {
startForegroundCompat(1, builder.build)
}
def notifyAlert(title: String, info: String) {
val openIntent: Intent = new Intent(this, classOf[Shadowsocks])
openIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
val builder: NotificationCompat.Builder = new NotificationCompat.Builder(this)
builder
.setSmallIcon(R.drawable.ic_stat_shadowsocks)
.setWhen(0)
.setTicker(title)
.setContentTitle(getString(R.string.app_name))
.setContentText(info)
.setContentIntent(contentIntent)
.setAutoCancel(true)
notificationManager.notify(1, builder.build)
}
def onBind(intent: Intent): IBinder = {
Log.d(TAG, "onBind")
if (Action.SERVICE == intent.getAction) {
@@ -343,10 +322,6 @@ class ShadowsocksNatService extends Service with BaseService {
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + myUid))
if (config.isGFWList) {
// Bypass DNS in China
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d 114.114.114.114"))
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d 114.114.115.115"))
if (!isACLEnabled)
{
val chn_list: Array[String] = getResources.getStringArray(R.array.chn_list)
@@ -492,44 +467,46 @@ class ShadowsocksNatService extends Service with BaseService {
}
spawn {
if (config.proxy == "198.199.101.152") {
val holder = application.containerHolder
try {
config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
} catch {
case ex: Exception =>
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
changeState(State.STOPPED, getString(R.string.service_failed))
stopRunner()
changeState(State.STOPPED)
return
config = null
}
}
killProcesses()
if (config != null) {
var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
!InetAddressUtils.isIPv6Address(config.proxy)) {
Utils.resolve(config.proxy, enableIPv6 = true) match {
case Some(a) =>
config.proxy = a
resolved = true
case None => resolved = false
killProcesses()
var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
!InetAddressUtils.isIPv6Address(config.proxy)) {
Utils.resolve(config.proxy, enableIPv6 = true) match {
case Some(a) =>
config.proxy = a
resolved = true
case None => resolved = false
}
} else {
resolved = true
}
} else {
resolved = true
}
hasRedirectSupport = Utils.getHasRedirectSupport
hasRedirectSupport = Utils.getHasRedirectSupport
if (resolved && handleConnection) {
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).format(config.profileName))
changeState(State.CONNECTED)
} else {
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
stopRunner()
changeState(State.STOPPED)
if (resolved && handleConnection) {
notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).format(config.profileName))
changeState(State.CONNECTED)
} else {
changeState(State.STOPPED, getString(R.string.service_failed))
stopRunner()
}
}
}
}
@@ -565,6 +542,7 @@ class ShadowsocksNatService extends Service with BaseService {
unregisterReceiver(receiver)
receiver = null
}
stopForegroundCompat(1)
}
@@ -76,24 +76,26 @@ class ShadowsocksVpnService extends VpnService with BaseService {
def isByass(net: SubnetUtils): Boolean = {
val info = net.getInfo
info.isInRange(config.proxy) || info.isInRange("114.114.114.114") || info.isInRange("114.114.115.115")
info.isInRange(config.proxy)
}
def startShadowsocksDaemon() {
val cmd: String = (Path.BASE +
"ss-local -b 127.0.0.1 -s %s -p %d -l %d -k %s -m %s -u -f " +
Path.BASE + "ss-local.pid")
.format(config.proxy, config.remotePort, config.localPort, config.sitekey, config.encMethod)
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
Core.sslocal(cmd.split(" "))
val cmd = new ArrayBuffer[String]
cmd += ("ss-local" , "-u"
, "-b" , "127.0.0.1"
, "-s" , config.proxy
, "-p" , config.remotePort.toString
, "-l" , config.localPort.toString
, "-k" , config.sitekey
, "-m" , config.encMethod
, "-f" , (Path.BASE + "ss-local.pid"))
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
Core.sslocal(cmd.toArray)
}
def startDnsDaemon() {
val conf = {
if (config.isGFWList)
ConfigUtils.PDNSD_BYPASS.format("0.0.0.0", getString(R.string.exclude))
else
ConfigUtils.PDNSD.format("0.0.0.0")
ConfigUtils.PDNSD.format("0.0.0.0")
}
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd.conf"))(p => {
p.println(conf)
@@ -142,7 +144,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
}
})
} else {
for (i <- 1 to 254) {
for (i <- 1 to 223) {
if (i != 26 && i != 127) {
val addr = i.toString + ".0.0.0"
val cidr = addr + "/8"
@@ -214,18 +216,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
true
}
def notifyAlert(title: String, info: String) {
val builder = new NotificationCompat.Builder(this)
builder
.setSmallIcon(R.drawable.ic_stat_shadowsocks)
.setWhen(0)
.setTicker(title)
.setContentTitle(getString(R.string.app_name))
.setContentText(info)
.setAutoCancel(true)
notificationManager.notify(1, builder.build)
}
override def onBind(intent: Intent): IBinder = {
val action = intent.getAction
if (VpnService.SERVICE_INTERFACE == action) {
@@ -297,36 +287,37 @@ class ShadowsocksVpnService extends VpnService with BaseService {
config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
} catch {
case ex: Exception =>
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
changeState(State.STOPPED, getString(R.string.service_failed))
stopRunner()
changeState(State.STOPPED)
return
config = null
}
}
// reset the context
killProcesses()
if (config != null) {
// Resolve the server address
var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
!InetAddressUtils.isIPv6Address(config.proxy)) {
Utils.resolve(config.proxy, enableIPv6 = true) match {
case Some(addr) =>
config.proxy = addr
resolved = true
case None => resolved = false
// reset the context
killProcesses()
// Resolve the server address
var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(config.proxy) &&
!InetAddressUtils.isIPv6Address(config.proxy)) {
Utils.resolve(config.proxy, enableIPv6 = true) match {
case Some(addr) =>
config.proxy = addr
resolved = true
case None => resolved = false
}
} else {
resolved = true
}
} else {
resolved = true
}
if (resolved && handleConnection) {
changeState(State.CONNECTED)
} else {
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
changeState(State.STOPPED)
stopRunner()
if (resolved && handleConnection) {
changeState(State.CONNECTED)
} else {
changeState(State.STOPPED, getString(R.string.service_failed))
stopRunner()
}
}
}
}
@@ -362,9 +353,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
unregisterReceiver(receiver)
receiver = null
}
// reset notifications
notificationManager.cancel(1)
}
override def stopBackgroundService() {
@@ -57,7 +57,10 @@ object Console {
.open(new OnCommandResultListener {
override def onCommandResult(commandCode: Int, exitCode: Int,
output: util.List[String]) {
if (exitCode < 0) shell = null
if (exitCode < 0) {
shell.close()
shell = null
}
}
})
}
@@ -82,8 +85,9 @@ object Console {
if (shell == null) {
openShell()
}
shell.addCommand(commands)
shell.waitForIdle()
val ts = shell
ts.addCommand(commands)
ts.waitForIdle()
}
def runRootCommand(command: String): String = runRootCommand(Array(command))
@@ -95,11 +99,13 @@ object Console {
if (rootShell == null) {
openRootShell()
}
val ts = rootShell
val sb = new StringBuilder
rootShell.addCommand(commands, 0, new OnCommandResultListener {
ts.addCommand(commands, 0, new OnCommandResultListener {
override def onCommandResult(commandCode: Int, exitCode: Int,
output: util.List[String]) {
if (exitCode < 0) {
rootShell.close()
rootShell = null
} else {
import scala.collection.JavaConversions._
@@ -107,7 +113,7 @@ object Console {
}
}
})
if (rootShell.waitForIdle()) sb.toString()
if (ts.waitForIdle()) sb.toString()
else null
}