Commit 32561d39 authored by Max Lv's avatar Max Lv

update Google Analytics and Tag Manager

parent c96dde86
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"com.google.android" % "support-v4" % "r12", "com.google.android" % "support-v4" % "r12",
"com.google.android.analytics" % "analytics" % "2.0beta4", "com.google.android" % "analytics" % "3.01",
"dnsjava" % "dnsjava" % "2.1.5", "com.google.android" % "admob" % "6.4.1",
"com.google.android.admob" % "admob" % "6.3.1" "dnsjava" % "dnsjava" % "2.1.5"
) )
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
......
...@@ -2,8 +2,4 @@ import sbtandroid.AndroidPlugin._ ...@@ -2,8 +2,4 @@ import sbtandroid.AndroidPlugin._
keyalias := "travis" keyalias := "travis"
publicServer := "127.0.0.1" containerId := "GTM-XXXX"
publicPorts := "443"
publicMethod := "rc4"
...@@ -15,7 +15,7 @@ object General { ...@@ -15,7 +15,7 @@ object General {
name := "shadowsocks", name := "shadowsocks",
version := App.version, version := App.version,
versionCode := App.versionCode, versionCode := App.versionCode,
scalaVersion := "2.9.2", scalaVersion := "2.10.3",
compileOrder := CompileOrder.JavaThenScala, compileOrder := CompileOrder.JavaThenScala,
platformName := "android-16", platformName := "android-16",
resolvers += "madeye-maven" at "http://madeye-maven-repository.googlecode.com/git", resolvers += "madeye-maven" at "http://madeye-maven-repository.googlecode.com/git",
......
...@@ -39,7 +39,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip ...@@ -39,7 +39,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip
} }
private def checkWithinBounds(toValidate: SortedSet[IpAddressRange]): Boolean = { 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 ...@@ -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 // get the first range of free addresses, and take the first address of that range
val range: IpAddressRange = freeRanges.firstKey val range: IpAddressRange = freeRanges.firstKey
val toAllocate: IpAddress = range.first val toAllocate: IpAddress = range.first
return doAllocate(toAllocate, range) doAllocate(toAllocate, range)
} else { } else {
return (this, None) (this, None)
} }
} }
...@@ -84,13 +84,13 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip ...@@ -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 // 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)) { if (!head.isEmpty && head.lastKey.contains(toAllocate)) {
return Some(head.lastKey) Some(head.lastKey)
} }
else if (!tail.isEmpty && tail.firstKey.contains(toAllocate)) { else if (!tail.isEmpty && tail.firstKey.contains(toAllocate)) {
return Some(tail.firstKey) Some(tail.firstKey)
} }
else { else {
return None None
} }
} }
...@@ -103,7 +103,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip ...@@ -103,7 +103,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip
val newRanges = range - toAllocate 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) // 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 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 ...@@ -115,7 +115,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip
if (!contains(address)) if (!contains(address))
throw new IllegalArgumentException("can not deallocate address which is not contained in the range of the pool [" + 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 ...@@ -128,24 +128,24 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip
if (freeRangeBeforeAddress.isEmpty && freeRangeAfterAddress.isEmpty) { if (freeRangeBeforeAddress.isEmpty && freeRangeAfterAddress.isEmpty) {
// no match -> nothing to "defragment" // no match -> nothing to "defragment"
return freeRanges + new IpAddressRange(address, address) freeRanges + new IpAddressRange(address, address)
} else { } else {
if (!freeRangeBeforeAddress.isEmpty && !freeRangeAfterAddress.isEmpty) { if (!freeRangeBeforeAddress.isEmpty && !freeRangeAfterAddress.isEmpty) {
// first and last match -> merge the 2 existing ranges // first and last match -> merge the 2 existing ranges
return (freeRanges - (freeRanges -
freeRangeBeforeAddress.toSeq(0) - freeRangeBeforeAddress.toSeq(0) -
freeRangeAfterAddress.toSeq(0) + freeRangeAfterAddress.toSeq(0) +
new IpAddressRange(freeRangeBeforeAddress.toSeq(0).first, freeRangeAfterAddress.toSeq(0).last)). new IpAddressRange(freeRangeBeforeAddress.toSeq(0).first, freeRangeAfterAddress.toSeq(0).last)).
asInstanceOf[SortedSet[IpAddressRange]] // workaround, see above asInstanceOf[SortedSet[IpAddressRange]] // workaround, see above
} else if (!freeRangeBeforeAddress.isEmpty) { } else if (!freeRangeBeforeAddress.isEmpty) {
// append // append
return (freeRanges - (freeRanges -
freeRangeBeforeAddress.toSeq(0) + freeRangeBeforeAddress.toSeq(0) +
(freeRangeBeforeAddress.toSeq(0) + address)). (freeRangeBeforeAddress.toSeq(0) + address)).
asInstanceOf[SortedSet[IpAddressRange]] // workaround, see above asInstanceOf[SortedSet[IpAddressRange]] // workaround, see above
} else { } else {
// prepend // prepend
return (freeRanges - (freeRanges -
freeRangeAfterAddress.toSeq(0) + freeRangeAfterAddress.toSeq(0) +
(freeRangeAfterAddress.toSeq(0) + address)). (freeRangeAfterAddress.toSeq(0) + address)).
asInstanceOf[SortedSet[IpAddressRange]] // workaround, see above asInstanceOf[SortedSet[IpAddressRange]] // workaround, see above
...@@ -153,7 +153,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip ...@@ -153,7 +153,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip
} }
} }
def isExhausted(): Boolean = { def isExhausted: Boolean = {
freeRanges.isEmpty freeRanges.isEmpty
} }
...@@ -187,7 +187,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip ...@@ -187,7 +187,7 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip
* @return ranges of allocated addresses in the pool * @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 * @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) { if (freeRanges.isEmpty) {
// one big range of allocated addresses // one big range of allocated addresses
List[IpAddressRange](new IpAddressRange(first, last)) List[IpAddressRange](new IpAddressRange(first, last))
...@@ -203,14 +203,14 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip ...@@ -203,14 +203,14 @@ class IpAddressPool private(override val first: IpAddress, override val last: Ip
for (freeRange <- freeRanges) { for (freeRange <- freeRanges) {
currentEnd = freeRange.first currentEnd = freeRange.first
if (currentEnd != currentStart) { // occurs if first free range starts at the beginning of the pool 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 currentStart = freeRange.last + 1
} }
if (currentStart <= last) { // occurs if the last free range didn't reach until the end of the pool 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 ...@@ -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 "IpAddressPool " + super.toString + " with free ranges " + freeRanges.toString
} }
......
...@@ -30,9 +30,9 @@ class IpAddressRange(val first: IpAddress, val last: IpAddress) extends Ordered[ ...@@ -30,9 +30,9 @@ class IpAddressRange(val first: IpAddress, val last: IpAddress) extends Ordered[
last.value - first.value + 1 last.value - first.value + 1
} }
def addresses(): Stream[IpAddress] = { def addresses: Stream[IpAddress] = {
if (first < last) { if (first < last) {
Stream.cons(first, new IpAddressRange(first + 1, last).addresses()) Stream.cons(first, new IpAddressRange(first + 1, last).addresses)
} else { } else {
Stream.cons(first, Stream.empty) Stream.cons(first, Stream.empty)
} }
......
...@@ -256,12 +256,12 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -256,12 +256,12 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
protected override def onStart() { protected override def onStart() {
super.onStart() super.onStart()
EasyTracker.getInstance.activityStart(this) EasyTracker.getInstance(this).activityStart(this)
} }
protected override def onStop() { protected override def onStop() {
super.onStop() super.onStop()
EasyTracker.getInstance.activityStop(this) EasyTracker.getInstance(this).activityStop(this)
} }
def saveAppSettings(context: Context) { def saveAppSettings(context: Context) {
......
...@@ -46,7 +46,7 @@ import android.content.pm.PackageManager ...@@ -46,7 +46,7 @@ import android.content.pm.PackageManager
import android.os._ import android.os._
import android.support.v4.app.NotificationCompat import android.support.v4.app.NotificationCompat
import android.util.Log 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.io._
import android.net.VpnService import android.net.VpnService
import org.apache.http.conn.util.InetAddressUtils import org.apache.http.conn.util.InetAddressUtils
...@@ -188,6 +188,19 @@ class ShadowVpnService extends VpnService { ...@@ -188,6 +188,19 @@ class ShadowVpnService extends VpnService {
config = Extra.get(intent) config = Extra.get(intent)
spawn { 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() killProcesses()
// Resolve server address // Resolve server address
...@@ -236,15 +249,10 @@ class ShadowVpnService extends VpnService { ...@@ -236,15 +249,10 @@ class ShadowVpnService extends VpnService {
def startVpn() { def startVpn() {
val proxy_address = new IpAddress(config.proxy) val proxy_address = new IpAddress(config.proxy)
val private_networks = Array[IpNetwork]( val private_networks = Array[IpNetwork](new IpNetwork("127.0.0.0/8"),
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"))
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() val builder = new Builder()
builder builder
...@@ -258,10 +266,9 @@ class ShadowVpnService extends VpnService { ...@@ -258,10 +266,9 @@ class ShadowVpnService extends VpnService {
} else if (config.isGFWList) { } else if (config.isGFWList) {
val gfwList = getResources.getStringArray(R.array.gfw_list) val gfwList = getResources.getStringArray(R.array.gfw_list)
gfwList.foreach(addr => { gfwList.foreach(addr => {
val network = new IpNetwork(addr) val network = new IpNetwork(addr)
if (!network.contains(proxy_address)) { if (!network.contains(proxy_address)) {
builder.addRoute(network.address.toString, network.mask.prefixLength) builder.addRoute(network.address.toString, network.mask.prefixLength)
Log.d(Shadowsocks.TAG, "add route: " + addr)
} }
}) })
} else { } else {
...@@ -269,7 +276,7 @@ class ShadowVpnService extends VpnService { ...@@ -269,7 +276,7 @@ class ShadowVpnService extends VpnService {
val network = new IpNetwork(i.toString + ".0.0.0/8") val network = new IpNetwork(i.toString + ".0.0.0/8")
if (!network.contains(proxy_address) && if (!network.contains(proxy_address) &&
private_networks.forall(range => !network.contains(range))) { private_networks.forall(range => !network.contains(range))) {
builder.addRoute(i + ".0.0.0", 8) builder.addRoute(i + ".0.0.0", 8)
} else { } else {
for (j <- 0 to 255) { for (j <- 0 to 255) {
val subNetwork = new IpNetwork(i.toString + "." + j.toString + ".0.0/16") val subNetwork = new IpNetwork(i.toString + "." + j.toString + ".0.0/16")
...@@ -313,7 +320,8 @@ class ShadowVpnService extends VpnService { ...@@ -313,7 +320,8 @@ class ShadowVpnService extends VpnService {
+ "--tunmtu %d " + "--tunmtu %d "
+ "--loglevel 3 " + "--loglevel 3 "
+ "--pid %stun2socks.pid") + "--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) if (BuildConfig.DEBUG) Log.d(TAG, cmd)
System.exec(cmd) System.exec(cmd)
} }
...@@ -357,8 +365,14 @@ class ShadowVpnService extends VpnService { ...@@ -357,8 +365,14 @@ class ShadowVpnService extends VpnService {
override def onCreate() { override def onCreate() {
super.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) notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
.asInstanceOf[NotificationManager] .asInstanceOf[NotificationManager]
...@@ -379,7 +393,14 @@ class ShadowVpnService extends VpnService { ...@@ -379,7 +393,14 @@ class ShadowVpnService extends VpnService {
killProcesses() killProcesses()
changeState(State.STOPPED) 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) { if (receiver != null) {
unregisterReceiver(receiver) unregisterReceiver(receiver)
receiver = null receiver = null
...@@ -393,8 +414,6 @@ class ShadowVpnService extends VpnService { ...@@ -393,8 +414,6 @@ class ShadowVpnService extends VpnService {
/** Called when the activity is closed. */ /** Called when the activity is closed. */
override def onDestroy() { override def onDestroy() {
EasyTracker.getTracker.setStartSession(false)
EasyTracker.getTracker.sendEvent(TAG, "stop", getVersionName, 0L)
destroy() destroy()
super.onDestroy() super.onDestroy()
} }
......
...@@ -47,7 +47,7 @@ import android.preference._ ...@@ -47,7 +47,7 @@ import android.preference._
import android.util.Log import android.util.Log
import android.view._ import android.view._
import android.widget._ 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.Crouton
import de.keyboardsurfer.android.widget.crouton.Style import de.keyboardsurfer.android.widget.crouton.Style
import java.io._ import java.io._
...@@ -78,6 +78,8 @@ import scala.Option ...@@ -78,6 +78,8 @@ import scala.Option
import android.view.ViewGroup.LayoutParams import android.view.ViewGroup.LayoutParams
import com.github.shadowsocks.database.Item import com.github.shadowsocks.database.Item
import com.github.shadowsocks.database.Category 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) class ProfileIconDownloader(context: Context, connectTimeout: Int, readTimeout: Int)
extends BaseImageDownloader(context, connectTimeout, readTimeout) { extends BaseImageDownloader(context, connectTimeout, readTimeout) {
...@@ -666,18 +668,21 @@ class Shadowsocks ...@@ -666,18 +668,21 @@ class Shadowsocks
buf += new Category("Settings") buf += new Category("Settings")
buf += new Item(-100, getString(R.string.recovery), android.R.drawable.ic_menu_revert, _ => { 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() recovery()
}) })
buf += buf +=
new Item(-200, getString(R.string.flush_dnscache), android.R.drawable.ic_menu_delete, _ => { 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() flushDnsCache()
}) })
buf += new Item(-300, getString(R.string.about), android.R.drawable.ic_menu_info_details, _ => { 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() showAbout()
}) })
...@@ -687,7 +692,8 @@ class Shadowsocks ...@@ -687,7 +692,8 @@ class Shadowsocks
override def onOptionsItemSelected(item: MenuItem): Boolean = { override def onOptionsItemSelected(item: MenuItem): Boolean = {
item.getItemId match { item.getItemId match {
case android.R.id.home => { 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() drawer.toggleMenu()
return true return true
} }
...@@ -769,12 +775,12 @@ class Shadowsocks ...@@ -769,12 +775,12 @@ class Shadowsocks
override def onStart() { override def onStart() {
super.onStart() super.onStart()
EasyTracker.getInstance.activityStart(this) EasyTracker.getInstance(this).activityStart(this)
} }
override def onStop() { override def onStop() {
super.onStop() super.onStop()
EasyTracker.getInstance.activityStop(this) EasyTracker.getInstance(this).activityStop(this)
clearDialog() clearDialog()
} }
......
...@@ -39,14 +39,20 @@ ...@@ -39,14 +39,20 @@
package com.github.shadowsocks package com.github.shadowsocks
import android.app.Application import android.app.Application
import com.google.analytics.tracking.android.EasyTracker import com.github.shadowsocks.database.DBHelper
import com.github.shadowsocks.database.{ProfileManager, DBHelper} import com.google.tagmanager.{Container, ContainerOpener, TagManager}
import com.google.tagmanager.ContainerOpener.{Notifier, OpenType}
class ShadowsocksApplication extends Application { class ShadowsocksApplication extends Application {
lazy val dbHelper = new DBHelper(this) lazy val dbHelper = new DBHelper(this)
var tagContainer: Container = null
override def onCreate() { 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
}
})
} }
} }
...@@ -49,7 +49,7 @@ import android.content.pm.PackageManager ...@@ -49,7 +49,7 @@ import android.content.pm.PackageManager
import android.os._ import android.os._
import android.support.v4.app.NotificationCompat import android.support.v4.app.NotificationCompat
import android.util.Log 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.io._
import java.lang.reflect.InvocationTargetException import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method import java.lang.reflect.Method
...@@ -224,6 +224,19 @@ class ShadowsocksService extends Service { ...@@ -224,6 +224,19 @@ class ShadowsocksService extends Service {
} }
spawn { 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() killProcesses()
var resolved: Boolean = false var resolved: Boolean = false
...@@ -374,8 +387,14 @@ class ShadowsocksService extends Service { ...@@ -374,8 +387,14 @@ class ShadowsocksService extends Service {
override def onCreate() { override def onCreate() {
super.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 notificationManager = this
.getSystemService(Context.NOTIFICATION_SERVICE) .getSystemService(Context.NOTIFICATION_SERVICE)
.asInstanceOf[NotificationManager] .asInstanceOf[NotificationManager]
...@@ -422,8 +441,14 @@ class ShadowsocksService extends Service { ...@@ -422,8 +441,14 @@ class ShadowsocksService extends Service {
// clean up context // clean up context
changeState(State.STOPPED) 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) stopForegroundCompat(1)
if (receiver != null) { if (receiver != null) {
unregisterReceiver(receiver) unregisterReceiver(receiver)
......
...@@ -48,12 +48,12 @@ import java.net.{UnknownHostException, InetAddress, NetworkInterface} ...@@ -48,12 +48,12 @@ import java.net.{UnknownHostException, InetAddress, NetworkInterface}
import org.apache.http.conn.util.InetAddressUtils import org.apache.http.conn.util.InetAddressUtils
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
import org.xbill.DNS._ import org.xbill.DNS._
import scala.Some
import android.graphics._ import android.graphics._
import android.app.ActivityManager import android.app.ActivityManager
import android.os.Build import android.os.Build
import android.provider.Settings import android.provider.Settings
import scala.Some import scala.Some
import com.google.tagmanager.Container
object Config { object Config {
val SHADOWSOCKS = "{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}" val SHADOWSOCKS = "{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}"
...@@ -110,11 +110,21 @@ object Config { ...@@ -110,11 +110,21 @@ object Config {
p.close() 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, case class Config(isGlobalProxy: Boolean, isGFWList: Boolean, isBypassApps: Boolean,
profileName: String, var proxy: String, sitekey: String, encMethod: String, remotePort: Int, isTrafficStat: Boolean, profileName: String, var proxy: String, sitekey: String,
localPort: Int, proxiedAppString: String) encMethod: String, remotePort: Int, localPort: Int, proxiedAppString: String)
object Key { object Key {
val profileId = "profileId" val profileId = "profileId"
...@@ -196,8 +206,8 @@ object Extra { ...@@ -196,8 +206,8 @@ object Extra {
val localPort = intent.getIntExtra(Key.localPort, 1984) val localPort = intent.getIntExtra(Key.localPort, 1984)
val proxiedString = intent.getStringExtra(Key.proxied) val proxiedString = intent.getStringExtra(Key.proxied)
new Config(isGlobalProxy, isGFWList, isBypassApps, isTrafficStat, profileName, proxy, sitekey, encMethod, remotePort, new Config(isGlobalProxy, isGFWList, isBypassApps, isTrafficStat, profileName, proxy, sitekey,
localPort, proxiedString) encMethod, remotePort, localPort, proxiedString)
} }
def put(settings: SharedPreferences, intent: Intent) { def put(settings: SharedPreferences, intent: Intent) {
...@@ -206,33 +216,20 @@ object Extra { ...@@ -206,33 +216,20 @@ object Extra {
val isBypassApps = settings.getBoolean(Key.isBypassApps, false) val isBypassApps = settings.getBoolean(Key.isBypassApps, false)
val isTrafficStat = settings.getBoolean(Key.isTrafficStat, false) val isTrafficStat = settings.getBoolean(Key.isTrafficStat, false)
val profileName = settings.getString(Key.profileName, "default") val profileName = settings.getString(Key.profileName, "default")
val proxy = settings.getString(Key.proxy, "127.0.0.1") match { val proxy = settings.getString(Key.proxy, "127.0.0.1")
case "198.199.101.152" => BuildConfig.SERVER
case s: String => s
case _ => "127.0.0.1"
}
val sitekey = settings.getString(Key.sitekey, "default") val sitekey = settings.getString(Key.sitekey, "default")
val encMethod = { val encMethod = settings.getString(Key.encMethod, "table")
if (proxy == BuildConfig.SERVER) {
BuildConfig.METHOD
} else {
settings.getString(Key.encMethod, "table")
}
}
val remotePort: Int = try { val remotePort: Int = try {
if (proxy == BuildConfig.SERVER) { settings.getString(Key.remotePort, "1984").toInt
scala.util.Random.shuffle(BuildConfig.PORTS.toSeq).toSeq(0)
} else {
Integer.valueOf(settings.getString(Key.remotePort, "1984"))
}
} catch { } catch {
case ex: NumberFormatException => { case ex: NumberFormatException => {
1984 1984
} }
} }
val localProt: Int = try { val localProt: Int = try {
Integer.valueOf(settings.getString(Key.localPort, "1984")) settings.getString(Key.localPort, "1984").toInt
} catch { } catch {
case ex: NumberFormatException => { case ex: NumberFormatException => {
1984 1984
...@@ -283,19 +280,18 @@ object Utils { ...@@ -283,19 +280,18 @@ object Utils {
* round or floor depending on whether you are using offsets(floor) or * round or floor depending on whether you are using offsets(floor) or
* widths(round) * widths(round)
*/ */
def dpToPx (context: Context, dp: Float): Float = { def dpToPx(context: Context, dp: Float): Float = {
val density = context.getResources.getDisplayMetrics.density val density = context.getResources.getDisplayMetrics.density
dp * density dp * density
} }
def pxToDp (context: Context, px: Float): Float = { def pxToDp(context: Context, px: Float): Float = {
val density = context.getResources.getDisplayMetrics.density val density = context.getResources.getDisplayMetrics.density
px / density px / density
} }
def getBitmap(text: String, width: Int, height: Int, background: Int): Bitmap = { def getBitmap(text: String, width: Int, height: Int, background: Int): Bitmap = {
val bitmap = Bitmap.createBitmap(width, val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
height, Bitmap.Config.ARGB_8888)
val size = bitmap.getHeight / 4 val size = bitmap.getHeight / 4
val canvas = new Canvas(bitmap) val canvas = new Canvas(bitmap)
canvas.drawColor(background) canvas.drawColor(background)
...@@ -304,7 +300,8 @@ object Utils { ...@@ -304,7 +300,8 @@ object Utils {
paint.setTextSize(size) paint.setTextSize(size)
val bounds = new Rect() val bounds = new Rect()
paint.getTextBounds(text, 0, text.length, bounds) 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.getHeight - (bitmap.getHeight - bounds.height()) / 2, paint)
bitmap bitmap
} }
...@@ -323,8 +320,7 @@ object Utils { ...@@ -323,8 +320,7 @@ object Utils {
Utils.runRootCommand("settings put global airplane_mode_on 1\n" Utils.runRootCommand("settings put global airplane_mode_on 1\n"
+ "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true\n" + "am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true\n"
+ "settings put global airplane_mode_on 0\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) { private def toggleBelowApiLevel17(context: Context) {
...@@ -792,6 +788,7 @@ object Utils { ...@@ -792,6 +788,7 @@ object Utils {
} }
} }
} }
} }
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