diff --git a/src/main/java/com/github/shadowsocks/IStateService.aidl b/src/main/java/com/github/shadowsocks/IStateService.aidl deleted file mode 100644 index f2b336f8..00000000 --- a/src/main/java/com/github/shadowsocks/IStateService.aidl +++ /dev/null @@ -1,6 +0,0 @@ -package com.github.shadowsocks; - -interface IStateService { - int getState(); - String getMessage(); -} diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 3ca82a4c..3068d60b 100755 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -9,7 +9,7 @@ Enable / Disable Proxy - Shadowsocks Settings + Server Settings Server Hostname of your Shadowsocks server Remote Port diff --git a/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala index d7359996..83b4f9d5 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala @@ -63,7 +63,6 @@ class ShadowVpnService extends VpnService { val TAG = "ShadowVpnService" val BASE = "/data/data/com.github.shadowsocks/" val SHADOWSOCKS_CONF = "{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}" - val MSG_CONNECT_START = 0 val MSG_CONNECT_FINISH = 1 val MSG_CONNECT_SUCCESS = 2 val MSG_CONNECT_FAIL = 3 @@ -103,30 +102,27 @@ class ShadowVpnService extends VpnService { if (state != s) { state = s if (m != null) message = m - sendBroadcast(new Intent(Utils.ACTION_UPDATE_STATE)) + val intent = new Intent(Action.UPDATE_STATE) + intent.putExtra(Extra.STATE, state) + intent.putExtra(Extra.MESSAGE, message) + sendBroadcast(intent) } } val handler: Handler = new Handler { override def handleMessage(msg: Message) { - val ed: SharedPreferences.Editor = settings.edit msg.what match { - case MSG_CONNECT_START => - changeState(State.CONNECTING) case MSG_CONNECT_SUCCESS => changeState(State.CONNECTED) - ed.putBoolean("isRunning", true) case MSG_CONNECT_FAIL => - changeState(State.FAILED) - ed.putBoolean("isRunning", false) + changeState(State.STOPPED) case MSG_VPN_ERROR => - if (msg.obj != null) changeState(State.FAILED, msg.obj.asInstanceOf[String]) + if (msg.obj != null) changeState(State.STOPPED, msg.obj.asInstanceOf[String]) case MSG_STOP_SELF => destroy() stopSelf() case _ => } - ed.commit super.handleMessage(msg) } } @@ -185,6 +181,10 @@ class ShadowVpnService extends VpnService { return } + settings.edit().putBoolean("isRunning", true).commit() + + changeState(State.CONNECTING) + appHost = settings.getString("proxy", "127.0.0.1") if (appHost == "198.199.101.152") { appHost = "s.maxcdn.info" @@ -213,9 +213,9 @@ class ShadowVpnService extends VpnService { if (isHTTPProxy) { localPort -= 1 } + new Thread(new Runnable { def run() { - handler.sendEmptyMessage(MSG_CONNECT_START) killProcesses() @@ -384,16 +384,7 @@ class ShadowVpnService extends VpnService { if (VpnService.SERVICE_INTERFACE == action) { return super.onBind(intent) } - - new IStateService.Stub { - def getMessage: String = { - val m = message - message = null - m - } - - def getState: Int = state - } + null } override def onCreate() { @@ -407,7 +398,7 @@ class ShadowVpnService extends VpnService { // register close receiver val filter = new IntentFilter() filter.addAction(Intent.ACTION_SHUTDOWN) - filter.addAction(Utils.ACTION_CLOSE) + filter.addAction(Action.CLOSE) receiver = new BroadcastReceiver { def onReceive(p1: Context, p2: Intent) { destroy() @@ -419,6 +410,7 @@ class ShadowVpnService extends VpnService { def destroy() { changeState(State.STOPPED) + settings.edit.putBoolean("isRunning", false).commit EasyTracker.getTracker.sendEvent(TAG, "stop", getVersionName, 0L) if (receiver != null) { unregisterReceiver(receiver) @@ -429,9 +421,6 @@ class ShadowVpnService extends VpnService { killProcesses() } }.start() - val ed: SharedPreferences.Editor = settings.edit - ed.putBoolean("isRunning", false) - ed.commit if (conn != null) { conn.close() conn = null diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 93cf4e96..147dc9fc 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -94,10 +94,10 @@ object Shadowsocks { } } - override def onStart() { - super.onStart() + override def onCreate(bundle: Bundle) { + super.onCreate(bundle) val filter = new IntentFilter() - filter.addAction(Utils.ACTION_UPDATE_FRAGMENT) + filter.addAction(Action.UPDATE_FRAGMENT) receiver = new BroadcastReceiver { def onReceive(p1: Context, p2: Intent) { setPreferenceEnabled() @@ -106,8 +106,8 @@ object Shadowsocks { getActivity.getApplicationContext.registerReceiver(receiver, filter) } - override def onStop() { - super.onStop() + override def onDestroy() { + super.onDestroy() getActivity.getApplicationContext.unregisterReceiver(receiver) } @@ -144,10 +144,10 @@ object Shadowsocks { } } - override def onStart() { - super.onStart() + override def onCreate(bundle: Bundle) { + super.onCreate(bundle) val filter = new IntentFilter() - filter.addAction(Utils.ACTION_UPDATE_FRAGMENT) + filter.addAction(Action.UPDATE_FRAGMENT) receiver = new BroadcastReceiver { def onReceive(p1: Context, p2: Intent) { setPreferenceEnabled() @@ -156,8 +156,8 @@ object Shadowsocks { getActivity.getApplicationContext.registerReceiver(receiver, filter) } - override def onStop() { - super.onStop() + override def onDestroy() { + super.onDestroy() getActivity.getApplicationContext.unregisterReceiver(receiver) } @@ -207,21 +207,8 @@ class Shadowsocks private var settings: SharedPreferences = null private var prepared = false private var state = State.INIT - private var binder: IStateService = null private var receiver: StateBroadcastReceiver = null - private val connection = new ServiceConnection { - def onServiceDisconnected(name: ComponentName) { - onStateChanged(binder.getState, binder.getMessage) - binder = null - } - - def onServiceConnected(name: ComponentName, s: IBinder) { - binder = IStateService.Stub.asInterface(s) - onStateChanged(binder.getState, binder.getMessage) - } - } - private val handler: Handler = new Handler { override def handleMessage(msg: Message) { val ed: SharedPreferences.Editor = settings.edit @@ -356,7 +343,8 @@ class Shadowsocks override def onCreate(savedInstanceState: Bundle) { setHeaderRes(R.xml.shadowsocks_headers) super.onCreate(savedInstanceState) - val switchLayout: RelativeLayout = getLayoutInflater + + val switchLayout = getLayoutInflater .inflate(R.layout.layout_switch, null) .asInstanceOf[RelativeLayout] getSupportActionBar.setCustomView(switchLayout) @@ -364,12 +352,15 @@ class Shadowsocks getSupportActionBar.setDisplayShowCustomEnabled(true) getSupportActionBar.setDisplayShowHomeEnabled(false) - switchButton = switchLayout.findViewById(R.id.switchButton).asInstanceOf[Switch] val title: TextView = switchLayout.findViewById(R.id.title).asInstanceOf[TextView] val tf: Typeface = Typefaces.get(this, "fonts/Iceland.ttf") if (tf != null) title.setTypeface(tf) title.setText(R.string.app_name) + + switchButton = switchLayout.findViewById(R.id.switchButton).asInstanceOf[Switch] settings = PreferenceManager.getDefaultSharedPreferences(this) + receiver = new StateBroadcastReceiver() + registerReceiver(receiver, new IntentFilter(Action.UPDATE_STATE)) val init: Boolean = !settings.getBoolean("isRunning", false) && !settings.getBoolean("isConnecting", false) @@ -464,11 +455,9 @@ class Shadowsocks .build() switchButton.setEnabled(false) Crouton.makeText(Shadowsocks.this, R.string.vpn_status, style).show() - if (binder == null) bindService(new Intent(this, classOf[ShadowVpnService]), connection, 0) - } else { - if (binder == null) bindService(new Intent(this, classOf[ShadowsocksService]), connection, 0) } setPreferenceEnabled(false) + onStateChanged(State.CONNECTED, null) } else { switchButton.setEnabled(true) switchButton.setChecked(false) @@ -482,6 +471,7 @@ class Shadowsocks } }.start() } + onStateChanged(State.STOPPED, null) } } @@ -512,14 +502,11 @@ class Shadowsocks override def onStart() { super.onStart() - receiver = new StateBroadcastReceiver() - registerReceiver(receiver, new IntentFilter(Utils.ACTION_UPDATE_STATE)) EasyTracker.getInstance.activityStart(this) } override def onStop() { super.onStop() - unregisterReceiver(receiver) EasyTracker.getInstance.activityStop(this) if (progressDialog != null) { progressDialog.dismiss() @@ -530,7 +517,7 @@ class Shadowsocks override def onDestroy() { super.onDestroy() Crouton.cancelAllCroutons() - if (binder != null) unbindService(connection) + unregisterReceiver(receiver) } def reset() { @@ -589,7 +576,7 @@ class Shadowsocks stopService(new Intent(this, classOf[ShadowVpnService])) } if (ShadowsocksService.isServiceStarted(this)) { - sendBroadcast(new Intent(Utils.ACTION_CLOSE)) + sendBroadcast(new Intent(Action.CLOSE)) } } @@ -617,7 +604,6 @@ class Shadowsocks if (ShadowVpnService.isServiceStarted(this)) return false val it: Intent = new Intent(this, classOf[ShadowVpnService]) startService(it) - bindService(it, connection, 0) val style = new Style.Builder() .setBackgroundColorValue(Style.holoBlueLight) .setDuration(Style.DURATION_INFINITE) @@ -628,7 +614,6 @@ class Shadowsocks if (ShadowsocksService.isServiceStarted(this)) return false val it: Intent = new Intent(this, classOf[ShadowsocksService]) startService(it) - bindService(it, connection, 0) } true } @@ -702,7 +687,7 @@ class Shadowsocks if (!switchButton.isChecked) switchButton.setChecked(true) setPreferenceEnabled(false) } - case State.FAILED => { + case State.STOPPED => { clearDialog() if (switchButton.isChecked) { switchButton.setEnabled(true) @@ -719,24 +704,16 @@ class Shadowsocks } setPreferenceEnabled(true) } - case State.STOPPED => { - clearDialog() - Crouton.cancelAllCroutons() - if (switchButton.isChecked) switchButton.setChecked(false) - setPreferenceEnabled(true) - } } - sendBroadcast(new Intent(Utils.ACTION_UPDATE_FRAGMENT)) + sendBroadcast(new Intent(Action.UPDATE_FRAGMENT)) } } class StateBroadcastReceiver extends BroadcastReceiver { override def onReceive(context: Context, intent: Intent) { - if (binder != null) { - val s = binder.getState - val m = binder.getMessage - onStateChanged(s, m) - } + val state = intent.getIntExtra(Extra.STATE, State.INIT) + val message = intent.getStringExtra(Extra.MESSAGE) + onStateChanged(state, message) } } } diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala index 84ab5ca4..f740f8e4 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala @@ -90,7 +90,6 @@ class ShadowsocksService extends Service { "-j DNAT --to-destination 127.0.0.1:8123\n" val DNS_PORT = 8153 - val MSG_CONNECT_START = 0 val MSG_CONNECT_FINISH = 1 val MSG_CONNECT_SUCCESS = 2 val MSG_CONNECT_FAIL = 3 @@ -128,7 +127,9 @@ class ShadowsocksService extends Service { private def changeState(s: Int) { if (state != s) { state = s - sendBroadcast(new Intent(Utils.ACTION_UPDATE_STATE)) + val intent = new Intent(Action.UPDATE_STATE) + intent.putExtra(Extra.STATE, state) + sendBroadcast(intent) } } @@ -136,14 +137,11 @@ class ShadowsocksService extends Service { override def handleMessage(msg: Message) { val ed: SharedPreferences.Editor = settings.edit msg.what match { - case MSG_CONNECT_START => - changeState(State.CONNECTING) case MSG_CONNECT_SUCCESS => changeState(State.CONNECTED) ed.putBoolean("isRunning", true) case MSG_CONNECT_FAIL => - changeState(State.FAILED) - ed.putBoolean("isRunning", false) + changeState(State.STOPPED) case MSG_STOP_SELF => stopSelf() case _ => @@ -219,6 +217,8 @@ class ShadowsocksService extends Service { return } + changeState(State.CONNECTING) + appHost = settings.getString("proxy", "127.0.0.1") if (appHost == "198.199.101.152") { appHost = "s.maxcdn.info" @@ -249,7 +249,6 @@ class ShadowsocksService extends Service { } new Thread(new Runnable { def run() { - handler.sendEmptyMessage(MSG_CONNECT_START) killProcesses() @@ -341,7 +340,7 @@ class ShadowsocksService extends Service { val openIntent: Intent = new Intent(this, classOf[Shadowsocks]) openIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) val contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, openIntent, 0) - val closeIntent: Intent = new Intent(Utils.ACTION_CLOSE) + val closeIntent: Intent = new Intent(Action.CLOSE) val actionIntent: PendingIntent = PendingIntent.getBroadcast(this, 0, closeIntent, 0) val builder: NotificationCompat.Builder = new NotificationCompat.Builder(this) builder @@ -373,10 +372,7 @@ class ShadowsocksService extends Service { } def onBind(intent: Intent): IBinder = { - new IStateService.Stub { - def getMessage: String = null - def getState: Int = state - } + null } override def onCreate() { @@ -410,7 +406,7 @@ class ShadowsocksService extends Service { // register close receiver val filter = new IntentFilter() filter.addAction(Intent.ACTION_SHUTDOWN) - filter.addAction(Utils.ACTION_CLOSE) + filter.addAction(Action.CLOSE) receiver = new BroadcastReceiver() { def onReceive(p1: Context, p2: Intent) { stopSelf() diff --git a/src/main/scala/com/github/shadowsocks/Utils.scala b/src/main/scala/com/github/shadowsocks/Utils.scala index f30218b5..44b5683b 100644 --- a/src/main/scala/com/github/shadowsocks/Utils.scala +++ b/src/main/scala/com/github/shadowsocks/Utils.scala @@ -54,18 +54,24 @@ import android.app.ActivityManager object State { val INIT = 0 - val CONNECTED = 1 - val CONNECTING = 2 - val FAILED = 3 - val STOPPED = 4 + val CONNECTING = 1 + val CONNECTED = 2 + val STOPPED = 3 +} + +object Action { + val CLOSE = "com.github.shadowsocks.ACTION_SHUTDOWN" + val UPDATE_STATE = "com.github.shadowsocks.ACTION_UPDATE_STATE" + val UPDATE_FRAGMENT = "com.github.shadowsocks.ACTION_UPDATE_FRAGMENT" +} + +object Extra { + val STATE = "state" + val MESSAGE = "message" } object Utils { - val ACTION_CLOSE = "com.github.shadowsocks.ACTION_SHUTDOWN" - val ACTION_UPDATE_STATE = "com.github.shadowsocks.ACTION_UPDATE_STATE" - val ACTION_UPDATE_FRAGMENT = "com.github.shadowsocks.ACTION_UPDATE_FRAGMENT" - val TAG: String = "Shadowsocks" val ABI_PROP: String = "ro.product.cpu.abi" val ABI2_PROP: String = "ro.product.cpu.abi2"