Commit ae30c218 authored by Max Lv's avatar Max Lv

drop support of Android 2.3

parent 86e93ffa
...@@ -15,7 +15,6 @@ resolvers += "JRAF" at "http://JRAF.org/static/maven/2" ...@@ -15,7 +15,6 @@ resolvers += "JRAF" at "http://JRAF.org/static/maven/2"
resolvers += "madeye private releases" at "http://madeye-maven-repository.googlecode.com/git/" resolvers += "madeye private releases" at "http://madeye-maven-repository.googlecode.com/git/"
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"com.google.android" % "analytics" % "3.01",
"dnsjava" % "dnsjava" % "2.1.5", "dnsjava" % "dnsjava" % "2.1.5",
"org.scalaj" %% "scalaj-http" % "0.3.10", "org.scalaj" %% "scalaj-http" % "0.3.10",
"commons-net" % "commons-net" % "3.3", "commons-net" % "commons-net" % "3.3",
...@@ -23,10 +22,8 @@ libraryDependencies ++= Seq( ...@@ -23,10 +22,8 @@ libraryDependencies ++= Seq(
) )
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
aar("com.actionbarsherlock" % "actionbarsherlock" % "4.4.0") exclude("com.google.android", "support-v4"),
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6", "net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
"org.jraf" % "android-switch-backport" % "1.3.1", "com.google.android.gms" % "play-services" % "5.2.08",
"com.google.android.gms" % "play-services" % "4.4.52",
"com.android.support" % "support-v4" % "19.1.0" "com.android.support" % "support-v4" % "19.1.0"
) )
......
...@@ -15,10 +15,11 @@ ...@@ -15,10 +15,11 @@
android:required="false"/> android:required="false"/>
<uses-sdk <uses-sdk
android:minSdkVersion="9" android:minSdkVersion="14"
android:targetSdkVersion="19"/> android:targetSdkVersion="19"/>
<application <application
android:allowBackup="true"
android:name=".ShadowsocksApplication" android:name=".ShadowsocksApplication"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
......
<?xml version="1.0" encoding="utf-8"?>
<!-- File created by the Android Action Bar Style Generator
Copyright (C) 2011 The Android Open Source Project
Copyright (C) 2012 readyState Software Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="PopupTheme" parent="@android:style/Theme.Holo.Light.Dialog.NoActionBar">
<item name="android:windowIsFloating">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="Theme.Shadow" parent="@style/Theme.Sherlock.Light.DarkActionBar">
<item name="android:actionBarItemBackground">@drawable/selectable_background_shadow</item>
<item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
<item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
<item name="android:actionBarTabStyle">@style/ActionBarTabStyle.Shadow</item>
<item name="android:actionDropDownStyle">@style/DropDownNav.Shadow</item>
<item name="android:actionBarStyle">@style/ActionBar.Solid.Shadow</item>
<item name="android:actionModeBackground">@drawable/cab_background_top_shadow</item>
<item name="android:actionModeSplitBackground">@drawable/cab_background_bottom_shadow</item>
<item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Shadow</item>
<!-- Light.DarkActionBar specific -->
<item name="android:actionBarWidgetTheme">@style/Theme.Shadow.Widget</item>
</style>
<style name="ActionBar.Solid.Shadow" parent="@style/Widget.Sherlock.Light.ActionBar.Solid.Inverse">
<item name="android:background">@drawable/ab_background_textured_shadow</item>
<item name="android:backgroundStacked">@drawable/ab_stacked_solid_shadow</item>
<item name="android:backgroundSplit">@drawable/ab_background_textured_shadow</item>
<item name="android:progressBarStyle">@style/ProgressBar.Shadow</item>
</style>
<style name="ActionBar.Transparent.Shadow" parent="@style/Widget.Sherlock.ActionBar">
<item name="android:background">@drawable/ab_transparent_shadow</item>
<item name="android:progressBarStyle">@style/ProgressBar.Shadow</item>
</style>
<!-- this style is only referenced in a Light.DarkActionBar based theme -->
<style name="Theme.Shadow.Widget" parent="@style/Theme.Sherlock">
<item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
<item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
</style>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<!--Replace placeholder ID with your tracking ID-->
<string name="ga_trackingId">UA-37082941-1</string>
<!--Enable Activity tracking-->
<bool name="ga_autoActivityTracking">true</bool>
<!--Enable automatic exception tracking-->
<bool name="ga_reportUncaughtExceptions">true</bool>
<!-- Set a session timeout period of 1 week -->
<integer name="ga_sessionTimeout">604800</integer>
</resources>
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
Zirco Browser for Android
Copyright (C) 2010 J. Devauchelle and contributors.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-->
<resources> <resources>
......
...@@ -16,20 +16,11 @@ ...@@ -16,20 +16,11 @@
<resources> <resources>
<style name="Widget.Shadow.Switch" parent="@style/Widget.Holo.CompoundButton.Switch">
<item name="switchTextAppearance">@android:style/TextAppearance.Small.Inverse</item>
</style>
<!-- Variation on the Light theme that turns off the title --> <!-- Variation on the Light theme that turns off the title -->
<style name="Theme.Shadowsocks" parent="@style/Theme.Shadow"> <style name="Theme.Shadowsocks" parent="@style/Theme.Shadow">
<item name="switchStyle">@style/Widget.Shadow.Switch</item>
<item name="menuDrawerStyle">@style/MenuDrawerStyle</item> <item name="menuDrawerStyle">@style/MenuDrawerStyle</item>
</style> </style>
<style name="Theme.AppManager" parent="@style/Theme.Shadow">
<item name="switchStyle">@style/Widget.Holo.Light.CompoundButton.Switch</item>
</style>
<style name="MenuDrawer"/> <style name="MenuDrawer"/>
<style name="MenuDrawer.Widget"/> <style name="MenuDrawer.Widget"/>
......
...@@ -19,77 +19,64 @@ ...@@ -19,77 +19,64 @@
<resources> <resources>
<style name="PopupTheme" parent="@android:style/Theme.Translucent.NoTitleBar"> <style name="Theme.Shadow" parent="@android:style/Theme.Holo.Light.DarkActionBar">
<item name="android:windowFrame">@null</item> <item name="android:actionBarItemBackground">@drawable/selectable_background_shadow</item>
<item name="android:windowIsFloating">false</item> <item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
<item name="android:windowContentOverlay">@null</item> <item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item> <item name="android:actionBarTabStyle">@style/ActionBarTabStyle.Shadow</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden</item> <item name="android:actionDropDownStyle">@style/DropDownNav.Shadow</item>
<item name="android:windowActionModeOverlay">true</item> <item name="android:actionBarStyle">@style/ActionBar.Solid.Shadow</item>
<item name="android:colorBackgroundCacheHint">@null</item> <item name="android:actionModeBackground">@drawable/cab_background_top_shadow</item>
<item name="android:windowCloseOnTouchOutside">true</item> <item name="android:actionModeSplitBackground">@drawable/cab_background_bottom_shadow</item>
<item name="android:windowIsTranslucent">true</item> <item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Shadow</item>
<item name="windowContentOverlay">@null</item>
</style> <!-- Light.DarkActionBar specific -->
<item name="android:actionBarWidgetTheme">@style/Theme.Shadow.Widget</item>
<style name="Theme.Shadow" parent="@style/Theme.Sherlock.Light.DarkActionBar">
<item name="actionBarItemBackground">@drawable/selectable_background_shadow</item>
<item name="popupMenuStyle">@style/PopupMenu.Shadow</item>
<item name="dropDownListViewStyle">@style/DropDownListView.Shadow</item>
<item name="actionBarTabStyle">@style/ActionBarTabStyle.Shadow</item>
<item name="actionDropDownStyle">@style/DropDownNav.Shadow</item>
<item name="actionBarStyle">@style/ActionBar.Solid.Shadow</item>
<item name="actionModeBackground">@drawable/cab_background_top_shadow</item>
<item name="actionModeSplitBackground">@drawable/cab_background_bottom_shadow</item>
<item name="actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Shadow</item>
<!-- Light.DarkActionBar specific -->
<item name="actionBarWidgetTheme">@style/Theme.Shadow.Widget</item>
</style> </style>
<style name="ActionBar.Solid.Shadow" parent="@style/Widget.Sherlock.Light.ActionBar.Solid.Inverse"> <style name="ActionBar.Solid.Shadow" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
<item name="background">@drawable/ab_solid_shadow</item> <item name="android:background">@drawable/ab_solid_shadow</item>
<item name="backgroundStacked">@drawable/ab_stacked_solid_shadow</item> <item name="android:backgroundStacked">@drawable/ab_stacked_solid_shadow</item>
<item name="backgroundSplit">@drawable/ab_bottom_solid_shadow</item> <item name="android:backgroundSplit">@drawable/ab_bottom_solid_shadow</item>
<item name="progressBarStyle">@style/ProgressBar.Shadow</item> <item name="android:progressBarStyle">@style/ProgressBar.Shadow</item>
</style> </style>
<style name="ActionBar.Transparent.Shadow" parent="@style/Widget.Sherlock.ActionBar"> <style name="ActionBar.Transparent.Shadow" parent="@android:style/Widget.Holo.ActionBar">
<item name="background">@drawable/ab_transparent_shadow</item> <item name="android:background">@drawable/ab_transparent_shadow</item>
<item name="progressBarStyle">@style/ProgressBar.Shadow</item> <item name="android:progressBarStyle">@style/ProgressBar.Shadow</item>
</style> </style>
<style name="PopupMenu.Shadow" parent="@style/Widget.Sherlock.ListPopupWindow"> <style name="PopupMenu.Shadow" parent="@android:style/Widget.Holo.ListPopupWindow">
<item name="android:popupBackground">@drawable/menu_dropdown_panel_shadow</item> <item name="android:popupBackground">@drawable/menu_dropdown_panel_shadow</item>
</style> </style>
<style name="DropDownListView.Shadow" parent="@style/Widget.Sherlock.ListView.DropDown"> <style name="DropDownListView.Shadow" parent="@android:style/Widget.Holo.ListView.DropDown">
<item name="android:listSelector">@drawable/selectable_background_shadow</item> <item name="android:listSelector">@drawable/selectable_background_shadow</item>
</style> </style>
<style name="ActionBarTabStyle.Shadow" parent="@style/Widget.Sherlock.ActionBar.TabView"> <style name="ActionBarTabStyle.Shadow" parent="@android:style/Widget.Holo.ActionBar.TabView">
<item name="android:background">@drawable/tab_indicator_ab_shadow</item> <item name="android:background">@drawable/tab_indicator_ab_shadow</item>
</style> </style>
<style name="DropDownNav.Shadow" parent="@style/Widget.Sherlock.Spinner.DropDown.ActionBar"> <style name="DropDownNav.Shadow" parent="@android:style/Widget.Holo.Spinner">
<item name="android:background">@drawable/spinner_background_ab_shadow</item> <item name="android:background">@drawable/spinner_background_ab_shadow</item>
<item name="android:popupBackground">@drawable/menu_dropdown_panel_shadow</item> <item name="android:popupBackground">@drawable/menu_dropdown_panel_shadow</item>
<item name="android:dropDownSelector">@drawable/selectable_background_shadow</item> <item name="android:dropDownSelector">@drawable/selectable_background_shadow</item>
</style> </style>
<style name="ProgressBar.Shadow" parent="@style/Widget.Sherlock.ProgressBar.Horizontal"> <style name="ProgressBar.Shadow" parent="@android:style/Widget.Holo.ProgressBar.Horizontal">
<item name="android:progressDrawable">@drawable/progress_horizontal_shadow</item> <item name="android:progressDrawable">@drawable/progress_horizontal_shadow</item>
</style> </style>
<style name="ActionButton.CloseMode.Shadow" parent="@style/Widget.Sherlock.ActionButton.CloseMode"> <style name="ActionButton.CloseMode.Shadow" parent="@android:style/Widget.Holo.ActionButton.CloseMode">
<item name="android:background">@drawable/btn_cab_done_shadow</item> <item name="android:background">@drawable/btn_cab_done_shadow</item>
</style> </style>
<!-- this style is only referenced in a Light.DarkActionBar based theme --> <!-- this style is only referenced in a Light.DarkActionBar based theme -->
<style name="Theme.Shadow.Widget" parent="@style/Theme.Sherlock"> <style name="Theme.Shadow.Widget" parent="@android:style/Theme.Holo">
<item name="popupMenuStyle">@style/PopupMenu.Shadow</item> <item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
<item name="dropDownListViewStyle">@style/DropDownListView.Shadow</item> <item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
</style> </style>
</resources> </resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Set a session timeout period of 1 week -->
<integer name="ga_sessionTimeout">604800</integer>
<!-- Enable automatic Activity measurement -->
<bool name="ga_autoActivityTracking">true</bool>
<!-- The screen names that will appear in reports -->
<screenName name="com.google.android.gms.analytics.samples.mobileplayground.ScreenviewFragment">
Shadowsocks ScreenView
</screenName>
<screenName name="com.google.android.gms.analytics.samples.mobileplayground.EcommerceFragment">
Shadowsocks EcommerceView
</screenName>
<!-- The following value should be replaced with correct property id. -->
<string name="ga_trackingId">UA-37082941-1</string>
</resources>
\ No newline at end of file
...@@ -68,7 +68,6 @@ import com.nostra13.universalimageloader.core.download.BaseImageDownloader ...@@ -68,7 +68,6 @@ import com.nostra13.universalimageloader.core.download.BaseImageDownloader
import java.io.{ByteArrayOutputStream, ByteArrayInputStream, InputStream} import java.io.{ByteArrayOutputStream, ByteArrayInputStream, InputStream}
import com.nostra13.universalimageloader.core.{DisplayImageOptions, ImageLoader, ImageLoaderConfiguration} import com.nostra13.universalimageloader.core.{DisplayImageOptions, ImageLoader, ImageLoaderConfiguration}
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer
import com.google.analytics.tracking.android.EasyTracker
import org.jraf.android.backport.switchwidget.Switch import org.jraf.android.backport.switchwidget.Switch
import com.github.shadowsocks.utils.{Utils, Scheme, Key} import com.github.shadowsocks.utils.{Utils, Scheme, Key}
...@@ -255,16 +254,6 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl ...@@ -255,16 +254,6 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
}.start() }.start()
} }
protected override def onStart() {
super.onStart()
EasyTracker.getInstance(this).activityStart(this)
}
protected override def onStop() {
super.onStop()
EasyTracker.getInstance(this).activityStop(this)
}
def saveAppSettings(context: Context) { def saveAppSettings(context: Context) {
if (apps == null) return if (apps == null) return
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
......
...@@ -54,18 +54,16 @@ import android.util.{DisplayMetrics, Log} ...@@ -54,18 +54,16 @@ import android.util.{DisplayMetrics, Log}
import android.view._ import android.view._
import android.webkit.{WebView, WebViewClient} import android.webkit.{WebView, WebViewClient}
import android.widget._ import android.widget._
import com.actionbarsherlock.app.SherlockPreferenceActivity
import com.github.shadowsocks.aidl.{IShadowsocksService, IShadowsocksServiceCallback} import com.github.shadowsocks.aidl.{IShadowsocksService, IShadowsocksServiceCallback}
import com.github.shadowsocks.database._ import com.github.shadowsocks.database._
import com.github.shadowsocks.preferences.{PasswordEditTextPreference, ProfileEditTextPreference, SummaryEditTextPreference} import com.github.shadowsocks.preferences.{PasswordEditTextPreference, ProfileEditTextPreference, SummaryEditTextPreference}
import com.github.shadowsocks.utils._ import com.github.shadowsocks.utils._
import com.google.analytics.tracking.android.{EasyTracker, MapBuilder}
import com.google.android.gms.ads.{AdRequest, AdSize, AdView} import com.google.android.gms.ads.{AdRequest, AdSize, AdView}
import com.google.android.gms.analytics.HitBuilders
import com.google.zxing.integration.android.IntentIntegrator import com.google.zxing.integration.android.IntentIntegrator
import com.nostra13.universalimageloader.core.download.BaseImageDownloader import com.nostra13.universalimageloader.core.download.BaseImageDownloader
import de.keyboardsurfer.android.widget.crouton.{Configuration, Crouton, Style} import de.keyboardsurfer.android.widget.crouton.{Configuration, Crouton, Style}
import net.simonvt.menudrawer.MenuDrawer import net.simonvt.menudrawer.MenuDrawer
import org.jraf.android.backport.switchwidget.Switch
import scala.collection.mutable.{ArrayBuffer, ListBuffer} import scala.collection.mutable.{ArrayBuffer, ListBuffer}
import scala.concurrent.ops._ import scala.concurrent.ops._
...@@ -169,7 +167,7 @@ object Shadowsocks { ...@@ -169,7 +167,7 @@ object Shadowsocks {
} }
class Shadowsocks class Shadowsocks
extends SherlockPreferenceActivity extends PreferenceActivity
with CompoundButton.OnCheckedChangeListener with CompoundButton.OnCheckedChangeListener
with MenuAdapter.MenuListener { with MenuAdapter.MenuListener {
...@@ -236,7 +234,8 @@ class Shadowsocks ...@@ -236,7 +234,8 @@ class Shadowsocks
lazy val profileManager = lazy val profileManager =
new ProfileManager(settings, getApplication.asInstanceOf[ShadowsocksApplication].dbHelper) new ProfileManager(settings, getApplication.asInstanceOf[ShadowsocksApplication].dbHelper)
val handler = new Handler() private lazy val handler = new Handler()
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
def isSinglePane: Boolean = { def isSinglePane: Boolean = {
if (singlePane == -1) { if (singlePane == -1) {
...@@ -481,10 +480,10 @@ class Shadowsocks ...@@ -481,10 +480,10 @@ class Shadowsocks
val tf: Typeface = Typefaces.get(this, "fonts/Iceland.ttf") val tf: Typeface = Typefaces.get(this, "fonts/Iceland.ttf")
if (tf != null) title.setTypeface(tf) if (tf != null) title.setTypeface(tf)
switchButton = switchLayout.findViewById(R.id.switchButton).asInstanceOf[Switch] switchButton = switchLayout.findViewById(R.id.switchButton).asInstanceOf[Switch]
getSupportActionBar.setCustomView(switchLayout) getActionBar.setCustomView(switchLayout)
getSupportActionBar.setDisplayShowTitleEnabled(false) getActionBar.setDisplayShowTitleEnabled(false)
getSupportActionBar.setDisplayShowCustomEnabled(true) getActionBar.setDisplayShowCustomEnabled(true)
getSupportActionBar.setIcon(R.drawable.ic_stat_shadowsocks) getActionBar.setIcon(R.drawable.ic_stat_shadowsocks)
// Register broadcast receiver // Register broadcast receiver
registerReceiver(preferenceReceiver, new IntentFilter(Action.UPDATE_PREFS)) registerReceiver(preferenceReceiver, new IntentFilter(Action.UPDATE_PREFS))
...@@ -683,32 +682,40 @@ class Shadowsocks ...@@ -683,32 +682,40 @@ class Shadowsocks
buf += new Category(getString(R.string.settings)) buf += new Category(getString(R.string.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 // send event
.getInstance(this) application.tracker.send(new HitBuilders.EventBuilder()
.send(MapBuilder.createEvent(Shadowsocks.TAG, "reset", getVersionName, null).build()) .setCategory(Shadowsocks.TAG)
.setAction("reset")
.setLabel(getVersionName)
.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 // send event
.getInstance(this) application.tracker.send(new HitBuilders.EventBuilder()
.send( .setCategory(Shadowsocks.TAG)
MapBuilder.createEvent(Shadowsocks.TAG, "flush_dnscache", getVersionName, null).build()) .setAction("flush_dnscache")
.setLabel(getVersionName)
.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 // send event
.getInstance(this) application.tracker.send(new HitBuilders.EventBuilder()
.send(MapBuilder.createEvent(Shadowsocks.TAG, "about", getVersionName, null).build()) .setCategory(Shadowsocks.TAG)
.setAction("about")
.setLabel(getVersionName)
.build())
showAbout() showAbout()
}) })
buf.toList buf.toList
} }
override def onOptionsItemSelected(item: com.actionbarsherlock.view.MenuItem): Boolean = { override def onOptionsItemSelected(item: MenuItem): Boolean = {
item.getItemId match { item.getItemId match {
case android.R.id.home => case android.R.id.home =>
drawer.toggleMenu() drawer.toggleMenu()
...@@ -776,12 +783,10 @@ class Shadowsocks ...@@ -776,12 +783,10 @@ class Shadowsocks
override def onStart() { override def onStart() {
super.onStart() super.onStart()
EasyTracker.getInstance(this).activityStart(this)
} }
override def onStop() { override def onStop() {
super.onStop() super.onStop()
EasyTracker.getInstance(this).activityStop(this)
clearDialog() clearDialog()
} }
......
...@@ -39,8 +39,14 @@ ...@@ -39,8 +39,14 @@
package com.github.shadowsocks package com.github.shadowsocks
import java.util.concurrent.TimeUnit
import android.app.Application import android.app.Application
import com.github.shadowsocks.database.DBHelper import com.github.shadowsocks.database.DBHelper
import com.google.android.gms.analytics.{GoogleAnalytics, Tracker}
import com.google.android.gms.common.api.ResultCallback
import com.google.android.gms.tagmanager.Container.FunctionCallMacroCallback
import com.google.android.gms.tagmanager.{ContainerHolder, TagManager, Container}
import com.google.tagmanager.{Container, ContainerOpener, TagManager} import com.google.tagmanager.{Container, ContainerOpener, TagManager}
import com.google.tagmanager.ContainerOpener.{Notifier, OpenType} import com.google.tagmanager.ContainerOpener.{Notifier, OpenType}
import com.google.tagmanager.Container.FunctionCallMacroHandler import com.google.tagmanager.Container.FunctionCallMacroHandler
...@@ -50,15 +56,21 @@ import com.github.shadowsocks.utils.Utils ...@@ -50,15 +56,21 @@ import com.github.shadowsocks.utils.Utils
class ShadowsocksApplication extends Application { class ShadowsocksApplication extends Application {
lazy val dbHelper = new DBHelper(this) lazy val dbHelper = new DBHelper(this)
lazy val SIG_FUNC = "getSignature" lazy val SIG_FUNC = "getSignature"
var tagContainer: Container = null var containerHolder: ContainerHolder = null
lazy val tracker = GoogleAnalytics.getInstance(this).newTracker(R.xml.tracker)
override def onCreate() { override def onCreate() {
val tm = TagManager.getInstance(this) val tm = TagManager.getInstance(this)
ContainerOpener.openContainer(tm, "GTM-NT8WS8", OpenType.PREFER_NON_DEFAULT, null, new Notifier { val pending = tm.loadContainerPreferNonDefault("GTM-NT8WS8", R.raw.gtm_default_container)
override def containerAvailable(container: Container) { val callback = new ResultCallback[ContainerHolder] {
tagContainer = container override def onResult(holder: ContainerHolder): Unit = {
container.registerFunctionCallMacroHandler(SIG_FUNC, new FunctionCallMacroHandler { if (!containerHolder.getStatus.isSuccess) {
def getValue(functionName: String, parameters: util.Map[String, AnyRef]): AnyRef = { return
}
containerHolder = holder
val container = holder.getContainer
container.registerFunctionCallMacroCallback(SIG_FUNC, new FunctionCallMacroCallback {
override def getValue(functionName: String, parameters: util.Map[String, AnyRef]): AnyRef = {
if (functionName == SIG_FUNC) { if (functionName == SIG_FUNC) {
Utils.getSignature(getApplicationContext) Utils.getSignature(getApplicationContext)
} }
...@@ -66,6 +78,7 @@ class ShadowsocksApplication extends Application { ...@@ -66,6 +78,7 @@ class ShadowsocksApplication extends Application {
} }
}) })
} }
}) }
pending.setResultCallback(callback, 2, TimeUnit.SECONDS)
} }
} }
...@@ -49,9 +49,9 @@ import android.content.pm.PackageManager ...@@ -49,9 +49,9 @@ 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.{Fields, MapBuilder, EasyTracker}
import java.lang.reflect.InvocationTargetException import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method import java.lang.reflect.Method
import com.google.android.gms.analytics.HitBuilders
import org.apache.http.conn.util.InetAddressUtils import org.apache.http.conn.util.InetAddressUtils
import scala.collection._ import scala.collection._
import java.util.{TimerTask, Timer} import java.util.{TimerTask, Timer}
...@@ -100,7 +100,7 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -100,7 +100,7 @@ class ShadowsocksNatService extends Service with BaseService {
private var timer: Timer = null private var timer: Timer = null
private val TIMER_INTERVAL = 2 private val TIMER_INTERVAL = 2
val handler: Handler = new Handler() private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
def isACLEnabled: Boolean = { def isACLEnabled: Boolean = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
...@@ -454,12 +454,12 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -454,12 +454,12 @@ class ShadowsocksNatService extends Service with BaseService {
} }
registerReceiver(receiver, filter) registerReceiver(receiver, filter)
// start tracker
EasyTracker // send event
.getInstance(this) application.tracker.send(new HitBuilders.EventBuilder()
.send(MapBuilder .setCategory(TAG)
.createEvent(TAG, "start", getVersionName, 0L) .setAction("start")
.set(Fields.SESSION_CONTROL, "start") .setLabel(getVersionName)
.build()) .build())
changeState(State.CONNECTING) changeState(State.CONNECTING)
...@@ -496,9 +496,9 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -496,9 +496,9 @@ class ShadowsocksNatService extends Service with BaseService {
spawn { spawn {
if (config.proxy == "198.199.101.152") { if (config.proxy == "198.199.101.152") {
val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer val holder = application.containerHolder
try { try {
config = ConfigUtils.getPublicConfig(getBaseContext, container, config) config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
} catch { } catch {
case ex: Exception => case ex: Exception =>
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
...@@ -542,12 +542,11 @@ class ShadowsocksNatService extends Service with BaseService { ...@@ -542,12 +542,11 @@ class ShadowsocksNatService extends Service with BaseService {
// change the state // change the state
changeState(State.STOPPED) changeState(State.STOPPED)
// stop the tracker // send event
EasyTracker application.tracker.send(new HitBuilders.EventBuilder()
.getInstance(this) .setCategory(TAG)
.send(MapBuilder .setAction("stop")
.createEvent(TAG, "stop", getVersionName, 0L) .setLabel(getVersionName)
.set(Fields.SESSION_CONTROL, "stop")
.build()) .build())
// reset timer // reset timer
......
...@@ -138,7 +138,7 @@ class ShadowsocksRunnerActivity extends Activity { ...@@ -138,7 +138,7 @@ class ShadowsocksRunnerActivity extends Activity {
deattachService() deattachService()
if (receiver != null) { if (receiver != null) {
unregisterReceiver(receiver) unregisterReceiver(receiver)
receiver = null; receiver = null
} }
} }
......
...@@ -39,25 +39,24 @@ ...@@ -39,25 +39,24 @@
package com.github.shadowsocks package com.github.shadowsocks
import java.io.File
import java.net.InetAddress
import android.app._ import android.app._
import android.content._ import android.content._
import android.content.pm.PackageInfo import android.content.pm.{PackageInfo, PackageManager}
import android.content.pm.PackageManager import android.net.VpnService
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.{Fields, MapBuilder, EasyTracker} import com.github.shadowsocks.aidl.Config
import android.net.VpnService
import org.apache.http.conn.util.InetAddressUtils
import android.os.Message
import scala.concurrent.ops._
import org.apache.commons.net.util.SubnetUtils
import com.github.shadowsocks.utils._ import com.github.shadowsocks.utils._
import scala.Some import com.google.android.gms.analytics.HitBuilders
import com.github.shadowsocks.aidl.{IShadowsocksService, Config} import org.apache.commons.net.util.SubnetUtils
import org.apache.http.conn.util.InetAddressUtils
import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer
import java.io.File import scala.concurrent.ops._
import java.net.InetAddress
class ShadowsocksVpnService extends VpnService with BaseService { class ShadowsocksVpnService extends VpnService with BaseService {
...@@ -73,7 +72,7 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -73,7 +72,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
var apps: Array[ProxiedApp] = null var apps: Array[ProxiedApp] = null
var config: Config = null var config: Config = null
val handler: Handler = new Handler() private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
def isByass(net: SubnetUtils): Boolean = { def isByass(net: SubnetUtils): Boolean = {
val info = net.getInfo val info = net.getInfo
...@@ -272,12 +271,11 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -272,12 +271,11 @@ class ShadowsocksVpnService extends VpnService with BaseService {
return return
} }
// start the tracker // send event
EasyTracker application.tracker.send(new HitBuilders.EventBuilder()
.getInstance(this) .setCategory(TAG)
.send(MapBuilder .setAction("start")
.createEvent(TAG, "start", getVersionName, 0L) .setLabel(getVersionName)
.set(Fields.SESSION_CONTROL, "start")
.build()) .build())
// register close receiver // register close receiver
...@@ -294,9 +292,9 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -294,9 +292,9 @@ class ShadowsocksVpnService extends VpnService with BaseService {
spawn { spawn {
if (config.proxy == "198.199.101.152") { if (config.proxy == "198.199.101.152") {
val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer val holder = getApplication.asInstanceOf[ShadowsocksApplication].containerHolder
try { try {
config = ConfigUtils.getPublicConfig(getBaseContext, container, config) config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
} catch { } catch {
case ex: Exception => case ex: Exception =>
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed)) notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
...@@ -338,12 +336,11 @@ class ShadowsocksVpnService extends VpnService with BaseService { ...@@ -338,12 +336,11 @@ class ShadowsocksVpnService extends VpnService with BaseService {
// channge the state // channge the state
changeState(State.STOPPED) changeState(State.STOPPED)
// stop the tracker // send event
EasyTracker application.tracker.send(new HitBuilders.EventBuilder()
.getInstance(this) .setCategory(TAG)
.send(MapBuilder .setAction("stop")
.createEvent(TAG, "stop", getVersionName, 0L) .setLabel(getVersionName)
.set(Fields.SESSION_CONTROL, "stop")
.build()) .build())
// reset VPN // reset VPN
......
...@@ -41,7 +41,7 @@ package com.github.shadowsocks.utils ...@@ -41,7 +41,7 @@ package com.github.shadowsocks.utils
import android.content.{SharedPreferences, Context} import android.content.{SharedPreferences, Context}
import com.github.shadowsocks.ShadowsocksApplication import com.github.shadowsocks.ShadowsocksApplication
import com.google.tagmanager.Container import com.google.android.gms.tagmanager.Container
import scalaj.http.{HttpOptions, Http} import scalaj.http.{HttpOptions, Http}
import com.github.shadowsocks.aidl.Config import com.github.shadowsocks.aidl.Config
...@@ -143,8 +143,8 @@ object ConfigUtils { ...@@ -143,8 +143,8 @@ object ConfigUtils {
} }
def refresh(context: Context) { def refresh(context: Context) {
val container = context.getApplicationContext.asInstanceOf[ShadowsocksApplication].tagContainer val holder = context.getApplicationContext.asInstanceOf[ShadowsocksApplication].containerHolder
if (container != null) container.refresh() if (holder != null) holder.refresh()
} }
def getPublicConfig(context: Context, container: Container, config: Config): Config = { def getPublicConfig(context: Context, container: Container, config: Config): Config = {
......
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