Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfaaaf5341 | ||
|
|
4a4d3b11fb | ||
|
|
3538caa80d | ||
|
|
ae30c218e9 | ||
|
|
86e93ffa2d | ||
|
|
acd89cc999 | ||
|
|
382af46d91 | ||
|
|
415a9f6847 | ||
|
|
91a069bc44 |
@@ -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
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
Before Width: | Height: | Size: 194 B After Width: | Height: | Size: 193 B |
|
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 198 B |
|
Before Width: | Height: | Size: 135 B After Width: | Height: | Size: 129 B |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 125 B |
|
After Width: | Height: | Size: 113 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 514 B After Width: | Height: | Size: 461 B |
|
Before Width: | Height: | Size: 107 B After Width: | Height: | Size: 107 B |
|
Before Width: | Height: | Size: 100 B After Width: | Height: | Size: 100 B |
|
Before Width: | Height: | Size: 156 B After Width: | Height: | Size: 156 B |
|
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 166 B |
|
Before Width: | Height: | Size: 105 B After Width: | Height: | Size: 105 B |
|
Before Width: | Height: | Size: 114 B After Width: | Height: | Size: 134 B |
|
After Width: | Height: | Size: 110 B |
|
Before Width: | Height: | Size: 817 B After Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 370 B After Width: | Height: | Size: 351 B |
|
Before Width: | Height: | Size: 104 B After Width: | Height: | Size: 104 B |
|
Before Width: | Height: | Size: 97 B After Width: | Height: | Size: 97 B |
|
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 251 B |
|
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 259 B |
|
Before Width: | Height: | Size: 123 B After Width: | Height: | Size: 123 B |
|
Before Width: | Height: | Size: 125 B After Width: | Height: | Size: 129 B |
|
After Width: | Height: | Size: 114 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 677 B After Width: | Height: | Size: 603 B |
|
Before Width: | Height: | Size: 111 B After Width: | Height: | Size: 111 B |
|
Before Width: | Height: | Size: 101 B After Width: | Height: | Size: 101 B |
|
After Width: | Height: | Size: 357 B |
|
After Width: | Height: | Size: 351 B |
|
After Width: | Height: | Size: 350 B |
|
After Width: | Height: | Size: 255 B |
|
After Width: | Height: | Size: 352 B |
|
After Width: | Height: | Size: 140 B |
|
After Width: | Height: | Size: 131 B |
|
After Width: | Height: | Size: 148 B |
|
After Width: | Height: | Size: 372 B |
|
After Width: | Height: | Size: 360 B |
|
After Width: | Height: | Size: 163 B |
|
After Width: | Height: | Size: 137 B |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 156 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 157 B |
|
After Width: | Height: | Size: 480 B |
|
After Width: | Height: | Size: 481 B |
|
After Width: | Height: | Size: 805 B |
|
After Width: | Height: | Size: 744 B |
|
After Width: | Height: | Size: 116 B |
|
After Width: | Height: | Size: 116 B |
|
After Width: | Height: | Size: 110 B |
|
After Width: | Height: | Size: 102 B |
|
After Width: | Height: | Size: 102 B |
|
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>
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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 = {
|
||||
|
||||