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
f40fb626
Commit
f40fb626
authored
May 14, 2013
by
Max Lv
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
clean up
parent
527d8f40
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
368 additions
and
319 deletions
+368
-319
src/main/scala/com/github/shadowsocks/AppManager.scala
src/main/scala/com/github/shadowsocks/AppManager.scala
+56
-44
src/main/scala/com/github/shadowsocks/ShadowVpnService.scala
src/main/scala/com/github/shadowsocks/ShadowVpnService.scala
+62
-63
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
+77
-56
src/main/scala/com/github/shadowsocks/ShadowsocksReceiver.scala
...in/scala/com/github/shadowsocks/ShadowsocksReceiver.scala
+2
-6
src/main/scala/com/github/shadowsocks/ShadowsocksService.scala
...ain/scala/com/github/shadowsocks/ShadowsocksService.scala
+124
-89
src/main/scala/com/github/shadowsocks/Utils.scala
src/main/scala/com/github/shadowsocks/Utils.scala
+47
-61
No files found.
src/main/scala/com/github/shadowsocks/AppManager.scala
View file @
f40fb626
...
@@ -41,7 +41,7 @@ package com.github.shadowsocks
...
@@ -41,7 +41,7 @@ package com.github.shadowsocks
import
android.app.ProgressDialog
import
android.app.ProgressDialog
import
android.content.Context
import
android.content.Context
import
android.content.SharedPreferences
import
android.content.SharedPreferences
import
android.content.pm.
{
ApplicationInfo
,
PackageManager
}
import
android.content.pm.
PackageManager
import
android.graphics.
{
Bitmap
,
PixelFormat
}
import
android.graphics.
{
Bitmap
,
PixelFormat
}
import
android.os.Bundle
import
android.os.Bundle
import
android.os.Handler
import
android.os.Handler
...
@@ -63,7 +63,6 @@ import android.widget.ListAdapter
...
@@ -63,7 +63,6 @@ import android.widget.ListAdapter
import
android.widget.ListView
import
android.widget.ListView
import
android.widget.TextView
import
android.widget.TextView
import
com.actionbarsherlock.app.SherlockActivity
import
com.actionbarsherlock.app.SherlockActivity
import
java.util.StringTokenizer
import
com.nostra13.universalimageloader.core.download.BaseImageDownloader
import
com.nostra13.universalimageloader.core.download.BaseImageDownloader
import
java.io.
{
ByteArrayOutputStream
,
ByteArrayInputStream
,
InputStream
}
import
java.io.
{
ByteArrayOutputStream
,
ByteArrayInputStream
,
InputStream
}
import
com.nostra13.universalimageloader.core.
{
DisplayImageOptions
,
ImageLoader
,
ImageLoaderConfiguration
}
import
com.nostra13.universalimageloader.core.
{
DisplayImageOptions
,
ImageLoader
,
ImageLoaderConfiguration
}
...
@@ -71,15 +70,17 @@ import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer
...
@@ -71,15 +70,17 @@ import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer
case
class
ProxiedApp
(
uid
:
Int
,
name
:
String
,
var
proxied
:
Boolean
)
case
class
ProxiedApp
(
uid
:
Int
,
name
:
String
,
var
proxied
:
Boolean
)
object
AppManager
{
class
ObjectArrayTools
[
T
<:
AnyRef
](
a
:
Array
[
T
])
{
val
PREFS_KEY_PROXYED
=
"Proxyed"
class
ObjectArrayTools
[
T
<:
AnyRef
](
a
:
Array
[
T
])
{
def
binarySearch
(
key
:
T
)
=
{
def
binarySearch
(
key
:
T
)
=
{
java
.
util
.
Arrays
.
binarySearch
(
a
.
asInstanceOf
[
Array
[
AnyRef
]],
key
)
java
.
util
.
Arrays
.
binarySearch
(
a
.
asInstanceOf
[
Array
[
AnyRef
]],
key
)
}
}
}
}
case
class
ListEntry
(
box
:
CheckBox
,
text
:
TextView
,
icon
:
ImageView
)
object
AppManager
{
val
PREFS_KEY_PROXYED
=
"Proxyed"
implicit
def
anyrefarray_tools
[
T
<:
AnyRef
](
a
:
Array
[
T
])
=
new
ObjectArrayTools
(
a
)
implicit
def
anyrefarray_tools
[
T
<:
AnyRef
](
a
:
Array
[
T
])
=
new
ObjectArrayTools
(
a
)
...
@@ -103,12 +104,23 @@ object AppManager {
...
@@ -103,12 +104,23 @@ object AppManager {
}
}
}.
toArray
}.
toArray
}
}
}
}
class
AppManager
extends
SherlockActivity
with
OnCheckedChangeListener
with
OnClickListener
{
class
AppManager
extends
SherlockActivity
with
OnCheckedChangeListener
with
OnClickListener
{
implicit
def
anyrefarray_tools
[
T
<:
AnyRef
](
a
:
Array
[
T
])
=
new
AppManager
.
ObjectArrayTools
(
a
)
val
MSG_LOAD_START
=
1
val
MSG_LOAD_FINISH
=
2
val
SCHEME
=
"app://"
val
STUB
=
android
.
R
.
drawable
.
sym_def_app_icon
implicit
def
anyrefarray_tools
[
T
<:
AnyRef
](
a
:
Array
[
T
])
=
new
ObjectArrayTools
(
a
)
var
apps
:
Array
[
ProxiedApp
]
=
null
var
appListView
:
ListView
=
null
var
overlay
:
TextView
=
null
var
progressDialog
:
ProgressDialog
=
null
var
adapter
:
ListAdapter
=
null
var
appsLoaded
:
Boolean
=
false
def
loadApps
(
context
:
Context
)
:
Array
[
ProxiedApp
]
=
{
def
loadApps
(
context
:
Context
)
:
Array
[
ProxiedApp
]
=
{
val
prefs
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
)
val
prefs
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
context
)
...
@@ -120,9 +132,10 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -120,9 +132,10 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
val
packageManager
:
PackageManager
=
context
.
getPackageManager
val
packageManager
:
PackageManager
=
context
.
getPackageManager
val
appList
=
packageManager
.
getInstalledApplications
(
0
)
val
appList
=
packageManager
.
getInstalledApplications
(
0
)
appList
.
filter
(
a
=>
a
.
uid
>=
10000
appList
.
filter
(
a
=>
a
.
uid
>=
10000
&&
packageManager
.
getApplicationLabel
(
a
)
!=
null
&&
packageManager
.
getApplicationLabel
(
a
)
!=
null
&&
packageManager
.
getApplicationIcon
(
a
)
!=
null
).
map
{
a
=>
&&
packageManager
.
getApplicationIcon
(
a
)
!=
null
).
map
{
a
=>
val
uid
=
a
.
uid
val
uid
=
a
.
uid
val
userName
=
uid
.
toString
val
userName
=
uid
.
toString
val
name
=
packageManager
.
getApplicationLabel
(
a
).
toString
val
name
=
packageManager
.
getApplicationLabel
(
a
).
toString
...
@@ -133,10 +146,15 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -133,10 +146,15 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
def
loadApps
()
{
def
loadApps
()
{
apps
=
loadApps
(
this
).
sortWith
((
a
,
b
)
=>
{
apps
=
loadApps
(
this
).
sortWith
((
a
,
b
)
=>
{
if
(
a
==
null
||
b
==
null
||
a
.
name
==
null
||
b
.
name
==
null
)
true
if
(
a
==
null
||
b
==
null
||
a
.
name
==
null
||
b
.
name
==
null
)
{
else
if
(
a
.
proxied
==
b
.
proxied
)
a
.
name
<
b
.
name
true
else
if
(
a
.
proxied
)
true
}
else
if
(
a
.
proxied
==
b
.
proxied
)
{
else
false
a
.
name
<
b
.
name
}
else
if
(
a
.
proxied
)
{
true
}
else
{
false
}
})
})
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
=
{
...
@@ -152,14 +170,14 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -152,14 +170,14 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
entry
.
text
.
setOnClickListener
(
AppManager
.
this
)
entry
.
text
.
setOnClickListener
(
AppManager
.
this
)
convertView
.
setTag
(
entry
)
convertView
.
setTag
(
entry
)
entry
.
box
.
setOnCheckedChangeListener
(
AppManager
.
this
)
entry
.
box
.
setOnCheckedChangeListener
(
AppManager
.
this
)
}
}
else
{
else
{
entry
=
convertView
.
getTag
.
asInstanceOf
[
ListEntry
]
entry
=
convertView
.
getTag
.
asInstanceOf
[
ListEntry
]
}
}
val
app
:
ProxiedApp
=
apps
(
position
)
val
app
:
ProxiedApp
=
apps
(
position
)
val
options
=
val
options
=
new
DisplayImageOptions
.
Builder
().
showStubImage
(
STUB
)
new
DisplayImageOptions
.
Builder
()
.
showStubImage
(
STUB
)
.
showImageForEmptyUri
(
STUB
)
.
showImageForEmptyUri
(
STUB
)
.
showImageOnFail
(
STUB
)
.
showImageOnFail
(
STUB
)
.
resetViewBeforeLoading
()
.
resetViewBeforeLoading
()
...
@@ -203,13 +221,18 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -203,13 +221,18 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
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
WindowManager
.
LayoutParams
(
LayoutParams
.
WRAP_CONTENT
,
LayoutParams
.
WRAP_CONTENT
,
WindowManager
.
LayoutParams
.
TYPE_APPLICATION
,
WindowManager
.
LayoutParams
.
FLAG_NOT_FOCUSABLE
|
WindowManager
.
LayoutParams
.
FLAG_NOT_TOUCHABLE
,
PixelFormat
.
TRANSLUCENT
))
getWindowManager
.
addView
(
overlay
,
new
WindowManager
.
LayoutParams
(
LayoutParams
.
WRAP_CONTENT
,
LayoutParams
.
WRAP_CONTENT
,
WindowManager
.
LayoutParams
.
TYPE_APPLICATION
,
WindowManager
.
LayoutParams
.
FLAG_NOT_FOCUSABLE
|
WindowManager
.
LayoutParams
.
FLAG_NOT_TOUCHABLE
,
PixelFormat
.
TRANSLUCENT
))
val
config
=
val
config
=
new
ImageLoaderConfiguration
.
Builder
(
this
).
imageDownloader
(
new
ImageLoaderConfiguration
.
Builder
(
this
)
new
AppIconDownloader
(
this
)).
build
()
.
imageDownloader
(
new
AppIconDownloader
(
this
))
.
build
()
ImageLoader
.
getInstance
().
init
(
config
)
ImageLoader
.
getInstance
().
init
(
config
)
}
}
protected
override
def
onResume
()
{
protected
override
def
onResume
()
{
...
@@ -236,8 +259,7 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -236,8 +259,7 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
if
(
app
.
proxied
)
{
if
(
app
.
proxied
)
{
proxiedApps
++=
app
.
uid
.
toString
proxiedApps
++=
app
.
uid
.
toString
proxiedApps
+=
'|'
proxiedApps
+=
'|'
}
})
)
val
edit
:
SharedPreferences.Editor
=
prefs
.
edit
val
edit
:
SharedPreferences.Editor
=
prefs
.
edit
edit
.
putString
(
AppManager
.
PREFS_KEY_PROXYED
,
proxiedApps
.
toString
())
edit
.
putString
(
AppManager
.
PREFS_KEY_PROXYED
,
proxiedApps
.
toString
())
edit
.
commit
edit
.
commit
...
@@ -247,17 +269,18 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -247,17 +269,18 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
override
def
handleMessage
(
msg
:
Message
)
{
override
def
handleMessage
(
msg
:
Message
)
{
msg
.
what
match
{
msg
.
what
match
{
case
MSG_LOAD_START
=>
case
MSG_LOAD_START
=>
progressDialog
=
ProgressDialog
.
show
(
AppManager
.
this
,
""
,
getString
(
R
.
string
.
loading
),
true
,
true
)
progressDialog
=
ProgressDialog
.
show
(
AppManager
.
this
,
""
,
getString
(
R
.
string
.
loading
),
true
,
true
)
case
MSG_LOAD_FINISH
=>
case
MSG_LOAD_FINISH
=>
appListView
.
setAdapter
(
adapter
)
appListView
.
setAdapter
(
adapter
)
appListView
.
setOnScrollListener
(
new
AbsListView
.
OnScrollListener
{
appListView
.
setOnScrollListener
(
new
AbsListView
.
OnScrollListener
{
def
onScroll
(
view
:
AbsListView
,
firstVisibleItem
:
Int
,
visibleItemCount
:
Int
,
totalItemCount
:
Int
)
{
def
onScroll
(
view
:
AbsListView
,
firstVisibleItem
:
Int
,
visibleItemCount
:
Int
,
totalItemCount
:
Int
)
{
if
(
visible
)
{
if
(
visible
)
{
val
name
:
String
=
apps
(
firstVisibleItem
).
name
val
name
:
String
=
apps
(
firstVisibleItem
).
name
if
(
name
!=
null
&&
name
.
length
>
1
)
{
if
(
name
!=
null
&&
name
.
length
>
1
)
{
overlay
.
setText
(
apps
(
firstVisibleItem
).
name
.
substring
(
0
,
1
))
overlay
.
setText
(
apps
(
firstVisibleItem
).
name
.
substring
(
0
,
1
))
}
}
else
{
else
{
overlay
.
setText
(
"*"
)
overlay
.
setText
(
"*"
)
}
}
overlay
.
setVisibility
(
View
.
VISIBLE
)
overlay
.
setVisibility
(
View
.
VISIBLE
)
...
@@ -285,7 +308,9 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -285,7 +308,9 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
class
AppIconDownloader
(
context
:
Context
,
connectTimeout
:
Int
,
readTimeout
:
Int
)
class
AppIconDownloader
(
context
:
Context
,
connectTimeout
:
Int
,
readTimeout
:
Int
)
extends
BaseImageDownloader
(
context
,
connectTimeout
,
readTimeout
)
{
extends
BaseImageDownloader
(
context
,
connectTimeout
,
readTimeout
)
{
def
this
(
context
:
Context
)
{
this
(
context
,
0
,
0
)
}
def
this
(
context
:
Context
)
{
this
(
context
,
0
,
0
)
}
override
def
getStreamFromOtherSource
(
imageUri
:
String
,
extra
:
AnyRef
)
:
InputStream
=
{
override
def
getStreamFromOtherSource
(
imageUri
:
String
,
extra
:
AnyRef
)
:
InputStream
=
{
val
uid
=
imageUri
.
substring
(
SCHEME
.
length
).
toInt
val
uid
=
imageUri
.
substring
(
SCHEME
.
length
).
toInt
...
@@ -298,17 +323,4 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
...
@@ -298,17 +323,4 @@ class AppManager extends SherlockActivity with OnCheckedChangeListener with OnCl
}
}
}
}
case
class
ListEntry
(
box
:
CheckBox
,
text
:
TextView
,
icon
:
ImageView
)
var
apps
:
Array
[
ProxiedApp
]
=
null
var
appListView
:
ListView
=
null
var
overlay
:
TextView
=
null
var
progressDialog
:
ProgressDialog
=
null
var
adapter
:
ListAdapter
=
null
var
appsLoaded
:
Boolean
=
false
val
MSG_LOAD_START
=
1
val
MSG_LOAD_FINISH
=
2
val
SCHEME
=
"app://"
val
STUB
=
android
.
R
.
drawable
.
sym_def_app_icon
}
}
\ No newline at end of file
src/main/scala/com/github/shadowsocks/ShadowVpnService.scala
View file @
f40fb626
...
@@ -50,10 +50,8 @@ import java.io._
...
@@ -50,10 +50,8 @@ import java.io._
import
java.lang.ref.WeakReference
import
java.lang.ref.WeakReference
import
android.net.VpnService
import
android.net.VpnService
import
org.apache.http.conn.util.InetAddressUtils
import
org.apache.http.conn.util.InetAddressUtils
import
org.xbill.DNS._
import
android.os.Message
import
android.os.Message
import
scala.Some
import
scala.Some
import
java.net.
{
UnknownHostException
,
InetAddress
}
object
ShadowVpnService
{
object
ShadowVpnService
{
def
isServiceStarted
:
Boolean
=
{
def
isServiceStarted
:
Boolean
=
{
...
@@ -68,7 +66,6 @@ object ShadowVpnService {
...
@@ -68,7 +66,6 @@ object ShadowVpnService {
}
}
var
sRunningInstance
:
WeakReference
[
ShadowVpnService
]
=
null
var
sRunningInstance
:
WeakReference
[
ShadowVpnService
]
=
null
}
}
class
ShadowVpnService
extends
VpnService
{
class
ShadowVpnService
extends
VpnService
{
...
@@ -86,14 +83,50 @@ class ShadowVpnService extends VpnService {
...
@@ -86,14 +83,50 @@ class ShadowVpnService extends VpnService {
var
conn
:
ParcelFileDescriptor
=
null
var
conn
:
ParcelFileDescriptor
=
null
var
udpgw
:
String
=
null
var
udpgw
:
String
=
null
var
notificationManager
:
NotificationManager
=
null
var
receiver
:
BroadcastReceiver
=
null
var
appHost
:
String
=
null
var
remotePort
:
Int
=
0
var
localPort
:
Int
=
0
var
sitekey
:
String
=
null
var
settings
:
SharedPreferences
=
null
var
isGlobalProxy
:
Boolean
=
false
var
isGFWList
:
Boolean
=
false
var
isBypassApps
:
Boolean
=
false
var
isDNSProxy
:
Boolean
=
false
var
isHTTPProxy
:
Boolean
=
false
var
encMethod
:
String
=
null
var
apps
:
Array
[
ProxiedApp
]
=
null
val
handler
:
Handler
=
new
Handler
{
override
def
handleMessage
(
msg
:
Message
)
{
val
ed
:
SharedPreferences.Editor
=
settings
.
edit
msg
.
what
match
{
case
MSG_CONNECT_START
=>
ed
.
putBoolean
(
"isConnecting"
,
true
)
case
MSG_CONNECT_FINISH
=>
ed
.
putBoolean
(
"isConnecting"
,
false
)
case
MSG_CONNECT_SUCCESS
=>
ed
.
putBoolean
(
"isRunning"
,
true
)
case
MSG_CONNECT_FAIL
=>
ed
.
putBoolean
(
"isRunning"
,
false
)
case
MSG_HOST_CHANGE
=>
ed
.
putString
(
"appHost"
,
appHost
)
case
MSG_STOP_SELF
=>
destroy
()
stopSelf
()
}
ed
.
commit
super
.
handleMessage
(
msg
)
}
}
def
getPid
(
name
:
String
)
:
Int
=
{
def
getPid
(
name
:
String
)
:
Int
=
{
try
{
try
{
val
reader
:
BufferedReader
=
new
BufferedReader
(
new
FileReader
(
BASE
+
name
+
".pid"
))
val
reader
:
BufferedReader
=
new
BufferedReader
(
new
FileReader
(
BASE
+
name
+
".pid"
))
val
line
=
reader
.
readLine
val
line
=
reader
.
readLine
return
Integer
.
valueOf
(
line
)
return
Integer
.
valueOf
(
line
)
}
}
catch
{
catch
{
case
e
:
FileNotFoundException
=>
{
case
e
:
FileNotFoundException
=>
{
Log
.
e
(
TAG
,
"Cannot open pid file: "
+
name
)
Log
.
e
(
TAG
,
"Cannot open pid file: "
+
name
)
}
}
...
@@ -110,8 +143,10 @@ class ShadowVpnService extends VpnService {
...
@@ -110,8 +143,10 @@ class ShadowVpnService extends VpnService {
def
startShadowsocksDaemon
()
{
def
startShadowsocksDaemon
()
{
new
Thread
{
new
Thread
{
override
def
run
()
{
override
def
run
()
{
val
cmd
:
String
=
(
BASE
+
"shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f "
+
BASE
+
"shadowsocks.pid"
)
val
cmd
:
String
=
(
BASE
+
.
format
(
appHost
,
remotePort
,
localPort
,
sitekey
,
encMethod
)
"shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f "
+
BASE
+
"shadowsocks.pid"
).
format
(
appHost
,
remotePort
,
localPort
,
sitekey
,
encMethod
)
System
.
exec
(
cmd
)
System
.
exec
(
cmd
)
}
}
}.
start
()
}.
start
()
...
@@ -122,8 +157,7 @@ class ShadowVpnService extends VpnService {
...
@@ -122,8 +157,7 @@ class ShadowVpnService extends VpnService {
try
{
try
{
val
pi
:
PackageInfo
=
getPackageManager
.
getPackageInfo
(
getPackageName
,
0
)
val
pi
:
PackageInfo
=
getPackageManager
.
getPackageInfo
(
getPackageName
,
0
)
version
=
pi
.
versionName
version
=
pi
.
versionName
}
}
catch
{
catch
{
case
e
:
PackageManager.NameNotFoundException
=>
{
case
e
:
PackageManager.NameNotFoundException
=>
{
version
=
"Package name not found"
version
=
"Package name not found"
}
}
...
@@ -141,16 +175,14 @@ class ShadowVpnService extends VpnService {
...
@@ -141,16 +175,14 @@ class ShadowVpnService extends VpnService {
encMethod
=
settings
.
getString
(
"encMethod"
,
"table"
)
encMethod
=
settings
.
getString
(
"encMethod"
,
"table"
)
try
{
try
{
remotePort
=
Integer
.
valueOf
(
settings
.
getString
(
"remotePort"
,
"1984"
))
remotePort
=
Integer
.
valueOf
(
settings
.
getString
(
"remotePort"
,
"1984"
))
}
}
catch
{
catch
{
case
ex
:
NumberFormatException
=>
{
case
ex
:
NumberFormatException
=>
{
remotePort
=
1984
remotePort
=
1984
}
}
}
}
try
{
try
{
localPort
=
Integer
.
valueOf
(
settings
.
getString
(
"port"
,
"1984"
))
localPort
=
Integer
.
valueOf
(
settings
.
getString
(
"port"
,
"1984"
))
}
}
catch
{
catch
{
case
ex
:
NumberFormatException
=>
{
case
ex
:
NumberFormatException
=>
{
localPort
=
1984
localPort
=
1984
}
}
...
@@ -214,8 +246,7 @@ class ShadowVpnService extends VpnService {
...
@@ -214,8 +246,7 @@ class ShadowVpnService extends VpnService {
t
.
start
()
t
.
start
()
try
{
try
{
t
.
join
(
300
)
t
.
join
(
300
)
}
}
catch
{
catch
{
case
ignored
:
InterruptedException
=>
{
case
ignored
:
InterruptedException
=>
{
}
}
}
}
...
@@ -249,8 +280,7 @@ class ShadowVpnService extends VpnService {
...
@@ -249,8 +280,7 @@ class ShadowVpnService extends VpnService {
val
prefix
=
Array
(
addr
,
i
.
toString
).
mkString
(
"."
)
val
prefix
=
Array
(
addr
,
i
.
toString
).
mkString
(
"."
)
if
(
prefix
!=
prefix3
)
builder
.
addRoute
(
prefix
+
".0"
,
24
)
if
(
prefix
!=
prefix3
)
builder
.
addRoute
(
prefix
+
".0"
,
24
)
}
}
}
})
)
builder
.
addRoute
(
"8.8.0.0"
,
16
)
builder
.
addRoute
(
"8.8.0.0"
,
16
)
}
else
{
}
else
{
for
(
i
<-
1
to
254
)
{
for
(
i
<-
1
to
254
)
{
...
@@ -274,9 +304,11 @@ class ShadowVpnService extends VpnService {
...
@@ -274,9 +304,11 @@ class ShadowVpnService extends VpnService {
val
fd
=
conn
.
getFd
val
fd
=
conn
.
getFd
val
cmd
=
(
BASE
+
"tun2socks --netif-ipaddr 172.16.0.2 --udpgw-remote-server-addr %s:7300 "
+
val
cmd
=
(
BASE
+
"--netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:%d --tunfd %d --tunmtu %d --pid "
+
BASE
+
"tun2socks.pid"
)
"tun2socks --netif-ipaddr 172.16.0.2 --udpgw-remote-server-addr %s:7300 "
+
.
format
(
udpgw
,
localPort
,
fd
,
VPN_MTU
)
"--netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:%d --tunfd %d --tunmtu %d --pid "
+
BASE
+
"tun2socks.pid"
).
format
(
udpgw
,
localPort
,
fd
,
VPN_MTU
)
Log
.
d
(
TAG
,
cmd
)
Log
.
d
(
TAG
,
cmd
)
System
.
exec
(
cmd
)
System
.
exec
(
cmd
)
...
@@ -308,9 +340,12 @@ class ShadowVpnService extends VpnService {
...
@@ -308,9 +340,12 @@ class ShadowVpnService extends VpnService {
val
contentIntent
:
PendingIntent
=
PendingIntent
.
getActivity
(
this
,
0
,
openIntent
,
0
)
val
contentIntent
:
PendingIntent
=
PendingIntent
.
getActivity
(
this
,
0
,
openIntent
,
0
)
val
builder
:
NotificationCompat.Builder
=
new
NotificationCompat
.
Builder
(
this
)
val
builder
:
NotificationCompat.Builder
=
new
NotificationCompat
.
Builder
(
this
)
builder
builder
.
setSmallIcon
(
R
.
drawable
.
ic_stat_shadowsocks
).
setWhen
(
0
)
.
setSmallIcon
(
R
.
drawable
.
ic_stat_shadowsocks
)
.
setTicker
(
title
).
setContentTitle
(
getString
(
R
.
string
.
app_name
))
.
setWhen
(
0
)
.
setContentText
(
info
).
setContentIntent
(
contentIntent
)
.
setTicker
(
title
)
.
setContentTitle
(
getString
(
R
.
string
.
app_name
))
.
setContentText
(
info
)
.
setContentIntent
(
contentIntent
)
.
setAutoCancel
(
true
)
.
setAutoCancel
(
true
)
notificationManager
.
notify
(
1
,
builder
.
build
)
notificationManager
.
notify
(
1
,
builder
.
build
)
}
}
...
@@ -328,7 +363,8 @@ class ShadowVpnService extends VpnService {
...
@@ -328,7 +363,8 @@ class ShadowVpnService extends VpnService {
EasyTracker
.
getTracker
.
sendEvent
(
"service"
,
"start"
,
getVersionName
,
0L
)
EasyTracker
.
getTracker
.
sendEvent
(
"service"
,
"start"
,
getVersionName
,
0L
)
settings
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
)
settings
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
)
notificationManager
=
getSystemService
(
Context
.
NOTIFICATION_SERVICE
).
asInstanceOf
[
NotificationManager
]
notificationManager
=
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
.
asInstanceOf
[
NotificationManager
]
// register close receiver
// register close receiver
val
filter
=
new
IntentFilter
()
val
filter
=
new
IntentFilter
()
...
@@ -337,7 +373,8 @@ class ShadowVpnService extends VpnService {
...
@@ -337,7 +373,8 @@ class ShadowVpnService extends VpnService {
receiver
=
new
BroadcastReceiver
{
receiver
=
new
BroadcastReceiver
{
def
onReceive
(
p1
:
Context
,
p2
:
Intent
)
{
def
onReceive
(
p1
:
Context
,
p2
:
Intent
)
{
destroy
()
destroy
()
stopSelf
()}
stopSelf
()
}
}
}
registerReceiver
(
receiver
,
filter
)
registerReceiver
(
receiver
,
filter
)
}
}
...
@@ -396,42 +433,4 @@ class ShadowVpnService extends VpnService {
...
@@ -396,42 +433,4 @@ class ShadowVpnService extends VpnService {
override
def
onRevoke
()
{
override
def
onRevoke
()
{
stopSelf
()
stopSelf
()
}
}
val
handler
:
Handler
=
new
Handler
{
override
def
handleMessage
(
msg
:
Message
)
{
val
ed
:
SharedPreferences.Editor
=
settings
.
edit
msg
.
what
match
{
case
MSG_CONNECT_START
=>
ed
.
putBoolean
(
"isConnecting"
,
true
)
case
MSG_CONNECT_FINISH
=>
ed
.
putBoolean
(
"isConnecting"
,
false
)
case
MSG_CONNECT_SUCCESS
=>
ed
.
putBoolean
(
"isRunning"
,
true
)
case
MSG_CONNECT_FAIL
=>
ed
.
putBoolean
(
"isRunning"
,
false
)
case
MSG_HOST_CHANGE
=>
ed
.
putString
(
"appHost"
,
appHost
)
case
MSG_STOP_SELF
=>
destroy
()
stopSelf
()
}
ed
.
commit
super
.
handleMessage
(
msg
)
}
}
var
notificationManager
:
NotificationManager
=
null
var
receiver
:
BroadcastReceiver
=
null
var
appHost
:
String
=
null
var
remotePort
:
Int
=
0
var
localPort
:
Int
=
0
var
sitekey
:
String
=
null
var
settings
:
SharedPreferences
=
null
var
isGlobalProxy
:
Boolean
=
false
var
isGFWList
:
Boolean
=
false
var
isBypassApps
:
Boolean
=
false
var
isDNSProxy
:
Boolean
=
false
var
isHTTPProxy
:
Boolean
=
false
var
encMethod
:
String
=
null
var
apps
:
Array
[
ProxiedApp
]
=
null
}
}
\ No newline at end of file
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
View file @
f40fb626
...
@@ -68,22 +68,22 @@ import net.saik0.android.unifiedpreference.UnifiedSherlockPreferenceActivity
...
@@ -68,22 +68,22 @@ import net.saik0.android.unifiedpreference.UnifiedSherlockPreferenceActivity
import
org.jraf.android.backport.switchwidget.Switch
import
org.jraf.android.backport.switchwidget.Switch
import
android.content.pm.PackageManager
import
android.content.pm.PackageManager
import
android.net.
{
Uri
,
VpnService
}
import
android.net.
{
Uri
,
VpnService
}
import
android.text.SpannableString
import
android.text.util.Linkify
import
android.text.method.LinkMovementMethod
import
android.webkit.
{
WebViewClient
,
WebView
}
import
android.webkit.
{
WebViewClient
,
WebView
}
object
Shadowsocks
{
object
Shadowsocks
{
val
PREFS_NAME
=
"Shadowsocks"
val
PREFS_NAME
=
"Shadowsocks"
val
PROXY_PREFS
=
Array
(
"proxy"
,
"remotePort"
,
"port"
,
"sitekey"
,
"encMethod"
)
val
PROXY_PREFS
=
Array
(
"proxy"
,
"remotePort"
,
"port"
,
"sitekey"
,
"encMethod"
)
val
FEATRUE_PREFS
=
Array
(
"isHTTPProxy"
,
"isDNSProxy"
,
"isGFWList"
,
"isGlobalProxy"
,
"isBypassApps"
,
"proxyedApps"
,
"isAutoConnect"
)
val
FEATRUE_PREFS
=
Array
(
"isHTTPProxy"
,
"isDNSProxy"
,
"isGFWList"
,
"isGlobalProxy"
,
"isBypassApps"
,
"proxyedApps"
,
"isAutoConnect"
)
val
TAG
=
"Shadowsocks"
val
TAG
=
"Shadowsocks"
val
REQUEST_CONNECT
=
1
val
REQUEST_CONNECT
=
1
class
ProxyFragment
extends
UnifiedPreferenceFragment
with
OnSharedPreferenceChangeListener
{
class
ProxyFragment
extends
UnifiedPreferenceFragment
with
OnSharedPreferenceChangeListener
{
private
def
setPreferenceEnabled
()
{
private
def
setPreferenceEnabled
()
{
val
settings
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
)
val
settings
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
)
val
enabled
:
Boolean
=
!
settings
.
getBoolean
(
"isRunning"
,
false
)
&&
!
settings
.
getBoolean
(
"isConnecting"
,
false
)
val
enabled
:
Boolean
=
!
settings
.
getBoolean
(
"isRunning"
,
false
)
&&
!
settings
.
getBoolean
(
"isConnecting"
,
false
)
for
(
name
<-
PROXY_PREFS
)
{
for
(
name
<-
PROXY_PREFS
)
{
val
pref
:
Preference
=
findPreference
(
name
)
val
pref
:
Preference
=
findPreference
(
name
)
if
(
pref
!=
null
)
{
if
(
pref
!=
null
)
{
...
@@ -113,7 +113,8 @@ object Shadowsocks {
...
@@ -113,7 +113,8 @@ object Shadowsocks {
class
FeatureFragment
extends
UnifiedPreferenceFragment
with
OnSharedPreferenceChangeListener
{
class
FeatureFragment
extends
UnifiedPreferenceFragment
with
OnSharedPreferenceChangeListener
{
private
def
setPreferenceEnabled
()
{
private
def
setPreferenceEnabled
()
{
val
settings
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
)
val
settings
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
getActivity
)
val
enabled
:
Boolean
=
!
settings
.
getBoolean
(
"isRunning"
,
false
)
&&
!
settings
.
getBoolean
(
"isConnecting"
,
false
)
val
enabled
:
Boolean
=
!
settings
.
getBoolean
(
"isRunning"
,
false
)
&&
!
settings
.
getBoolean
(
"isConnecting"
,
false
)
for
(
name
<-
Shadowsocks
.
FEATRUE_PREFS
)
{
for
(
name
<-
Shadowsocks
.
FEATRUE_PREFS
)
{
val
pref
:
Preference
=
findPreference
(
name
)
val
pref
:
Preference
=
findPreference
(
name
)
if
(
pref
!=
null
)
{
if
(
pref
!=
null
)
{
...
@@ -156,8 +157,7 @@ object Typefaces {
...
@@ -156,8 +157,7 @@ object Typefaces {
try
{
try
{
val
t
:
Typeface
=
Typeface
.
createFromAsset
(
c
.
getAssets
,
assetPath
)
val
t
:
Typeface
=
Typeface
.
createFromAsset
(
c
.
getAssets
,
assetPath
)
cache
.
put
(
assetPath
,
t
)
cache
.
put
(
assetPath
,
t
)
}
}
catch
{
catch
{
case
e
:
Exception
=>
{
case
e
:
Exception
=>
{
Log
.
e
(
TAG
,
"Could not get typeface '"
+
assetPath
+
"' because "
+
e
.
getMessage
)
Log
.
e
(
TAG
,
"Could not get typeface '"
+
assetPath
+
"' because "
+
e
.
getMessage
)
return
null
return
null
...
@@ -172,7 +172,9 @@ object Typefaces {
...
@@ -172,7 +172,9 @@ object Typefaces {
private
final
val
cache
:
Hashtable
[
String
,
Typeface
]
=
new
Hashtable
[
String
,
Typeface
]
private
final
val
cache
:
Hashtable
[
String
,
Typeface
]
=
new
Hashtable
[
String
,
Typeface
]
}
}
class
Shadowsocks
extends
UnifiedSherlockPreferenceActivity
with
CompoundButton
.
OnCheckedChangeListener
with
OnSharedPreferenceChangeListener
{
class
Shadowsocks
extends
UnifiedSherlockPreferenceActivity
with
CompoundButton
.
OnCheckedChangeListener
with
OnSharedPreferenceChangeListener
{
private
val
MSG_CRASH_RECOVER
:
Int
=
1
private
val
MSG_CRASH_RECOVER
:
Int
=
1
private
val
MSG_INITIAL_FINISH
:
Int
=
2
private
val
MSG_INITIAL_FINISH
:
Int
=
2
...
@@ -181,13 +183,32 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -181,13 +183,32 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
private
var
progressDialog
:
ProgressDialog
=
null
private
var
progressDialog
:
ProgressDialog
=
null
private
var
prepared
=
false
private
var
prepared
=
false
private
val
handler
:
Handler
=
new
Handler
{
override
def
handleMessage
(
msg
:
Message
)
{
val
settings
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
Shadowsocks
.
this
)
val
ed
:
SharedPreferences.Editor
=
settings
.
edit
msg
.
what
match
{
case
MSG_CRASH_RECOVER
=>
Crouton
.
makeText
(
Shadowsocks
.
this
,
R
.
string
.
crash_alert
,
Style
.
ALERT
).
show
()
ed
.
putBoolean
(
"isRunning"
,
false
)
case
MSG_INITIAL_FINISH
=>
if
(
progressDialog
!=
null
)
{
progressDialog
.
dismiss
()
progressDialog
=
null
}
}
ed
.
commit
super
.
handleMessage
(
msg
)
}
}
private
def
copyAssets
(
path
:
String
)
{
private
def
copyAssets
(
path
:
String
)
{
val
assetManager
:
AssetManager
=
getAssets
val
assetManager
:
AssetManager
=
getAssets
var
files
:
Array
[
String
]
=
null
var
files
:
Array
[
String
]
=
null
try
{
try
{
files
=
assetManager
.
list
(
path
)
files
=
assetManager
.
list
(
path
)
}
}
catch
{
catch
{
case
e
:
IOException
=>
{
case
e
:
IOException
=>
{
Log
.
e
(
Shadowsocks
.
TAG
,
e
.
getMessage
)
Log
.
e
(
Shadowsocks
.
TAG
,
e
.
getMessage
)
}
}
...
@@ -199,8 +220,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -199,8 +220,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
try
{
try
{
if
(
path
.
length
>
0
)
{
if
(
path
.
length
>
0
)
{
in
=
assetManager
.
open
(
path
+
"/"
+
file
)
in
=
assetManager
.
open
(
path
+
"/"
+
file
)
}
}
else
{
else
{
in
=
assetManager
.
open
(
file
)
in
=
assetManager
.
open
(
file
)
}
}
out
=
new
FileOutputStream
(
"/data/data/com.github.shadowsocks/"
+
file
)
out
=
new
FileOutputStream
(
"/data/data/com.github.shadowsocks/"
+
file
)
...
@@ -210,8 +230,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -210,8 +230,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
out
.
flush
()
out
.
flush
()
out
.
close
()
out
.
close
()
out
=
null
out
=
null
}
}
catch
{
catch
{
case
ex
:
Exception
=>
{
case
ex
:
Exception
=>
{
Log
.
e
(
Shadowsocks
.
TAG
,
ex
.
getMessage
)
Log
.
e
(
Shadowsocks
.
TAG
,
ex
.
getMessage
)
}
}
...
@@ -287,7 +306,9 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -287,7 +306,9 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
override
def
onCreate
(
savedInstanceState
:
Bundle
)
{
override
def
onCreate
(
savedInstanceState
:
Bundle
)
{
setHeaderRes
(
R
.
xml
.
shadowsocks_headers
)
setHeaderRes
(
R
.
xml
.
shadowsocks_headers
)
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
val
switchLayout
:
RelativeLayout
=
getLayoutInflater
.
inflate
(
R
.
layout
.
layout_switch
,
null
).
asInstanceOf
[
RelativeLayout
]
val
switchLayout
:
RelativeLayout
=
getLayoutInflater
.
inflate
(
R
.
layout
.
layout_switch
,
null
)
.
asInstanceOf
[
RelativeLayout
]
getSupportActionBar
.
setCustomView
(
switchLayout
)
getSupportActionBar
.
setCustomView
(
switchLayout
)
getSupportActionBar
.
setDisplayShowTitleEnabled
(
false
)
getSupportActionBar
.
setDisplayShowTitleEnabled
(
false
)
getSupportActionBar
.
setDisplayShowCustomEnabled
(
true
)
getSupportActionBar
.
setDisplayShowCustomEnabled
(
true
)
...
@@ -297,8 +318,10 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -297,8 +318,10 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
val
tf
:
Typeface
=
Typefaces
.
get
(
this
,
"fonts/Iceland.ttf"
)
val
tf
:
Typeface
=
Typefaces
.
get
(
this
,
"fonts/Iceland.ttf"
)
if
(
tf
!=
null
)
title
.
setTypeface
(
tf
)
if
(
tf
!=
null
)
title
.
setTypeface
(
tf
)
title
.
setText
(
R
.
string
.
app_name
)
title
.
setText
(
R
.
string
.
app_name
)
val
settings
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
Shadowsocks
.
this
)
val
settings
:
SharedPreferences
=
PreferenceManager
val
init
:
Boolean
=
!
settings
.
getBoolean
(
"isRunning"
,
false
)
&&
!
settings
.
getBoolean
(
"isConnecting"
,
false
)
.
getDefaultSharedPreferences
(
Shadowsocks
.
this
)
val
init
:
Boolean
=
!
settings
.
getBoolean
(
"isRunning"
,
false
)
&&
!
settings
.
getBoolean
(
"isConnecting"
,
false
)
if
(
init
)
{
if
(
init
)
{
if
(
progressDialog
==
null
)
{
if
(
progressDialog
==
null
)
{
progressDialog
=
ProgressDialog
.
show
(
this
,
""
,
getString
(
R
.
string
.
initializing
),
true
,
true
)
progressDialog
=
ProgressDialog
.
show
(
this
,
""
,
getString
(
R
.
string
.
initializing
),
true
,
true
)
...
@@ -309,8 +332,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -309,8 +332,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
var
versionName
:
String
=
null
var
versionName
:
String
=
null
try
{
try
{
versionName
=
getPackageManager
.
getPackageInfo
(
getPackageName
,
0
).
versionName
versionName
=
getPackageManager
.
getPackageInfo
(
getPackageName
,
0
).
versionName
}
}
catch
{
catch
{
case
e
:
PackageManager.NameNotFoundException
=>
{
case
e
:
PackageManager.NameNotFoundException
=>
{
versionName
=
"NONE"
versionName
=
"NONE"
}
}
...
@@ -328,9 +350,18 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -328,9 +350,18 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
}
}
override
def
onCreateOptionsMenu
(
menu
:
Menu
)
:
Boolean
=
{
override
def
onCreateOptionsMenu
(
menu
:
Menu
)
:
Boolean
=
{
menu
.
add
(
0
,
0
,
0
,
R
.
string
.
recovery
).
setIcon
(
android
.
R
.
drawable
.
ic_menu_revert
).
setShowAsAction
(
MenuItem
.
SHOW_AS_ACTION_WITH_TEXT
)
menu
menu
.
add
(
0
,
1
,
1
,
R
.
string
.
about
).
setIcon
(
android
.
R
.
drawable
.
ic_menu_info_details
).
setShowAsAction
(
MenuItem
.
SHOW_AS_ACTION_WITH_TEXT
)
.
add
(
0
,
0
,
0
,
R
.
string
.
recovery
)
menu
.
add
(
0
,
2
,
2
,
R
.
string
.
donate
).
setIcon
(
android
.
R
.
drawable
.
ic_menu_info_details
).
setShowAsAction
(
MenuItem
.
SHOW_AS_ACTION_WITH_TEXT
)
.
setIcon
(
android
.
R
.
drawable
.
ic_menu_revert
)
.
setShowAsAction
(
MenuItem
.
SHOW_AS_ACTION_WITH_TEXT
)
menu
.
add
(
0
,
1
,
1
,
R
.
string
.
about
)
.
setIcon
(
android
.
R
.
drawable
.
ic_menu_info_details
)
.
setShowAsAction
(
MenuItem
.
SHOW_AS_ACTION_WITH_TEXT
)
menu
.
add
(
0
,
2
,
2
,
R
.
string
.
donate
)
.
setIcon
(
android
.
R
.
drawable
.
ic_menu_info_details
)
.
setShowAsAction
(
MenuItem
.
SHOW_AS_ACTION_WITH_TEXT
)
true
true
}
}
...
@@ -338,8 +369,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -338,8 +369,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
if
(
keyCode
==
KeyEvent
.
KEYCODE_BACK
&&
event
.
getRepeatCount
==
0
)
{
if
(
keyCode
==
KeyEvent
.
KEYCODE_BACK
&&
event
.
getRepeatCount
==
0
)
{
try
{
try
{
finish
()
finish
()
}
}
catch
{
catch
{
case
ignore
:
Exception
=>
{
case
ignore
:
Exception
=>
{
}
}
}
}
...
@@ -363,7 +393,9 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -363,7 +393,9 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
protected
override
def
onPause
()
{
protected
override
def
onPause
()
{
super
.
onPause
()
super
.
onPause
()
prepared
=
false
prepared
=
false
PreferenceManager
.
getDefaultSharedPreferences
(
this
).
unregisterOnSharedPreferenceChangeListener
(
this
)
PreferenceManager
.
getDefaultSharedPreferences
(
this
)
.
unregisterOnSharedPreferenceChangeListener
(
this
)
}
}
protected
override
def
onResume
()
{
protected
override
def
onResume
()
{
...
@@ -396,12 +428,16 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -396,12 +428,16 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
}
}
setPreferenceEnabled
()
setPreferenceEnabled
()
switchButton
.
setOnCheckedChangeListener
(
this
)
switchButton
.
setOnCheckedChangeListener
(
this
)
PreferenceManager
.
getDefaultSharedPreferences
(
this
).
registerOnSharedPreferenceChangeListener
(
this
)
PreferenceManager
.
getDefaultSharedPreferences
(
this
)
.
registerOnSharedPreferenceChangeListener
(
this
)
}
}
private
def
setPreferenceEnabled
()
{
private
def
setPreferenceEnabled
()
{
val
settings
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
Shadowsocks
.
this
)
val
settings
:
SharedPreferences
=
PreferenceManager
val
enabled
:
Boolean
=
!
settings
.
getBoolean
(
"isRunning"
,
false
)
&&
!
settings
.
getBoolean
(
"isConnecting"
,
false
)
.
getDefaultSharedPreferences
(
Shadowsocks
.
this
)
val
enabled
:
Boolean
=
!
settings
.
getBoolean
(
"isRunning"
,
false
)
&&
!
settings
.
getBoolean
(
"isConnecting"
,
false
)
for
(
name
<-
Shadowsocks
.
PROXY_PREFS
)
{
for
(
name
<-
Shadowsocks
.
PROXY_PREFS
)
{
val
pref
:
Preference
=
findPreference
(
name
)
val
pref
:
Preference
=
findPreference
(
name
)
if
(
pref
!=
null
)
{
if
(
pref
!=
null
)
{
...
@@ -443,8 +479,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -443,8 +479,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
if
(
progressDialog
==
null
)
{
if
(
progressDialog
==
null
)
{
progressDialog
=
ProgressDialog
.
show
(
this
,
""
,
getString
(
R
.
string
.
connecting
),
true
,
true
)
progressDialog
=
ProgressDialog
.
show
(
this
,
""
,
getString
(
R
.
string
.
connecting
),
true
,
true
)
}
}
}
}
else
{
else
{
Log
.
d
(
Shadowsocks
.
TAG
,
"Connecting finish"
)
Log
.
d
(
Shadowsocks
.
TAG
,
"Connecting finish"
)
if
(
progressDialog
!=
null
)
{
if
(
progressDialog
!=
null
)
{
progressDialog
.
dismiss
()
progressDialog
.
dismiss
()
...
@@ -554,8 +589,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -554,8 +589,7 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
this
.
showDialog
(
getString
(
R
.
string
.
port_alert
))
this
.
showDialog
(
getString
(
R
.
string
.
port_alert
))
return
false
return
false
}
}
}
}
catch
{
catch
{
case
ex
:
Exception
=>
{
case
ex
:
Exception
=>
{
this
.
showDialog
(
getString
(
R
.
string
.
port_alert
))
this
.
showDialog
(
getString
(
R
.
string
.
port_alert
))
return
false
return
false
...
@@ -601,18 +635,25 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -601,18 +635,25 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
}
}
}
}
new
AlertDialog
.
Builder
(
this
).
setTitle
(
getString
(
R
.
string
.
about_title
).
format
(
versionName
))
new
AlertDialog
.
Builder
(
this
)
.
setTitle
(
getString
(
R
.
string
.
about_title
).
format
(
versionName
))
.
setCancelable
(
false
)
.
setCancelable
(
false
)
.
setNegativeButton
(
getString
(
R
.
string
.
ok_iknow
),
new
DialogInterface
.
OnClickListener
()
{
.
setNegativeButton
(
getString
(
R
.
string
.
ok_iknow
),
new
DialogInterface
.
OnClickListener
()
{
override
def
onClick
(
dialog
:
DialogInterface
,
id
:
Int
)
{
override
def
onClick
(
dialog
:
DialogInterface
,
id
:
Int
)
{
dialog
.
cancel
()
dialog
.
cancel
()
}
}
}).
setView
(
web
).
create
().
show
()
})
.
setView
(
web
)
.
create
()
.
show
()
}
}
private
def
showDialog
(
msg
:
String
)
{
private
def
showDialog
(
msg
:
String
)
{
val
builder
:
AlertDialog.Builder
=
new
AlertDialog
.
Builder
(
this
)
val
builder
:
AlertDialog.Builder
=
new
AlertDialog
.
Builder
(
this
)
builder
.
setMessage
(
msg
).
setCancelable
(
false
).
setNegativeButton
(
getString
(
R
.
string
.
ok_iknow
),
new
DialogInterface
.
OnClickListener
{
builder
.
setMessage
(
msg
)
.
setCancelable
(
false
)
.
setNegativeButton
(
getString
(
R
.
string
.
ok_iknow
),
new
DialogInterface
.
OnClickListener
{
def
onClick
(
dialog
:
DialogInterface
,
id
:
Int
)
{
def
onClick
(
dialog
:
DialogInterface
,
id
:
Int
)
{
dialog
.
cancel
()
dialog
.
cancel
()
}
}
...
@@ -620,24 +661,4 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
...
@@ -620,24 +661,4 @@ class Shadowsocks extends UnifiedSherlockPreferenceActivity with CompoundButton.
val
alert
:
AlertDialog
=
builder
.
create
val
alert
:
AlertDialog
=
builder
.
create
alert
.
show
()
alert
.
show
()
}
}
private
[
shadowsocks
]
final
val
handler
:
Handler
=
new
Handler
{
override
def
handleMessage
(
msg
:
Message
)
{
val
settings
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
Shadowsocks
.
this
)
val
ed
:
SharedPreferences.Editor
=
settings
.
edit
msg
.
what
match
{
case
MSG_CRASH_RECOVER
=>
Crouton
.
makeText
(
Shadowsocks
.
this
,
R
.
string
.
crash_alert
,
Style
.
ALERT
).
show
()
ed
.
putBoolean
(
"isRunning"
,
false
)
case
MSG_INITIAL_FINISH
=>
if
(
progressDialog
!=
null
)
{
progressDialog
.
dismiss
()
progressDialog
=
null
}
}
ed
.
commit
super
.
handleMessage
(
msg
)
}
}
}
}
\ No newline at end of file
src/main/scala/com/github/shadowsocks/ShadowsocksReceiver.scala
View file @
f40fb626
...
@@ -44,7 +44,6 @@ import android.content.SharedPreferences
...
@@ -44,7 +44,6 @@ import android.content.SharedPreferences
import
android.content.pm.PackageManager
import
android.content.pm.PackageManager
import
android.preference.PreferenceManager
import
android.preference.PreferenceManager
class
ShadowsocksReceiver
extends
BroadcastReceiver
{
class
ShadowsocksReceiver
extends
BroadcastReceiver
{
val
TAG
=
"Shadowsocks"
val
TAG
=
"Shadowsocks"
...
@@ -54,8 +53,7 @@ class ShadowsocksReceiver extends BroadcastReceiver {
...
@@ -54,8 +53,7 @@ class ShadowsocksReceiver extends BroadcastReceiver {
var
versionName
:
String
=
null
var
versionName
:
String
=
null
try
{
try
{
versionName
=
context
.
getPackageManager
.
getPackageInfo
(
context
.
getPackageName
,
0
).
versionName
versionName
=
context
.
getPackageManager
.
getPackageInfo
(
context
.
getPackageName
,
0
).
versionName
}
}
catch
{
catch
{
case
e
:
PackageManager.NameNotFoundException
=>
{
case
e
:
PackageManager.NameNotFoundException
=>
{
versionName
=
"NONE"
versionName
=
"NONE"
}
}
...
@@ -72,8 +70,7 @@ class ShadowsocksReceiver extends BroadcastReceiver {
...
@@ -72,8 +70,7 @@ class ShadowsocksReceiver extends BroadcastReceiver {
if
(
port
<=
1024
)
{
if
(
port
<=
1024
)
{
return
return
}
}
}
}
catch
{
catch
{
case
e
:
Exception
=>
{
case
e
:
Exception
=>
{
return
return
}
}
...
@@ -84,7 +81,6 @@ class ShadowsocksReceiver extends BroadcastReceiver {
...
@@ -84,7 +81,6 @@ class ShadowsocksReceiver extends BroadcastReceiver {
val
it
:
Intent
=
new
Intent
(
context
,
classOf
[
ShadowsocksService
])
val
it
:
Intent
=
new
Intent
(
context
,
classOf
[
ShadowsocksService
])
context
.
startService
(
it
)
context
.
startService
(
it
)
}
}
}
}
}
}
}
}
\ No newline at end of file
src/main/scala/com/github/shadowsocks/ShadowsocksService.scala
View file @
f40fb626
...
@@ -61,10 +61,7 @@ import java.lang.reflect.InvocationTargetException
...
@@ -61,10 +61,7 @@ import java.lang.reflect.InvocationTargetException
import
java.lang.reflect.Method
import
java.lang.reflect.Method
import
org.apache.http.conn.util.InetAddressUtils
import
org.apache.http.conn.util.InetAddressUtils
import
scala.collection._
import
scala.collection._
import
org.xbill.DNS._
import
scala.Some
import
scala.Some
import
scala.Some
import
java.net.
{
UnknownHostException
,
InetAddress
}
object
ShadowsocksService
{
object
ShadowsocksService
{
def
isServiceStarted
:
Boolean
=
{
def
isServiceStarted
:
Boolean
=
{
...
@@ -83,13 +80,68 @@ object ShadowsocksService {
...
@@ -83,13 +80,68 @@ object ShadowsocksService {
class
ShadowsocksService
extends
Service
{
class
ShadowsocksService
extends
Service
{
val
TAG
=
"ShadowsocksService"
val
BASE
=
"/data/data/com.github.shadowsocks/"
val
REDSOCKS_CONF
=
"base {"
+
" log_debug = off;"
+
" log_info = off;"
+
" log = stderr;"
+
" daemon = on;"
+
" redirector = iptables;"
+
"}"
+
"redsocks {"
+
" local_ip = 127.0.0.1;"
+
" local_port = 8123;"
+
" ip = 127.0.0.1;"
+
" port = %d;"
+
" type = socks5;"
+
"}"
val
SHADOWSOCKS_CONF
=
"{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}"
val
CMD_IPTABLES_RETURN
=
" -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN\n"
val
CMD_IPTABLES_REDIRECT_ADD_SOCKS
=
" -t nat -A OUTPUT -p tcp "
+
"-j REDIRECT --to 8123\n"
val
CMD_IPTABLES_DNAT_ADD_SOCKS
=
" -t nat -A OUTPUT -p tcp "
+
"-j DNAT --to-destination 127.0.0.1:8123\n"
val
MSG_CONNECT_START
:
Int
=
0
val
MSG_CONNECT_FINISH
:
Int
=
1
val
MSG_CONNECT_SUCCESS
:
Int
=
2
val
MSG_CONNECT_FAIL
:
Int
=
3
val
MSG_HOST_CHANGE
:
Int
=
4
val
MSG_STOP_SELF
:
Int
=
5
val
DNS_PORT
:
Int
=
8153
val
mStartForegroundSignature
=
Array
[
Class
[
_
]](
classOf
[
Int
],
classOf
[
Notification
])
val
mStopForegroundSignature
=
Array
[
Class
[
_
]](
classOf
[
Boolean
])
val
mSetForegroundSignature
=
Array
[
Class
[
_
]](
classOf
[
Boolean
])
var
receiver
:
BroadcastReceiver
=
null
var
notificationManager
:
NotificationManager
=
null
var
mWakeLock
:
PowerManager
#
WakeLock
=
null
var
appHost
:
String
=
null
var
remotePort
:
Int
=
0
var
localPort
:
Int
=
0
var
sitekey
:
String
=
null
var
settings
:
SharedPreferences
=
null
var
hasRedirectSupport
:
Boolean
=
true
var
isGlobalProxy
:
Boolean
=
false
var
isGFWList
:
Boolean
=
false
var
isBypassApps
:
Boolean
=
false
var
isDNSProxy
:
Boolean
=
false
var
isHTTPProxy
:
Boolean
=
false
var
encMethod
:
String
=
null
var
apps
:
Array
[
ProxiedApp
]
=
null
var
mSetForeground
:
Method
=
null
var
mStartForeground
:
Method
=
null
var
mStopForeground
:
Method
=
null
var
mSetForegroundArgs
=
new
Array
[
AnyRef
](
1
)
var
mStartForegroundArgs
=
new
Array
[
AnyRef
](
2
)
var
mStopForegroundArgs
=
new
Array
[
AnyRef
](
1
)
def
getPid
(
name
:
String
)
:
Int
=
{
def
getPid
(
name
:
String
)
:
Int
=
{
try
{
try
{
val
reader
:
BufferedReader
=
new
BufferedReader
(
new
FileReader
(
BASE
+
name
+
".pid"
))
val
reader
:
BufferedReader
=
new
BufferedReader
(
new
FileReader
(
BASE
+
name
+
".pid"
))
val
line
=
reader
.
readLine
val
line
=
reader
.
readLine
return
Integer
.
valueOf
(
line
)
return
Integer
.
valueOf
(
line
)
}
}
catch
{
catch
{
case
e
:
FileNotFoundException
=>
{
case
e
:
FileNotFoundException
=>
{
Log
.
e
(
TAG
,
"Cannot open pid file: "
+
name
)
Log
.
e
(
TAG
,
"Cannot open pid file: "
+
name
)
}
}
...
@@ -106,8 +158,10 @@ class ShadowsocksService extends Service {
...
@@ -106,8 +158,10 @@ class ShadowsocksService extends Service {
def
startShadowsocksDaemon
()
{
def
startShadowsocksDaemon
()
{
new
Thread
{
new
Thread
{
override
def
run
()
{
override
def
run
()
{
val
cmd
:
String
=
(
BASE
+
"shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f "
+
BASE
+
"shadowsocks.pid"
)
val
cmd
:
String
=
(
BASE
+
.
format
(
appHost
,
remotePort
,
localPort
,
sitekey
,
encMethod
)
"shadowsocks -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" -m \"%s\" -f "
+
BASE
+
"shadowsocks.pid"
).
format
(
appHost
,
remotePort
,
localPort
,
sitekey
,
encMethod
)
System
.
exec
(
cmd
)
System
.
exec
(
cmd
)
}
}
}.
start
()
}.
start
()
...
@@ -116,7 +170,8 @@ class ShadowsocksService extends Service {
...
@@ -116,7 +170,8 @@ class ShadowsocksService extends Service {
def
startPolipoDaemon
()
{
def
startPolipoDaemon
()
{
new
Thread
{
new
Thread
{
override
def
run
()
{
override
def
run
()
{
val
cmd
:
String
=
(
BASE
+
"polipo proxyPort=%d socksParentProxy=127.0.0.1:%d daemonise=true pidFile=\"%s\" logLevel=1 logFile=\"%s\""
)
val
cmd
:
String
=
(
BASE
+
"polipo proxyPort=%d socksParentProxy=127.0.0.1:%d daemonise=true pidFile=\"%s\" logLevel=1 logFile=\"%s\""
)
.
format
(
localPort
+
1
,
localPort
,
BASE
+
"polipo.pid"
,
BASE
+
"polipo.log"
)
.
format
(
localPort
+
1
,
localPort
,
BASE
+
"polipo.pid"
,
BASE
+
"polipo.log"
)
System
.
exec
(
cmd
)
System
.
exec
(
cmd
)
}
}
...
@@ -133,8 +188,7 @@ class ShadowsocksService extends Service {
...
@@ -133,8 +188,7 @@ class ShadowsocksService extends Service {
try
{
try
{
val
pi
:
PackageInfo
=
getPackageManager
.
getPackageInfo
(
getPackageName
,
0
)
val
pi
:
PackageInfo
=
getPackageManager
.
getPackageInfo
(
getPackageName
,
0
)
version
=
pi
.
versionName
version
=
pi
.
versionName
}
}
catch
{
catch
{
case
e
:
PackageManager.NameNotFoundException
=>
{
case
e
:
PackageManager.NameNotFoundException
=>
{
version
=
"Package name not found"
version
=
"Package name not found"
}
}
...
@@ -152,16 +206,14 @@ class ShadowsocksService extends Service {
...
@@ -152,16 +206,14 @@ class ShadowsocksService extends Service {
encMethod
=
settings
.
getString
(
"encMethod"
,
"table"
)
encMethod
=
settings
.
getString
(
"encMethod"
,
"table"
)
try
{
try
{
remotePort
=
Integer
.
valueOf
(
settings
.
getString
(
"remotePort"
,
"1984"
))
remotePort
=
Integer
.
valueOf
(
settings
.
getString
(
"remotePort"
,
"1984"
))
}
}
catch
{
catch
{
case
ex
:
NumberFormatException
=>
{
case
ex
:
NumberFormatException
=>
{
remotePort
=
1984
remotePort
=
1984
}
}
}
}
try
{
try
{
localPort
=
Integer
.
valueOf
(
settings
.
getString
(
"port"
,
"1984"
))
localPort
=
Integer
.
valueOf
(
settings
.
getString
(
"port"
,
"1984"
))
}
}
catch
{
catch
{
case
ex
:
NumberFormatException
=>
{
case
ex
:
NumberFormatException
=>
{
localPort
=
1984
localPort
=
1984
}
}
...
@@ -192,10 +244,10 @@ class ShadowsocksService extends Service {
...
@@ -192,10 +244,10 @@ class ShadowsocksService extends Service {
Log
.
d
(
TAG
,
"IPTABLES: "
+
Utils
.
getIptables
)
Log
.
d
(
TAG
,
"IPTABLES: "
+
Utils
.
getIptables
)
hasRedirectSupport
=
Utils
.
getHasRedirectSupport
hasRedirectSupport
=
Utils
.
getHasRedirectSupport
if
(
resolved
&&
handleConnection
)
{
if
(
resolved
&&
handleConnection
)
{
notifyForegroundAlert
(
getString
(
R
.
string
.
forward_success
),
getString
(
R
.
string
.
service_running
))
notifyForegroundAlert
(
getString
(
R
.
string
.
forward_success
),
getString
(
R
.
string
.
service_running
))
handler
.
sendEmptyMessageDelayed
(
MSG_CONNECT_SUCCESS
,
500
)
handler
.
sendEmptyMessageDelayed
(
MSG_CONNECT_SUCCESS
,
500
)
}
}
else
{
else
{
notifyAlert
(
getString
(
R
.
string
.
forward_fail
),
getString
(
R
.
string
.
service_failed
))
notifyAlert
(
getString
(
R
.
string
.
forward_fail
),
getString
(
R
.
string
.
service_failed
))
stopSelf
()
stopSelf
()
handler
.
sendEmptyMessageDelayed
(
MSG_CONNECT_FAIL
,
500
)
handler
.
sendEmptyMessageDelayed
(
MSG_CONNECT_FAIL
,
500
)
...
@@ -225,8 +277,7 @@ class ShadowsocksService extends Service {
...
@@ -225,8 +277,7 @@ class ShadowsocksService extends Service {
t
.
start
()
t
.
start
()
try
{
try
{
t
.
join
(
300
)
t
.
join
(
300
)
}
}
catch
{
catch
{
case
ignored
:
InterruptedException
=>
{
case
ignored
:
InterruptedException
=>
{
}
}
}
}
...
@@ -253,8 +304,7 @@ class ShadowsocksService extends Service {
...
@@ -253,8 +304,7 @@ class ShadowsocksService extends Service {
def
invokeMethod
(
method
:
Method
,
args
:
Array
[
AnyRef
])
{
def
invokeMethod
(
method
:
Method
,
args
:
Array
[
AnyRef
])
{
try
{
try
{
method
.
invoke
(
this
,
mStartForegroundArgs
:
_
*
)
method
.
invoke
(
this
,
mStartForegroundArgs
:
_
*
)
}
}
catch
{
catch
{
case
e
:
InvocationTargetException
=>
{
case
e
:
InvocationTargetException
=>
{
Log
.
w
(
TAG
,
"Unable to invoke method"
,
e
)
Log
.
w
(
TAG
,
"Unable to invoke method"
,
e
)
}
}
...
@@ -280,10 +330,14 @@ class ShadowsocksService extends Service {
...
@@ -280,10 +330,14 @@ class ShadowsocksService extends Service {
val
actionIntent
:
PendingIntent
=
PendingIntent
.
getBroadcast
(
this
,
0
,
closeIntent
,
0
)
val
actionIntent
:
PendingIntent
=
PendingIntent
.
getBroadcast
(
this
,
0
,
closeIntent
,
0
)
val
builder
:
NotificationCompat.Builder
=
new
NotificationCompat
.
Builder
(
this
)
val
builder
:
NotificationCompat.Builder
=
new
NotificationCompat
.
Builder
(
this
)
builder
builder
.
setSmallIcon
(
R
.
drawable
.
ic_stat_shadowsocks
).
setWhen
(
0
)
.
setSmallIcon
(
R
.
drawable
.
ic_stat_shadowsocks
)
.
setTicker
(
title
).
setContentTitle
(
getString
(
R
.
string
.
app_name
))
.
setWhen
(
0
)
.
setContentText
(
info
).
setContentIntent
(
contentIntent
)
.
setTicker
(
title
)
.
addAction
(
android
.
R
.
drawable
.
ic_menu_close_clear_cancel
,
getString
(
R
.
string
.
stop
),
actionIntent
)
.
setContentTitle
(
getString
(
R
.
string
.
app_name
))
.
setContentText
(
info
)
.
setContentIntent
(
contentIntent
)
.
addAction
(
android
.
R
.
drawable
.
ic_menu_close_clear_cancel
,
getString
(
R
.
string
.
stop
),
actionIntent
)
startForegroundCompat
(
1
,
builder
.
build
)
startForegroundCompat
(
1
,
builder
.
build
)
}
}
...
@@ -293,10 +347,12 @@ class ShadowsocksService extends Service {
...
@@ -293,10 +347,12 @@ class ShadowsocksService extends Service {
val
contentIntent
:
PendingIntent
=
PendingIntent
.
getActivity
(
this
,
0
,
openIntent
,
0
)
val
contentIntent
:
PendingIntent
=
PendingIntent
.
getActivity
(
this
,
0
,
openIntent
,
0
)
val
builder
:
NotificationCompat.Builder
=
new
NotificationCompat
.
Builder
(
this
)
val
builder
:
NotificationCompat.Builder
=
new
NotificationCompat
.
Builder
(
this
)
builder
builder
.
setSmallIcon
(
R
.
drawable
.
ic_stat_shadowsocks
).
setWhen
(
0
)
.
setSmallIcon
(
R
.
drawable
.
ic_stat_shadowsocks
)
.
setWhen
(
0
)
.
setTicker
(
title
)
.
setTicker
(
title
)
.
setContentTitle
(
getString
(
R
.
string
.
app_name
))
.
setContentTitle
(
getString
(
R
.
string
.
app_name
))
.
setContentText
(
info
).
setContentIntent
(
contentIntent
)
.
setContentText
(
info
)
.
setContentIntent
(
contentIntent
)
.
setAutoCancel
(
true
)
.
setAutoCancel
(
true
)
notificationManager
.
notify
(
1
,
builder
.
build
)
notificationManager
.
notify
(
1
,
builder
.
build
)
}
}
...
@@ -309,12 +365,13 @@ class ShadowsocksService extends Service {
...
@@ -309,12 +365,13 @@ class ShadowsocksService extends Service {
super
.
onCreate
()
super
.
onCreate
()
EasyTracker
.
getTracker
.
sendEvent
(
"service"
,
"start"
,
getVersionName
,
0L
)
EasyTracker
.
getTracker
.
sendEvent
(
"service"
,
"start"
,
getVersionName
,
0L
)
settings
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
)
settings
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
)
notificationManager
=
this
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
).
asInstanceOf
[
NotificationManager
]
notificationManager
=
this
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
.
asInstanceOf
[
NotificationManager
]
try
{
try
{
mStartForeground
=
getClass
.
getMethod
(
"startForeground"
,
mStartForegroundSignature
:
_
*
)
mStartForeground
=
getClass
.
getMethod
(
"startForeground"
,
mStartForegroundSignature
:
_
*
)
mStopForeground
=
getClass
.
getMethod
(
"stopForeground"
,
mStopForegroundSignature
:
_
*
)
mStopForeground
=
getClass
.
getMethod
(
"stopForeground"
,
mStopForegroundSignature
:
_
*
)
}
}
catch
{
catch
{
case
e
:
NoSuchMethodException
=>
{
case
e
:
NoSuchMethodException
=>
{
mStartForeground
=
({
mStartForeground
=
({
mStopForeground
=
null
mStopForeground
=
null
...
@@ -324,10 +381,10 @@ class ShadowsocksService extends Service {
...
@@ -324,10 +381,10 @@ class ShadowsocksService extends Service {
}
}
try
{
try
{
mSetForeground
=
getClass
.
getMethod
(
"setForeground"
,
mSetForegroundSignature
:
_
*
)
mSetForeground
=
getClass
.
getMethod
(
"setForeground"
,
mSetForegroundSignature
:
_
*
)
}
}
catch
{
catch
{
case
e
:
NoSuchMethodException
=>
{
case
e
:
NoSuchMethodException
=>
{
throw
new
IllegalStateException
(
"OS doesn't have Service.startForeground OR Service.setForeground!"
)
throw
new
IllegalStateException
(
"OS doesn't have Service.startForeground OR Service.setForeground!"
)
}
}
}
}
...
@@ -336,10 +393,11 @@ class ShadowsocksService extends Service {
...
@@ -336,10 +393,11 @@ class ShadowsocksService extends Service {
filter
.
addAction
(
Intent
.
ACTION_SHUTDOWN
)
filter
.
addAction
(
Intent
.
ACTION_SHUTDOWN
)
filter
.
addAction
(
Utils
.
CLOSE_ACTION
)
filter
.
addAction
(
Utils
.
CLOSE_ACTION
)
receiver
=
new
BroadcastReceiver
()
{
receiver
=
new
BroadcastReceiver
()
{
def
onReceive
(
p1
:
Context
,
p2
:
Intent
)
{
stopSelf
()
}
def
onReceive
(
p1
:
Context
,
p2
:
Intent
)
{
stopSelf
()
}
}
}
registerReceiver
(
receiver
,
filter
)
registerReceiver
(
receiver
,
filter
)
}
}
/** Called when the activity is closed. */
/** Called when the activity is closed. */
...
@@ -412,13 +470,21 @@ class ShadowsocksService extends Service {
...
@@ -412,13 +470,21 @@ class ShadowsocksService extends Service {
init_sb
.
append
(
cmd_bypass
.
replace
(
"0.0.0.0"
,
"127.0.0.1"
))
init_sb
.
append
(
cmd_bypass
.
replace
(
"0.0.0.0"
,
"127.0.0.1"
))
if
(!
isDNSProxy
)
{
if
(!
isDNSProxy
)
{
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
))
init_sb
.
append
(
cmd_bypass
.
replace
(
"-d 0.0.0.0"
,
"-m owner --uid-owner "
+
getApplicationInfo
.
uid
))
init_sb
.
append
(
cmd_bypass
.
replace
(
"-d 0.0.0.0"
,
"-m owner --uid-owner "
+
getApplicationInfo
.
uid
))
}
}
if
(
hasRedirectSupport
)
{
if
(
hasRedirectSupport
)
{
init_sb
.
append
(
Utils
.
getIptables
).
append
(
" -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to "
).
append
(
DNS_PORT
).
append
(
"\n"
)
init_sb
}
.
append
(
Utils
.
getIptables
)
else
{
.
append
(
" -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to "
)
init_sb
.
append
(
Utils
.
getIptables
).
append
(
" -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:"
).
append
(
DNS_PORT
).
append
(
"\n"
)
.
append
(
DNS_PORT
)
.
append
(
"\n"
)
}
else
{
init_sb
.
append
(
Utils
.
getIptables
)
.
append
(
" -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:"
)
.
append
(
DNS_PORT
)
.
append
(
"\n"
)
}
}
if
(
isGFWList
)
{
if
(
isGFWList
)
{
val
chn_list
:
Array
[
String
]
=
getResources
.
getStringArray
(
R
.
array
.
chn_list
)
val
chn_list
:
Array
[
String
]
=
getResources
.
getStringArray
(
R
.
array
.
chn_list
)
...
@@ -427,7 +493,12 @@ class ShadowsocksService extends Service {
...
@@ -427,7 +493,12 @@ class ShadowsocksService extends Service {
}
}
}
}
if
(
isGlobalProxy
||
isBypassApps
)
{
if
(
isGlobalProxy
||
isBypassApps
)
{
http_sb
.
append
(
if
(
hasRedirectSupport
)
Utils
.
getIptables
+
CMD_IPTABLES_REDIRECT_ADD_SOCKS
else
Utils
.
getIptables
+
CMD_IPTABLES_DNAT_ADD_SOCKS
)
http_sb
.
append
(
if
(
hasRedirectSupport
)
{
Utils
.
getIptables
+
CMD_IPTABLES_REDIRECT_ADD_SOCKS
}
else
{
Utils
.
getIptables
+
CMD_IPTABLES_DNAT_ADD_SOCKS
})
}
}
if
(!
isGlobalProxy
)
{
if
(!
isGlobalProxy
)
{
if
(
apps
==
null
||
apps
.
length
<=
0
)
apps
=
AppManager
.
getProxiedApps
(
this
)
if
(
apps
==
null
||
apps
.
length
<=
0
)
apps
=
AppManager
.
getProxiedApps
(
this
)
...
@@ -439,9 +510,14 @@ class ShadowsocksService extends Service {
...
@@ -439,9 +510,14 @@ class ShadowsocksService extends Service {
}
}
for
(
uid
<-
uidSet
)
{
for
(
uid
<-
uidSet
)
{
if
(!
isBypassApps
)
{
if
(!
isBypassApps
)
{
http_sb
.
append
((
if
(
hasRedirectSupport
)
Utils
.
getIptables
+
CMD_IPTABLES_REDIRECT_ADD_SOCKS
else
Utils
.
getIptables
+
CMD_IPTABLES_DNAT_ADD_SOCKS
).
replace
(
"-t nat"
,
"-t nat -m owner --uid-owner "
+
uid
))
http_sb
}
.
append
((
if
(
hasRedirectSupport
)
{
else
{
Utils
.
getIptables
+
CMD_IPTABLES_REDIRECT_ADD_SOCKS
}
else
{
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
))
init_sb
.
append
(
cmd_bypass
.
replace
(
"-d 0.0.0.0"
,
"-m owner --uid-owner "
+
uid
))
}
}
}
}
...
@@ -478,8 +554,7 @@ class ShadowsocksService extends Service {
...
@@ -478,8 +554,7 @@ class ShadowsocksService extends Service {
mStopForegroundArgs
(
0
)
=
boolean2Boolean
(
x
=
true
)
mStopForegroundArgs
(
0
)
=
boolean2Boolean
(
x
=
true
)
try
{
try
{
mStopForeground
.
invoke
(
this
,
mStopForegroundArgs
:
_
*
)
mStopForeground
.
invoke
(
this
,
mStopForegroundArgs
:
_
*
)
}
}
catch
{
catch
{
case
e
:
InvocationTargetException
=>
{
case
e
:
InvocationTargetException
=>
{
Log
.
w
(
TAG
,
"Unable to invoke stopForeground"
,
e
)
Log
.
w
(
TAG
,
"Unable to invoke stopForeground"
,
e
)
}
}
...
@@ -501,7 +576,9 @@ class ShadowsocksService extends Service {
...
@@ -501,7 +576,9 @@ class ShadowsocksService extends Service {
case
MSG_CONNECT_START
=>
case
MSG_CONNECT_START
=>
ed
.
putBoolean
(
"isConnecting"
,
true
)
ed
.
putBoolean
(
"isConnecting"
,
true
)
val
pm
:
PowerManager
=
getSystemService
(
Context
.
POWER_SERVICE
).
asInstanceOf
[
PowerManager
]
val
pm
:
PowerManager
=
getSystemService
(
Context
.
POWER_SERVICE
).
asInstanceOf
[
PowerManager
]
mWakeLock
=
pm
.
newWakeLock
(
PowerManager
.
SCREEN_DIM_WAKE_LOCK
|
PowerManager
.
ON_AFTER_RELEASE
,
"GAEProxy"
)
mWakeLock
=
pm
.
newWakeLock
(
PowerManager
.
SCREEN_DIM_WAKE_LOCK
|
PowerManager
.
ON_AFTER_RELEASE
,
"GAEProxy"
)
mWakeLock
.
acquire
()
mWakeLock
.
acquire
()
case
MSG_CONNECT_FINISH
=>
case
MSG_CONNECT_FINISH
=>
ed
.
putBoolean
(
"isConnecting"
,
false
)
ed
.
putBoolean
(
"isConnecting"
,
false
)
...
@@ -519,46 +596,4 @@ class ShadowsocksService extends Service {
...
@@ -519,46 +596,4 @@ class ShadowsocksService extends Service {
super
.
handleMessage
(
msg
)
super
.
handleMessage
(
msg
)
}
}
}
}
val
TAG
=
"ShadowsocksService"
val
BASE
=
"/data/data/com.github.shadowsocks/"
val
REDSOCKS_CONF
=
"base {"
+
" log_debug = off;"
+
" log_info = off;"
+
" log = stderr;"
+
" daemon = on;"
+
" redirector = iptables;"
+
"}"
+
"redsocks {"
+
" local_ip = 127.0.0.1;"
+
" local_port = 8123;"
+
" ip = 127.0.0.1;"
+
" port = %d;"
+
" type = socks5;"
+
"}"
val
SHADOWSOCKS_CONF
=
"{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}"
val
CMD_IPTABLES_RETURN
=
" -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN\n"
val
CMD_IPTABLES_REDIRECT_ADD_SOCKS
=
" -t nat -A OUTPUT -p tcp "
+
"-j REDIRECT --to 8123\n"
val
CMD_IPTABLES_DNAT_ADD_SOCKS
=
" -t nat -A OUTPUT -p tcp "
+
"-j DNAT --to-destination 127.0.0.1:8123\n"
val
MSG_CONNECT_START
:
Int
=
0
val
MSG_CONNECT_FINISH
:
Int
=
1
val
MSG_CONNECT_SUCCESS
:
Int
=
2
val
MSG_CONNECT_FAIL
:
Int
=
3
val
MSG_HOST_CHANGE
:
Int
=
4
val
MSG_STOP_SELF
:
Int
=
5
val
DNS_PORT
:
Int
=
8153
val
mStartForegroundSignature
=
Array
[
Class
[
_
]](
classOf
[
Int
],
classOf
[
Notification
])
val
mStopForegroundSignature
=
Array
[
Class
[
_
]](
classOf
[
Boolean
])
val
mSetForegroundSignature
=
Array
[
Class
[
_
]](
classOf
[
Boolean
])
var
receiver
:
BroadcastReceiver
=
null
var
notificationManager
:
NotificationManager
=
null
var
mWakeLock
:
PowerManager
#
WakeLock
=
null
var
appHost
:
String
=
null
var
remotePort
:
Int
=
0
var
localPort
:
Int
=
0
var
sitekey
:
String
=
null
var
settings
:
SharedPreferences
=
null
var
hasRedirectSupport
:
Boolean
=
true
var
isGlobalProxy
:
Boolean
=
false
var
isGFWList
:
Boolean
=
false
var
isBypassApps
:
Boolean
=
false
var
isDNSProxy
:
Boolean
=
false
var
isHTTPProxy
:
Boolean
=
false
var
encMethod
:
String
=
null
var
apps
:
Array
[
ProxiedApp
]
=
null
var
mSetForeground
:
Method
=
null
var
mStartForeground
:
Method
=
null
var
mStopForeground
:
Method
=
null
var
mSetForegroundArgs
=
new
Array
[
AnyRef
](
1
)
var
mStartForegroundArgs
=
new
Array
[
AnyRef
](
2
)
var
mStopForegroundArgs
=
new
Array
[
AnyRef
](
1
)
}
}
\ No newline at end of file
src/main/scala/com/github/shadowsocks/Utils.scala
View file @
f40fb626
...
@@ -53,6 +53,27 @@ import android.graphics.{Canvas, Bitmap}
...
@@ -53,6 +53,27 @@ import android.graphics.{Canvas, Bitmap}
object
Utils
{
object
Utils
{
val
CLOSE_ACTION
=
"com.github.shadowsocks.ACTION_SHUTDOWN"
val
TAG
:
String
=
"Shadowsocks"
val
ABI_PROP
:
String
=
"ro.product.cpu.abi"
val
ABI2_PROP
:
String
=
"ro.product.cpu.abi2"
val
ARM_ABI
:
String
=
"arm"
val
X86_ABI
:
String
=
"x86"
val
MIPS_ABI
:
String
=
"mips"
val
DEFAULT_SHELL
:
String
=
"/system/bin/sh"
val
DEFAULT_ROOT
:
String
=
"/system/bin/su"
val
ALTERNATIVE_ROOT
:
String
=
"/system/xbin/su"
val
DEFAULT_IPTABLES
:
String
=
"/data/data/com.github.shadowsocks/iptables"
val
ALTERNATIVE_IPTABLES
:
String
=
"/system/bin/iptables"
val
TIME_OUT
:
Int
=
-
99
var
initialized
:
Boolean
=
false
var
hasRedirectSupport
:
Int
=
-
1
var
isRoot
:
Int
=
-
1
var
shell
:
String
=
null
var
root_shell
:
String
=
null
var
iptables
:
String
=
null
var
data_path
:
String
=
null
var
rootTries
=
0
def
resolve
(
host
:
String
,
addrType
:
Int
)
:
Option
[
String
]
=
{
def
resolve
(
host
:
String
,
addrType
:
Int
)
:
Option
[
String
]
=
{
val
lookup
=
new
Lookup
(
host
,
addrType
)
val
lookup
=
new
Lookup
(
host
,
addrType
)
...
@@ -124,8 +145,7 @@ object Utils {
...
@@ -124,8 +145,7 @@ object Utils {
}
}
}
}
}
}
}
}
catch
{
catch
{
case
ex
:
Exception
=>
{
case
ex
:
Exception
=>
{
Log
.
e
(
TAG
,
"Failed to get interfaces' addresses."
,
ex
)
Log
.
e
(
TAG
,
"Failed to get interfaces' addresses."
,
ex
)
}
}
...
@@ -153,8 +173,7 @@ object Utils {
...
@@ -153,8 +173,7 @@ object Utils {
}
}
}
}
}
}
}
}
catch
{
catch
{
case
ex
:
Exception
=>
{
case
ex
:
Exception
=>
{
Log
.
e
(
TAG
,
"Failed to get interfaces' addresses."
,
ex
)
Log
.
e
(
TAG
,
"Failed to get interfaces' addresses."
,
ex
)
}
}
...
@@ -189,19 +208,16 @@ object Utils {
...
@@ -189,19 +208,16 @@ object Utils {
input
=
new
BufferedReader
(
new
InputStreamReader
(
p
.
getInputStream
),
1024
)
input
=
new
BufferedReader
(
new
InputStreamReader
(
p
.
getInputStream
),
1024
)
line
=
input
.
readLine
line
=
input
.
readLine
input
.
close
()
input
.
close
()
}
}
catch
{
catch
{
case
ex
:
IOException
=>
{
case
ex
:
IOException
=>
{
Log
.
e
(
TAG
,
"Unable to read sysprop "
+
propName
,
ex
)
Log
.
e
(
TAG
,
"Unable to read sysprop "
+
propName
,
ex
)
return
null
return
null
}
}
}
}
finally
{
finally
{
if
(
input
!=
null
)
{
if
(
input
!=
null
)
{
try
{
try
{
input
.
close
()
input
.
close
()
}
}
catch
{
catch
{
case
ex
:
IOException
=>
{
case
ex
:
IOException
=>
{
Log
.
e
(
TAG
,
"Exception while closing InputStream"
,
ex
)
Log
.
e
(
TAG
,
"Exception while closing InputStream"
,
ex
)
}
}
...
@@ -246,7 +262,7 @@ object Utils {
...
@@ -246,7 +262,7 @@ object Utils {
}
}
}
}
def
drawableToBitmap
(
drawable
:
Drawable
)
:
Bitmap
=
{
def
drawableToBitmap
(
drawable
:
Drawable
)
:
Bitmap
=
{
if
(
drawable
.
isInstanceOf
[
BitmapDrawable
])
{
if
(
drawable
.
isInstanceOf
[
BitmapDrawable
])
{
return
drawable
.
asInstanceOf
[
BitmapDrawable
].
getBitmap
return
drawable
.
asInstanceOf
[
BitmapDrawable
].
getBitmap
}
}
...
@@ -271,15 +287,13 @@ object Utils {
...
@@ -271,15 +287,13 @@ object Utils {
try
{
try
{
val
appInfo
:
ApplicationInfo
=
pm
.
getApplicationInfo
(
packages
(
0
),
0
)
val
appInfo
:
ApplicationInfo
=
pm
.
getApplicationInfo
(
packages
(
0
),
0
)
appIcon
=
pm
.
getApplicationIcon
(
appInfo
)
appIcon
=
pm
.
getApplicationIcon
(
appInfo
)
}
}
catch
{
catch
{
case
e
:
PackageManager.NameNotFoundException
=>
{
case
e
:
PackageManager.NameNotFoundException
=>
{
Log
.
e
(
c
.
getPackageName
,
"No package found matching with the uid "
+
uid
)
Log
.
e
(
c
.
getPackageName
,
"No package found matching with the uid "
+
uid
)
}
}
}
}
}
}
}
}
else
{
else
{
Log
.
e
(
c
.
getPackageName
,
"Package not found for uid "
+
uid
)
Log
.
e
(
c
.
getPackageName
,
"Package not found for uid "
+
uid
)
}
}
appIcon
appIcon
...
@@ -289,8 +303,7 @@ object Utils {
...
@@ -289,8 +303,7 @@ object Utils {
if
(
data_path
==
null
)
{
if
(
data_path
==
null
)
{
if
(
Environment
.
MEDIA_MOUNTED
==
Environment
.
getExternalStorageState
)
{
if
(
Environment
.
MEDIA_MOUNTED
==
Environment
.
getExternalStorageState
)
{
data_path
=
Environment
.
getExternalStorageDirectory
.
getAbsolutePath
data_path
=
Environment
.
getExternalStorageDirectory
.
getAbsolutePath
}
}
else
{
else
{
data_path
=
ctx
.
getFilesDir
.
getAbsolutePath
data_path
=
ctx
.
getFilesDir
.
getAbsolutePath
}
}
Log
.
d
(
TAG
,
"Python Data Path: "
+
data_path
)
Log
.
d
(
TAG
,
"Python Data Path: "
+
data_path
)
...
@@ -346,11 +359,9 @@ object Utils {
...
@@ -346,11 +359,9 @@ object Utils {
if
(
isRoot
!=
-
1
)
return
isRoot
==
1
if
(
isRoot
!=
-
1
)
return
isRoot
==
1
if
(
new
File
(
DEFAULT_ROOT
).
exists
)
{
if
(
new
File
(
DEFAULT_ROOT
).
exists
)
{
root_shell
=
DEFAULT_ROOT
root_shell
=
DEFAULT_ROOT
}
}
else
if
(
new
File
(
ALTERNATIVE_ROOT
).
exists
)
{
else
if
(
new
File
(
ALTERNATIVE_ROOT
).
exists
)
{
root_shell
=
ALTERNATIVE_ROOT
root_shell
=
ALTERNATIVE_ROOT
}
}
else
{
else
{
root_shell
=
"su"
root_shell
=
"su"
}
}
val
sb
=
new
StringBuilder
val
sb
=
new
StringBuilder
...
@@ -399,8 +410,7 @@ object Utils {
...
@@ -399,8 +410,7 @@ object Utils {
try
{
try
{
if
(
timeout
>
0
)
{
if
(
timeout
>
0
)
{
runner
.
join
(
timeout
)
runner
.
join
(
timeout
)
}
}
else
{
else
{
runner
.
join
()
runner
.
join
()
}
}
if
(
runner
.
isAlive
)
{
if
(
runner
.
isAlive
)
{
...
@@ -408,8 +418,7 @@ object Utils {
...
@@ -408,8 +418,7 @@ object Utils {
runner
.
join
(
1000
)
runner
.
join
(
1000
)
return
TIME_OUT
return
TIME_OUT
}
}
}
}
catch
{
catch
{
case
ex
:
InterruptedException
=>
{
case
ex
:
InterruptedException
=>
{
return
TIME_OUT
return
TIME_OUT
}
}
...
@@ -417,28 +426,6 @@ object Utils {
...
@@ -417,28 +426,6 @@ object Utils {
runner
.
exitcode
runner
.
exitcode
}
}
val
CLOSE_ACTION
=
"com.github.shadowsocks.ACTION_SHUTDOWN"
val
TAG
:
String
=
"Shadowsocks"
val
ABI_PROP
:
String
=
"ro.product.cpu.abi"
val
ABI2_PROP
:
String
=
"ro.product.cpu.abi2"
val
ARM_ABI
:
String
=
"arm"
val
X86_ABI
:
String
=
"x86"
val
MIPS_ABI
:
String
=
"mips"
val
DEFAULT_SHELL
:
String
=
"/system/bin/sh"
val
DEFAULT_ROOT
:
String
=
"/system/bin/su"
val
ALTERNATIVE_ROOT
:
String
=
"/system/xbin/su"
val
DEFAULT_IPTABLES
:
String
=
"/data/data/com.github.shadowsocks/iptables"
val
ALTERNATIVE_IPTABLES
:
String
=
"/system/bin/iptables"
val
TIME_OUT
:
Int
=
-
99
var
initialized
:
Boolean
=
false
var
hasRedirectSupport
:
Int
=
-
1
var
isRoot
:
Int
=
-
1
var
shell
:
String
=
null
var
root_shell
:
String
=
null
var
iptables
:
String
=
null
var
data_path
:
String
=
null
var
rootTries
=
0
/**
/**
* Internal thread used to execute scripts (as root or not).
* Internal thread used to execute scripts (as root or not).
* Creates a new script runner.
* Creates a new script runner.
...
@@ -447,9 +434,13 @@ object Utils {
...
@@ -447,9 +434,13 @@ object Utils {
* @param result result output
* @param result result output
* @param asroot if true, executes the script as root
* @param asroot if true, executes the script as root
*/
*/
class
ScriptRunner
(
val
scripts
:
String
,
class
ScriptRunner
(
val
scripts
:
String
,
val
result
:
StringBuilder
,
val
asroot
:
Boolean
)
val
result
:
StringBuilder
,
extends
Thread
{
val
asroot
:
Boolean
)
extends
Thread
{
var
exitcode
:
Int
=
-
1
val
pid
:
Array
[
Int
]
=
new
Array
[
Int
](
1
)
var
pipe
:
FileDescriptor
=
null
override
def
destroy
()
{
override
def
destroy
()
{
if
(
pid
(
0
)
!=
-
1
)
{
if
(
pid
(
0
)
!=
-
1
)
{
Exec
.
hangupProcessGroup
(
pid
(
0
))
Exec
.
hangupProcessGroup
(
pid
(
0
))
...
@@ -464,7 +455,9 @@ object Utils {
...
@@ -464,7 +455,9 @@ object Utils {
def
createSubprocess
(
processId
:
Array
[
Int
],
cmd
:
String
)
:
FileDescriptor
=
{
def
createSubprocess
(
processId
:
Array
[
Int
],
cmd
:
String
)
:
FileDescriptor
=
{
val
args
=
parse
(
cmd
)
val
args
=
parse
(
cmd
)
val
arg0
=
args
(
0
)
val
arg0
=
args
(
0
)
Exec
.
createSubprocess
(
if
(
result
!=
null
)
1
else
0
,
arg0
,
args
,
null
,
scripts
+
"\nexit\n"
,
processId
)
Exec
.
createSubprocess
(
if
(
result
!=
null
)
1
else
0
,
arg0
,
args
,
null
,
scripts
+
"\nexit\n"
,
processId
)
}
}
def
parse
(
cmd
:
String
)
:
Array
[
String
]
=
{
def
parse
(
cmd
:
String
)
:
Array
[
String
]
=
{
...
@@ -515,8 +508,7 @@ object Utils {
...
@@ -515,8 +508,7 @@ object Utils {
try
{
try
{
if
(
this
.
asroot
)
{
if
(
this
.
asroot
)
{
pipe
=
createSubprocess
(
pid
,
root_shell
)
pipe
=
createSubprocess
(
pid
,
root_shell
)
}
}
else
{
else
{
pipe
=
createSubprocess
(
pid
,
getShell
)
pipe
=
createSubprocess
(
pid
,
getShell
)
}
}
if
(
pid
(
0
)
!=
-
1
)
{
if
(
pid
(
0
)
!=
-
1
)
{
...
@@ -530,14 +522,12 @@ object Utils {
...
@@ -530,14 +522,12 @@ object Utils {
read
=
stdout
.
read
(
buf
)
read
=
stdout
.
read
(
buf
)
result
.
append
(
new
String
(
buf
,
0
,
read
))
result
.
append
(
new
String
(
buf
,
0
,
read
))
}
}
}
}
catch
{
catch
{
case
ex
:
Exception
=>
{
case
ex
:
Exception
=>
{
Log
.
e
(
TAG
,
"Cannot execute command"
,
ex
)
Log
.
e
(
TAG
,
"Cannot execute command"
,
ex
)
if
(
result
!=
null
)
result
.
append
(
"\n"
).
append
(
ex
)
if
(
result
!=
null
)
result
.
append
(
"\n"
).
append
(
ex
)
}
}
}
}
finally
{
finally
{
if
(
pipe
!=
null
)
{
if
(
pipe
!=
null
)
{
Exec
.
close
(
pipe
)
Exec
.
close
(
pipe
)
}
}
...
@@ -546,10 +536,6 @@ object Utils {
...
@@ -546,10 +536,6 @@ object Utils {
}
}
}
}
}
}
var
exitcode
:
Int
=
-
1
val
pid
:
Array
[
Int
]
=
new
Array
[
Int
](
1
)
var
pipe
:
FileDescriptor
=
null
}
}
}
}
\ No newline at end of file
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