Commit 36cdcdac authored by Max Lv's avatar Max Lv

fix some issues

parent c4833ddb
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
</activity> </activity>
<activity <activity
android:name=".ShadowVpnActivity" android:name=".ShadowsocksRunnerActivity"
android:theme="@style/PopupTheme" android:theme="@style/PopupTheme"
android:launchMode="singleTask"> android:launchMode="singleTask">
</activity> </activity>
......
...@@ -531,7 +531,6 @@ class Shadowsocks ...@@ -531,7 +531,6 @@ class Shadowsocks
onContentChanged() onContentChanged()
} }
/** Called when the activity is first created. */
override def onCreate(savedInstanceState: Bundle) { override def onCreate(savedInstanceState: Bundle) {
// Initialize the preference // Initialize the preference
...@@ -580,17 +579,22 @@ class Shadowsocks ...@@ -580,17 +579,22 @@ class Shadowsocks
// Register broadcast receiver // Register broadcast receiver
registerReceiver(preferenceReceiver, new IntentFilter(Action.UPDATE_PREFS)) registerReceiver(preferenceReceiver, new IntentFilter(Action.UPDATE_PREFS))
// Bind to the service }
spawn {
status.edit.putBoolean(Key.isRoot, Utils.getRoot).apply() def attachService() {
handler.post(new Runnable { if (bgService == null) {
override def run() { val isRoot = status.getBoolean(Key.isRoot, false)
val isRoot = status.getBoolean(Key.isRoot, false) val s = if (isRoot) classOf[ShadowsocksNatService] else classOf[ShadowsocksVpnService]
val s = if (isRoot) classOf[ShadowsocksNatService] else classOf[ShadowsocksVpnService] bindService(new Intent(s.getName), connection, Context.BIND_AUTO_CREATE)
bindService(new Intent(s.getName), connection, Context.BIND_AUTO_CREATE) startService(new Intent(Shadowsocks.this, s))
startService(new Intent(Shadowsocks.this, s)) }
} }
})
def deattachService() {
if (bgService != null) {
bgService.unregisterCallback(callback)
unbindService(connection)
bgService = null
} }
} }
...@@ -806,11 +810,22 @@ class Shadowsocks ...@@ -806,11 +810,22 @@ class Shadowsocks
protected override def onPause() { protected override def onPause() {
super.onPause() super.onPause()
deattachService()
prepared = false prepared = false
} }
protected override def onResume() { protected override def onResume() {
super.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()
}
})
}
ConfigUtils.refresh(this) ConfigUtils.refresh(this)
} }
...@@ -860,10 +875,6 @@ class Shadowsocks ...@@ -860,10 +875,6 @@ class Shadowsocks
override def onDestroy() { override def onDestroy() {
super.onDestroy() super.onDestroy()
if (bgService != null) {
bgService.unregisterCallback(callback)
unbindService(connection)
}
Crouton.cancelAllCroutons() Crouton.cancelAllCroutons()
unregisterReceiver(preferenceReceiver) unregisterReceiver(preferenceReceiver)
new BackupManager(this).dataChanged() new BackupManager(this).dataChanged()
...@@ -913,6 +924,7 @@ class Shadowsocks ...@@ -913,6 +924,7 @@ class Shadowsocks
} }
case _ => case _ =>
clearDialog() clearDialog()
switchButton.setChecked(false)
Log.e(Shadowsocks.TAG, "Failed to start VpnService") Log.e(Shadowsocks.TAG, "Failed to start VpnService")
} }
} }
...@@ -921,7 +933,7 @@ class Shadowsocks ...@@ -921,7 +933,7 @@ class Shadowsocks
def isVpnEnabled: Boolean = { def isVpnEnabled: Boolean = {
if (Shadowsocks.vpnEnabled < 0) { if (Shadowsocks.vpnEnabled < 0) {
Shadowsocks.vpnEnabled = if (Build.VERSION.SDK_INT Shadowsocks.vpnEnabled = if (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.ICE_CREAM_SANDWICH && !Utils.getRoot) { >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && !status.getBoolean(Key.isRoot, false)) {
1 1
} else { } else {
0 0
......
...@@ -57,6 +57,7 @@ import org.apache.http.conn.util.InetAddressUtils ...@@ -57,6 +57,7 @@ import org.apache.http.conn.util.InetAddressUtils
import scala.collection._ import scala.collection._
import java.util.{TimerTask, Timer} import java.util.{TimerTask, Timer}
import android.net.TrafficStats import android.net.TrafficStats
import scala.concurrent.ops._
import com.github.shadowsocks.utils._ import com.github.shadowsocks.utils._
import scala.Some import scala.Some
import android.graphics.Color import android.graphics.Color
...@@ -208,7 +209,7 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -208,7 +209,7 @@ class ShadowsocksNatService extends Service with BaseService {
if (rate >= 0) { if (rate >= 0) {
val bitmap = Utils val bitmap = Utils
.getBitmap(rate.toString, icon.getIntrinsicWidth * 4, icon.getIntrinsicHeight * 4, .getBitmap(rate.toString, icon.getIntrinsicWidth * 4, icon.getIntrinsicHeight * 4,
Color.TRANSPARENT) Color.TRANSPARENT)
builder.setLargeIcon(bitmap) builder.setLargeIcon(bitmap)
if (rate < 1000) { if (rate < 1000) {
...@@ -421,7 +422,7 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -421,7 +422,7 @@ class ShadowsocksNatService extends Service with BaseService {
override def startRunner(c: Config) { override def startRunner(c: Config) {
var config = c config = c
// register close receiver // register close receiver
val filter = new IntentFilter() val filter = new IntentFilter()
...@@ -474,46 +475,48 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -474,46 +475,48 @@ class ShadowsocksNatService extends Service with BaseService {
timer.schedule(task, TIMER_INTERVAL * 1000, TIMER_INTERVAL * 1000) timer.schedule(task, TIMER_INTERVAL * 1000, TIMER_INTERVAL * 1000)
} }
if (config.proxy == "198.199.101.152") { spawn {
val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer if (config.proxy == "198.199.101.152") {
try { val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer
config = ConfigUtils.getPublicConfig(getBaseContext, container, config) try {
} catch { config = ConfigUtils.getPublicConfig(getBaseContext, container, config)
case ex: Exception => } catch {
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) case ex: Exception =>
stopRunner() notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
handler.sendEmptyMessageDelayed(Msg.CONNECT_FAIL, 500) stopRunner()
return handler.sendEmptyMessageDelayed(Msg.CONNECT_FAIL, 500)
return
}
} }
}
killProcesses() killProcesses()
var resolved: Boolean = false var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(config.proxy) && if (!InetAddressUtils.isIPv4Address(config.proxy) &&
!InetAddressUtils.isIPv6Address(config.proxy)) { !InetAddressUtils.isIPv6Address(config.proxy)) {
Utils.resolve(config.proxy, enableIPv6 = true) match { Utils.resolve(config.proxy, enableIPv6 = true) match {
case Some(a) => case Some(a) =>
config.proxy = a config.proxy = a
resolved = true resolved = true
case None => resolved = false case None => resolved = false
}
} else {
resolved = true
} }
} else {
resolved = true
}
hasRedirectSupport = Utils.getHasRedirectSupport hasRedirectSupport = Utils.getHasRedirectSupport
if (resolved && handleConnection) { if (resolved && handleConnection) {
notifyForegroundAlert(getString(R.string.forward_success), notifyForegroundAlert(getString(R.string.forward_success),
getString(R.string.service_running).format(config.profileName)) getString(R.string.service_running).format(config.profileName))
handler.sendEmptyMessageDelayed(Msg.CONNECT_SUCCESS, 500) handler.sendEmptyMessageDelayed(Msg.CONNECT_SUCCESS, 500)
} else { } else {
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
stopRunner() stopRunner()
handler.sendEmptyMessageDelayed(Msg.CONNECT_FAIL, 500) handler.sendEmptyMessageDelayed(Msg.CONNECT_FAIL, 500)
}
handler.sendEmptyMessageDelayed(Msg.CONNECT_FINISH, 500)
} }
handler.sendEmptyMessageDelayed(Msg.CONNECT_FINISH, 500)
} }
override def stopRunner() { override def stopRunner() {
......
...@@ -64,8 +64,7 @@ class ShadowsocksReceiver extends BroadcastReceiver { ...@@ -64,8 +64,7 @@ class ShadowsocksReceiver extends BroadcastReceiver {
val isAutoConnect: Boolean = settings.getBoolean(Key.isAutoConnect, false) val isAutoConnect: Boolean = settings.getBoolean(Key.isAutoConnect, false)
val isInstalled: Boolean = status.getBoolean(versionName, false) val isInstalled: Boolean = status.getBoolean(versionName, false)
if (isAutoConnect && isInstalled) { if (isAutoConnect && isInstalled) {
if (Utils.getRoot) { context.startActivity(new Intent(context, classOf[ShadowsocksRunnerActivity]))
}
} }
} }
} }
...@@ -42,41 +42,68 @@ package com.github.shadowsocks ...@@ -42,41 +42,68 @@ package com.github.shadowsocks
import android.app.Activity import android.app.Activity
import android.os.{IBinder, Bundle} import android.os.{IBinder, Bundle}
import android.net.VpnService import android.net.VpnService
import android.content.{ComponentName, ServiceConnection, Intent} import android.content.{Context, ComponentName, ServiceConnection, Intent}
import android.util.Log import android.util.Log
import android.preference.PreferenceManager import android.preference.PreferenceManager
import com.github.shadowsocks.utils._ import com.github.shadowsocks.utils._
import com.github.shadowsocks.aidl.IShadowsocksService import com.github.shadowsocks.aidl.IShadowsocksService
class ShadowVpnActivity extends Activity { class ShadowsocksRunnerActivity extends Activity {
lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
lazy val isRoot = Utils.getRoot
// Services // Services
var bgService: IShadowsocksService = null var bgService: IShadowsocksService = null
val connection = new ServiceConnection { val connection = new ServiceConnection {
override def onServiceConnected(name: ComponentName, service: IBinder) { override def onServiceConnected(name: ComponentName, service: IBinder) {
bgService = IShadowsocksService.Stub.asInterface(service) bgService = IShadowsocksService.Stub.asInterface(service)
if (!isRoot) {
val intent = VpnService.prepare(ShadowsocksRunnerActivity.this)
if (intent != null) {
startActivityForResult(intent, Shadowsocks.REQUEST_CONNECT)
} else {
onActivityResult(Shadowsocks.REQUEST_CONNECT, Activity.RESULT_OK, null)
}
} else {
bgService.start(ConfigUtils.load(settings))
}
} }
override def onServiceDisconnected(name: ComponentName) { override def onServiceDisconnected(name: ComponentName) {
bgService = null bgService = null
} }
} }
def attachService() {
if (bgService == null) {
val s = if (isRoot) classOf[ShadowsocksNatService] else classOf[ShadowsocksVpnService]
bindService(new Intent(s.getName), connection, Context.BIND_AUTO_CREATE)
startService(new Intent(this, s))
}
}
def deattachService() {
if (bgService != null) {
unbindService(connection)
bgService = null
}
}
override def onCreate(savedInstanceState: Bundle) { override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val intent = VpnService.prepare(this) attachService()
if (intent != null) { }
startActivityForResult(intent, Shadowsocks.REQUEST_CONNECT)
} else { override def onDestroy() {
onActivityResult(Shadowsocks.REQUEST_CONNECT, Activity.RESULT_OK, null) super.onDestroy()
} deattachService()
} }
override def onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { override def onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
resultCode match { resultCode match {
case Activity.RESULT_OK => case Activity.RESULT_OK =>
if (bgService != null) { if (bgService != null) {
bgService.start(ConfigUtils.load(PreferenceManager.getDefaultSharedPreferences(this))) bgService.start(ConfigUtils.load(settings))
} }
case _ => case _ =>
Log.e(Shadowsocks.TAG, "Failed to start VpnService") Log.e(Shadowsocks.TAG, "Failed to start VpnService")
......
...@@ -51,11 +51,12 @@ import java.io._ ...@@ -51,11 +51,12 @@ import java.io._
import android.net.VpnService import android.net.VpnService
import org.apache.http.conn.util.InetAddressUtils import org.apache.http.conn.util.InetAddressUtils
import android.os.Message import android.os.Message
import scala.concurrent.ops._
import org.apache.commons.net.util.SubnetUtils import org.apache.commons.net.util.SubnetUtils
import java.net.InetAddress import java.net.InetAddress
import com.github.shadowsocks.utils._ import com.github.shadowsocks.utils._
import scala.Some import scala.Some
import com.github.shadowsocks.aidl.Config import com.github.shadowsocks.aidl.{IShadowsocksService, Config}
class ShadowsocksVpnService extends VpnService with BaseService { class ShadowsocksVpnService extends VpnService with BaseService {
...@@ -266,6 +267,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -266,6 +267,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
.asInstanceOf[NotificationManager] .asInstanceOf[NotificationManager]
} }
def killProcesses() { def killProcesses() {
...@@ -291,11 +293,11 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -291,11 +293,11 @@ class ShadowsocksVpnService extends VpnService with BaseService {
override def startRunner(c: Config) { override def startRunner(c: Config) {
var config = c config = c
// ensure the VPNService is prepared // ensure the VPNService is prepared
if (VpnService.prepare(this) != null) { if (VpnService.prepare(this) != null) {
val i = new Intent(this, classOf[ShadowVpnActivity]) val i = new Intent(this, classOf[ShadowsocksRunnerActivity])
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(i) startActivity(i)
return return
...@@ -321,44 +323,46 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -321,44 +323,46 @@ class ShadowsocksVpnService extends VpnService with BaseService {
changeState(State.CONNECTING) changeState(State.CONNECTING)
if (config.proxy == "198.199.101.152") { spawn {
val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer if (config.proxy == "198.199.101.152") {
try { val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer
config = ConfigUtils.getPublicConfig(getBaseContext, container, config) try {
} catch { config = ConfigUtils.getPublicConfig(getBaseContext, container, config)
case ex: Exception => } catch {
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) case ex: Exception =>
stopRunner() notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
handler.sendEmptyMessageDelayed(Msg.CONNECT_FAIL, 500) stopRunner()
return handler.sendEmptyMessageDelayed(Msg.CONNECT_FAIL, 500)
return
}
} }
}
// reset the context // reset the context
killProcesses() killProcesses()
// Resolve the server address // Resolve the server address
var resolved: Boolean = false var resolved: Boolean = false
if (!InetAddressUtils.isIPv4Address(config.proxy) && if (!InetAddressUtils.isIPv4Address(config.proxy) &&
!InetAddressUtils.isIPv6Address(config.proxy)) { !InetAddressUtils.isIPv6Address(config.proxy)) {
Utils.resolve(config.proxy, enableIPv6 = true) match { Utils.resolve(config.proxy, enableIPv6 = true) match {
case Some(addr) => case Some(addr) =>
config.proxy = addr config.proxy = addr
resolved = true resolved = true
case None => resolved = false case None => resolved = false
}
} else {
resolved = true
} }
} else {
resolved = true
}
if (resolved && handleConnection) { if (resolved && handleConnection) {
handler.sendEmptyMessageDelayed(Msg.CONNECT_SUCCESS, 300) handler.sendEmptyMessageDelayed(Msg.CONNECT_SUCCESS, 300)
} else { } else {
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
handler.sendEmptyMessageDelayed(Msg.CONNECT_FAIL, 300) handler.sendEmptyMessageDelayed(Msg.CONNECT_FAIL, 300)
stopRunner() stopRunner()
}
handler.sendEmptyMessageDelayed(Msg.CONNECT_FINISH, 300)
} }
handler.sendEmptyMessageDelayed(Msg.CONNECT_FINISH, 300)
} }
override def stopRunner() { override def stopRunner() {
...@@ -394,6 +398,6 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -394,6 +398,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
} }
override def getTag = TAG override def getTag = TAG
override def getServiceMode = Mode.VPN override def getServiceMode = Mode.VPN
} }
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