Commit f40fb626 authored by Max Lv's avatar Max Lv

clean up

parent 527d8f40
...@@ -41,7 +41,7 @@ package com.github.shadowsocks ...@@ -41,7 +41,7 @@ package com.github.shadowsocks
import android.app.ProgressDialog import android.app.ProgressDialog
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.pm.{ApplicationInfo, PackageManager} import android.content.pm.PackageManager
import android.graphics.{Bitmap, PixelFormat} import android.graphics.{Bitmap, PixelFormat}
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
...@@ -63,7 +63,6 @@ import android.widget.ListAdapter ...@@ -63,7 +63,6 @@ import android.widget.ListAdapter
import android.widget.ListView import android.widget.ListView
import android.widget.TextView import android.widget.TextView
import com.actionbarsherlock.app.SherlockActivity import com.actionbarsherlock.app.SherlockActivity
import java.util.StringTokenizer
import com.nostra13.universalimageloader.core.download.BaseImageDownloader import com.nostra13.universalimageloader.core.download.BaseImageDownloader
import java.io.{ByteArrayOutputStream, ByteArrayInputStream, InputStream} import java.io.{ByteArrayOutputStream, ByteArrayInputStream, InputStream}
import com.nostra13.universalimageloader.core.{DisplayImageOptions, ImageLoader, ImageLoaderConfiguration} import com.nostra13.universalimageloader.core.{DisplayImageOptions, ImageLoader, ImageLoaderConfiguration}
...@@ -71,15 +70,17 @@ import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer ...@@ -71,15 +70,17 @@ import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer
case class ProxiedApp(uid: Int, name: String, var proxied: Boolean) case class ProxiedApp(uid: Int, name: String, var proxied: Boolean)
object AppManager { class ObjectArrayTools[T <: AnyRef](a: Array[T]) {
val PREFS_KEY_PROXYED = "Proxyed"
class ObjectArrayTools[T <: AnyRef](a: Array[T]) {
def binarySearch(key: T) = { def binarySearch(key: T) = {
java.util.Arrays.binarySearch(a.asInstanceOf[Array[AnyRef]], key) java.util.Arrays.binarySearch(a.asInstanceOf[Array[AnyRef]], key)
} }
} }
case class ListEntry(box: CheckBox, text: TextView, icon: ImageView)
object AppManager {
val PREFS_KEY_PROXYED = "Proxyed"
implicit def anyrefarray_tools[T <: AnyRef](a: Array[T]) = new ObjectArrayTools(a) implicit def anyrefarray_tools[T <: AnyRef](a: Array[T]) = new ObjectArrayTools(a)
...@@ -103,12 +104,23 @@ object AppManager { ...@@ -103,12 +104,23 @@ object AppManager {
} }
}.toArray }.toArray
} }
} }
class AppManager extends SherlockActivity with OnCheckedChangeListener with OnClickListener { class AppManager extends SherlockActivity with OnCheckedChangeListener with OnClickListener {
implicit def anyrefarray_tools[T <: AnyRef](a: Array[T]) = new AppManager.ObjectArrayTools(a) val MSG_LOAD_START = 1
val MSG_LOAD_FINISH = 2
val SCHEME = "app://"
val STUB = android.R.drawable.sym_def_app_icon
implicit def anyrefarray_tools[T <: AnyRef](a: Array[T]) = new ObjectArrayTools(a)
var apps: Array[ProxiedApp] = null
var appListView: ListView = null
var overlay: TextView = null
var progressDialog: ProgressDialog = null
var adapter: ListAdapter = null
var appsLoaded: Boolean = false
def loadApps(context: Context): Array[ProxiedApp] = { def loadApps(context: Context): Array[ProxiedApp] = {
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
...@@ -120,9 +132,10 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -120,9 +132,10 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
val packageManager: PackageManager = context.getPackageManager val packageManager: PackageManager = context.getPackageManager
val appList = packageManager.getInstalledApplications(0) val appList = packageManager.getInstalledApplications(0)
appList.filter (a => a.uid >= 10000 appList.filter(a => a.uid >= 10000
&& packageManager.getApplicationLabel(a) != null && packageManager.getApplicationLabel(a) != null
&& packageManager.getApplicationIcon(a) != null).map { a => && packageManager.getApplicationIcon(a) != null).map {
a =>
val uid = a.uid val uid = a.uid
val userName = uid.toString val userName = uid.toString
val name = packageManager.getApplicationLabel(a).toString val name = packageManager.getApplicationLabel(a).toString
...@@ -133,10 +146,15 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -133,10 +146,15 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
def loadApps() { def loadApps() {
apps = loadApps(this).sortWith((a, b) => { apps = loadApps(this).sortWith((a, b) => {
if (a == null || b == null || a.name == null || b.name == null) true if (a == null || b == null || a.name == null || b.name == null) {
else if (a.proxied == b.proxied) a.name < b.name true
else if (a.proxied) true } else if (a.proxied == b.proxied) {
else false a.name < b.name
} else if (a.proxied) {
true
} else {
false
}
}) })
adapter = new ArrayAdapter[ProxiedApp](this, R.layout.layout_apps_item, R.id.itemtext, apps) { adapter = new ArrayAdapter[ProxiedApp](this, R.layout.layout_apps_item, R.id.itemtext, apps) {
override def getView(position: Int, view: View, parent: ViewGroup): View = { override def getView(position: Int, view: View, parent: ViewGroup): View = {
...@@ -152,14 +170,14 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -152,14 +170,14 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
entry.text.setOnClickListener(AppManager.this) entry.text.setOnClickListener(AppManager.this)
convertView.setTag(entry) convertView.setTag(entry)
entry.box.setOnCheckedChangeListener(AppManager.this) entry.box.setOnCheckedChangeListener(AppManager.this)
} } else {
else {
entry = convertView.getTag.asInstanceOf[ListEntry] entry = convertView.getTag.asInstanceOf[ListEntry]
} }
val app: ProxiedApp = apps(position) val app: ProxiedApp = apps(position)
val options = val options =
new DisplayImageOptions.Builder().showStubImage(STUB) new DisplayImageOptions.Builder()
.showStubImage(STUB)
.showImageForEmptyUri(STUB) .showImageForEmptyUri(STUB)
.showImageOnFail(STUB) .showImageOnFail(STUB)
.resetViewBeforeLoading() .resetViewBeforeLoading()
...@@ -203,13 +221,18 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -203,13 +221,18 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
this.setContentView(R.layout.layout_apps) this.setContentView(R.layout.layout_apps)
this.overlay = View.inflate(this, R.layout.overlay, null).asInstanceOf[TextView] this.overlay = View.inflate(this, R.layout.overlay, null).asInstanceOf[TextView]
getWindowManager.addView(overlay, new WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT)) getWindowManager
.addView(overlay, new
WindowManager.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT))
val config = val config =
new ImageLoaderConfiguration.Builder(this).imageDownloader( new ImageLoaderConfiguration.Builder(this)
new AppIconDownloader(this)).build() .imageDownloader(new AppIconDownloader(this))
.build()
ImageLoader.getInstance().init(config) ImageLoader.getInstance().init(config)
} }
protected override def onResume() { protected override def onResume() {
...@@ -236,8 +259,7 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -236,8 +259,7 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
if (app.proxied) { if (app.proxied) {
proxiedApps ++= app.uid.toString proxiedApps ++= app.uid.toString
proxiedApps += '|' proxiedApps += '|'
} })
)
val edit: SharedPreferences.Editor = prefs.edit val edit: SharedPreferences.Editor = prefs.edit
edit.putString(AppManager.PREFS_KEY_PROXYED, proxiedApps.toString()) edit.putString(AppManager.PREFS_KEY_PROXYED, proxiedApps.toString())
edit.commit edit.commit
...@@ -247,17 +269,18 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -247,17 +269,18 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
override def handleMessage(msg: Message) { override def handleMessage(msg: Message) {
msg.what match { msg.what match {
case MSG_LOAD_START => case MSG_LOAD_START =>
progressDialog = ProgressDialog.show(AppManager.this, "", getString(R.string.loading), true, true) progressDialog = ProgressDialog
.show(AppManager.this, "", getString(R.string.loading), true, true)
case MSG_LOAD_FINISH => case MSG_LOAD_FINISH =>
appListView.setAdapter(adapter) appListView.setAdapter(adapter)
appListView.setOnScrollListener(new AbsListView.OnScrollListener { appListView.setOnScrollListener(new AbsListView.OnScrollListener {
def onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int) { def onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int,
totalItemCount: Int) {
if (visible) { if (visible) {
val name: String = apps(firstVisibleItem).name val name: String = apps(firstVisibleItem).name
if (name != null && name.length > 1) { if (name != null && name.length > 1) {
overlay.setText(apps(firstVisibleItem).name.substring(0, 1)) overlay.setText(apps(firstVisibleItem).name.substring(0, 1))
} } else {
else {
overlay.setText("*") overlay.setText("*")
} }
overlay.setVisibility(View.VISIBLE) overlay.setVisibility(View.VISIBLE)
...@@ -285,7 +308,9 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -285,7 +308,9 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
class AppIconDownloader(context: Context, connectTimeout: Int, readTimeout: Int) class AppIconDownloader(context: Context, connectTimeout: Int, readTimeout: Int)
extends BaseImageDownloader(context, connectTimeout, readTimeout) { extends BaseImageDownloader(context, connectTimeout, readTimeout) {
def this(context: Context) { this(context, 0, 0) } def this(context: Context) {
this(context, 0, 0)
}
override def getStreamFromOtherSource(imageUri: String, extra: AnyRef): InputStream = { override def getStreamFromOtherSource(imageUri: String, extra: AnyRef): InputStream = {
val uid = imageUri.substring(SCHEME.length).toInt val uid = imageUri.substring(SCHEME.length).toInt
...@@ -298,17 +323,4 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -298,17 +323,4 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
} }
} }
case class ListEntry(box: CheckBox, text: TextView, icon: ImageView)
var apps: Array[ProxiedApp] = null
var appListView: ListView = null
var overlay: TextView = null
var progressDialog: ProgressDialog = null
var adapter: ListAdapter = null
var appsLoaded: Boolean = false
val MSG_LOAD_START = 1
val MSG_LOAD_FINISH = 2
val SCHEME = "app://"
val STUB = android.R.drawable.sym_def_app_icon
} }
\ No newline at end of file
...@@ -50,10 +50,8 @@ import java.io._ ...@@ -50,10 +50,8 @@ import java.io._
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import android.net.VpnService import android.net.VpnService
import org.apache.http.conn.util.InetAddressUtils import org.apache.http.conn.util.InetAddressUtils
import org.xbill.DNS._
import android.os.Message import android.os.Message
import scala.Some import scala.Some
import java.net.{UnknownHostException, InetAddress}
object ShadowVpnService { object ShadowVpnService {
def isServiceStarted: Boolean = { def isServiceStarted: Boolean = {
...@@ -68,7 +66,6 @@ object ShadowVpnService { ...@@ -68,7 +66,6 @@ object ShadowVpnService {
} }
var sRunningInstance: WeakReference[ShadowVpnService] = null var sRunningInstance: WeakReference[ShadowVpnService] = null
} }
class ShadowVpnService extends VpnService { class ShadowVpnService extends VpnService {
...@@ -86,14 +83,50 @@ class ShadowVpnService extends VpnService { ...@@ -86,14 +83,50 @@ class ShadowVpnService extends VpnService {
var conn: ParcelFileDescriptor = null var conn: ParcelFileDescriptor = null
var udpgw: String = null var udpgw: String = null
var notificationManager: NotificationManager = null
var receiver: BroadcastReceiver = null
var appHost: String = null
var remotePort: Int = 0
var localPort: Int = 0
var sitekey: String = null
var settings: SharedPreferences = null
var isGlobalProxy: Boolean = false
var isGFWList: Boolean = false
var isBypassApps: Boolean = false
var isDNSProxy: Boolean = false
var isHTTPProxy: Boolean = false
var encMethod: String = null
var apps: Array[ProxiedApp] = null
val handler: Handler = new Handler {
override def handleMessage(msg: Message) {
val ed: SharedPreferences.Editor = settings.edit
msg.what match {
case MSG_CONNECT_START =>
ed.putBoolean("isConnecting", true)
case MSG_CONNECT_FINISH =>
ed.putBoolean("isConnecting", false)
case MSG_CONNECT_SUCCESS =>
ed.putBoolean("isRunning", true)
case MSG_CONNECT_FAIL =>
ed.putBoolean("isRunning", false)
case MSG_HOST_CHANGE =>
ed.putString("appHost", appHost)
case MSG_STOP_SELF =>
destroy()
stopSelf()
}
ed.commit
super.handleMessage(msg)
}
}
def getPid(name: String): Int = { def getPid(name: String): Int = {
try { try {
val reader: BufferedReader = new BufferedReader(new FileReader(BASE + name + ".pid")) val reader: BufferedReader = new BufferedReader(new FileReader(BASE + name + ".pid"))
val line = reader.readLine val line = reader.readLine
return Integer.valueOf(line) return Integer.valueOf(line)
} } catch {
catch {
case e: FileNotFoundException => { case e: FileNotFoundException => {
Log.e(TAG, "Cannot open pid file: " + name) Log.e(TAG, "Cannot open pid file: " + name)
} }
...@@ -110,8 +143,10 @@ class ShadowVpnService extends VpnService { ...@@ -110,8 +143,10 @@ class ShadowVpnService extends VpnService {
def startShadowsocksDaemon() { def startShadowsocksDaemon() {
new Thread { new Thread {
override def run() { override def run() {
val cmd: String = (BASE + "shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f " + BASE + "shadowsocks.pid") val cmd: String = (BASE +
.format(appHost, remotePort, localPort, sitekey, encMethod) "shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f " +
BASE +
"shadowsocks.pid").format(appHost, remotePort, localPort, sitekey, encMethod)
System.exec(cmd) System.exec(cmd)
} }
}.start() }.start()
...@@ -122,8 +157,7 @@ class ShadowVpnService extends VpnService { ...@@ -122,8 +157,7 @@ class ShadowVpnService extends VpnService {
try { try {
val pi: PackageInfo = getPackageManager.getPackageInfo(getPackageName, 0) val pi: PackageInfo = getPackageManager.getPackageInfo(getPackageName, 0)
version = pi.versionName version = pi.versionName
} } catch {
catch {
case e: PackageManager.NameNotFoundException => { case e: PackageManager.NameNotFoundException => {
version = "Package name not found" version = "Package name not found"
} }
...@@ -141,16 +175,14 @@ class ShadowVpnService extends VpnService { ...@@ -141,16 +175,14 @@ class ShadowVpnService extends VpnService {
encMethod = settings.getString("encMethod", "table") encMethod = settings.getString("encMethod", "table")
try { try {
remotePort = Integer.valueOf(settings.getString("remotePort", "1984")) remotePort = Integer.valueOf(settings.getString("remotePort", "1984"))
} } catch {
catch {
case ex: NumberFormatException => { case ex: NumberFormatException => {
remotePort = 1984 remotePort = 1984
} }
} }
try { try {
localPort = Integer.valueOf(settings.getString("port", "1984")) localPort = Integer.valueOf(settings.getString("port", "1984"))
} } catch {
catch {
case ex: NumberFormatException => { case ex: NumberFormatException => {
localPort = 1984 localPort = 1984
} }
...@@ -214,8 +246,7 @@ class ShadowVpnService extends VpnService { ...@@ -214,8 +246,7 @@ class ShadowVpnService extends VpnService {
t.start() t.start()
try { try {
t.join(300) t.join(300)
} } catch {
catch {
case ignored: InterruptedException => { case ignored: InterruptedException => {
} }
} }
...@@ -249,8 +280,7 @@ class ShadowVpnService extends VpnService { ...@@ -249,8 +280,7 @@ class ShadowVpnService extends VpnService {
val prefix = Array(addr, i.toString).mkString(".") val prefix = Array(addr, i.toString).mkString(".")
if (prefix != prefix3) builder.addRoute(prefix + ".0", 24) if (prefix != prefix3) builder.addRoute(prefix + ".0", 24)
} }
} })
)
builder.addRoute("8.8.0.0", 16) builder.addRoute("8.8.0.0", 16)
} else { } else {
for (i <- 1 to 254) { for (i <- 1 to 254) {
...@@ -274,9 +304,11 @@ class ShadowVpnService extends VpnService { ...@@ -274,9 +304,11 @@ class ShadowVpnService extends VpnService {
val fd = conn.getFd val fd = conn.getFd
val cmd = (BASE + "tun2socks --netif-ipaddr 172.16.0.2 --udpgw-remote-server-addr %s:7300 " + val cmd = (BASE +
"--netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:%d --tunfd %d --tunmtu %d --pid " + BASE + "tun2socks.pid") "tun2socks --netif-ipaddr 172.16.0.2 --udpgw-remote-server-addr %s:7300 " +
.format(udpgw, localPort, fd, VPN_MTU) "--netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:%d --tunfd %d --tunmtu %d --pid " +
BASE +
"tun2socks.pid").format(udpgw, localPort, fd, VPN_MTU)
Log.d(TAG, cmd) Log.d(TAG, cmd)
System.exec(cmd) System.exec(cmd)
...@@ -308,9 +340,12 @@ class ShadowVpnService extends VpnService { ...@@ -308,9 +340,12 @@ class ShadowVpnService extends VpnService {
val contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, openIntent, 0) val contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
val builder: NotificationCompat.Builder = new NotificationCompat.Builder(this) val builder: NotificationCompat.Builder = new NotificationCompat.Builder(this)
builder builder
.setSmallIcon(R.drawable.ic_stat_shadowsocks).setWhen(0) .setSmallIcon(R.drawable.ic_stat_shadowsocks)
.setTicker(title).setContentTitle(getString(R.string.app_name)) .setWhen(0)
.setContentText(info).setContentIntent(contentIntent) .setTicker(title)
.setContentTitle(getString(R.string.app_name))
.setContentText(info)
.setContentIntent(contentIntent)
.setAutoCancel(true) .setAutoCancel(true)
notificationManager.notify(1, builder.build) notificationManager.notify(1, builder.build)
} }
...@@ -328,7 +363,8 @@ class ShadowVpnService extends VpnService { ...@@ -328,7 +363,8 @@ class ShadowVpnService extends VpnService {
EasyTracker.getTracker.sendEvent("service", "start", getVersionName, 0L) EasyTracker.getTracker.sendEvent("service", "start", getVersionName, 0L)
settings = PreferenceManager.getDefaultSharedPreferences(this) settings = PreferenceManager.getDefaultSharedPreferences(this)
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE).asInstanceOf[NotificationManager] notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
.asInstanceOf[NotificationManager]
// register close receiver // register close receiver
val filter = new IntentFilter() val filter = new IntentFilter()
...@@ -337,7 +373,8 @@ class ShadowVpnService extends VpnService { ...@@ -337,7 +373,8 @@ class ShadowVpnService extends VpnService {
receiver = new BroadcastReceiver { receiver = new BroadcastReceiver {
def onReceive(p1: Context, p2: Intent) { def onReceive(p1: Context, p2: Intent) {
destroy() destroy()
stopSelf()} stopSelf()
}
} }
registerReceiver(receiver, filter) registerReceiver(receiver, filter)
} }
...@@ -396,42 +433,4 @@ class ShadowVpnService extends VpnService { ...@@ -396,42 +433,4 @@ class ShadowVpnService extends VpnService {
override def onRevoke() { override def onRevoke() {
stopSelf() stopSelf()
} }
val handler: Handler = new Handler {
override def handleMessage(msg: Message) {
val ed: SharedPreferences.Editor = settings.edit
msg.what match {
case MSG_CONNECT_START =>
ed.putBoolean("isConnecting", true)
case MSG_CONNECT_FINISH =>
ed.putBoolean("isConnecting", false)
case MSG_CONNECT_SUCCESS =>
ed.putBoolean("isRunning", true)
case MSG_CONNECT_FAIL =>
ed.putBoolean("isRunning", false)
case MSG_HOST_CHANGE =>
ed.putString("appHost", appHost)
case MSG_STOP_SELF =>
destroy()
stopSelf()
}
ed.commit
super.handleMessage(msg)
}
}
var notificationManager: NotificationManager = null
var receiver: BroadcastReceiver = null
var appHost: String = null
var remotePort: Int = 0
var localPort: Int = 0
var sitekey: String = null
var settings: SharedPreferences = null
var isGlobalProxy: Boolean = false
var isGFWList: Boolean = false
var isBypassApps: Boolean = false
var isDNSProxy: Boolean = false
var isHTTPProxy: Boolean = false
var encMethod: String = null
var apps: Array[ProxiedApp] = null
} }
\ No newline at end of file
...@@ -44,7 +44,6 @@ import android.content.SharedPreferences ...@@ -44,7 +44,6 @@ import android.content.SharedPreferences
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.preference.PreferenceManager import android.preference.PreferenceManager
class ShadowsocksReceiver extends BroadcastReceiver { class ShadowsocksReceiver extends BroadcastReceiver {
val TAG = "Shadowsocks" val TAG = "Shadowsocks"
...@@ -54,8 +53,7 @@ class ShadowsocksReceiver extends BroadcastReceiver { ...@@ -54,8 +53,7 @@ class ShadowsocksReceiver extends BroadcastReceiver {
var versionName: String = null var versionName: String = null
try { try {
versionName = context.getPackageManager.getPackageInfo(context.getPackageName, 0).versionName versionName = context.getPackageManager.getPackageInfo(context.getPackageName, 0).versionName
} } catch {
catch {
case e: PackageManager.NameNotFoundException => { case e: PackageManager.NameNotFoundException => {
versionName = "NONE" versionName = "NONE"
} }
...@@ -72,8 +70,7 @@ class ShadowsocksReceiver extends BroadcastReceiver { ...@@ -72,8 +70,7 @@ class ShadowsocksReceiver extends BroadcastReceiver {
if (port <= 1024) { if (port <= 1024) {
return return
} }
} } catch {
catch {
case e: Exception => { case e: Exception => {
return return
} }
...@@ -84,7 +81,6 @@ class ShadowsocksReceiver extends BroadcastReceiver { ...@@ -84,7 +81,6 @@ class ShadowsocksReceiver extends BroadcastReceiver {
val it: Intent = new Intent(context, classOf[ShadowsocksService]) val it: Intent = new Intent(context, classOf[ShadowsocksService])
context.startService(it) context.startService(it)
} }
} }
} }
} }
\ No newline at end of file
...@@ -53,6 +53,27 @@ import android.graphics.{Canvas, Bitmap} ...@@ -53,6 +53,27 @@ import android.graphics.{Canvas, Bitmap}
object Utils { object Utils {
val CLOSE_ACTION = "com.github.shadowsocks.ACTION_SHUTDOWN"
val TAG: String = "Shadowsocks"
val ABI_PROP: String = "ro.product.cpu.abi"
val ABI2_PROP: String = "ro.product.cpu.abi2"
val ARM_ABI: String = "arm"
val X86_ABI: String = "x86"
val MIPS_ABI: String = "mips"
val DEFAULT_SHELL: String = "/system/bin/sh"
val DEFAULT_ROOT: String = "/system/bin/su"
val ALTERNATIVE_ROOT: String = "/system/xbin/su"
val DEFAULT_IPTABLES: String = "/data/data/com.github.shadowsocks/iptables"
val ALTERNATIVE_IPTABLES: String = "/system/bin/iptables"
val TIME_OUT: Int = -99
var initialized: Boolean = false
var hasRedirectSupport: Int = -1
var isRoot: Int = -1
var shell: String = null
var root_shell: String = null
var iptables: String = null
var data_path: String = null
var rootTries = 0
def resolve(host: String, addrType: Int): Option[String] = { def resolve(host: String, addrType: Int): Option[String] = {
val lookup = new Lookup(host, addrType) val lookup = new Lookup(host, addrType)
...@@ -124,8 +145,7 @@ object Utils { ...@@ -124,8 +145,7 @@ object Utils {
} }
} }
} }
} } catch {
catch {
case ex: Exception => { case ex: Exception => {
Log.e(TAG, "Failed to get interfaces' addresses.", ex) Log.e(TAG, "Failed to get interfaces' addresses.", ex)
} }
...@@ -153,8 +173,7 @@ object Utils { ...@@ -153,8 +173,7 @@ object Utils {
} }
} }
} }
} } catch {
catch {
case ex: Exception => { case ex: Exception => {
Log.e(TAG, "Failed to get interfaces' addresses.", ex) Log.e(TAG, "Failed to get interfaces' addresses.", ex)
} }
...@@ -189,19 +208,16 @@ object Utils { ...@@ -189,19 +208,16 @@ object Utils {
input = new BufferedReader(new InputStreamReader(p.getInputStream), 1024) input = new BufferedReader(new InputStreamReader(p.getInputStream), 1024)
line = input.readLine line = input.readLine
input.close() input.close()
} } catch {
catch {
case ex: IOException => { case ex: IOException => {
Log.e(TAG, "Unable to read sysprop " + propName, ex) Log.e(TAG, "Unable to read sysprop " + propName, ex)
return null return null
} }
} } finally {
finally {
if (input != null) { if (input != null) {
try { try {
input.close() input.close()
} } catch {
catch {
case ex: IOException => { case ex: IOException => {
Log.e(TAG, "Exception while closing InputStream", ex) Log.e(TAG, "Exception while closing InputStream", ex)
} }
...@@ -246,7 +262,7 @@ object Utils { ...@@ -246,7 +262,7 @@ object Utils {
} }
} }
def drawableToBitmap (drawable: Drawable): Bitmap = { def drawableToBitmap(drawable: Drawable): Bitmap = {
if (drawable.isInstanceOf[BitmapDrawable]) { if (drawable.isInstanceOf[BitmapDrawable]) {
return drawable.asInstanceOf[BitmapDrawable].getBitmap return drawable.asInstanceOf[BitmapDrawable].getBitmap
} }
...@@ -271,15 +287,13 @@ object Utils { ...@@ -271,15 +287,13 @@ object Utils {
try { try {
val appInfo: ApplicationInfo = pm.getApplicationInfo(packages(0), 0) val appInfo: ApplicationInfo = pm.getApplicationInfo(packages(0), 0)
appIcon = pm.getApplicationIcon(appInfo) appIcon = pm.getApplicationIcon(appInfo)
} } catch {
catch {
case e: PackageManager.NameNotFoundException => { case e: PackageManager.NameNotFoundException => {
Log.e(c.getPackageName, "No package found matching with the uid " + uid) Log.e(c.getPackageName, "No package found matching with the uid " + uid)
} }
} }
} }
} } else {
else {
Log.e(c.getPackageName, "Package not found for uid " + uid) Log.e(c.getPackageName, "Package not found for uid " + uid)
} }
appIcon appIcon
...@@ -289,8 +303,7 @@ object Utils { ...@@ -289,8 +303,7 @@ object Utils {
if (data_path == null) { if (data_path == null) {
if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState) { if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState) {
data_path = Environment.getExternalStorageDirectory.getAbsolutePath data_path = Environment.getExternalStorageDirectory.getAbsolutePath
} } else {
else {
data_path = ctx.getFilesDir.getAbsolutePath data_path = ctx.getFilesDir.getAbsolutePath
} }
Log.d(TAG, "Python Data Path: " + data_path) Log.d(TAG, "Python Data Path: " + data_path)
...@@ -346,11 +359,9 @@ object Utils { ...@@ -346,11 +359,9 @@ object Utils {
if (isRoot != -1) return isRoot == 1 if (isRoot != -1) return isRoot == 1
if (new File(DEFAULT_ROOT).exists) { if (new File(DEFAULT_ROOT).exists) {
root_shell = DEFAULT_ROOT root_shell = DEFAULT_ROOT
} } else if (new File(ALTERNATIVE_ROOT).exists) {
else if (new File(ALTERNATIVE_ROOT).exists) {
root_shell = ALTERNATIVE_ROOT root_shell = ALTERNATIVE_ROOT
} } else {
else {
root_shell = "su" root_shell = "su"
} }
val sb = new StringBuilder val sb = new StringBuilder
...@@ -399,8 +410,7 @@ object Utils { ...@@ -399,8 +410,7 @@ object Utils {
try { try {
if (timeout > 0) { if (timeout > 0) {
runner.join(timeout) runner.join(timeout)
} } else {
else {
runner.join() runner.join()
} }
if (runner.isAlive) { if (runner.isAlive) {
...@@ -408,8 +418,7 @@ object Utils { ...@@ -408,8 +418,7 @@ object Utils {
runner.join(1000) runner.join(1000)
return TIME_OUT return TIME_OUT
} }
} } catch {
catch {
case ex: InterruptedException => { case ex: InterruptedException => {
return TIME_OUT return TIME_OUT
} }
...@@ -417,28 +426,6 @@ object Utils { ...@@ -417,28 +426,6 @@ object Utils {
runner.exitcode runner.exitcode
} }
val CLOSE_ACTION = "com.github.shadowsocks.ACTION_SHUTDOWN"
val TAG: String = "Shadowsocks"
val ABI_PROP: String = "ro.product.cpu.abi"
val ABI2_PROP: String = "ro.product.cpu.abi2"
val ARM_ABI: String = "arm"
val X86_ABI: String = "x86"
val MIPS_ABI: String = "mips"
val DEFAULT_SHELL: String = "/system/bin/sh"
val DEFAULT_ROOT: String = "/system/bin/su"
val ALTERNATIVE_ROOT: String = "/system/xbin/su"
val DEFAULT_IPTABLES: String = "/data/data/com.github.shadowsocks/iptables"
val ALTERNATIVE_IPTABLES: String = "/system/bin/iptables"
val TIME_OUT: Int = -99
var initialized: Boolean = false
var hasRedirectSupport: Int = -1
var isRoot: Int = -1
var shell: String = null
var root_shell: String = null
var iptables: String = null
var data_path: String = null
var rootTries = 0
/** /**
* Internal thread used to execute scripts (as root or not). * Internal thread used to execute scripts (as root or not).
* Creates a new script runner. * Creates a new script runner.
...@@ -447,9 +434,13 @@ object Utils { ...@@ -447,9 +434,13 @@ object Utils {
* @param result result output * @param result result output
* @param asroot if true, executes the script as root * @param asroot if true, executes the script as root
*/ */
class ScriptRunner(val scripts: String, class ScriptRunner(val scripts: String, val result: StringBuilder, val asroot: Boolean)
val result: StringBuilder, extends Thread {
val asroot: Boolean) extends Thread {
var exitcode: Int = -1
val pid: Array[Int] = new Array[Int](1)
var pipe: FileDescriptor = null
override def destroy() { override def destroy() {
if (pid(0) != -1) { if (pid(0) != -1) {
Exec.hangupProcessGroup(pid(0)) Exec.hangupProcessGroup(pid(0))
...@@ -464,7 +455,9 @@ object Utils { ...@@ -464,7 +455,9 @@ object Utils {
def createSubprocess(processId: Array[Int], cmd: String): FileDescriptor = { def createSubprocess(processId: Array[Int], cmd: String): FileDescriptor = {
val args = parse(cmd) val args = parse(cmd)
val arg0 = args(0) val arg0 = args(0)
Exec.createSubprocess(if (result != null) 1 else 0, arg0, args, null, scripts + "\nexit\n", processId) Exec
.createSubprocess(if (result != null) 1 else 0, arg0, args, null, scripts + "\nexit\n",
processId)
} }
def parse(cmd: String): Array[String] = { def parse(cmd: String): Array[String] = {
...@@ -515,8 +508,7 @@ object Utils { ...@@ -515,8 +508,7 @@ object Utils {
try { try {
if (this.asroot) { if (this.asroot) {
pipe = createSubprocess(pid, root_shell) pipe = createSubprocess(pid, root_shell)
} } else {
else {
pipe = createSubprocess(pid, getShell) pipe = createSubprocess(pid, getShell)
} }
if (pid(0) != -1) { if (pid(0) != -1) {
...@@ -530,14 +522,12 @@ object Utils { ...@@ -530,14 +522,12 @@ object Utils {
read = stdout.read(buf) read = stdout.read(buf)
result.append(new String(buf, 0, read)) result.append(new String(buf, 0, read))
} }
} } catch {
catch {
case ex: Exception => { case ex: Exception => {
Log.e(TAG, "Cannot execute command", ex) Log.e(TAG, "Cannot execute command", ex)
if (result != null) result.append("\n").append(ex) if (result != null) result.append("\n").append(ex)
} }
} } finally {
finally {
if (pipe != null) { if (pipe != null) {
Exec.close(pipe) Exec.close(pipe)
} }
...@@ -546,10 +536,6 @@ object Utils { ...@@ -546,10 +536,6 @@ object Utils {
} }
} }
} }
var exitcode: Int = -1
val pid: Array[Int] = new Array[Int](1)
var pipe: FileDescriptor = null
} }
} }
\ No newline at end of file
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