Commit 0b7fb75b authored by Mygod's avatar Mygod

Obsolete code cleanup

parent c52c33f3
......@@ -29,7 +29,6 @@ resolvers += "JRAF" at "http://JRAF.org/static/maven/2"
libraryDependencies ++= Seq(
"dnsjava" % "dnsjava" % "2.1.7",
"com.github.kevinsawicki" % "http-request" % "6.0",
"commons-net" % "commons-net" % "3.5",
"eu.chainfire" % "libsuperuser" % "1.0.0.201602271131",
"com.google.zxing" % "android-integration" % "3.2.1",
"net.glxn.qrgen" % "android" % "2.0",
......
......@@ -4,7 +4,6 @@ import com.github.shadowsocks.aidl.Config;
import com.github.shadowsocks.aidl.IShadowsocksServiceCallback;
interface IShadowsocksService {
int getMode();
int getState();
oneway void registerCallback(IShadowsocksServiceCallback cb);
......
......@@ -60,7 +60,7 @@ trait BaseService extends Service {
final val callbacks = new RemoteCallbackList[IShadowsocksServiceCallback]
var callbacksCount: Int = _
lazy val handler = new Handler(getContext.getMainLooper)
lazy val handler = new Handler(getMainLooper)
private val closeReceiver: BroadcastReceiver = (context: Context, intent: Intent) => {
Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show()
......@@ -69,10 +69,6 @@ trait BaseService extends Service {
var closeReceiverRegistered: Boolean = _
val binder = new IShadowsocksService.Stub {
override def getMode: Int = {
getServiceMode
}
override def getState: Int = {
state
}
......@@ -125,7 +121,7 @@ trait BaseService extends Service {
def startRunner(config: Config) {
this.config = config
startService(new Intent(getContext, getClass))
startService(new Intent(this, getClass))
TrafficMonitor.reset()
trafficMonitorThread = new TrafficMonitorThread(getApplicationContext)
trafficMonitorThread.start()
......@@ -176,16 +172,9 @@ trait BaseService extends Service {
}
}
def getServiceMode: Int
def getTag: String
def getContext: Context
def getState: Int = {
state
}
def changeState(s: Int) {
changeState(s, null)
}
def updateTrafficRate() {
handler.post(() => {
......@@ -210,8 +199,8 @@ trait BaseService extends Service {
// Service of shadowsocks should always be started explicitly
override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = Service.START_NOT_STICKY
protected def changeState(s: Int, msg: String) {
val handler = new Handler(getContext.getMainLooper)
protected def changeState(s: Int, msg: String = null) {
val handler = new Handler(getMainLooper)
handler.post(() => if (state != s) {
if (callbacksCount > 0) {
val n = callbacks.beginBroadcast()
......
......@@ -56,7 +56,7 @@ import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.util.Log
import android.view.{View, ViewGroup, ViewParent}
import android.view.{View, ViewGroup}
import android.widget._
import com.github.jorgecastilloprz.FABProgressCircle
import com.github.shadowsocks.aidl.IShadowsocksServiceCallback
......@@ -88,29 +88,25 @@ object Typefaces {
}
object Shadowsocks {
// Constants
val TAG = "Shadowsocks"
val REQUEST_CONNECT = 1
val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL,
private final val TAG = "Shadowsocks"
private final val REQUEST_CONNECT = 1
private val EXECUTABLES = Array(Executable.PDNSD, Executable.REDSOCKS, Executable.SS_TUNNEL, Executable.SS_LOCAL,
Executable.TUN2SOCKS)
}
class Shadowsocks
extends AppCompatActivity with ServiceBoundContext {
class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
import Shadowsocks._
// Variables
var serviceStarted = false
var fab: FloatingActionButton = _
var fabProgressCircle: FABProgressCircle = _
var progressDialog: ProgressDialog = _
var progressTag = -1
var state = State.STOPPED
var currentProfile = new Profile
// Services
var currentServiceName = classOf[ShadowsocksNatService].getName
private val callback = new IShadowsocksServiceCallback.Stub {
def stateChanged(s: Int, m: String) {
handler.post(() => if (state != s) {
......@@ -148,7 +144,7 @@ class Shadowsocks
if (m == getString(R.string.nat_no_root)) snackbar.setAction(R.string.switch_to_vpn,
(_ => preferences.natSwitch.setChecked(false)): View.OnClickListener)
snackbar.show
Log.e(Shadowsocks.TAG, "Error to start VPN service: " + m)
Log.e(TAG, "Error to start VPN service: " + m)
}
preferences.setEnabled(true)
stat.setVisibility(View.GONE)
......@@ -230,7 +226,7 @@ class Shadowsocks
private lazy val preferences =
getFragmentManager.findFragmentById(android.R.id.content).asInstanceOf[ShadowsocksSettings]
var handler = new Handler()
val handler = new Handler()
private def changeSwitch(checked: Boolean) {
serviceStarted = checked
......@@ -244,7 +240,6 @@ class Shadowsocks
private def showProgress(msg: Int): Handler = {
clearDialog()
progressDialog = ProgressDialog.show(this, "", getString(msg), true, false)
progressTag = msg
new Handler {
override def handleMessage(msg: Message) {
clearDialog()
......@@ -259,7 +254,7 @@ class Shadowsocks
files = assetManager.list(path)
} catch {
case e: IOException =>
Log.e(Shadowsocks.TAG, e.getMessage)
Log.e(TAG, e.getMessage)
}
if (files != null) {
for (file <- files) {
......@@ -280,7 +275,7 @@ class Shadowsocks
out = null
} catch {
case ex: Exception =>
Log.e(Shadowsocks.TAG, ex.getMessage)
Log.e(TAG, ex.getMessage)
}
}
}
......@@ -331,7 +326,7 @@ class Shadowsocks
}
if (ShadowsocksApplication.isVpnEnabled) Console.runCommand(cmd.toArray) else {
Console.runRootCommand(cmd.toArray)
Console.runRootCommand(Utils.getIptables + " -t nat -F OUTPUT")
Console.runRootCommand(Utils.iptables + " -t nat -F OUTPUT")
}
}
......@@ -345,9 +340,9 @@ class Shadowsocks
if (ShadowsocksApplication.isVpnEnabled) {
val intent = VpnService.prepare(this)
if (intent != null) {
startActivityForResult(intent, Shadowsocks.REQUEST_CONNECT)
startActivityForResult(intent, REQUEST_CONNECT)
} else {
handler.post(() => onActivityResult(Shadowsocks.REQUEST_CONNECT, Activity.RESULT_OK, null))
handler.post(() => onActivityResult(REQUEST_CONNECT, Activity.RESULT_OK, null))
}
} else {
serviceLoad()
......@@ -355,13 +350,6 @@ class Shadowsocks
}
}
def getLayoutView(view: ViewParent): LinearLayout = {
view match {
case layout: LinearLayout => layout
case _ => if (view != null) getLayoutView(view.getParent) else null
}
}
override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
......@@ -565,7 +553,7 @@ class Shadowsocks
copyAssets(System.getABI)
val ab = new ArrayBuffer[String]
for (executable <- Shadowsocks.EXECUTABLES) {
for (executable <- EXECUTABLES) {
ab.append("chmod 755 " + getApplicationInfo.dataDir + "/" + executable)
}
Console.runCommand(ab.toArray)
......@@ -594,7 +582,7 @@ class Shadowsocks
serviceLoad()
case _ =>
cancelStart()
Log.e(Shadowsocks.TAG, "Failed to start VpnService")
Log.e(TAG, "Failed to start VpnService")
}
def serviceStop() {
......@@ -621,7 +609,6 @@ class Shadowsocks
if (progressDialog != null && progressDialog.isShowing) {
if (!isDestroyed) progressDialog.dismiss()
progressDialog = null
progressTag = -1
}
}
}
......@@ -45,7 +45,6 @@ import java.net.{Inet6Address, InetAddress}
import java.util.Locale
import android.content._
import android.content.pm.{PackageInfo, PackageManager}
import android.net.{ConnectivityManager, Network}
import android.os._
import android.util.{Log, SparseArray}
......@@ -64,7 +63,6 @@ class ShadowsocksNatService extends BaseService {
"-j DNAT --to-destination 127.0.0.1:8123"
private var notification: ShadowsocksNotification = _
var connReceiver: BroadcastReceiver = _
val myUid = android.os.Process.myUid()
var sslocalProcess: Process = _
......@@ -144,21 +142,6 @@ class ShadowsocksNatService extends BaseService {
}
}
def destroyConnectionReceiver() {
if (connReceiver != null) {
unregisterReceiver(connReceiver)
connReceiver = null
}
resetDns()
}
def initConnectionReceiver() {
val filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
connReceiver = (context: Context, intent: Intent) => setupDns()
registerReceiver(connReceiver, filter)
}
def startShadowsocksDaemon() {
if (config.route != Route.ALL) {
val acl: Array[Array[String]] = config.route match {
......@@ -250,8 +233,8 @@ class ShadowsocksNatService extends BaseService {
def startDnsDaemon() {
val conf = if (config.route == Route.BYPASS_CHN || config.route == Route.BYPASS_LAN_CHN) {
val reject = ConfigUtils.getRejectList(getContext)
val blackList = ConfigUtils.getBlackList(getContext)
val reject = ConfigUtils.getRejectList(this)
val blackList = ConfigUtils.getBlackList(this)
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
"127.0.0.1", 8153, reject, blackList, 8163, "")
} else {
......@@ -269,18 +252,6 @@ class ShadowsocksNatService extends BaseService {
pdnsdProcess = new GuardedProcess(cmd.split(" ").toSeq).start()
}
def getVersionName: String = {
var version: String = null
try {
val pi: PackageInfo = getPackageManager.getPackageInfo(getPackageName, 0)
version = pi.versionName
} catch {
case e: PackageManager.NameNotFoundException =>
version = "Package name not found"
}
version
}
def startRedsocksDaemon() {
val conf = ConfigUtils.REDSOCKS.formatLocal(Locale.ENGLISH, config.localPort)
val cmd = "%s/redsocks -c %s/redsocks-nat.conf"
......@@ -337,7 +308,7 @@ class ShadowsocksNatService extends BaseService {
pdnsdProcess = null
}
Console.runRootCommand(Utils.getIptables + " -t nat -F OUTPUT")
Console.runRootCommand(Utils.iptables + " -t nat -F OUTPUT")
}
def setupIptables() = {
......@@ -345,9 +316,9 @@ class ShadowsocksNatService extends BaseService {
val http_sb = new ArrayBuffer[String]
init_sb.append("ulimit -n 4096")
init_sb.append(Utils.getIptables + " -t nat -F OUTPUT")
init_sb.append(Utils.iptables + " -t nat -F OUTPUT")
val cmd_bypass = Utils.getIptables + CMD_IPTABLES_RETURN
val cmd_bypass = Utils.iptables + CMD_IPTABLES_RETURN
if (!InetAddress.getByName(config.proxy.toUpperCase).isInstanceOf[Inet6Address]) {
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d " + config.proxy))
}
......@@ -355,18 +326,18 @@ class ShadowsocksNatService extends BaseService {
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-m owner --uid-owner " + myUid))
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport 53"))
init_sb.append(Utils.getIptables
init_sb.append(Utils.iptables
+ " -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:8153")
if (!config.isProxyApps || config.isBypassApps) {
http_sb.append(Utils.getIptables + CMD_IPTABLES_DNAT_ADD_SOCKS)
http_sb.append(Utils.iptables + CMD_IPTABLES_DNAT_ADD_SOCKS)
}
if (config.isProxyApps) {
val uidMap = getPackageManager.getInstalledApplications(0).map(ai => ai.packageName -> ai.uid).toMap
for (pn <- config.proxiedAppString.split('\n')) uidMap.get(pn) match {
case Some(uid) =>
if (!config.isBypassApps) {
http_sb.append((Utils.getIptables + CMD_IPTABLES_DNAT_ADD_SOCKS)
http_sb.append((Utils.iptables + CMD_IPTABLES_DNAT_ADD_SOCKS)
.replace("-t nat", "-t nat -m owner --uid-owner " + uid))
} else {
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + uid))
......@@ -448,8 +419,4 @@ class ShadowsocksNatService extends BaseService {
super.stopRunner(stopService)
}
override def getTag = TAG
override def getServiceMode = Mode.NAT
override def getContext = getBaseContext
}
......@@ -40,13 +40,20 @@
package com.github.shadowsocks
import android.app.{Activity, KeyguardManager}
import android.content.{Intent, IntentFilter, Context, BroadcastReceiver}
import android.content.{BroadcastReceiver, Context, Intent, IntentFilter}
import android.net.VpnService
import android.os.{Bundle, Handler}
import android.util.Log
import com.github.shadowsocks.utils.ConfigUtils
object ShadowsocksRunnerActivity {
private final val TAG = "ShadowsocksRunnerActivity"
private final val REQUEST_CONNECT = 1
}
class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
import ShadowsocksRunnerActivity._
val handler = new Handler()
// Variables
......@@ -60,9 +67,9 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
if (ShadowsocksApplication.isVpnEnabled) {
val intent = VpnService.prepare(ShadowsocksRunnerActivity.this)
if (intent != null) {
startActivityForResult(intent, Shadowsocks.REQUEST_CONNECT)
startActivityForResult(intent, REQUEST_CONNECT)
} else {
onActivityResult(Shadowsocks.REQUEST_CONNECT, Activity.RESULT_OK, null)
onActivityResult(REQUEST_CONNECT, Activity.RESULT_OK, null)
}
} else {
bgService.use(ConfigUtils.load(ShadowsocksApplication.settings))
......@@ -104,7 +111,7 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
bgService.use(ConfigUtils.load(ShadowsocksApplication.settings))
}
case _ =>
Log.e(Shadowsocks.TAG, "Failed to start VpnService")
Log.e(TAG, "Failed to start VpnService")
}
finish()
}
......
......@@ -45,13 +45,11 @@ import java.util.Locale
import android.content._
import android.content.pm.PackageManager.NameNotFoundException
import android.content.pm.{PackageInfo, PackageManager}
import android.net.VpnService
import android.os._
import android.util.Log
import com.github.shadowsocks.aidl.Config
import com.github.shadowsocks.utils._
import org.apache.commons.net.util.SubnetUtils
import scala.collection.mutable.ArrayBuffer
......@@ -69,27 +67,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
var pdnsdProcess: Process = _
var tun2socksProcess: Process = _
def isByass(net: SubnetUtils): Boolean = {
val info = net.getInfo
info.isInRange(config.proxy)
}
def isPrivateA(a: Int): Boolean = {
if (a == 10 || a == 192 || a == 172) {
true
} else {
false
}
}
def isPrivateB(a: Int, b: Int): Boolean = {
if (a == 10 || (a == 192 && b == 168) || (a == 172 && b >= 16 && b < 32)) {
true
} else {
false
}
}
override def onBind(intent: Intent): IBinder = {
val action = intent.getAction
if (VpnService.SERVICE_INTERFACE == action) {
......@@ -135,18 +112,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
super.stopRunner(stopService)
}
def getVersionName: String = {
var version: String = null
try {
val pi: PackageInfo = getPackageManager.getPackageInfo(getPackageName, 0)
version = pi.versionName
} catch {
case e: PackageManager.NameNotFoundException =>
version = "Package name not found"
}
version
}
def killProcesses() {
if (sslocalProcess != null) {
sslocalProcess.destroy()
......@@ -311,8 +276,8 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val ipv6 = if (config.isIpv6) "" else "reject = ::/0;"
val conf = {
if (config.route == Route.BYPASS_CHN || config.route == Route.BYPASS_LAN_CHN) {
val reject = ConfigUtils.getRejectList(getContext)
val blackList = ConfigUtils.getBlackList(getContext)
val reject = ConfigUtils.getRejectList(this)
val blackList = ConfigUtils.getBlackList(this)
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, getApplicationInfo.dataDir,
"0.0.0.0", 8153, reject, blackList, 8163, ipv6)
} else {
......@@ -330,8 +295,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
pdnsdProcess = new GuardedProcess(cmd.split(" ").toSeq).start()
}
override def getContext = getBaseContext
def startVpn(): Int = {
val builder = new Builder()
......@@ -435,8 +398,4 @@ class ShadowsocksVpnService extends VpnService with BaseService {
}
false
}
override def getTag = TAG
override def getServiceMode = Mode.VPN
}
......@@ -96,49 +96,6 @@ object ConfigUtils {
|}
""".stripMargin
val PDNSD_BYPASS =
"""
|global {
| perm_cache = 2048;
| cache_dir = "%s";
| server_ip = %s;
| server_port = %d;
| query_method = tcp_only;
| run_ipv4 = on;
| min_ttl = 15m;
| max_ttl = 1w;
| timeout = 10;
| daemon = off;
|}
|
|server {
| label = "china-servers";
| ip = 114.114.114.114, 223.5.5.5;
| uptest = none;
| preset = on;
| include = %s;
| policy = excluded;
| timeout = 2;
|}
|
|server {
| label = "local-server";
| ip = 127.0.0.1;
| uptest = none;
| preset = on;
| port = %d;
| timeout = 5;
|}
|
|rr {
| name=localhost;
| reverse=on;
| a=127.0.0.1;
| owner=localhost;
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|}
""".stripMargin
val PDNSD_DIRECT =
"""
|global {
......
......@@ -63,10 +63,6 @@ object Console {
.open()
}
def runCommand(command: String) {
runCommand(Array(command))
}
def runCommand(commands: Array[String]) {
val shell = openShell()
shell.addCommand(commands, 0, ((commandCode: Int, exitCode: Int, output: util.List[String]) =>
......
......@@ -44,17 +44,9 @@ object Executable {
val PDNSD = "pdnsd"
val SS_LOCAL = "ss-local"
val SS_TUNNEL = "ss-tunnel"
val IPTABLES = "iptables"
val TUN2SOCKS = "tun2socks"
}
object Msg {
val CONNECT_FINISH = 1
val CONNECT_SUCCESS = 2
val CONNECT_FAIL = 3
val VPN_ERROR = 6
}
object Key {
val profileId = "profileId"
val profileName = "profileName"
......@@ -63,9 +55,7 @@ object Key {
val isNAT = "isNAT"
val route = "route"
val stat = "stat"
val isRunning = "isRunning"
val isAutoConnect = "isAutoConnect"
val isProxyApps = "isProxyApps"
......@@ -83,17 +73,6 @@ object Key {
val profileTip = "profileTip"
}
object Scheme {
val APP = "app://"
val PROFILE = "profile://"
val SS = "ss"
}
object Mode {
val NAT = 0
val VPN = 1
}
object State {
val CONNECTING = 1
val CONNECTED = 2
......
......@@ -49,8 +49,6 @@ object TaskerSettings {
def fromIntent(intent: Intent) = new TaskerSettings(if (intent.hasExtra(ApiIntent.EXTRA_BUNDLE))
intent.getBundleExtra(ApiIntent.EXTRA_BUNDLE) else Bundle.EMPTY)
def fromBundle(bundle: Bundle) = new TaskerSettings(bundle)
}
class TaskerSettings(bundle: Bundle) {
......
......@@ -38,19 +38,15 @@
*/
package com.github.shadowsocks.utils
import java.io._
import java.net._
import java.security.MessageDigest
import android.animation.{Animator, AnimatorListenerAdapter}
import android.app.ActivityManager
import android.content.pm.{ApplicationInfo, PackageManager}
import android.content.pm.PackageManager
import android.content.{Context, Intent}
import android.graphics._
import android.graphics.drawable.{BitmapDrawable, Drawable}
import android.os.Build
import android.provider.Settings
import android.support.v4.content.ContextCompat
import android.util.{Base64, DisplayMetrics, Log}
import android.view.View.MeasureSpec
import android.view.{Gravity, View, Window}
......@@ -61,12 +57,19 @@ import org.xbill.DNS._
object Utils {
val TAG: String = "Shadowsocks"
val DEFAULT_IPTABLES: String = "/system/bin/iptables"
val ALTERNATIVE_IPTABLES: String = "iptables"
var initialized: Boolean = false
var hasRedirectSupport: Int = -1
var iptables: String = null
private val TAG = "Shadowsocks"
/**
* Check the system's iptables
* Default to use the app's iptables
*/
private val DEFAULT_IPTABLES = "/system/bin/iptables"
private val ALTERNATIVE_IPTABLES = "iptables"
lazy val iptables = if (Console.isRoot) {
val lines = Console.runRootCommand(DEFAULT_IPTABLES + " --version", DEFAULT_IPTABLES + " -L -t nat -n")
if (Console.isRoot && lines != null && !lines.contains("OUTPUT") || !lines.contains("v1.4.")) ALTERNATIVE_IPTABLES
else DEFAULT_IPTABLES
} else DEFAULT_IPTABLES
def isLollipopOrAbove: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
......@@ -86,31 +89,6 @@ object Utils {
* round or floor depending on whether you are using offsets(floor) or
* widths(round)
*/
def dpToPx(context: Context, dp: Float): Float = {
val density = context.getResources.getDisplayMetrics.density
dp * density
}
def pxToDp(context: Context, px: Float): Float = {
val density = context.getResources.getDisplayMetrics.density
px / density
}
def getBitmap(text: String, width: Int, height: Int, background: Int): Bitmap = {
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val size = bitmap.getHeight / 4
val canvas = new Canvas(bitmap)
canvas.drawColor(background)
val paint = new Paint()
paint.setColor(Color.WHITE)
paint.setTextSize(size)
val bounds = new Rect()
paint.getTextBounds(text, 0, text.length, bounds)
canvas
.drawText(text, (bitmap.getWidth - bounds.width()) / 2,
bitmap.getHeight - (bitmap.getHeight - bounds.height()) / 2, paint)
bitmap
}
// Based on: http://stackoverflow.com/a/21026866/2245107
def positionToast(toast: Toast, view: View, window: Window, offsetX: Int = 0, offsetY: Int = 0) = {
......@@ -165,25 +143,6 @@ object Utils {
context.sendBroadcast(disableIntent)
}
def isServiceStarted(name: String, context: Context): Boolean = {
import scala.collection.JavaConversions._
val activityManager = context
.getSystemService(Context.ACTIVITY_SERVICE)
.asInstanceOf[ActivityManager]
val services = activityManager.getRunningServices(Integer.MAX_VALUE)
if (services != null) {
for (service <- services) {
if (service.service.getClassName == name) {
return true
}
}
}
false
}
def resolve(host: String, addrType: Int): Option[String] = {
try {
val lookup = new Lookup(host, addrType)
......@@ -240,31 +199,6 @@ object Utils {
private lazy val isNumericMethod = classOf[InetAddress].getMethod("isNumeric", classOf[String])
def isNumeric(address: String): Boolean = isNumericMethod.invoke(null, address).asInstanceOf[Boolean]
/**
* Get local IPv4 address
*/
def getIPv4Address: Option[String] = {
try {
val interfaces = NetworkInterface.getNetworkInterfaces
while (interfaces.hasMoreElements) {
val intf = interfaces.nextElement()
val addrs = intf.getInetAddresses
while (addrs.hasMoreElements) {
val addr = addrs.nextElement()
if (!addr.isLoopbackAddress && !addr.isLinkLocalAddress) {
if (addr.isInstanceOf[Inet4Address]) {
return Some(addr.getHostAddress.toUpperCase)
}
}
}
}
} catch {
case ex: Exception =>
Log.e(TAG, "Failed to get interfaces' addresses.", ex)
}
None
}
/**
* If there exists a valid IPv6 interface
*/
......@@ -291,116 +225,6 @@ object Utils {
false
}
/**
* Check the system's iptables
* Default to use the app's iptables
*/
def checkIptables() {
if (!Console.isRoot) {
iptables = DEFAULT_IPTABLES
return
}
iptables = DEFAULT_IPTABLES
var compatible: Boolean = false
var version: Boolean = false
val lines = Console.runRootCommand(iptables + " --version", iptables + " -L -t nat -n")
if (lines == null) return
if (lines.contains("OUTPUT")) {
compatible = true
}
if (lines.contains("v1.4.")) {
version = true
}
if (!compatible || !version) {
iptables = ALTERNATIVE_IPTABLES
if (!new File(iptables).exists) iptables = "iptables"
}
}
def drawableToBitmap(drawable: Drawable): Bitmap = {
drawable match {
case d: BitmapDrawable =>
return d.getBitmap
case _ =>
}
val width = if (drawable.getIntrinsicWidth > 0) drawable.getIntrinsicWidth else 1
val height = if (drawable.getIntrinsicWidth > 0) drawable.getIntrinsicWidth else 1
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = new Canvas(bitmap)
drawable.setBounds(0, 0, canvas.getWidth, canvas.getHeight)
drawable.draw(canvas)
bitmap
}
def getAppIcon(c: Context, packageName: String): Drawable = {
val pm: PackageManager = c.getPackageManager
val icon: Drawable = ContextCompat.getDrawable(c, android.R.drawable.sym_def_app_icon)
try {
pm.getApplicationIcon(packageName)
} catch {
case e: PackageManager.NameNotFoundException => icon
}
}
def getAppIcon(c: Context, uid: Int): Drawable = {
val pm: PackageManager = c.getPackageManager
val icon: Drawable = ContextCompat.getDrawable(c, android.R.drawable.sym_def_app_icon)
val packages: Array[String] = pm.getPackagesForUid(uid)
if (packages != null) {
if (packages.length >= 1) {
try {
val appInfo: ApplicationInfo = pm.getApplicationInfo(packages(0), 0)
return pm.getApplicationIcon(appInfo)
} catch {
case e: PackageManager.NameNotFoundException =>
Log.e(c.getPackageName, "No package found matching with the uid " + uid)
}
}
} else {
Log.e(c.getPackageName, "Package not found for uid " + uid)
}
icon
}
def getHasRedirectSupport: Boolean = {
if (hasRedirectSupport == -1) initHasRedirectSupported()
hasRedirectSupport == 1
}
def getIptables: String = {
if (iptables == null) checkIptables()
iptables
}
def initHasRedirectSupported() {
if (!Console.isRoot) return
hasRedirectSupport = 1
val command = Utils.getIptables + " -t nat -A OUTPUT -p udp --dport 54 -j REDIRECT --to 8154"
val lines = Console.runRootCommand(command, command.replace("-A", "-D"))
if (lines == null) return
if (lines.contains("No chain/target/match")) {
hasRedirectSupport = 0
}
}
def isInitialized: Boolean = {
initialized match {
case true => true
case _ =>
initialized = true
false
}
}
def startSsService(context: Context) {
val isInstalled: Boolean = ShadowsocksApplication.settings.getBoolean(ShadowsocksApplication.getVersionName, false)
if (!isInstalled) return
......@@ -414,5 +238,3 @@ object Utils {
context.sendBroadcast(intent)
}
}
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