Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
com.ccwangluo.accelerator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sheteng
com.ccwangluo.accelerator
Commits
10234542
Commit
10234542
authored
Dec 07, 2015
by
Max Lv
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #469 from Mygod/master
Persist package names in individual/proxied
parents
d2740700
4312e167
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
144 additions
and
150 deletions
+144
-150
src/main/res/values-zh/strings.xml
src/main/res/values-zh/strings.xml
+6
-3
src/main/res/values/strings.xml
src/main/res/values/strings.xml
+6
-3
src/main/res/xml/pref_all.xml
src/main/res/xml/pref_all.xml
+6
-4
src/main/scala/com/github/shadowsocks/AppManager.scala
src/main/scala/com/github/shadowsocks/AppManager.scala
+22
-23
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
+26
-32
src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala
...scala/com/github/shadowsocks/ShadowsocksApplication.scala
+2
-3
src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
.../scala/com/github/shadowsocks/ShadowsocksNatService.scala
+20
-16
src/main/scala/com/github/shadowsocks/ShadowsocksSettings.scala
...in/scala/com/github/shadowsocks/ShadowsocksSettings.scala
+7
-10
src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
.../scala/com/github/shadowsocks/ShadowsocksVpnService.scala
+3
-5
src/main/scala/com/github/shadowsocks/database/DBHelper.scala
...main/scala/com/github/shadowsocks/database/DBHelper.scala
+21
-5
src/main/scala/com/github/shadowsocks/package.scala
src/main/scala/com/github/shadowsocks/package.scala
+13
-0
src/main/scala/com/github/shadowsocks/preferences/NatSwitchPreference.scala
.../github/shadowsocks/preferences/NatSwitchPreference.scala
+0
-27
src/main/scala/com/github/shadowsocks/utils/Console.scala
src/main/scala/com/github/shadowsocks/utils/Console.scala
+4
-10
src/main/scala/com/github/shadowsocks/utils/Utils.scala
src/main/scala/com/github/shadowsocks/utils/Utils.scala
+8
-9
No files found.
src/main/res/values-zh/strings.xml
View file @
10234542
...
@@ -34,6 +34,8 @@
...
@@ -34,6 +34,8 @@
<string
name=
"auto_connect_summary"
>
随系统启动后台服务
</string>
<string
name=
"auto_connect_summary"
>
随系统启动后台服务
</string>
<string
name=
"forward_success"
>
后台服务已开始运行。
</string>
<string
name=
"forward_success"
>
后台服务已开始运行。
</string>
<string
name=
"service_failed"
>
无法连接远程服务器
</string>
<string
name=
"service_failed"
>
无法连接远程服务器
</string>
<string
name=
"nat_no_root"
>
NAT 模式需要 ROOT 权限
</string>
<string
name=
"switch_to_vpn"
>
切换到 VPN 模式
</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>
...
@@ -52,14 +54,15 @@
...
@@ -52,14 +54,15 @@
<string
name=
"about"
>
关于
</string>
<string
name=
"about"
>
关于
</string>
<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=
"flush_dnscache_summary_disabled"
>
需要 ROOT 权限
</string>
<string
name=
"flush_dnscache_summary"
>
只需在 NAT 模式下使用
</string>
<string
name=
"flush_dnscache_summary_root"
>
只需在 NAT 模式下使用,需要 ROOT 权限
</string>
<string
name=
"flush_dnscache_no_root"
>
在没有 ROOT 权限的情况下无法刷新 DNS 缓存
</string>
<string
name=
"flushing"
>
刷新中……
</string>
<string
name=
"flushing"
>
刷新中……
</string>
<string
name=
"qrcode"
>
二维码
</string>
<string
name=
"qrcode"
>
二维码
</string>
<string
name=
"add_profile"
>
添加配置文件
</string>
<string
name=
"add_profile"
>
添加配置文件
</string>
<string
name=
"nat"
>
NAT 模式 (仅限调试)
</string>
<string
name=
"nat"
>
NAT 模式 (仅限调试)
</string>
<string
name=
"nat_summary"
>
从 VPN 模式切换为 NAT 模式
</string>
<string
name=
"nat_summary"
>
从 VPN 模式切换为 NAT 模式,需要 ROOT 权限
</string>
<string
name=
"nat_summary_no_root"
>
NAT 模式已禁用,需要 ROOT 权限
</string>
<string
name=
"udp_dns"
>
UDP 转发
</string>
<string
name=
"udp_dns"
>
UDP 转发
</string>
<string
name=
"udp_dns_summary"
>
由远程服务器转发 UDP 协议的数据包
</string>
<string
name=
"udp_dns_summary"
>
由远程服务器转发 UDP 协议的数据包
</string>
...
...
src/main/res/values/strings.xml
View file @
10234542
...
@@ -10,8 +10,7 @@
...
@@ -10,8 +10,7 @@
<string
name=
"profile"
>
Profile
</string>
<string
name=
"profile"
>
Profile
</string>
<string
name=
"profile_summary"
>
Switch to another profile or add new profiles
</string>
<string
name=
"profile_summary"
>
Switch to another profile or add new profiles
</string>
<string
name=
"nat"
>
NAT mode (deprecated)
</string>
<string
name=
"nat"
>
NAT mode (deprecated)
</string>
<string
name=
"nat_summary"
>
Use NAT mode instead of VPN mode
</string>
<string
name=
"nat_summary"
>
Use NAT mode instead of VPN mode. Requires ROOT permission.
</string>
<string
name=
"nat_summary_no_root"
>
NAT mode is disabled without root
</string>
<string
name=
"stat"
>
Network Traffic
</string>
<string
name=
"stat"
>
Network Traffic
</string>
<string
name=
"stat_summary"
>
Sent: \t\t\t\t\t%3$s\t↑\t%1$s/s\nReceived: \t%4$s\t↓\t%2$s/s
</string>
<string
name=
"stat_summary"
>
Sent: \t\t\t\t\t%3$s\t↑\t%1$s/s\nReceived: \t%4$s\t↓\t%2$s/s
</string>
<string
name=
"stat_profiles"
>
\n%1$s↑\t%2$s↓
</string>
<string
name=
"stat_profiles"
>
\n%1$s↑\t%2$s↓
</string>
...
@@ -61,6 +60,8 @@
...
@@ -61,6 +60,8 @@
<!-- notification category -->
<!-- notification category -->
<string
name=
"forward_success"
>
Shadowsocks started.
</string>
<string
name=
"forward_success"
>
Shadowsocks started.
</string>
<string
name=
"service_failed"
>
Failed to connect the remote server
</string>
<string
name=
"service_failed"
>
Failed to connect the remote server
</string>
<string
name=
"nat_no_root"
>
NAT mode requires ROOT permission
</string>
<string
name=
"switch_to_vpn"
>
Switch to VPN mode
</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"
>
%s
</string>
<string
name=
"vpn_error"
>
%s
</string>
...
@@ -84,7 +85,9 @@
...
@@ -84,7 +85,9 @@
<string
name=
"about_title"
>
Shadowsocks %s
</string>
<string
name=
"about_title"
>
Shadowsocks %s
</string>
<string
name=
"qrcode"
>
QR Code
</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=
"flush_dnscache_summary_disabled"
>
Requires ROOT permission
</string>
<string
name=
"flush_dnscache_summary"
>
Only useful in NAT mode
</string>
<string
name=
"flush_dnscache_summary_root"
>
Only useful in NAT mode. Requires ROOT permission.
</string>
<string
name=
"flush_dnscache_no_root"
>
Flush DNS cache cannot proceed without ROOT permission
</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_export"
>
Export to Clipboard
</string>
...
...
src/main/res/xml/pref_all.xml
View file @
10234542
...
@@ -83,12 +83,14 @@
...
@@ -83,12 +83,14 @@
android:summary=
"@string/auto_connect_summary"
android:summary=
"@string/auto_connect_summary"
android:title=
"@string/auto_connect"
/>
android:title=
"@string/auto_connect"
/>
<
com.github.shadowsocks.preferences.Nat
SwitchPreference
android:key=
"isNAT"
<SwitchPreference
android:key=
"isNAT"
android:title=
"@string/nat"
android:title=
"@string/nat"
android:summary=
"@string/nat_summary"
/>
android:summary=
"@string/nat_summary"
/>
<Preference
android:key=
"recovery"
android:title=
"@string/recovery"
<Preference
android:key=
"recovery"
android:title=
"@string/recovery"
android:summary=
"@string/recovery_summary"
/>
android:summary=
"@string/recovery_summary"
/>
<Preference
android:key=
"flush_dnscache"
android:title=
"@string/flush_dnscache"
/>
<Preference
android:key=
"flush_dnscache"
android:title=
"@string/flush_dnscache"
android:summary=
"@string/flush_dnscache_summary_root"
/>
<Preference
android:key=
"about"
android:title=
"@string/about"
/>
<Preference
android:key=
"about"
android:title=
"@string/about"
/>
</PreferenceCategory>
</PreferenceCategory>
...
...
src/main/scala/com/github/shadowsocks/AppManager.scala
View file @
10234542
...
@@ -58,18 +58,16 @@ import com.github.shadowsocks.utils.{Key, Utils}
...
@@ -58,18 +58,16 @@ import com.github.shadowsocks.utils.{Key, Utils}
import
scala.collection.JavaConversions._
import
scala.collection.JavaConversions._
import
scala.collection.mutable
import
scala.collection.mutable
import
scala.concurrent.ExecutionContext.Implicits.global
import
scala.concurrent.Future
import
scala.language.implicitConversions
import
scala.language.implicitConversions
object
AppManager
{
object
AppManager
{
case
class
ProxiedApp
(
uid
:
Int
,
name
:
String
,
packageName
:
String
,
icon
:
Drawable
)
case
class
ProxiedApp
(
name
:
String
,
packageName
:
String
,
icon
:
Drawable
)
private
case
class
ListEntry
(
switch
:
Switch
,
text
:
TextView
,
icon
:
ImageView
)
private
case
class
ListEntry
(
switch
:
Switch
,
text
:
TextView
,
icon
:
ImageView
)
var
cachedApps
:
Array
[
ProxiedApp
]
=
_
var
cachedApps
:
Array
[
ProxiedApp
]
=
_
private
def
getApps
(
pm
:
PackageManager
)
=
{
private
def
getApps
(
pm
:
PackageManager
)
=
{
if
(
cachedApps
==
null
)
cachedApps
=
pm
.
getInstalledApplications
(
0
)
.
filter
(
_
.
uid
>=
10000
)
if
(
cachedApps
==
null
)
cachedApps
=
pm
.
getInstalledApplications
(
0
)
.
map
(
a
=>
new
ProxiedApp
(
a
.
uid
,
pm
.
getApplicationLabel
(
a
).
toString
,
a
.
packageName
,
a
.
loadIcon
(
pm
))).
toArray
.
map
(
a
=>
new
ProxiedApp
(
pm
.
getApplicationLabel
(
a
).
toString
,
a
.
packageName
,
a
.
loadIcon
(
pm
))).
toArray
cachedApps
cachedApps
}
}
}
}
...
@@ -79,7 +77,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
...
@@ -79,7 +77,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
import
AppManager._
import
AppManager._
private
var
apps
:
Array
[
ProxiedApp
]
=
_
private
var
apps
:
Array
[
ProxiedApp
]
=
_
private
var
proxiedApps
:
mutable.HashSet
[
Int
]
=
_
private
var
proxiedApps
:
mutable.HashSet
[
String
]
=
_
private
var
toolbar
:
Toolbar
=
_
private
var
toolbar
:
Toolbar
=
_
private
var
appListView
:
ListView
=
_
private
var
appListView
:
ListView
=
_
private
var
loadingView
:
View
=
_
private
var
loadingView
:
View
=
_
...
@@ -89,10 +87,10 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
...
@@ -89,10 +87,10 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
def
loadApps
()
{
def
loadApps
()
{
appsLoading
=
true
appsLoading
=
true
proxiedApps
=
ShadowsocksApplication
.
settings
.
getString
(
Key
.
proxied
,
""
).
split
(
'
|'
).
map
(
_
.
toInt
).
to
[
mutable.HashSet
]
proxiedApps
=
ShadowsocksApplication
.
settings
.
getString
(
Key
.
proxied
,
""
).
split
(
'
\n'
).
to
[
mutable.HashSet
]
apps
=
getApps
(
getPackageManager
).
sortWith
((
a
,
b
)
=>
{
apps
=
getApps
(
getPackageManager
).
sortWith
((
a
,
b
)
=>
{
val
aProxied
=
proxiedApps
.
contains
(
a
.
uid
)
val
aProxied
=
proxiedApps
.
contains
(
a
.
packageName
)
if
(
aProxied
^
proxiedApps
.
contains
(
b
.
uid
))
aProxied
else
a
.
name
<
b
.
name
if
(
aProxied
^
proxiedApps
.
contains
(
b
.
packageName
))
aProxied
else
a
.
name
.
compareToIgnoreCase
(
b
.
name
)
<
0
})
})
adapter
=
new
ArrayAdapter
[
ProxiedApp
](
this
,
R
.
layout
.
layout_apps_item
,
R
.
id
.
itemtext
,
apps
)
{
adapter
=
new
ArrayAdapter
[
ProxiedApp
](
this
,
R
.
layout
.
layout_apps_item
,
R
.
id
.
itemtext
,
apps
)
{
override
def
getView
(
position
:
Int
,
view
:
View
,
parent
:
ViewGroup
)
:
View
=
{
override
def
getView
(
position
:
Int
,
view
:
View
,
parent
:
ViewGroup
)
:
View
=
{
...
@@ -116,19 +114,19 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
...
@@ -116,19 +114,19 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
entry
.
icon
.
setImageDrawable
(
app
.
icon
)
entry
.
icon
.
setImageDrawable
(
app
.
icon
)
val
switch
=
entry
.
switch
val
switch
=
entry
.
switch
switch
.
setTag
(
app
)
switch
.
setTag
(
app
)
switch
.
setChecked
(
proxiedApps
.
contains
(
app
.
uid
))
switch
.
setChecked
(
proxiedApps
.
contains
(
app
.
packageName
))
entry
.
text
.
setTag
(
switch
)
entry
.
text
.
setTag
(
switch
)
convertView
convertView
}
}
}
}
}
}
private
def
setProxied
(
uid
:
Int
,
proxied
:
Boolean
)
=
if
(
proxied
)
proxiedApps
.
add
(
uid
)
else
proxiedApps
.
remove
(
uid
)
private
def
setProxied
(
pn
:
String
,
proxied
:
Boolean
)
=
if
(
proxied
)
proxiedApps
.
add
(
pn
)
else
proxiedApps
.
remove
(
pn
)
/** Called an application is check/unchecked */
/** Called an application is check/unchecked */
def
onCheckedChanged
(
buttonView
:
CompoundButton
,
isChecked
:
Boolean
)
{
def
onCheckedChanged
(
buttonView
:
CompoundButton
,
isChecked
:
Boolean
)
{
val
app
:
ProxiedApp
=
buttonView
.
getTag
.
asInstanceOf
[
ProxiedApp
]
val
app
:
ProxiedApp
=
buttonView
.
getTag
.
asInstanceOf
[
ProxiedApp
]
if
(
app
!=
null
)
setProxied
(
app
.
uid
,
isChecked
)
if
(
app
!=
null
)
setProxied
(
app
.
packageName
,
isChecked
)
saveAppSettings
(
this
)
saveAppSettings
(
this
)
}
}
...
@@ -136,8 +134,8 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
...
@@ -136,8 +134,8 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
val
switch
=
v
.
getTag
.
asInstanceOf
[
ListEntry
].
switch
val
switch
=
v
.
getTag
.
asInstanceOf
[
ListEntry
].
switch
val
app
:
ProxiedApp
=
switch
.
getTag
.
asInstanceOf
[
ProxiedApp
]
val
app
:
ProxiedApp
=
switch
.
getTag
.
asInstanceOf
[
ProxiedApp
]
if
(
app
!=
null
)
{
if
(
app
!=
null
)
{
val
proxied
=
!
proxiedApps
.
contains
(
app
.
uid
)
val
proxied
=
!
proxiedApps
.
contains
(
app
.
packageName
)
setProxied
(
app
.
uid
,
proxied
)
setProxied
(
app
.
packageName
,
proxied
)
switch
.
setChecked
(
proxied
)
switch
.
setChecked
(
proxied
)
}
}
saveAppSettings
(
this
)
saveAppSettings
(
this
)
...
@@ -158,7 +156,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
...
@@ -158,7 +156,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
case
R
.
id
.
action_export
=>
case
R
.
id
.
action_export
=>
val
bypass
=
prefs
.
getBoolean
(
Key
.
isBypassApps
,
false
)
val
bypass
=
prefs
.
getBoolean
(
Key
.
isBypassApps
,
false
)
val
proxiedAppString
=
prefs
.
getString
(
Key
.
proxied
,
""
)
val
proxiedAppString
=
prefs
.
getString
(
Key
.
proxied
,
""
)
val
clip
=
ClipData
.
newPlainText
(
Key
.
proxied
,
bypass
+
"
"
+
proxiedAppString
)
val
clip
=
ClipData
.
newPlainText
(
Key
.
proxied
,
bypass
+
"
\n
"
+
proxiedAppString
)
clipboard
.
setPrimaryClip
(
clip
)
clipboard
.
setPrimaryClip
(
clip
)
Toast
.
makeText
(
this
,
R
.
string
.
action_export_msg
,
Toast
.
LENGTH_SHORT
).
show
()
Toast
.
makeText
(
this
,
R
.
string
.
action_export_msg
,
Toast
.
LENGTH_SHORT
).
show
()
return
true
return
true
...
@@ -171,11 +169,12 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
...
@@ -171,11 +169,12 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
if
(
proxiedAppSequence
!=
null
)
{
if
(
proxiedAppSequence
!=
null
)
{
val
proxiedAppString
=
proxiedAppSequence
.
toString
val
proxiedAppString
=
proxiedAppSequence
.
toString
if
(!
proxiedAppString
.
isEmpty
)
{
if
(!
proxiedAppString
.
isEmpty
)
{
val
array
=
proxiedAppString
.
split
(
" "
)
val
editor
=
prefs
.
edit
val
bypass
=
array
(
0
).
toBoolean
val
i
=
proxiedAppString
.
indexOf
(
'\n'
)
val
apps
=
if
(
array
.
size
>
1
)
array
(
1
)
else
""
if
(
i
<
0
)
prefs
.
edit
.
putBoolean
(
Key
.
isBypassApps
,
bypass
).
apply
()
editor
.
putBoolean
(
Key
.
isBypassApps
,
proxiedAppString
.
toBoolean
).
putString
(
Key
.
proxied
,
""
).
apply
()
prefs
.
edit
.
putString
(
Key
.
proxied
,
apps
).
apply
()
else
editor
.
putBoolean
(
Key
.
isBypassApps
,
proxiedAppString
.
substring
(
0
,
i
).
toBoolean
)
.
putString
(
Key
.
proxied
,
proxiedAppString
.
substring
(
i
+
1
)).
apply
()
Toast
.
makeText
(
this
,
R
.
string
.
action_import_msg
,
Toast
.
LENGTH_SHORT
).
show
()
Toast
.
makeText
(
this
,
R
.
string
.
action_import_msg
,
Toast
.
LENGTH_SHORT
).
show
()
// Restart activity
// Restart activity
appListView
.
setVisibility
(
View
.
GONE
)
appListView
.
setVisibility
(
View
.
GONE
)
...
@@ -234,7 +233,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
...
@@ -234,7 +233,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
totalItemCount
:
Int
)
{
totalItemCount
:
Int
)
{
if
(
visible
)
{
if
(
visible
)
{
val
name
=
apps
(
firstVisibleItem
).
name
val
name
=
apps
(
firstVisibleItem
).
name
overlay
.
setText
(
if
(
name
!=
null
&&
name
.
length
>
1
)
name
(
0
).
toString
else
"*"
)
overlay
.
setText
(
if
(
name
!=
null
&&
name
.
length
>
1
)
name
(
0
).
to
Upper
.
to
String
else
"*"
)
overlay
.
setVisibility
(
View
.
VISIBLE
)
overlay
.
setVisibility
(
View
.
VISIBLE
)
}
}
}
}
...
@@ -249,7 +248,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
...
@@ -249,7 +248,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
}
}
def
loadAppsAsync
()
{
def
loadAppsAsync
()
{
Future
{
Throwable
Future
{
while
(!
appsLoading
)
loadApps
()
while
(!
appsLoading
)
loadApps
()
appsLoading
=
false
appsLoading
=
false
handler
.
post
(()
=>
{
handler
.
post
(()
=>
{
...
@@ -260,7 +259,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
...
@@ -260,7 +259,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
}
}
def
saveAppSettings
(
context
:
Context
)
{
def
saveAppSettings
(
context
:
Context
)
{
if
(!
appsLoading
)
ShadowsocksApplication
.
settings
.
edit
.
putString
(
Key
.
proxied
,
proxiedApps
.
mkString
(
"
|
"
)).
apply
if
(!
appsLoading
)
ShadowsocksApplication
.
settings
.
edit
.
putString
(
Key
.
proxied
,
proxiedApps
.
mkString
(
"
\n
"
)).
apply
}
}
var
handler
:
Handler
=
null
var
handler
:
Handler
=
null
...
...
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
View file @
10234542
...
@@ -65,8 +65,6 @@ import com.github.shadowsocks.utils._
...
@@ -65,8 +65,6 @@ import com.github.shadowsocks.utils._
import
com.google.android.gms.ads.
{
AdRequest
,
AdSize
,
AdView
}
import
com.google.android.gms.ads.
{
AdRequest
,
AdSize
,
AdView
}
import
scala.collection.mutable.ArrayBuffer
import
scala.collection.mutable.ArrayBuffer
import
scala.concurrent.ExecutionContext.Implicits.global
import
scala.concurrent.Future
object
Typefaces
{
object
Typefaces
{
def
get
(
c
:
Context
,
assetPath
:
String
)
:
Typeface
=
{
def
get
(
c
:
Context
,
assetPath
:
String
)
:
Typeface
=
{
...
@@ -182,8 +180,13 @@ class Shadowsocks
...
@@ -182,8 +180,13 @@ class Shadowsocks
handler
.
postDelayed
(()
=>
fabProgressCircle
.
hide
(),
1000
)
handler
.
postDelayed
(()
=>
fabProgressCircle
.
hide
(),
1000
)
fab
.
setEnabled
(
true
)
fab
.
setEnabled
(
true
)
changeSwitch
(
checked
=
false
)
changeSwitch
(
checked
=
false
)
if
(
m
!=
null
)
Snackbar
.
make
(
findViewById
(
android
.
R
.
id
.
content
),
if
(
m
!=
null
)
{
getString
(
R
.
string
.
vpn_error
).
formatLocal
(
Locale
.
ENGLISH
,
m
),
Snackbar
.
LENGTH_LONG
).
show
val
snackbar
=
Snackbar
.
make
(
findViewById
(
android
.
R
.
id
.
content
),
getString
(
R
.
string
.
vpn_error
).
formatLocal
(
Locale
.
ENGLISH
,
m
),
Snackbar
.
LENGTH_LONG
)
if
(
m
==
getString
(
R
.
string
.
nat_no_root
))
snackbar
.
setAction
(
R
.
string
.
switch_to_vpn
,
(
_
=>
preferences
.
natSwitch
.
setChecked
(
false
))
:
View.OnClickListener
)
snackbar
.
show
}
setPreferenceEnabled
(
enabled
=
true
)
setPreferenceEnabled
(
enabled
=
true
)
case
State
.
STOPPING
=>
case
State
.
STOPPING
=>
fab
.
setBackgroundTintList
(
greyTint
)
fab
.
setBackgroundTintList
(
greyTint
)
...
@@ -215,18 +218,21 @@ class Shadowsocks
...
@@ -215,18 +218,21 @@ class Shadowsocks
ShadowsocksApplication
.
settings
.
edit
.
putBoolean
(
ShadowsocksApplication
.
getVersionName
,
true
).
apply
()
ShadowsocksApplication
.
settings
.
edit
.
putBoolean
(
ShadowsocksApplication
.
getVersionName
,
true
).
apply
()
try
{
try
{
// Workaround that convert port(String) to port(Int)
// Workaround that convert port(String) to port(Int)
val
oldLocalPort
=
ShadowsocksApplication
.
settings
.
getString
(
"port"
,
"-1
"
)
val
oldLocalPort
=
ShadowsocksApplication
.
settings
.
getString
(
Key
.
localPort
,
"
"
)
val
oldRemotePort
=
ShadowsocksApplication
.
settings
.
getString
(
"remotePort"
,
"-1
"
)
val
oldRemotePort
=
ShadowsocksApplication
.
settings
.
getString
(
Key
.
remotePort
,
"
"
)
if
(
oldLocalPort
!=
"
-1
"
)
{
if
(
oldLocalPort
!=
""
)
{
ShadowsocksApplication
.
settings
.
edit
.
putInt
(
Key
.
localPort
,
oldLocalPort
.
toInt
).
commit
()
ShadowsocksApplication
.
settings
.
edit
.
putInt
(
Key
.
localPort
,
oldLocalPort
.
toInt
).
apply
()
}
}
if
(
oldRemotePort
!=
"
-1
"
)
{
if
(
oldRemotePort
!=
""
)
{
ShadowsocksApplication
.
settings
.
edit
.
putInt
(
Key
.
remotePort
,
oldRemotePort
.
toInt
).
commit
()
ShadowsocksApplication
.
settings
.
edit
.
putInt
(
Key
.
remotePort
,
oldRemotePort
.
toInt
).
apply
()
}
}
}
catch
{
}
catch
{
case
ex
:
Exception
=>
// Ignore
case
ex
:
Exception
=>
// Ignore
}
}
val
oldProxiedApps
=
ShadowsocksApplication
.
settings
.
getString
(
Key
.
proxied
,
""
)
if
(
oldProxiedApps
.
contains
(
'|'
))
ShadowsocksApplication
.
settings
.
edit
.
putString
(
Key
.
proxied
,
DBHelper
.
updateProxiedApps
(
this
,
oldProxiedApps
)).
apply
()
recovery
()
recovery
()
}
}
...
@@ -317,10 +323,10 @@ class Shadowsocks
...
@@ -317,10 +323,10 @@ class Shadowsocks
cmd
.
append
(
"chmod 666 %s%s-vpn.pid"
.
formatLocal
(
Locale
.
ENGLISH
,
Path
.
BASE
,
task
))
cmd
.
append
(
"chmod 666 %s%s-vpn.pid"
.
formatLocal
(
Locale
.
ENGLISH
,
Path
.
BASE
,
task
))
}
}
if
(!
ShadowsocksApplication
.
isVpnEnabled
)
{
if
(
ShadowsocksApplication
.
isVpnEnabled
)
{
Console
.
runRootCommand
(
cmd
.
toArray
)
}
else
{
Console
.
runCommand
(
cmd
.
toArray
)
Console
.
runCommand
(
cmd
.
toArray
)
}
else
{
Console
.
runRootCommand
(
cmd
.
toArray
)
}
}
cmd
.
clear
()
cmd
.
clear
()
...
@@ -341,8 +347,7 @@ class Shadowsocks
...
@@ -341,8 +347,7 @@ class Shadowsocks
cmd
.
append
(
"rm -f %s%s-vpn.pid"
.
formatLocal
(
Locale
.
ENGLISH
,
Path
.
BASE
,
task
))
cmd
.
append
(
"rm -f %s%s-vpn.pid"
.
formatLocal
(
Locale
.
ENGLISH
,
Path
.
BASE
,
task
))
cmd
.
append
(
"rm -f %s%s-vpn.conf"
.
formatLocal
(
Locale
.
ENGLISH
,
Path
.
BASE
,
task
))
cmd
.
append
(
"rm -f %s%s-vpn.conf"
.
formatLocal
(
Locale
.
ENGLISH
,
Path
.
BASE
,
task
))
}
}
Console
.
runCommand
(
cmd
.
toArray
)
if
(
ShadowsocksApplication
.
isVpnEnabled
)
Console
.
runCommand
(
cmd
.
toArray
)
else
{
if
(!
ShadowsocksApplication
.
isVpnEnabled
)
{
Console
.
runRootCommand
(
cmd
.
toArray
)
Console
.
runRootCommand
(
cmd
.
toArray
)
Console
.
runRootCommand
(
Utils
.
getIptables
+
" -t nat -F OUTPUT"
)
Console
.
runRootCommand
(
Utils
.
getIptables
+
" -t nat -F OUTPUT"
)
}
}
...
@@ -361,7 +366,7 @@ class Shadowsocks
...
@@ -361,7 +366,7 @@ class Shadowsocks
}
}
def
prepareStartService
()
{
def
prepareStartService
()
{
Future
{
Throwable
Future
{
if
(
ShadowsocksApplication
.
isVpnEnabled
)
{
if
(
ShadowsocksApplication
.
isVpnEnabled
)
{
val
intent
=
VpnService
.
prepare
(
this
)
val
intent
=
VpnService
.
prepare
(
this
)
if
(
intent
!=
null
)
{
if
(
intent
!=
null
)
{
...
@@ -534,18 +539,6 @@ class Shadowsocks
...
@@ -534,18 +539,6 @@ class Shadowsocks
handler
.
removeCallbacksAndMessages
(
null
)
handler
.
removeCallbacksAndMessages
(
null
)
}
}
def
copyToSystem
()
{
val
ab
=
new
ArrayBuffer
[
String
]
ab
.
append
(
"mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system"
)
for
(
executable
<-
Shadowsocks
.
EXECUTABLES
)
{
ab
.
append
(
"cp %s%s /system/bin/"
.
formatLocal
(
Locale
.
ENGLISH
,
Path
.
BASE
,
executable
))
ab
.
append
(
"chmod 755 /system/bin/"
+
executable
)
ab
.
append
(
"chown root:shell /system/bin/"
+
executable
)
}
ab
.
append
(
"mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system"
)
Console
.
runRootCommand
(
ab
.
toArray
)
}
def
install
()
{
def
install
()
{
copyAssets
(
System
.
getABI
)
copyAssets
(
System
.
getABI
)
...
@@ -565,7 +558,7 @@ class Shadowsocks
...
@@ -565,7 +558,7 @@ class Shadowsocks
def
recovery
()
{
def
recovery
()
{
serviceStop
()
serviceStop
()
val
h
=
showProgress
(
R
.
string
.
recovering
)
val
h
=
showProgress
(
R
.
string
.
recovering
)
Future
{
Throwable
Future
{
reset
()
reset
()
h
.
sendEmptyMessage
(
0
)
h
.
sendEmptyMessage
(
0
)
}
}
...
@@ -573,8 +566,9 @@ class Shadowsocks
...
@@ -573,8 +566,9 @@ class Shadowsocks
def
flushDnsCache
()
{
def
flushDnsCache
()
{
val
h
=
showProgress
(
R
.
string
.
flushing
)
val
h
=
showProgress
(
R
.
string
.
flushing
)
Future
{
ThrowableFuture
{
Utils
.
toggleAirplaneMode
(
getBaseContext
)
if
(!
Utils
.
toggleAirplaneMode
(
getBaseContext
))
h
.
post
(()
=>
Snackbar
.
make
(
findViewById
(
android
.
R
.
id
.
content
),
R
.
string
.
flush_dnscache_no_root
,
Snackbar
.
LENGTH_LONG
).
show
)
h
.
sendEmptyMessage
(
0
)
h
.
sendEmptyMessage
(
0
)
}
}
}
}
...
@@ -595,7 +589,7 @@ class Shadowsocks
...
@@ -595,7 +589,7 @@ class Shadowsocks
def
checkText
(
key
:
String
)
:
Boolean
=
{
def
checkText
(
key
:
String
)
:
Boolean
=
{
val
text
=
ShadowsocksApplication
.
settings
.
getString
(
key
,
""
)
val
text
=
ShadowsocksApplication
.
settings
.
getString
(
key
,
""
)
if
(
text
!=
null
&&
text
.
length
>
0
)
return
true
if
(
text
!=
null
&&
text
.
length
>
0
)
return
true
Snackbar
.
make
(
findViewById
(
android
.
R
.
id
.
content
),
getString
(
R
.
string
.
proxy_empty
)
,
Snackbar
.
LENGTH_LONG
).
show
Snackbar
.
make
(
findViewById
(
android
.
R
.
id
.
content
),
R
.
string
.
proxy_empty
,
Snackbar
.
LENGTH_LONG
).
show
false
false
}
}
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala
View file @
10234542
...
@@ -46,7 +46,7 @@ import android.app.Application
...
@@ -46,7 +46,7 @@ import android.app.Application
import
android.content.pm.PackageManager
import
android.content.pm.PackageManager
import
android.preference.PreferenceManager
import
android.preference.PreferenceManager
import
com.github.shadowsocks.database.
{
DBHelper
,
ProfileManager
}
import
com.github.shadowsocks.database.
{
DBHelper
,
ProfileManager
}
import
com.github.shadowsocks.utils.
{
Console
,
Key
,
Utils
}
import
com.github.shadowsocks.utils.
{
Key
,
Utils
}
import
com.google.android.gms.analytics.
{
GoogleAnalytics
,
HitBuilders
}
import
com.google.android.gms.analytics.
{
GoogleAnalytics
,
HitBuilders
}
import
com.google.android.gms.common.api.ResultCallback
import
com.google.android.gms.common.api.ResultCallback
import
com.google.android.gms.tagmanager.
{
ContainerHolder
,
TagManager
}
import
com.google.android.gms.tagmanager.
{
ContainerHolder
,
TagManager
}
...
@@ -60,8 +60,7 @@ object ShadowsocksApplication {
...
@@ -60,8 +60,7 @@ object ShadowsocksApplication {
lazy
val
settings
=
PreferenceManager
.
getDefaultSharedPreferences
(
instance
)
lazy
val
settings
=
PreferenceManager
.
getDefaultSharedPreferences
(
instance
)
lazy
val
profileManager
=
new
ProfileManager
(
settings
,
dbHelper
)
lazy
val
profileManager
=
new
ProfileManager
(
settings
,
dbHelper
)
val
isRoot
=
Console
.
isRoot
def
isVpnEnabled
=
!
settings
.
getBoolean
(
Key
.
isNAT
,
false
)
def
isVpnEnabled
=
!(
isRoot
&&
settings
.
getBoolean
(
Key
.
isNAT
,
!
Utils
.
isLollipopOrAbove
))
def
getVersionName
=
try
{
def
getVersionName
=
try
{
instance
.
getPackageManager
.
getPackageInfo
(
instance
.
getPackageName
,
0
).
versionName
instance
.
getPackageManager
.
getPackageInfo
(
instance
.
getPackageName
,
0
).
versionName
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
View file @
10234542
...
@@ -55,8 +55,6 @@ import com.github.shadowsocks.utils._
...
@@ -55,8 +55,6 @@ import com.github.shadowsocks.utils._
import
scala.collection.JavaConversions._
import
scala.collection.JavaConversions._
import
scala.collection.mutable.ArrayBuffer
import
scala.collection.mutable.ArrayBuffer
import
scala.concurrent.ExecutionContext.Implicits.global
import
scala.concurrent.Future
class
ShadowsocksNatService
extends
BaseService
{
class
ShadowsocksNatService
extends
BaseService
{
...
@@ -144,7 +142,7 @@ class ShadowsocksNatService extends BaseService {
...
@@ -144,7 +142,7 @@ class ShadowsocksNatService extends BaseService {
})
})
Console
.
runRootCommand
(
cmdBuf
.
toArray
)
Console
.
runRootCommand
(
cmdBuf
.
toArray
)
}
else
{
}
else
{
Console
.
runRootCommand
(
Array
(
"ndc resolver flushdefaultif"
,
"ndc resolver flushif wlan0"
)
)
Console
.
runRootCommand
(
"ndc resolver flushdefaultif"
,
"ndc resolver flushif wlan0"
)
}
}
}
}
...
@@ -376,20 +374,29 @@ class ShadowsocksNatService extends BaseService {
...
@@ -376,20 +374,29 @@ class ShadowsocksNatService extends BaseService {
http_sb
.
append
(
Utils
.
getIptables
+
CMD_IPTABLES_DNAT_ADD_SOCKS
)
http_sb
.
append
(
Utils
.
getIptables
+
CMD_IPTABLES_DNAT_ADD_SOCKS
)
}
}
if
(
config
.
isProxyApps
)
{
if
(
config
.
isProxyApps
)
{
for
(
uid
<-
config
.
proxiedAppString
.
split
(
'|'
).
distinct
)
{
val
uidMap
=
getPackageManager
.
getInstalledApplications
(
0
).
map
(
ai
=>
ai
.
packageName
->
ai
.
uid
).
toMap
if
(!
config
.
isBypassApps
)
{
for
(
pn
<-
config
.
proxiedAppString
.
split
(
'\n'
))
uidMap
.
get
(
pn
)
match
{
http_sb
.
append
((
Utils
.
getIptables
+
CMD_IPTABLES_DNAT_ADD_SOCKS
).
replace
(
"-t nat"
,
"-t nat -m owner --uid-owner "
+
uid
))
case
Some
(
uid
)
=>
}
else
{
if
(!
config
.
isBypassApps
)
{
init_sb
.
append
(
cmd_bypass
.
replace
(
"-d 0.0.0.0"
,
"-m owner --uid-owner "
+
uid
))
http_sb
.
append
((
Utils
.
getIptables
+
CMD_IPTABLES_DNAT_ADD_SOCKS
)
}
.
replace
(
"-t nat"
,
"-t nat -m owner --uid-owner "
+
uid
))
}
else
{
init_sb
.
append
(
cmd_bypass
.
replace
(
"-d 0.0.0.0"
,
"-m owner --uid-owner "
+
uid
))
}
case
_
=>
// probably removed package, ignore
}
}
}
}
Console
.
runRootCommand
(
init_sb
.
toArray
)
Console
.
runRootCommand
((
init_sb
++
http_sb
).
toArray
)
Console
.
runRootCommand
(
http_sb
.
toArray
)
}
}
override
def
startRunner
(
config
:
Config
)
{
override
def
startRunner
(
config
:
Config
)
{
changeState
(
State
.
CONNECTING
)
if
(!
Console
.
isRoot
)
{
changeState
(
State
.
STOPPED
,
getString
(
R
.
string
.
nat_no_root
))
return
}
super
.
startRunner
(
config
)
super
.
startRunner
(
config
)
// register close receiver
// register close receiver
...
@@ -404,10 +411,7 @@ class ShadowsocksNatService extends BaseService {
...
@@ -404,10 +411,7 @@ class ShadowsocksNatService extends BaseService {
ShadowsocksApplication
.
track
(
TAG
,
"start"
)
ShadowsocksApplication
.
track
(
TAG
,
"start"
)
changeState
(
State
.
CONNECTING
)
ThrowableFuture
{
Future
{
if
(
config
.
proxy
==
"198.199.101.152"
)
{
if
(
config
.
proxy
==
"198.199.101.152"
)
{
val
holder
=
ShadowsocksApplication
.
containerHolder
val
holder
=
ShadowsocksApplication
.
containerHolder
try
{
try
{
...
@@ -465,7 +469,7 @@ class ShadowsocksNatService extends BaseService {
...
@@ -465,7 +469,7 @@ class ShadowsocksNatService extends BaseService {
closeReceiver
=
null
closeReceiver
=
null
}
}
notification
.
destroy
()
if
(
notification
!=
null
)
notification
.
destroy
()
ShadowsocksApplication
.
track
(
TAG
,
"stop"
)
ShadowsocksApplication
.
track
(
TAG
,
"stop"
)
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksSettings.scala
View file @
10234542
...
@@ -14,6 +14,7 @@ import com.github.shadowsocks.utils.Key
...
@@ -14,6 +14,7 @@ import com.github.shadowsocks.utils.Key
// TODO: Move related logic here
// TODO: Move related logic here
class
ShadowsocksSettings
extends
PreferenceFragment
with
OnSharedPreferenceChangeListener
{
class
ShadowsocksSettings
extends
PreferenceFragment
with
OnSharedPreferenceChangeListener
{
private
lazy
val
activity
=
getActivity
.
asInstanceOf
[
Shadowsocks
]
private
lazy
val
activity
=
getActivity
.
asInstanceOf
[
Shadowsocks
]
lazy
val
natSwitch
=
findPreference
(
Key
.
isNAT
).
asInstanceOf
[
SwitchPreference
]
private
var
isProxyApps
:
SwitchPreference
=
_
private
var
isProxyApps
:
SwitchPreference
=
_
...
@@ -35,10 +36,8 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
...
@@ -35,10 +36,8 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
})
})
val
flush
=
findPreference
(
"flush_dnscache"
)
val
flush
=
findPreference
(
"flush_dnscache"
)
if
(
Build
.
VERSION
.
SDK_INT
>=
17
&&
!
ShadowsocksApplication
.
isRoot
)
{
if
(
Build
.
VERSION
.
SDK_INT
<
17
)
flush
.
setSummary
(
R
.
string
.
flush_dnscache_summary
)
flush
.
setEnabled
(
false
)
flush
.
setOnPreferenceClickListener
(
_
=>
{
flush
.
setSummary
(
R
.
string
.
flush_dnscache_summary_disabled
)
}
else
flush
.
setOnPreferenceClickListener
((
preference
:
Preference
)
=>
{
ShadowsocksApplication
.
track
(
Shadowsocks
.
TAG
,
"flush_dnscache"
)
ShadowsocksApplication
.
track
(
Shadowsocks
.
TAG
,
"flush_dnscache"
)
activity
.
flushDnsCache
()
activity
.
flushDnsCache
()
true
true
...
@@ -73,12 +72,10 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
...
@@ -73,12 +72,10 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
}
}
def
onSharedPreferenceChanged
(
sharedPreferences
:
SharedPreferences
,
key
:
String
)
=
key
match
{
def
onSharedPreferenceChanged
(
sharedPreferences
:
SharedPreferences
,
key
:
String
)
=
key
match
{
case
Key
.
isNAT
=>
if
(
ShadowsocksApplication
.
isRoot
&&
activity
!=
null
)
{
case
Key
.
isNAT
=>
activity
.
handler
.
post
(()
=>
{
activity
.
handler
.
post
(()
=>
{
activity
.
deattachService
activity
.
deattachService
activity
.
attachService
activity
.
attachService
})
})
}
case
_
=>
case
_
=>
}
}
}
}
src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
View file @
10234542
...
@@ -55,8 +55,6 @@ import org.apache.commons.net.util.SubnetUtils
...
@@ -55,8 +55,6 @@ import org.apache.commons.net.util.SubnetUtils
import
scala.collection.JavaConversions._
import
scala.collection.JavaConversions._
import
scala.collection.mutable.ArrayBuffer
import
scala.collection.mutable.ArrayBuffer
import
scala.concurrent.ExecutionContext.Implicits.global
import
scala.concurrent.Future
class
ShadowsocksVpnService
extends
VpnService
with
BaseService
{
class
ShadowsocksVpnService
extends
VpnService
with
BaseService
{
val
TAG
=
"ShadowsocksVpnService"
val
TAG
=
"ShadowsocksVpnService"
...
@@ -122,7 +120,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -122,7 +120,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
vpnThread
=
null
vpnThread
=
null
}
}
notification
.
destroy
()
if
(
notification
!=
null
)
notification
.
destroy
()
// channge the state
// channge the state
changeState
(
State
.
STOPPING
)
changeState
(
State
.
STOPPING
)
...
@@ -213,7 +211,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -213,7 +211,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
changeState
(
State
.
CONNECTING
)
changeState
(
State
.
CONNECTING
)
Future
{
Throwable
Future
{
if
(
config
.
proxy
==
"198.199.101.152"
)
{
if
(
config
.
proxy
==
"198.199.101.152"
)
{
val
holder
=
ShadowsocksApplication
.
containerHolder
val
holder
=
ShadowsocksApplication
.
containerHolder
try
{
try
{
...
@@ -390,7 +388,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -390,7 +388,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
if
(
Utils
.
isLollipopOrAbove
)
{
if
(
Utils
.
isLollipopOrAbove
)
{
if
(
config
.
isProxyApps
)
{
if
(
config
.
isProxyApps
)
{
for
(
pkg
<-
config
.
proxiedAppString
.
split
(
'
|'
).
distinct
)
{
for
(
pkg
<-
config
.
proxiedAppString
.
split
(
'
\n'
)
)
{
if
(!
config
.
isBypassApps
)
{
if
(!
config
.
isBypassApps
)
{
builder
.
addAllowedApplication
(
pkg
)
builder
.
addAllowedApplication
(
pkg
)
}
else
{
}
else
{
...
...
src/main/scala/com/github/shadowsocks/database/DBHelper.scala
View file @
10234542
...
@@ -40,18 +40,30 @@
...
@@ -40,18 +40,30 @@
package
com.github.shadowsocks.database
package
com.github.shadowsocks.database
import
android.content.Context
import
android.content.Context
import
android.content.pm.ApplicationInfo
import
android.database.sqlite.SQLiteDatabase
import
android.database.sqlite.SQLiteDatabase
import
com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
import
com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
import
com.j256.ormlite.dao.Dao
import
com.j256.ormlite.dao.Dao
import
com.j256.ormlite.support.ConnectionSource
import
com.j256.ormlite.support.ConnectionSource
import
com.j256.ormlite.table.TableUtils
import
com.j256.ormlite.table.TableUtils
import
scala.collection.JavaConverters._
import
scala.collection.mutable
object
DBHelper
{
object
DBHelper
{
val
PROFILE
=
"profile.db"
final
val
PROFILE
=
"profile.db"
private
var
apps
:
mutable.Buffer
[
ApplicationInfo
]
=
_
def
updateProxiedApps
(
context
:
Context
,
old
:
String
)
=
{
synchronized
(
if
(
apps
==
null
)
apps
=
context
.
getPackageManager
.
getInstalledApplications
(
0
).
asScala
)
val
uidSet
=
old
.
split
(
'|'
).
map
(
_
.
toInt
).
toSet
apps
.
filter
(
ai
=>
uidSet
.
contains
(
ai
.
uid
)).
map
(
_
.
packageName
).
mkString
(
"\n"
)
}
}
}
class
DBHelper
(
val
context
:
Context
)
class
DBHelper
(
val
context
:
Context
)
extends
OrmLiteSqliteOpenHelper
(
context
,
DBHelper
.
PROFILE
,
null
,
13
)
{
extends
OrmLiteSqliteOpenHelper
(
context
,
DBHelper
.
PROFILE
,
null
,
14
)
{
import
DBHelper._
lazy
val
profileDao
:
Dao
[
Profile
,
Int
]
=
getDao
(
classOf
[
Profile
])
lazy
val
profileDao
:
Dao
[
Profile
,
Int
]
=
getDao
(
classOf
[
Profile
])
...
@@ -91,13 +103,17 @@ class DBHelper(val context: Context)
...
@@ -91,13 +103,17 @@ class DBHelper(val context: Context)
" ipv6, individual FROM `tmp`;"
)
" ipv6, individual FROM `tmp`;"
)
profileDao
.
executeRawNoArgs
(
"DROP TABLE `tmp`;"
)
profileDao
.
executeRawNoArgs
(
"DROP TABLE `tmp`;"
)
profileDao
.
executeRawNoArgs
(
"COMMIT;"
)
profileDao
.
executeRawNoArgs
(
"COMMIT;"
)
return
}
else
if
(
oldVersion
<
13
)
{
}
if
(
oldVersion
<
13
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN tx LONG;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN tx LONG;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN rx LONG;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN rx LONG;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN date VARCHAR;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN date VARCHAR;"
)
}
}
if
(
oldVersion
<
14
)
{
for
(
profile
<-
profileDao
.
queryForAll
.
asScala
)
{
profile
.
individual
=
updateProxiedApps
(
context
,
profile
.
individual
)
profileDao
.
update
(
profile
)
}
}
}
}
}
}
}
}
src/main/scala/com/github/shadowsocks/package.scala
0 → 100644
View file @
10234542
package
com.github
import
scala.concurrent.ExecutionContext.Implicits.global
import
scala.concurrent.Future
/**
* @author Mygod
*/
package
object
shadowsocks
{
def
ThrowableFuture
[
T
](
f
:
=>
T
)
=
Future
(
f
)
onFailure
{
case
e
:
Throwable
=>
e
.
printStackTrace
()
}
}
src/main/scala/com/github/shadowsocks/preferences/NatSwitchPreference.scala
deleted
100644 → 0
View file @
d2740700
package
com.github.shadowsocks.preferences
import
android.content.Context
import
android.content.res.TypedArray
import
android.preference.SwitchPreference
import
android.util.AttributeSet
import
com.github.shadowsocks.
{
R
,
ShadowsocksApplication
}
/**
* TODO: No animations?
* @author Mygod
*/
final
class
NatSwitchPreference
(
context
:
Context
,
attrs
:
AttributeSet
)
extends
SwitchPreference
(
context
,
attrs
)
{
private
var
disabled
=
false
override
def
isEnabled
=
super
.
isEnabled
&&
!
disabled
override
def
setEnabled
(
b
:
Boolean
)
=
super
.
setEnabled
(
b
&&
!
disabled
)
if
(!
ShadowsocksApplication
.
isRoot
)
{
disabled
=
true
setEnabled
(
false
)
setSummary
(
R
.
string
.
nat_summary_no_root
)
}
override
def
onGetDefaultValue
(
a
:
TypedArray
,
index
:
Int
)
=
(!
ShadowsocksApplication
.
isVpnEnabled
).
asInstanceOf
[
AnyRef
]
}
src/main/scala/com/github/shadowsocks/utils/Console.scala
View file @
10234542
...
@@ -75,17 +75,11 @@ object Console {
...
@@ -75,17 +75,11 @@ object Console {
shell
.
close
()
shell
.
close
()
}
}
def
runRootCommand
(
command
:
String
)
:
String
=
runRootCommand
(
Array
(
command
))
def
runRootCommand
(
commands
:
String*
)
:
String
=
runRootCommand
(
commands
.
toArray
)
def
runRootCommand
(
command
:
String
,
context
:
String
)
:
String
=
runRootCommand
(
Array
(
command
),
context
)
def
runRootCommand
(
commands
:
Array
[
String
])
:
String
=
{
def
runRootCommand
(
commands
:
Array
[
String
])
:
String
=
runRootCommand
(
commands
,
"u:r:init_shell:s0"
)
val
shell
=
openRootShell
(
"u:r:init_shell:s0"
)
def
runRootCommand
(
commands
:
Array
[
String
],
context
:
String
)
:
String
=
{
if
(!
isRoot
)
{
return
null
}
val
shell
=
openRootShell
(
context
)
val
sb
=
new
StringBuilder
val
sb
=
new
StringBuilder
shell
.
addCommand
(
commands
,
0
,
((
commandCode
:
Int
,
exitCode
:
Int
,
output
:
util.List
[
String
]
)
=>
{
shell
.
addCommand
(
commands
,
0
,
((
_
,
exitCode
,
output
)
=>
{
if
(
exitCode
<
0
)
{
if
(
exitCode
<
0
)
{
shell
.
close
()
shell
.
close
()
}
else
{
}
else
{
...
...
src/main/scala/com/github/shadowsocks/utils/Utils.scala
View file @
10234542
...
@@ -140,12 +140,14 @@ object Utils {
...
@@ -140,12 +140,14 @@ object Utils {
}
}
// Blocked > 3 seconds
// Blocked > 3 seconds
def
toggleAirplaneMode
(
context
:
Context
)
{
def
toggleAirplaneMode
(
context
:
Context
)
=
{
if
(
ShadowsocksApplication
.
isRoot
)
{
if
(
Console
.
isRoot
)
{
Console
.
runRootCommand
(
Array
(
"ndc resolver flushdefaultif"
,
"ndc resolver flushif wlan0"
))
Console
.
runRootCommand
(
"ndc resolver flushdefaultif"
,
"ndc resolver flushif wlan0"
)
true
}
else
if
(
Build
.
VERSION
.
SDK_INT
<
17
)
{
}
else
if
(
Build
.
VERSION
.
SDK_INT
<
17
)
{
toggleBelowApiLevel17
(
context
)
toggleBelowApiLevel17
(
context
)
}
true
}
else
false
}
}
//noinspection ScalaDeprecation
//noinspection ScalaDeprecation
...
@@ -305,8 +307,7 @@ object Utils {
...
@@ -305,8 +307,7 @@ object Utils {
var
compatible
:
Boolean
=
false
var
compatible
:
Boolean
=
false
var
version
:
Boolean
=
false
var
version
:
Boolean
=
false
val
command
=
Array
(
iptables
+
" --version"
,
iptables
+
" -L -t nat -n"
)
val
lines
=
Console
.
runRootCommand
(
iptables
+
" --version"
,
iptables
+
" -L -t nat -n"
)
val
lines
=
Console
.
runRootCommand
(
command
)
if
(
lines
==
null
)
return
if
(
lines
==
null
)
return
if
(
lines
.
contains
(
"OUTPUT"
))
{
if
(
lines
.
contains
(
"OUTPUT"
))
{
...
@@ -384,9 +385,7 @@ object Utils {
...
@@ -384,9 +385,7 @@ object Utils {
hasRedirectSupport
=
1
hasRedirectSupport
=
1
val
command
=
Utils
.
getIptables
+
" -t nat -A OUTPUT -p udp --dport 54 -j REDIRECT --to 8154"
val
command
=
Utils
.
getIptables
+
" -t nat -A OUTPUT -p udp --dport 54 -j REDIRECT --to 8154"
val
lines
=
Console
.
runRootCommand
(
command
)
val
lines
=
Console
.
runRootCommand
(
command
,
command
.
replace
(
"-A"
,
"-D"
))
Console
.
runRootCommand
(
command
.
replace
(
"-A"
,
"-D"
))
if
(
lines
==
null
)
return
if
(
lines
==
null
)
return
if
(
lines
.
contains
(
"No chain/target/match"
))
{
if
(
lines
.
contains
(
"No chain/target/match"
))
{
hasRedirectSupport
=
0
hasRedirectSupport
=
0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment