From 32561d39fc824c9ebf7f574934e166159ab6fa93 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sun, 13 Oct 2013 11:29:39 +0800 Subject: [PATCH] update Google Analytics and Tag Manager --- build.sbt | 6 +- local.sbt.example | 6 +- project/Build.scala | 2 +- .../scala/be/jvb/iptypes/IpAddressPool.scala | 36 +++++------ .../scala/be/jvb/iptypes/IpAddressRange.scala | 4 +- .../com/github/shadowsocks/AppManager.scala | 4 +- .../github/shadowsocks/ShadowVpnService.scala | 53 +++++++++++------ .../com/github/shadowsocks/Shadowsocks.scala | 20 ++++--- .../shadowsocks/ShadowsocksApplication.scala | 14 +++-- .../shadowsocks/ShadowsocksService.scala | 35 +++++++++-- .../scala/com/github/shadowsocks/Utils.scala | 59 +++++++++---------- 11 files changed, 144 insertions(+), 95 deletions(-) diff --git a/build.sbt b/build.sbt index 0a01f5e0..1db72bac 100644 --- a/build.sbt +++ b/build.sbt @@ -1,8 +1,8 @@ libraryDependencies ++= Seq( "com.google.android" % "support-v4" % "r12", - "com.google.android.analytics" % "analytics" % "2.0beta4", - "dnsjava" % "dnsjava" % "2.1.5", - "com.google.android.admob" % "admob" % "6.3.1" + "com.google.android" % "analytics" % "3.01", + "com.google.android" % "admob" % "6.4.1", + "dnsjava" % "dnsjava" % "2.1.5" ) libraryDependencies ++= Seq( diff --git a/local.sbt.example b/local.sbt.example index 994eb3be..738d9e8f 100644 --- a/local.sbt.example +++ b/local.sbt.example @@ -2,8 +2,4 @@ import sbtandroid.AndroidPlugin._ keyalias := "travis" -publicServer := "127.0.0.1" - -publicPorts := "443" - -publicMethod := "rc4" +containerId := "GTM-XXXX" diff --git a/project/Build.scala b/project/Build.scala index f0bdc0a2..cf010882 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -15,7 +15,7 @@ object General { name := "shadowsocks", version := App.version, versionCode := App.versionCode, - scalaVersion := "2.9.2", + scalaVersion := "2.10.3", compileOrder := CompileOrder.JavaThenScala, platformName := "android-16", resolvers += "madeye-maven" at "http://madeye-maven-repository.googlecode.com/git", diff --git a/src/main/scala/be/jvb/iptypes/IpAddressPool.scala b/src/main/scala/be/jvb/iptypes/IpAddressPool.scala index 6e845e89..df3bbf00 100644 --- a/src/main/scala/be/jvb/iptypes/IpAddressPool.scala +++ b/src/main/scala/be/jvb/iptypes/IpAddressPool.scala @@ -39,7 +39,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip } private def checkWithinBounds(toValidate: SortedSet[IpAddressRange]): Boolean = { - return (toValidate.firstKey.first >= first && toValidate.lastKey.last <= last) + toValidate.firstKey.first >= first && toValidate.lastKey.last <= last } /** @@ -52,9 +52,9 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip // get the first range of free addresses, and take the first address of that range val range: IpAddressRange = freeRanges.firstKey val toAllocate: IpAddress = range.first - return doAllocate(toAllocate, range) + doAllocate(toAllocate, range) } else { - return (this, None) + (this, None) } } @@ -84,13 +84,13 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip // the range we need is either the first of the tail, or the last of the head, or it doesn't exist if (!head.isEmpty && head.lastKey.contains(toAllocate)) { - return Some(head.lastKey) + Some(head.lastKey) } else if (!tail.isEmpty && tail.firstKey.contains(toAllocate)) { - return Some(tail.firstKey) + Some(tail.firstKey) } else { - return None + None } } @@ -103,7 +103,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip val newRanges = range - toAllocate // note: the cast to SortedSet is a workaround until scala 2.8 (http://stackoverflow.com/questions/1271426/scala-immutable-sortedset-are-not-stable-on-deletion) val remainingRanges = (freeRanges ++ newRanges).asInstanceOf[SortedSet[IpAddressRange]] - range - return (new IpAddressPool(this.first, this.last, remainingRanges.asInstanceOf[SortedSet[IpAddressRange]]), Some(toAllocate)) + (new IpAddressPool(this.first, this.last, remainingRanges.asInstanceOf[SortedSet[IpAddressRange]]), Some(toAllocate)) } /** @@ -115,7 +115,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip if (!contains(address)) throw new IllegalArgumentException("can not deallocate address which is not contained in the range of the pool [" + address + "]") - return new IpAddressPool(first, last, addAddressToFreeRanges(address)) + new IpAddressPool(first, last, addAddressToFreeRanges(address)) } /** @@ -128,24 +128,24 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip if (freeRangeBeforeAddress.isEmpty && freeRangeAfterAddress.isEmpty) { // no match -> nothing to "defragment" - return freeRanges + new IpAddressRange(address, address) + freeRanges + new IpAddressRange(address, address) } else { if (!freeRangeBeforeAddress.isEmpty && !freeRangeAfterAddress.isEmpty) { // first and last match -> merge the 2 existing ranges - return (freeRanges - + (freeRanges - freeRangeBeforeAddress.toSeq(0) - freeRangeAfterAddress.toSeq(0) + new IpAddressRange(freeRangeBeforeAddress.toSeq(0).first, freeRangeAfterAddress.toSeq(0).last)). asInstanceOf[SortedSet[IpAddressRange]] // workaround, see above } else if (!freeRangeBeforeAddress.isEmpty) { // append - return (freeRanges - + (freeRanges - freeRangeBeforeAddress.toSeq(0) + (freeRangeBeforeAddress.toSeq(0) + address)). asInstanceOf[SortedSet[IpAddressRange]] // workaround, see above } else { // prepend - return (freeRanges - + (freeRanges - freeRangeAfterAddress.toSeq(0) + (freeRangeAfterAddress.toSeq(0) + address)). asInstanceOf[SortedSet[IpAddressRange]] // workaround, see above @@ -153,7 +153,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip } } - def isExhausted(): Boolean = { + def isExhausted: Boolean = { freeRanges.isEmpty } @@ -187,7 +187,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip * @return ranges of allocated addresses in the pool * @note the pool implementation keeps track of the free addresses, so this operation is more expensive than the freeRanges() one */ - def allocatedRanges(): List[IpAddressRange] = { + def allocatedRanges: List[IpAddressRange] = { if (freeRanges.isEmpty) { // one big range of allocated addresses List[IpAddressRange](new IpAddressRange(first, last)) @@ -203,14 +203,14 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip for (freeRange <- freeRanges) { currentEnd = freeRange.first if (currentEnd != currentStart) { // occurs if first free range starts at the beginning of the pool - allocatedRanges + new IpAddressRange(currentStart, currentEnd - 1) + allocatedRanges.append(new IpAddressRange(currentStart, currentEnd - 1)) } currentStart = freeRange.last + 1 } if (currentStart <= last) { // occurs if the last free range didn't reach until the end of the pool - allocatedRanges + new IpAddressRange(currentStart, last) + allocatedRanges.append(new IpAddressRange(currentStart, last)) } - return allocatedRanges.toList + allocatedRanges.toList } @@ -227,7 +227,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip } } - override def toString(): String = { + override def toString: String = { "IpAddressPool " + super.toString + " with free ranges " + freeRanges.toString } diff --git a/src/main/scala/be/jvb/iptypes/IpAddressRange.scala b/src/main/scala/be/jvb/iptypes/IpAddressRange.scala index 45193caf..77dd8cd8 100644 --- a/src/main/scala/be/jvb/iptypes/IpAddressRange.scala +++ b/src/main/scala/be/jvb/iptypes/IpAddressRange.scala @@ -30,9 +30,9 @@ class IpAddressRange(val first: IpAddress, val last: IpAddress) extends Ordered[ last.value - first.value + 1 } - def addresses(): Stream[IpAddress] = { + def addresses: Stream[IpAddress] = { if (first < last) { - Stream.cons(first, new IpAddressRange(first + 1, last).addresses()) + Stream.cons(first, new IpAddressRange(first + 1, last).addresses) } else { Stream.cons(first, Stream.empty) } diff --git a/src/main/scala/com/github/shadowsocks/AppManager.scala b/src/main/scala/com/github/shadowsocks/AppManager.scala index c384fea1..ae532824 100644 --- a/src/main/scala/com/github/shadowsocks/AppManager.scala +++ b/src/main/scala/com/github/shadowsocks/AppManager.scala @@ -256,12 +256,12 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl protected override def onStart() { super.onStart() - EasyTracker.getInstance.activityStart(this) + EasyTracker.getInstance(this).activityStart(this) } protected override def onStop() { super.onStop() - EasyTracker.getInstance.activityStop(this) + EasyTracker.getInstance(this).activityStop(this) } def saveAppSettings(context: Context) { diff --git a/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala b/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala index 33e9fd7b..32e8e55d 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowVpnService.scala @@ -46,7 +46,7 @@ import android.content.pm.PackageManager import android.os._ import android.support.v4.app.NotificationCompat import android.util.Log -import com.google.analytics.tracking.android.EasyTracker +import com.google.analytics.tracking.android.{Fields, MapBuilder, EasyTracker} import java.io._ import android.net.VpnService import org.apache.http.conn.util.InetAddressUtils @@ -188,6 +188,19 @@ class ShadowVpnService extends VpnService { config = Extra.get(intent) spawn { + + if (config.proxy == "198.199.101.152") { + val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer + if (container == null) { + notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) + stopSelf() + handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 500) + return + } else { + config = Config.getPublicConfig(container, config) + } + } + killProcesses() // Resolve server address @@ -236,15 +249,10 @@ class ShadowVpnService extends VpnService { def startVpn() { - val proxy_address = new IpAddress(config.proxy) - val private_networks = Array[IpNetwork]( - new IpNetwork("127.0.0.0/8"), - new IpNetwork("10.0.0.0/8"), - new IpNetwork("172.16.0.0/12"), - new IpNetwork("192.168.0.0/16") - ) + val private_networks = Array[IpNetwork](new IpNetwork("127.0.0.0/8"), + new IpNetwork("10.0.0.0/8"), new IpNetwork("172.16.0.0/12"), new IpNetwork("192.168.0.0/16")) val builder = new Builder() builder @@ -258,10 +266,9 @@ class ShadowVpnService extends VpnService { } else if (config.isGFWList) { val gfwList = getResources.getStringArray(R.array.gfw_list) gfwList.foreach(addr => { - val network = new IpNetwork(addr) + val network = new IpNetwork(addr) if (!network.contains(proxy_address)) { builder.addRoute(network.address.toString, network.mask.prefixLength) - Log.d(Shadowsocks.TAG, "add route: " + addr) } }) } else { @@ -269,7 +276,7 @@ class ShadowVpnService extends VpnService { val network = new IpNetwork(i.toString + ".0.0.0/8") if (!network.contains(proxy_address) && private_networks.forall(range => !network.contains(range))) { - builder.addRoute(i + ".0.0.0", 8) + builder.addRoute(i + ".0.0.0", 8) } else { for (j <- 0 to 255) { val subNetwork = new IpNetwork(i.toString + "." + j.toString + ".0.0/16") @@ -313,7 +320,8 @@ class ShadowVpnService extends VpnService { + "--tunmtu %d " + "--loglevel 3 " + "--pid %stun2socks.pid") - .format(PRIVATE_VLAN.format("2"), PRIVATE_VLAN.format("1"), config.localPort, fd, VPN_MTU, BASE) + .format(PRIVATE_VLAN.format("2"), PRIVATE_VLAN.format("1"), config.localPort, fd, VPN_MTU, + BASE) if (BuildConfig.DEBUG) Log.d(TAG, cmd) System.exec(cmd) } @@ -357,8 +365,14 @@ class ShadowVpnService extends VpnService { override def onCreate() { super.onCreate() - EasyTracker.getTracker.setStartSession(true) - EasyTracker.getTracker.sendEvent(TAG, "start", getVersionName, 0L) + + EasyTracker + .getInstance(this) + .send(MapBuilder + .createEvent(TAG, "start", getVersionName, 0L) + .set(Fields.SESSION_CONTROL, "start") + .build()) + notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) .asInstanceOf[NotificationManager] @@ -379,7 +393,14 @@ class ShadowVpnService extends VpnService { killProcesses() changeState(State.STOPPED) - EasyTracker.getTracker.sendEvent(TAG, "stop", getVersionName, 0L) + + EasyTracker + .getInstance(this) + .send(MapBuilder + .createEvent(TAG, "stop", getVersionName, 0L) + .set(Fields.SESSION_CONTROL, "stop") + .build()) + if (receiver != null) { unregisterReceiver(receiver) receiver = null @@ -393,8 +414,6 @@ class ShadowVpnService extends VpnService { /** Called when the activity is closed. */ override def onDestroy() { - EasyTracker.getTracker.setStartSession(false) - EasyTracker.getTracker.sendEvent(TAG, "stop", getVersionName, 0L) destroy() super.onDestroy() } diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 5eb62008..9ea7c0b8 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -47,7 +47,7 @@ import android.preference._ import android.util.Log import android.view._ import android.widget._ -import com.google.analytics.tracking.android.EasyTracker +import com.google.analytics.tracking.android.{MapBuilder, EasyTracker} import de.keyboardsurfer.android.widget.crouton.Crouton import de.keyboardsurfer.android.widget.crouton.Style import java.io._ @@ -78,6 +78,8 @@ import scala.Option import android.view.ViewGroup.LayoutParams import com.github.shadowsocks.database.Item import com.github.shadowsocks.database.Category +import com.google.tagmanager.{Container, ContainerOpener, TagManager} +import com.google.tagmanager.ContainerOpener.{Notifier, OpenType} class ProfileIconDownloader(context: Context, connectTimeout: Int, readTimeout: Int) extends BaseImageDownloader(context, connectTimeout, readTimeout) { @@ -666,18 +668,21 @@ class Shadowsocks buf += new Category("Settings") buf += new Item(-100, getString(R.string.recovery), android.R.drawable.ic_menu_revert, _ => { - EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "reset", getVersionName, 0L) + EasyTracker.getInstance(this).send( + MapBuilder.createEvent(Shadowsocks.TAG, "reset", getVersionName, null).build()) recovery() }) buf += new Item(-200, getString(R.string.flush_dnscache), android.R.drawable.ic_menu_delete, _ => { - EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "flush_dnscache", getVersionName, 0L) + EasyTracker.getInstance(this).send( + MapBuilder.createEvent(Shadowsocks.TAG, "flush_dnscache", getVersionName, null).build()) flushDnsCache() }) buf += new Item(-300, getString(R.string.about), android.R.drawable.ic_menu_info_details, _ => { - EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "about", getVersionName, 0L) + EasyTracker.getInstance(this).send( + MapBuilder.createEvent(Shadowsocks.TAG, "about", getVersionName, null).build()) showAbout() }) @@ -687,7 +692,8 @@ class Shadowsocks override def onOptionsItemSelected(item: MenuItem): Boolean = { item.getItemId match { case android.R.id.home => { - EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "home", getVersionName, 0L) + EasyTracker.getInstance(this).send( + MapBuilder.createEvent(Shadowsocks.TAG, "home", getVersionName, null).build()) drawer.toggleMenu() return true } @@ -769,12 +775,12 @@ class Shadowsocks override def onStart() { super.onStart() - EasyTracker.getInstance.activityStart(this) + EasyTracker.getInstance(this).activityStart(this) } override def onStop() { super.onStop() - EasyTracker.getInstance.activityStop(this) + EasyTracker.getInstance(this).activityStop(this) clearDialog() } diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala index 9a3703ab..5629d89b 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala @@ -39,14 +39,20 @@ package com.github.shadowsocks import android.app.Application -import com.google.analytics.tracking.android.EasyTracker -import com.github.shadowsocks.database.{ProfileManager, DBHelper} +import com.github.shadowsocks.database.DBHelper +import com.google.tagmanager.{Container, ContainerOpener, TagManager} +import com.google.tagmanager.ContainerOpener.{Notifier, OpenType} class ShadowsocksApplication extends Application { lazy val dbHelper = new DBHelper(this) + var tagContainer: Container = null override def onCreate() { - EasyTracker.getInstance.setContext(this) + val tm = TagManager.getInstance(this) + ContainerOpener.openContainer(tm, BuildConfig.CONTAINER_ID, OpenType.PREFER_FRESH, null, new Notifier { + override def containerAvailable(container: Container) { + tagContainer = container + } + }) } - } diff --git a/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala b/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala index c88b56ad..c2eb51a2 100644 --- a/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala +++ b/src/main/scala/com/github/shadowsocks/ShadowsocksService.scala @@ -49,7 +49,7 @@ import android.content.pm.PackageManager import android.os._ import android.support.v4.app.NotificationCompat import android.util.Log -import com.google.analytics.tracking.android.EasyTracker +import com.google.analytics.tracking.android.{Fields, MapBuilder, EasyTracker} import java.io._ import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method @@ -224,6 +224,19 @@ class ShadowsocksService extends Service { } spawn { + + if (config.proxy == "198.199.101.152") { + val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer + if (container == null) { + notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) + stopSelf() + handler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 500) + return + } else { + config = Config.getPublicConfig(container, config) + } + } + killProcesses() var resolved: Boolean = false @@ -374,8 +387,14 @@ class ShadowsocksService extends Service { override def onCreate() { super.onCreate() - EasyTracker.getTracker.setStartSession(true) - EasyTracker.getTracker.sendEvent(TAG, "start", getVersionName, 0L) + + EasyTracker + .getInstance(this) + .send(MapBuilder + .createEvent(TAG, "start", getVersionName, 0L) + .set(Fields.SESSION_CONTROL, "start") + .build()) + notificationManager = this .getSystemService(Context.NOTIFICATION_SERVICE) .asInstanceOf[NotificationManager] @@ -422,8 +441,14 @@ class ShadowsocksService extends Service { // clean up context changeState(State.STOPPED) - EasyTracker.getTracker.setStartSession(false) - EasyTracker.getTracker.sendEvent(TAG, "stop", getVersionName, 0L) + + EasyTracker + .getInstance(this) + .send(MapBuilder + .createEvent(TAG, "stop", getVersionName, 0L) + .set(Fields.SESSION_CONTROL, "stop") + .build()) + stopForegroundCompat(1) if (receiver != null) { unregisterReceiver(receiver) diff --git a/src/main/scala/com/github/shadowsocks/Utils.scala b/src/main/scala/com/github/shadowsocks/Utils.scala index 3d91e454..932c1fbb 100644 --- a/src/main/scala/com/github/shadowsocks/Utils.scala +++ b/src/main/scala/com/github/shadowsocks/Utils.scala @@ -48,12 +48,12 @@ import java.net.{UnknownHostException, InetAddress, NetworkInterface} import org.apache.http.conn.util.InetAddressUtils import scala.collection.mutable.ArrayBuffer import org.xbill.DNS._ -import scala.Some import android.graphics._ import android.app.ActivityManager import android.os.Build import android.provider.Settings import scala.Some +import com.google.tagmanager.Container object Config { val SHADOWSOCKS = "{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}" @@ -110,11 +110,21 @@ object Config { p.close() } } + + def getPublicConfig(container: Container, config: Config): Config = { + val host = container.getString("host") + val port = util.Random.shuffle(container.getString("port").split(',').toSeq).toSeq(0).toInt + val method = container.getString("method") + val password = container.getString("password") + + new Config(config.isGlobalProxy, config.isGFWList, config.isBypassApps, config.isTrafficStat, + config.profileName, host, password, method, port, config.localPort, config.proxiedAppString) + } } -case class Config(isGlobalProxy: Boolean, isGFWList: Boolean, isBypassApps: Boolean, isTrafficStat: Boolean, - profileName: String, var proxy: String, sitekey: String, encMethod: String, remotePort: Int, - localPort: Int, proxiedAppString: String) +case class Config(isGlobalProxy: Boolean, isGFWList: Boolean, isBypassApps: Boolean, + isTrafficStat: Boolean, profileName: String, var proxy: String, sitekey: String, + encMethod: String, remotePort: Int, localPort: Int, proxiedAppString: String) object Key { val profileId = "profileId" @@ -196,8 +206,8 @@ object Extra { val localPort = intent.getIntExtra(Key.localPort, 1984) val proxiedString = intent.getStringExtra(Key.proxied) - new Config(isGlobalProxy, isGFWList, isBypassApps, isTrafficStat, profileName, proxy, sitekey, encMethod, remotePort, - localPort, proxiedString) + new Config(isGlobalProxy, isGFWList, isBypassApps, isTrafficStat, profileName, proxy, sitekey, + encMethod, remotePort, localPort, proxiedString) } def put(settings: SharedPreferences, intent: Intent) { @@ -206,33 +216,20 @@ object Extra { val isBypassApps = settings.getBoolean(Key.isBypassApps, false) val isTrafficStat = settings.getBoolean(Key.isTrafficStat, false) + val profileName = settings.getString(Key.profileName, "default") - val proxy = settings.getString(Key.proxy, "127.0.0.1") match { - case "198.199.101.152" => BuildConfig.SERVER - case s: String => s - case _ => "127.0.0.1" - } + val proxy = settings.getString(Key.proxy, "127.0.0.1") val sitekey = settings.getString(Key.sitekey, "default") - val encMethod = { - if (proxy == BuildConfig.SERVER) { - BuildConfig.METHOD - } else { - settings.getString(Key.encMethod, "table") - } - } + val encMethod = settings.getString(Key.encMethod, "table") val remotePort: Int = try { - if (proxy == BuildConfig.SERVER) { - scala.util.Random.shuffle(BuildConfig.PORTS.toSeq).toSeq(0) - } else { - Integer.valueOf(settings.getString(Key.remotePort, "1984")) - } + settings.getString(Key.remotePort, "1984").toInt } catch { case ex: NumberFormatException => { 1984 } } val localProt: Int = try { - Integer.valueOf(settings.getString(Key.localPort, "1984")) + settings.getString(Key.localPort, "1984").toInt } catch { case ex: NumberFormatException => { 1984 @@ -283,19 +280,18 @@ object Utils { * round or floor depending on whether you are using offsets(floor) or * widths(round) */ - def dpToPx (context: Context, dp: Float): Float = { + def dpToPx(context: Context, dp: Float): Float = { val density = context.getResources.getDisplayMetrics.density dp * density } - def pxToDp (context: Context, px: Float): Float = { + 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 bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val size = bitmap.getHeight / 4 val canvas = new Canvas(bitmap) canvas.drawColor(background) @@ -304,7 +300,8 @@ object Utils { paint.setTextSize(size) val bounds = new Rect() paint.getTextBounds(text, 0, text.length, bounds) - canvas.drawText(text, (bitmap.getWidth - bounds.width()) / 2, + canvas + .drawText(text, (bitmap.getWidth - bounds.width()) / 2, bitmap.getHeight - (bitmap.getHeight - bounds.height()) / 2, paint) bitmap } @@ -323,8 +320,7 @@ object Utils { Utils.runRootCommand("settings put global airplane_mode_on 1\n" + "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true\n" + "settings put global airplane_mode_on 0\n" - + "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false\n" - ) + + "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false\n") } private def toggleBelowApiLevel17(context: Context) { @@ -792,6 +788,7 @@ object Utils { } } } + }