diff --git a/src/main/scala/com/github/shadowsocks/BaseService.scala b/src/main/scala/com/github/shadowsocks/BaseService.scala index 43a22194..fed5ac85 100644 --- a/src/main/scala/com/github/shadowsocks/BaseService.scala +++ b/src/main/scala/com/github/shadowsocks/BaseService.scala @@ -1,11 +1,12 @@ package com.github.shadowsocks -import android.os.RemoteCallbackList +import android.os.{Handler, RemoteCallbackList} import com.github.shadowsocks.aidl.{Config, IShadowsocksService, IShadowsocksServiceCallback} import com.github.shadowsocks.utils.{Path, State} import java.io.{IOException, FileNotFoundException, FileReader, BufferedReader} import android.util.Log import android.app.Notification +import android.content.Context trait BaseService { @@ -43,20 +44,26 @@ trait BaseService { def stopRunner() def getServiceMode: Int def getTag: String + def getContext: Context def changeState(s: Int) { changeState(s, null) } protected def changeState(s: Int, msg: String) { - if (state != s) { - val n = callbacks.beginBroadcast() - for (i <- 0 to n -1) { - callbacks.getBroadcastItem(i).stateChanged(s, msg) + val handler = new Handler(getContext.getMainLooper) + handler.post(new Runnable { + override def run() { + if (state != s) { + val n = callbacks.beginBroadcast() + for (i <- 0 to n -1) { + callbacks.getBroadcastItem(i).stateChanged(s, msg) + } + callbacks.finishBroadcast() + state = s + } } - callbacks.finishBroadcast() - state = s - } + }) } def getPid(name: String): Int = { diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index e6b56db9..d69443a0 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -324,24 +324,12 @@ class Shadowsocks } } Crouton.cancelAllCroutons() - onStateChanged(State.STOPPED, null) setPreferenceEnabled(enabled = true) } else { - if (bgService.getMode == Mode.VPN) { - val style = new Style.Builder().setBackgroundColorValue(Style.holoBlueLight).build() - val config = new Configuration.Builder().setDuration(Configuration.DURATION_LONG).build() - Crouton - .makeText(Shadowsocks.this, R.string.vpn_status, style) - .setConfiguration(config) - .show() - switchButton.setEnabled(false) - } changeSwitch(checked = true) - onStateChanged(bgService.getState, null) setPreferenceEnabled(enabled = false) } - // set the listener - switchButton.setOnCheckedChangeListener(Shadowsocks.this) + state = bgService.getState } override def onServiceDisconnected(name: ComponentName) { @@ -371,6 +359,7 @@ class Shadowsocks } private def changeSwitch (checked: Boolean) { + switchButton.setOnCheckedChangeListener(null) switchButton.setChecked(checked) if (switchButton.isEnabled) { switchButton.setEnabled(false) @@ -378,6 +367,7 @@ class Shadowsocks override def run() { switchButton.setEnabled(true) } }, 1000) } + switchButton.setOnCheckedChangeListener(this) } private def showProgress(msg: String): Handler = { @@ -604,6 +594,16 @@ class Shadowsocks // Register broadcast receiver registerReceiver(preferenceReceiver, new IntentFilter(Action.UPDATE_PREFS)) + // Bind to the service + spawn { + val isRoot = Utils.getRoot + handler.post(new Runnable { + override def run() { + status.edit.putBoolean(Key.isRoot, isRoot).commit() + attachService() + } + }) + } } def attachService() { @@ -835,22 +835,25 @@ class Shadowsocks protected override def onPause() { super.onPause() - deattachService() + switchButton.setOnCheckedChangeListener(null) prepared = false } protected override def onResume() { super.onResume() - // Bind to the service - spawn { - val isRoot = Utils.getRoot - handler.post(new Runnable { - override def run() { - status.edit.putBoolean(Key.isRoot, isRoot).commit() - attachService() - } - }) + if (bgService != null) { + bgService.getState match { + case State.CONNECTED => + changeSwitch(checked = true) + case State.CONNECTING => + changeSwitch(checked = true) + case _ => + changeSwitch(checked = false) + } + state = bgService.getState } + // set the listener + switchButton.setOnCheckedChangeListener(Shadowsocks.this) ConfigUtils.refresh(this) } @@ -900,6 +903,7 @@ class Shadowsocks override def onDestroy() { super.onDestroy() + deattachService() Crouton.cancelAllCroutons() unregisterReceiver(preferenceReceiver) new BackupManager(this).dataChanged() @@ -917,7 +921,6 @@ class Shadowsocks private def recovery() { val h = showProgress(getString(R.string.recovering)) - serviceStop() spawn { reset() @@ -1066,15 +1069,12 @@ class Shadowsocks setPreferenceEnabled(enabled = false) case State.CONNECTED => clearDialog() - if (!switchButton.isChecked) changeSwitch(checked = true) + changeSwitch(checked = true) setPreferenceEnabled(enabled = false) case State.STOPPED => clearDialog() - if (switchButton.isChecked) { - switchButton.setEnabled(true) - changeSwitch(checked = false) - Crouton.cancelAllCroutons() - } + changeSwitch(checked = false) + Crouton.cancelAllCroutons() if (m != null) { Crouton.cancelAllCroutons() val style = new Style.Builder().setBackgroundColorValue(Style.holoRedLight).build() diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala index 445e2141..10fc98c3 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala @@ -550,6 +550,6 @@ class ShadowsocksNatService extends Service with BaseService { } override def getTag = TAG - override def getServiceMode = Mode.NAT + override def getContext = getBaseContext } diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala index 50edf476..ace47e25 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala @@ -399,5 +399,5 @@ class ShadowsocksVpnService extends VpnService with BaseService { override def getTag = TAG override def getServiceMode = Mode.VPN - + override def getContext = getBaseContext }