Compare commits

..
9 Commits
Author SHA1 Message Date
Max Lv cfaaaf5341 update with new cipher rc4-md5 2014-09-09 21:28:19 +08:00
Max Lv 4a4d3b11fb refine handler 2014-09-07 11:44:06 +08:00
Max Lv 3538caa80d update styles 2014-09-07 11:00:12 +08:00
Max Lv ae30c218e9 drop support of Android 2.3 2014-09-07 10:06:22 +08:00
Max Lv 86e93ffa2d try to fix #114 2014-09-04 16:51:37 +08:00
Max Lv acd89cc999 refine VPN mode 2014-09-02 10:02:08 +08:00
Max Lv 382af46d91 Update .travis.yml 2014-08-24 13:37:01 +08:00
Max Lv 415a9f6847 refine onTaskRemoved 2014-08-24 12:23:38 +08:00
Max Lv 91a069bc44 Update .travis.yml 2014-07-26 21:51:32 +08:00
79 changed files with 312 additions and 449 deletions
+2 -12
View File
@@ -20,18 +20,8 @@ before_install:
- export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
- echo "y" | android update sdk --filter tools,platform-tools,build-tools-20.0.0,android-19,extra-google-m2repository --no-ui --no-https -a
- echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a
install:
- gem install --version 0.8.9 faraday
- gem install travis-artifacts
script:
- ./build-ndk.sh
- cp local.properties.travis local.properties
- sbt clean android:package-release
after_success:
- ./deploy target/android-bin shadowsocks-release.apk
env:
global:
- "ARTIFACTS_AWS_REGION=us-east-1"
- "ARTIFACTS_S3_BUCKET=travis-nightly"
- secure: "GkAdnMh07id2VKhpCW16lE73A0LK2Jsk3hzkFvdx76JKW8FjLgaimLJ2T/+i\nxFfDw8XBinLE09dqg8JxSNS6JbLHLcav8P3yJIlzFh1NqfJABU9U4I8atb6P\nITSdSo9nb3LX6sB8SOU0nqXb5U+nj7jiekQqiBhmEmu6iDmMtfU="
- secure: "eCh5BjCFccp+sB/FIrjsmxJU4475D4qiWvDV++khcIHLel6lgUjDX18ImBlJ\n+IdiCKxvR6EpRDV1Cs4gJ2jZEAV0PbojQMoQOXbs1FLggM8RRq/Re1qWQFq7\nWkBRjjr8w8ddjJZHRo459cTUvgvD7krhp07coabAnEahDaGWSUo="
- sbt android:package-release
- exit 0
+1 -4
View File
@@ -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/"
libraryDependencies ++= Seq(
"com.google.android" % "analytics" % "3.01",
"dnsjava" % "dnsjava" % "2.1.5",
"org.scalaj" %% "scalaj-http" % "0.3.10",
"commons-net" % "commons-net" % "3.3",
@@ -23,10 +22,8 @@ libraryDependencies ++= Seq(
)
libraryDependencies ++= Seq(
aar("com.actionbarsherlock" % "actionbarsherlock" % "4.4.0") exclude("com.google.android", "support-v4"),
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
"org.jraf" % "android-switch-backport" % "1.3.1",
"com.google.android.gms" % "play-services" % "4.4.52",
"com.google.android.gms" % "play-services" % "5.2.08",
"com.android.support" % "support-v4" % "19.1.0"
)
+4 -5
View File
@@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.shadowsocks"
android:versionCode="68"
android:versionName="2.2.0">
android:versionCode="70"
android:versionName="2.2.2">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
@@ -15,10 +15,11 @@
android:required="false"/>
<uses-sdk
android:minSdkVersion="9"
android:minSdkVersion="14"
android:targetSdkVersion="19"/>
<application
android:allowBackup="true"
android:name=".ShadowsocksApplication"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
@@ -75,14 +76,12 @@
<service
android:name=".ShadowsocksNatService"
android:process=":proxy"
android:exported="false">
</service>
<service
android:name=".ShadowsocksVpnService"
android:label="@string/app_name"
android:process=":vpn"
android:permission="android.permission.BIND_VPN_SERVICE"
android:exported="false">
<intent-filter>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 B

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 B

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 514 B

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 B

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 B

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 817 B

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 B

After

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 B

After

Width:  |  Height:  |  Size: 97 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 260 B

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 677 B

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

@@ -1,22 +0,0 @@
<?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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/pressed_shadow" />
</shape>
@@ -20,6 +20,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:exitFadeDuration="@android:integer/config_mediumAnimTime" >
<item android:state_pressed="false" android:state_focused="true" android:drawable="@drawable/list_focused_shadow" />
<item android:state_pressed="true" android:drawable="@drawable/pressed_background_shadow" />
<item android:state_pressed="true" android:drawable="@drawable/list_pressed_shadow" />
<item android:drawable="@android:color/transparent" />
</selector>
+1 -1
View File
@@ -21,7 +21,7 @@
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"/>
<org.jraf.android.backport.switchwidget.Switch
<Switch
android:id="@+id/bypassSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+2 -1
View File
@@ -15,8 +15,9 @@
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"/>
<org.jraf.android.backport.switchwidget.Switch
<Switch
android:id="@+id/switchButton"
android:switchTextAppearance="@android:style/TextAppearance.Small.Inverse"
android:enabled="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Binary file not shown.
-65
View File
@@ -1,65 +0,0 @@
<?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>
-1
View File
@@ -44,7 +44,6 @@
<string name="forward_stop">后台服务已停止。</string>
<string name="service_failed">请检查你的网络状态后并重试。</string>
<string name="stop">停止服务</string>
<string name="vpn_status">推荐通过通知栏关闭 VPN 服务</string>
<string name="vpn_error">无法启动 VPN 服务:\"%s\"。看来和你的设备存在兼容性问题,请使用 Root 模式。</string>
<string name="ok_iknow">确定</string>
<string name="port_alert">端口号应大于1024</string>
-14
View File
@@ -1,14 +0,0 @@
<?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>
+2
View File
@@ -5,6 +5,7 @@
<string-array name="enc_method_entry">
<item>TABLE</item>
<item>RC4</item>
<item>RC4-MD5</item>
<item>AES-128-CFB</item>
<item>AES-192-CFB</item>
<item>AES-256-CFB</item>
@@ -22,6 +23,7 @@
<string-array name="enc_method_value">
<item>table</item>
<item>rc4</item>
<item>rc4-md5</item>
<item>aes-128-cfb</item>
<item>aes-192-cfb</item>
<item>aes-256-cfb</item>
-14
View File
@@ -1,18 +1,4 @@
<?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>
-1
View File
@@ -57,7 +57,6 @@
<string name="forward_stop">Shadowsocks stopped.</string>
<string name="service_failed">Please check your network status and try again.</string>
<string name="stop">Stop the service</string>
<string name="vpn_status">Recommend to disable the VPN service through the notification bar.</string>
<string name="vpn_error">Unable to start VPN service: "%s". It seems to be a compatibility issue with your device. Please consider using ROOT mode instead.</string>
<!-- alert category -->
+46 -40
View File
@@ -16,54 +16,60 @@
<resources>
<style name="Widget.Shadow.Switch" parent="@style/Widget.Holo.CompoundButton.Switch">
<item name="switchTextAppearance">@android:style/TextAppearance.Small.Inverse</item>
</style>
<style name="Theme.AppManager" parent="@style/Theme.Shadow">
</style>
<!-- Variation on the Light theme that turns off the title -->
<style name="Theme.Shadowsocks" parent="@style/Theme.Shadow">
<item name="switchStyle">@style/Widget.Shadow.Switch</item>
<item name="menuDrawerStyle">@style/MenuDrawerStyle</item>
</style>
<style name="PopupTheme" parent="@android:style/Theme.Translucent.NoTitleBar">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowCloseOnTouchOutside">true</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="Theme.AppManager" parent="@style/Theme.Shadow">
<item name="switchStyle">@style/Widget.Holo.Light.CompoundButton.Switch</item>
</style>
<!-- Variation on the Light theme that turns off the title -->
<style name="Theme.Shadowsocks" parent="@style/Theme.Shadow">
<item name="menuDrawerStyle">@style/MenuDrawerStyle</item>
</style>
<style name="MenuDrawer"/>
<style name="MenuDrawer"/>
<style name="MenuDrawer.Widget"/>
<style name="MenuDrawer.Widget"/>
<style name="MenuDrawer.Widget.Category">
<item name="android:textStyle">bold</item>
<item name="android:textColor">?android:attr/textColorSecondaryInverse</item>
<item name="android:textSize">14sp</item>
<item name="android:textAllCaps">true</item>
<style name="MenuDrawer.Widget.Category">
<item name="android:textStyle">bold</item>
<item name="android:textColor">?android:attr/textColorSecondaryInverse</item>
<item name="android:textSize">14sp</item>
<item name="android:textAllCaps">true</item>
<item name="android:gravity">center_vertical</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:background">@drawable/md__category_background</item>
<item name="android:gravity">center_vertical</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:background">@drawable/md__category_background</item>
<item name="android:singleLine">true</item>
<item name="android:ellipsize">end</item>
</style>
<item name="android:singleLine">true</item>
<item name="android:ellipsize">end</item>
</style>
<style name="MenuDrawer.Widget.Title">
<item name="android:background">@drawable/md__list_selector_holo_dark</item>
<item name="android:textAppearance">?android:attr/textAppearance</item>
<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
<item name="android:textSize">18sp</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:paddingRight">32dp</item>
<item name="android:paddingTop">8dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:drawablePadding">16dp</item>
<item name="android:gravity">center_vertical</item>
</style>
<style name="MenuDrawer.Widget.Title">
<item name="android:background">@drawable/md__list_selector_holo_dark</item>
<item name="android:textAppearance">?android:attr/textAppearance</item>
<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
<item name="android:textSize">18sp</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:paddingRight">32dp</item>
<item name="android:paddingTop">8dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:drawablePadding">16dp</item>
<item name="android:gravity">center_vertical</item>
</style>
<style name="MenuDrawerStyle" parent="Widget.MenuDrawer">
<item name="mdActiveIndicator">@drawable/menu_arrow</item>
<item name="mdMenuSize">250dp</item>
</style>
<style name="MenuDrawerStyle" parent="Widget.MenuDrawer">
<item name="mdActiveIndicator">@drawable/menu_arrow</item>
<item name="mdMenuSize">250dp</item>
</style>
</resources>
+34 -47
View File
@@ -19,77 +19,64 @@
<resources>
<style name="PopupTheme" parent="@android:style/Theme.Translucent.NoTitleBar">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden</item>
<item name="android:windowActionModeOverlay">true</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowCloseOnTouchOutside">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="windowContentOverlay">@null</item>
</style>
<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 name="Theme.Shadow" parent="@android:style/Theme.Holo.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="background">@drawable/ab_solid_shadow</item>
<item name="backgroundStacked">@drawable/ab_stacked_solid_shadow</item>
<item name="backgroundSplit">@drawable/ab_bottom_solid_shadow</item>
<item name="progressBarStyle">@style/ProgressBar.Shadow</item>
<style name="ActionBar.Solid.Shadow" parent="@android:style/Widget.Holo.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="background">@drawable/ab_transparent_shadow</item>
<item name="progressBarStyle">@style/ProgressBar.Shadow</item>
<style name="ActionBar.Transparent.Shadow" parent="@android:style/Widget.Holo.ActionBar">
<item name="android:background">@drawable/ab_transparent_shadow</item>
<item name="android:progressBarStyle">@style/ProgressBar.Shadow</item>
</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>
</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>
</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>
</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:popupBackground">@drawable/menu_dropdown_panel_shadow</item>
<item name="android:dropDownSelector">@drawable/selectable_background_shadow</item>
</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>
</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>
</style>
<!-- this style is only referenced in a Light.DarkActionBar based theme -->
<style name="Theme.Shadow.Widget" parent="@style/Theme.Sherlock">
<item name="popupMenuStyle">@style/PopupMenu.Shadow</item>
<item name="dropDownListViewStyle">@style/DropDownListView.Shadow</item>
<style name="Theme.Shadow.Widget" parent="@android:style/Theme.Holo">
<item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
<item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
</style>
</resources>
+18
View File
@@ -0,0 +1,18 @@
<?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>
@@ -39,7 +39,7 @@
package com.github.shadowsocks
import android.app.ProgressDialog
import android.app.{Activity, ProgressDialog}
import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
@@ -53,23 +53,13 @@ import android.view.View.OnClickListener
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams
import android.view.WindowManager
import android.widget.AbsListView
import android.widget._
import android.widget.AbsListView.OnScrollListener
import android.widget.ArrayAdapter
import android.widget.CheckBox
import android.widget.CompoundButton
import android.widget.CompoundButton.OnCheckedChangeListener
import android.widget.ImageView
import android.widget.ListAdapter
import android.widget.ListView
import android.widget.TextView
import com.actionbarsherlock.app.SherlockActivity
import com.nostra13.universalimageloader.core.download.BaseImageDownloader
import java.io.{ByteArrayOutputStream, ByteArrayInputStream, InputStream}
import com.nostra13.universalimageloader.core.{DisplayImageOptions, ImageLoader, ImageLoaderConfiguration}
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer
import com.google.analytics.tracking.android.EasyTracker
import org.jraf.android.backport.switchwidget.Switch
import com.github.shadowsocks.utils.{Utils, Scheme, Key}
case class ProxiedApp(uid: Int, name: String, var proxied: Boolean)
@@ -106,7 +96,7 @@ object AppManager {
}
}
class AppManager extends SherlockActivity with OnCheckedChangeListener with OnClickListener {
class AppManager extends Activity with OnCheckedChangeListener with OnClickListener {
val MSG_LOAD_START = 1
val MSG_LOAD_FINISH = 2
@@ -216,9 +206,20 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
saveAppSettings(this)
}
override def onDestroy() {
super.onDestroy()
if (handler != null) {
handler.removeCallbacksAndMessages(null)
handler = null
}
}
protected override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
getSupportActionBar.setTitle(R.string.proxied_help)
handler = new Handler()
getActionBar.setTitle(R.string.proxied_help)
this.setContentView(R.layout.layout_apps)
this.overlay = View.inflate(this, R.layout.overlay, null).asInstanceOf[TextView]
getWindowManager.addView(overlay, new
@@ -233,7 +234,7 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
.build()
ImageLoader.getInstance().init(config)
val bypassSwitch: Switch = findViewById(R.id.bypassSwitch).asInstanceOf[Switch]
val bypassSwitch = findViewById(R.id.bypassSwitch).asInstanceOf[Switch]
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
bypassSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener {
def onCheckedChanged(button: CompoundButton, checked: Boolean) {
@@ -247,24 +248,14 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
super.onResume()
new Thread {
override def run() {
handler.sendEmptyMessage(MSG_LOAD_START)
handler.post(loadStartRunnable)
appListView = findViewById(R.id.applistview).asInstanceOf[ListView]
if (!appsLoaded) loadApps()
handler.sendEmptyMessage(MSG_LOAD_FINISH)
handler.post(loadFinishRunnable)
}
}.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) {
if (apps == null) return
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
@@ -279,46 +270,46 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
edit.commit
}
val handler: Handler = new Handler {
override def handleMessage(msg: Message) {
msg.what match {
case MSG_LOAD_START =>
progressDialog = ProgressDialog
.show(AppManager.this, "", getString(R.string.loading), true, true)
case MSG_LOAD_FINISH =>
appListView.setAdapter(adapter)
appListView.setOnScrollListener(new AbsListView.OnScrollListener {
def onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int,
totalItemCount: Int) {
if (visible) {
val name: String = apps(firstVisibleItem).name
if (name != null && name.length > 1) {
overlay.setText(apps(firstVisibleItem).name.substring(0, 1))
} else {
overlay.setText("*")
}
overlay.setVisibility(View.VISIBLE)
}
}
def onScrollStateChanged(view: AbsListView, scrollState: Int) {
visible = true
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
overlay.setVisibility(View.INVISIBLE)
}
}
var visible = false
})
if (progressDialog != null) {
progressDialog.dismiss()
progressDialog = null
}
}
super.handleMessage(msg)
val loadStartRunnable = new Runnable {
override def run() {
progressDialog = ProgressDialog
.show(AppManager.this, "", getString(R.string.loading), true, true)
}
}
val loadFinishRunnable = new Runnable {
override def run() = {
appListView.setAdapter(adapter)
appListView.setOnScrollListener(new AbsListView.OnScrollListener {
def onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int,
totalItemCount: Int) {
if (visible) {
val name: String = apps(firstVisibleItem).name
if (name != null && name.length > 1) {
overlay.setText(apps(firstVisibleItem).name.substring(0, 1))
} else {
overlay.setText("*")
}
overlay.setVisibility(View.VISIBLE)
}
}
def onScrollStateChanged(view: AbsListView, scrollState: Int) {
visible = true
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
overlay.setVisibility(View.INVISIBLE)
}
}
var visible = false
})
if (progressDialog != null) {
progressDialog.dismiss()
progressDialog = null
}
}
}
var handler: Handler = null
class AppIconDownloader(context: Context, connectTimeout: Int, readTimeout: Int)
extends BaseImageDownloader(context, connectTimeout, readTimeout) {
@@ -54,21 +54,20 @@ import android.util.{DisplayMetrics, Log}
import android.view._
import android.webkit.{WebView, WebViewClient}
import android.widget._
import com.actionbarsherlock.app.SherlockPreferenceActivity
import com.github.shadowsocks.aidl.{IShadowsocksService, IShadowsocksServiceCallback}
import com.github.shadowsocks.database._
import com.github.shadowsocks.preferences.{PasswordEditTextPreference, ProfileEditTextPreference, SummaryEditTextPreference}
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.analytics.HitBuilders
import com.google.zxing.integration.android.IntentIntegrator
import com.nostra13.universalimageloader.core.download.BaseImageDownloader
import de.keyboardsurfer.android.widget.crouton.{Configuration, Crouton, Style}
import net.simonvt.menudrawer.MenuDrawer
import org.jraf.android.backport.switchwidget.Switch
import scala.collection.mutable.{ArrayBuffer, ListBuffer}
import scala.concurrent.ops._
import scala.ref.WeakReference
class ProfileIconDownloader(context: Context, connectTimeout: Int, readTimeout: Int)
extends BaseImageDownloader(context, connectTimeout, readTimeout) {
@@ -169,7 +168,7 @@ object Shadowsocks {
}
class Shadowsocks
extends SherlockPreferenceActivity
extends PreferenceActivity
with CompoundButton.OnCheckedChangeListener
with MenuAdapter.MenuListener {
@@ -227,16 +226,18 @@ class Shadowsocks
}
}
lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
lazy val status = getSharedPreferences(Key.status, Context.MODE_PRIVATE)
lazy val preferenceReceiver = new PreferenceBroadcastReceiver
lazy val drawer = MenuDrawer.attach(this)
lazy val menuAdapter = new MenuAdapter(this, getMenuList)
lazy val listView = new ListView(this)
lazy val profileManager =
private lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
private lazy val status = getSharedPreferences(Key.status, Context.MODE_PRIVATE)
private lazy val preferenceReceiver = new PreferenceBroadcastReceiver
private lazy val drawer = MenuDrawer.attach(this)
private lazy val menuAdapter = new MenuAdapter(this, getMenuList)
private lazy val listView = new ListView(this)
private lazy val profileManager =
new ProfileManager(settings, getApplication.asInstanceOf[ShadowsocksApplication].dbHelper)
val handler = new Handler()
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
var handler: Handler = null
def isSinglePane: Boolean = {
if (singlePane == -1) {
@@ -442,6 +443,8 @@ class Shadowsocks
super.onCreate(savedInstanceState)
handler = new Handler()
addPreferencesFromResource(R.xml.pref_all)
// Initialize the profile
@@ -481,10 +484,10 @@ class Shadowsocks
val tf: Typeface = Typefaces.get(this, "fonts/Iceland.ttf")
if (tf != null) title.setTypeface(tf)
switchButton = switchLayout.findViewById(R.id.switchButton).asInstanceOf[Switch]
getSupportActionBar.setCustomView(switchLayout)
getSupportActionBar.setDisplayShowTitleEnabled(false)
getSupportActionBar.setDisplayShowCustomEnabled(true)
getSupportActionBar.setIcon(R.drawable.ic_stat_shadowsocks)
getActionBar.setCustomView(switchLayout)
getActionBar.setDisplayShowTitleEnabled(false)
getActionBar.setDisplayShowCustomEnabled(true)
getActionBar.setIcon(R.drawable.ic_stat_shadowsocks)
// Register broadcast receiver
registerReceiver(preferenceReceiver, new IntentFilter(Action.UPDATE_PREFS))
@@ -519,8 +522,8 @@ class Shadowsocks
case ignored: RemoteException => // Nothing
}
bgService = null
unbindService(connection)
}
unbindService(connection)
}
override def onRestoreInstanceState(inState: Bundle) {
@@ -683,32 +686,40 @@ class Shadowsocks
buf += new Category(getString(R.string.settings))
buf += new Item(-100, getString(R.string.recovery), android.R.drawable.ic_menu_revert, _ => {
EasyTracker
.getInstance(this)
.send(MapBuilder.createEvent(Shadowsocks.TAG, "reset", getVersionName, null).build())
// send event
application.tracker.send(new HitBuilders.EventBuilder()
.setCategory(Shadowsocks.TAG)
.setAction("reset")
.setLabel(getVersionName)
.build())
recovery()
})
buf +=
new Item(-200, getString(R.string.flush_dnscache), android.R.drawable.ic_menu_delete, _ => {
EasyTracker
.getInstance(this)
.send(
MapBuilder.createEvent(Shadowsocks.TAG, "flush_dnscache", getVersionName, null).build())
// send event
application.tracker.send(new HitBuilders.EventBuilder()
.setCategory(Shadowsocks.TAG)
.setAction("flush_dnscache")
.setLabel(getVersionName)
.build())
flushDnsCache()
})
buf += new Item(-300, getString(R.string.about), android.R.drawable.ic_menu_info_details, _ => {
EasyTracker
.getInstance(this)
.send(MapBuilder.createEvent(Shadowsocks.TAG, "about", getVersionName, null).build())
// send event
application.tracker.send(new HitBuilders.EventBuilder()
.setCategory(Shadowsocks.TAG)
.setAction("about")
.setLabel(getVersionName)
.build())
showAbout()
})
buf.toList
}
override def onOptionsItemSelected(item: com.actionbarsherlock.view.MenuItem): Boolean = {
override def onOptionsItemSelected(item: MenuItem): Boolean = {
item.getItemId match {
case android.R.id.home =>
drawer.toggleMenu()
@@ -776,12 +787,10 @@ class Shadowsocks
override def onStart() {
super.onStart()
EasyTracker.getInstance(this).activityStart(this)
}
override def onStop() {
super.onStop()
EasyTracker.getInstance(this).activityStop(this)
clearDialog()
}
@@ -791,6 +800,10 @@ class Shadowsocks
Crouton.cancelAllCroutons()
unregisterReceiver(preferenceReceiver)
new BackupManager(this).dataChanged()
if (handler != null) {
handler.removeCallbacksAndMessages(null)
handler = null
}
}
def copyToSystem() {
@@ -919,7 +932,6 @@ class Shadowsocks
if (isVpnEnabled) {
val style = new Style.Builder().setBackgroundColorValue(Style.holoBlueLight).build()
val config = new Configuration.Builder().setDuration(Configuration.DURATION_LONG).build()
Crouton.makeText(Shadowsocks.this, R.string.vpn_status, style).setConfiguration(config).show()
changeSwitch(checked = false)
}
true
@@ -39,26 +39,35 @@
package com.github.shadowsocks
import java.util
import java.util.concurrent.TimeUnit
import android.app.Application
import com.github.shadowsocks.database.DBHelper
import com.google.tagmanager.{Container, ContainerOpener, TagManager}
import com.google.tagmanager.ContainerOpener.{Notifier, OpenType}
import com.google.tagmanager.Container.FunctionCallMacroHandler
import java.util
import com.github.shadowsocks.utils.Utils
import com.google.android.gms.analytics.GoogleAnalytics
import com.google.android.gms.common.api.ResultCallback
import com.google.android.gms.tagmanager.Container.FunctionCallMacroCallback
import com.google.android.gms.tagmanager.{ContainerHolder, TagManager}
class ShadowsocksApplication extends Application {
lazy val dbHelper = new DBHelper(this)
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() {
val tm = TagManager.getInstance(this)
ContainerOpener.openContainer(tm, "GTM-NT8WS8", OpenType.PREFER_NON_DEFAULT, null, new Notifier {
override def containerAvailable(container: Container) {
tagContainer = container
container.registerFunctionCallMacroHandler(SIG_FUNC, new FunctionCallMacroHandler {
def getValue(functionName: String, parameters: util.Map[String, AnyRef]): AnyRef = {
val pending = tm.loadContainerPreferNonDefault("GTM-NT8WS8", R.raw.gtm_default_container)
val callback = new ResultCallback[ContainerHolder] {
override def onResult(holder: ContainerHolder): Unit = {
if (!holder.getStatus.isSuccess) {
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) {
Utils.getSignature(getApplicationContext)
}
@@ -66,6 +75,7 @@ class ShadowsocksApplication extends Application {
}
})
}
})
}
pending.setResultCallback(callback, 2, TimeUnit.SECONDS)
}
}
@@ -39,8 +39,7 @@
package com.github.shadowsocks
import android.app.backup.{FileBackupHelper, SharedPreferencesBackupHelper, BackupAgentHelper}
import android.content.Context
import android.app.backup.{BackupAgentHelper, FileBackupHelper, SharedPreferencesBackupHelper}
import com.github.shadowsocks.database.DBHelper
class ShadowsocksBackupAgent extends BackupAgentHelper {
@@ -39,30 +39,26 @@
package com.github.shadowsocks
import android.app.Notification
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import java.io.File
import java.lang.reflect.{InvocationTargetException, Method}
import java.util.{Timer, TimerTask}
import android.app.{Notification, NotificationManager, PendingIntent, Service}
import android.content._
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.{PackageInfo, PackageManager}
import android.graphics.Color
import android.net.TrafficStats
import android.os._
import android.support.v4.app.NotificationCompat
import android.util.Log
import com.google.analytics.tracking.android.{Fields, MapBuilder, EasyTracker}
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
import org.apache.http.conn.util.InetAddressUtils
import scala.collection._
import java.util.{TimerTask, Timer}
import android.net.TrafficStats
import scala.concurrent.ops._
import com.github.shadowsocks.utils._
import scala.Some
import android.graphics.Color
import com.github.shadowsocks.aidl.Config
import com.github.shadowsocks.utils._
import com.google.android.gms.analytics.HitBuilders
import org.apache.http.conn.util.InetAddressUtils
import scala.collection._
import scala.collection.mutable.ArrayBuffer
import java.io.File
import scala.concurrent.ops._
case class TrafficStat(tx: Long, rx: Long, timestamp: Long)
@@ -100,7 +96,7 @@ class ShadowsocksNatService extends Service with BaseService {
private var timer: Timer = null
private val TIMER_INTERVAL = 2
val handler: Handler = new Handler()
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
def isACLEnabled: Boolean = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
@@ -220,12 +216,12 @@ class ShadowsocksNatService extends Service with BaseService {
}
def notifyForegroundAlert(title: String, info: String, rate: Int) {
val openIntent: Intent = new Intent(this, classOf[Shadowsocks])
openIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
val closeIntent: Intent = new Intent(Action.CLOSE)
val actionIntent: PendingIntent = PendingIntent.getBroadcast(this, 0, closeIntent, 0)
val builder: NotificationCompat.Builder = new NotificationCompat.Builder(this)
val openIntent = new Intent(this, classOf[Shadowsocks])
openIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
val contentIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
val closeIntent = new Intent(Action.CLOSE)
val actionIntent = PendingIntent.getBroadcast(this, 0, closeIntent, 0)
val builder = new NotificationCompat.Builder(this)
val icon = getResources.getDrawable(R.drawable.ic_stat_shadowsocks)
if (rate >= 0) {
@@ -275,6 +271,7 @@ class ShadowsocksNatService extends Service with BaseService {
}
def onBind(intent: Intent): IBinder = {
Log.d(TAG, "onBind")
if (Action.SERVICE == intent.getAction) {
binder
} else {
@@ -309,14 +306,6 @@ class ShadowsocksNatService extends Service with BaseService {
}
}
override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = {
Service.START_STICKY
}
override def onTaskRemoved(intent: Intent) {
stopRunner()
}
def killProcesses() {
Console.runRootCommand(Utils.getIptables + " -t nat -F OUTPUT")
@@ -462,12 +451,12 @@ class ShadowsocksNatService extends Service with BaseService {
}
registerReceiver(receiver, filter)
// start tracker
EasyTracker
.getInstance(this)
.send(MapBuilder
.createEvent(TAG, "start", getVersionName, 0L)
.set(Fields.SESSION_CONTROL, "start")
// send event
application.tracker.send(new HitBuilders.EventBuilder()
.setCategory(TAG)
.setAction("start")
.setLabel(getVersionName)
.build())
changeState(State.CONNECTING)
@@ -504,9 +493,9 @@ class ShadowsocksNatService extends Service with BaseService {
spawn {
if (config.proxy == "198.199.101.152") {
val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer
val holder = application.containerHolder
try {
config = ConfigUtils.getPublicConfig(getBaseContext, container, config)
config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
} catch {
case ex: Exception =>
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
@@ -550,12 +539,11 @@ class ShadowsocksNatService extends Service with BaseService {
// change the state
changeState(State.STOPPED)
// stop the tracker
EasyTracker
.getInstance(this)
.send(MapBuilder
.createEvent(TAG, "stop", getVersionName, 0L)
.set(Fields.SESSION_CONTROL, "stop")
// send event
application.tracker.send(new HitBuilders.EventBuilder()
.setCategory(TAG)
.setAction("stop")
.setLabel(getVersionName)
.build())
// reset timer
@@ -564,13 +552,6 @@ class ShadowsocksNatService extends Service with BaseService {
timer = null
}
// clean up context
stopForegroundCompat(1)
if (receiver != null) {
unregisterReceiver(receiver)
receiver = null
}
// reset NAT
killProcesses()
@@ -578,6 +559,13 @@ class ShadowsocksNatService extends Service with BaseService {
if (callbackCount == 0) {
stopSelf()
}
// clean up context
if (receiver != null) {
unregisterReceiver(receiver)
receiver = null
}
stopForegroundCompat(1)
}
override def stopBackgroundService() {
@@ -138,7 +138,7 @@ class ShadowsocksRunnerActivity extends Activity {
deattachService()
if (receiver != null) {
unregisterReceiver(receiver)
receiver = null;
receiver = null
}
}
@@ -39,25 +39,24 @@
package com.github.shadowsocks
import java.io.File
import java.net.InetAddress
import android.app._
import android.content._
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.{PackageInfo, PackageManager}
import android.net.VpnService
import android.os._
import android.support.v4.app.NotificationCompat
import android.util.Log
import com.google.analytics.tracking.android.{Fields, MapBuilder, EasyTracker}
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.aidl.Config
import com.github.shadowsocks.utils._
import scala.Some
import com.github.shadowsocks.aidl.{IShadowsocksService, Config}
import com.google.android.gms.analytics.HitBuilders
import org.apache.commons.net.util.SubnetUtils
import org.apache.http.conn.util.InetAddressUtils
import scala.collection.mutable.ArrayBuffer
import java.io.File
import java.net.InetAddress
import scala.concurrent.ops._
class ShadowsocksVpnService extends VpnService with BaseService {
@@ -73,7 +72,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
var apps: Array[ProxiedApp] = null
var config: Config = null
val handler: Handler = new Handler()
private lazy val application = getApplication.asInstanceOf[ShadowsocksApplication]
def isByass(net: SubnetUtils): Boolean = {
val info = net.getInfo
@@ -118,13 +117,8 @@ class ShadowsocksVpnService extends VpnService with BaseService {
def startVpn() {
val openIntent: Intent = new Intent(this, classOf[Shadowsocks])
openIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val configIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
val builder = new Builder()
builder
.setConfigureIntent(configIntent)
.setSession(config.profileName)
.setMtu(VPN_MTU)
.addAddress(PRIVATE_VLAN.format("1"), 24)
@@ -221,17 +215,13 @@ class ShadowsocksVpnService extends VpnService with BaseService {
}
def notifyAlert(title: String, info: String) {
val openIntent: Intent = new Intent(this, classOf[Shadowsocks])
openIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
val builder: NotificationCompat.Builder = new NotificationCompat.Builder(this)
val builder = new NotificationCompat.Builder(this)
builder
.setSmallIcon(R.drawable.ic_stat_shadowsocks)
.setWhen(0)
.setTicker(title)
.setContentTitle(getString(R.string.app_name))
.setContentText(info)
.setContentIntent(contentIntent)
.setAutoCancel(true)
notificationManager.notify(1, builder.build)
}
@@ -255,14 +245,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
.asInstanceOf[NotificationManager]
}
override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = {
Service.START_STICKY
}
override def onTaskRemoved(intent: Intent) {
stopRunner()
}
override def onRevoke() {
stopRunner()
}
@@ -289,12 +271,11 @@ class ShadowsocksVpnService extends VpnService with BaseService {
return
}
// start the tracker
EasyTracker
.getInstance(this)
.send(MapBuilder
.createEvent(TAG, "start", getVersionName, 0L)
.set(Fields.SESSION_CONTROL, "start")
// send event
application.tracker.send(new HitBuilders.EventBuilder()
.setCategory(TAG)
.setAction("start")
.setLabel(getVersionName)
.build())
// register close receiver
@@ -311,9 +292,9 @@ class ShadowsocksVpnService extends VpnService with BaseService {
spawn {
if (config.proxy == "198.199.101.152") {
val container = getApplication.asInstanceOf[ShadowsocksApplication].tagContainer
val holder = getApplication.asInstanceOf[ShadowsocksApplication].containerHolder
try {
config = ConfigUtils.getPublicConfig(getBaseContext, container, config)
config = ConfigUtils.getPublicConfig(getBaseContext, holder.getContainer, config)
} catch {
case ex: Exception =>
notifyAlert(getString(R.string.forward_fail), getString(R.string.service_failed))
@@ -355,20 +336,13 @@ class ShadowsocksVpnService extends VpnService with BaseService {
// channge the state
changeState(State.STOPPED)
// stop the tracker
EasyTracker
.getInstance(this)
.send(MapBuilder
.createEvent(TAG, "stop", getVersionName, 0L)
.set(Fields.SESSION_CONTROL, "stop")
// send event
application.tracker.send(new HitBuilders.EventBuilder()
.setCategory(TAG)
.setAction("stop")
.setLabel(getVersionName)
.build())
// clean up the context
if (receiver != null) {
unregisterReceiver(receiver)
receiver = null
}
// reset VPN
killProcesses()
@@ -378,13 +352,19 @@ class ShadowsocksVpnService extends VpnService with BaseService {
conn = null
}
// reset notifications
notificationManager.cancel(1)
// stop the service if no callback registered
if (callbackCount == 0) {
stopSelf()
}
// clean up the context
if (receiver != null) {
unregisterReceiver(receiver)
receiver = null
}
// reset notifications
notificationManager.cancel(1)
}
override def stopBackgroundService() {
@@ -41,7 +41,7 @@ package com.github.shadowsocks.utils
import android.content.{SharedPreferences, Context}
import com.github.shadowsocks.ShadowsocksApplication
import com.google.tagmanager.Container
import com.google.android.gms.tagmanager.Container
import scalaj.http.{HttpOptions, Http}
import com.github.shadowsocks.aidl.Config
@@ -143,8 +143,8 @@ object ConfigUtils {
}
def refresh(context: Context) {
val container = context.getApplicationContext.asInstanceOf[ShadowsocksApplication].tagContainer
if (container != null) container.refresh()
val holder = context.getApplicationContext.asInstanceOf[ShadowsocksApplication].containerHolder
if (holder != null) holder.refresh()
}
def getPublicConfig(context: Context, container: Container, config: Config): Config = {