update Google Analytics and Tag Manager

This commit is contained in:
Max Lv
2013-10-13 11:29:39 +08:00
parent c96dde8644
commit 32561d39fc
11 changed files with 144 additions and 95 deletions
@@ -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) {
@@ -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()
}
@@ -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()
}
@@ -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
}
})
}
}
@@ -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)
@@ -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 {
}
}
}
}