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