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
Hide 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 @@
...
@@ -3,6 +3,7 @@
[

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

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

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

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

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

](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)
[

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