diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 470ced60..1864ccdb 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + android:versionCode="76" + android:versionName="2.3.1"> diff --git a/src/main/scala/com/github/shadowsocks/AppManager.scala b/src/main/scala/com/github/shadowsocks/AppManager.scala index cbd6fb25..ad4661e1 100644 --- a/src/main/scala/com/github/shadowsocks/AppManager.scala +++ b/src/main/scala/com/github/shadowsocks/AppManager.scala @@ -89,8 +89,9 @@ object AppManager { case a => { val uid = a.uid val userName = uid.toString + val packageName = a.packageName val proxied = proxiedApps.binarySearch(userName) >= 0 - new ProxiedApp(uid, userName, proxied) + new ProxiedApp(uid, packageName, proxied) } }.toArray } diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 2071ce69..78cba307 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -766,7 +766,7 @@ class Shadowsocks if (pref != null) { if (Seq(Key.isGlobalProxy, Key.isTrafficStat, Key.proxyedApps) .contains(name)) { - pref.setEnabled(enabled && !isVpnEnabled) + pref.setEnabled(enabled && (!isVpnEnabled || Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP)) } else { pref.setEnabled(enabled) } diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index 3e041bd2..5ee75479 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -55,6 +55,7 @@ import com.google.android.gms.analytics.HitBuilders import org.apache.commons.net.util.SubnetUtils import org.apache.http.conn.util.InetAddressUtils +import scala.collection.mutable import scala.collection.mutable.ArrayBuffer import scala.concurrent.ops._ @@ -66,6 +67,8 @@ class ShadowsocksVpnService extends VpnService with BaseService { val PRIVATE_VLAN = "26.26.26.%s" + val AF_INET6 = 10 + var conn: ParcelFileDescriptor = null var notificationManager: NotificationManager = null var receiver: BroadcastReceiver = null @@ -88,7 +91,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { , "-l" , config.localPort.toString , "-k" , config.sitekey , "-m" , config.encMethod - , "-f" , (Path.BASE + "ss-local.pid")) + , "-f" , Path.BASE + "ss-local.pid") if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" ")) Core.sslocal(cmd.toArray) } @@ -126,11 +129,36 @@ class ShadowsocksVpnService extends VpnService with BaseService { .addAddress(PRIVATE_VLAN.format("1"), 24) .addDnsServer("8.8.8.8") + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) { + builder.allowFamily(AF_INET6) + + if (config.isBypassApps) { + builder.addDisallowedApplication(this.getPackageName) + } + + if (!config.isGlobalProxy) { + val apps = AppManager.getProxiedApps(this, config.proxiedAppString) + val uidSet: mutable.HashSet[String] = new mutable.HashSet[String] + for (app <- apps) { + if (app.proxied) { + uidSet.add(app.name) + } + } + for (uid <- uidSet) { + if (!config.isBypassApps) { + builder.addAllowedApplication(uid) + } else { + builder.addDisallowedApplication(uid) + } + } + } + } + if (InetAddressUtils.isIPv6Address(config.proxy)) { builder.addRoute("0.0.0.0", 0) } else if (config.isGFWList) { val gfwList = { - if (Build.VERSION.SDK_INT == 19) { + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { getResources.getStringArray(R.array.simple_list) } else { getResources.getStringArray(R.array.gfw_list)