Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa083a8eca | ||
|
|
ef2ff23cd0 | ||
|
|
c1e208737c | ||
|
|
75bb00593a | ||
|
|
15f25b95a0 | ||
|
|
cc9fa4c4a6 | ||
|
|
9041404f42 | ||
|
|
5aae822cdd | ||
|
|
33ed5c65c5 | ||
|
|
1424e056ac | ||
|
|
ed79e0090e | ||
|
|
304113ce97 | ||
|
|
290bf8cb31 | ||
|
|
fcb0e2ace3 | ||
|
|
f240d5d202 | ||
|
|
ea85bbd83d | ||
|
|
d3018fc090 | ||
|
|
f1f585b4d9 | ||
|
|
3653f73e0b | ||
|
|
d648910aac | ||
|
|
1e2f8c3bd3 | ||
|
|
b94c16c725 | ||
|
|
a03a6af5ba | ||
|
|
b9414c6b0a | ||
|
|
0d54d9cd9b | ||
|
|
8611a66cdc | ||
|
|
740dcc3ca9 | ||
|
|
730efbafc0 | ||
|
|
8b05476823 | ||
|
|
50b890423a | ||
|
|
fb63268895 | ||
|
|
41934f8909 | ||
|
|
bedc7a0443 | ||
|
|
537f790386 | ||
|
|
62afcf51d7 | ||
|
|
6c1ae68931 | ||
|
|
2703e91bbe | ||
|
|
8fba319db2 | ||
|
|
3e04734b9b | ||
|
|
fe33997494 | ||
|
|
86cd49d3e1 | ||
|
|
ff13792192 | ||
|
|
f36a8c784d | ||
|
|
57f8c0f307 | ||
|
|
601c227644 | ||
|
|
220143aee1 | ||
|
|
81a19c4a81 | ||
|
|
27cc53baf8 | ||
|
|
935fddcb15 | ||
|
|
49458080a1 | ||
|
|
8101fc935e | ||
|
|
491ebe500f | ||
|
|
98ce68774a | ||
|
|
b0e20552dd | ||
|
|
0d478cfbc4 | ||
|
|
d1d135ccdd | ||
|
|
a28303ee76 | ||
|
|
2b09ebcd2c | ||
|
|
59ede2586a | ||
|
|
abd1d0220c | ||
|
|
5427e00012 | ||
|
|
7f226d3f0c | ||
|
|
ee3f3c2338 | ||
|
|
6ac90abbf7 | ||
|
|
2f553b156a | ||
|
|
dec098fbc5 | ||
|
|
000d03ad4c | ||
|
|
667619f701 | ||
|
|
afd91b7155 | ||
|
|
e10272c8e5 | ||
|
|
0f5651fef7 | ||
|
|
f258de36d7 | ||
|
|
e71db2160e | ||
|
|
f1cbfb7ea7 | ||
|
|
8c2a2f032a | ||
|
|
24d45cc2a2 | ||
|
|
5220f302c5 | ||
|
|
f0ef6c8e35 | ||
|
|
10de6ea6d9 | ||
|
|
c1f55c80f9 | ||
|
|
3503e7233f |
+3
-3
@@ -1,3 +1,3 @@
|
|||||||
[submodule "src/main/jni/shadowsocks"]
|
[submodule "src/main/jni/shadowsocks-libev"]
|
||||||
path = src/main/jni/shadowsocks
|
path = src/main/jni/shadowsocks-libev
|
||||||
url = https://github.com/madeye/shadowsocks-libev
|
url = https://github.com/shadowsocks/shadowsocks-libev
|
||||||
|
|||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
language: scala
|
|
||||||
scala:
|
|
||||||
- 2.10.4
|
|
||||||
before_install:
|
|
||||||
- sudo apt-get update
|
|
||||||
install:
|
|
||||||
- sudo apt-get install -y libc6-dev-i386 lib32ncurses5-dev libx11-dev g++-multilib lib32z1-dev ccache
|
|
||||||
- export NDK_CCACHE=ccache
|
|
||||||
- export ARCH=`uname -m`
|
|
||||||
- wget http://dl.google.com/android/android-sdk_r23.0.2-linux.tgz
|
|
||||||
- tar xf android-sdk_r23.0.2-linux.tgz
|
|
||||||
- wget http://dl.google.com/android/ndk/android-ndk-r9d-linux-${ARCH}.tar.bz2
|
|
||||||
- tar xf android-ndk-r9d-linux-${ARCH}.tar.bz2
|
|
||||||
- export ANDROID_NDK_HOME=`pwd`/android-ndk-r9d
|
|
||||||
- export ANDROID_HOME=`pwd`/android-sdk-linux
|
|
||||||
- export PATH=${PATH}:${ANDROID_NDK_HOME}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
|
|
||||||
- echo "y" | android update sdk --filter tools,platform-tools,build-tools-21.0.1,android-21,extra-google-m2repository --no-ui --no-https -a
|
|
||||||
- echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a
|
|
||||||
script:
|
|
||||||
- cp local.properties.travis local.properties
|
|
||||||
- ./build.sh
|
|
||||||
- sbt android:package-release
|
|
||||||
- exit 0
|
|
||||||
@@ -6,14 +6,14 @@ Help to translate shadowsocks: http://crowdin.net/project/shadowsocks/invite
|
|||||||
|
|
||||||
[](https://play.google.com/store/apps/details?id=com.github.shadowsocks)
|
[](https://play.google.com/store/apps/details?id=com.github.shadowsocks)
|
||||||
|
|
||||||
### TRAVIS CI STATUS
|
### CI STATUS
|
||||||
|
|
||||||
[](http://travis-ci.org/shadowsocks/shadowsocks-android)
|
[](https://drone.io/github.com/shadowsocks/shadowsocks-android/latest)
|
||||||
|
|
||||||
### PREREQUISITES
|
### PREREQUISITES
|
||||||
|
|
||||||
* JDK 1.6+
|
* JDK 1.7+
|
||||||
* SBT 0.12.3
|
* SBT 0.13.0+
|
||||||
* Android SDK r21+
|
* Android SDK r21+
|
||||||
* Android NDK r9+
|
* Android NDK r9+
|
||||||
|
|
||||||
@@ -40,6 +40,7 @@ Help to translate shadowsocks: http://crowdin.net/project/shadowsocks/invite
|
|||||||
|
|
||||||
* Install Android SDK and NDK by run `brew install android-ndk android-sdk`
|
* Install Android SDK and NDK by run `brew install android-ndk android-sdk`
|
||||||
* Add `export ANDROID_HOME=/usr/local/Cellar/android-sdk/$version` to your .bashrc , then reopen the shell to load it.
|
* Add `export ANDROID_HOME=/usr/local/Cellar/android-sdk/$version` to your .bashrc , then reopen the shell to load it.
|
||||||
|
* Add `export ANDROID_NDK_HOME=/usr/local/Cellar/android-ndk/$version` to your .bashrc , then reopen the shell to load it.
|
||||||
* echo "y" | android update sdk --filter tools,platform-tools,build-tools-21.0.1,android-21,extra-google-m2repository --no-ui --no-https -a
|
* echo "y" | android update sdk --filter tools,platform-tools,build-tools-21.0.1,android-21,extra-google-m2repository --no-ui --no-https -a
|
||||||
* echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a
|
* echo "y" | android update sdk --filter extra-android-m2repository --no-ui --no-https -a
|
||||||
* Create your key following the instructions at http://developer.android.com/guide/publishing/app-signing.html#cert
|
* Create your key following the instructions at http://developer.android.com/guide/publishing/app-signing.html#cert
|
||||||
|
|||||||
@@ -14,25 +14,30 @@ ndkJavah in Android := List()
|
|||||||
|
|
||||||
ndkBuild in Android := List()
|
ndkBuild in Android := List()
|
||||||
|
|
||||||
|
typedResources in Android := false
|
||||||
|
|
||||||
|
resolvers += Resolver.jcenterRepo
|
||||||
|
|
||||||
resolvers += "JRAF" at "http://JRAF.org/static/maven/2"
|
resolvers += "JRAF" at "http://JRAF.org/static/maven/2"
|
||||||
|
|
||||||
resolvers += "madeye private releases" at "http://madeye-maven-repository.googlecode.com/git/"
|
|
||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"dnsjava" % "dnsjava" % "2.1.5",
|
"dnsjava" % "dnsjava" % "2.1.7",
|
||||||
"com.github.kevinsawicki" % "http-request" % "5.6",
|
"com.github.kevinsawicki" % "http-request" % "5.6",
|
||||||
"commons-net" % "commons-net" % "3.3",
|
"commons-net" % "commons-net" % "3.3",
|
||||||
"com.google.zxing" % "android-integration" % "3.1.0"
|
"com.google.zxing" % "android-integration" % "3.1.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
|
"com.joanzapata.android" % "android-iconify" % "1.0.9",
|
||||||
|
"net.glxn.qrgen" % "android" % "2.0",
|
||||||
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
|
"net.simonvt.menudrawer" % "menudrawer" % "3.0.6",
|
||||||
"com.google.android.gms" % "play-services" % "5.0.89",
|
"com.google.android.gms" % "play-services-base" % "6.5.87",
|
||||||
"com.android.support" % "support-v4" % "19.1.0"
|
"com.google.android.gms" % "play-services-ads" % "6.5.87",
|
||||||
|
"com.android.support" % "support-v4" % "21.0.3"
|
||||||
)
|
)
|
||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"de.keyboardsurfer.android.widget" % "crouton" % "1.8.4" exclude("com.google.android", "support-v4"),
|
"com.github.mrengineer13" % "snackbar" % "0.5.0",
|
||||||
"com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4",
|
"com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4",
|
||||||
"com.j256.ormlite" % "ormlite-core" % "4.47",
|
"com.j256.ormlite" % "ormlite-core" % "4.47",
|
||||||
"com.j256.ormlite" % "ormlite-android" % "4.47"
|
"com.j256.ormlite" % "ormlite-android" % "4.47"
|
||||||
@@ -45,6 +50,7 @@ proguardOptions in Android ++= Seq("-keep class android.support.v4.app.** { *; }
|
|||||||
"-keep class org.jraf.android.backport.** { *; }",
|
"-keep class org.jraf.android.backport.** { *; }",
|
||||||
"-keep class com.github.shadowsocks.** { *; }",
|
"-keep class com.github.shadowsocks.** { *; }",
|
||||||
"-keep class * extends com.j256.ormlite.** { *; }",
|
"-keep class * extends com.j256.ormlite.** { *; }",
|
||||||
|
"-keep class com.joanzapata.** { *; }",
|
||||||
"-keepattributes *Annotation*",
|
"-keepattributes *Annotation*",
|
||||||
"-dontwarn org.xbill.**",
|
"-dontwarn org.xbill.**",
|
||||||
"-dontwarn com.actionbarsherlock.**")
|
"-dontwarn com.actionbarsherlock.**")
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
-4488
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
|||||||
sbt.version=0.13.5
|
sbt.version=0.13.8
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
resolvers += Resolver.url("scalasbt releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns)
|
resolvers += Resolver.url("scalasbt releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns)
|
||||||
|
|
||||||
addSbtPlugin("com.hanhuy.sbt" % "android-sdk-plugin" % "1.3.10")
|
addSbtPlugin("com.hanhuy.sbt" % "android-sdk-plugin" % "1.3.22")
|
||||||
|
|
||||||
resolvers += Resolver.sbtPluginRepo("snapshots")
|
resolvers += Resolver.sbtPluginRepo("snapshots")
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.github.shadowsocks"
|
package="com.github.shadowsocks"
|
||||||
android:versionCode="91"
|
android:versionCode="104"
|
||||||
android:versionName="2.5.3">
|
android:versionName="2.6.6">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
@@ -65,7 +65,8 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".AppManager"
|
android:name=".AppManager"
|
||||||
android:theme="@style/Theme.AppManager"
|
android:theme="@style/Theme.AppManager"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name"
|
||||||
|
android:parentActivityName=".Shadowsocks">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="com.github.shadowsocks.AppManager"/>
|
<action android:name="com.github.shadowsocks.AppManager"/>
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
|||||||
+108
-15
@@ -16,6 +16,73 @@
|
|||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
ROOT_PATH := $(LOCAL_PATH)
|
ROOT_PATH := $(LOCAL_PATH)
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
## libsodium
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
crypto_aead_src := crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c
|
||||||
|
|
||||||
|
crypto_auth_src := crypto_auth/crypto_auth.c crypto_auth/hmacsha256/auth_hmacsha256_api.c crypto_auth/hmacsha256/cp/hmac_hmacsha256.c crypto_auth/hmacsha256/cp/verify_hmacsha256.c crypto_auth/hmacsha512/auth_hmacsha512_api.c crypto_auth/hmacsha512/cp/hmac_hmacsha512.c crypto_auth/hmacsha512/cp/verify_hmacsha512.c crypto_auth/hmacsha512256/auth_hmacsha512256_api.c crypto_auth/hmacsha512256/cp/hmac_hmacsha512256.c crypto_auth/hmacsha512256/cp/verify_hmacsha512256.c
|
||||||
|
|
||||||
|
crypto_box_src := crypto_box/crypto_box.c crypto_box/crypto_box_easy.c crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305_api.c crypto_box/curve25519xsalsa20poly1305/ref/after_curve25519xsalsa20poly1305.c crypto_box/curve25519xsalsa20poly1305/ref/before_curve25519xsalsa20poly1305.c crypto_box/curve25519xsalsa20poly1305/ref/box_curve25519xsalsa20poly1305.c crypto_box/curve25519xsalsa20poly1305/ref/keypair_curve25519xsalsa20poly1305.c
|
||||||
|
|
||||||
|
crypto_core_src := crypto_core/hsalsa20/core_hsalsa20_api.c crypto_core/hsalsa20/ref2/core_hsalsa20.c crypto_core/salsa20/core_salsa20_api.c crypto_core/salsa20/ref/core_salsa20.c crypto_core/salsa2012/core_salsa2012_api.c crypto_core/salsa2012/ref/core_salsa2012.c crypto_core/salsa208/core_salsa208_api.c crypto_core/salsa208/ref/core_salsa208.c
|
||||||
|
|
||||||
|
crypto_generichash_src := crypto_generichash/blake2/generichash_blake2_api.c crypto_generichash/blake2/ref/blake2b-ref.c crypto_generichash/blake2/ref/generichash_blake2b.c crypto_generichash/crypto_generichash.c
|
||||||
|
|
||||||
|
crypto_hash_src := crypto_hash/crypto_hash.c crypto_hash/sha256/cp/hash_sha256.c crypto_hash/sha256/hash_sha256_api.c crypto_hash/sha512/cp/hash_sha512.c crypto_hash/sha512/hash_sha512_api.c
|
||||||
|
|
||||||
|
crypto_onetimeauth_src := crypto_onetimeauth/crypto_onetimeauth.c crypto_onetimeauth/poly1305/donna/auth_poly1305_donna.c crypto_onetimeauth/poly1305/donna/verify_poly1305_donna.c crypto_onetimeauth/poly1305/onetimeauth_poly1305.c crypto_onetimeauth/poly1305/onetimeauth_poly1305_api.c crypto_onetimeauth/poly1305/onetimeauth_poly1305_try.c
|
||||||
|
|
||||||
|
crypto_pwhash_src := crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c
|
||||||
|
|
||||||
|
crypto_scalarmult_src := crypto_scalarmult/crypto_scalarmult.c crypto_scalarmult/curve25519/donna_c64/base_curve25519_donna_c64.c crypto_scalarmult/curve25519/donna_c64/smult_curve25519_donna_c64.c crypto_scalarmult/curve25519/ref10/base_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_0_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_1_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_add_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_copy_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_cswap_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_frombytes_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_invert_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_mul121666_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_mul_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_sq_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_sub_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/fe_tobytes_curve25519_ref10.c crypto_scalarmult/curve25519/ref10/scalarmult_curve25519_ref10.c crypto_scalarmult/curve25519/scalarmult_curve25519_api.c
|
||||||
|
|
||||||
|
crypto_secretbox_src := crypto_secretbox/crypto_secretbox.c crypto_secretbox/crypto_secretbox_easy.c crypto_secretbox/xsalsa20poly1305/ref/box_xsalsa20poly1305.c crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305_api.c
|
||||||
|
|
||||||
|
crypto_shorthash_src := crypto_shorthash/crypto_shorthash.c crypto_shorthash/siphash24/ref/shorthash_siphash24.c crypto_shorthash/siphash24/shorthash_siphash24_api.c
|
||||||
|
|
||||||
|
crypto_sign_src := crypto_sign/crypto_sign.c crypto_sign/ed25519/ref10/fe_0.c crypto_sign/ed25519/ref10/fe_1.c crypto_sign/ed25519/ref10/fe_add.c crypto_sign/ed25519/ref10/fe_cmov.c crypto_sign/ed25519/ref10/fe_copy.c crypto_sign/ed25519/ref10/fe_frombytes.c crypto_sign/ed25519/ref10/fe_invert.c crypto_sign/ed25519/ref10/fe_isnegative.c crypto_sign/ed25519/ref10/fe_isnonzero.c crypto_sign/ed25519/ref10/fe_mul.c crypto_sign/ed25519/ref10/fe_neg.c crypto_sign/ed25519/ref10/fe_pow22523.c crypto_sign/ed25519/ref10/fe_sq.c crypto_sign/ed25519/ref10/fe_sq2.c crypto_sign/ed25519/ref10/fe_sub.c crypto_sign/ed25519/ref10/fe_tobytes.c crypto_sign/ed25519/ref10/ge_add.c crypto_sign/ed25519/ref10/ge_double_scalarmult.c crypto_sign/ed25519/ref10/ge_frombytes.c crypto_sign/ed25519/ref10/ge_madd.c crypto_sign/ed25519/ref10/ge_msub.c crypto_sign/ed25519/ref10/ge_p1p1_to_p2.c crypto_sign/ed25519/ref10/ge_p1p1_to_p3.c crypto_sign/ed25519/ref10/ge_p2_0.c crypto_sign/ed25519/ref10/ge_p2_dbl.c crypto_sign/ed25519/ref10/ge_p3_0.c crypto_sign/ed25519/ref10/ge_p3_dbl.c crypto_sign/ed25519/ref10/ge_p3_to_cached.c crypto_sign/ed25519/ref10/ge_p3_to_p2.c crypto_sign/ed25519/ref10/ge_p3_tobytes.c crypto_sign/ed25519/ref10/ge_precomp_0.c crypto_sign/ed25519/ref10/ge_scalarmult_base.c crypto_sign/ed25519/ref10/ge_sub.c crypto_sign/ed25519/ref10/ge_tobytes.c crypto_sign/ed25519/ref10/keypair.c crypto_sign/ed25519/ref10/open.c crypto_sign/ed25519/ref10/sc_muladd.c crypto_sign/ed25519/ref10/sc_reduce.c crypto_sign/ed25519/ref10/sign.c crypto_sign/ed25519/sign_ed25519_api.c crypto_sign/edwards25519sha512batch/ref/fe25519_edwards25519sha512batch.c crypto_sign/edwards25519sha512batch/ref/ge25519_edwards25519sha512batch.c crypto_sign/edwards25519sha512batch/ref/sc25519_edwards25519sha512batch.c crypto_sign/edwards25519sha512batch/ref/sign_edwards25519sha512batch.c crypto_sign/edwards25519sha512batch/sign_edwards25519sha512batch_api.c
|
||||||
|
|
||||||
|
crypto_stream_src := crypto_stream/aes128ctr/portable/afternm_aes128ctr.c crypto_stream/aes128ctr/portable/beforenm_aes128ctr.c crypto_stream/aes128ctr/portable/common_aes128ctr.c crypto_stream/aes128ctr/portable/consts_aes128ctr.c crypto_stream/aes128ctr/portable/int128_aes128ctr.c crypto_stream/aes128ctr/portable/stream_aes128ctr.c crypto_stream/aes128ctr/portable/xor_afternm_aes128ctr.c crypto_stream/aes128ctr/stream_aes128ctr_api.c crypto_stream/chacha20/ref/stream_chacha20_ref.c crypto_stream/chacha20/stream_chacha20_api.c crypto_stream/crypto_stream.c crypto_stream/salsa20/ref/stream_salsa20_ref.c crypto_stream/salsa20/ref/xor_salsa20_ref.c crypto_stream/salsa20/stream_salsa20_api.c crypto_stream/salsa2012/ref/stream_salsa2012.c crypto_stream/salsa2012/ref/xor_salsa2012.c crypto_stream/salsa2012/stream_salsa2012_api.c crypto_stream/salsa208/ref/stream_salsa208.c crypto_stream/salsa208/ref/xor_salsa208.c crypto_stream/salsa208/stream_salsa208_api.c crypto_stream/xsalsa20/ref/stream_xsalsa20.c crypto_stream/xsalsa20/ref/xor_xsalsa20.c crypto_stream/xsalsa20/stream_xsalsa20_api.c
|
||||||
|
|
||||||
|
crypto_verify_src := crypto_verify/16/ref/verify_16.c crypto_verify/16/verify_16_api.c crypto_verify/32/ref/verify_32.c crypto_verify/32/verify_32_api.c crypto_verify/64/ref/verify_64.c crypto_verify/64/verify_64_api.c
|
||||||
|
|
||||||
|
randombytes_src := randombytes/randombytes.c randombytes/salsa20/randombytes_salsa20_random.c randombytes/sysrandom/randombytes_sysrandom.c
|
||||||
|
|
||||||
|
sodium_src := sodium/core.c sodium/runtime.c sodium/utils.c sodium/version.c
|
||||||
|
|
||||||
|
SODIUM_SOURCE := $(crypto_aead_src) $(crypto_auth_src) $(crypto_box_src) \
|
||||||
|
$(crypto_core_src) $(crypto_generichash_src) $(crypto_hash_src) \
|
||||||
|
$(crypto_onetimeauth_src) $(crypto_pwhash_src) $(crypto_scalarmult_src) \
|
||||||
|
$(crypto_secretbox_src) $(crypto_shorthash_src) $(crypto_sign_src) \
|
||||||
|
$(crypto_stream_src) $(crypto_verify_src) $(randombytes_src) $(sodium_src)
|
||||||
|
|
||||||
|
LOCAL_MODULE := sodium
|
||||||
|
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include \
|
||||||
|
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
|
||||||
|
-DPACKAGE_NAME=\"libsodium\" -DPACKAGE_TARNAME=\"libsodium\" \
|
||||||
|
-DPACKAGE_VERSION=\"1.0.1\" -DPACKAGE_STRING=\"libsodium\ 1.0.1\" \
|
||||||
|
-DPACKAGE_BUGREPORT=\"https://github.com/jedisct1/libsodium/issues\" \
|
||||||
|
-DPACKAGE_URL=\"https://github.com/jedisct1/libsodium\" \
|
||||||
|
-DPACKAGE=\"libsodium\" -DVERSION=\"1.0.1\" -DSTDC_HEADERS=1 \
|
||||||
|
-DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 \
|
||||||
|
-DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 \
|
||||||
|
-DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 \
|
||||||
|
-D__EXTENSIONS__=1 -D_ALL_SOURCE=1 -D_GNU_SOURCE=1 \
|
||||||
|
-D_POSIX_PTHREAD_SEMANTICS=1 -D_TANDEM_SOURCE=1 \
|
||||||
|
-DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_MMINTRIN_H=1 \
|
||||||
|
-DHAVE_EMMINTRIN_H=1 -DHAVE_PMMINTRIN_H=1 -DHAVE_TMMINTRIN_H=1 \
|
||||||
|
-DHAVE_SYS_MMAN_H=1 -DNATIVE_LITTLE_ENDIAN=1 \
|
||||||
|
-DHAVE_WEAK_SYMBOLS=1 -DHAVE_ARC4RANDOM=1 -DHAVE_ARC4RANDOM_BUF=1 \
|
||||||
|
-DHAVE_MLOCK=1 -DHAVE_MPROTECT=1 -DHAVE_POSIX_MEMALIGN=1
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libsodium/src/libsodium/,$(SODIUM_SOURCE))
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
## libevent
|
## libevent
|
||||||
########################################################
|
########################################################
|
||||||
@@ -59,10 +126,10 @@ set_src = set/allocation.c set/inspection.c set/ipv4_set.c set/ipv6_set.c \
|
|||||||
IPSET_SOURCE := general.c $(bdd_src) $(map_src) $(set_src)
|
IPSET_SOURCE := general.c $(bdd_src) $(map_src) $(set_src)
|
||||||
|
|
||||||
LOCAL_MODULE := libipset
|
LOCAL_MODULE := libipset
|
||||||
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks/libipset/include \
|
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks-libev/libipset/include \
|
||||||
-I$(LOCAL_PATH)/shadowsocks/libcork/include
|
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(addprefix shadowsocks/libipset/,$(IPSET_SOURCE))
|
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libipset/,$(IPSET_SOURCE))
|
||||||
|
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
@@ -86,10 +153,29 @@ pthreads_src := pthreads/thread.c
|
|||||||
CORK_SOURCE := $(cli_src) $(core_src) $(ds_src) $(posix_src) $(pthreads_src)
|
CORK_SOURCE := $(cli_src) $(core_src) $(ds_src) $(posix_src) $(pthreads_src)
|
||||||
|
|
||||||
LOCAL_MODULE := libcork
|
LOCAL_MODULE := libcork
|
||||||
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks/libcork/include \
|
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
||||||
-DCORK_API=CORK_LOCAL
|
-DCORK_API=CORK_LOCAL
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(addprefix shadowsocks/libcork/,$(CORK_SOURCE))
|
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libcork/,$(CORK_SOURCE))
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
########################################################
|
||||||
|
## libudns
|
||||||
|
########################################################
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
UDNS_SOURCES := udns_dn.c udns_dntosp.c udns_parse.c udns_resolver.c udns_init.c \
|
||||||
|
udns_misc.c udns_XtoX.c \
|
||||||
|
udns_rr_a.c udns_rr_ptr.c udns_rr_mx.c udns_rr_txt.c udns_bl.c \
|
||||||
|
udns_rr_srv.c udns_rr_naptr.c udns_codes.c udns_jran.c
|
||||||
|
|
||||||
|
LOCAL_MODULE := libudns
|
||||||
|
LOCAL_CFLAGS += -O2 -I$(LOCAL_PATH)/shadowsocks-libev/libudns \
|
||||||
|
-DHAVE_DECL_INET_NTOP
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/libudns/,$(UDNS_SOURCES))
|
||||||
|
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
@@ -143,44 +229,51 @@ LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/pdnsd
|
|||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
## shadowsocks local library
|
## shadowsocks-libev local library
|
||||||
########################################################
|
########################################################
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
SHADOWSOCKS_SOURCES := local.c cache.c udprelay.c encrypt.c utils.c json.c jconf.c acl.c
|
SHADOWSOCKS_SOURCES := local.c cache.c udprelay.c encrypt.c utils.c netutils.c json.c jconf.c acl.c
|
||||||
|
|
||||||
LOCAL_MODULE := ss-local
|
LOCAL_MODULE := ss-local
|
||||||
LOCAL_SRC_FILES := $(addprefix shadowsocks/src/, $(SHADOWSOCKS_SOURCES))
|
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/src/, $(SHADOWSOCKS_SOURCES))
|
||||||
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL \
|
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL \
|
||||||
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H \
|
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H \
|
||||||
-I$(LOCAL_PATH)/libev/ \
|
-I$(LOCAL_PATH)/libev/ \
|
||||||
-I$(LOCAL_PATH)/openssl/include \
|
-I$(LOCAL_PATH)/openssl/include \
|
||||||
-I$(LOCAL_PATH)/shadowsocks/libcork/include \
|
-I$(LOCAL_PATH)/shadowsocks-libev/libudns \
|
||||||
-I$(LOCAL_PATH)/shadowsocks/libipset/include
|
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
||||||
|
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include \
|
||||||
|
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
|
||||||
|
-I$(LOCAL_PATH)/shadowsocks-libev/libipset/include
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := libev libcrypto libipset libcork
|
LOCAL_STATIC_LIBRARIES := libev libcrypto libipset libcork libudns libsodium
|
||||||
|
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
## shadowsocks tunnel
|
## shadowsocks-libev tunnel
|
||||||
########################################################
|
########################################################
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
SHADOWSOCKS_SOURCES := tunnel.c cache.c udprelay.c encrypt.c utils.c json.c jconf.c
|
SHADOWSOCKS_SOURCES := tunnel.c cache.c udprelay.c encrypt.c utils.c netutils.c json.c jconf.c
|
||||||
|
|
||||||
LOCAL_MODULE := ss-tunnel
|
LOCAL_MODULE := ss-tunnel
|
||||||
LOCAL_SRC_FILES := $(addprefix shadowsocks/src/, $(SHADOWSOCKS_SOURCES))
|
LOCAL_SRC_FILES := $(addprefix shadowsocks-libev/src/, $(SHADOWSOCKS_SOURCES))
|
||||||
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL -DUDPRELAY_TUNNEL \
|
LOCAL_CFLAGS := -Wall -O2 -fno-strict-aliasing -DUDPRELAY_LOCAL -DUDPRELAY_TUNNEL \
|
||||||
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H -DSSTUNNEL_JNI \
|
-DUSE_CRYPTO_OPENSSL -DANDROID -DHAVE_CONFIG_H -DSSTUNNEL_JNI \
|
||||||
-I$(LOCAL_PATH)/libev/ \
|
-I$(LOCAL_PATH)/libev/ \
|
||||||
|
-I$(LOCAL_PATH)/shadowsocks-libev/libudns \
|
||||||
|
-I$(LOCAL_PATH)/shadowsocks-libev/libcork/include \
|
||||||
|
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include \
|
||||||
|
-I$(LOCAL_PATH)/shadowsocks-libev/libsodium/src/libsodium/include/sodium \
|
||||||
-I$(LOCAL_PATH)/openssl/include
|
-I$(LOCAL_PATH)/openssl/include
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := libev libcrypto
|
LOCAL_STATIC_LIBRARIES := libev libcrypto libsodium libcork libudns
|
||||||
|
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ static void
|
|||||||
ev_arc4random_buf(void *buf, size_t n)
|
ev_arc4random_buf(void *buf, size_t n)
|
||||||
{
|
{
|
||||||
#if defined(_EVENT_HAVE_ARC4RANDOM_BUF) && !defined(__APPLE__)
|
#if defined(_EVENT_HAVE_ARC4RANDOM_BUF) && !defined(__APPLE__)
|
||||||
return arc4random_buf(buf, n);
|
arc4random_buf(buf, n);
|
||||||
|
return;
|
||||||
#else
|
#else
|
||||||
unsigned char *b = buf;
|
unsigned char *b = buf;
|
||||||
|
|
||||||
@@ -71,7 +72,8 @@ ev_arc4random_buf(void *buf, size_t n)
|
|||||||
* trickery.)
|
* trickery.)
|
||||||
*/
|
*/
|
||||||
if (arc4random_buf != NULL) {
|
if (arc4random_buf != NULL) {
|
||||||
return arc4random_buf(buf, n);
|
arc4random_buf(buf, n);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Make sure that we start out with b at a 4-byte alignment; plenty
|
/* Make sure that we start out with b at a 4-byte alignment; plenty
|
||||||
|
|||||||
@@ -25,11 +25,11 @@
|
|||||||
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
|
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
|
||||||
* major minor fix final patch/beta)
|
* major minor fix final patch/beta)
|
||||||
*/
|
*/
|
||||||
#define OPENSSL_VERSION_NUMBER 0x1000103fL
|
#define OPENSSL_VERSION_NUMBER 0x100010afL
|
||||||
#ifdef OPENSSL_FIPS
|
#ifdef OPENSSL_FIPS
|
||||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1c-fips 10 May 2012"
|
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1j-fips 15 Oct 2014"
|
||||||
#else
|
#else
|
||||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1c 10 May 2012"
|
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1j 15 Oct 2014"
|
||||||
#endif
|
#endif
|
||||||
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
|
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
|
||||||
|
|
||||||
|
|||||||
Submodule src/main/jni/shadowsocks deleted from e9f2369486
Submodule
+1
Submodule src/main/jni/shadowsocks-libev added at 02050e49e7
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@@ -9,7 +9,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:textSize="24sp"
|
android:textSize="26sp"
|
||||||
android:textColor="@color/title"
|
android:textColor="@color/title"
|
||||||
android:text="@string/screen_name"
|
android:text="@string/screen_name"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item android:id="@+id/action_export"
|
||||||
|
android:title="@string/action_export"
|
||||||
|
android:showAsAction="never" />
|
||||||
|
<item android:id="@+id/action_import"
|
||||||
|
android:title="@string/action_import"
|
||||||
|
android:showAsAction="never" />
|
||||||
|
</menu>
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
<?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="Theme.Shadow" parent="@android:style/Theme.Material.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>
|
||||||
|
<!-- Light.DarkActionBar specific -->
|
||||||
|
<item name="android:actionBarWidgetTheme">@style/Theme.Shadow.Widget</item>
|
||||||
|
<item name="android:textAppearanceLargePopupMenu">@style/m_textAppearanceLargePopupMenu</item>
|
||||||
|
<item name="android:textAppearanceSmallPopupMenu" >@style/m_textAppearanceSmallPopupMenu</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="ActionBar.Solid.Shadow" parent="@android:style/Widget.Material.ActionBar">
|
||||||
|
<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>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="ActionBar.Transparent.Shadow" parent="@android:style/Widget.Material.ActionBar">
|
||||||
|
<item name="android:background">@drawable/ab_transparent_shadow</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="PopupMenu.Shadow" parent="@android:style/Widget.Material.ListPopupWindow">
|
||||||
|
<item name="android:popupBackground">@drawable/menu_dropdown_panel_shadow</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="m_textAppearanceSmallPopupMenu" parent="@android:style/TextAppearance.Material.Widget.PopupMenu.Small">
|
||||||
|
<item name="android:textColor">@android:color/black</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="m_textAppearanceLargePopupMenu" parent="@android:style/TextAppearance.Material.Widget.PopupMenu.Large">
|
||||||
|
<item name="android:textColor">@android:color/black</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="DropDownListView.Shadow" parent="@android:style/Widget.Material.ListView.DropDown">
|
||||||
|
<item name="android:listSelector">@drawable/selectable_background_shadow</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="ActionBarTabStyle.Shadow" parent="@android:style/Widget.Material.ActionBar.TabView">
|
||||||
|
<item name="android:background">@drawable/tab_indicator_ab_shadow</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="DropDownNav.Shadow" parent="@android:style/Widget.Material.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>
|
||||||
|
|
||||||
|
<!-- this style is only referenced in a Light.DarkActionBar based theme -->
|
||||||
|
<style name="Theme.Shadow.Widget" parent="@android:style/Theme.Material">
|
||||||
|
<item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
|
||||||
|
<item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
|
||||||
|
<item name="android:textColor">@android:color/white</item>
|
||||||
|
<item name="android:textAppearanceLargePopupMenu">@style/m_textAppearanceLargePopupMenu</item>
|
||||||
|
<item name="android:textAppearanceSmallPopupMenu" >@style/m_textAppearanceSmallPopupMenu</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="PopupTheme" parent="@android:style/Theme.Material.Light">
|
||||||
|
<item name="android:windowActionBar">false</item>
|
||||||
|
<item name="android:windowNoTitle">true</item>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -10,13 +10,13 @@
|
|||||||
<string name="profile">配置文件</string>
|
<string name="profile">配置文件</string>
|
||||||
<string name="profile_summary">配置文件名称</string>
|
<string name="profile_summary">配置文件名称</string>
|
||||||
<string name="proxy">服务器</string>
|
<string name="proxy">服务器</string>
|
||||||
<string name="proxy_summary">您的影梭服务器的地址</string>
|
<string name="proxy_summary">远程服务器的地址</string>
|
||||||
<string name="remote_port">远程端口</string>
|
<string name="remote_port">远程端口</string>
|
||||||
<string name="remote_port_summary">您的影梭服务器的端口号</string>
|
<string name="remote_port_summary">远程服务器的端口号</string>
|
||||||
<string name="port">本地端口</string>
|
<string name="port">本地端口</string>
|
||||||
<string name="port_summary">您的影梭客户端的端口号</string>
|
<string name="port_summary">本地客户端的端口号</string>
|
||||||
<string name="sitekey">密码</string>
|
<string name="sitekey">密码</string>
|
||||||
<string name="sitekey_summary">您的影梭服务器的密码</string>
|
<string name="sitekey_summary">远程服务器的密码</string>
|
||||||
<string name="enc_method">加密方法</string>
|
<string name="enc_method">加密方法</string>
|
||||||
<string name="feature_cat">功能设置</string>
|
<string name="feature_cat">功能设置</string>
|
||||||
<string name="http_proxy">HTTP 代理服务器</string>
|
<string name="http_proxy">HTTP 代理服务器</string>
|
||||||
@@ -47,9 +47,10 @@
|
|||||||
<string name="service_failed">无法连接远程服务器</string>
|
<string name="service_failed">无法连接远程服务器</string>
|
||||||
<string name="stop">停止服务</string>
|
<string name="stop">停止服务</string>
|
||||||
<string name="stopping">正在关闭...</string>
|
<string name="stopping">正在关闭...</string>
|
||||||
<string name="vpn_error">后台服务启动失败:\"%s\"。</string>
|
<string name="vpn_error">后台服务启动失败:%s</string>
|
||||||
<string name="ok_iknow">确定</string>
|
<string name="ok_iknow">确定</string>
|
||||||
<string name="port_alert">端口号应大于1024</string>
|
<string name="close">关闭</string>
|
||||||
|
<string name="port_alert">本地端口号应大于1024</string>
|
||||||
<string name="port_empty">端口号不能为空</string>
|
<string name="port_empty">端口号不能为空</string>
|
||||||
<string name="proxy_empty">代理服务器地址不能为空</string>
|
<string name="proxy_empty">代理服务器地址不能为空</string>
|
||||||
<string name="crash_alert">检测到意外退出,状态已被重置。</string>
|
<string name="crash_alert">检测到意外退出,状态已被重置。</string>
|
||||||
@@ -67,6 +68,7 @@
|
|||||||
<string name="about_title">影梭(shadowsocks)%s</string>
|
<string name="about_title">影梭(shadowsocks)%s</string>
|
||||||
<string name="flush_dnscache">刷新 DNS 缓存</string>
|
<string name="flush_dnscache">刷新 DNS 缓存</string>
|
||||||
<string name="flushing">刷新中...</string>
|
<string name="flushing">刷新中...</string>
|
||||||
|
<string name="qrcode">二维码</string>
|
||||||
<string name="add_profile">添加配置文件</string>
|
<string name="add_profile">添加配置文件</string>
|
||||||
|
|
||||||
<string name="enable_nat">启用 NAT 模式.</string>
|
<string name="enable_nat">启用 NAT 模式.</string>
|
||||||
@@ -88,4 +90,12 @@
|
|||||||
<item>绕过局域网及中国大陆地址</item>
|
<item>绕过局域网及中国大陆地址</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string name="action_export">导出至剪贴板</string>
|
||||||
|
<string name="action_import">从剪贴板导入</string>
|
||||||
|
<string name="action_export_msg">导出成功</string>
|
||||||
|
<string name="action_export_err">导出失败</string>
|
||||||
|
<string name="action_import_msg">导入成功</string>
|
||||||
|
<string name="action_import_err">导入失败</string>
|
||||||
|
<string name="error">错误</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
+187
-9682
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
<color name="title_background">#ff5e5e5e</color>
|
<color name="title_background">#ff5e5e5e</color>
|
||||||
<color name="dialog_title_background">#17170443</color>
|
<color name="dialog_title_background">#17170443</color>
|
||||||
|
<color name="white">#FFFFFF</color>
|
||||||
<color name="black">#000000</color>
|
<color name="black">#000000</color>
|
||||||
<color name="grey1">#646464</color>
|
<color name="grey1">#646464</color>
|
||||||
<color name="grey2">#c8c8c8</color>
|
<color name="grey2">#c8c8c8</color>
|
||||||
@@ -11,4 +12,4 @@
|
|||||||
<color name="md__transparent">#00000000</color>
|
<color name="md__transparent">#00000000</color>
|
||||||
<color name="md__defaultBackground">#FF555555</color>
|
<color name="md__defaultBackground">#FF555555</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Executable → Regular
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable → Regular
+15
-6
@@ -14,13 +14,13 @@
|
|||||||
<string name="profile">Profile</string>
|
<string name="profile">Profile</string>
|
||||||
<string name="profile_summary">Profile name</string>
|
<string name="profile_summary">Profile name</string>
|
||||||
<string name="proxy">Server</string>
|
<string name="proxy">Server</string>
|
||||||
<string name="proxy_summary">Hostname or IP Address of your Shadowsocks server</string>
|
<string name="proxy_summary">Hostname or IP of the remote server</string>
|
||||||
<string name="remote_port">Remote Port</string>
|
<string name="remote_port">Remote Port</string>
|
||||||
<string name="remote_port_summary">Port number of your Shadowsocks server</string>
|
<string name="remote_port_summary">Port number of the remote server</string>
|
||||||
<string name="port">Local Port</string>
|
<string name="port">Local Port</string>
|
||||||
<string name="port_summary">Port number of your Shadowsocks client</string>
|
<string name="port_summary">Port number of the local server</string>
|
||||||
<string name="sitekey">Password</string>
|
<string name="sitekey">Password</string>
|
||||||
<string name="sitekey_summary">Password of your Shadowsocks server</string>
|
<string name="sitekey_summary">Password of the remote server</string>
|
||||||
<string name="enc_method">Encrypt Method</string>
|
<string name="enc_method">Encrypt Method</string>
|
||||||
|
|
||||||
<!-- feature category -->
|
<!-- feature category -->
|
||||||
@@ -58,13 +58,15 @@
|
|||||||
<string name="service_failed">Failed to connect the remote server</string>
|
<string name="service_failed">Failed to connect the remote server</string>
|
||||||
<string name="stop">Stop the service</string>
|
<string name="stop">Stop the service</string>
|
||||||
<string name="stopping">Shutting down...</string>
|
<string name="stopping">Shutting down...</string>
|
||||||
<string name="vpn_error">Error: \"%s\".</string>
|
<string name="vpn_error">%s</string>
|
||||||
<string name="enable_nat">Turn on NAT mode.</string>
|
<string name="enable_nat">Turn on NAT mode.</string>
|
||||||
<string name="disable_nat">Turn off NAT mode.</string>
|
<string name="disable_nat">Turn off NAT mode.</string>
|
||||||
|
<string name="error">ERROR</string>
|
||||||
|
|
||||||
<!-- alert category -->
|
<!-- alert category -->
|
||||||
<string name="ok_iknow">OK</string>
|
<string name="ok_iknow">OK</string>
|
||||||
<string name="port_alert">The port number should be greater than 1024</string>
|
<string name="close">Close</string>
|
||||||
|
<string name="port_alert">The local port number should be greater than 1024</string>
|
||||||
<string name="port_empty">Port should not be empty</string>
|
<string name="port_empty">Port should not be empty</string>
|
||||||
<string name="proxy_empty">Proxy should not be empty</string>
|
<string name="proxy_empty">Proxy should not be empty</string>
|
||||||
<string name="crash_alert">An unexpected exit detected, the context has been reset.
|
<string name="crash_alert">An unexpected exit detected, the context has been reset.
|
||||||
@@ -83,9 +85,16 @@
|
|||||||
<string name="recovery">Reset</string>
|
<string name="recovery">Reset</string>
|
||||||
<string name="about">About</string>
|
<string name="about">About</string>
|
||||||
<string name="about_title">Shadowsocks %s</string>
|
<string name="about_title">Shadowsocks %s</string>
|
||||||
|
<string name="qrcode">QR Code</string>
|
||||||
<string name="flush_dnscache">Flush DNS Cache</string>
|
<string name="flush_dnscache">Flush DNS Cache</string>
|
||||||
<string name="flushing">Flushing</string>
|
<string name="flushing">Flushing</string>
|
||||||
<string name="add_profile">Add Profile</string>
|
<string name="add_profile">Add Profile</string>
|
||||||
|
<string name="action_export">Export to Clipboard</string>
|
||||||
|
<string name="action_import">Import from Clipboard</string>
|
||||||
|
<string name="action_export_msg">Successfully export!</string>
|
||||||
|
<string name="action_export_err">Failed to export.</string>
|
||||||
|
<string name="action_import_msg">Successfully import!</string>
|
||||||
|
<string name="action_import_err">Failed to import.</string>
|
||||||
|
|
||||||
<!-- profile -->
|
<!-- profile -->
|
||||||
<string name="add_profile_dialog">Add this Shadowsocks Profile?</string>
|
<string name="add_profile_dialog">Add this Shadowsocks Profile?</string>
|
||||||
|
|||||||
@@ -19,7 +19,9 @@
|
|||||||
<style name="Theme.AppManager" parent="@style/Theme.Shadow">
|
<style name="Theme.AppManager" parent="@style/Theme.Shadow">
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="PopupTheme" parent="@android:style/Theme.Translucent.NoTitleBar">
|
<style name="PopupTheme" parent="@android:style/Theme.Holo.Light">
|
||||||
|
<item name="android:windowActionBar">false</item>
|
||||||
|
<item name="android:windowNoTitle">true</item>
|
||||||
<item name="android:windowFrame">@null</item>
|
<item name="android:windowFrame">@null</item>
|
||||||
<item name="android:windowIsFloating">false</item>
|
<item name="android:windowIsFloating">false</item>
|
||||||
<item name="android:windowContentOverlay">@null</item>
|
<item name="android:windowContentOverlay">@null</item>
|
||||||
@@ -72,4 +74,4 @@
|
|||||||
<item name="mdMenuSize">250dp</item>
|
<item name="mdMenuSize">250dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Executable → Regular
+16
-5
@@ -29,13 +29,13 @@
|
|||||||
<item name="android:actionModeBackground">@drawable/cab_background_top_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:actionModeSplitBackground">@drawable/cab_background_bottom_shadow</item>
|
||||||
<item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Shadow</item>
|
<item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Shadow</item>
|
||||||
|
<!-- Light.DarkActionBar specific -->
|
||||||
<!-- Light.DarkActionBar specific -->
|
|
||||||
<item name="android:actionBarWidgetTheme">@style/Theme.Shadow.Widget</item>
|
<item name="android:actionBarWidgetTheme">@style/Theme.Shadow.Widget</item>
|
||||||
|
<item name="android:textAppearanceLargePopupMenu">@style/m_textAppearanceLargePopupMenu</item>
|
||||||
|
<item name="android:textAppearanceSmallPopupMenu" >@style/m_textAppearanceSmallPopupMenu</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ActionBar.Solid.Shadow" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
|
<style name="ActionBar.Solid.Shadow" parent="@android:style/Widget.Holo.ActionBar">
|
||||||
<item name="android:background">@drawable/ab_background_textured_shadow</item>
|
<item name="android:background">@drawable/ab_background_textured_shadow</item>
|
||||||
<item name="android:backgroundStacked">@drawable/ab_stacked_solid_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:backgroundSplit">@drawable/ab_background_textured_shadow</item>
|
||||||
@@ -51,6 +51,14 @@
|
|||||||
<item name="android:popupBackground">@drawable/menu_dropdown_panel_shadow</item>
|
<item name="android:popupBackground">@drawable/menu_dropdown_panel_shadow</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="m_textAppearanceSmallPopupMenu" parent="@android:style/TextAppearance.Holo.Widget.PopupMenu.Small">
|
||||||
|
<item name="android:textColor">@android:color/white</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="m_textAppearanceLargePopupMenu" parent="@android:style/TextAppearance.Holo.Widget.PopupMenu.Large">
|
||||||
|
<item name="android:textColor">@android:color/white</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="DropDownListView.Shadow" parent="@android:style/Widget.Holo.ListView.DropDown">
|
<style name="DropDownListView.Shadow" parent="@android:style/Widget.Holo.ListView.DropDown">
|
||||||
<item name="android:listSelector">@drawable/selectable_background_shadow</item>
|
<item name="android:listSelector">@drawable/selectable_background_shadow</item>
|
||||||
</style>
|
</style>
|
||||||
@@ -77,6 +85,9 @@
|
|||||||
<style name="Theme.Shadow.Widget" parent="@android:style/Theme.Holo">
|
<style name="Theme.Shadow.Widget" parent="@android:style/Theme.Holo">
|
||||||
<item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
|
<item name="android:popupMenuStyle">@style/PopupMenu.Shadow</item>
|
||||||
<item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
|
<item name="android:dropDownListViewStyle">@style/DropDownListView.Shadow</item>
|
||||||
|
<item name="android:textColor">@android:color/white</item>
|
||||||
|
<item name="android:textAppearanceLargePopupMenu">@style/m_textAppearanceLargePopupMenu</item>
|
||||||
|
<item name="android:textAppearanceSmallPopupMenu" >@style/m_textAppearanceSmallPopupMenu</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -40,6 +40,8 @@
|
|||||||
package com.github.shadowsocks
|
package com.github.shadowsocks
|
||||||
|
|
||||||
import android.app.{Activity, ProgressDialog}
|
import android.app.{Activity, ProgressDialog}
|
||||||
|
import android.content.ClipboardManager
|
||||||
|
import android.content.ClipData
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
@@ -47,6 +49,8 @@ import android.graphics.{Bitmap, PixelFormat}
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.OnClickListener
|
import android.view.View.OnClickListener
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@@ -115,7 +119,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
|
|||||||
var appsLoaded: Boolean = false
|
var appsLoaded: Boolean = false
|
||||||
|
|
||||||
def loadApps(context: Context): Array[ProxiedApp] = {
|
def loadApps(context: Context): Array[ProxiedApp] = {
|
||||||
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
val proxiedAppString = prefs.getString(Key.proxied, "")
|
val proxiedAppString = prefs.getString(Key.proxied, "")
|
||||||
val proxiedApps = proxiedAppString.split('|').sortWith(_ < _)
|
val proxiedApps = proxiedAppString.split('|').sortWith(_ < _)
|
||||||
|
|
||||||
@@ -218,12 +222,65 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override def onOptionsItemSelected(item: MenuItem): Boolean = {
|
||||||
|
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE).asInstanceOf[ClipboardManager]
|
||||||
|
val prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
|
||||||
|
item.getItemId match {
|
||||||
|
case R.id.action_export =>
|
||||||
|
val bypass = prefs.getBoolean(Key.isBypassApps, false)
|
||||||
|
val proxiedAppString = prefs.getString(Key.proxied, "")
|
||||||
|
val clip = ClipData.newPlainText(Key.proxied, bypass + " " + proxiedAppString)
|
||||||
|
clipboard.setPrimaryClip(clip)
|
||||||
|
Toast.makeText(this, R.string.action_export_msg, Toast.LENGTH_SHORT).show()
|
||||||
|
return true
|
||||||
|
case R.id.action_import =>
|
||||||
|
if (clipboard.hasPrimaryClip) {
|
||||||
|
val clipdata = clipboard.getPrimaryClip
|
||||||
|
val label = clipdata.getDescription.getLabel
|
||||||
|
if (label == Key.proxied) {
|
||||||
|
val proxiedAppSequence = clipdata.getItemAt(0).getText
|
||||||
|
if (proxiedAppSequence != null) {
|
||||||
|
val proxiedAppString = proxiedAppSequence.toString
|
||||||
|
if (!proxiedAppString.isEmpty) {
|
||||||
|
val array = proxiedAppString.split(" ")
|
||||||
|
val bypass = array(0).toBoolean
|
||||||
|
val apps = if (array.size > 1) array(1) else ""
|
||||||
|
prefs.edit.putBoolean(Key.isBypassApps, bypass).commit()
|
||||||
|
prefs.edit.putString(Key.proxied, apps).commit()
|
||||||
|
Toast.makeText(this, R.string.action_import_msg, Toast.LENGTH_SHORT).show()
|
||||||
|
// Restart activity
|
||||||
|
val intent = getIntent
|
||||||
|
finish()
|
||||||
|
startActivity(intent)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Toast.makeText(this, R.string.action_import_err, Toast.LENGTH_SHORT).show()
|
||||||
|
return false
|
||||||
|
case android.R.id.home =>
|
||||||
|
navigateUpTo(getParentActivityIntent)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override def onCreateOptionsMenu(menu: Menu): Boolean = {
|
||||||
|
val inflater = getMenuInflater()
|
||||||
|
inflater.inflate(R.menu.app_manager_menu, menu)
|
||||||
|
return super.onCreateOptionsMenu(menu)
|
||||||
|
}
|
||||||
|
|
||||||
protected override def onCreate(savedInstanceState: Bundle) {
|
protected override def onCreate(savedInstanceState: Bundle) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
handler = new Handler()
|
handler = new Handler()
|
||||||
|
|
||||||
getActionBar.setTitle(R.string.proxied_help)
|
val actionBar = getActionBar()
|
||||||
|
actionBar.setTitle(R.string.proxied_help)
|
||||||
|
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||||
|
actionBar.setDisplayShowHomeEnabled(false)
|
||||||
this.setContentView(R.layout.layout_apps)
|
this.setContentView(R.layout.layout_apps)
|
||||||
this.overlay = View.inflate(this, R.layout.overlay, null).asInstanceOf[TextView]
|
this.overlay = View.inflate(this, R.layout.overlay, null).asInstanceOf[TextView]
|
||||||
getWindowManager.addView(overlay, new
|
getWindowManager.addView(overlay, new
|
||||||
@@ -239,7 +296,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
|
|||||||
ImageLoader.getInstance().init(config)
|
ImageLoader.getInstance().init(config)
|
||||||
|
|
||||||
val bypassSwitch = findViewById(R.id.bypassSwitch).asInstanceOf[Switch]
|
val bypassSwitch = findViewById(R.id.bypassSwitch).asInstanceOf[Switch]
|
||||||
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext)
|
||||||
bypassSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener {
|
bypassSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener {
|
||||||
def onCheckedChanged(button: CompoundButton, checked: Boolean) {
|
def onCheckedChanged(button: CompoundButton, checked: Boolean) {
|
||||||
prefs.edit().putBoolean(Key.isBypassApps, checked).commit()
|
prefs.edit().putBoolean(Key.isBypassApps, checked).commit()
|
||||||
@@ -261,7 +318,7 @@ class AppManager extends Activity with OnCheckedChangeListener with OnClickListe
|
|||||||
|
|
||||||
def saveAppSettings(context: Context) {
|
def saveAppSettings(context: Context) {
|
||||||
if (apps == null) return
|
if (apps == null) return
|
||||||
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
val proxiedApps = new StringBuilder
|
val proxiedApps = new StringBuilder
|
||||||
apps.foreach(app =>
|
apps.foreach(app =>
|
||||||
if (app.proxied) {
|
if (app.proxied) {
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ import android.content.Context
|
|||||||
|
|
||||||
trait BaseService {
|
trait BaseService {
|
||||||
|
|
||||||
@volatile var state = State.INIT
|
@volatile private var state = State.INIT
|
||||||
@volatile var callbackCount = 0
|
@volatile private var callbackCount = 0
|
||||||
|
|
||||||
final val callbacks = new RemoteCallbackList[IShadowsocksServiceCallback]
|
final val callbacks = new RemoteCallbackList[IShadowsocksServiceCallback]
|
||||||
|
|
||||||
@@ -100,6 +100,12 @@ trait BaseService {
|
|||||||
def getTag: String
|
def getTag: String
|
||||||
def getContext: Context
|
def getContext: Context
|
||||||
|
|
||||||
|
def getCallbackCount(): Int = {
|
||||||
|
callbackCount
|
||||||
|
}
|
||||||
|
def getState(): Int = {
|
||||||
|
state
|
||||||
|
}
|
||||||
def changeState(s: Int) {
|
def changeState(s: Int) {
|
||||||
changeState(s, null)
|
changeState(s, null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ package com.github.shadowsocks
|
|||||||
import java.util
|
import java.util
|
||||||
import java.io.{OutputStream, InputStream, ByteArrayInputStream, ByteArrayOutputStream, IOException, FileOutputStream}
|
import java.io.{OutputStream, InputStream, ByteArrayInputStream, ByteArrayOutputStream, IOException, FileOutputStream}
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import java.lang.Math
|
||||||
|
|
||||||
import android.app.backup.BackupManager
|
import android.app.backup.BackupManager
|
||||||
import android.app.{Activity, AlertDialog, ProgressDialog}
|
import android.app.{Activity, AlertDialog, ProgressDialog}
|
||||||
@@ -56,6 +57,7 @@ import android.view.View.OnLongClickListener
|
|||||||
import android.view._
|
import android.view._
|
||||||
import android.webkit.{WebView, WebViewClient}
|
import android.webkit.{WebView, WebViewClient}
|
||||||
import android.widget._
|
import android.widget._
|
||||||
|
import com.github.mrengineer13.snackbar._
|
||||||
import com.github.shadowsocks.aidl.{IShadowsocksService, IShadowsocksServiceCallback}
|
import com.github.shadowsocks.aidl.{IShadowsocksService, IShadowsocksServiceCallback}
|
||||||
import com.github.shadowsocks.database._
|
import com.github.shadowsocks.database._
|
||||||
import com.github.shadowsocks.preferences.{PasswordEditTextPreference, ProfileEditTextPreference, SummaryEditTextPreference}
|
import com.github.shadowsocks.preferences.{PasswordEditTextPreference, ProfileEditTextPreference, SummaryEditTextPreference}
|
||||||
@@ -64,8 +66,11 @@ import com.google.android.gms.ads.{AdRequest, AdSize, AdView}
|
|||||||
import com.google.android.gms.analytics.HitBuilders
|
import com.google.android.gms.analytics.HitBuilders
|
||||||
import com.google.zxing.integration.android.IntentIntegrator
|
import com.google.zxing.integration.android.IntentIntegrator
|
||||||
import com.nostra13.universalimageloader.core.download.BaseImageDownloader
|
import com.nostra13.universalimageloader.core.download.BaseImageDownloader
|
||||||
import de.keyboardsurfer.android.widget.crouton.{Configuration, Crouton, Style}
|
|
||||||
import net.simonvt.menudrawer.MenuDrawer
|
import net.simonvt.menudrawer.MenuDrawer
|
||||||
|
import com.joanzapata.android.iconify.Iconify
|
||||||
|
import com.joanzapata.android.iconify.Iconify.IconValue
|
||||||
|
import com.joanzapata.android.iconify.IconDrawable
|
||||||
|
import net.glxn.qrgen.android.QRCode
|
||||||
|
|
||||||
import scala.collection.mutable.{ArrayBuffer, ListBuffer}
|
import scala.collection.mutable.{ArrayBuffer, ListBuffer}
|
||||||
import scala.concurrent.ops._
|
import scala.concurrent.ops._
|
||||||
@@ -205,7 +210,6 @@ class Shadowsocks
|
|||||||
// Update the UI
|
// Update the UI
|
||||||
if (switchButton != null) switchButton.setEnabled(true)
|
if (switchButton != null) switchButton.setEnabled(true)
|
||||||
if (State.isAvailable(bgService.getState)) {
|
if (State.isAvailable(bgService.getState)) {
|
||||||
Crouton.cancelAllCroutons()
|
|
||||||
setPreferenceEnabled(enabled = true)
|
setPreferenceEnabled(enabled = true)
|
||||||
} else {
|
} else {
|
||||||
changeSwitch(checked = true)
|
changeSwitch(checked = true)
|
||||||
@@ -322,7 +326,7 @@ class Shadowsocks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private def crash_recovery() {
|
private def crashRecovery() {
|
||||||
val cmd = new ArrayBuffer[String]()
|
val cmd = new ArrayBuffer[String]()
|
||||||
|
|
||||||
for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "redsocks", "tun2socks")) {
|
for (task <- Array("ss-local", "ss-tunnel", "pdnsd", "redsocks", "tun2socks")) {
|
||||||
@@ -367,19 +371,29 @@ class Shadowsocks
|
|||||||
|
|
||||||
def isTextEmpty(s: String, msg: String): Boolean = {
|
def isTextEmpty(s: String, msg: String): Boolean = {
|
||||||
if (s == null || s.length <= 0) {
|
if (s == null || s.length <= 0) {
|
||||||
Crouton.makeText(this, msg, Style.ALERT).show()
|
new SnackBar.Builder(this)
|
||||||
|
.withMessage(msg)
|
||||||
|
.withActionMessageId(R.string.error)
|
||||||
|
.withStyle(SnackBar.Style.ALERT)
|
||||||
|
.withDuration(SnackBar.LONG_SNACK)
|
||||||
|
.show()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
def cancelStart() {
|
def cancelStart() {
|
||||||
handler.postDelayed(new Runnable {
|
clearDialog()
|
||||||
override def run() {
|
changeSwitch(checked = false)
|
||||||
clearDialog()
|
}
|
||||||
changeSwitch(checked = false)
|
|
||||||
}
|
def isReady(): Boolean = {
|
||||||
}, 1000)
|
if (!checkText(Key.proxy)) return false
|
||||||
|
if (!checkText(Key.sitekey)) return false
|
||||||
|
if (!checkNumber(Key.localPort, low = false)) return false
|
||||||
|
if (!checkNumber(Key.remotePort, low = true)) return false
|
||||||
|
if (bgService == null) return false
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
def prepareStartService() {
|
def prepareStartService() {
|
||||||
@@ -393,9 +407,7 @@ class Shadowsocks
|
|||||||
onActivityResult(Shadowsocks.REQUEST_CONNECT, Activity.RESULT_OK, null)
|
onActivityResult(Shadowsocks.REQUEST_CONNECT, Activity.RESULT_OK, null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!serviceStart) {
|
serviceStart()
|
||||||
cancelStart()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -404,7 +416,10 @@ class Shadowsocks
|
|||||||
if (compoundButton eq switchButton) {
|
if (compoundButton eq switchButton) {
|
||||||
checked match {
|
checked match {
|
||||||
case true =>
|
case true =>
|
||||||
prepareStartService()
|
if (isReady)
|
||||||
|
prepareStartService()
|
||||||
|
else
|
||||||
|
changeSwitch(checked = false)
|
||||||
case false =>
|
case false =>
|
||||||
serviceStop()
|
serviceStop()
|
||||||
}
|
}
|
||||||
@@ -480,10 +495,16 @@ class Shadowsocks
|
|||||||
menuAdapter.setListener(this)
|
menuAdapter.setListener(this)
|
||||||
listView.setAdapter(menuAdapter)
|
listView.setAdapter(menuAdapter)
|
||||||
drawer.setMenuView(listView)
|
drawer.setMenuView(listView)
|
||||||
// The drawable that replaces the up indicator in the action bar
|
|
||||||
drawer.setSlideDrawable(R.drawable.ic_drawer)
|
if (Utils.isLollipopOrAbove) {
|
||||||
// Whether the previous drawable should be shown
|
drawer.setDrawerIndicatorEnabled(false)
|
||||||
drawer.setDrawerIndicatorEnabled(true)
|
} else {
|
||||||
|
// The drawable that replaces the up indicator in the action bar
|
||||||
|
drawer.setSlideDrawable(R.drawable.ic_drawer)
|
||||||
|
// Whether the previous drawable should be shown
|
||||||
|
drawer.setDrawerIndicatorEnabled(true)
|
||||||
|
}
|
||||||
|
|
||||||
if (!isSinglePane) {
|
if (!isSinglePane) {
|
||||||
drawer.openMenu(false)
|
drawer.openMenu(false)
|
||||||
}
|
}
|
||||||
@@ -499,7 +520,14 @@ class Shadowsocks
|
|||||||
getActionBar.setCustomView(switchLayout)
|
getActionBar.setCustomView(switchLayout)
|
||||||
getActionBar.setDisplayShowTitleEnabled(false)
|
getActionBar.setDisplayShowTitleEnabled(false)
|
||||||
getActionBar.setDisplayShowCustomEnabled(true)
|
getActionBar.setDisplayShowCustomEnabled(true)
|
||||||
getActionBar.setIcon(R.drawable.ic_stat_shadowsocks)
|
if (Utils.isLollipopOrAbove) {
|
||||||
|
getWindow.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||||
|
getWindow.setStatusBarColor(getResources().getColor(R.color.grey3));
|
||||||
|
getActionBar.setDisplayHomeAsUpEnabled(true)
|
||||||
|
getActionBar.setHomeAsUpIndicator(R.drawable.ic_drawer)
|
||||||
|
} else {
|
||||||
|
getActionBar.setIcon(R.drawable.ic_stat_shadowsocks)
|
||||||
|
}
|
||||||
title.setOnLongClickListener(new OnLongClickListener {
|
title.setOnLongClickListener(new OnLongClickListener {
|
||||||
override def onLongClick(v: View): Boolean = {
|
override def onLongClick(v: View): Boolean = {
|
||||||
if (Utils.isLollipopOrAbove && bgService != null
|
if (Utils.isLollipopOrAbove && bgService != null
|
||||||
@@ -610,6 +638,25 @@ class Shadowsocks
|
|||||||
builder.create().show()
|
builder.create().show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def reloadProfile() {
|
||||||
|
drawer.closeMenu(true)
|
||||||
|
|
||||||
|
val h = showProgress(getString(R.string.loading))
|
||||||
|
|
||||||
|
handler.postDelayed(new Runnable {
|
||||||
|
def run() {
|
||||||
|
currentProfile = {
|
||||||
|
profileManager.getProfile(settings.getInt(Key.profileId, -1)) getOrElse currentProfile
|
||||||
|
}
|
||||||
|
menuAdapter.updateList(getMenuList, currentProfile.id)
|
||||||
|
|
||||||
|
updatePreferenceScreen()
|
||||||
|
|
||||||
|
h.sendEmptyMessage(0)
|
||||||
|
}
|
||||||
|
}, 600)
|
||||||
|
}
|
||||||
|
|
||||||
def addProfile(profile: Profile) {
|
def addProfile(profile: Profile) {
|
||||||
drawer.closeMenu(true)
|
drawer.closeMenu(true)
|
||||||
|
|
||||||
@@ -688,7 +735,7 @@ class Shadowsocks
|
|||||||
currentProfile = profileManager.load(profileId)
|
currentProfile = profileManager.load(profileId)
|
||||||
menuAdapter.updateList(getMenuList, currentProfile.id)
|
menuAdapter.updateList(getMenuList, currentProfile.id)
|
||||||
|
|
||||||
sendBroadcast(new Intent(Action.UPDATE_FRAGMENT))
|
updatePreferenceScreen()
|
||||||
|
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
@@ -701,7 +748,7 @@ class Shadowsocks
|
|||||||
|
|
||||||
def getProfileList: List[Item] = {
|
def getProfileList: List[Item] = {
|
||||||
val list = profileManager.getAllProfiles getOrElse List[Profile]()
|
val list = profileManager.getAllProfiles getOrElse List[Profile]()
|
||||||
list.map(p => new Item(p.id, p.name, -1, updateProfile, delProfile))
|
list.map(p => new IconItem(p.id, p.name, -1, updateProfile, delProfile))
|
||||||
}
|
}
|
||||||
|
|
||||||
def getMenuList: List[Any] = {
|
def getMenuList: List[Any] = {
|
||||||
@@ -713,11 +760,13 @@ class Shadowsocks
|
|||||||
buf ++= getProfileList
|
buf ++= getProfileList
|
||||||
|
|
||||||
buf +=
|
buf +=
|
||||||
new Item(-400, getString(R.string.add_profile), android.R.drawable.ic_menu_add, newProfile)
|
new DrawableItem(-400, getString(R.string.add_profile), new IconDrawable(this, IconValue.fa_plus_circle)
|
||||||
|
.colorRes(android.R.color.darker_gray).sizeDp(26), newProfile)
|
||||||
|
|
||||||
buf += new Category(getString(R.string.settings))
|
buf += new Category(getString(R.string.settings))
|
||||||
|
|
||||||
buf += new Item(-100, getString(R.string.recovery), android.R.drawable.ic_menu_revert, _ => {
|
buf += new DrawableItem(-100, getString(R.string.recovery), new IconDrawable(this, IconValue.fa_recycle)
|
||||||
|
.colorRes(android.R.color.darker_gray).sizeDp(26), _ => {
|
||||||
// send event
|
// send event
|
||||||
application.tracker.send(new HitBuilders.EventBuilder()
|
application.tracker.send(new HitBuilders.EventBuilder()
|
||||||
.setCategory(Shadowsocks.TAG)
|
.setCategory(Shadowsocks.TAG)
|
||||||
@@ -728,7 +777,8 @@ class Shadowsocks
|
|||||||
})
|
})
|
||||||
|
|
||||||
buf +=
|
buf +=
|
||||||
new Item(-200, getString(R.string.flush_dnscache), android.R.drawable.ic_menu_delete, _ => {
|
new DrawableItem(-200, getString(R.string.flush_dnscache), new IconDrawable(this, IconValue.fa_refresh)
|
||||||
|
.colorRes(android.R.color.darker_gray).sizeDp(26), _ => {
|
||||||
// send event
|
// send event
|
||||||
application.tracker.send(new HitBuilders.EventBuilder()
|
application.tracker.send(new HitBuilders.EventBuilder()
|
||||||
.setCategory(Shadowsocks.TAG)
|
.setCategory(Shadowsocks.TAG)
|
||||||
@@ -738,7 +788,20 @@ class Shadowsocks
|
|||||||
flushDnsCache()
|
flushDnsCache()
|
||||||
})
|
})
|
||||||
|
|
||||||
buf += new Item(-300, getString(R.string.about), android.R.drawable.ic_menu_info_details, _ => {
|
buf +=
|
||||||
|
new DrawableItem(-300, getString(R.string.qrcode), new IconDrawable(this, IconValue.fa_qrcode)
|
||||||
|
.colorRes(android.R.color.darker_gray).sizeDp(26), _ => {
|
||||||
|
// send event
|
||||||
|
application.tracker.send(new HitBuilders.EventBuilder()
|
||||||
|
.setCategory(Shadowsocks.TAG)
|
||||||
|
.setAction("qrcode")
|
||||||
|
.setLabel(getVersionName)
|
||||||
|
.build())
|
||||||
|
showQrCode()
|
||||||
|
})
|
||||||
|
|
||||||
|
buf += new DrawableItem(-400, getString(R.string.about), new IconDrawable(this, IconValue.fa_info_circle)
|
||||||
|
.colorRes(android.R.color.darker_gray).sizeDp(26), _ => {
|
||||||
// send event
|
// send event
|
||||||
application.tracker.send(new HitBuilders.EventBuilder()
|
application.tracker.send(new HitBuilders.EventBuilder()
|
||||||
.setCategory(Shadowsocks.TAG)
|
.setCategory(Shadowsocks.TAG)
|
||||||
@@ -782,6 +845,10 @@ class Shadowsocks
|
|||||||
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
|
switchButton.setOnCheckedChangeListener(Shadowsocks.this)
|
||||||
}
|
}
|
||||||
ConfigUtils.refresh(this)
|
ConfigUtils.refresh(this)
|
||||||
|
|
||||||
|
// Check if profile list changed
|
||||||
|
if (currentProfile.id != settings.getInt(Key.profileId, -1))
|
||||||
|
reloadProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
private def setPreferenceEnabled(enabled: Boolean) {
|
private def setPreferenceEnabled(enabled: Boolean) {
|
||||||
@@ -828,7 +895,6 @@ class Shadowsocks
|
|||||||
override def onDestroy() {
|
override def onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
deattachService()
|
deattachService()
|
||||||
Crouton.cancelAllCroutons()
|
|
||||||
unregisterReceiver(preferenceReceiver)
|
unregisterReceiver(preferenceReceiver)
|
||||||
new BackupManager(this).dataChanged()
|
new BackupManager(this).dataChanged()
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
@@ -847,12 +913,11 @@ class Shadowsocks
|
|||||||
}
|
}
|
||||||
ab.append("mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system")
|
ab.append("mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system")
|
||||||
Console.runRootCommand(ab.toArray)
|
Console.runRootCommand(ab.toArray)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def reset() {
|
def reset() {
|
||||||
|
|
||||||
crash_recovery()
|
crashRecovery()
|
||||||
|
|
||||||
copyAssets(System.getABI)
|
copyAssets(System.getABI)
|
||||||
|
|
||||||
@@ -873,6 +938,31 @@ class Shadowsocks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def dp2px(dp: Int): Int = {
|
||||||
|
val displayMetrics = getBaseContext.getResources.getDisplayMetrics()
|
||||||
|
Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT))
|
||||||
|
}
|
||||||
|
|
||||||
|
private def showQrCode() {
|
||||||
|
val image = new ImageView(this)
|
||||||
|
image.setPadding(0, dp2px(20), 0, dp2px(20))
|
||||||
|
image.setLayoutParams(new LinearLayout.LayoutParams(-1, -1))
|
||||||
|
val qrcode = QRCode.from(Parser.generate(currentProfile))
|
||||||
|
.withSize(dp2px(250), dp2px(250)).asInstanceOf[QRCode]
|
||||||
|
image.setImageBitmap(qrcode.bitmap())
|
||||||
|
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setCancelable(true)
|
||||||
|
.setNegativeButton(getString(R.string.close), new DialogInterface.OnClickListener() {
|
||||||
|
override def onClick(dialog: DialogInterface, id: Int) {
|
||||||
|
dialog.cancel()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setView(image)
|
||||||
|
.create()
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
private def flushDnsCache() {
|
private def flushDnsCache() {
|
||||||
val h = showProgress(getString(R.string.flushing))
|
val h = showProgress(getString(R.string.flushing))
|
||||||
spawn {
|
spawn {
|
||||||
@@ -892,9 +982,7 @@ class Shadowsocks
|
|||||||
resultCode match {
|
resultCode match {
|
||||||
case Activity.RESULT_OK =>
|
case Activity.RESULT_OK =>
|
||||||
prepared = true
|
prepared = true
|
||||||
if (!serviceStart) {
|
serviceStart()
|
||||||
cancelStart()
|
|
||||||
}
|
|
||||||
case _ =>
|
case _ =>
|
||||||
cancelStart()
|
cancelStart()
|
||||||
Log.e(Shadowsocks.TAG, "Failed to start VpnService")
|
Log.e(Shadowsocks.TAG, "Failed to start VpnService")
|
||||||
@@ -928,33 +1016,34 @@ class Shadowsocks
|
|||||||
try {
|
try {
|
||||||
val port: Int = Integer.valueOf(text)
|
val port: Int = Integer.valueOf(text)
|
||||||
if (!low && port <= 1024) {
|
if (!low && port <= 1024) {
|
||||||
Crouton.makeText(this, R.string.port_alert, Style.ALERT).show()
|
new SnackBar.Builder(this)
|
||||||
|
.withMessageId(R.string.port_alert)
|
||||||
|
.withActionMessageId(R.string.error)
|
||||||
|
.withStyle(SnackBar.Style.ALERT)
|
||||||
|
.withDuration(SnackBar.LONG_SNACK)
|
||||||
|
.show()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
case ex: Exception =>
|
case ex: Exception =>
|
||||||
Crouton.makeText(this, R.string.port_alert, Style.ALERT).show()
|
new SnackBar.Builder(this)
|
||||||
|
.withMessageId(R.string.port_alert)
|
||||||
|
.withActionMessageId(R.string.error)
|
||||||
|
.withStyle(SnackBar.Style.ALERT)
|
||||||
|
.withDuration(SnackBar.LONG_SNACK)
|
||||||
|
.show()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called when connect button is clicked. */
|
/** Called when connect button is clicked. */
|
||||||
def serviceStart: Boolean = {
|
def serviceStart() {
|
||||||
|
|
||||||
if (!checkText(Key.proxy)) return false
|
|
||||||
if (!checkText(Key.sitekey)) return false
|
|
||||||
if (!checkNumber(Key.localPort, low = false)) return false
|
|
||||||
if (!checkNumber(Key.remotePort, low = true)) return false
|
|
||||||
|
|
||||||
if (bgService == null) return false
|
|
||||||
|
|
||||||
bgService.start(ConfigUtils.load(settings))
|
bgService.start(ConfigUtils.load(settings))
|
||||||
|
|
||||||
if (isVpnEnabled) {
|
if (isVpnEnabled) {
|
||||||
changeSwitch(checked = false)
|
changeSwitch(checked = false)
|
||||||
}
|
}
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private def showAbout() {
|
private def showAbout() {
|
||||||
@@ -1015,15 +1104,12 @@ class Shadowsocks
|
|||||||
case State.STOPPED =>
|
case State.STOPPED =>
|
||||||
clearDialog()
|
clearDialog()
|
||||||
changeSwitch(checked = false)
|
changeSwitch(checked = false)
|
||||||
Crouton.cancelAllCroutons()
|
|
||||||
if (m != null) {
|
if (m != null) {
|
||||||
val style = new Style.Builder().setBackgroundColorValue(Style.holoRedLight).build()
|
new SnackBar.Builder(Shadowsocks.this)
|
||||||
val config = new Configuration.Builder()
|
.withMessage(getString(R.string.vpn_error).formatLocal(Locale.ENGLISH, m))
|
||||||
.setDuration(Configuration.DURATION_LONG)
|
.withActionMessageId(R.string.error)
|
||||||
.build()
|
.withStyle(SnackBar.Style.ALERT)
|
||||||
Crouton
|
.withDuration(SnackBar.LONG_SNACK)
|
||||||
.makeText(Shadowsocks.this, getString(R.string.vpn_error).formatLocal(Locale.ENGLISH, m), style)
|
|
||||||
.setConfiguration(config)
|
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
setPreferenceEnabled(enabled = true)
|
setPreferenceEnabled(enabled = true)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ import java.io.File
|
|||||||
import java.lang.reflect.{InvocationTargetException, Method}
|
import java.lang.reflect.{InvocationTargetException, Method}
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
import android.app.{Notification, NotificationManager, PendingIntent, Service}
|
import android.app._
|
||||||
import android.content._
|
import android.content._
|
||||||
import android.content.pm.{PackageInfo, PackageManager}
|
import android.content.pm.{PackageInfo, PackageManager}
|
||||||
import android.net.{Network, ConnectivityManager}
|
import android.net.{Network, ConnectivityManager}
|
||||||
@@ -67,7 +67,6 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
val CMD_IPTABLES_RETURN = " -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN"
|
val CMD_IPTABLES_RETURN = " -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN"
|
||||||
val CMD_IPTABLES_DNAT_ADD_SOCKS = " -t nat -A OUTPUT -p tcp " +
|
val CMD_IPTABLES_DNAT_ADD_SOCKS = " -t nat -A OUTPUT -p tcp " +
|
||||||
"-j DNAT --to-destination 127.0.0.1:8123"
|
"-j DNAT --to-destination 127.0.0.1:8123"
|
||||||
val DNS_PORT = 8153
|
|
||||||
|
|
||||||
private val mStartForegroundSignature = Array[Class[_]](classOf[Int], classOf[Notification])
|
private val mStartForegroundSignature = Array[Class[_]](classOf[Int], classOf[Notification])
|
||||||
private val mStopForegroundSignature = Array[Class[_]](classOf[Boolean])
|
private val mStopForegroundSignature = Array[Class[_]](classOf[Boolean])
|
||||||
@@ -76,6 +75,7 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
private val mStartForegroundArgs = new Array[AnyRef](2)
|
private val mStartForegroundArgs = new Array[AnyRef](2)
|
||||||
private val mStopForegroundArgs = new Array[AnyRef](1)
|
private val mStopForegroundArgs = new Array[AnyRef](1)
|
||||||
|
|
||||||
|
var lockReceiver: BroadcastReceiver = null
|
||||||
var closeReceiver: BroadcastReceiver = null
|
var closeReceiver: BroadcastReceiver = null
|
||||||
var connReceiver: BroadcastReceiver = null
|
var connReceiver: BroadcastReceiver = null
|
||||||
var notificationManager: NotificationManager = null
|
var notificationManager: NotificationManager = null
|
||||||
@@ -201,6 +201,7 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
val cmd = new ArrayBuffer[String]
|
val cmd = new ArrayBuffer[String]
|
||||||
cmd += (Path.BASE + "ss-local"
|
cmd += (Path.BASE + "ss-local"
|
||||||
, "-b" , "127.0.0.1"
|
, "-b" , "127.0.0.1"
|
||||||
|
, "-t" , "600"
|
||||||
, "-c" , Path.BASE + "ss-local-nat.conf"
|
, "-c" , Path.BASE + "ss-local-nat.conf"
|
||||||
, "-f" , Path.BASE + "ss-local-nat.pid")
|
, "-f" , Path.BASE + "ss-local-nat.pid")
|
||||||
|
|
||||||
@@ -222,25 +223,19 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
p.println(conf)
|
p.println(conf)
|
||||||
})
|
})
|
||||||
val cmd = new ArrayBuffer[String]
|
val cmd = new ArrayBuffer[String]
|
||||||
cmd += (Path.BASE + "ss-tunnel" , "-u"
|
cmd += (Path.BASE + "ss-tunnel"
|
||||||
, "-b" , "127.0.0.1"
|
, "-u"
|
||||||
, "-L" , "8.8.8.8:53"
|
, "-t" , "10"
|
||||||
, "-c" , Path.BASE + "ss-tunnel-nat.conf"
|
, "-b" , "127.0.0.1"
|
||||||
, "-f" , Path.BASE + "ss-tunnel-nat.pid")
|
, "-L" , "8.8.8.8:53"
|
||||||
|
, "-c" , Path.BASE + "ss-tunnel-nat.conf"
|
||||||
|
, "-f" , Path.BASE + "ss-tunnel-nat.pid")
|
||||||
|
|
||||||
if (Utils.isLollipopOrAbove) {
|
cmd += ("-l" , "8153")
|
||||||
cmd += ("-l" , "53")
|
|
||||||
} else {
|
|
||||||
cmd += ("-l" , "8153")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||||
|
|
||||||
if (Utils.isLollipopOrAbove) {
|
Console.runCommand(cmd.mkString(" "))
|
||||||
Console.runRootCommand(cmd.mkString(" "))
|
|
||||||
} else {
|
|
||||||
Console.runCommand(cmd.mkString(" "))
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
val conf = ConfigUtils
|
val conf = ConfigUtils
|
||||||
@@ -251,6 +246,8 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
})
|
})
|
||||||
val cmdBuf = new ArrayBuffer[String]
|
val cmdBuf = new ArrayBuffer[String]
|
||||||
cmdBuf += (Path.BASE + "ss-tunnel"
|
cmdBuf += (Path.BASE + "ss-tunnel"
|
||||||
|
, "-u"
|
||||||
|
, "-t" , "10"
|
||||||
, "-b" , "127.0.0.1"
|
, "-b" , "127.0.0.1"
|
||||||
, "-l" , "8163"
|
, "-l" , "8163"
|
||||||
, "-L" , "8.8.8.8:53"
|
, "-L" , "8.8.8.8:53"
|
||||||
@@ -263,13 +260,17 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def startDnsDaemon() {
|
def startDnsDaemon() {
|
||||||
val conf = if (Utils.isLollipopOrAbove) {
|
|
||||||
ConfigUtils
|
val conf = if (config.route == Route.BYPASS_CHN) {
|
||||||
.PDNSD_BYPASS.formatLocal(Locale.ENGLISH, "127.0.0.1", 53, Path.BASE + "pdnsd-nat.pid", getString(R.string.exclude), 8163)
|
val reject = ConfigUtils.getRejectList(getContext, application)
|
||||||
|
val blackList = ConfigUtils.getBlackList(getContext, application)
|
||||||
|
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
|
||||||
|
Path.BASE + "pdnsd-nat.pid", reject, blackList, 8163)
|
||||||
} else {
|
} else {
|
||||||
ConfigUtils
|
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153,
|
||||||
.PDNSD_BYPASS.formatLocal(Locale.ENGLISH, "127.0.0.1", 8153, Path.BASE + "pdnsd-nat.pid", getString(R.string.exclude), 8163)
|
Path.BASE + "pdnsd-nat.pid", 8163)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-nat.conf"))(p => {
|
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-nat.conf"))(p => {
|
||||||
p.println(conf)
|
p.println(conf)
|
||||||
})
|
})
|
||||||
@@ -277,11 +278,7 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
|
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd)
|
||||||
|
|
||||||
if (Utils.isLollipopOrAbove) {
|
Console.runCommand(cmd)
|
||||||
Console.runRootCommand(cmd)
|
|
||||||
} else {
|
|
||||||
Console.runCommand(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +329,7 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def notifyForegroundAlert(title: String, info: String) {
|
def notifyForegroundAlert(title: String, info: String, visible: Boolean) {
|
||||||
val openIntent = new Intent(this, classOf[Shadowsocks])
|
val openIntent = new Intent(this, classOf[Shadowsocks])
|
||||||
openIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
|
openIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
|
||||||
val contentIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
|
val contentIntent = PendingIntent.getActivity(this, 0, openIntent, 0)
|
||||||
@@ -350,6 +347,11 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.stop),
|
.addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.stop),
|
||||||
actionIntent)
|
actionIntent)
|
||||||
|
|
||||||
|
if (visible)
|
||||||
|
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
||||||
|
else
|
||||||
|
builder.setPriority(NotificationCompat.PRIORITY_MIN)
|
||||||
|
|
||||||
startForegroundCompat(1, builder.build)
|
startForegroundCompat(1, builder.build)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,20 +420,19 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
val init_sb = new ArrayBuffer[String]
|
val init_sb = new ArrayBuffer[String]
|
||||||
val http_sb = new ArrayBuffer[String]
|
val http_sb = new ArrayBuffer[String]
|
||||||
|
|
||||||
|
init_sb.append("ulimit -n 4096")
|
||||||
init_sb.append(Utils.getIptables + " -t nat -F OUTPUT")
|
init_sb.append(Utils.getIptables + " -t nat -F OUTPUT")
|
||||||
|
|
||||||
val cmd_bypass = Utils.getIptables + CMD_IPTABLES_RETURN
|
val cmd_bypass = Utils.getIptables + CMD_IPTABLES_RETURN
|
||||||
if (!InetAddressUtils.isIPv6Address(config.proxy.toUpperCase)) {
|
if (!InetAddressUtils.isIPv6Address(config.proxy.toUpperCase)) {
|
||||||
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-d " + config.proxy))
|
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d " + config.proxy))
|
||||||
}
|
}
|
||||||
init_sb.append(cmd_bypass.replace("0.0.0.0", "127.0.0.1"))
|
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-d 127.0.0.1"))
|
||||||
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + myUid))
|
init_sb.append(cmd_bypass.replace("-p tcp -d 0.0.0.0", "-m owner --uid-owner " + myUid))
|
||||||
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport 53"))
|
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport 53"))
|
||||||
|
|
||||||
if (!Utils.isLollipopOrAbove) {
|
init_sb.append(Utils.getIptables
|
||||||
init_sb.append(Utils.getIptables
|
+ " -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:" + 8153)
|
||||||
+ " -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:" + DNS_PORT)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.isGlobalProxy || config.isBypassApps) {
|
if (config.isGlobalProxy || config.isBypassApps) {
|
||||||
http_sb.append(Utils.getIptables + CMD_IPTABLES_DNAT_ADD_SOCKS)
|
http_sb.append(Utils.getIptables + CMD_IPTABLES_DNAT_ADD_SOCKS)
|
||||||
@@ -500,21 +501,46 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
|
|
||||||
config = c
|
config = c
|
||||||
|
|
||||||
// register connection receiver
|
|
||||||
if (Utils.isLollipopOrAbove) initConnectionReceiver()
|
|
||||||
|
|
||||||
// register close receiver
|
// register close receiver
|
||||||
val filter = new IntentFilter()
|
val filter = new IntentFilter()
|
||||||
filter.addAction(Intent.ACTION_SHUTDOWN)
|
filter.addAction(Intent.ACTION_SHUTDOWN)
|
||||||
filter.addAction(Action.CLOSE)
|
filter.addAction(Action.CLOSE)
|
||||||
closeReceiver = new BroadcastReceiver() {
|
closeReceiver = new BroadcastReceiver() {
|
||||||
def onReceive(p1: Context, p2: Intent) {
|
def onReceive(context: Context, intent: Intent) {
|
||||||
Toast.makeText(p1, R.string.stopping, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.stopping, Toast.LENGTH_SHORT).show()
|
||||||
stopRunner()
|
stopRunner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
registerReceiver(closeReceiver, filter)
|
registerReceiver(closeReceiver, filter)
|
||||||
|
|
||||||
|
if (Utils.isLollipopOrAbove) {
|
||||||
|
val screenFilter = new IntentFilter()
|
||||||
|
screenFilter.addAction(Intent.ACTION_SCREEN_ON)
|
||||||
|
screenFilter.addAction(Intent.ACTION_SCREEN_OFF)
|
||||||
|
screenFilter.addAction(Intent.ACTION_USER_PRESENT)
|
||||||
|
lockReceiver = new BroadcastReceiver() {
|
||||||
|
def onReceive(context: Context, intent: Intent) {
|
||||||
|
if (getState == State.CONNECTED) {
|
||||||
|
val action = intent.getAction
|
||||||
|
if (action == Intent.ACTION_SCREEN_OFF) {
|
||||||
|
notifyForegroundAlert(getString(R.string.forward_success),
|
||||||
|
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), false)
|
||||||
|
} else if (action == Intent.ACTION_SCREEN_ON) {
|
||||||
|
val keyGuard = getSystemService(Context.KEYGUARD_SERVICE).asInstanceOf[KeyguardManager]
|
||||||
|
if (!keyGuard.inKeyguardRestrictedInputMode) {
|
||||||
|
notifyForegroundAlert(getString(R.string.forward_success),
|
||||||
|
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
|
||||||
|
}
|
||||||
|
} else if (action == Intent.ACTION_USER_PRESENT) {
|
||||||
|
notifyForegroundAlert(getString(R.string.forward_success),
|
||||||
|
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
registerReceiver(lockReceiver, screenFilter)
|
||||||
|
}
|
||||||
|
|
||||||
// send event
|
// send event
|
||||||
application.tracker.send(new HitBuilders.EventBuilder()
|
application.tracker.send(new HitBuilders.EventBuilder()
|
||||||
.setCategory(TAG)
|
.setCategory(TAG)
|
||||||
@@ -559,11 +585,10 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
if (resolved && handleConnection) {
|
if (resolved && handleConnection) {
|
||||||
|
|
||||||
// Set DNS
|
// Set DNS
|
||||||
if (Utils.isLollipopOrAbove) setupDns()
|
|
||||||
flushDns()
|
flushDns()
|
||||||
|
|
||||||
notifyForegroundAlert(getString(R.string.forward_success),
|
notifyForegroundAlert(getString(R.string.forward_success),
|
||||||
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName))
|
getString(R.string.service_running).formatLocal(Locale.ENGLISH, config.profileName), true)
|
||||||
changeState(State.CONNECTED)
|
changeState(State.CONNECTED)
|
||||||
} else {
|
} else {
|
||||||
changeState(State.STOPPED, getString(R.string.service_failed))
|
changeState(State.STOPPED, getString(R.string.service_failed))
|
||||||
@@ -583,8 +608,12 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
unregisterReceiver(closeReceiver)
|
unregisterReceiver(closeReceiver)
|
||||||
closeReceiver = null
|
closeReceiver = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.isLollipopOrAbove) {
|
if (Utils.isLollipopOrAbove) {
|
||||||
destroyConnectionReceiver()
|
if (lockReceiver != null) {
|
||||||
|
unregisterReceiver(lockReceiver)
|
||||||
|
lockReceiver = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// send event
|
// send event
|
||||||
@@ -598,7 +627,7 @@ class ShadowsocksNatService extends Service with BaseService {
|
|||||||
killProcesses()
|
killProcesses()
|
||||||
|
|
||||||
// stop the service if no callback registered
|
// stop the service if no callback registered
|
||||||
if (callbackCount == 0) {
|
if (getCallbackCount == 0) {
|
||||||
stopSelf()
|
stopSelf()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ class ShadowsocksRunnerActivity extends Activity {
|
|||||||
override def onServiceConnected(name: ComponentName, service: IBinder) {
|
override def onServiceConnected(name: ComponentName, service: IBinder) {
|
||||||
bgService = IShadowsocksService.Stub.asInterface(service)
|
bgService = IShadowsocksService.Stub.asInterface(service)
|
||||||
handler.postDelayed(new Runnable() {
|
handler.postDelayed(new Runnable() {
|
||||||
override def run() = startBackgroundService()
|
override def run() {
|
||||||
|
if (bgService != null) startBackgroundService()
|
||||||
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
override def onServiceDisconnected(name: ComponentName) {
|
override def onServiceDisconnected(name: ComponentName) {
|
||||||
|
|||||||
@@ -116,9 +116,10 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
|
|
||||||
val cmd = new ArrayBuffer[String]
|
val cmd = new ArrayBuffer[String]
|
||||||
cmd +=(Path.BASE + "ss-local", "-u"
|
cmd +=(Path.BASE + "ss-local", "-u"
|
||||||
, "-b", "127.0.0.1"
|
, "-b" , "127.0.0.1"
|
||||||
, "-c", Path.BASE + "ss-local-vpn.conf"
|
, "-t" , "600"
|
||||||
, "-f", Path.BASE + "ss-local-vpn.pid")
|
, "-c" , Path.BASE + "ss-local-vpn.conf"
|
||||||
|
, "-f" , Path.BASE + "ss-local-vpn.pid")
|
||||||
|
|
||||||
if (Utils.isLollipopOrAbove && config.route != Route.ALL) {
|
if (Utils.isLollipopOrAbove && config.route != Route.ALL) {
|
||||||
cmd += "--acl"
|
cmd += "--acl"
|
||||||
@@ -138,11 +139,13 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
})
|
})
|
||||||
val cmd = new ArrayBuffer[String]
|
val cmd = new ArrayBuffer[String]
|
||||||
cmd +=(Path.BASE + "ss-tunnel"
|
cmd +=(Path.BASE + "ss-tunnel"
|
||||||
, "-b", "127.0.0.1"
|
, "-u"
|
||||||
, "-l", "8163"
|
, "-t" , "10"
|
||||||
, "-L", "8.8.8.8:53"
|
, "-b" , "127.0.0.1"
|
||||||
, "-c", Path.BASE + "ss-tunnel-vpn.conf"
|
, "-l" , "8163"
|
||||||
, "-f", Path.BASE + "ss-tunnel-vpn.pid")
|
, "-L" , "8.8.8.8:53"
|
||||||
|
, "-c" , Path.BASE + "ss-tunnel-vpn.conf"
|
||||||
|
, "-f" , Path.BASE + "ss-tunnel-vpn.pid")
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
if (BuildConfig.DEBUG) Log.d(TAG, cmd.mkString(" "))
|
||||||
Console.runCommand(cmd.mkString(" "))
|
Console.runCommand(cmd.mkString(" "))
|
||||||
@@ -150,10 +153,14 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
|
|
||||||
def startDnsDaemon() {
|
def startDnsDaemon() {
|
||||||
val conf = {
|
val conf = {
|
||||||
if (Utils.isLollipopOrAbove) {
|
if (config.route == Route.BYPASS_CHN) {
|
||||||
ConfigUtils.PDNSD_BYPASS.formatLocal(Locale.ENGLISH, "0.0.0.0", 8153, Path.BASE + "pdnsd-vpn.pid", getString(R.string.exclude), 8163)
|
val reject = ConfigUtils.getRejectList(getContext, application)
|
||||||
|
val blackList = ConfigUtils.getBlackList(getContext, application)
|
||||||
|
ConfigUtils.PDNSD_DIRECT.formatLocal(Locale.ENGLISH, "0.0.0.0", 8153,
|
||||||
|
Path.BASE + "pdnsd-vpn.pid", reject, blackList, 8163)
|
||||||
} else {
|
} else {
|
||||||
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "0.0.0.0", 8163)
|
ConfigUtils.PDNSD_LOCAL.formatLocal(Locale.ENGLISH, "0.0.0.0", 8153,
|
||||||
|
Path.BASE + "pdnsd-vpn.pid", 8163)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-vpn.conf"))(p => {
|
ConfigUtils.printToFile(new File(Path.BASE + "pdnsd-vpn.conf"))(p => {
|
||||||
@@ -187,6 +194,9 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
.addDnsServer("8.8.8.8")
|
.addDnsServer("8.8.8.8")
|
||||||
|
|
||||||
if (Utils.isLollipopOrAbove) {
|
if (Utils.isLollipopOrAbove) {
|
||||||
|
|
||||||
|
builder.allowFamily(android.system.OsConstants.AF_INET6)
|
||||||
|
|
||||||
if (!config.isGlobalProxy) {
|
if (!config.isGlobalProxy) {
|
||||||
val apps = AppManager.getProxiedApps(this, config.proxiedAppString)
|
val apps = AppManager.getProxiedApps(this, config.proxiedAppString)
|
||||||
val pkgSet: mutable.HashSet[String] = new mutable.HashSet[String]
|
val pkgSet: mutable.HashSet[String] = new mutable.HashSet[String]
|
||||||
@@ -470,7 +480,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stop the service if no callback registered
|
// stop the service if no callback registered
|
||||||
if (callbackCount == 0) {
|
if (getCallbackCount == 0) {
|
||||||
stopSelf()
|
stopSelf()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,24 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.BaseAdapter
|
import android.widget.BaseAdapter
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
import com.github.shadowsocks.{R}
|
import com.github.shadowsocks.{R}
|
||||||
import android.view.View.{OnLongClickListener, OnClickListener}
|
import android.view.View.{OnLongClickListener, OnClickListener}
|
||||||
|
|
||||||
case class Item(id: Int, title: String, iconRes: Int,
|
abstract class Item {
|
||||||
|
def id: Int
|
||||||
|
def title: String
|
||||||
|
def click: Int => Unit
|
||||||
|
def longClick: Int => Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
case class IconItem(id: Int, title: String, iconRes: Int,
|
||||||
click: Int => Unit, longClick: Int => Boolean = _ => false)
|
click: Int => Unit, longClick: Int => Boolean = _ => false)
|
||||||
|
extends Item
|
||||||
|
|
||||||
|
case class DrawableItem(id: Int, title: String, iconRes: Drawable,
|
||||||
|
click: Int => Unit, longClick: Int => Boolean = _ => false)
|
||||||
|
extends Item
|
||||||
|
|
||||||
case class Category(title: String)
|
case class Category(title: String)
|
||||||
|
|
||||||
@@ -89,7 +102,8 @@ class MenuAdapter(context: Context, var items: List[Any]) extends BaseAdapter {
|
|||||||
@Override override def getItemViewType(position: Int): Int = {
|
@Override override def getItemViewType(position: Int): Int = {
|
||||||
getItem(position) match {
|
getItem(position) match {
|
||||||
case Category => MenuAdapter.CATEGORY
|
case Category => MenuAdapter.CATEGORY
|
||||||
case Item => MenuAdapter.ITEM
|
case IconItem => MenuAdapter.ITEM
|
||||||
|
case DrawableItem => MenuAdapter.ITEM
|
||||||
case _ => MenuAdapter.UNDEFINED
|
case _ => MenuAdapter.UNDEFINED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,9 +135,18 @@ class MenuAdapter(context: Context, var items: List[Any]) extends BaseAdapter {
|
|||||||
}
|
}
|
||||||
val tv: TextView = v.asInstanceOf[TextView]
|
val tv: TextView = v.asInstanceOf[TextView]
|
||||||
tv.setText(value.title)
|
tv.setText(value.title)
|
||||||
if (value.iconRes != -1) {
|
|
||||||
tv.setCompoundDrawablesWithIntrinsicBounds(value.iconRes, 0, 0, 0)
|
value match {
|
||||||
|
case iconItem: IconItem =>
|
||||||
|
if (iconItem.iconRes != -1) {
|
||||||
|
tv.setCompoundDrawablesWithIntrinsicBounds(iconItem.iconRes, 0, 0, 0)
|
||||||
|
}
|
||||||
|
case drawableItem: DrawableItem =>
|
||||||
|
if (drawableItem.iconRes != null) {
|
||||||
|
tv.setCompoundDrawablesWithIntrinsicBounds(drawableItem.iconRes, null, null, null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tv.setOnClickListener(new OnClickListener {
|
tv.setOnClickListener(new OnClickListener {
|
||||||
def onClick(view: View) {
|
def onClick(view: View) {
|
||||||
val item = view.getTag(R.id.mdItem).asInstanceOf[Item]
|
val item = view.getTag(R.id.mdItem).asInstanceOf[Item]
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
package com.github.shadowsocks.utils
|
package com.github.shadowsocks.utils
|
||||||
|
|
||||||
import android.content.{SharedPreferences, Context}
|
import android.content.{SharedPreferences, Context}
|
||||||
import com.github.shadowsocks.ShadowsocksApplication
|
import com.github.shadowsocks.{R, ShadowsocksApplication}
|
||||||
import com.google.android.gms.tagmanager.Container
|
import com.google.android.gms.tagmanager.Container
|
||||||
import com.github.kevinsawicki.http.HttpRequest
|
import com.github.kevinsawicki.http.HttpRequest
|
||||||
import com.github.shadowsocks.aidl.Config
|
import com.github.shadowsocks.aidl.Config
|
||||||
@@ -61,36 +61,6 @@ object ConfigUtils {
|
|||||||
" port = %d;" +
|
" port = %d;" +
|
||||||
" type = socks5;" +
|
" type = socks5;" +
|
||||||
"}"
|
"}"
|
||||||
val PDNSD =
|
|
||||||
"""
|
|
||||||
|global {
|
|
||||||
| perm_cache = 2048;
|
|
||||||
| cache_dir = "/data/data/com.github.shadowsocks";
|
|
||||||
| server_ip = %s;
|
|
||||||
| server_port = 8153;
|
|
||||||
| query_method = tcp_only;
|
|
||||||
| run_ipv4 = on;
|
|
||||||
| min_ttl = 15m;
|
|
||||||
| max_ttl = 1w;
|
|
||||||
| timeout = 10;
|
|
||||||
| daemon = on;
|
|
||||||
| pid_file = "/data/data/com.github.shadowsocks/pdnsd.pid";
|
|
||||||
|}
|
|
||||||
|
|
|
||||||
|server {
|
|
||||||
| label = "google-servers";
|
|
||||||
| ip = 8.8.8.8, 8.8.4.4;
|
|
||||||
| timeout = 5;
|
|
||||||
|}
|
|
||||||
|
|
|
||||||
|rr {
|
|
||||||
| name=localhost;
|
|
||||||
| reverse=on;
|
|
||||||
| a=127.0.0.1;
|
|
||||||
| owner=localhost;
|
|
||||||
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|
|
||||||
|}
|
|
||||||
""".stripMargin
|
|
||||||
|
|
||||||
val PDNSD_LOCAL =
|
val PDNSD_LOCAL =
|
||||||
"""
|
"""
|
||||||
@@ -98,20 +68,23 @@ object ConfigUtils {
|
|||||||
| perm_cache = 2048;
|
| perm_cache = 2048;
|
||||||
| cache_dir = "/data/data/com.github.shadowsocks";
|
| cache_dir = "/data/data/com.github.shadowsocks";
|
||||||
| server_ip = %s;
|
| server_ip = %s;
|
||||||
| server_port = 8153;
|
| server_port = %d;
|
||||||
| query_method = tcp_only;
|
| query_method = tcp_only;
|
||||||
| run_ipv4 = on;
|
| run_ipv4 = on;
|
||||||
| min_ttl = 15m;
|
| min_ttl = 15m;
|
||||||
| max_ttl = 1w;
|
| max_ttl = 1w;
|
||||||
| timeout = 10;
|
| timeout = 10;
|
||||||
| daemon = on;
|
| daemon = on;
|
||||||
| pid_file = "/data/data/com.github.shadowsocks/pdnsd.pid";
|
| pid_file = %s;
|
||||||
|}
|
|}
|
||||||
|
|
|
|
||||||
|server {
|
|server {
|
||||||
| label = "local";
|
| label = "local";
|
||||||
| ip = 127.0.0.1;
|
| ip = 127.0.0.1;
|
||||||
| port = %d;
|
| port = %d;
|
||||||
|
| reject = ::/0;
|
||||||
|
| reject_policy = negate;
|
||||||
|
| reject_recursively = on;
|
||||||
| timeout = 5;
|
| timeout = 5;
|
||||||
|}
|
|}
|
||||||
|
|
|
|
||||||
@@ -153,6 +126,8 @@ object ConfigUtils {
|
|||||||
|server {
|
|server {
|
||||||
| label = "local-server";
|
| label = "local-server";
|
||||||
| ip = 127.0.0.1;
|
| ip = 127.0.0.1;
|
||||||
|
| uptest = none;
|
||||||
|
| preset = on;
|
||||||
| port = %d;
|
| port = %d;
|
||||||
| timeout = 5;
|
| timeout = 5;
|
||||||
|}
|
|}
|
||||||
@@ -166,6 +141,51 @@ object ConfigUtils {
|
|||||||
|}
|
|}
|
||||||
""".stripMargin
|
""".stripMargin
|
||||||
|
|
||||||
|
val PDNSD_DIRECT =
|
||||||
|
"""
|
||||||
|
|global {
|
||||||
|
| perm_cache = 2048;
|
||||||
|
| cache_dir = "/data/data/com.github.shadowsocks";
|
||||||
|
| server_ip = %s;
|
||||||
|
| server_port = %d;
|
||||||
|
| query_method = tcp_only;
|
||||||
|
| run_ipv4 = on;
|
||||||
|
| min_ttl = 15m;
|
||||||
|
| max_ttl = 1w;
|
||||||
|
| timeout = 10;
|
||||||
|
| daemon = on;
|
||||||
|
| pid_file = "%s";
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
|server {
|
||||||
|
| label = "china-servers";
|
||||||
|
| ip = 223.5.5.5, 114.114.114.114;
|
||||||
|
| timeout = 2;
|
||||||
|
| reject = %s;
|
||||||
|
| reject_policy = fail;
|
||||||
|
| reject_recursively = on;
|
||||||
|
| exclude = %s;
|
||||||
|
| policy = included;
|
||||||
|
| uptest = none;
|
||||||
|
| preset = on;
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
|server {
|
||||||
|
| label = "local-server";
|
||||||
|
| ip = 127.0.0.1;
|
||||||
|
| port = %d;
|
||||||
|
| timeout = 3;
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
|rr {
|
||||||
|
| name=localhost;
|
||||||
|
| reverse=on;
|
||||||
|
| a=127.0.0.1;
|
||||||
|
| owner=localhost;
|
||||||
|
| soa=localhost,root.localhost,42,86400,900,86400,86400;
|
||||||
|
|}
|
||||||
|
""".stripMargin
|
||||||
|
|
||||||
def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) {
|
def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) {
|
||||||
val p = new java.io.PrintWriter(f)
|
val p = new java.io.PrintWriter(f)
|
||||||
try {
|
try {
|
||||||
@@ -180,6 +200,28 @@ object ConfigUtils {
|
|||||||
if (holder != null) holder.refresh()
|
if (holder != null) holder.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def getRejectList(context: Context, app: ShadowsocksApplication): String = {
|
||||||
|
val default = context.getString(R.string.reject)
|
||||||
|
try {
|
||||||
|
val container = app.containerHolder.getContainer
|
||||||
|
val update = container.getString("reject")
|
||||||
|
if (update == null || update.isEmpty) default else update
|
||||||
|
} catch {
|
||||||
|
case ex: Exception => default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getBlackList(context: Context, app: ShadowsocksApplication): String = {
|
||||||
|
val default = context.getString(R.string.black_list)
|
||||||
|
try {
|
||||||
|
val container = app.containerHolder.getContainer
|
||||||
|
val update = container.getString("black_list")
|
||||||
|
if (update == null || update.isEmpty) default else update
|
||||||
|
} catch {
|
||||||
|
case ex: Exception => default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def getPublicConfig(context: Context, container: Container, config: Config): Config = {
|
def getPublicConfig(context: Context, container: Container, config: Config): Config = {
|
||||||
val url = container.getString("proxy_url")
|
val url = container.getString("proxy_url")
|
||||||
val sig = Utils.getSignature(context)
|
val sig = Utils.getSignature(context)
|
||||||
|
|||||||
@@ -40,11 +40,19 @@
|
|||||||
package com.github.shadowsocks.utils
|
package com.github.shadowsocks.utils
|
||||||
|
|
||||||
import com.github.shadowsocks.database.Profile
|
import com.github.shadowsocks.database.Profile
|
||||||
|
import java.util.Locale
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.util.{Log, Base64}
|
import android.util.{Log, Base64}
|
||||||
|
|
||||||
object Parser {
|
object Parser {
|
||||||
val TAG = "ShadowParser"
|
val TAG = "ShadowParser"
|
||||||
|
|
||||||
|
def generate (profile: Profile): String = {
|
||||||
|
val path = "%s:%s@%s:%d".formatLocal(Locale.ENGLISH,
|
||||||
|
profile.method, profile.password, profile.host, profile.remotePort)
|
||||||
|
return "ss://" + Base64.encodeToString(path.getBytes, Base64.NO_PADDING)
|
||||||
|
}
|
||||||
|
|
||||||
def parse (data: String): Option[Profile] = {
|
def parse (data: String): Option[Profile] = {
|
||||||
try {
|
try {
|
||||||
Log.d(TAG, data)
|
Log.d(TAG, data)
|
||||||
@@ -52,17 +60,21 @@ object Parser {
|
|||||||
if (uri.getScheme == Scheme.SS) {
|
if (uri.getScheme == Scheme.SS) {
|
||||||
val encoded = data.replace(Scheme.SS + "://", "")
|
val encoded = data.replace(Scheme.SS + "://", "")
|
||||||
val content = new String(Base64.decode(encoded, Base64.NO_PADDING), "UTF-8")
|
val content = new String(Base64.decode(encoded, Base64.NO_PADDING), "UTF-8")
|
||||||
val info = content.split('@')
|
val methodIdx = content.indexOf(':')
|
||||||
val encinfo = info(0).split(':')
|
val passwordIdx = content.lastIndexOf('@')
|
||||||
val serverinfo = info(1).split(':')
|
val hostIdx = content.lastIndexOf(':')
|
||||||
|
val method = content.substring(0, methodIdx)
|
||||||
|
val password = content.substring(methodIdx + 1, passwordIdx)
|
||||||
|
val host = content.substring(passwordIdx + 1, hostIdx)
|
||||||
|
val port = content.substring(hostIdx + 1)
|
||||||
|
|
||||||
val profile = new Profile
|
val profile = new Profile
|
||||||
profile.name = serverinfo(0)
|
profile.name = host
|
||||||
profile.host = serverinfo(0)
|
profile.host = host
|
||||||
profile.remotePort = serverinfo(1).toInt
|
profile.remotePort = port.toInt
|
||||||
profile.localPort = 1080
|
profile.localPort = 1080
|
||||||
profile.method = encinfo(0)
|
profile.method = method.toLowerCase
|
||||||
profile.password = encinfo(1)
|
profile.password = password
|
||||||
return Some(profile)
|
return Some(profile)
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
Reference in New Issue
Block a user