Commit bf3933bf authored by Max Lv's avatar Max Lv

Merge pull request #379 from Mygod/master

SAM (Scala 2.11.7)
parents 1ad82972 d111bc82
...@@ -6,11 +6,13 @@ platformTarget in Android := "android-23" ...@@ -6,11 +6,13 @@ platformTarget in Android := "android-23"
name := "shadowsocks" name := "shadowsocks"
scalaVersion := "2.11.7"
compileOrder in Compile := CompileOrder.JavaThenScala compileOrder in Compile := CompileOrder.JavaThenScala
javacOptions ++= Seq("-source", "1.6", "-target", "1.6") javacOptions ++= Seq("-source", "1.6", "-target", "1.6")
scalacOptions += "-target:jvm-1.6" scalacOptions ++= Seq("-target:jvm-1.6", "-Xexperimental")
ndkJavah in Android := List() ndkJavah in Android := List()
...@@ -24,26 +26,20 @@ resolvers += "JRAF" at "http://JRAF.org/static/maven/2" ...@@ -24,26 +26,20 @@ resolvers += "JRAF" at "http://JRAF.org/static/maven/2"
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"dnsjava" % "dnsjava" % "2.1.7", "dnsjava" % "dnsjava" % "2.1.7",
"com.github.kevinsawicki" % "http-request" % "5.6", "com.github.kevinsawicki" % "http-request" % "6.0",
"commons-net" % "commons-net" % "3.3", "commons-net" % "commons-net" % "3.3",
"com.google.zxing" % "android-integration" % "3.1.0" "com.google.zxing" % "android-integration" % "3.1.0",
) "com.joanzapata.android" % "android-iconify" % "1.0.11",
libraryDependencies ++= Seq(
"com.joanzapata.android" % "android-iconify" % "1.0.9",
"net.glxn.qrgen" % "android" % "2.0", "net.glxn.qrgen" % "android" % "2.0",
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6", "net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
"com.google.android.gms" % "play-services-base" % "8.1.0", "com.google.android.gms" % "play-services-base" % "8.1.0",
"com.google.android.gms" % "play-services-ads" % "8.1.0", "com.google.android.gms" % "play-services-ads" % "8.1.0",
"com.google.android.gms" % "play-services-analytics" % "8.1.0", "com.google.android.gms" % "play-services-analytics" % "8.1.0",
"com.android.support" % "support-v4" % "23.0.1" "com.android.support" % "support-v4" % "23.0.1",
)
libraryDependencies ++= Seq(
"com.github.mrengineer13" % "snackbar" % "0.5.0", "com.github.mrengineer13" % "snackbar" % "0.5.0",
"com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4", "com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4",
"com.j256.ormlite" % "ormlite-core" % "4.47", "com.j256.ormlite" % "ormlite-core" % "4.48",
"com.j256.ormlite" % "ormlite-android" % "4.47" "com.j256.ormlite" % "ormlite-android" % "4.48"
) )
proguardOptions in Android ++= Seq("-keep class android.support.v4.app.** { *; }", proguardOptions in Android ++= Seq("-keep class android.support.v4.app.** { *; }",
......
...@@ -65,7 +65,8 @@ import com.nostra13.universalimageloader.core.{DisplayImageOptions, ImageLoader, ...@@ -65,7 +65,8 @@ import com.nostra13.universalimageloader.core.{DisplayImageOptions, ImageLoader,
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer
import com.github.shadowsocks.utils.{Utils, Scheme, Key} import com.github.shadowsocks.utils.{Utils, Scheme, Key}
import scala.concurrent.ops._ import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.language.implicitConversions import scala.language.implicitConversions
case class ProxiedApp(uid: Int, name: String, packageName: String, var proxied: Boolean) case class ProxiedApp(uid: Int, name: String, packageName: String, var proxied: Boolean)
...@@ -267,9 +268,8 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe ...@@ -267,9 +268,8 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
} }
protected override def onCreateOptionsMenu(menu: Menu): Boolean = { protected override def onCreateOptionsMenu(menu: Menu): Boolean = {
val inflater = getMenuInflater() getMenuInflater.inflate(R.menu.app_manager_menu, menu)
inflater.inflate(R.menu.app_manager_menu, menu) super.onCreateOptionsMenu(menu)
return super.onCreateOptionsMenu(menu)
} }
protected override def onCreate(savedInstanceState: Bundle) { protected override def onCreate(savedInstanceState: Bundle) {
...@@ -277,7 +277,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe ...@@ -277,7 +277,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
handler = new Handler() handler = new Handler()
val actionBar = getActionBar() val actionBar = getActionBar
actionBar.setTitle(R.string.proxied_help) actionBar.setTitle(R.string.proxied_help)
actionBar.setDisplayHomeAsUpEnabled(true) actionBar.setDisplayHomeAsUpEnabled(true)
actionBar.setDisplayShowHomeEnabled(false) actionBar.setDisplayShowHomeEnabled(false)
...@@ -297,11 +297,8 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe ...@@ -297,11 +297,8 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
val bypassSwitch = findViewById(R.id.bypassSwitch).asInstanceOf[Switch] val bypassSwitch = findViewById(R.id.bypassSwitch).asInstanceOf[Switch]
val prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext) val prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
bypassSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener { bypassSwitch.setOnCheckedChangeListener((button: CompoundButton, checked: Boolean) =>
def onCheckedChanged(button: CompoundButton, checked: Boolean) { prefs.edit().putBoolean(Key.isBypassApps, checked).commit())
prefs.edit().putBoolean(Key.isBypassApps, checked).commit()
}
})
bypassSwitch.setChecked(prefs.getBoolean(Key.isBypassApps, false)) bypassSwitch.setChecked(prefs.getBoolean(Key.isBypassApps, false))
appListView = findViewById(R.id.applistview).asInstanceOf[ListView] appListView = findViewById(R.id.applistview).asInstanceOf[ListView]
...@@ -309,7 +306,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe ...@@ -309,7 +306,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
protected override def onResume() { protected override def onResume() {
super.onResume() super.onResume()
spawn { Future {
handler.post(loadStartRunnable) handler.post(loadStartRunnable)
if (!appsLoaded) loadApps() if (!appsLoaded) loadApps()
handler.post(loadFinishRunnable) handler.post(loadFinishRunnable)
......
...@@ -39,13 +39,11 @@ ...@@ -39,13 +39,11 @@
package com.github.shadowsocks package com.github.shadowsocks
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.app.Notification
import android.content.Context import android.content.Context
import android.os.{Handler, RemoteCallbackList}
import com.github.shadowsocks.aidl.{Config, IShadowsocksService, IShadowsocksServiceCallback}
import com.github.shadowsocks.utils.State
trait BaseService { trait BaseService {
...@@ -100,10 +98,10 @@ trait BaseService { ...@@ -100,10 +98,10 @@ trait BaseService {
def getTag: String def getTag: String
def getContext: Context def getContext: Context
def getCallbackCount(): Int = { def getCallbackCount: Int = {
callbackCount callbackCount
} }
def getState(): Int = { def getState: Int = {
state state
} }
def changeState(s: Int) { def changeState(s: Int) {
...@@ -112,23 +110,19 @@ trait BaseService { ...@@ -112,23 +110,19 @@ trait BaseService {
protected def changeState(s: Int, msg: String) { protected def changeState(s: Int, msg: String) {
val handler = new Handler(getContext.getMainLooper) val handler = new Handler(getContext.getMainLooper)
handler.post(new Runnable { handler.post(() => if (state != s) {
override def run() { if (callbackCount > 0) {
if (state != s) { val n = callbacks.beginBroadcast()
if (callbackCount > 0) { for (i <- 0 to n - 1) {
val n = callbacks.beginBroadcast() try {
for (i <- 0 to n - 1) { callbacks.getBroadcastItem(i).stateChanged(s, msg)
try { } catch {
callbacks.getBroadcastItem(i).stateChanged(s, msg) case _: Exception => // Ignore
} catch {
case _: Exception => // Ignore
}
}
callbacks.finishBroadcast()
} }
state = s
} }
callbacks.finishBroadcast()
} }
state = s
}) })
} }
......
...@@ -39,15 +39,15 @@ ...@@ -39,15 +39,15 @@
package com.github.shadowsocks package com.github.shadowsocks
import android.os.{Message, Handler, Bundle} import android.app.{Activity, AlertDialog, ProgressDialog}
import android.app.{ProgressDialog, AlertDialog, Activity} import android.content.DialogInterface
import android.content.{Intent, DialogInterface}
import com.github.shadowsocks.database.{ProfileManager, Profile}
import com.github.shadowsocks.utils.{Parser, Action}
import android.preference.PreferenceManager
import android.view.WindowManager
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.{Bundle, Handler, Message}
import android.preference.PreferenceManager
import android.view.WindowManager
import com.github.shadowsocks.database.{Profile, ProfileManager}
import com.github.shadowsocks.utils.Parser
class ParserActivity extends Activity { class ParserActivity extends Activity {
override def onCreate(savedInstanceState: Bundle) { override def onCreate(savedInstanceState: Bundle) {
...@@ -57,21 +57,17 @@ class ParserActivity extends Activity { ...@@ -57,21 +57,17 @@ class ParserActivity extends Activity {
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setTitle(R.string.add_profile_dialog) .setTitle(R.string.add_profile_dialog)
.setCancelable(false) .setCancelable(false)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { .setPositiveButton(R.string.yes, ((dialog: DialogInterface, id: Int) => {
override def onClick(dialog: DialogInterface, id: Int) {
Parser.parse(data) match { Parser.parse(data) match {
case Some(profile) => addProfile(profile) case Some(profile) => addProfile(profile)
case _ => // ignore case _ => // ignore
} }
dialog.dismiss() dialog.dismiss()
} }): DialogInterface.OnClickListener)
}) .setNegativeButton(R.string.no, ((dialog: DialogInterface, id: Int) => {
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
override def onClick(dialog: DialogInterface, id: Int) {
dialog.dismiss() dialog.dismiss()
finish() finish()
} }): DialogInterface.OnClickListener)
})
.setMessage(data) .setMessage(data)
.create() .create()
.show() .show()
...@@ -91,15 +87,13 @@ class ParserActivity extends Activity { ...@@ -91,15 +87,13 @@ class ParserActivity extends Activity {
val h = showProgress(getString(R.string.loading)) val h = showProgress(getString(R.string.loading))
h.postDelayed(new Runnable { h.postDelayed(() => {
def run() { val profileManager =
val profileManager = new ProfileManager(PreferenceManager.getDefaultSharedPreferences(getBaseContext),
new ProfileManager(PreferenceManager.getDefaultSharedPreferences(getBaseContext), getApplication.asInstanceOf[ShadowsocksApplication].dbHelper)
getApplication.asInstanceOf[ShadowsocksApplication].dbHelper) profileManager.createOrUpdateProfile(profile)
profileManager.createOrUpdateProfile(profile) profileManager.reload(profile.id)
profileManager.reload(profile.id) h.sendEmptyMessage(0)
h.sendEmptyMessage(0)
}
}, 600) }, 600)
} }
......
...@@ -47,7 +47,6 @@ import com.github.shadowsocks.database.DBHelper ...@@ -47,7 +47,6 @@ import com.github.shadowsocks.database.DBHelper
import com.github.shadowsocks.utils.Utils import com.github.shadowsocks.utils.Utils
import com.google.android.gms.analytics.GoogleAnalytics import com.google.android.gms.analytics.GoogleAnalytics
import com.google.android.gms.common.api.ResultCallback import com.google.android.gms.common.api.ResultCallback
import com.google.android.gms.tagmanager.Container.FunctionCallMacroCallback
import com.google.android.gms.tagmanager.{ContainerHolder, TagManager} import com.google.android.gms.tagmanager.{ContainerHolder, TagManager}
class ShadowsocksApplication extends Application { class ShadowsocksApplication extends Application {
...@@ -66,14 +65,13 @@ class ShadowsocksApplication extends Application { ...@@ -66,14 +65,13 @@ class ShadowsocksApplication extends Application {
} }
containerHolder = holder containerHolder = holder
val container = holder.getContainer val container = holder.getContainer
container.registerFunctionCallMacroCallback(SIG_FUNC, new FunctionCallMacroCallback { container.registerFunctionCallMacroCallback(SIG_FUNC,
override def getValue(functionName: String, parameters: util.Map[String, AnyRef]): AnyRef = { (functionName: String, parameters: util.Map[String, AnyRef]) => {
if (functionName == SIG_FUNC) { if (functionName == SIG_FUNC) {
Utils.getSignature(getApplicationContext) Utils.getSignature(getApplicationContext)
} }
null null
} })
})
} }
} }
pending.setResultCallback(callback, 2, TimeUnit.SECONDS) pending.setResultCallback(callback, 2, TimeUnit.SECONDS)
......
...@@ -58,7 +58,8 @@ import com.google.android.gms.analytics.HitBuilders ...@@ -58,7 +58,8 @@ import com.google.android.gms.analytics.HitBuilders
import scala.collection._ import scala.collection._
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
import scala.concurrent.ops._ import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
class ShadowsocksNatService extends Service with BaseService { class ShadowsocksNatService extends Service with BaseService {
...@@ -172,11 +173,7 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -172,11 +173,7 @@ class ShadowsocksNatService extends Service with BaseService {
def initConnectionReceiver() { def initConnectionReceiver() {
val filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) val filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
connReceiver = new BroadcastReceiver { connReceiver = (context: Context, intent: Intent) => setupDns()
override def onReceive(context: Context, intent: Intent) = {
setupDns()
}
}
registerReceiver(connReceiver, filter) registerReceiver(connReceiver, filter)
} }
...@@ -511,11 +508,9 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -511,11 +508,9 @@ class ShadowsocksNatService extends Service with BaseService {
val filter = new IntentFilter() val filter = new IntentFilter()
filter.addAction(Intent.ACTION_SHUTDOWN) filter.addAction(Intent.ACTION_SHUTDOWN)
filter.addAction(Action.CLOSE) filter.addAction(Action.CLOSE)
closeReceiver = new BroadcastReceiver() { closeReceiver = (context: Context, intent: Intent) => {
def onReceive(context: Context, intent: Intent) { Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show()
Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show() stopRunner()
stopRunner()
}
} }
registerReceiver(closeReceiver, filter) registerReceiver(closeReceiver, filter)
...@@ -524,26 +519,22 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -524,26 +519,22 @@ class ShadowsocksNatService extends Service with BaseService {
screenFilter.addAction(Intent.ACTION_SCREEN_ON) screenFilter.addAction(Intent.ACTION_SCREEN_ON)
screenFilter.addAction(Intent.ACTION_SCREEN_OFF) screenFilter.addAction(Intent.ACTION_SCREEN_OFF)
screenFilter.addAction(Intent.ACTION_USER_PRESENT) screenFilter.addAction(Intent.ACTION_USER_PRESENT)
lockReceiver = new BroadcastReceiver() { lockReceiver = (context: Context, intent: Intent) => if (getState == State.CONNECTED) {
def onReceive(context: Context, intent: Intent) { val action = intent.getAction
if (getState == State.CONNECTED) { if (action == Intent.ACTION_SCREEN_OFF) {
val action = intent.getAction notifyForegroundAlert(getString(R.string.forward_success),
if (action == Intent.ACTION_SCREEN_OFF) { getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), false)
notifyForegroundAlert(getString(R.string.forward_success), } else if (action == Intent.ACTION_SCREEN_ON) {
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), false) val keyGuard = getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
} else if (action == Intent.ACTION_SCREEN_ON) { if (!keyGuard.inKeyguardRestrictedInputMode) {
val keyGuard = getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager] notifyForegroundAlert(getString(R.string.forward_success),
if (!keyGuard.inKeyguardRestrictedInputMode) { getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
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)
}
}
} }
} 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) registerReceiver(lockReceiver, screenFilter)
} }
...@@ -556,7 +547,7 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -556,7 +547,7 @@ class ShadowsocksNatService extends Service with BaseService {
changeState(State.CONNECTING) changeState(State.CONNECTING)
spawn { Future {
if (config.proxy == "198.199.101.152") { if (config.proxy == "198.199.101.152") {
val holder = application.containerHolder val holder = application.containerHolder
......
...@@ -57,11 +57,7 @@ class ShadowsocksRunnerActivity extends Activity { ...@@ -57,11 +57,7 @@ class ShadowsocksRunnerActivity extends Activity {
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)
handler.postDelayed(new Runnable() { handler.postDelayed(() => if (bgService != null) startBackgroundService(), 1000)
override def run() {
if (bgService != null) startBackgroundService()
}
}, 1000)
} }
override def onServiceDisconnected(name: ComponentName) { override def onServiceDisconnected(name: ComponentName) {
bgService = null bgService = null
...@@ -122,11 +118,9 @@ class ShadowsocksRunnerActivity extends Activity { ...@@ -122,11 +118,9 @@ class ShadowsocksRunnerActivity extends Activity {
val locked = km.inKeyguardRestrictedInputMode val locked = km.inKeyguardRestrictedInputMode
if (locked) { if (locked) {
val filter = new IntentFilter(Intent.ACTION_USER_PRESENT) val filter = new IntentFilter(Intent.ACTION_USER_PRESENT)
receiver = new BroadcastReceiver() { receiver = (context: Context, intent: Intent) => {
override def onReceive(context: Context, intent: Intent) { if (intent.getAction == Intent.ACTION_USER_PRESENT) {
if (intent.getAction == Intent.ACTION_USER_PRESENT) { attachService()
attachService()
}
} }
} }
registerReceiver(receiver, filter) registerReceiver(receiver, filter)
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
package com.github.shadowsocks package com.github.shadowsocks
import java.io.File import java.io.File
import java.net.InetAddress
import java.util.Locale import java.util.Locale
import android.app._ import android.app._
...@@ -57,7 +56,8 @@ import org.apache.commons.net.util.SubnetUtils ...@@ -57,7 +56,8 @@ import org.apache.commons.net.util.SubnetUtils
import scala.collection.mutable import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
import scala.concurrent.ops._ import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
class ShadowsocksVpnService extends VpnService with BaseService { class ShadowsocksVpnService extends VpnService with BaseService {
...@@ -208,17 +208,15 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -208,17 +208,15 @@ class ShadowsocksVpnService extends VpnService with BaseService {
// register close receiver // register close receiver
val filter = new IntentFilter() val filter = new IntentFilter()
filter.addAction(Intent.ACTION_SHUTDOWN) filter.addAction(Intent.ACTION_SHUTDOWN)
receiver = new BroadcastReceiver { receiver = (p1: Context, p2: Intent) => {
def onReceive(p1: Context, p2: Intent) { Toast.makeText(p1, R.string.stopping, Toast.LENGTH_SHORT)
Toast.makeText(p1, R.string.stopping, Toast.LENGTH_SHORT) stopRunner()
stopRunner()
}
} }
registerReceiver(receiver, filter) registerReceiver(receiver, filter)
changeState(State.CONNECTING) changeState(State.CONNECTING)
spawn { Future {
if (config.proxy == "198.199.101.152") { if (config.proxy == "198.199.101.152") {
val holder = getApplication.asInstanceOf[ShadowsocksApplication].containerHolder val holder = getApplication.asInstanceOf[ShadowsocksApplication].containerHolder
try { try {
...@@ -453,7 +451,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -453,7 +451,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
Console.runCommand(cmd) Console.runCommand(cmd)
return fd fd
} }
override def stopBackgroundService() { override def stopBackgroundService() {
......
...@@ -93,35 +93,34 @@ class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread { ...@@ -93,35 +93,34 @@ class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread {
try { try {
val socket = serverSocket.accept() val socket = serverSocket.accept()
pool.execute(new Runnable { pool.execute(() => {
override def run() { try {
try { val input = socket.getInputStream
val input = socket.getInputStream val output = socket.getOutputStream
val output = socket.getOutputStream
input.read()
val fds = socket.getAncillaryFileDescriptors input.read()
if (fds.length > 0) { val fds = socket.getAncillaryFileDescriptors
var ret = false
val getInt = classOf[FileDescriptor].getDeclaredMethod("getInt$") if (fds.nonEmpty) {
val fd = getInt.invoke(fds(0)).asInstanceOf[Int] var ret = false
ret = vpnService.protect(fd)
// Trick to close file decriptor val getInt = classOf[FileDescriptor].getDeclaredMethod("getInt$")
System.jniclose(fd) val fd = getInt.invoke(fds(0)).asInstanceOf[Int]
ret = vpnService.protect(fd)
if (ret) { // Trick to close file decriptor
output.write(0) System.jniclose(fd)
} else {
output.write(1)
}
input.close() if (ret) {
output.close() output.write(0)
} else {
output.write(1)
} }
input.close()
output.close()
}
} catch { } catch {
case e: Exception => case e: Exception =>
Log.e(TAG, "Error when protect socket", e) Log.e(TAG, "Error when protect socket", e)
...@@ -134,12 +133,11 @@ class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread { ...@@ -134,12 +133,11 @@ class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread {
case _: Exception => // ignore case _: Exception => // ignore
} }
}}) })
} catch { } catch {
case e: IOException => { case e: IOException =>
Log.e(TAG, "Error when accept socket", e) Log.e(TAG, "Error when accept socket", e)
return return
}
} }
} }
} }
......
...@@ -40,14 +40,10 @@ ...@@ -40,14 +40,10 @@
package com.github.shadowsocks.database package com.github.shadowsocks.database
import android.content.Context 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.graphics.drawable.Drawable
import com.github.shadowsocks.{R} import android.view.{LayoutInflater, View, ViewGroup}
import android.view.View.{OnLongClickListener, OnClickListener} import android.widget.{BaseAdapter, TextView}
import com.github.shadowsocks.R
abstract class Item { abstract class Item {
def id: Int def id: Int
...@@ -147,17 +143,13 @@ class MenuAdapter(context: Context, var items: List[Any]) extends BaseAdapter { ...@@ -147,17 +143,13 @@ class MenuAdapter(context: Context, var items: List[Any]) extends BaseAdapter {
} }
} }
tv.setOnClickListener(new OnClickListener { tv.setOnClickListener((view: View) => {
def onClick(view: View) { val item = view.getTag(R.id.mdItem).asInstanceOf[Item]
val item = view.getTag(R.id.mdItem).asInstanceOf[Item] item.click(item.id)
item.click(item.id)
}
}) })
tv.setOnLongClickListener(new OnLongClickListener { tv.setOnLongClickListener((view: View) => {
def onLongClick(view: View): Boolean = { val item = view.getTag(R.id.mdItem).asInstanceOf[Item]
val item = view.getTag(R.id.mdItem).asInstanceOf[Item] item.longClick(item.id)
item.longClick(item.id)
}
}) })
v.setTag(R.id.mdItem, value) v.setTag(R.id.mdItem, value)
......
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
package com.github.shadowsocks.database package com.github.shadowsocks.database
import android.content.SharedPreferences
import android.util.Log import android.util.Log
import com.github.shadowsocks._ import com.github.shadowsocks._
import android.content.{SharedPreferences, Context}
import com.github.shadowsocks.utils.Key import com.github.shadowsocks.utils.Key
class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) { class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
......
...@@ -233,8 +233,8 @@ object ConfigUtils { ...@@ -233,8 +233,8 @@ object ConfigUtils {
.readTimeout(2000) .readTimeout(2000)
.send("sig="+sig) .send("sig="+sig)
.body .body
val proxies = util.Random.shuffle(list.split('|').toSeq).toSeq val proxies = util.Random.shuffle(list.split('|').toSeq)
val proxy = proxies(0).split(':') val proxy = proxies.head.split(':')
val host = proxy(0).trim val host = proxy(0).trim
val port = proxy(1).trim.toInt val port = proxy(1).trim.toInt
......
...@@ -39,10 +39,11 @@ ...@@ -39,10 +39,11 @@
package com.github.shadowsocks.utils package com.github.shadowsocks.utils
import eu.chainfire.libsuperuser.Shell
import eu.chainfire.libsuperuser.Shell.{OnCommandResultListener, SU, Builder}
import java.util import java.util
import eu.chainfire.libsuperuser.Shell
import eu.chainfire.libsuperuser.Shell.{Builder, SU}
object Console { object Console {
private def openShell(): Shell.Interactive = { private def openShell(): Shell.Interactive = {
...@@ -68,14 +69,8 @@ object Console { ...@@ -68,14 +69,8 @@ object Console {
def runCommand(commands: Array[String]) { def runCommand(commands: Array[String]) {
val shell = openShell() val shell = openShell()
shell.addCommand(commands, 0, new OnCommandResultListener { shell.addCommand(commands, 0, ((commandCode: Int, exitCode: Int, output: util.List[String]) =>
override def onCommandResult(commandCode: Int, exitCode: Int, if (exitCode < 0) shell.close()): Shell.OnCommandResultListener)
output: util.List[String]) {
if (exitCode < 0) {
shell.close()
}
}
})
shell.waitForIdle() shell.waitForIdle()
shell.close() shell.close()
} }
...@@ -90,17 +85,14 @@ object Console { ...@@ -90,17 +85,14 @@ object Console {
} }
val shell = openRootShell(context) val shell = openRootShell(context)
val sb = new StringBuilder val sb = new StringBuilder
shell.addCommand(commands, 0, new OnCommandResultListener { shell.addCommand(commands, 0, ((commandCode: Int, exitCode: Int, output: util.List[String]) => {
override def onCommandResult(commandCode: Int, exitCode: Int, if (exitCode < 0) {
output: util.List[String]) { shell.close()
if (exitCode < 0) { } else {
shell.close() import scala.collection.JavaConversions._
} else { output.foreach(line => sb.append(line).append('\n'))
import scala.collection.JavaConversions._
output.foreach(line => sb.append(line).append('\n'))
}
} }
}) }): Shell.OnCommandResultListener)
if (shell.waitForIdle()) { if (shell.waitForIdle()) {
shell.close() shell.close()
sb.toString() sb.toString()
......
...@@ -47,11 +47,8 @@ import android.util.{Log, Base64} ...@@ -47,11 +47,8 @@ import android.util.{Log, Base64}
object Parser { object Parser {
val TAG = "ShadowParser" val TAG = "ShadowParser"
def generate (profile: Profile): String = { def generate (profile: Profile): String = "ss://" + Base64.encodeToString("%s:%s@%s:%d".formatLocal(Locale.ENGLISH,
val path = "%s:%s@%s:%d".formatLocal(Locale.ENGLISH, profile.method, profile.password, profile.host, profile.remotePort).getBytes, Base64.NO_PADDING)
profile.method, profile.password, profile.host, profile.remotePort)
return "ss://" + Base64.encodeToString(path.getBytes, Base64.NO_PADDING)
}
def parse (data: String): Option[Profile] = { def parse (data: String): Option[Profile] = {
try { try {
......
...@@ -38,21 +38,21 @@ ...@@ -38,21 +38,21 @@
*/ */
package com.github.shadowsocks.utils package com.github.shadowsocks.utils
import android.content.{Intent, Context}
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.graphics.drawable.{BitmapDrawable, Drawable}
import android.util.{Base64, Log}
import java.io._ import java.io._
import java.net._ import java.net._
import org.xbill.DNS._ import java.security.MessageDigest
import android.graphics._
import android.app.ActivityManager import android.app.ActivityManager
import android.content.pm.{ApplicationInfo, PackageManager}
import android.content.{Context, Intent}
import android.graphics._
import android.graphics.drawable.{BitmapDrawable, Drawable}
import android.os.Build import android.os.Build
import android.provider.Settings import android.provider.Settings
import scala.Some import android.support.v4.content.ContextCompat
import java.security.MessageDigest import android.util.{Base64, Log}
import com.github.shadowsocks.{BuildConfig} import com.github.shadowsocks.BuildConfig
import org.xbill.DNS._
object Utils { object Utils {
...@@ -146,6 +146,7 @@ object Utils { ...@@ -146,6 +146,7 @@ object Utils {
// + "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false\n") // + "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false\n")
} }
//noinspection ScalaDeprecation
private def toggleBelowApiLevel17(context: Context) { private def toggleBelowApiLevel17(context: Context) {
// Android 4.2 below // Android 4.2 below
Settings.System.putInt(context.getContentResolver, Settings.System.AIRPLANE_MODE_ON, 1) Settings.System.putInt(context.getContentResolver, Settings.System.AIRPLANE_MODE_ON, 1)
...@@ -197,7 +198,7 @@ object Utils { ...@@ -197,7 +198,7 @@ object Utils {
} }
} }
} catch { } catch {
case e: Exception => None case e: Exception =>
} }
None None
} }
...@@ -232,7 +233,7 @@ object Utils { ...@@ -232,7 +233,7 @@ object Utils {
None None
} }
lazy val isNumericMethod = classOf[InetAddress].getMethod("isNumeric", classOf[String]) private lazy val isNumericMethod = classOf[InetAddress].getMethod("isNumeric", classOf[String])
def isNumeric(address: String): Boolean = isNumericMethod.invoke(null, address).asInstanceOf[Boolean] def isNumeric(address: String): Boolean = isNumericMethod.invoke(null, address).asInstanceOf[Boolean]
/** /**
...@@ -338,7 +339,7 @@ object Utils { ...@@ -338,7 +339,7 @@ object Utils {
def getAppIcon(c: Context, packageName: String): Drawable = { def getAppIcon(c: Context, packageName: String): Drawable = {
val pm: PackageManager = c.getPackageManager val pm: PackageManager = c.getPackageManager
val icon: Drawable = c.getResources.getDrawable(android.R.drawable.sym_def_app_icon) val icon: Drawable = ContextCompat.getDrawable(c, android.R.drawable.sym_def_app_icon)
try { try {
pm.getApplicationIcon(packageName) pm.getApplicationIcon(packageName)
} catch { } catch {
...@@ -348,7 +349,7 @@ object Utils { ...@@ -348,7 +349,7 @@ object Utils {
def getAppIcon(c: Context, uid: Int): Drawable = { def getAppIcon(c: Context, uid: Int): Drawable = {
val pm: PackageManager = c.getPackageManager val pm: PackageManager = c.getPackageManager
val icon: Drawable = c.getResources.getDrawable(android.R.drawable.sym_def_app_icon) val icon: Drawable = ContextCompat.getDrawable(c, android.R.drawable.sym_def_app_icon)
val packages: Array[String] = pm.getPackagesForUid(uid) val packages: Array[String] = pm.getPackagesForUid(uid)
if (packages != null) { if (packages != null) {
if (packages.length >= 1) { if (packages.length >= 1) {
......
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