Commit 270d4360 authored by Mygod's avatar Mygod

Refine ShadowsocksDeathRecipient and ServiceBoundContext

parent a4e186b7
...@@ -8,11 +8,11 @@ import com.github.shadowsocks.utils.Action ...@@ -8,11 +8,11 @@ import com.github.shadowsocks.utils.Action
/** /**
* @author Mygod * @author Mygod
*/ */
trait ServiceBoundContext extends Context { outer => trait ServiceBoundContext extends Context {
class ShadowsocksServiceConnection extends ServiceConnection { class ShadowsocksServiceConnection extends ServiceConnection {
override def onServiceConnected(name: ComponentName, service: IBinder) { override def onServiceConnected(name: ComponentName, service: IBinder) {
service.linkToDeath(new ShadowsocksDeathRecipient(ServiceBoundContext.this), 0)
bgService = IShadowsocksService.Stub.asInterface(service) bgService = IShadowsocksService.Stub.asInterface(service)
bgService.asBinder().linkToDeath(new ShadowsocksDeathRecipient(outer), 0)
registerCallback registerCallback
ServiceBoundContext.this.onServiceConnected() ServiceBoundContext.this.onServiceConnected()
} }
...@@ -26,18 +26,18 @@ trait ServiceBoundContext extends Context { outer => ...@@ -26,18 +26,18 @@ trait ServiceBoundContext extends Context { outer =>
} }
} }
def registerCallback = if (bgService != null && callback != null && !callbackRegistered) try { protected def registerCallback = if (bgService != null && callback != null && !callbackRegistered) try {
bgService.registerCallback(callback) bgService.registerCallback(callback)
callbackRegistered = true callbackRegistered = true
} catch { } catch {
case ignored: RemoteException => // Nothing case ignored: RemoteException => // Nothing
} }
def unregisterCallback = if (bgService != null && callback != null && callbackRegistered) try { protected def unregisterCallback = {
bgService.unregisterCallback(callback) if (bgService != null && callback != null && callbackRegistered) try bgService.unregisterCallback(callback) catch {
case ignored: RemoteException =>
}
callbackRegistered = false callbackRegistered = false
} catch {
case ignored: RemoteException => callbackRegistered = false
} }
def onServiceConnected() = () def onServiceConnected() = ()
...@@ -66,16 +66,12 @@ trait ServiceBoundContext extends Context { outer => ...@@ -66,16 +66,12 @@ trait ServiceBoundContext extends Context { outer =>
} }
def deattachService() { def deattachService() {
if (bgService != null) { unregisterCallback
if (callback != null) { callback = null
unregisterCallback if (connection != null) {
callback = null unbindService(connection)
} connection = null
if (connection != null) {
unbindService(connection)
connection = null
}
bgService = null
} }
bgService = null
} }
} }
...@@ -318,8 +318,6 @@ class Shadowsocks ...@@ -318,8 +318,6 @@ class Shadowsocks
changeSwitch(checked = false) changeSwitch(checked = false)
} }
def isReady: Boolean = checkText(Key.proxy) && checkText(Key.sitekey) && bgService != null
def prepareStartService() { def prepareStartService() {
ThrowableFuture { ThrowableFuture {
if (ShadowsocksApplication.isVpnEnabled) { if (ShadowsocksApplication.isVpnEnabled) {
...@@ -358,18 +356,9 @@ class Shadowsocks ...@@ -358,18 +356,9 @@ class Shadowsocks
fab = findViewById(R.id.fab).asInstanceOf[FloatingActionButton] fab = findViewById(R.id.fab).asInstanceOf[FloatingActionButton]
fabProgressCircle = findViewById(R.id.fabProgressCircle).asInstanceOf[FABProgressCircle] fabProgressCircle = findViewById(R.id.fabProgressCircle).asInstanceOf[FABProgressCircle]
fab.setOnClickListener((v: View) => { fab.setOnClickListener((v: View) => if (serviceStarted) serviceStop()
serviceStarted = !serviceStarted else if (checkText(Key.proxy) && checkText(Key.sitekey) && bgService != null) prepareStartService()
serviceStarted match { else changeSwitch(checked = false))
case true =>
if (isReady)
prepareStartService()
else
changeSwitch(checked = false)
case false =>
serviceStop()
}
})
fab.setOnLongClickListener((v: View) => { fab.setOnLongClickListener((v: View) => {
Utils.positionToast(Toast.makeText(this, if (serviceStarted) R.string.stop else R.string.connect, Utils.positionToast(Toast.makeText(this, if (serviceStarted) R.string.stop else R.string.connect,
Toast.LENGTH_SHORT), fab, getWindow, 0, Utils.dpToPx(this, 8)).show Toast.LENGTH_SHORT), fab, getWindow, 0, Utils.dpToPx(this, 8)).show
......
...@@ -18,8 +18,8 @@ class ShadowsocksDeathRecipient(val mContext: ServiceBoundContext) ...@@ -18,8 +18,8 @@ class ShadowsocksDeathRecipient(val mContext: ServiceBoundContext)
mContext match { mContext match {
case ss: Shadowsocks => case ss: Shadowsocks =>
inShadowsocks(mContext) { inShadowsocks(mContext) {
ss.unregisterCallback ss.deattachService
ss.bindToService() ss.attachService
} }
case _ => case _ =>
} }
......
...@@ -4,11 +4,14 @@ package com.github.shadowsocks.utils ...@@ -4,11 +4,14 @@ package com.github.shadowsocks.utils
* @author Mygod * @author Mygod
*/ */
object CloseUtils { object CloseUtils {
type Closeable = {
def close()
}
type Disconnectable = { type Disconnectable = {
def disconnect() def disconnect()
} }
def autoClose[A <: AutoCloseable, B](x: => A)(block: A => B): B = { def autoClose[A <: Closeable, B](x: => A)(block: A => B): B = {
var a: Option[A] = None var a: Option[A] = None
try { try {
a = Some(x) a = Some(x)
......
...@@ -3,41 +3,32 @@ package com.github.shadowsocks.utils ...@@ -3,41 +3,32 @@ package com.github.shadowsocks.utils
import java.io.{BufferedReader, FileInputStream, InputStreamReader} import java.io.{BufferedReader, FileInputStream, InputStreamReader}
import android.content.Context import android.content.Context
import com.github.shadowsocks.utils.IOUtils._ import com.github.shadowsocks.utils.CloseUtils._
/** /**
* @author chentaov5@gmail.com * @author chentaov5@gmail.com
*/ */
object ProcessUtils { object ProcessUtils {
def getCurrentProcessName = autoClose(new FileInputStream("/proc/self/cmdline")) { inputStream =>
def getCurrentProcessName: String = { autoClose(new BufferedReader(new InputStreamReader(inputStream))) { reader =>
inSafe { val sb = new StringBuilder
val inputStream = new FileInputStream("/proc/self/cmdline") var c = 0
val reader = new BufferedReader(new InputStreamReader(inputStream)) while ({c = reader.read(); c > 0}) sb.append(c.asInstanceOf[Char])
autoClose(reader) { sb.toString()
val sb = new StringBuilder
var c: Int = 0
while({c = reader.read(); c > 0})
sb.append(c.asInstanceOf[Char])
sb.toString()
}
} match {
case Some(name: String) => name
case None => ""
} }
} }
def inShadowsocks[A](context: Context)(fun: => A): Unit = { def inShadowsocks(context: Context)(fun: => Unit) {
if (context != null && getCurrentProcessName.equals(context.getPackageName)) fun if (context != null && getCurrentProcessName.equals(context.getPackageName)) fun
} }
def inVpn[A](context: Context)(fun: => A): Unit = { def inVpn(context: Context)(fun: => Unit) {
if (context != null && getCurrentProcessName.equals(context.getPackageName + ":vpn")) fun if (context != null && getCurrentProcessName.equals(context.getPackageName + ":vpn")) fun
} }
def inNat[A](context: Context)(fun: => A): Unit = { def inNat(context: Context)(fun: => Unit) {
if (context != null && getCurrentProcessName.equals(context.getPackageName + ":nat")) fun if (context != null && getCurrentProcessName.equals(context.getPackageName + ":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