From a24d29196f7989db16eab6e11140ec0c6baa6e7e Mon Sep 17 00:00:00 2001 From: chentao Date: Wed, 24 Feb 2016 23:57:38 +0800 Subject: [PATCH 1/4] Add ProcessUtils --- .../shadowsocks/utils/ProcessUtils.scala | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/main/scala/com/github/shadowsocks/utils/ProcessUtils.scala diff --git a/src/main/scala/com/github/shadowsocks/utils/ProcessUtils.scala b/src/main/scala/com/github/shadowsocks/utils/ProcessUtils.scala new file mode 100644 index 00000000..8de7939c --- /dev/null +++ b/src/main/scala/com/github/shadowsocks/utils/ProcessUtils.scala @@ -0,0 +1,46 @@ +package com.github.shadowsocks.utils + +import java.io.{BufferedReader, FileInputStream, InputStreamReader} + +import com.github.shadowsocks.utils.IOUtils._ + +/** + * @author chentaov5@gmail.com + */ +object ProcessUtils { + + val SHADOWNSOCKS = "com.github.shadowsocks" + val SHADOWNSOCKS_VPN = "com.github.shadowsocks:vpn" + val SHADOWNSOCKS_NAT = "com.github.shadowsocks:nat" + val TUN2SOCKS = "/data/data/com.github.shadowsocks/tun2socks" + val SS_LOCAL = "/data/data/com.github.shadowsocks/ss-local" + val SS_TUNNEL = "/data/data/com.github.shadowsocks/ss-tunnel" + val PDNSD = "/data/data/com.github.shadowsocks/pdnsd" + + def getCurrentProcessName: String = { + inSafe { + val inputStream = new FileInputStream("/proc/self/cmdline") + val reader = new BufferedReader(new InputStreamReader(inputStream)) + autoClose(reader) { + reader.readLine() match { + case name: String => name + case _ => "" + } + } + } match { + case Some(name: String) => name + case None => "" + } + } + + def inShadowsocks[A](fun: => A): Unit = + if(getCurrentProcessName startsWith SHADOWNSOCKS) fun + + def inVpn[A](fun: => A): Unit = + if (getCurrentProcessName startsWith SHADOWNSOCKS_VPN) fun + + + def inNat[A](fun: => A): Unit = + if (getCurrentProcessName startsWith SHADOWNSOCKS_NAT) fun + +} From f6cab9b99c7fcb75158a23a5810b11348b02c5f1 Mon Sep 17 00:00:00 2001 From: chentao Date: Wed, 24 Feb 2016 23:58:57 +0800 Subject: [PATCH 2/4] Add IOUtils --- .../github/shadowsocks/utils/IOUtils.scala | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/main/scala/com/github/shadowsocks/utils/IOUtils.scala diff --git a/src/main/scala/com/github/shadowsocks/utils/IOUtils.scala b/src/main/scala/com/github/shadowsocks/utils/IOUtils.scala new file mode 100644 index 00000000..0fdf4269 --- /dev/null +++ b/src/main/scala/com/github/shadowsocks/utils/IOUtils.scala @@ -0,0 +1,33 @@ +package com.github.shadowsocks.utils + +import android.util.Log + +/** + * @author chentaov5@gmail.com + */ +object IOUtils { + + val TAG = "IOUtils" + + def autoClose[R <: {def close() : Unit}, T](in: R)(fun: => T): T = { + try { + fun + } finally if (in ne null) + try { + in.close() + } catch { + case e: Exception => Log.d(TAG, e.getMessage, e) + } + } + + def inSafe[T](fun: => T): Option[T] = { + var res: Option[T] = None + try { + res = Some(fun) + } catch { + case e: Exception => Log.d(TAG, e.getMessage, e) + } + res + } + +} From 1bb3a6bf5d32eb91afc0a48ac36524f44cb15662 Mon Sep 17 00:00:00 2001 From: chentao Date: Thu, 25 Feb 2016 00:00:33 +0800 Subject: [PATCH 3/4] Add ShadowsocksDeathRecipient --- .../ShadowsocksDeathRecipient.scala | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/scala/com/github/shadowsocks/ShadowsocksDeathRecipient.scala diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksDeathRecipient.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksDeathRecipient.scala new file mode 100644 index 00000000..44b4e177 --- /dev/null +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksDeathRecipient.scala @@ -0,0 +1,28 @@ +package com.github.shadowsocks + +import android.os.IBinder +import android.util.Log +import com.github.shadowsocks.utils.ProcessUtils._ + +/** + * @author chentaov5@gmail.com + */ +class ShadowsocksDeathRecipient(val mContext: ServiceBoundContext) + extends IBinder.DeathRecipient { + + val TAG = "ShadowsocksDeathRecipient" + + override def binderDied(): Unit = { + Log.d(TAG, "[ShadowsocksDeathRecipient] binder died.") + + mContext match { + case ss: Shadowsocks => + inShadowsocks { + ss.unregisterCallback + ss.bindToService() + } + case _ => + } + } + +} From fc3d26d626b7a82681e00b4dfe06b46022327b6f Mon Sep 17 00:00:00 2001 From: chentao Date: Thu, 25 Feb 2016 00:04:57 +0800 Subject: [PATCH 4/4] Fix binder ipc issue when process died unexpected --- .../com/github/shadowsocks/ServiceBoundContext.scala | 8 ++++---- src/main/scala/com/github/shadowsocks/Shadowsocks.scala | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/scala/com/github/shadowsocks/ServiceBoundContext.scala b/src/main/scala/com/github/shadowsocks/ServiceBoundContext.scala index 34ffe537..6cba8d7d 100644 --- a/src/main/scala/com/github/shadowsocks/ServiceBoundContext.scala +++ b/src/main/scala/com/github/shadowsocks/ServiceBoundContext.scala @@ -4,16 +4,15 @@ import android.content.{ComponentName, Context, Intent, ServiceConnection} import android.os.{RemoteException, IBinder} import com.github.shadowsocks.aidl.{IShadowsocksServiceCallback, IShadowsocksService} import com.github.shadowsocks.utils.Action -import com.github.shadowsocks.utils.Utils /** * @author Mygod */ -trait ServiceBoundContext extends Context { - +trait ServiceBoundContext extends Context { outer => class ShadowsocksServiceConnection extends ServiceConnection { override def onServiceConnected(name: ComponentName, service: IBinder) { bgService = IShadowsocksService.Stub.asInterface(service) + bgService.asBinder().linkToDeath(new ShadowsocksDeathRecipient(outer), 0) registerCallback ServiceBoundContext.this.onServiceConnected() } @@ -33,11 +32,12 @@ trait ServiceBoundContext extends Context { } catch { case ignored: RemoteException => // Nothing } + def unregisterCallback = if (bgService != null && callback != null && callbackRegistered) try { bgService.unregisterCallback(callback) callbackRegistered = false } catch { - case ignored: RemoteException => // Nothing + case ignored: RemoteException => callbackRegistered = false } def onServiceConnected() = () diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 84a8602f..bcc2b6cc 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -377,7 +377,11 @@ class Shadowsocks }) updateTraffic(0, 0, 0, 0) - // Bind to the service + bindToService() + } + + // Bind to the service + def bindToService() { handler.post(() => attachService) }