Refine ShadowsocksDeathRecipient and ServiceBoundContext
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 _ =>
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user