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
a755b669
Commit
a755b669
authored
Feb 04, 2018
by
Mygod
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix code style issues
parent
9fb18095
Changes
30
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
145 additions
and
178 deletions
+145
-178
README.md
README.md
+1
-0
core/gfwlist/gen.py
core/gfwlist/gen.py
+0
-2
detekt.yml
detekt.yml
+1
-2
mobile/src/main/java/com/github/shadowsocks/AppManager.kt
mobile/src/main/java/com/github/shadowsocks/AppManager.kt
+3
-6
mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt
...om/github/shadowsocks/GlobalSettingsPreferenceFragment.kt
+0
-1
mobile/src/main/java/com/github/shadowsocks/MainActivity.kt
mobile/src/main/java/com/github/shadowsocks/MainActivity.kt
+3
-2
mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt
...main/java/com/github/shadowsocks/ProfileConfigFragment.kt
+18
-20
mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt
.../src/main/java/com/github/shadowsocks/ProfilesFragment.kt
+1
-4
mobile/src/main/java/com/github/shadowsocks/ScannerActivity.kt
...e/src/main/java/com/github/shadowsocks/ScannerActivity.kt
+22
-24
mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt
...in/java/com/github/shadowsocks/acl/CustomRulesFragment.kt
+9
-11
mobile/src/main/java/com/github/shadowsocks/bg/BaseService.kt
...le/src/main/java/com/github/shadowsocks/bg/BaseService.kt
+10
-11
mobile/src/main/java/com/github/shadowsocks/bg/Dns.kt
mobile/src/main/java/com/github/shadowsocks/bg/Dns.kt
+6
-9
mobile/src/main/java/com/github/shadowsocks/bg/LocalDnsService.kt
...rc/main/java/com/github/shadowsocks/bg/LocalDnsService.kt
+2
-3
mobile/src/main/java/com/github/shadowsocks/bg/ProxyService.kt
...e/src/main/java/com/github/shadowsocks/bg/ProxyService.kt
+0
-1
mobile/src/main/java/com/github/shadowsocks/bg/TrafficMonitor.kt
...src/main/java/com/github/shadowsocks/bg/TrafficMonitor.kt
+1
-1
mobile/src/main/java/com/github/shadowsocks/bg/TrafficMonitorThread.kt
...in/java/com/github/shadowsocks/bg/TrafficMonitorThread.kt
+1
-1
mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt
mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt
+10
-3
mobile/src/main/java/com/github/shadowsocks/database/PrivateDatabase.kt
...n/java/com/github/shadowsocks/database/PrivateDatabase.kt
+4
-4
mobile/src/main/java/com/github/shadowsocks/database/Profile.kt
.../src/main/java/com/github/shadowsocks/database/Profile.kt
+1
-0
mobile/src/main/java/com/github/shadowsocks/database/ProfileManager.kt
...in/java/com/github/shadowsocks/database/ProfileManager.kt
+29
-39
mobile/src/main/java/com/github/shadowsocks/preference/DataStore.kt
.../main/java/com/github/shadowsocks/preference/DataStore.kt
+1
-1
mobile/src/main/java/com/github/shadowsocks/preference/IconListPreference.kt
...a/com/github/shadowsocks/preference/IconListPreference.kt
+3
-7
mobile/src/main/java/com/github/shadowsocks/tasker/ConfigActivity.kt
...main/java/com/github/shadowsocks/tasker/ConfigActivity.kt
+3
-3
mobile/src/main/java/com/github/shadowsocks/tasker/Settings.kt
...e/src/main/java/com/github/shadowsocks/tasker/Settings.kt
+2
-2
mobile/src/main/java/com/github/shadowsocks/utils/Commandline.kt
...src/main/java/com/github/shadowsocks/utils/Commandline.kt
+2
-6
mobile/src/main/java/com/github/shadowsocks/utils/DirectBoot.kt
.../src/main/java/com/github/shadowsocks/utils/DirectBoot.kt
+2
-2
mobile/src/main/java/com/github/shadowsocks/utils/Utils.kt
mobile/src/main/java/com/github/shadowsocks/utils/Utils.kt
+3
-3
mobile/src/main/java/com/github/shadowsocks/widget/ServiceButton.kt
.../main/java/com/github/shadowsocks/widget/ServiceButton.kt
+0
-1
plugin/src/main/java/com/github/shadowsocks/plugin/NativePluginProvider.kt
...ava/com/github/shadowsocks/plugin/NativePluginProvider.kt
+2
-2
plugin/src/main/java/com/github/shadowsocks/plugin/OptionsCapableActivity.kt
...a/com/github/shadowsocks/plugin/OptionsCapableActivity.kt
+5
-7
No files found.
README.md
View file @
a755b669
...
...
@@ -3,6 +3,7 @@
[

](https://travis-ci.org/shadowsocks/shadowsocks-android)
[

](https://android-arsenal.com/api?level=21)
[

](https://github.com/shadowsocks/shadowsocks-android/releases)
[

](https://www.codacy.com/app/shadowsocks/shadowsocks-android?utm_source=github.com
&
utm_medium=referral
&
utm_content=shadowsocks/shadowsocks-android
&
utm_campaign=Badge_Grade)
[

](https://www.gnu.org/licenses/gpl-3.0)
A
[
shadowsocks
](
http://shadowsocks.org
)
client for Android, written in Kotlin.
...
...
core/gfwlist/gen.py
View file @
a755b669
#!/usr/bin/python
# -*- encoding: utf8 -*-
import
itertools
import
math
import
sys
import
IPy
...
...
detekt.yml
View file @
a755b669
...
...
@@ -28,8 +28,7 @@ complexity:
threshold
:
5
ignoreDefaultParameters
:
true
MethodOverloading
:
active
:
true
threshold
:
5
active
:
false
NestedBlockDepth
:
active
:
true
threshold
:
3
...
...
mobile/src/main/java/com/github/shadowsocks/AppManager.kt
View file @
a755b669
...
...
@@ -44,7 +44,6 @@ import android.support.v7.widget.Toolbar
import
android.view.*
import
android.widget.ImageView
import
android.widget.Switch
import
android.widget.Toast
import
com.futuremind.recyclerviewfastscroll.FastScroller
import
com.futuremind.recyclerviewfastscroll.SectionTitleProvider
import
com.github.shadowsocks.App.Companion.app
...
...
@@ -264,11 +263,9 @@ class AppManager : AppCompatActivity(), Toolbar.OnMenuItemClickListener {
return
false
}
override
fun
onKeyUp
(
keyCode
:
Int
,
event
:
KeyEvent
?):
Boolean
{
return
if
(
keyCode
==
KeyEvent
.
KEYCODE_MENU
)
override
fun
onKeyUp
(
keyCode
:
Int
,
event
:
KeyEvent
?)
=
if
(
keyCode
==
KeyEvent
.
KEYCODE_MENU
)
if
(
toolbar
.
isOverflowMenuShowing
)
toolbar
.
hideOverflowMenu
()
else
toolbar
.
showOverflowMenu
()
else
super
.
onKeyUp
(
keyCode
,
event
)
}
override
fun
onDestroy
()
{
instance
=
null
...
...
mobile/src/main/java/com/github/shadowsocks/GlobalSettingsPreferenceFragment.kt
View file @
a755b669
...
...
@@ -26,7 +26,6 @@ import android.os.Bundle
import
android.support.design.widget.Snackbar
import
android.support.v14.preference.SwitchPreference
import
android.support.v7.preference.Preference
import
com.github.shadowsocks.App.Companion.app
import
com.github.shadowsocks.bg.BaseService
import
com.github.shadowsocks.preference.DataStore
import
com.github.shadowsocks.utils.DirectBoot
...
...
mobile/src/main/java/com/github/shadowsocks/MainActivity.kt
View file @
a755b669
...
...
@@ -62,6 +62,7 @@ import com.mikepenz.materialdrawer.Drawer
import
com.mikepenz.materialdrawer.DrawerBuilder
import
com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import
com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
import
java.io.IOException
import
java.net.HttpURLConnection
import
java.net.InetSocketAddress
import
java.net.Proxy
...
...
@@ -178,8 +179,8 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Interface, Drawe
val
elapsed
=
SystemClock
.
elapsedRealtime
()
-
start
if
(
code
==
204
||
code
==
200
&&
conn
.
responseLength
==
0L
)
Pair
(
true
,
getString
(
R
.
string
.
connection_test_available
,
elapsed
))
else
throw
Exception
(
getString
(
R
.
string
.
connection_test_error_status_code
,
code
))
}
catch
(
e
:
Exception
)
{
else
throw
IO
Exception
(
getString
(
R
.
string
.
connection_test_error_status_code
,
code
))
}
catch
(
e
:
IO
Exception
)
{
Pair
(
false
,
getString
(
R
.
string
.
connection_test_error
,
e
.
message
))
}
finally
{
conn
.
disconnect
()
...
...
mobile/src/main/java/com/github/shadowsocks/ProfileConfigFragment.kt
View file @
a755b669
...
...
@@ -179,8 +179,7 @@ class ProfileConfigFragment : PreferenceFragmentCompatDividers(), Toolbar.OnMenu
}
else
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
)
}
override
fun
onMenuItemClick
(
item
:
MenuItem
):
Boolean
{
return
when
(
item
.
itemId
)
{
override
fun
onMenuItemClick
(
item
:
MenuItem
)
=
when
(
item
.
itemId
)
{
R
.
id
.
action_delete
->
{
val
activity
=
activity
!!
AlertDialog
.
Builder
(
activity
)
...
...
@@ -200,7 +199,6 @@ class ProfileConfigFragment : PreferenceFragmentCompatDividers(), Toolbar.OnMenu
}
else
->
false
}
}
override
fun
onDestroy
()
{
DataStore
.
privateStore
.
unregisterChangeListener
(
this
)
...
...
mobile/src/main/java/com/github/shadowsocks/ProfilesFragment.kt
View file @
a755b669
...
...
@@ -37,7 +37,6 @@ import android.view.*
import
android.widget.ImageView
import
android.widget.LinearLayout
import
android.widget.TextView
import
android.widget.Toast
import
com.github.shadowsocks.App.Companion.app
import
com.github.shadowsocks.bg.BaseService
import
com.github.shadowsocks.bg.TrafficMonitor
...
...
@@ -374,9 +373,7 @@ class ProfilesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener {
Snackbar
.
LENGTH_LONG
).
show
()
return
true
}
}
catch
(
exc
:
Exception
)
{
app
.
track
(
exc
)
}
}
catch
(
_
:
IndexOutOfBoundsException
)
{
}
Snackbar
.
make
(
activity
!!
.
findViewById
(
R
.
id
.
snackbar
),
R
.
string
.
action_import_err
,
Snackbar
.
LENGTH_LONG
)
.
show
()
true
...
...
mobile/src/main/java/com/github/shadowsocks/ScannerActivity.kt
View file @
a755b669
...
...
@@ -139,8 +139,7 @@ class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler, Too
.
putExtra
(
Intent
.
EXTRA_ALLOW_MULTIPLE
,
true
),
if
(
manual
)
REQUEST_IMPORT
else
REQUEST_IMPORT_OR_FINISH
)
override
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
data
:
Intent
?)
{
when
(
requestCode
)
{
REQUEST_IMPORT
,
REQUEST_IMPORT_OR_FINISH
->
{
if
(
resultCode
==
Activity
.
RESULT_OK
)
{
REQUEST_IMPORT
,
REQUEST_IMPORT_OR_FINISH
->
if
(
resultCode
==
Activity
.
RESULT_OK
)
{
var
list
=
listOfNotNull
(
data
?.
data
)
val
clipData
=
data
?.
clipData
if
(
clipData
!=
null
)
list
+=
(
0
until
clipData
.
itemCount
).
map
{
clipData
.
getItemAt
(
it
).
uri
}
...
...
@@ -163,7 +162,6 @@ class ScannerActivity : AppCompatActivity(), ZXingScannerView.ResultHandler, Too
Toast
.
LENGTH_SHORT
).
show
()
finish
()
}
else
if
(
requestCode
==
REQUEST_IMPORT_OR_FINISH
)
finish
()
}
else
->
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
)
}
}
...
...
mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt
View file @
a755b669
...
...
@@ -124,7 +124,7 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
override
fun
beforeTextChanged
(
s
:
CharSequence
?,
start
:
Int
,
count
:
Int
,
after
:
Int
)
{
}
override
fun
onTextChanged
(
s
:
CharSequence
?,
start
:
Int
,
before
:
Int
,
count
:
Int
)
{
}
override
fun
afterTextChanged
(
s
:
Editable
)
=
validate
(
value
=
s
)
override
fun
onNothingSelected
(
parent
:
AdapterView
<
*
>?)
=
throw
IllegalStateException
(
)
override
fun
onNothingSelected
(
parent
:
AdapterView
<
*
>?)
=
check
(
false
)
override
fun
onItemSelected
(
parent
:
AdapterView
<
*
>?,
view
:
View
?,
position
:
Int
,
id
:
Long
)
=
validate
(
position
)
private
fun
validate
(
template
:
Int
=
templateSelector
.
selectedItemPosition
,
value
:
Editable
=
editText
.
text
)
{
...
...
@@ -228,16 +228,14 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
override
fun
getItemCount
():
Int
=
acl
.
subnets
.
size
()
+
acl
.
hostnames
.
size
()
+
acl
.
urls
.
size
()
override
fun
getSectionTitle
(
i
:
Int
):
String
{
val
j
=
i
-
acl
.
subnets
.
size
()
return
try
{
(
if
(
j
<
0
)
acl
.
subnets
[
i
].
address
.
hostAddress
.
substring
(
0
,
1
)
else
{
return
(
if
(
j
<
0
)
acl
.
subnets
[
i
].
address
.
hostAddress
.
substring
(
0
,
1
)
else
{
val
k
=
j
-
acl
.
hostnames
.
size
()
if
(
k
<
0
)
{
val
hostname
=
acl
.
hostnames
[
j
]
// don't convert IDN yet
PATTERN_DOMAIN
.
find
(
hostname
)
?.
value
?.
replace
(
"\\."
,
"."
)
?:
hostname
}
else
acl
.
urls
[
k
].
host
}).
substring
(
0
,
1
)
}
catch
(
_
:
IndexOutOfBoundsException
)
{
" "
}
}).
firstOrNull
()
?.
toString
()
?:
" "
}
private
fun
apply
()
{
...
...
mobile/src/main/java/com/github/shadowsocks/bg/BaseService.kt
View file @
a755b669
...
...
@@ -31,7 +31,6 @@ import android.os.RemoteCallbackList
import
android.support.v4.os.UserManagerCompat
import
android.util.Base64
import
android.util.Log
import
android.widget.Toast
import
com.github.shadowsocks.App.Companion.app
import
com.github.shadowsocks.R
import
com.github.shadowsocks.acl.Acl
...
...
@@ -146,18 +145,18 @@ object BaseService {
}
internal
fun
updateTrafficTotal
(
tx
:
Long
,
rx
:
Long
)
{
val
profile
=
profile
?:
return
val
p
=
ProfileManager
.
getProfile
(
profile
.
id
)
?:
return
// profile may have host, etc. modified
p
.
tx
+=
tx
p
.
rx
+=
rx
ProfileManager
.
updateProfile
(
p
)
// this.profile may have host, etc. modified and thus a re-fetch is necessary (possible race condition)
val
p
rofile
=
ProfileManager
.
getProfile
((
profile
?:
return
).
id
)
?:
return
p
rofile
.
tx
+=
tx
p
rofile
.
rx
+=
rx
ProfileManager
.
updateProfile
(
p
rofile
)
app
.
handler
.
post
{
if
(
bandwidthListeners
.
isNotEmpty
())
{
val
n
=
callbacks
.
beginBroadcast
()
for
(
i
in
0
until
n
)
{
try
{
val
item
=
callbacks
.
getBroadcastItem
(
i
)
if
(
bandwidthListeners
.
contains
(
item
.
asBinder
()))
item
.
trafficPersisted
(
p
.
id
)
if
(
bandwidthListeners
.
contains
(
item
.
asBinder
()))
item
.
trafficPersisted
(
p
rofile
.
id
)
}
catch
(
_
:
Exception
)
{
}
// ignore
}
callbacks
.
finishBroadcast
()
...
...
@@ -182,9 +181,9 @@ object BaseService {
.
put
(
"plugin_opts"
,
plugin
.
toString
())
}
// sensitive Shadowsocks config is stored in
val
file
=
File
(
(
if
(
UserManagerCompat
.
isUserUnlocked
(
app
))
app
.
filesDir
else
@TargetApi
(
24
)
{
val
file
=
File
(
if
(
UserManagerCompat
.
isUserUnlocked
(
app
))
app
.
filesDir
else
@TargetApi
(
24
)
{
app
.
deviceContext
.
noBackupFilesDir
// only API 24+ will be in locked state
}
)
,
CONFIG_FILE
)
},
CONFIG_FILE
)
shadowsocksConfigFile
=
file
file
.
writeText
(
config
.
toString
())
return
file
...
...
@@ -218,9 +217,9 @@ object BaseService {
false
}
else
true
fun
forceLoad
()
{
val
p
=
app
.
currentProfile
val
p
rofile
=
app
.
currentProfile
?:
return
stopRunner
(
true
,
(
this
as
Context
).
getString
(
R
.
string
.
profile_empty
))
if
(!
checkProfile
(
p
))
return
if
(!
checkProfile
(
p
rofile
))
return
val
s
=
data
.
state
when
(
s
)
{
STOPPED
->
startRunner
()
...
...
mobile/src/main/java/com/github/shadowsocks/bg/Dns.kt
View file @
a755b669
...
...
@@ -24,22 +24,19 @@ import android.util.Log
import
com.github.shadowsocks.App.Companion.app
import
com.github.shadowsocks.BuildConfig
import
org.xbill.DNS.*
import
java.net.Inet6Address
import
java.net.InetAddress
import
java.net.NetworkInterface
import
java.net.UnknownHostException
import
okhttp3.Dns
as
Okdns
import
java.io.IOException
import
java.net.*
object
Dns
{
private
const
val
TAG
=
"Dns"
private
val
hasIPv6Support
get
()
=
try
{
val
result
=
NetworkInterface
.
getNetworkInterfaces
().
asSequence
().
flatMap
{
it
.
inetAddresses
.
asSequence
()
}
.
count
{
it
is
Inet6Address
&&
!
it
.
isLoopbackAddress
&&
!
it
.
isLinkLocalAddress
}
>
0
.
any
{
it
is
Inet6Address
&&
!
it
.
isLoopbackAddress
&&
!
it
.
isLinkLocalAddress
}
if
(
result
&&
BuildConfig
.
DEBUG
)
Log
.
d
(
TAG
,
"IPv6 address detected"
)
result
}
catch
(
ex
:
Exception
)
{
Log
.
e
(
TAG
,
"Failed to get interfaces' addresses."
)
}
catch
(
ex
:
Socket
Exception
)
{
Log
.
e
(
TAG
,
"Failed to get interfaces' addresses."
,
ex
)
app
.
track
(
ex
)
false
}
...
...
@@ -60,7 +57,7 @@ object Dns {
Type
.
AAAA
->
return
(
r
as
AAAARecord
).
address
.
hostAddress
}
}
}
catch
(
_
:
Exception
)
{
}
}
catch
(
_
:
IO
Exception
)
{
}
return
null
}
private
fun
resolve
(
host
:
String
):
String
?
=
try
{
...
...
mobile/src/main/java/com/github/shadowsocks/bg/LocalDnsService.kt
View file @
a755b669
...
...
@@ -20,7 +20,6 @@
package
com.github.shadowsocks.bg
import
android.content.Context
import
com.github.shadowsocks.App.Companion.app
import
com.github.shadowsocks.acl.Acl
import
com.github.shadowsocks.preference.DataStore
...
...
@@ -50,10 +49,10 @@ object LocalDnsService {
fun
makeDns
(
name
:
String
,
address
:
String
,
timeout
:
Int
,
edns
:
Boolean
=
true
):
JSONObject
{
val
dns
=
JSONObject
()
.
put
(
"Name"
,
name
)
.
put
(
"Address"
,
(
when
(
address
.
parseNumericAddress
())
{
.
put
(
"Address"
,
when
(
address
.
parseNumericAddress
())
{
is
Inet6Address
->
"[$address]"
else
->
address
})
)
})
.
put
(
"Timeout"
,
timeout
)
.
put
(
"EDNSClientSubnet"
,
JSONObject
().
put
(
"Policy"
,
"disable"
))
if
(
edns
)
dns
...
...
mobile/src/main/java/com/github/shadowsocks/bg/ProxyService.kt
View file @
a755b669
...
...
@@ -23,7 +23,6 @@ package com.github.shadowsocks.bg
import
android.app.Service
import
android.content.Intent
import
android.os.IBinder
import
com.github.shadowsocks.database.Profile
/**
* Shadowsocks service at its minimum.
...
...
mobile/src/main/java/com/github/shadowsocks/bg/TrafficMonitor.kt
View file @
a755b669
...
...
@@ -44,7 +44,7 @@ object TrafficMonitor {
private
val
units
=
arrayOf
(
"KB"
,
"MB"
,
"GB"
,
"TB"
,
"PB"
,
"EB"
,
"ZB"
,
"YB"
,
"BB"
,
"NB"
,
"DB"
,
"CB"
)
private
val
numberFormat
=
DecimalFormat
(
"@@@"
)
fun
formatTraffic
(
size
:
Long
):
String
{
var
n
:
Double
=
size
.
toDouble
()
var
n
=
size
.
toDouble
()
var
i
=
-
1
while
(
n
>=
999.5
)
{
n
/=
1024
...
...
mobile/src/main/java/com/github/shadowsocks/bg/TrafficMonitorThread.kt
View file @
a755b669
...
...
@@ -38,7 +38,7 @@ class TrafficMonitorThread : LocalSocketListener("TrafficMonitorThread") {
val
stat
=
ByteBuffer
.
wrap
(
buffer
).
order
(
ByteOrder
.
LITTLE_ENDIAN
)
TrafficMonitor
.
update
(
stat
.
getLong
(
0
),
stat
.
getLong
(
8
))
socket
.
outputStream
.
write
(
0
)
}
catch
(
e
:
Exception
)
{
}
catch
(
e
:
IO
Exception
)
{
Log
.
e
(
tag
,
"Error when recv traffic stat"
,
e
)
app
.
track
(
e
)
}
...
...
mobile/src/main/java/com/github/shadowsocks/bg/VpnService.kt
View file @
a755b669
...
...
@@ -38,6 +38,7 @@ import com.github.shadowsocks.utils.Subnet
import
com.github.shadowsocks.utils.parseNumericAddress
import
java.io.File
import
java.io.FileDescriptor
import
java.io.IOException
import
java.lang.reflect.Method
import
java.util.*
import
android.net.VpnService
as
BaseVpnService
...
...
@@ -55,18 +56,24 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
override
val
socketFile
:
File
=
File
(
app
.
deviceContext
.
filesDir
,
"protect_path"
)
override
fun
accept
(
socket
:
LocalSocket
)
{
var
success
=
false
try
{
socket
.
inputStream
.
read
()
val
fds
=
socket
.
ancillaryFileDescriptors
if
(
fds
.
isEmpty
())
return
val
fd
=
getInt
.
invoke
(
fds
.
first
())
as
Int
val
ret
=
protect
(
fd
)
success
=
protect
(
fd
)
JniHelper
.
close
(
fd
)
// Trick to close file decriptor
socket
.
outputStream
.
write
(
if
(
ret
)
0
else
1
)
}
catch
(
e
:
Exception
)
{
Log
.
e
(
tag
,
"Error when protect socket"
,
e
)
app
.
track
(
e
)
}
try
{
socket
.
outputStream
.
write
(
if
(
success
)
0
else
1
)
}
catch
(
e
:
IOException
)
{
Log
.
e
(
tag
,
"Error when returning result in protect"
,
e
)
app
.
track
(
e
)
}
}
}
class
NullConnectionException
:
NullPointerException
()
...
...
@@ -118,7 +125,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
super
.
startNativeProcesses
()
val
fd
=
startVpn
()
if
(!
sendFd
(
fd
))
throw
Exception
(
"sendFd failed"
)
if
(!
sendFd
(
fd
))
throw
IO
Exception
(
"sendFd failed"
)
}
override
fun
buildAdditionalArguments
(
cmd
:
ArrayList
<
String
>):
ArrayList
<
String
>
{
...
...
mobile/src/main/java/com/github/shadowsocks/database/PrivateDatabase.kt
View file @
a755b669
...
...
@@ -72,10 +72,10 @@ object PrivateDatabase : OrmLiteSqliteOpenHelper(app, Key.DB_PROFILE, null, 25)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` RENAME TO `tmp`;"
)
TableUtils
.
createTable
(
connectionSource
,
Profile
::
class
.
java
)
profileDao
.
executeRawNoArgs
(
"INSERT INTO `profile`(id, name, host, localPort, remotePort, password, method, route,
proxyApps, bypass,
"
+
" udpdns, ipv6, individual) "
+
"SELECT id, name, host, localPort, remotePort, password, method, route, 1 - global,
bypass, udpdns, ipv6,
"
+
" individual FROM `tmp`;"
)
"INSERT INTO `profile`(id, name, host, localPort, remotePort, password, method, route,"
+
"
proxyApps, bypass,
udpdns, ipv6, individual) "
+
"SELECT id, name, host, localPort, remotePort, password, method, route, 1 - global,"
+
"
bypass, udpdns, ipv6,
individual FROM `tmp`;"
)
profileDao
.
executeRawNoArgs
(
"DROP TABLE `tmp`;"
)
profileDao
.
executeRawNoArgs
(
"COMMIT;"
)
}
else
if
(
oldVersion
<
13
)
{
...
...
mobile/src/main/java/com/github/shadowsocks/database/Profile.kt
View file @
a755b669
...
...
@@ -36,6 +36,7 @@ import java.util.*
class
Profile
:
Serializable
{
companion
object
{
private
const
val
TAG
=
"ShadowParser"
private
const
val
serialVersionUID
=
0L
private
val
pattern
=
"""(?i)ss://[-a-zA-Z0-9+&@#/%?=~_|!:,.;\[\]]*[-a-zA-Z0-9+&@#/%=~_|\[\]]"""
.
toRegex
()
private
val
userInfoPattern
=
"^(.+?):(.*)$"
.
toRegex
()
private
val
legacyPattern
=
"^(.+?):(.*)@(.+?):(\\d+?)$"
.
toRegex
()
...
...
mobile/src/main/java/com/github/shadowsocks/database/ProfileManager.kt
View file @
a755b669
...
...
@@ -25,14 +25,19 @@ import com.github.shadowsocks.App.Companion.app
import
com.github.shadowsocks.ProfilesFragment
import
com.github.shadowsocks.preference.DataStore
import
com.github.shadowsocks.utils.DirectBoot
import
java.sql.SQLException
/**
* SQLExceptions are not caught (and therefore will cause crash) for insert/update transactions
* to ensure we are in a consistent state.
*/
object
ProfileManager
{
private
const
val
TAG
=
"ProfileManager"
@Throws
(
SQLException
::
class
)
fun
createProfile
(
p
:
Profile
?
=
null
):
Profile
{
val
profile
=
p
?:
Profile
()
profile
.
id
=
0
try
{
val
oldProfile
=
app
.
currentProfile
if
(
oldProfile
!=
null
)
{
// Copy Feature Settings from old profile
...
...
@@ -48,56 +53,41 @@ object ProfileManager {
if
(
last
!=
null
&&
last
.
size
==
1
&&
last
[
0
]
!=
null
)
profile
.
userOrder
=
last
[
0
].
toLong
()
+
1
PrivateDatabase
.
profileDao
.
createOrUpdate
(
profile
)
ProfilesFragment
.
instance
?.
profilesAdapter
?.
add
(
profile
)
}
catch
(
ex
:
Exception
)
{
Log
.
e
(
TAG
,
"addProfile"
,
ex
)
app
.
track
(
ex
)
}
return
profile
}
/**
* Note: It's caller's responsibility to update DirectBoot profile if necessary.
*/
fun
updateProfile
(
profile
:
Profile
):
Boolean
=
try
{
PrivateDatabase
.
profileDao
.
update
(
profile
)
true
}
catch
(
ex
:
Exception
)
{
Log
.
e
(
TAG
,
"updateProfile"
,
ex
)
app
.
track
(
ex
)
false
}
@Throws
(
SQLException
::
class
)
fun
updateProfile
(
profile
:
Profile
)
=
PrivateDatabase
.
profileDao
.
update
(
profile
)
fun
getProfile
(
id
:
Int
):
Profile
?
=
try
{
PrivateDatabase
.
profileDao
.
queryForId
(
id
)
}
catch
(
ex
:
Exception
)
{
}
catch
(
ex
:
SQL
Exception
)
{
Log
.
e
(
TAG
,
"getProfile"
,
ex
)
app
.
track
(
ex
)
null
}
fun
delProfile
(
id
:
Int
):
Boolean
=
try
{
@Throws
(
SQLException
::
class
)
fun
delProfile
(
id
:
Int
)
{
PrivateDatabase
.
profileDao
.
deleteById
(
id
)
ProfilesFragment
.
instance
?.
profilesAdapter
?.
removeId
(
id
)
if
(
id
==
DataStore
.
profileId
&&
DataStore
.
directBootAware
)
DirectBoot
.
clean
()
true
}
catch
(
ex
:
Exception
)
{
Log
.
e
(
TAG
,
"delProfile"
,
ex
)
app
.
track
(
ex
)
false
}
fun
getFirstProfile
():
Profile
?
=
try
{
val
result
=
PrivateDatabase
.
profileDao
.
query
(
PrivateDatabase
.
profileDao
.
queryBuilder
().
limit
(
1L
).
prepare
())
if
(
result
.
size
==
1
)
result
[
0
]
else
null
}
catch
(
ex
:
Exception
)
{
Log
.
e
(
TAG
,
"getAllProfiles"
,
ex
)
PrivateDatabase
.
profileDao
.
query
(
PrivateDatabase
.
profileDao
.
queryBuilder
().
limit
(
1L
).
prepare
()).
singleOrNull
()
}
catch
(
ex
:
SQLException
)
{
Log
.
e
(
TAG
,
"getFirstProfile"
,
ex
)
app
.
track
(
ex
)
null
}
fun
getAllProfiles
():
List
<
Profile
>?
=
try
{
PrivateDatabase
.
profileDao
.
query
(
PrivateDatabase
.
profileDao
.
queryBuilder
().
orderBy
(
"userOrder"
,
true
).
prepare
())
}
catch
(
ex
:
Exception
)
{
}
catch
(
ex
:
SQL
Exception
)
{
Log
.
e
(
TAG
,
"getAllProfiles"
,
ex
)
app
.
track
(
ex
)
null
...
...
mobile/src/main/java/com/github/shadowsocks/preference/DataStore.kt
View file @
a755b669
...
...
@@ -52,7 +52,7 @@ object DataStore {
/**
* Setter is defined in MainActivity.onPreferenceDataStoreChanged.
*/
val
directBootAware
:
Boolean
get
()
=
BootReceiver
.
enabled
&&
(
publicStore
.
getBoolean
(
Key
.
directBootAware
)
?:
false
)
val
directBootAware
:
Boolean
get
()
=
BootReceiver
.
enabled
&&
publicStore
.
getBoolean
(
Key
.
directBootAware
)
==
true
var
serviceMode
:
String
get
()
=
publicStore
.
getString
(
Key
.
serviceMode
)
?:
Key
.
modeVpn
set
(
value
)
=
publicStore
.
putString
(
Key
.
serviceMode
,
value
)
...
...
mobile/src/main/java/com/github/shadowsocks/preference/IconListPreference.kt
View file @
a755b669
...
...
@@ -28,11 +28,7 @@ import android.util.AttributeSet
class
IconListPreference
(
context
:
Context
,
attrs
:
AttributeSet
?
=
null
)
:
ListPreference
(
context
,
attrs
)
{
var
entryIcons
:
Array
<
Drawable
?
>?
=
null
val
selectedEntry
:
Int
get
()
=
entryValues
.
indexOf
(
value
)
val
entryIcon
:
Drawable
?
get
()
=
try
{
entryIcons
?.
get
(
selectedEntry
)
}
catch
(
_
:
ArrayIndexOutOfBoundsException
)
{
null
}
val
entryIcon
:
Drawable
?
get
()
=
entryIcons
?.
getOrNull
(
selectedEntry
)
// fun setEntryIcons(@ArrayRes entryIconsResId: Int) {
// val array = getContext().getResources().obtainTypedArray(entryIconsResId)
// entryIcons = Array(array.length(), { i -> array.getDrawable(i) })
...
...
@@ -49,7 +45,7 @@ class IconListPreference(context: Context, attrs: AttributeSet? = null) : ListPr
}
init
{
super
.
setOnPreferenceChangeListener
(
{
preference
,
newValue
->
super
.
setOnPreferenceChangeListener
{
preference
,
newValue
->
val
listener
=
listener
if
(
listener
==
null
||
listener
.
onPreferenceChange
(
preference
,
newValue
))
{
value
=
newValue
.
toString
()
...
...
@@ -57,7 +53,7 @@ class IconListPreference(context: Context, attrs: AttributeSet? = null) : ListPr
if
(
entryIcons
!=
null
)
icon
=
entryIcon
true
}
else
false
}
)
}
// val a = context.obtainStyledAttributes(attrs, R.styleable.IconListPreference)
// val entryIconsResId: Int = a.getResourceId(R.styleable.IconListPreference_entryIcons, -1)
// if (entryIconsResId != -1) entryIcons = entryIconsResId
...
...
mobile/src/main/java/com/github/shadowsocks/tasker/ConfigActivity.kt
View file @
a755b669
...
...
@@ -85,12 +85,12 @@ class ConfigActivity : AppCompatActivity() {
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
try
{
taskerOption
=
Settings
.
fromIntent
(
intent
!!
)
}
catch
(
_
:
Exception
)
{
val
intent
=
intent
if
(
intent
==
null
)
{
finish
()
return
}
taskerOption
=
Settings
.
fromIntent
(
intent
)
setContentView
(
R
.
layout
.
layout_tasker
)
val
toolbar
=
findViewById
<
Toolbar
>(
R
.
id
.
toolbar
)
...
...
mobile/src/main/java/com/github/shadowsocks/tasker/Settings.kt
View file @
a755b669
...
...
@@ -44,8 +44,8 @@ class Settings(bundle: Bundle?) {
if
(
profileId
>=
0
)
bundle
.
putInt
(
KEY_PROFILE_ID
,
profileId
)
val
profile
=
ProfileManager
.
getProfile
(
profileId
)
return
Intent
().
putExtra
(
ApiIntent
.
EXTRA_BUNDLE
,
bundle
).
putExtra
(
ApiIntent
.
EXTRA_STRING_BLURB
,
if
(
profile
!=
null
)
context
.
getString
(
if
(
switchOn
)
R
.
string
.
start_service
else
R
.
string
.
stop_service
,
profile
.
formattedName
)
if
(
profile
!=
null
)
context
.
getString
(
if
(
switchOn
)
R
.
string
.
start_service
else
R
.
string
.
stop_service
,
profile
.
formattedName
)
else
context
.
getString
(
if
(
switchOn
)
R
.
string
.
start_service_default
else
R
.
string
.
stop
))
}
}
mobile/src/main/java/com/github/shadowsocks/utils/Commandline.kt
View file @
a755b669
...
...
@@ -20,9 +20,7 @@
package
com.github.shadowsocks.utils
import
java.util.ArrayList
import
java.util.Arrays
import
java.util.StringTokenizer
import
java.util.*
/**
* Commandline objects help handling command lines specifying processes to
...
...
@@ -86,9 +84,7 @@ object Commandline {
* @return empty string for null or no command, else every argument split
* by spaces and quoted by quoting rules.
*/
fun
toString
(
args
:
Array
<
String
>):
String
{
return
toString
(
Arrays
.
asList
(*
args
))
// thanks to Java, arrays aren't iterable
}
fun
toString
(
args
:
Array
<
String
>)
=
toString
(
args
.
asIterable
())
// thanks to Java, arrays aren't iterable
/**
* Crack a command line.
...
...
mobile/src/main/java/com/github/shadowsocks/utils/DirectBoot.kt
View file @
a755b669
...
...
@@ -7,7 +7,7 @@ import com.github.shadowsocks.database.Profile
import
com.github.shadowsocks.database.ProfileManager
import
com.github.shadowsocks.preference.DataStore
import
java.io.File
import
java.io.
FileNotFound
Exception
import
java.io.
IO
Exception
import
java.io.ObjectInputStream
import
java.io.ObjectOutputStream
...
...
@@ -17,7 +17,7 @@ object DirectBoot {
fun
getDeviceProfile
():
Profile
?
=
try
{
ObjectInputStream
(
file
.
inputStream
()).
use
{
it
.
readObject
()
as
Profile
}
}
catch
(
_
:
FileNotFound
Exception
)
{
null
}
}
catch
(
_
:
IO
Exception
)
{
null
}
fun
clean
()
{
file
.
delete
()
...
...
mobile/src/main/java/com/github/shadowsocks/utils/Utils.kt
View file @
a755b669
...
...
@@ -28,8 +28,8 @@ fun String.parseNumericAddress(): InetAddress? {
}
fun
parsePort
(
str
:
String
?,
default
:
Int
,
min
:
Int
=
1025
):
Int
{
val
x
=
str
?.
toIntOrNull
()
?:
default
return
if
(
x
<
min
||
x
>
65535
)
default
else
x
val
value
=
str
?.
toIntOrNull
()
?:
default
return
if
(
value
<
min
||
value
>
65535
)
default
else
value
}
fun
broadcastReceiver
(
callback
:
(
Context
,
Intent
)
->
Unit
):
BroadcastReceiver
=
object
:
BroadcastReceiver
()
{
...
...
@@ -72,6 +72,6 @@ private class SortedListIterable<out T>(private val list: SortedList<T>) : Itera
private
class
SortedListIterator
<
out
T
>(
private
val
list
:
SortedList
<
T
>)
:
Iterator
<
T
>
{
private
var
count
=
0
override
fun
hasNext
()
=
count
<
list
.
size
()
override
fun
next
():
T
=
list
[
count
++]
override
fun
next
():
T
=
if
(
hasNext
())
list
[
count
++]
else
throw
NoSuchElementException
()
}
fun
<
T
>
SortedList
<
T
>.
asIterable
():
Iterable
<
T
>
=
SortedListIterable
(
this
)
mobile/src/main/java/com/github/shadowsocks/widget/ServiceButton.kt
View file @
a755b669
...
...
@@ -29,7 +29,6 @@ import android.support.graphics.drawable.AnimatedVectorDrawableCompat
import
android.support.v7.widget.TooltipCompat
import
android.util.AttributeSet
import
android.view.View
import
com.github.shadowsocks.App.Companion.app
import
com.github.shadowsocks.R
import
com.github.shadowsocks.bg.BaseService
import
java.util.*
...
...
plugin/src/main/java/com/github/shadowsocks/plugin/NativePluginProvider.kt
View file @
a755b669
...
...
@@ -70,8 +70,8 @@ abstract class NativePluginProvider : ContentProvider() {
/**
* Returns executable entry absolute path. This is used if plugin is sharing UID with the host.
*
* Default behavior is throwing UnsupportedOperationException. If you don't wish to use this feature, use the
default
* behavior.
* Default behavior is throwing UnsupportedOperationException. If you don't wish to use this feature, use the
*
default
behavior.
*
* @return Absolute path for executable entry.
*/
...
...
plugin/src/main/java/com/github/shadowsocks/plugin/OptionsCapableActivity.kt
View file @
a755b669
...
...
@@ -29,14 +29,12 @@ import android.widget.Toast
* Activity that's capable of getting EXTRA_OPTIONS input.
*/
abstract
class
OptionsCapableActivity
:
AppCompatActivity
()
{
protected
fun
pluginOptions
(
intent
:
Intent
=
this
.
intent
):
PluginOptions
{
return
try
{
protected
fun
pluginOptions
(
intent
:
Intent
=
this
.
intent
)
=
try
{
PluginOptions
(
intent
.
getStringExtra
(
PluginContract
.
EXTRA_OPTIONS
))
}
catch
(
exc
:
IllegalArgumentException
)
{
Toast
.
makeText
(
this
,
exc
.
message
,
Toast
.
LENGTH_SHORT
).
show
()
PluginOptions
()
}
}
/**
* Populate args to your user interface.
...
...
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