Commit d9eb0e51 authored by Max Lv's avatar Max Lv

Merge pull request #583 from JLLK/master

Fix binder ipc issue when process died unexpected
parents 2eb12ee2 fc3d26d6
......@@ -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() = ()
......
......@@ -377,7 +377,11 @@ class Shadowsocks
})
updateTraffic(0, 0, 0, 0)
bindToService()
}
// Bind to the service
def bindToService() {
handler.post(() => attachService)
}
......
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 _ =>
}
}
}
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
}
}
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
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment