Using SAM
This commit is contained in:
@@ -297,11 +297,8 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
|
||||
|
||||
val bypassSwitch = findViewById(R.id.bypassSwitch).asInstanceOf[Switch]
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
|
||||
bypassSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener {
|
||||
def onCheckedChanged(button: CompoundButton, checked: Boolean) {
|
||||
prefs.edit().putBoolean(Key.isBypassApps, checked).commit()
|
||||
}
|
||||
})
|
||||
bypassSwitch.setOnCheckedChangeListener((button: CompoundButton, checked: Boolean) =>
|
||||
prefs.edit().putBoolean(Key.isBypassApps, checked).commit())
|
||||
bypassSwitch.setChecked(prefs.getBoolean(Key.isBypassApps, false))
|
||||
|
||||
appListView = findViewById(R.id.applistview).asInstanceOf[ListView]
|
||||
|
||||
@@ -110,23 +110,19 @@ trait BaseService {
|
||||
|
||||
protected def changeState(s: Int, msg: String) {
|
||||
val handler = new Handler(getContext.getMainLooper)
|
||||
handler.post(new Runnable {
|
||||
override def run() {
|
||||
if (state != s) {
|
||||
if (callbackCount > 0) {
|
||||
val n = callbacks.beginBroadcast()
|
||||
for (i <- 0 to n - 1) {
|
||||
try {
|
||||
callbacks.getBroadcastItem(i).stateChanged(s, msg)
|
||||
} catch {
|
||||
case _: Exception => // Ignore
|
||||
}
|
||||
}
|
||||
callbacks.finishBroadcast()
|
||||
handler.post(() => if (state != s) {
|
||||
if (callbackCount > 0) {
|
||||
val n = callbacks.beginBroadcast()
|
||||
for (i <- 0 to n - 1) {
|
||||
try {
|
||||
callbacks.getBroadcastItem(i).stateChanged(s, msg)
|
||||
} catch {
|
||||
case _: Exception => // Ignore
|
||||
}
|
||||
state = s
|
||||
}
|
||||
callbacks.finishBroadcast()
|
||||
}
|
||||
state = s
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -57,21 +57,17 @@ class ParserActivity extends Activity {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.add_profile_dialog)
|
||||
.setCancelable(false)
|
||||
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
override def onClick(dialog: DialogInterface, id: Int) {
|
||||
.setPositiveButton(R.string.yes, ((dialog: DialogInterface, id: Int) => {
|
||||
Parser.parse(data) match {
|
||||
case Some(profile) => addProfile(profile)
|
||||
case _ => // ignore
|
||||
}
|
||||
dialog.dismiss()
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||
override def onClick(dialog: DialogInterface, id: Int) {
|
||||
}): DialogInterface.OnClickListener)
|
||||
.setNegativeButton(R.string.no, ((dialog: DialogInterface, id: Int) => {
|
||||
dialog.dismiss()
|
||||
finish()
|
||||
}
|
||||
})
|
||||
}): DialogInterface.OnClickListener)
|
||||
.setMessage(data)
|
||||
.create()
|
||||
.show()
|
||||
@@ -91,15 +87,13 @@ class ParserActivity extends Activity {
|
||||
|
||||
val h = showProgress(getString(R.string.loading))
|
||||
|
||||
h.postDelayed(new Runnable {
|
||||
def run() {
|
||||
val profileManager =
|
||||
new ProfileManager(PreferenceManager.getDefaultSharedPreferences(getBaseContext),
|
||||
getApplication.asInstanceOf[ShadowsocksApplication].dbHelper)
|
||||
profileManager.createOrUpdateProfile(profile)
|
||||
profileManager.reload(profile.id)
|
||||
h.sendEmptyMessage(0)
|
||||
}
|
||||
h.postDelayed(() => {
|
||||
val profileManager =
|
||||
new ProfileManager(PreferenceManager.getDefaultSharedPreferences(getBaseContext),
|
||||
getApplication.asInstanceOf[ShadowsocksApplication].dbHelper)
|
||||
profileManager.createOrUpdateProfile(profile)
|
||||
profileManager.reload(profile.id)
|
||||
h.sendEmptyMessage(0)
|
||||
}, 600)
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ import android.os._
|
||||
import android.preference._
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.util.{DisplayMetrics, Log}
|
||||
import android.view.View.OnLongClickListener
|
||||
import android.view._
|
||||
import android.webkit.{WebView, WebViewClient}
|
||||
import android.widget._
|
||||
@@ -270,11 +269,7 @@ class Shadowsocks
|
||||
switchButton.setChecked(checked)
|
||||
if (switchButton.isEnabled) {
|
||||
switchButton.setEnabled(false)
|
||||
handler.postDelayed(new Runnable {
|
||||
override def run() {
|
||||
switchButton.setEnabled(true)
|
||||
}
|
||||
}, 1000)
|
||||
handler.postDelayed(() => switchButton.setEnabled(true), 1000)
|
||||
}
|
||||
switchButton.setOnCheckedChangeListener(this)
|
||||
}
|
||||
@@ -434,11 +429,7 @@ class Shadowsocks
|
||||
}
|
||||
if (switchButton.isEnabled) {
|
||||
switchButton.setEnabled(false)
|
||||
handler.postDelayed(new Runnable {
|
||||
override def run() {
|
||||
switchButton.setEnabled(true)
|
||||
}
|
||||
}, 1000)
|
||||
handler.postDelayed(() => switchButton.setEnabled(true), 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,21 +520,19 @@ class Shadowsocks
|
||||
} else {
|
||||
getActionBar.setIcon(R.drawable.ic_stat_shadowsocks)
|
||||
}
|
||||
title.setOnLongClickListener(new OnLongClickListener {
|
||||
override def onLongClick(v: View): Boolean = {
|
||||
if (Utils.isLollipopOrAbove && bgService != null
|
||||
&& (bgService.getState == State.INIT || bgService.getState == State.STOPPED)) {
|
||||
val natEnabled = status.getBoolean(Key.isNAT, false)
|
||||
status.edit().putBoolean(Key.isNAT, !natEnabled).commit()
|
||||
if (!natEnabled) {
|
||||
Toast.makeText(getBaseContext, R.string.enable_nat, Toast.LENGTH_LONG).show()
|
||||
} else {
|
||||
Toast.makeText(getBaseContext, R.string.disable_nat, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
true
|
||||
title.setOnLongClickListener((v: View) => {
|
||||
if (Utils.isLollipopOrAbove && bgService != null
|
||||
&& (bgService.getState == State.INIT || bgService.getState == State.STOPPED)) {
|
||||
val natEnabled = status.getBoolean(Key.isNAT, false)
|
||||
status.edit().putBoolean(Key.isNAT, !natEnabled).commit()
|
||||
if (!natEnabled) {
|
||||
Toast.makeText(getBaseContext, R.string.enable_nat, Toast.LENGTH_LONG).show()
|
||||
} else {
|
||||
false
|
||||
Toast.makeText(getBaseContext, R.string.disable_nat, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -553,11 +542,9 @@ class Shadowsocks
|
||||
// Bind to the service
|
||||
Future {
|
||||
val isRoot = (!Utils.isLollipopOrAbove || status.getBoolean(Key.isNAT, false)) && Console.isRoot
|
||||
handler.post(new Runnable {
|
||||
override def run() {
|
||||
status.edit.putBoolean(Key.isRoot, isRoot).commit()
|
||||
attachService()
|
||||
}
|
||||
handler.post(() => {
|
||||
status.edit.putBoolean(Key.isRoot, isRoot).commit()
|
||||
attachService()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -613,29 +600,23 @@ class Shadowsocks
|
||||
val builder = new AlertDialog.Builder(this)
|
||||
builder
|
||||
.setTitle(R.string.add_profile)
|
||||
.setItems(R.array.add_profile_methods, new DialogInterface.OnClickListener() {
|
||||
def onClick(dialog: DialogInterface, which: Int) {
|
||||
which match {
|
||||
case 0 =>
|
||||
dialog.dismiss()
|
||||
val h = showProgress(R.string.loading)
|
||||
h.postDelayed(new Runnable() {
|
||||
def run() {
|
||||
val integrator = new IntentIntegrator(Shadowsocks.this)
|
||||
val list = new java.util.ArrayList(IntentIntegrator.TARGET_ALL_KNOWN)
|
||||
list.add("tw.com.quickmark")
|
||||
integrator.setTargetApplications(list)
|
||||
integrator.initiateScan()
|
||||
h.sendEmptyMessage(0)
|
||||
}
|
||||
}, 600)
|
||||
case 1 =>
|
||||
dialog.dismiss()
|
||||
addProfile(id)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
})
|
||||
.setItems(R.array.add_profile_methods, ((dialog: DialogInterface, which: Int) => which match {
|
||||
case 0 =>
|
||||
dialog.dismiss()
|
||||
val h = showProgress(R.string.loading)
|
||||
h.postDelayed(() => {
|
||||
val integrator = new IntentIntegrator(Shadowsocks.this)
|
||||
val list = new java.util.ArrayList(IntentIntegrator.TARGET_ALL_KNOWN)
|
||||
list.add("tw.com.quickmark")
|
||||
integrator.setTargetApplications(list)
|
||||
integrator.initiateScan()
|
||||
h.sendEmptyMessage(0)
|
||||
}, 600)
|
||||
case 1 =>
|
||||
dialog.dismiss()
|
||||
addProfile(id)
|
||||
case _ =>
|
||||
}): DialogInterface.OnClickListener)
|
||||
builder.create().show()
|
||||
}
|
||||
|
||||
@@ -644,17 +625,15 @@ class Shadowsocks
|
||||
|
||||
val h = showProgress(R.string.loading)
|
||||
|
||||
handler.postDelayed(new Runnable {
|
||||
def run() {
|
||||
currentProfile = {
|
||||
profileManager.getProfile(settings.getInt(Key.profileId, -1)) getOrElse currentProfile
|
||||
}
|
||||
menuAdapter.updateList(getMenuList, currentProfile.id)
|
||||
|
||||
updatePreferenceScreen()
|
||||
|
||||
h.sendEmptyMessage(0)
|
||||
handler.postDelayed(() => {
|
||||
currentProfile = {
|
||||
profileManager.getProfile(settings.getInt(Key.profileId, -1)) getOrElse currentProfile
|
||||
}
|
||||
menuAdapter.updateList(getMenuList, currentProfile.id)
|
||||
|
||||
updatePreferenceScreen()
|
||||
|
||||
h.sendEmptyMessage(0)
|
||||
}, 600)
|
||||
}
|
||||
|
||||
@@ -663,17 +642,15 @@ class Shadowsocks
|
||||
|
||||
val h = showProgress(R.string.loading)
|
||||
|
||||
handler.postDelayed(new Runnable {
|
||||
def run() {
|
||||
currentProfile = profile
|
||||
profileManager.createOrUpdateProfile(currentProfile)
|
||||
profileManager.reload(currentProfile.id)
|
||||
menuAdapter.updateList(getMenuList, currentProfile.id)
|
||||
handler.postDelayed(() => {
|
||||
currentProfile = profile
|
||||
profileManager.createOrUpdateProfile(currentProfile)
|
||||
profileManager.reload(currentProfile.id)
|
||||
menuAdapter.updateList(getMenuList, currentProfile.id)
|
||||
|
||||
updatePreferenceScreen()
|
||||
updatePreferenceScreen()
|
||||
|
||||
h.sendEmptyMessage(0)
|
||||
}
|
||||
h.sendEmptyMessage(0)
|
||||
}, 600)
|
||||
}
|
||||
|
||||
@@ -682,16 +659,14 @@ class Shadowsocks
|
||||
|
||||
val h = showProgress(R.string.loading)
|
||||
|
||||
handler.postDelayed(new Runnable {
|
||||
def run() {
|
||||
currentProfile = profileManager.reload(id)
|
||||
profileManager.save()
|
||||
menuAdapter.updateList(getMenuList, currentProfile.id)
|
||||
handler.postDelayed(() => {
|
||||
currentProfile = profileManager.reload(id)
|
||||
profileManager.save()
|
||||
menuAdapter.updateList(getMenuList, currentProfile.id)
|
||||
|
||||
updatePreferenceScreen()
|
||||
updatePreferenceScreen()
|
||||
|
||||
h.sendEmptyMessage(0)
|
||||
}
|
||||
h.sendEmptyMessage(0)
|
||||
}, 600)
|
||||
}
|
||||
|
||||
@@ -700,16 +675,14 @@ class Shadowsocks
|
||||
|
||||
val h = showProgress(R.string.loading)
|
||||
|
||||
handler.postDelayed(new Runnable {
|
||||
def run() {
|
||||
currentProfile = profileManager.reload(id)
|
||||
menuAdapter.setActiveId(id)
|
||||
menuAdapter.notifyDataSetChanged()
|
||||
handler.postDelayed(() => {
|
||||
currentProfile = profileManager.reload(id)
|
||||
menuAdapter.setActiveId(id)
|
||||
menuAdapter.notifyDataSetChanged()
|
||||
|
||||
updatePreferenceScreen()
|
||||
updatePreferenceScreen()
|
||||
|
||||
h.sendEmptyMessage(0)
|
||||
}
|
||||
h.sendEmptyMessage(0)
|
||||
}, 600)
|
||||
}
|
||||
|
||||
@@ -723,11 +696,9 @@ class Shadowsocks
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage(String.format(Locale.ENGLISH, getString(R.string.remove_profile), profile.get.name))
|
||||
.setCancelable(false)
|
||||
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
|
||||
override def onClick(dialog: DialogInterface, i: Int) = dialog.cancel()
|
||||
})
|
||||
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
|
||||
override def onClick(dialog: DialogInterface, i: Int) {
|
||||
.setNegativeButton(R.string.no,
|
||||
((dialog: DialogInterface, i: Int) => dialog.cancel()): DialogInterface.OnClickListener)
|
||||
.setPositiveButton(R.string.yes, ((dialog: DialogInterface, i: Int) => {
|
||||
profileManager.delProfile(id)
|
||||
val profileId = {
|
||||
val profiles = profileManager.getAllProfiles.getOrElse(List[Profile]())
|
||||
@@ -739,8 +710,7 @@ class Shadowsocks
|
||||
updatePreferenceScreen()
|
||||
|
||||
dialog.dismiss()
|
||||
}
|
||||
})
|
||||
}): DialogInterface.OnClickListener)
|
||||
.create()
|
||||
.show()
|
||||
|
||||
@@ -953,7 +923,8 @@ class Shadowsocks
|
||||
|
||||
new AlertDialog.Builder(this)
|
||||
.setCancelable(true)
|
||||
.setNegativeButton(getString(R.string.close), (dialog: DialogInterface, id: Int) => dialog.cancel())
|
||||
.setNegativeButton(getString(R.string.close),
|
||||
((dialog: DialogInterface, id: Int) => dialog.cancel()): DialogInterface.OnClickListener)
|
||||
.setView(image)
|
||||
.create()
|
||||
.show()
|
||||
@@ -1064,11 +1035,8 @@ class Shadowsocks
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(getString(R.string.about_title).formatLocal(Locale.ENGLISH, versionName))
|
||||
.setCancelable(false)
|
||||
.setNegativeButton(getString(R.string.ok_iknow), new DialogInterface.OnClickListener() {
|
||||
override def onClick(dialog: DialogInterface, id: Int) {
|
||||
dialog.cancel()
|
||||
}
|
||||
})
|
||||
.setNegativeButton(getString(R.string.ok_iknow),
|
||||
((dialog: DialogInterface, id: Int) => dialog.cancel()): DialogInterface.OnClickListener)
|
||||
.setView(web)
|
||||
.create()
|
||||
.show()
|
||||
@@ -1083,46 +1051,42 @@ class Shadowsocks
|
||||
}
|
||||
|
||||
def onStateChanged(s: Int, m: String) {
|
||||
handler.post(new Runnable {
|
||||
override def run() {
|
||||
if (state != s) {
|
||||
state = s
|
||||
state match {
|
||||
case State.CONNECTING =>
|
||||
if (progressDialog == null) {
|
||||
progressDialog = ProgressDialog
|
||||
.show(Shadowsocks.this, "", getString(R.string.connecting), true, true)
|
||||
progressTag = R.string.connecting
|
||||
}
|
||||
setPreferenceEnabled(enabled = false)
|
||||
case State.CONNECTED =>
|
||||
if (progressTag == R.string.connecting) {
|
||||
clearDialog()
|
||||
}
|
||||
changeSwitch(checked = true)
|
||||
setPreferenceEnabled(enabled = false)
|
||||
case State.STOPPED =>
|
||||
if (progressTag == R.string.stopping || progressTag == R.string.connecting) {
|
||||
clearDialog()
|
||||
}
|
||||
changeSwitch(checked = false)
|
||||
if (m != null) {
|
||||
new SnackBar.Builder(Shadowsocks.this)
|
||||
.withMessage(getString(R.string.vpn_error).formatLocal(Locale.ENGLISH, m))
|
||||
.withActionMessageId(R.string.error)
|
||||
.withStyle(SnackBar.Style.ALERT)
|
||||
.withDuration(SnackBar.LONG_SNACK)
|
||||
.show()
|
||||
}
|
||||
setPreferenceEnabled(enabled = true)
|
||||
case State.STOPPING =>
|
||||
if (progressDialog == null) {
|
||||
progressDialog = ProgressDialog
|
||||
.show(Shadowsocks.this, "", getString(R.string.stopping), true, true)
|
||||
progressTag = R.string.stopping
|
||||
}
|
||||
handler.post(() => if (state != s) {
|
||||
state = s
|
||||
state match {
|
||||
case State.CONNECTING =>
|
||||
if (progressDialog == null) {
|
||||
progressDialog = ProgressDialog
|
||||
.show(Shadowsocks.this, "", getString(R.string.connecting), true, true)
|
||||
progressTag = R.string.connecting
|
||||
}
|
||||
setPreferenceEnabled(enabled = false)
|
||||
case State.CONNECTED =>
|
||||
if (progressTag == R.string.connecting) {
|
||||
clearDialog()
|
||||
}
|
||||
changeSwitch(checked = true)
|
||||
setPreferenceEnabled(enabled = false)
|
||||
case State.STOPPED =>
|
||||
if (progressTag == R.string.stopping || progressTag == R.string.connecting) {
|
||||
clearDialog()
|
||||
}
|
||||
changeSwitch(checked = false)
|
||||
if (m != null) {
|
||||
new SnackBar.Builder(Shadowsocks.this)
|
||||
.withMessage(getString(R.string.vpn_error).formatLocal(Locale.ENGLISH, m))
|
||||
.withActionMessageId(R.string.error)
|
||||
.withStyle(SnackBar.Style.ALERT)
|
||||
.withDuration(SnackBar.LONG_SNACK)
|
||||
.show()
|
||||
}
|
||||
setPreferenceEnabled(enabled = true)
|
||||
case State.STOPPING =>
|
||||
if (progressDialog == null) {
|
||||
progressDialog = ProgressDialog
|
||||
.show(Shadowsocks.this, "", getString(R.string.stopping), true, true)
|
||||
progressTag = R.string.stopping
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ import com.github.shadowsocks.database.DBHelper
|
||||
import com.github.shadowsocks.utils.Utils
|
||||
import com.google.android.gms.analytics.GoogleAnalytics
|
||||
import com.google.android.gms.common.api.ResultCallback
|
||||
import com.google.android.gms.tagmanager.Container.FunctionCallMacroCallback
|
||||
import com.google.android.gms.tagmanager.{ContainerHolder, TagManager}
|
||||
|
||||
class ShadowsocksApplication extends Application {
|
||||
@@ -66,14 +65,13 @@ class ShadowsocksApplication extends Application {
|
||||
}
|
||||
containerHolder = holder
|
||||
val container = holder.getContainer
|
||||
container.registerFunctionCallMacroCallback(SIG_FUNC, new FunctionCallMacroCallback {
|
||||
override def getValue(functionName: String, parameters: util.Map[String, AnyRef]): AnyRef = {
|
||||
container.registerFunctionCallMacroCallback(SIG_FUNC,
|
||||
(functionName: String, parameters: util.Map[String, AnyRef]) => {
|
||||
if (functionName == SIG_FUNC) {
|
||||
Utils.getSignature(getApplicationContext)
|
||||
}
|
||||
null
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
pending.setResultCallback(callback, 2, TimeUnit.SECONDS)
|
||||
|
||||
@@ -173,11 +173,7 @@ class ShadowsocksNatService extends Service with BaseService {
|
||||
|
||||
def initConnectionReceiver() {
|
||||
val filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
|
||||
connReceiver = new BroadcastReceiver {
|
||||
override def onReceive(context: Context, intent: Intent) = {
|
||||
setupDns()
|
||||
}
|
||||
}
|
||||
connReceiver = (context: Context, intent: Intent) => setupDns()
|
||||
registerReceiver(connReceiver, filter)
|
||||
}
|
||||
|
||||
@@ -512,11 +508,9 @@ class ShadowsocksNatService extends Service with BaseService {
|
||||
val filter = new IntentFilter()
|
||||
filter.addAction(Intent.ACTION_SHUTDOWN)
|
||||
filter.addAction(Action.CLOSE)
|
||||
closeReceiver = new BroadcastReceiver() {
|
||||
def onReceive(context: Context, intent: Intent) {
|
||||
Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show()
|
||||
stopRunner()
|
||||
}
|
||||
closeReceiver = (context: Context, intent: Intent) => {
|
||||
Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show()
|
||||
stopRunner()
|
||||
}
|
||||
registerReceiver(closeReceiver, filter)
|
||||
|
||||
@@ -525,26 +519,22 @@ class ShadowsocksNatService extends Service with BaseService {
|
||||
screenFilter.addAction(Intent.ACTION_SCREEN_ON)
|
||||
screenFilter.addAction(Intent.ACTION_SCREEN_OFF)
|
||||
screenFilter.addAction(Intent.ACTION_USER_PRESENT)
|
||||
lockReceiver = new BroadcastReceiver() {
|
||||
def onReceive(context: Context, intent: Intent) {
|
||||
if (getState == State.CONNECTED) {
|
||||
val action = intent.getAction
|
||||
if (action == Intent.ACTION_SCREEN_OFF) {
|
||||
notifyForegroundAlert(getString(R.string.forward_success),
|
||||
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), false)
|
||||
} else if (action == Intent.ACTION_SCREEN_ON) {
|
||||
val keyGuard = getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
|
||||
if (!keyGuard.inKeyguardRestrictedInputMode) {
|
||||
notifyForegroundAlert(getString(R.string.forward_success),
|
||||
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
|
||||
}
|
||||
} else if (action == Intent.ACTION_USER_PRESENT) {
|
||||
notifyForegroundAlert(getString(R.string.forward_success),
|
||||
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
|
||||
}
|
||||
}
|
||||
lockReceiver = (context: Context, intent: Intent) => if (getState == State.CONNECTED) {
|
||||
val action = intent.getAction
|
||||
if (action == Intent.ACTION_SCREEN_OFF) {
|
||||
notifyForegroundAlert(getString(R.string.forward_success),
|
||||
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), false)
|
||||
} else if (action == Intent.ACTION_SCREEN_ON) {
|
||||
val keyGuard = getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
|
||||
if (!keyGuard.inKeyguardRestrictedInputMode) {
|
||||
notifyForegroundAlert(getString(R.string.forward_success),
|
||||
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
|
||||
}
|
||||
} else if (action == Intent.ACTION_USER_PRESENT) {
|
||||
notifyForegroundAlert(getString(R.string.forward_success),
|
||||
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
|
||||
}
|
||||
}
|
||||
registerReceiver(lockReceiver, screenFilter)
|
||||
}
|
||||
|
||||
|
||||
@@ -57,11 +57,7 @@ class ShadowsocksRunnerActivity extends Activity {
|
||||
val connection = new ServiceConnection {
|
||||
override def onServiceConnected(name: ComponentName, service: IBinder) {
|
||||
bgService = IShadowsocksService.Stub.asInterface(service)
|
||||
handler.postDelayed(new Runnable() {
|
||||
override def run() {
|
||||
if (bgService != null) startBackgroundService()
|
||||
}
|
||||
}, 1000)
|
||||
handler.postDelayed(() => if (bgService != null) startBackgroundService(), 1000)
|
||||
}
|
||||
override def onServiceDisconnected(name: ComponentName) {
|
||||
bgService = null
|
||||
@@ -122,11 +118,9 @@ class ShadowsocksRunnerActivity extends Activity {
|
||||
val locked = km.inKeyguardRestrictedInputMode
|
||||
if (locked) {
|
||||
val filter = new IntentFilter(Intent.ACTION_USER_PRESENT)
|
||||
receiver = new BroadcastReceiver() {
|
||||
override def onReceive(context: Context, intent: Intent) {
|
||||
if (intent.getAction == Intent.ACTION_USER_PRESENT) {
|
||||
attachService()
|
||||
}
|
||||
receiver = (context: Context, intent: Intent) => {
|
||||
if (intent.getAction == Intent.ACTION_USER_PRESENT) {
|
||||
attachService()
|
||||
}
|
||||
}
|
||||
registerReceiver(receiver, filter)
|
||||
|
||||
@@ -208,11 +208,9 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
// register close receiver
|
||||
val filter = new IntentFilter()
|
||||
filter.addAction(Intent.ACTION_SHUTDOWN)
|
||||
receiver = new BroadcastReceiver {
|
||||
def onReceive(p1: Context, p2: Intent) {
|
||||
Toast.makeText(p1, R.string.stopping, Toast.LENGTH_SHORT)
|
||||
stopRunner()
|
||||
}
|
||||
receiver = (p1: Context, p2: Intent) => {
|
||||
Toast.makeText(p1, R.string.stopping, Toast.LENGTH_SHORT)
|
||||
stopRunner()
|
||||
}
|
||||
registerReceiver(receiver, filter)
|
||||
|
||||
|
||||
@@ -93,35 +93,34 @@ class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread {
|
||||
try {
|
||||
val socket = serverSocket.accept()
|
||||
|
||||
pool.execute(new Runnable {
|
||||
override def run() {
|
||||
try {
|
||||
val input = socket.getInputStream
|
||||
val output = socket.getOutputStream
|
||||
pool.execute(() => {
|
||||
try {
|
||||
val input = socket.getInputStream
|
||||
val output = socket.getOutputStream
|
||||
|
||||
input.read()
|
||||
input.read()
|
||||
|
||||
val fds = socket.getAncillaryFileDescriptors
|
||||
val fds = socket.getAncillaryFileDescriptors
|
||||
|
||||
if (fds.nonEmpty) {
|
||||
var ret = false
|
||||
if (fds.nonEmpty) {
|
||||
var ret = false
|
||||
|
||||
val getInt = classOf[FileDescriptor].getDeclaredMethod("getInt$")
|
||||
val fd = getInt.invoke(fds(0)).asInstanceOf[Int]
|
||||
ret = vpnService.protect(fd)
|
||||
val getInt = classOf[FileDescriptor].getDeclaredMethod("getInt$")
|
||||
val fd = getInt.invoke(fds(0)).asInstanceOf[Int]
|
||||
ret = vpnService.protect(fd)
|
||||
|
||||
// Trick to close file decriptor
|
||||
System.jniclose(fd)
|
||||
// Trick to close file decriptor
|
||||
System.jniclose(fd)
|
||||
|
||||
if (ret) {
|
||||
output.write(0)
|
||||
} else {
|
||||
output.write(1)
|
||||
}
|
||||
|
||||
input.close()
|
||||
output.close()
|
||||
if (ret) {
|
||||
output.write(0)
|
||||
} else {
|
||||
output.write(1)
|
||||
}
|
||||
|
||||
input.close()
|
||||
output.close()
|
||||
}
|
||||
} catch {
|
||||
case e: Exception =>
|
||||
Log.e(TAG, "Error when protect socket", e)
|
||||
@@ -134,7 +133,7 @@ class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread {
|
||||
case _: Exception => // ignore
|
||||
}
|
||||
|
||||
}})
|
||||
})
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
Log.e(TAG, "Error when accept socket", e)
|
||||
|
||||
@@ -40,14 +40,10 @@
|
||||
package com.github.shadowsocks.database
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.BaseAdapter
|
||||
import android.widget.TextView
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.{LayoutInflater, View, ViewGroup}
|
||||
import android.widget.{BaseAdapter, TextView}
|
||||
import com.github.shadowsocks.R
|
||||
import android.view.View.{OnLongClickListener, OnClickListener}
|
||||
|
||||
abstract class Item {
|
||||
def id: Int
|
||||
@@ -147,17 +143,13 @@ class MenuAdapter(context: Context, var items: List[Any]) extends BaseAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
tv.setOnClickListener(new OnClickListener {
|
||||
def onClick(view: View) {
|
||||
val item = view.getTag(R.id.mdItem).asInstanceOf[Item]
|
||||
item.click(item.id)
|
||||
}
|
||||
tv.setOnClickListener((view: View) => {
|
||||
val item = view.getTag(R.id.mdItem).asInstanceOf[Item]
|
||||
item.click(item.id)
|
||||
})
|
||||
tv.setOnLongClickListener(new OnLongClickListener {
|
||||
def onLongClick(view: View): Boolean = {
|
||||
val item = view.getTag(R.id.mdItem).asInstanceOf[Item]
|
||||
item.longClick(item.id)
|
||||
}
|
||||
tv.setOnLongClickListener((view: View) => {
|
||||
val item = view.getTag(R.id.mdItem).asInstanceOf[Item]
|
||||
item.longClick(item.id)
|
||||
})
|
||||
|
||||
v.setTag(R.id.mdItem, value)
|
||||
|
||||
@@ -39,10 +39,11 @@
|
||||
|
||||
package com.github.shadowsocks.utils
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell
|
||||
import eu.chainfire.libsuperuser.Shell.{OnCommandResultListener, SU, Builder}
|
||||
import java.util
|
||||
|
||||
import eu.chainfire.libsuperuser.Shell
|
||||
import eu.chainfire.libsuperuser.Shell.{Builder, SU}
|
||||
|
||||
object Console {
|
||||
|
||||
private def openShell(): Shell.Interactive = {
|
||||
@@ -68,14 +69,8 @@ object Console {
|
||||
|
||||
def runCommand(commands: Array[String]) {
|
||||
val shell = openShell()
|
||||
shell.addCommand(commands, 0, new OnCommandResultListener {
|
||||
override def onCommandResult(commandCode: Int, exitCode: Int,
|
||||
output: util.List[String]) {
|
||||
if (exitCode < 0) {
|
||||
shell.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
shell.addCommand(commands, 0, ((commandCode: Int, exitCode: Int, output: util.List[String]) =>
|
||||
if (exitCode < 0) shell.close()): Shell.OnCommandResultListener)
|
||||
shell.waitForIdle()
|
||||
shell.close()
|
||||
}
|
||||
@@ -90,17 +85,14 @@ object Console {
|
||||
}
|
||||
val shell = openRootShell(context)
|
||||
val sb = new StringBuilder
|
||||
shell.addCommand(commands, 0, new OnCommandResultListener {
|
||||
override def onCommandResult(commandCode: Int, exitCode: Int,
|
||||
output: util.List[String]) {
|
||||
if (exitCode < 0) {
|
||||
shell.close()
|
||||
} else {
|
||||
import scala.collection.JavaConversions._
|
||||
output.foreach(line => sb.append(line).append('\n'))
|
||||
}
|
||||
shell.addCommand(commands, 0, ((commandCode: Int, exitCode: Int, output: util.List[String]) => {
|
||||
if (exitCode < 0) {
|
||||
shell.close()
|
||||
} else {
|
||||
import scala.collection.JavaConversions._
|
||||
output.foreach(line => sb.append(line).append('\n'))
|
||||
}
|
||||
})
|
||||
}): Shell.OnCommandResultListener)
|
||||
if (shell.waitForIdle()) {
|
||||
shell.close()
|
||||
sb.toString()
|
||||
|
||||
Reference in New Issue
Block a user