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
a5df60ae
Commit
a5df60ae
authored
Dec 09, 2016
by
Mygod
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refine code style
parent
c9b404fa
Changes
42
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
301 additions
and
335 deletions
+301
-335
src/main/scala/be/mygod/preference/EditTextPreference.scala
src/main/scala/be/mygod/preference/EditTextPreference.scala
+3
-3
src/main/scala/be/mygod/preference/EditTextPreferenceDialogFragment.scala
...e/mygod/preference/EditTextPreferenceDialogFragment.scala
+3
-2
src/main/scala/be/mygod/preference/NumberPickerPreference.scala
...in/scala/be/mygod/preference/NumberPickerPreference.scala
+7
-7
src/main/scala/be/mygod/preference/NumberPickerPreferenceDialogFragment.scala
...god/preference/NumberPickerPreferenceDialogFragment.scala
+3
-2
src/main/scala/be/mygod/preference/PreferenceFragment.scala
src/main/scala/be/mygod/preference/PreferenceFragment.scala
+5
-5
src/main/scala/be/mygod/preference/PreferenceGroupAdapter.scala
...in/scala/be/mygod/preference/PreferenceGroupAdapter.scala
+27
-25
src/main/scala/be/mygod/preference/SummaryPreference.scala
src/main/scala/be/mygod/preference/SummaryPreference.scala
+1
-1
src/main/scala/com/github/shadowsocks/AppManager.scala
src/main/scala/com/github/shadowsocks/AppManager.scala
+8
-8
src/main/scala/com/github/shadowsocks/BaseService.scala
src/main/scala/com/github/shadowsocks/BaseService.scala
+23
-22
src/main/scala/com/github/shadowsocks/BootReceiver.scala
src/main/scala/com/github/shadowsocks/BootReceiver.scala
+3
-3
src/main/scala/com/github/shadowsocks/GuardedProcess.scala
src/main/scala/com/github/shadowsocks/GuardedProcess.scala
+14
-25
src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala
...scala/com/github/shadowsocks/ProfileManagerActivity.scala
+35
-36
src/main/scala/com/github/shadowsocks/ScannerActivity.scala
src/main/scala/com/github/shadowsocks/ScannerActivity.scala
+3
-4
src/main/scala/com/github/shadowsocks/ServiceBoundContext.scala
...in/scala/com/github/shadowsocks/ServiceBoundContext.scala
+10
-10
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
+12
-12
src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala
...scala/com/github/shadowsocks/ShadowsocksApplication.scala
+18
-15
src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
.../scala/com/github/shadowsocks/ShadowsocksNatService.scala
+9
-12
src/main/scala/com/github/shadowsocks/ShadowsocksNotification.scala
...cala/com/github/shadowsocks/ShadowsocksNotification.scala
+9
-9
src/main/scala/com/github/shadowsocks/ShadowsocksQuickSwitchActivity.scala
...m/github/shadowsocks/ShadowsocksQuickSwitchActivity.scala
+5
-5
src/main/scala/com/github/shadowsocks/ShadowsocksRunnerActivity.scala
...la/com/github/shadowsocks/ShadowsocksRunnerActivity.scala
+2
-3
src/main/scala/com/github/shadowsocks/ShadowsocksRunnerService.scala
...ala/com/github/shadowsocks/ShadowsocksRunnerService.scala
+2
-3
src/main/scala/com/github/shadowsocks/ShadowsocksSettings.scala
...in/scala/com/github/shadowsocks/ShadowsocksSettings.scala
+9
-9
src/main/scala/com/github/shadowsocks/ShadowsocksTileService.scala
...scala/com/github/shadowsocks/ShadowsocksTileService.scala
+9
-9
src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
.../scala/com/github/shadowsocks/ShadowsocksVpnService.scala
+7
-10
src/main/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala
...n/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala
+3
-2
src/main/scala/com/github/shadowsocks/TaskerActivity.scala
src/main/scala/com/github/shadowsocks/TaskerActivity.scala
+7
-7
src/main/scala/com/github/shadowsocks/TaskerReceiver.scala
src/main/scala/com/github/shadowsocks/TaskerReceiver.scala
+3
-5
src/main/scala/com/github/shadowsocks/database/DBHelper.scala
...main/scala/com/github/shadowsocks/database/DBHelper.scala
+2
-2
src/main/scala/com/github/shadowsocks/database/Profile.scala
src/main/scala/com/github/shadowsocks/database/Profile.scala
+2
-2
src/main/scala/com/github/shadowsocks/database/ProfileManager.scala
...cala/com/github/shadowsocks/database/ProfileManager.scala
+2
-2
src/main/scala/com/github/shadowsocks/job/AclSyncJob.scala
src/main/scala/com/github/shadowsocks/job/AclSyncJob.scala
+1
-1
src/main/scala/com/github/shadowsocks/job/DonaldTrump.scala
src/main/scala/com/github/shadowsocks/job/DonaldTrump.scala
+1
-1
src/main/scala/com/github/shadowsocks/utils/CloseUtils.scala
src/main/scala/com/github/shadowsocks/utils/CloseUtils.scala
+4
-4
src/main/scala/com/github/shadowsocks/utils/IOUtils.scala
src/main/scala/com/github/shadowsocks/utils/IOUtils.scala
+2
-1
src/main/scala/com/github/shadowsocks/utils/Parser.scala
src/main/scala/com/github/shadowsocks/utils/Parser.scala
+19
-19
src/main/scala/com/github/shadowsocks/utils/TaskerSettings.scala
...n/scala/com/github/shadowsocks/utils/TaskerSettings.scala
+3
-3
src/main/scala/com/github/shadowsocks/utils/TcpFastOpen.scala
...main/scala/com/github/shadowsocks/utils/TcpFastOpen.scala
+2
-2
src/main/scala/com/github/shadowsocks/utils/TrafficMonitor.scala
...n/scala/com/github/shadowsocks/utils/TrafficMonitor.scala
+1
-1
src/main/scala/com/github/shadowsocks/utils/TrafficMonitorThread.scala
...a/com/github/shadowsocks/utils/TrafficMonitorThread.scala
+1
-1
src/main/scala/com/github/shadowsocks/utils/Utils.scala
src/main/scala/com/github/shadowsocks/utils/Utils.scala
+10
-32
src/main/scala/com/github/shadowsocks/widget/FloatingActionMenuBehavior.scala
...ithub/shadowsocks/widget/FloatingActionMenuBehavior.scala
+6
-5
src/main/scala/com/github/shadowsocks/widget/UndoSnackbarManager.scala
...a/com/github/shadowsocks/widget/UndoSnackbarManager.scala
+5
-5
No files found.
src/main/scala/be/mygod/preference/EditTextPreference.scala
View file @
a5df60ae
...
@@ -37,7 +37,7 @@ class EditTextPreference(context: Context, attrs: AttributeSet = null) extends P
...
@@ -37,7 +37,7 @@ class EditTextPreference(context: Context, attrs: AttributeSet = null) extends P
override
def
createDialog
()
=
new
EditTextPreferenceDialogFragment
()
override
def
createDialog
()
=
new
EditTextPreferenceDialogFragment
()
override
protected
def
getSummaryValue
=
{
override
protected
def
getSummaryValue
:
String
=
{
var
text
=
getText
var
text
=
getText
if
(
text
==
null
)
text
=
""
if
(
text
==
null
)
text
=
""
val
inputType
=
editText
.
getInputType
val
inputType
=
editText
.
getInputType
...
@@ -47,8 +47,8 @@ class EditTextPreference(context: Context, attrs: AttributeSet = null) extends P
...
@@ -47,8 +47,8 @@ class EditTextPreference(context: Context, attrs: AttributeSet = null) extends P
"\u2022"
*
text
.
length
else
text
"\u2022"
*
text
.
length
else
text
}
}
override
def
setText
(
text
:
String
)
=
{
override
def
setText
(
text
:
String
)
:
Unit
=
{
super
.
setText
(
text
)
super
.
setText
(
text
)
notifyChanged
notifyChanged
()
}
}
}
}
src/main/scala/be/mygod/preference/EditTextPreferenceDialogFragment.scala
View file @
a5df60ae
...
@@ -22,13 +22,14 @@ package be.mygod.preference
...
@@ -22,13 +22,14 @@ package be.mygod.preference
import
android.content.Context
import
android.content.Context
import
android.support.v14.preference.PreferenceDialogFragment
import
android.support.v14.preference.PreferenceDialogFragment
import
android.support.v7.widget.AppCompatEditText
import
android.view.
{
View
,
ViewGroup
}
import
android.view.
{
View
,
ViewGroup
}
class
EditTextPreferenceDialogFragment
extends
PreferenceDialogFragment
{
class
EditTextPreferenceDialogFragment
extends
PreferenceDialogFragment
{
private
lazy
val
preference
=
getPreference
.
asInstanceOf
[
EditTextPreference
]
private
lazy
val
preference
=
getPreference
.
asInstanceOf
[
EditTextPreference
]
private
lazy
val
editText
=
preference
.
editText
private
lazy
val
editText
=
preference
.
editText
override
protected
def
onCreateDialogView
(
context
:
Context
)
=
{
override
protected
def
onCreateDialogView
(
context
:
Context
)
:
AppCompatEditText
=
{
val
parent
=
editText
.
getParent
.
asInstanceOf
[
ViewGroup
]
val
parent
=
editText
.
getParent
.
asInstanceOf
[
ViewGroup
]
if
(
parent
!=
null
)
parent
.
removeView
(
editText
)
if
(
parent
!=
null
)
parent
.
removeView
(
editText
)
editText
editText
...
@@ -43,7 +44,7 @@ class EditTextPreferenceDialogFragment extends PreferenceDialogFragment {
...
@@ -43,7 +44,7 @@ class EditTextPreferenceDialogFragment extends PreferenceDialogFragment {
override
protected
def
needInputMethod
=
true
override
protected
def
needInputMethod
=
true
def
onDialogClosed
(
positiveResult
:
Boolean
)
=
if
(
positiveResult
)
{
def
onDialogClosed
(
positiveResult
:
Boolean
)
:
Unit
=
if
(
positiveResult
)
{
val
value
=
editText
.
getText
.
toString
val
value
=
editText
.
getText
.
toString
if
(
preference
.
callChangeListener
(
value
))
preference
.
setText
(
value
)
if
(
preference
.
callChangeListener
(
value
))
preference
.
setText
(
value
)
}
}
...
...
src/main/scala/be/mygod/preference/NumberPickerPreference.scala
View file @
a5df60ae
...
@@ -37,23 +37,23 @@ class NumberPickerPreference(private val context: Context, attrs: AttributeSet =
...
@@ -37,23 +37,23 @@ class NumberPickerPreference(private val context: Context, attrs: AttributeSet =
val
a
:
TypedArray
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
NumberPickerPreference
)
val
a
:
TypedArray
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
NumberPickerPreference
)
setMin
(
a
.
getInt
(
R
.
styleable
.
NumberPickerPreference_min
,
0
))
setMin
(
a
.
getInt
(
R
.
styleable
.
NumberPickerPreference_min
,
0
))
setMax
(
a
.
getInt
(
R
.
styleable
.
NumberPickerPreference_max
,
Int
.
MaxValue
-
1
))
setMax
(
a
.
getInt
(
R
.
styleable
.
NumberPickerPreference_max
,
Int
.
MaxValue
-
1
))
a
.
recycle
a
.
recycle
()
}
}
override
def
createDialog
()
=
new
NumberPickerPreferenceDialogFragment
()
override
def
createDialog
()
=
new
NumberPickerPreferenceDialogFragment
()
def
getValue
=
value
def
getValue
:
Int
=
value
def
getMin
=
if
(
picker
==
null
)
0
else
picker
.
getMinValue
def
getMin
:
Int
=
if
(
picker
==
null
)
0
else
picker
.
getMinValue
def
getMax
=
picker
.
getMaxValue
def
getMax
:
Int
=
picker
.
getMaxValue
def
setValue
(
i
:
Int
)
{
def
setValue
(
i
:
Int
)
{
if
(
i
==
value
)
return
if
(
i
==
value
)
return
picker
.
setValue
(
i
)
picker
.
setValue
(
i
)
value
=
picker
.
getValue
value
=
picker
.
getValue
persistInt
(
value
)
persistInt
(
value
)
notifyChanged
notifyChanged
()
}
}
def
setMin
(
value
:
Int
)
=
picker
.
setMinValue
(
value
)
def
setMin
(
value
:
Int
)
:
Unit
=
picker
.
setMinValue
(
value
)
def
setMax
(
value
:
Int
)
=
picker
.
setMaxValue
(
value
)
def
setMax
(
value
:
Int
)
:
Unit
=
picker
.
setMaxValue
(
value
)
override
protected
def
onGetDefaultValue
(
a
:
TypedArray
,
index
:
Int
)
:
AnyRef
=
override
protected
def
onGetDefaultValue
(
a
:
TypedArray
,
index
:
Int
)
:
AnyRef
=
a
.
getInt
(
index
,
getMin
).
asInstanceOf
[
AnyRef
]
a
.
getInt
(
index
,
getMin
).
asInstanceOf
[
AnyRef
]
...
...
src/main/scala/be/mygod/preference/NumberPickerPreferenceDialogFragment.scala
View file @
a5df60ae
...
@@ -23,12 +23,13 @@ package be.mygod.preference
...
@@ -23,12 +23,13 @@ package be.mygod.preference
import
android.content.Context
import
android.content.Context
import
android.support.v14.preference.PreferenceDialogFragment
import
android.support.v14.preference.PreferenceDialogFragment
import
android.view.
{
View
,
ViewGroup
}
import
android.view.
{
View
,
ViewGroup
}
import
android.widget.NumberPicker
class
NumberPickerPreferenceDialogFragment
extends
PreferenceDialogFragment
{
class
NumberPickerPreferenceDialogFragment
extends
PreferenceDialogFragment
{
private
lazy
val
preference
=
getPreference
.
asInstanceOf
[
NumberPickerPreference
]
private
lazy
val
preference
=
getPreference
.
asInstanceOf
[
NumberPickerPreference
]
private
lazy
val
picker
=
preference
.
picker
private
lazy
val
picker
=
preference
.
picker
override
protected
def
onCreateDialogView
(
context
:
Context
)
=
{
override
protected
def
onCreateDialogView
(
context
:
Context
)
:
NumberPicker
=
{
val
parent
=
picker
.
getParent
.
asInstanceOf
[
ViewGroup
]
val
parent
=
picker
.
getParent
.
asInstanceOf
[
ViewGroup
]
if
(
parent
!=
null
)
parent
.
removeView
(
picker
)
if
(
parent
!=
null
)
parent
.
removeView
(
picker
)
picker
picker
...
@@ -42,7 +43,7 @@ class NumberPickerPreferenceDialogFragment extends PreferenceDialogFragment {
...
@@ -42,7 +43,7 @@ class NumberPickerPreferenceDialogFragment extends PreferenceDialogFragment {
override
protected
def
needInputMethod
=
true
override
protected
def
needInputMethod
=
true
def
onDialogClosed
(
positiveResult
:
Boolean
)
{
def
onDialogClosed
(
positiveResult
:
Boolean
)
{
picker
.
clearFocus
// commit changes
picker
.
clearFocus
()
// commit changes
if
(
positiveResult
)
{
if
(
positiveResult
)
{
val
value
=
picker
.
getValue
val
value
=
picker
.
getValue
if
(
preference
.
callChangeListener
(
value
))
preference
.
setValue
(
value
)
if
(
preference
.
callChangeListener
(
value
))
preference
.
setValue
(
value
)
...
...
src/main/scala/be/mygod/preference/PreferenceFragment.scala
View file @
a5df60ae
...
@@ -24,10 +24,10 @@ import android.app.DialogFragment
...
@@ -24,10 +24,10 @@ import android.app.DialogFragment
import
android.os.Bundle
import
android.os.Bundle
import
android.support.v14.preference.
{
PreferenceFragment
=>
Base
}
import
android.support.v14.preference.
{
PreferenceFragment
=>
Base
}
import
android.support.v7.preference.
{
Preference
,
PreferenceScreen
}
import
android.support.v7.preference.
{
Preference
,
PreferenceScreen
}
import
android.view.
{
LayoutInflater
,
ViewGroup
}
import
android.view.
{
LayoutInflater
,
View
,
View
Group
}
abstract
class
PreferenceFragment
extends
Base
{
abstract
class
PreferenceFragment
extends
Base
{
override
def
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
,
savedInstanceState
:
Bundle
)
=
override
def
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
,
savedInstanceState
:
Bundle
)
:
View
=
super
.
onCreateView
(
inflater
,
container
,
savedInstanceState
)
super
.
onCreateView
(
inflater
,
container
,
savedInstanceState
)
protected
final
def
displayPreferenceDialog
(
key
:
String
,
fragment
:
DialogFragment
)
{
protected
final
def
displayPreferenceDialog
(
key
:
String
,
fragment
:
DialogFragment
)
{
...
@@ -40,15 +40,15 @@ abstract class PreferenceFragment extends Base {
...
@@ -40,15 +40,15 @@ abstract class PreferenceFragment extends Base {
.
commitAllowingStateLoss
()
.
commitAllowingStateLoss
()
}
}
override
def
onDisplayPreferenceDialog
(
preference
:
Preference
)
=
preference
match
{
override
def
onDisplayPreferenceDialog
(
preference
:
Preference
)
:
Unit
=
preference
match
{
case
dpp
:
DialogPreferencePlus
=>
displayPreferenceDialog
(
preference
.
getKey
,
dpp
.
createDialog
())
case
dpp
:
DialogPreferencePlus
=>
displayPreferenceDialog
(
preference
.
getKey
,
dpp
.
createDialog
())
case
_
=>
super
.
onDisplayPreferenceDialog
(
preference
)
case
_
=>
super
.
onDisplayPreferenceDialog
(
preference
)
}
}
override
protected
def
onCreateAdapter
(
screen
:
PreferenceScreen
)
=
new
PreferenceGroupAdapter
(
screen
)
override
protected
def
onCreateAdapter
(
screen
:
PreferenceScreen
)
=
new
PreferenceGroupAdapter
(
screen
)
override
def
onResume
{
override
def
onResume
()
{
super
.
onResume
super
.
onResume
()
getListView
.
scrollBy
(
0
,
0
)
getListView
.
scrollBy
(
0
,
0
)
}
}
}
}
src/main/scala/be/mygod/preference/PreferenceGroupAdapter.scala
View file @
a5df60ae
...
@@ -21,7 +21,7 @@
...
@@ -21,7 +21,7 @@
package
be.mygod.preference
package
be.mygod.preference
import
java.lang.reflect.Field
import
java.lang.reflect.Field
import
java.util
.List
import
java.util
import
android.os.Build
import
android.os.Build
import
android.support.v4.content.ContextCompat
import
android.support.v4.content.ContextCompat
...
@@ -57,29 +57,31 @@ object PreferenceGroupAdapter {
...
@@ -57,29 +57,31 @@ object PreferenceGroupAdapter {
class
PreferenceGroupAdapter
(
group
:
PreferenceGroup
)
extends
Old
(
group
)
{
class
PreferenceGroupAdapter
(
group
:
PreferenceGroup
)
extends
Old
(
group
)
{
import
PreferenceGroupAdapter._
import
PreferenceGroupAdapter._
protected
lazy
val
preferenceLayouts
=
preferenceLayoutsField
.
get
(
this
).
asInstanceOf
[
List
[
AnyRef
]]
protected
lazy
val
preferenceLayouts
:
util.List
[
AnyRef
]
=
preferenceLayoutsField
.
get
(
this
).
asInstanceOf
[
util.List
[
AnyRef
]]
override
def
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
)
=
if
(
Build
.
VERSION
.
SDK_INT
<
21
)
{
override
def
onCreateViewHolder
(
parent
:
ViewGroup
,
viewType
:
Int
)
:
PreferenceViewHolder
=
val
context
=
parent
.
getContext
if
(
Build
.
VERSION
.
SDK_INT
<
21
)
{
val
inflater
=
LayoutInflater
.
from
(
context
)
val
context
=
parent
.
getContext
val
pl
=
preferenceLayouts
.
get
(
viewType
)
val
inflater
=
LayoutInflater
.
from
(
context
)
val
view
=
inflater
.
inflate
(
fieldResId
.
get
(
pl
).
asInstanceOf
[
Int
],
parent
,
false
)
val
pl
=
preferenceLayouts
.
get
(
viewType
)
if
(
view
.
getBackground
==
null
)
{
val
view
=
inflater
.
inflate
(
fieldResId
.
get
(
pl
).
asInstanceOf
[
Int
],
parent
,
false
)
val
array
=
context
.
obtainStyledAttributes
(
null
,
R
.
styleable
.
BackgroundStyle
)
if
(
view
.
getBackground
==
null
)
{
var
background
=
array
.
getDrawable
(
R
.
styleable
.
BackgroundStyle_android_selectableItemBackground
)
val
array
=
context
.
obtainStyledAttributes
(
null
,
R
.
styleable
.
BackgroundStyle
)
if
(
background
==
null
)
var
background
=
array
.
getDrawable
(
R
.
styleable
.
BackgroundStyle_android_selectableItemBackground
)
background
=
ContextCompat
.
getDrawable
(
context
,
android
.
R
.
drawable
.
list_selector_background
)
if
(
background
==
null
)
array
.
recycle
background
=
ContextCompat
.
getDrawable
(
context
,
android
.
R
.
drawable
.
list_selector_background
)
val
(
s
,
t
,
e
,
b
)
=
(
ViewCompat
.
getPaddingStart
(
view
),
view
.
getPaddingTop
,
array
.
recycle
()
ViewCompat
.
getPaddingEnd
(
view
),
view
.
getPaddingBottom
)
val
(
s
,
t
,
e
,
b
)
=
(
ViewCompat
.
getPaddingStart
(
view
),
view
.
getPaddingTop
,
view
.
setBackground
(
background
)
ViewCompat
.
getPaddingEnd
(
view
),
view
.
getPaddingBottom
)
ViewCompat
.
setPaddingRelative
(
view
,
s
,
t
,
e
,
b
)
view
.
setBackground
(
background
)
}
ViewCompat
.
setPaddingRelative
(
view
,
s
,
t
,
e
,
b
)
val
widgetFrame
=
view
.
findViewById
(
android
.
R
.
id
.
widget_frame
).
asInstanceOf
[
ViewGroup
]
}
if
(
widgetFrame
!=
null
)
{
val
widgetFrame
=
view
.
findViewById
(
android
.
R
.
id
.
widget_frame
).
asInstanceOf
[
ViewGroup
]
val
widgetResId
=
fieldWidgetResId
.
get
(
pl
).
asInstanceOf
[
Int
]
if
(
widgetFrame
!=
null
)
{
if
(
widgetResId
!=
0
)
inflater
.
inflate
(
widgetResId
,
widgetFrame
)
else
widgetFrame
.
setVisibility
(
View
.
GONE
)
val
widgetResId
=
fieldWidgetResId
.
get
(
pl
).
asInstanceOf
[
Int
]
}
if
(
widgetResId
!=
0
)
inflater
.
inflate
(
widgetResId
,
widgetFrame
)
else
widgetFrame
.
setVisibility
(
View
.
GONE
)
preferenceViewHolderConstructor
.
newInstance
(
view
)
}
}
else
super
.
onCreateViewHolder
(
parent
,
viewType
)
preferenceViewHolderConstructor
.
newInstance
(
view
)
}
else
super
.
onCreateViewHolder
(
parent
,
viewType
)
}
}
src/main/scala/be/mygod/preference/SummaryPreference.scala
View file @
a5df60ae
...
@@ -38,7 +38,7 @@ trait SummaryPreference extends Preference {
...
@@ -38,7 +38,7 @@ trait SummaryPreference extends Preference {
*
*
* @return the summary with appropriate string substitution
* @return the summary with appropriate string substitution
*/
*/
override
def
getSummary
=
{
override
def
getSummary
:
String
=
{
val
summary
=
super
.
getSummary
val
summary
=
super
.
getSummary
if
(
summary
==
null
)
null
else
String
.
format
(
summary
.
toString
,
getSummaryValue
)
if
(
summary
==
null
)
null
else
String
.
format
(
summary
.
toString
,
getSummaryValue
)
}
}
...
...
src/main/scala/com/github/shadowsocks/AppManager.scala
View file @
a5df60ae
...
@@ -53,7 +53,7 @@ object AppManager {
...
@@ -53,7 +53,7 @@ object AppManager {
val
filter
=
new
IntentFilter
(
Intent
.
ACTION_PACKAGE_ADDED
)
val
filter
=
new
IntentFilter
(
Intent
.
ACTION_PACKAGE_ADDED
)
filter
.
addAction
(
Intent
.
ACTION_PACKAGE_REMOVED
)
filter
.
addAction
(
Intent
.
ACTION_PACKAGE_REMOVED
)
filter
.
addDataScheme
(
"package"
)
filter
.
addDataScheme
(
"package"
)
app
.
registerReceiver
((
context
:
Context
,
intent
:
Intent
)
=>
app
.
registerReceiver
((
_
:
Context
,
intent
:
Intent
)
=>
if
(
intent
.
getAction
!=
Intent
.
ACTION_PACKAGE_REMOVED
||
if
(
intent
.
getAction
!=
Intent
.
ACTION_PACKAGE_REMOVED
||
!
intent
.
getBooleanExtra
(
Intent
.
EXTRA_REPLACING
,
false
))
{
!
intent
.
getBooleanExtra
(
Intent
.
EXTRA_REPLACING
,
false
))
{
synchronized
(
cachedApps
=
null
)
synchronized
(
cachedApps
=
null
)
...
@@ -111,8 +111,8 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
...
@@ -111,8 +111,8 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
if
(
aProxied
^
proxiedApps
.
contains
(
b
.
packageName
))
aProxied
else
a
.
name
.
compareToIgnoreCase
(
b
.
name
)
<
0
if
(
aProxied
^
proxiedApps
.
contains
(
b
.
packageName
))
aProxied
else
a
.
name
.
compareToIgnoreCase
(
b
.
name
)
<
0
})
})
def
getItemCount
=
apps
.
length
def
getItemCount
:
Int
=
apps
.
length
def
onBindViewHolder
(
vh
:
AppViewHolder
,
i
:
Int
)
=
vh
.
bind
(
apps
(
i
))
def
onBindViewHolder
(
vh
:
AppViewHolder
,
i
:
Int
)
:
Unit
=
vh
.
bind
(
apps
(
i
))
def
onCreateViewHolder
(
vg
:
ViewGroup
,
i
:
Int
)
=
def
onCreateViewHolder
(
vg
:
ViewGroup
,
i
:
Int
)
=
new
AppViewHolder
(
LayoutInflater
.
from
(
vg
.
getContext
).
inflate
(
R
.
layout
.
layout_apps_item
,
vg
,
false
))
new
AppViewHolder
(
LayoutInflater
.
from
(
vg
.
getContext
).
inflate
(
R
.
layout
.
layout_apps_item
,
vg
,
false
))
}
}
...
@@ -148,8 +148,8 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
...
@@ -148,8 +148,8 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
p
.
individual
=
proxiedAppString
p
.
individual
=
proxiedAppString
app
.
profileManager
.
updateProfile
(
p
)
app
.
profileManager
.
updateProfile
(
p
)
})
})
Toast
.
makeText
(
this
,
R
.
string
.
action_apply_all
,
Toast
.
LENGTH_SHORT
).
show
Toast
.
makeText
(
this
,
R
.
string
.
action_apply_all
,
Toast
.
LENGTH_SHORT
).
show
()
case
_
=>
Toast
.
makeText
(
this
,
R
.
string
.
action_export_err
,
Toast
.
LENGTH_SHORT
).
show
case
_
=>
Toast
.
makeText
(
this
,
R
.
string
.
action_export_err
,
Toast
.
LENGTH_SHORT
).
show
()
}
}
return
true
return
true
case
R
.
id
.
action_export
=>
case
R
.
id
.
action_export
=>
...
@@ -180,7 +180,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
...
@@ -180,7 +180,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
return
true
return
true
}
catch
{
}
catch
{
case
_:
IllegalArgumentException
=>
case
_:
IllegalArgumentException
=>
Toast
.
makeText
(
this
,
R
.
string
.
action_import_err
,
Toast
.
LENGTH_SHORT
).
show
Toast
.
makeText
(
this
,
R
.
string
.
action_import_err
,
Toast
.
LENGTH_SHORT
).
show
()
}
}
}
}
}
}
...
@@ -239,7 +239,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
...
@@ -239,7 +239,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
loadAppsAsync
()
loadAppsAsync
()
}
}
def
reloadApps
()
=
if
(!
appsLoading
.
compareAndSet
(
true
,
false
))
loadAppsAsync
()
def
reloadApps
()
:
Unit
=
if
(!
appsLoading
.
compareAndSet
(
true
,
false
))
loadAppsAsync
()
def
loadAppsAsync
()
{
def
loadAppsAsync
()
{
if
(!
appsLoading
.
compareAndSet
(
false
,
true
))
return
if
(!
appsLoading
.
compareAndSet
(
false
,
true
))
return
Utils
.
ThrowableFuture
{
Utils
.
ThrowableFuture
{
...
@@ -255,7 +255,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
...
@@ -255,7 +255,7 @@ class AppManager extends AppCompatActivity with OnMenuItemClickListener {
}
}
}
}
override
def
onKeyUp
(
keyCode
:
Int
,
event
:
KeyEvent
)
=
keyCode
match
{
override
def
onKeyUp
(
keyCode
:
Int
,
event
:
KeyEvent
)
:
Boolean
=
keyCode
match
{
case
KeyEvent
.
KEYCODE_MENU
=>
case
KeyEvent
.
KEYCODE_MENU
=>
if
(
toolbar
.
isOverflowMenuShowing
)
toolbar
.
hideOverflowMenu
else
toolbar
.
showOverflowMenu
if
(
toolbar
.
isOverflowMenuShowing
)
toolbar
.
hideOverflowMenu
else
toolbar
.
showOverflowMenu
case
_
=>
super
.
onKeyUp
(
keyCode
,
event
)
case
_
=>
super
.
onKeyUp
(
keyCode
,
event
)
...
...
src/main/scala/com/github/shadowsocks/BaseService.scala
View file @
a5df60ae
...
@@ -52,19 +52,19 @@ trait BaseService extends Service {
...
@@ -52,19 +52,19 @@ trait BaseService extends Service {
var
callbacksCount
:
Int
=
_
var
callbacksCount
:
Int
=
_
lazy
val
handler
=
new
Handler
(
getMainLooper
)
lazy
val
handler
=
new
Handler
(
getMainLooper
)
lazy
val
restartHanlder
=
new
Handler
(
getMainLooper
)
lazy
val
restartHanlder
=
new
Handler
(
getMainLooper
)
lazy
val
protectPath
=
getApplicationInfo
.
dataDir
+
"/protect_path"
lazy
val
protectPath
:
String
=
getApplicationInfo
.
dataDir
+
"/protect_path"
private
val
closeReceiver
:
BroadcastReceiver
=
(
context
:
Context
,
intent
:
Intent
)
=>
{
private
val
closeReceiver
:
BroadcastReceiver
=
(
context
:
Context
,
_
:
Intent
)
=>
{
Toast
.
makeText
(
context
,
R
.
string
.
stopping
,
Toast
.
LENGTH_SHORT
).
show
()
Toast
.
makeText
(
context
,
R
.
string
.
stopping
,
Toast
.
LENGTH_SHORT
).
show
()
stopRunner
(
true
)
stopRunner
(
stopService
=
true
)
}
}
var
closeReceiverRegistered
:
Boolean
=
_
var
closeReceiverRegistered
:
Boolean
=
_
var
kcptunProcess
:
GuardedProcess
=
_
var
kcptunProcess
:
GuardedProcess
=
_
private
val
networkReceiver
:
BroadcastReceiver
=
(
context
:
Context
,
intent
:
Intent
)
=>
{
private
val
networkReceiver
:
BroadcastReceiver
=
(
context
:
Context
,
_
:
Intent
)
=>
{
val
cm
=
context
.
getSystemService
(
Context
.
CONNECTIVITY_SERVICE
).
asInstanceOf
[
ConnectivityManager
]
val
cm
=
context
.
getSystemService
(
Context
.
CONNECTIVITY_SERVICE
).
asInstanceOf
[
ConnectivityManager
]
val
activeNetwork
=
cm
.
getActiveNetworkInfo
()
val
activeNetwork
=
cm
.
getActiveNetworkInfo
val
isConnected
=
activeNetwork
!=
null
&&
activeNetwork
.
isConnected
()
val
isConnected
=
activeNetwork
!=
null
&&
activeNetwork
.
isConnected
if
(
isConnected
&&
profile
.
kcp
&&
kcptunProcess
!=
null
)
{
if
(
isConnected
&&
profile
.
kcp
&&
kcptunProcess
!=
null
)
{
restartHanlder
.
removeCallbacks
(
null
)
restartHanlder
.
removeCallbacks
(
null
)
...
@@ -95,7 +95,7 @@ trait BaseService extends Service {
...
@@ -95,7 +95,7 @@ trait BaseService extends Service {
callbacksCount
+=
1
callbacksCount
+=
1
if
(
callbacksCount
!=
0
&&
timer
==
null
)
{
if
(
callbacksCount
!=
0
&&
timer
==
null
)
{
val
task
=
new
TimerTask
{
val
task
=
new
TimerTask
{
def
run
{
def
run
()
{
if
(
TrafficMonitor
.
updateRate
())
updateTrafficRate
()
if
(
TrafficMonitor
.
updateRate
())
updateTrafficRate
()
}
}
}
}
...
@@ -107,27 +107,27 @@ trait BaseService extends Service {
...
@@ -107,27 +107,27 @@ trait BaseService extends Service {
}
}
}
}
override
def
use
(
profileId
:
Int
)
=
synchronized
(
if
(
profileId
<
0
)
stopRunner
(
true
)
else
{
override
def
use
(
profileId
:
Int
)
:
Unit
=
synchronized
(
if
(
profileId
<
0
)
stopRunner
(
stopService
=
true
)
else
{
val
profile
=
app
.
profileManager
.
getProfile
(
profileId
).
orNull
val
profile
=
app
.
profileManager
.
getProfile
(
profileId
).
orNull
if
(
profile
==
null
)
stopRunner
(
true
)
else
state
match
{
if
(
profile
==
null
)
stopRunner
(
stopService
=
true
)
else
state
match
{
case
State
.
STOPPED
=>
if
(
checkProfile
(
profile
))
startRunner
(
profile
)
case
State
.
STOPPED
=>
if
(
checkProfile
(
profile
))
startRunner
(
profile
)
case
State
.
CONNECTED
=>
if
(
profileId
!=
BaseService
.
this
.
profile
.
id
&&
checkProfile
(
profile
))
{
case
State
.
CONNECTED
=>
if
(
profileId
!=
BaseService
.
this
.
profile
.
id
&&
checkProfile
(
profile
))
{
stopRunner
(
false
)
stopRunner
(
stopService
=
false
)
startRunner
(
profile
)
startRunner
(
profile
)
}
}
case
_
=>
Log
.
w
(
BaseService
.
this
.
getClass
.
getSimpleName
,
"Illegal state when invoking use: "
+
state
)
case
_
=>
Log
.
w
(
BaseService
.
this
.
getClass
.
getSimpleName
,
"Illegal state when invoking use: "
+
state
)
}
}
})
})
override
def
useSync
(
profileId
:
Int
)
=
use
(
profileId
)
override
def
useSync
(
profileId
:
Int
)
:
Unit
=
use
(
profileId
)
}
}
def
checkProfile
(
profile
:
Profile
)
=
if
(
TextUtils
.
isEmpty
(
profile
.
host
)
||
TextUtils
.
isEmpty
(
profile
.
password
))
{
def
checkProfile
(
profile
:
Profile
)
:
Boolean
=
if
(
TextUtils
.
isEmpty
(
profile
.
host
)
||
TextUtils
.
isEmpty
(
profile
.
password
))
{
stopRunner
(
true
,
getString
(
R
.
string
.
proxy_empty
))
stopRunner
(
stopService
=
true
,
getString
(
R
.
string
.
proxy_empty
))
false
false
}
else
true
}
else
true
def
connect
()
=
if
(
profile
.
host
==
"198.199.101.152"
)
{
def
connect
()
:
Unit
=
if
(
profile
.
host
==
"198.199.101.152"
)
{
val
holder
=
app
.
containerHolder
val
holder
=
app
.
containerHolder
val
container
=
holder
.
getContainer
val
container
=
holder
.
getContainer
val
url
=
container
.
getString
(
"proxy_url"
)
val
url
=
container
.
getString
(
"proxy_url"
)
...
@@ -175,15 +175,16 @@ trait BaseService extends Service {
...
@@ -175,15 +175,16 @@ trait BaseService extends Service {
changeState
(
State
.
CONNECTING
)
changeState
(
State
.
CONNECTING
)
if
(
profile
.
isMethodUnsafe
)
handler
.
post
(()
=>
Toast
.
makeText
(
this
,
R
.
string
.
method_unsafe
,
Toast
.
LENGTH_LONG
).
show
)
if
(
profile
.
isMethodUnsafe
)
handler
.
post
(()
=>
Toast
.
makeText
(
this
,
R
.
string
.
method_unsafe
,
Toast
.
LENGTH_LONG
).
show
())
Utils
.
ThrowableFuture
(
try
connect
catch
{
Utils
.
ThrowableFuture
(
try
connect
()
catch
{
case
_:
NameNotResolvedException
=>
stopRunner
(
true
,
getString
(
R
.
string
.
invalid_server
))
case
_:
NameNotResolvedException
=>
stopRunner
(
stopService
=
true
,
getString
(
R
.
string
.
invalid_server
))
case
exc
:
KcpcliParseException
=>
case
exc
:
KcpcliParseException
=>
stopRunner
(
true
,
getString
(
R
.
string
.
service_failed
)
+
": "
+
exc
.
cause
.
getMessage
)
stopRunner
(
stopService
=
true
,
getString
(
R
.
string
.
service_failed
)
+
": "
+
exc
.
cause
.
getMessage
)
case
_:
NullConnectionException
=>
stopRunner
(
true
,
getString
(
R
.
string
.
reboot_required
))
case
_:
NullConnectionException
=>
stopRunner
(
stopService
=
true
,
getString
(
R
.
string
.
reboot_required
))
case
exc
:
Throwable
=>
case
exc
:
Throwable
=>
stopRunner
(
true
,
getString
(
R
.
string
.
service_failed
)
+
": "
+
exc
.
getMessage
)
stopRunner
(
stopService
=
true
,
getString
(
R
.
string
.
service_failed
)
+
": "
+
exc
.
getMessage
)
exc
.
printStackTrace
()
exc
.
printStackTrace
()
app
.
track
(
exc
)
app
.
track
(
exc
)
})
})
...
@@ -283,7 +284,7 @@ trait BaseService extends Service {
...
@@ -283,7 +284,7 @@ trait BaseService extends Service {
})
})
}
}
def
getBlackList
=
{
def
getBlackList
:
String
=
{
val
default
=
getString
(
R
.
string
.
black_list
)
val
default
=
getString
(
R
.
string
.
black_list
)
try
{
try
{
val
container
=
app
.
containerHolder
.
getContainer
val
container
=
app
.
containerHolder
.
getContainer
...
@@ -291,7 +292,7 @@ trait BaseService extends Service {
...
@@ -291,7 +292,7 @@ trait BaseService extends Service {
val
list
=
if
(
update
==
null
||
update
.
isEmpty
)
default
else
update
val
list
=
if
(
update
==
null
||
update
.
isEmpty
)
default
else
update
"exclude = "
+
list
+
";"
"exclude = "
+
list
+
";"
}
catch
{
}
catch
{
case
ex
:
Exception
=>
"exclude = "
+
default
+
";"
case
_
:
Exception
=>
"exclude = "
+
default
+
";"
}
}
}
}
}
}
src/main/scala/com/github/shadowsocks/BootReceiver.scala
View file @
a5df60ae
...
@@ -25,16 +25,16 @@ import android.content.{BroadcastReceiver, ComponentName, Context, Intent}
...
@@ -25,16 +25,16 @@ import android.content.{BroadcastReceiver, ComponentName, Context, Intent}
import
com.github.shadowsocks.utils._
import
com.github.shadowsocks.utils._
object
BootReceiver
{
object
BootReceiver
{
def
getEnabled
(
context
:
Context
)
=
PackageManager
.
COMPONENT_ENABLED_STATE_ENABLED
==
def
getEnabled
(
context
:
Context
)
:
Boolean
=
PackageManager
.
COMPONENT_ENABLED_STATE_ENABLED
==
context
.
getPackageManager
.
getComponentEnabledSetting
(
new
ComponentName
(
context
,
classOf
[
BootReceiver
]))
context
.
getPackageManager
.
getComponentEnabledSetting
(
new
ComponentName
(
context
,
classOf
[
BootReceiver
]))
def
setEnabled
(
context
:
Context
,
enabled
:
Boolean
)
=
context
.
getPackageManager
.
setComponentEnabledSetting
(
def
setEnabled
(
context
:
Context
,
enabled
:
Boolean
)
:
Unit
=
context
.
getPackageManager
.
setComponentEnabledSetting
(
new
ComponentName
(
context
,
classOf
[
BootReceiver
]),
new
ComponentName
(
context
,
classOf
[
BootReceiver
]),
if
(
enabled
)
PackageManager
.
COMPONENT_ENABLED_STATE_ENABLED
else
PackageManager
.
COMPONENT_ENABLED_STATE_DISABLED
,
if
(
enabled
)
PackageManager
.
COMPONENT_ENABLED_STATE_ENABLED
else
PackageManager
.
COMPONENT_ENABLED_STATE_DISABLED
,
PackageManager
.
DONT_KILL_APP
)
PackageManager
.
DONT_KILL_APP
)
}
}
class
BootReceiver
extends
BroadcastReceiver
{
class
BootReceiver
extends
BroadcastReceiver
{
def
onReceive
(
context
:
Context
,
intent
:
Intent
)
=
{
def
onReceive
(
context
:
Context
,
intent
:
Intent
)
:
Unit
=
{
Utils
.
startSsService
(
context
)
Utils
.
startSsService
(
context
)
}
}
}
}
src/main/scala/com/github/shadowsocks/GuardedProcess.scala
View file @
a5df60ae
...
@@ -25,24 +25,16 @@ import java.lang.System.currentTimeMillis
...
@@ -25,24 +25,16 @@ import java.lang.System.currentTimeMillis
import
java.util.concurrent.Semaphore
import
java.util.concurrent.Semaphore
import
android.util.Log
import
android.util.Log
import
com.github.shadowsocks.utils.CloseUtils._
import
scala.collection.JavaConversions._
import
scala.collection.JavaConversions._
import
scala.collection.immutable.Stream
import
scala.collection.immutable.Stream
import
scala.util.control.Exception._
class
StreamLogger
(
is
:
InputStream
,
tag
:
String
)
extends
Thread
{
class
StreamLogger
(
is
:
InputStream
,
tag
:
String
)
extends
Thread
{
override
def
run
()
:
Unit
=
autoClose
(
new
BufferedReader
(
new
InputStreamReader
(
is
)))(
br
=>
def
withCloseable
[
T
<:
Closeable
,
R
](
t
:
T
)(
f
:
T
=>
R
)
:
R
=
{
try
Stream
.
continually
(
br
.
readLine
()).
takeWhile
(
_
!=
null
).
foreach
(
Log
.
i
(
tag
,
_
))
catch
{
allCatch
.
andFinally
{
t
.
close
}
apply
{
f
(
t
)
}
case
_:
IOException
=>
}
})
override
def
run
()
{
withCloseable
(
new
BufferedReader
(
new
InputStreamReader
(
is
)))
{
br
=>
try
Stream
.
continually
(
br
.
readLine
()).
takeWhile
(
_
!=
null
).
foreach
(
Log
.
i
(
tag
,
_
))
catch
{
case
ignore
:
IOException
=>
}
}
}
}
}
/**
/**
...
@@ -58,7 +50,7 @@ class GuardedProcess(cmd: Seq[String]) {
...
@@ -58,7 +50,7 @@ class GuardedProcess(cmd: Seq[String]) {
def
start
(
onRestartCallback
:
()
=>
Unit
=
null
)
:
GuardedProcess
=
{
def
start
(
onRestartCallback
:
()
=>
Unit
=
null
)
:
GuardedProcess
=
{
val
semaphore
=
new
Semaphore
(
1
)
val
semaphore
=
new
Semaphore
(
1
)
semaphore
.
acquire
semaphore
.
acquire
()
@volatile
var
ioException
:
IOException
=
null
@volatile
var
ioException
:
IOException
=
null
guardThread
=
new
Thread
(()
=>
{
guardThread
=
new
Thread
(()
=>
{
...
@@ -71,11 +63,11 @@ class GuardedProcess(cmd: Seq[String]) {
...
@@ -71,11 +63,11 @@ class GuardedProcess(cmd: Seq[String]) {
process
=
new
ProcessBuilder
(
cmd
).
redirectErrorStream
(
true
).
start
process
=
new
ProcessBuilder
(
cmd
).
redirectErrorStream
(
true
).
start
val
is
=
process
.
getInputStream
val
is
=
process
.
getInputStream
new
StreamLogger
(
is
,
TAG
).
start
new
StreamLogger
(
is
,
TAG
).
start
()
if
(
callback
==
null
)
callback
=
onRestartCallback
else
callback
()
if
(
callback
==
null
)
callback
=
onRestartCallback
else
callback
()
semaphore
.
release
semaphore
.
release
()
process
.
waitFor
process
.
waitFor
this
.
synchronized
{
this
.
synchronized
{
...
@@ -88,22 +80,19 @@ class GuardedProcess(cmd: Seq[String]) {
...
@@ -88,22 +80,19 @@ class GuardedProcess(cmd: Seq[String]) {
}
}
}
}
}
}
}
}
}
catch
{
}
catch
{
case
ignored
:
InterruptedException
=>
case
_
:
InterruptedException
=>
Log
.
i
(
TAG
,
"thread interrupt, destroy process: "
+
cmd
)
Log
.
i
(
TAG
,
"thread interrupt, destroy process: "
+
cmd
)
process
.
destroy
()
process
.
destroy
()
case
e
:
IOException
=>
ioException
=
e
case
e
:
IOException
=>
ioException
=
e
}
finally
semaphore
.
release
}
finally
semaphore
.
release
()
},
"GuardThread-"
+
cmd
)
},
"GuardThread-"
+
cmd
)
guardThread
.
start
()
guardThread
.
start
()
semaphore
.
acquire
semaphore
.
acquire
()
if
(
ioException
!=
null
)
{
if
(
ioException
!=
null
)
throw
ioException
throw
ioException
}
this
this
}
}
...
@@ -113,7 +102,7 @@ class GuardedProcess(cmd: Seq[String]) {
...
@@ -113,7 +102,7 @@ class GuardedProcess(cmd: Seq[String]) {
guardThread
.
interrupt
()
guardThread
.
interrupt
()
process
.
destroy
()
process
.
destroy
()
try
guardThread
.
join
()
catch
{
try
guardThread
.
join
()
catch
{
case
ignored
:
InterruptedException
=>
case
_
:
InterruptedException
=>
}
}
}
}
...
@@ -125,7 +114,7 @@ class GuardedProcess(cmd: Seq[String]) {
...
@@ -125,7 +114,7 @@ class GuardedProcess(cmd: Seq[String]) {
}
}
@throws
(
classOf
[
InterruptedException
])
@throws
(
classOf
[
InterruptedException
])
def
waitFor
=
{
def
waitFor
:
Int
=
{
guardThread
.
join
()
guardThread
.
join
()
0
0
}
}
...
...
src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala
View file @
a5df60ae
...
@@ -22,7 +22,7 @@ package com.github.shadowsocks
...
@@ -22,7 +22,7 @@ package com.github.shadowsocks
import
java.nio.charset.Charset
import
java.nio.charset.Charset
import
android.app.
{
Activity
,
TaskStackBuilder
}
import
android.app.
TaskStackBuilder
import
android.content._
import
android.content._
import
android.content.pm.PackageManager
import
android.content.pm.PackageManager
import
android.nfc.NfcAdapter.CreateNdefMessageCallback
import
android.nfc.NfcAdapter.CreateNdefMessageCallback
...
@@ -97,7 +97,7 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
...
@@ -97,7 +97,7 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
})
})
shareBtn
.
setOnLongClickListener
(
_
=>
{
shareBtn
.
setOnLongClickListener
(
_
=>
{
Utils
.
positionToast
(
Toast
.
makeText
(
ProfileManagerActivity
.
this
,
R
.
string
.
share
,
Toast
.
LENGTH_SHORT
),
shareBtn
,
Utils
.
positionToast
(
Toast
.
makeText
(
ProfileManagerActivity
.
this
,
R
.
string
.
share
,
Toast
.
LENGTH_SHORT
),
shareBtn
,
getWindow
,
0
,
Utils
.
dpToPx
(
ProfileManagerActivity
.
this
,
8
)).
show
getWindow
,
0
,
Utils
.
dpToPx
(
ProfileManagerActivity
.
this
,
8
)).
show
()
true
true
})
})
}
}
...
@@ -131,41 +131,42 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
...
@@ -131,41 +131,42 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
def
onClick
(
v
:
View
)
{
def
onClick
(
v
:
View
)
{
app
.
switchProfile
(
item
.
id
)
app
.
switchProfile
(
item
.
id
)
finish
finish
()
}
}
def
onKey
(
v
:
View
,
keyCode
:
Int
,
event
:
KeyEvent
)
=
if
(
event
.
getAction
==
KeyEvent
.
ACTION_DOWN
)
keyCode
match
{
def
onKey
(
v
:
View
,
keyCode
:
Int
,
event
:
KeyEvent
)
:
Boolean
=
case
KeyEvent
.
KEYCODE_DPAD_LEFT
=>
if
(
event
.
getAction
==
KeyEvent
.
ACTION_DOWN
)
keyCode
match
{
val
index
=
getAdapterPosition
case
KeyEvent
.
KEYCODE_DPAD_LEFT
=>
if
(
index
>=
0
)
{
val
index
=
getAdapterPosition
profilesAdapter
.
remove
(
index
)
if
(
index
>=
0
)
{
undoManager
.
remove
(
index
,
item
)
profilesAdapter
.
remove
(
index
)
true
undoManager
.
remove
(
index
,
item
)
}
else
false
true
case
_
=>
false
}
else
false
}
else
false
case
_
=>
false
}
else
false
}
}
private
class
ProfilesAdapter
extends
RecyclerView
.
Adapter
[
ProfileViewHolder
]
{
private
class
ProfilesAdapter
extends
RecyclerView
.
Adapter
[
ProfileViewHolder
]
{
var
profiles
=
new
ArrayBuffer
[
Profile
]
var
profiles
=
new
ArrayBuffer
[
Profile
]
profiles
++=
app
.
profileManager
.
getAllProfiles
.
getOrElse
(
List
.
empty
[
Profile
])
profiles
++=
app
.
profileManager
.
getAllProfiles
.
getOrElse
(
List
.
empty
[
Profile
])
def
getItemCount
=
profiles
.
length
def
getItemCount
:
Int
=
profiles
.
length
def
onBindViewHolder
(
vh
:
ProfileViewHolder
,
i
:
Int
)
=
vh
.
bind
(
profiles
(
i
))
def
onBindViewHolder
(
vh
:
ProfileViewHolder
,
i
:
Int
)
:
Unit
=
vh
.
bind
(
profiles
(
i
))
def
onCreateViewHolder
(
vg
:
ViewGroup
,
i
:
Int
)
=
def
onCreateViewHolder
(
vg
:
ViewGroup
,
i
:
Int
)
=
new
ProfileViewHolder
(
LayoutInflater
.
from
(
vg
.
getContext
).
inflate
(
R
.
layout
.
layout_profiles_item
,
vg
,
false
))
new
ProfileViewHolder
(
LayoutInflater
.
from
(
vg
.
getContext
).
inflate
(
R
.
layout
.
layout_profiles_item
,
vg
,
false
))
def
add
(
item
:
Profile
)
{
def
add
(
item
:
Profile
)
{
undoManager
.
flush
undoManager
.
flush
()
val
pos
=
getItemCount
val
pos
=
getItemCount
profiles
+=
item
profiles
+=
item
notifyItemInserted
(
pos
)
notifyItemInserted
(
pos
)
}
}
def
move
(
from
:
Int
,
to
:
Int
)
{
def
move
(
from
:
Int
,
to
:
Int
)
{
undoManager
.
flush
undoManager
.
flush
()
val
step
=
if
(
from
<
to
)
1
else
-
1
val
step
=
if
(
from
<
to
)
1
else
-
1
val
first
=
profiles
(
from
)
val
first
=
profiles
(
from
)
var
previousOrder
=
profiles
(
from
).
userOrder
var
previousOrder
=
profiles
(
from
).
userOrder
...
@@ -187,11 +188,11 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
...
@@ -187,11 +188,11 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
profiles
.
remove
(
pos
)
profiles
.
remove
(
pos
)
notifyItemRemoved
(
pos
)
notifyItemRemoved
(
pos
)
}
}
def
undo
(
actions
:
Iterator
[(
Int
,
Profile
)])
=
for
((
index
,
item
)
<-
actions
)
{
def
undo
(
actions
:
Iterator
[(
Int
,
Profile
)])
:
Unit
=
for
((
index
,
item
)
<-
actions
)
{
profiles
.
insert
(
index
,
item
)
profiles
.
insert
(
index
,
item
)
notifyItemInserted
(
index
)
notifyItemInserted
(
index
)
}
}
def
commit
(
actions
:
Iterator
[(
Int
,
Profile
)])
=
for
((
index
,
item
)
<-
actions
)
{
def
commit
(
actions
:
Iterator
[(
Int
,
Profile
)])
:
Unit
=
for
((
_
,
item
)
<-
actions
)
{
app
.
profileManager
.
delProfile
(
item
.
id
)
app
.
profileManager
.
delProfile
(
item
.
id
)
if
(
item
.
id
==
app
.
profileId
)
app
.
profileId
(-
1
)
if
(
item
.
id
==
app
.
profileId
)
app
.
profileId
(-
1
)
}
}
...
@@ -214,8 +215,6 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
...
@@ -214,8 +215,6 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
private
var
isNfcEnabled
:
Boolean
=
_
private
var
isNfcEnabled
:
Boolean
=
_
private
var
isNfcBeamEnabled
:
Boolean
=
_
private
var
isNfcBeamEnabled
:
Boolean
=
_
private
val
REQUEST_QRCODE
=
1
override
def
onCreate
(
savedInstanceState
:
Bundle
)
{
override
def
onCreate
(
savedInstanceState
:
Bundle
)
{
super
.
onCreate
(
savedInstanceState
)
super
.
onCreate
(
savedInstanceState
)
setContentView
(
R
.
layout
.
layout_profiles
)
setContentView
(
R
.
layout
.
layout_profiles
)
...
@@ -246,27 +245,27 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
...
@@ -246,27 +245,27 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
undoManager
=
new
UndoSnackbarManager
[
Profile
](
profilesList
,
profilesAdapter
.
undo
,
profilesAdapter
.
commit
)
undoManager
=
new
UndoSnackbarManager
[
Profile
](
profilesList
,
profilesAdapter
.
undo
,
profilesAdapter
.
commit
)
new
ItemTouchHelper
(
new
SimpleCallback
(
ItemTouchHelper
.
UP
|
ItemTouchHelper
.
DOWN
,
new
ItemTouchHelper
(
new
SimpleCallback
(
ItemTouchHelper
.
UP
|
ItemTouchHelper
.
DOWN
,
ItemTouchHelper
.
START
|
ItemTouchHelper
.
END
)
{
ItemTouchHelper
.
START
|
ItemTouchHelper
.
END
)
{
def
onSwiped
(
viewHolder
:
ViewHolder
,
direction
:
Int
)
=
{
def
onSwiped
(
viewHolder
:
ViewHolder
,
direction
:
Int
)
{
val
index
=
viewHolder
.
getAdapterPosition
val
index
=
viewHolder
.
getAdapterPosition
profilesAdapter
.
remove
(
index
)
profilesAdapter
.
remove
(
index
)
undoManager
.
remove
(
index
,
viewHolder
.
asInstanceOf
[
ProfileViewHolder
].
item
)
undoManager
.
remove
(
index
,
viewHolder
.
asInstanceOf
[
ProfileViewHolder
].
item
)
}
}
def
onMove
(
recyclerView
:
RecyclerView
,
viewHolder
:
ViewHolder
,
target
:
ViewHolder
)
=
{
def
onMove
(
recyclerView
:
RecyclerView
,
viewHolder
:
ViewHolder
,
target
:
ViewHolder
)
:
Boolean
=
{
profilesAdapter
.
move
(
viewHolder
.
getAdapterPosition
,
target
.
getAdapterPosition
)
profilesAdapter
.
move
(
viewHolder
.
getAdapterPosition
,
target
.
getAdapterPosition
)
true
true
}
}
}).
attachToRecyclerView
(
profilesList
)
}).
attachToRecyclerView
(
profilesList
)
attachService
(
new
IShadowsocksServiceCallback
.
Stub
{
attachService
(
new
IShadowsocksServiceCallback
.
Stub
{
def
stateChanged
(
state
:
Int
,
profileName
:
String
,
msg
:
String
)
=
()
// ignore
def
stateChanged
(
state
:
Int
,
profileName
:
String
,
msg
:
String
)
:
Unit
=
()
// ignore
def
trafficUpdated
(
txRate
:
Long
,
rxRate
:
Long
,
txTotal
:
Long
,
rxTotal
:
Long
)
=
def
trafficUpdated
(
txRate
:
Long
,
rxRate
:
Long
,
txTotal
:
Long
,
rxTotal
:
Long
)
:
Unit
=
if
(
selectedItem
!=
null
)
selectedItem
.
updateText
(
txTotal
,
rxTotal
)
if
(
selectedItem
!=
null
)
selectedItem
.
updateText
(
txTotal
,
rxTotal
)
})
})
if
(
app
.
settings
.
getBoolean
(
Key
.
profileTip
,
true
))
{
if
(
app
.
settings
.
getBoolean
(
Key
.
profileTip
,
true
))
{
app
.
editor
.
putBoolean
(
Key
.
profileTip
,
false
).
apply
app
.
editor
.
putBoolean
(
Key
.
profileTip
,
false
).
apply
()
new
AlertDialog
.
Builder
(
this
).
setTitle
(
R
.
string
.
profile_manager_dialog
)
new
AlertDialog
.
Builder
(
this
).
setTitle
(
R
.
string
.
profile_manager_dialog
)
.
setMessage
(
R
.
string
.
profile_manager_dialog_content
).
setPositiveButton
(
R
.
string
.
gotcha
,
null
).
create
.
show
.
setMessage
(
R
.
string
.
profile_manager_dialog_content
).
setPositiveButton
(
R
.
string
.
gotcha
,
null
).
create
().
show
()
}
}
val
intent
=
getIntent
val
intent
=
getIntent
...
@@ -311,7 +310,7 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
...
@@ -311,7 +310,7 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
val
profile
=
app
.
profileManager
.
createProfile
()
val
profile
=
app
.
profileManager
.
createProfile
()
app
.
profileManager
.
updateProfile
(
profile
)
app
.
profileManager
.
updateProfile
(
profile
)
app
.
switchProfile
(
profile
.
id
)
app
.
switchProfile
(
profile
.
id
)
finish
finish
()
case
R
.
id
.
fab_qrcode_add
=>
case
R
.
id
.
fab_qrcode_add
=>
menu
.
toggle
(
false
)
menu
.
toggle
(
false
)
val
intent
=
new
Intent
(
this
,
classOf
[
ScannerActivity
])
val
intent
=
new
Intent
(
this
,
classOf
[
ScannerActivity
])
...
@@ -331,18 +330,18 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
...
@@ -331,18 +330,18 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
}
else
{
}
else
{
dialog
.
setMessage
(
getString
(
R
.
string
.
add_profile_nfc_hint
))
dialog
.
setMessage
(
getString
(
R
.
string
.
add_profile_nfc_hint
))
}
}
dialog
.
show
dialog
.
show
()
case
R
.
id
.
fab_import_add
=>
case
R
.
id
.
fab_import_add
=>
menu
.
toggle
(
true
)
menu
.
toggle
(
true
)
if
(
clipboard
.
hasPrimaryClip
)
{
if
(
clipboard
.
hasPrimaryClip
)
{
val
profiles
=
Parser
.
findAll
(
clipboard
.
getPrimaryClip
.
getItemAt
(
0
).
getText
)
val
profiles
=
Parser
.
findAll
(
clipboard
.
getPrimaryClip
.
getItemAt
(
0
).
getText
)
if
(
profiles
.
nonEmpty
)
{
if
(
profiles
.
nonEmpty
)
{
profiles
.
foreach
(
app
.
profileManager
.
createProfile
)
profiles
.
foreach
(
app
.
profileManager
.
createProfile
)
Toast
.
makeText
(
this
,
R
.
string
.
action_import_msg
,
Toast
.
LENGTH_SHORT
).
show
Toast
.
makeText
(
this
,
R
.
string
.
action_import_msg
,
Toast
.
LENGTH_SHORT
).
show
()
return
return
}
}
}
}
Toast
.
makeText
(
this
,
R
.
string
.
action_import_err
,
Toast
.
LENGTH_SHORT
).
show
Toast
.
makeText
(
this
,
R
.
string
.
action_import_err
,
Toast
.
LENGTH_SHORT
).
show
()
}
}
}
}
...
@@ -398,11 +397,11 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
...
@@ -398,11 +397,11 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
unregisterCallback
unregisterCallback
}
}
override
def
onDestroy
{
override
def
onDestroy
()
{
detachService
()
detachService
()
undoManager
.
flush
undoManager
.
flush
()
app
.
profileManager
.
setProfileAddedListener
(
null
)
app
.
profileManager
.
setProfileAddedListener
(
null
)
super
.
onDestroy
super
.
onDestroy
()
}
}
override
def
onBackPressed
()
{
override
def
onBackPressed
()
{
...
@@ -417,8 +416,8 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
...
@@ -417,8 +416,8 @@ final class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClic
app
.
profileManager
.
getAllProfiles
match
{
app
.
profileManager
.
getAllProfiles
match
{
case
Some
(
profiles
)
=>
case
Some
(
profiles
)
=>
clipboard
.
setPrimaryClip
(
ClipData
.
newPlainText
(
null
,
profiles
.
mkString
(
"\n"
)))
clipboard
.
setPrimaryClip
(
ClipData
.
newPlainText
(
null
,
profiles
.
mkString
(
"\n"
)))
Toast
.
makeText
(
this
,
R
.
string
.
action_export_msg
,
Toast
.
LENGTH_SHORT
).
show
Toast
.
makeText
(
this
,
R
.
string
.
action_export_msg
,
Toast
.
LENGTH_SHORT
).
show
()
case
_
=>
Toast
.
makeText
(
this
,
R
.
string
.
action_export_err
,
Toast
.
LENGTH_SHORT
).
show
case
_
=>
Toast
.
makeText
(
this
,
R
.
string
.
action_export_err
,
Toast
.
LENGTH_SHORT
).
show
()
}
}
true
true
case
_
=>
false
case
_
=>
false
...
...
src/main/scala/com/github/shadowsocks/ScannerActivity.scala
View file @
a5df60ae
...
@@ -20,8 +20,7 @@
...
@@ -20,8 +20,7 @@
package
com.github.shadowsocks
package
com.github.shadowsocks
import
android.app.
{
Activity
,
TaskStackBuilder
}
import
android.app.TaskStackBuilder
import
android.content.Intent
import
android.content.pm.
{
PackageManager
,
ShortcutManager
}
import
android.content.pm.
{
PackageManager
,
ShortcutManager
}
import
android.os.
{
Build
,
Bundle
}
import
android.os.
{
Build
,
Bundle
}
import
android.support.v4.app.ActivityCompat
import
android.support.v4.app.ActivityCompat
...
@@ -30,9 +29,9 @@ import android.support.v7.app.AppCompatActivity
...
@@ -30,9 +29,9 @@ import android.support.v7.app.AppCompatActivity
import
android.support.v7.widget.Toolbar
import
android.support.v7.widget.Toolbar
import
android.text.TextUtils
import
android.text.TextUtils
import
android.widget.Toast
import
android.widget.Toast
import
com.google.zxing.Result
import
com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.utils.Parser
import
com.github.shadowsocks.utils.Parser
import
com.google.zxing.Result
import
me.dm7.barcodescanner.zxing.ZXingScannerView
import
me.dm7.barcodescanner.zxing.ZXingScannerView
object
ScannerActivity
{
object
ScannerActivity
{
...
@@ -95,7 +94,7 @@ class ScannerActivity extends AppCompatActivity with ZXingScannerView.ResultHand
...
@@ -95,7 +94,7 @@ class ScannerActivity extends AppCompatActivity with ZXingScannerView.ResultHand
scannerView
.
stopCamera
()
// Stop camera on pause
scannerView
.
stopCamera
()
// Stop camera on pause
}
}
override
def
handleResult
(
rawResult
:
Result
)
=
{
override
def
handleResult
(
rawResult
:
Result
)
{
val
uri
=
rawResult
.
getText
val
uri
=
rawResult
.
getText
if
(!
TextUtils
.
isEmpty
(
uri
))
if
(!
TextUtils
.
isEmpty
(
uri
))
Parser
.
findAll
(
uri
).
foreach
(
app
.
profileManager
.
createProfile
)
Parser
.
findAll
(
uri
).
foreach
(
app
.
profileManager
.
createProfile
)
...
...
src/main/scala/com/github/shadowsocks/ServiceBoundContext.scala
View file @
a5df60ae
...
@@ -35,34 +35,34 @@ trait ServiceBoundContext extends Context with IBinder.DeathRecipient {
...
@@ -35,34 +35,34 @@ trait ServiceBoundContext extends Context with IBinder.DeathRecipient {
binder
=
service
binder
=
service
service
.
linkToDeath
(
ServiceBoundContext
.
this
,
0
)
service
.
linkToDeath
(
ServiceBoundContext
.
this
,
0
)
bgService
=
IShadowsocksService
.
Stub
.
asInterface
(
service
)
bgService
=
IShadowsocksService
.
Stub
.
asInterface
(
service
)
registerCallback
registerCallback
()
ServiceBoundContext
.
this
.
onServiceConnected
()
ServiceBoundContext
.
this
.
onServiceConnected
()
}
}
override
def
onServiceDisconnected
(
name
:
ComponentName
)
{
override
def
onServiceDisconnected
(
name
:
ComponentName
)
{
unregisterCallback
unregisterCallback
()
ServiceBoundContext
.
this
.
onServiceDisconnected
()
ServiceBoundContext
.
this
.
onServiceDisconnected
()
bgService
=
null
bgService
=
null
binder
=
null
binder
=
null
}
}
}
}
protected
def
registerCallback
=
if
(
bgService
!=
null
&&
callback
!=
null
&&
!
callbackRegistered
)
try
{
protected
def
registerCallback
()
:
Unit
=
if
(
bgService
!=
null
&&
callback
!=
null
&&
!
callbackRegistered
)
try
{
bgService
.
registerCallback
(
callback
)
bgService
.
registerCallback
(
callback
)
callbackRegistered
=
true
callbackRegistered
=
true
}
catch
{
}
catch
{
case
ignored
:
RemoteException
=>
// Nothing
case
_
:
RemoteException
=>
// Nothing
}
}
protected
def
unregisterCallback
=
{
protected
def
unregisterCallback
()
{
if
(
bgService
!=
null
&&
callback
!=
null
&&
callbackRegistered
)
try
bgService
.
unregisterCallback
(
callback
)
catch
{
if
(
bgService
!=
null
&&
callback
!=
null
&&
callbackRegistered
)
try
bgService
.
unregisterCallback
(
callback
)
catch
{
case
ignored
:
RemoteException
=>
case
_
:
RemoteException
=>
}
}
callbackRegistered
=
false
callbackRegistered
=
false
}
}
def
onServiceConnected
()
=
()
def
onServiceConnected
()
:
Unit
=
()
def
onServiceDisconnected
()
=
()
def
onServiceDisconnected
()
:
Unit
=
()
override
def
binderDied
=
()
override
def
binderDied
()
:
Unit
=
()
private
var
callback
:
IShadowsocksServiceCallback.Stub
=
_
private
var
callback
:
IShadowsocksServiceCallback.Stub
=
_
private
var
connection
:
ShadowsocksServiceConnection
=
_
private
var
connection
:
ShadowsocksServiceConnection
=
_
...
@@ -86,7 +86,7 @@ trait ServiceBoundContext extends Context with IBinder.DeathRecipient {
...
@@ -86,7 +86,7 @@ trait ServiceBoundContext extends Context with IBinder.DeathRecipient {
}
}
def
detachService
()
{
def
detachService
()
{
unregisterCallback
unregisterCallback
()
callback
=
null
callback
=
null
if
(
connection
!=
null
)
{
if
(
connection
!=
null
)
{
try
unbindService
(
connection
)
catch
{
try
unbindService
(
connection
)
catch
{
...
...
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
View file @
a5df60ae
...
@@ -123,7 +123,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
...
@@ -123,7 +123,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
getString
(
R
.
string
.
vpn_error
).
formatLocal
(
Locale
.
ENGLISH
,
m
),
Snackbar
.
LENGTH_LONG
)
getString
(
R
.
string
.
vpn_error
).
formatLocal
(
Locale
.
ENGLISH
,
m
),
Snackbar
.
LENGTH_LONG
)
if
(
m
==
getString
(
R
.
string
.
nat_no_root
))
snackbar
.
setAction
(
R
.
string
.
switch_to_vpn
,
if
(
m
==
getString
(
R
.
string
.
nat_no_root
))
snackbar
.
setAction
(
R
.
string
.
switch_to_vpn
,
(
_
=>
preferences
.
natSwitch
.
setChecked
(
false
))
:
View.OnClickListener
)
(
_
=>
preferences
.
natSwitch
.
setChecked
(
false
))
:
View.OnClickListener
)
snackbar
.
show
snackbar
.
show
()
Log
.
e
(
TAG
,
"Error to start VPN service: "
+
m
)
Log
.
e
(
TAG
,
"Error to start VPN service: "
+
m
)
}
}
preferences
.
setEnabled
(
true
)
preferences
.
setEnabled
(
true
)
...
@@ -151,7 +151,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
...
@@ -151,7 +151,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
rxRateText
.
setText
(
TrafficMonitor
.
formatTraffic
(
rxRate
)
+
"/s"
)
rxRateText
.
setText
(
TrafficMonitor
.
formatTraffic
(
rxRate
)
+
"/s"
)
}
}
def
attachService
:
Unit
=
attachService
(
callback
)
def
attachService
Callback
()
:
Unit
=
attachService
(
callback
)
override
def
onServiceConnected
()
{
override
def
onServiceConnected
()
{
// Update the UI
// Update the UI
...
@@ -160,7 +160,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
...
@@ -160,7 +160,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
if
(
Build
.
VERSION
.
SDK_INT
>=
21
&&
app
.
isNatEnabled
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
21
&&
app
.
isNatEnabled
)
{
val
snackbar
=
Snackbar
.
make
(
findViewById
(
android
.
R
.
id
.
content
),
R
.
string
.
nat_deprecated
,
Snackbar
.
LENGTH_LONG
)
val
snackbar
=
Snackbar
.
make
(
findViewById
(
android
.
R
.
id
.
content
),
R
.
string
.
nat_deprecated
,
Snackbar
.
LENGTH_LONG
)
snackbar
.
setAction
(
R
.
string
.
switch_to_vpn
,
(
_
=>
preferences
.
natSwitch
.
setChecked
(
false
))
:
View.OnClickListener
)
snackbar
.
setAction
(
R
.
string
.
switch_to_vpn
,
(
_
=>
preferences
.
natSwitch
.
setChecked
(
false
))
:
View.OnClickListener
)
snackbar
.
show
snackbar
.
show
()
}
}
}
}
...
@@ -168,10 +168,10 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
...
@@ -168,10 +168,10 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
if
(
fab
!=
null
)
fab
.
setEnabled
(
false
)
if
(
fab
!=
null
)
fab
.
setEnabled
(
false
)
}
}
override
def
binderDied
{
override
def
binderDied
()
{
detachService
()
detachService
()
app
.
crashRecovery
()
app
.
crashRecovery
()
attachService
attachService
Callback
()
}
}
private
var
testCount
:
Int
=
_
private
var
testCount
:
Int
=
_
...
@@ -243,7 +243,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
...
@@ -243,7 +243,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
title
.
setOnClickListener
(
_
=>
startActivity
(
new
Intent
(
this
,
classOf
[
ProfileManagerActivity
])))
title
.
setOnClickListener
(
_
=>
startActivity
(
new
Intent
(
this
,
classOf
[
ProfileManagerActivity
])))
val
typedArray
=
obtainStyledAttributes
(
Array
(
R
.
attr
.
selectableItemBackgroundBorderless
))
val
typedArray
=
obtainStyledAttributes
(
Array
(
R
.
attr
.
selectableItemBackgroundBorderless
))
title
.
setBackgroundResource
(
typedArray
.
getResourceId
(
0
,
0
))
title
.
setBackgroundResource
(
typedArray
.
getResourceId
(
0
,
0
))
typedArray
.
recycle
typedArray
.
recycle
()
val
tf
=
Typefaces
.
get
(
this
,
"fonts/Iceland.ttf"
)
val
tf
=
Typefaces
.
get
(
this
,
"fonts/Iceland.ttf"
)
if
(
tf
!=
null
)
title
.
setTypeface
(
tf
)
if
(
tf
!=
null
)
title
.
setTypeface
(
tf
)
title
.
setCompoundDrawablesWithIntrinsicBounds
(
0
,
0
,
R
.
drawable
.
ic_arrow_drop_down
,
0
)
title
.
setCompoundDrawablesWithIntrinsicBounds
(
0
,
0
,
R
.
drawable
.
ic_arrow_drop_down
,
0
)
...
@@ -287,7 +287,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
...
@@ -287,7 +287,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
synchronized
(
if
(
testCount
==
id
&&
app
.
isVpnEnabled
)
handler
.
post
(()
=>
synchronized
(
if
(
testCount
==
id
&&
app
.
isVpnEnabled
)
handler
.
post
(()
=>
if
(
success
)
connectionTestText
.
setText
(
result
)
else
{
if
(
success
)
connectionTestText
.
setText
(
result
)
else
{
connectionTestText
.
setText
(
R
.
string
.
connection_test_fail
)
connectionTestText
.
setText
(
R
.
string
.
connection_test_fail
)
Snackbar
.
make
(
findViewById
(
android
.
R
.
id
.
content
),
result
,
Snackbar
.
LENGTH_LONG
).
show
Snackbar
.
make
(
findViewById
(
android
.
R
.
id
.
content
),
result
,
Snackbar
.
LENGTH_LONG
).
show
()
}))
}))
}
}
}
}
...
@@ -301,12 +301,12 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
...
@@ -301,12 +301,12 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
else
changeSwitch
(
checked
=
false
))
else
changeSwitch
(
checked
=
false
))
fab
.
setOnLongClickListener
((
v
:
View
)
=>
{
fab
.
setOnLongClickListener
((
v
:
View
)
=>
{
Utils
.
positionToast
(
Toast
.
makeText
(
this
,
if
(
serviceStarted
)
R
.
string
.
stop
else
R
.
string
.
connect
,
Utils
.
positionToast
(
Toast
.
makeText
(
this
,
if
(
serviceStarted
)
R
.
string
.
stop
else
R
.
string
.
connect
,
Toast
.
LENGTH_SHORT
),
fab
,
getWindow
,
0
,
Utils
.
dpToPx
(
this
,
8
)).
show
Toast
.
LENGTH_SHORT
),
fab
,
getWindow
,
0
,
Utils
.
dpToPx
(
this
,
8
)).
show
()
true
true
})
})
updateTraffic
(
0
,
0
,
0
,
0
)
updateTraffic
(
0
,
0
,
0
,
0
)
handler
.
post
(
()
=>
attachService
)
handler
.
post
(
attachServiceCallback
)
}
}
private
def
hideCircle
()
{
private
def
hideCircle
()
{
...
@@ -412,11 +412,11 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
...
@@ -412,11 +412,11 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
override
def
onStart
()
{
override
def
onStart
()
{
super
.
onStart
()
super
.
onStart
()
registerCallback
registerCallback
()
}
}
override
def
onStop
()
{
override
def
onStop
()
{
super
.
onStop
()
super
.
onStop
()
unregisterCallback
unregisterCallback
()
clearDialog
()
clearDialog
()
}
}
...
@@ -436,7 +436,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
...
@@ -436,7 +436,7 @@ class Shadowsocks extends AppCompatActivity with ServiceBoundContext {
}
}
}
}
override
def
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
data
:
Intent
)
=
resultCode
match
{
override
def
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
data
:
Intent
)
:
Unit
=
resultCode
match
{
case
Activity
.
RESULT_OK
=>
case
Activity
.
RESULT_OK
=>
serviceLoad
()
serviceLoad
()
case
_
=>
case
_
=>
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksApplication.scala
View file @
a5df60ae
...
@@ -27,17 +27,18 @@ import java.util.concurrent.TimeUnit
...
@@ -27,17 +27,18 @@ import java.util.concurrent.TimeUnit
import
android.annotation.SuppressLint
import
android.annotation.SuppressLint
import
android.app.Application
import
android.app.Application
import
android.content.SharedPreferences
import
android.content.res.Configuration
import
android.content.res.Configuration
import
android.os.
{
Build
,
LocaleList
}
import
android.os.
{
Build
,
LocaleList
}
import
android.preference.PreferenceManager
import
android.preference.PreferenceManager
import
android.support.v7.app.AppCompatDelegate
import
android.support.v7.app.AppCompatDelegate
import
android.util.Log
import
android.util.Log
import
com.evernote.android.job.JobManager
import
com.evernote.android.job.JobManager
import
com.github.shadowsocks.database.
{
DBHelper
,
ProfileManager
}
import
com.github.shadowsocks.database.
{
DBHelper
,
Profile
,
Profile
Manager
}
import
com.github.shadowsocks.job.DonaldTrump
import
com.github.shadowsocks.job.DonaldTrump
import
com.github.shadowsocks.utils.CloseUtils._
import
com.github.shadowsocks.utils.CloseUtils._
import
com.github.shadowsocks.utils._
import
com.github.shadowsocks.utils._
import
com.google.android.gms.analytics.
{
GoogleAnalytics
,
HitBuilders
,
StandardExceptionParser
}
import
com.google.android.gms.analytics.
{
GoogleAnalytics
,
HitBuilders
,
StandardExceptionParser
,
Tracker
}
import
com.google.android.gms.common.api.ResultCallback
import
com.google.android.gms.common.api.ResultCallback
import
com.google.android.gms.tagmanager.
{
ContainerHolder
,
TagManager
}
import
com.google.android.gms.tagmanager.
{
ContainerHolder
,
TagManager
}
import
com.j256.ormlite.logger.LocalLog
import
com.j256.ormlite.logger.LocalLog
...
@@ -64,29 +65,29 @@ class ShadowsocksApplication extends Application {
...
@@ -64,29 +65,29 @@ class ShadowsocksApplication extends Application {
final
val
SIG_FUNC
=
"getSignature"
final
val
SIG_FUNC
=
"getSignature"
var
containerHolder
:
ContainerHolder
=
_
var
containerHolder
:
ContainerHolder
=
_
lazy
val
tracker
=
GoogleAnalytics
.
getInstance
(
this
).
newTracker
(
R
.
xml
.
tracker
)
lazy
val
tracker
:
Tracker
=
GoogleAnalytics
.
getInstance
(
this
).
newTracker
(
R
.
xml
.
tracker
)
lazy
val
settings
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
)
lazy
val
settings
:
SharedPreferences
=
PreferenceManager
.
getDefaultSharedPreferences
(
this
)
lazy
val
editor
=
settings
.
edit
lazy
val
editor
:
SharedPreferences.Editor
=
settings
.
edit
lazy
val
profileManager
=
new
ProfileManager
(
new
DBHelper
(
this
))
lazy
val
profileManager
=
new
ProfileManager
(
new
DBHelper
(
this
))
def
isNatEnabled
=
settings
.
getBoolean
(
Key
.
isNAT
,
false
)
def
isNatEnabled
:
Boolean
=
settings
.
getBoolean
(
Key
.
isNAT
,
false
)
def
isVpnEnabled
=
!
isNatEnabled
def
isVpnEnabled
:
Boolean
=
!
isNatEnabled
// send event
// send event
def
track
(
category
:
String
,
action
:
String
)
=
tracker
.
send
(
new
HitBuilders
.
EventBuilder
()
def
track
(
category
:
String
,
action
:
String
)
:
Unit
=
tracker
.
send
(
new
HitBuilders
.
EventBuilder
()
.
setAction
(
action
)
.
setAction
(
action
)
.
setLabel
(
BuildConfig
.
VERSION_NAME
)
.
setLabel
(
BuildConfig
.
VERSION_NAME
)
.
build
())
.
build
())
def
track
(
t
:
Throwable
)
=
tracker
.
send
(
new
HitBuilders
.
ExceptionBuilder
()
def
track
(
t
:
Throwable
)
:
Unit
=
tracker
.
send
(
new
HitBuilders
.
ExceptionBuilder
()
.
setDescription
(
new
StandardExceptionParser
(
this
,
null
).
getDescription
(
Thread
.
currentThread
.
getName
,
t
))
.
setDescription
(
new
StandardExceptionParser
(
this
,
null
).
getDescription
(
Thread
.
currentThread
.
getName
,
t
))
.
setFatal
(
false
)
.
setFatal
(
false
)
.
build
())
.
build
())
def
profileId
=
settings
.
getInt
(
Key
.
id
,
-
1
)
def
profileId
:
Int
=
settings
.
getInt
(
Key
.
id
,
-
1
)
def
profileId
(
i
:
Int
)
=
editor
.
putInt
(
Key
.
id
,
i
).
apply
def
profileId
(
i
:
Int
)
:
Unit
=
editor
.
putInt
(
Key
.
id
,
i
).
apply
()
def
currentProfile
=
profileManager
.
getProfile
(
profileId
)
def
currentProfile
:
Option
[
Profile
]
=
profileManager
.
getProfile
(
profileId
)
def
switchProfile
(
id
:
Int
)
=
{
def
switchProfile
(
id
:
Int
)
:
Profile
=
{
profileId
(
id
)
profileId
(
id
)
profileManager
.
getProfile
(
id
)
getOrElse
profileManager
.
createProfile
()
profileManager
.
getProfile
(
id
)
getOrElse
profileManager
.
createProfile
()
}
}
...
@@ -128,9 +129,11 @@ class ShadowsocksApplication extends Application {
...
@@ -128,9 +129,11 @@ class ShadowsocksApplication extends Application {
res
.
updateConfiguration
(
newConfig
,
res
.
getDisplayMetrics
)
res
.
updateConfiguration
(
newConfig
,
res
.
getDisplayMetrics
)
}
}
}
else
{
}
else
{
//noinspection ScalaDeprecation
val
newLocale
=
checkChineseLocale
(
config
.
locale
)
val
newLocale
=
checkChineseLocale
(
config
.
locale
)
if
(
newLocale
!=
null
)
{
if
(
newLocale
!=
null
)
{
val
newConfig
=
new
Configuration
(
config
)
val
newConfig
=
new
Configuration
(
config
)
//noinspection ScalaDeprecation
newConfig
.
locale
=
newLocale
newConfig
.
locale
=
newLocale
val
res
=
getResources
val
res
=
getResources
res
.
updateConfiguration
(
newConfig
,
res
.
getDisplayMetrics
)
res
.
updateConfiguration
(
newConfig
,
res
.
getDisplayMetrics
)
...
@@ -171,7 +174,7 @@ class ShadowsocksApplication extends Application {
...
@@ -171,7 +174,7 @@ class ShadowsocksApplication extends Application {
TcpFastOpen
.
enabled
(
settings
.
getBoolean
(
Key
.
tfo
,
TcpFastOpen
.
sendEnabled
))
TcpFastOpen
.
enabled
(
settings
.
getBoolean
(
Key
.
tfo
,
TcpFastOpen
.
sendEnabled
))
}
}
def
refreshContainerHolder
{
def
refreshContainerHolder
()
{
val
holder
=
app
.
containerHolder
val
holder
=
app
.
containerHolder
if
(
holder
!=
null
)
holder
.
refresh
()
if
(
holder
!=
null
)
holder
.
refresh
()
}
}
...
@@ -215,5 +218,5 @@ class ShadowsocksApplication extends Application {
...
@@ -215,5 +218,5 @@ class ShadowsocksApplication extends Application {
editor
.
putInt
(
Key
.
currentVersionCode
,
BuildConfig
.
VERSION_CODE
).
apply
()
editor
.
putInt
(
Key
.
currentVersionCode
,
BuildConfig
.
VERSION_CODE
).
apply
()
}
}
def
updateAssets
()
=
if
(
settings
.
getInt
(
Key
.
currentVersionCode
,
-
1
)
!=
BuildConfig
.
VERSION_CODE
)
copyAssets
()
def
updateAssets
()
:
Unit
=
if
(
settings
.
getInt
(
Key
.
currentVersionCode
,
-
1
)
!=
BuildConfig
.
VERSION_CODE
)
copyAssets
()
}
}
src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
View file @
a5df60ae
...
@@ -40,11 +40,11 @@ class ShadowsocksNatService extends BaseService {
...
@@ -40,11 +40,11 @@ class ShadowsocksNatService extends BaseService {
val
TAG
=
"ShadowsocksNatService"
val
TAG
=
"ShadowsocksNatService"
val
CMD_IPTABLES_DNAT_ADD_SOCKS
=
"iptables -t nat -A OUTPUT -p tcp "
+
val
CMD_IPTABLES_DNAT_ADD_SOCKS
=
"-j DNAT --to-destination 127.0.0.1:8123"
"
iptables -t nat -A OUTPUT -p tcp
-j DNAT --to-destination 127.0.0.1:8123"
private
var
notification
:
ShadowsocksNotification
=
_
private
var
notification
:
ShadowsocksNotification
=
_
val
myUid
=
android
.
os
.
Process
.
myUid
()
val
myUid
:
Int
=
android
.
os
.
Process
.
myUid
()
var
sslocalProcess
:
GuardedProcess
=
_
var
sslocalProcess
:
GuardedProcess
=
_
var
sstunnelProcess
:
GuardedProcess
=
_
var
sstunnelProcess
:
GuardedProcess
=
_
...
@@ -169,20 +169,17 @@ class ShadowsocksNatService extends BaseService {
...
@@ -169,20 +169,17 @@ class ShadowsocksNatService extends BaseService {
val
reject
=
if
(
profile
.
ipv6
)
"224.0.0.0/3"
else
"224.0.0.0/3, ::/0"
val
reject
=
if
(
profile
.
ipv6
)
"224.0.0.0/3"
else
"224.0.0.0/3, ::/0"
val
conf
=
profile
.
route
match
{
val
conf
=
profile
.
route
match
{
case
Route
.
BYPASS_CHN
|
Route
.
BYPASS_LAN_CHN
|
Route
.
GFWLIST
=>
{
case
Route
.
BYPASS_CHN
|
Route
.
BYPASS_LAN_CHN
|
Route
.
GFWLIST
=>
ConfigUtils
.
PDNSD_DIRECT
.
formatLocal
(
Locale
.
ENGLISH
,
""
,
getApplicationInfo
.
dataDir
,
ConfigUtils
.
PDNSD_DIRECT
.
formatLocal
(
Locale
.
ENGLISH
,
""
,
getApplicationInfo
.
dataDir
,
"127.0.0.1"
,
profile
.
localPort
+
53
,
"114.114.114.114, 223.5.5.5, 1.2.4.8"
,
"127.0.0.1"
,
profile
.
localPort
+
53
,
"114.114.114.114, 223.5.5.5, 1.2.4.8"
,
getBlackList
,
reject
,
profile
.
localPort
+
63
,
reject
)
getBlackList
,
reject
,
profile
.
localPort
+
63
,
reject
)
}
case
Route
.
CHINALIST
=>
case
Route
.
CHINALIST
=>
{
ConfigUtils
.
PDNSD_DIRECT
.
formatLocal
(
Locale
.
ENGLISH
,
""
,
getApplicationInfo
.
dataDir
,
ConfigUtils
.
PDNSD_DIRECT
.
formatLocal
(
Locale
.
ENGLISH
,
""
,
getApplicationInfo
.
dataDir
,
"127.0.0.1"
,
profile
.
localPort
+
53
,
"8.8.8.8, 8.8.4.4, 208.67.222.222"
,
"127.0.0.1"
,
profile
.
localPort
+
53
,
"8.8.8.8, 8.8.4.4, 208.67.222.222"
,
""
,
reject
,
profile
.
localPort
+
63
,
reject
)
""
,
reject
,
profile
.
localPort
+
63
,
reject
)
}
case
_
=>
case
_
=>
{
ConfigUtils
.
PDNSD_LOCAL
.
formatLocal
(
Locale
.
ENGLISH
,
""
,
getApplicationInfo
.
dataDir
,
ConfigUtils
.
PDNSD_LOCAL
.
formatLocal
(
Locale
.
ENGLISH
,
""
,
getApplicationInfo
.
dataDir
,
"127.0.0.1"
,
profile
.
localPort
+
53
,
profile
.
localPort
+
63
,
reject
)
"127.0.0.1"
,
profile
.
localPort
+
53
,
profile
.
localPort
+
63
,
reject
)
}
}
}
Utils
.
printToFile
(
new
File
(
getApplicationInfo
.
dataDir
+
"/pdnsd-nat.conf"
))(
p
=>
{
Utils
.
printToFile
(
new
File
(
getApplicationInfo
.
dataDir
+
"/pdnsd-nat.conf"
))(
p
=>
{
...
@@ -254,7 +251,7 @@ class ShadowsocksNatService extends BaseService {
...
@@ -254,7 +251,7 @@ class ShadowsocksNatService extends BaseService {
su
.
addCommand
(
"iptables -t nat -F OUTPUT"
)
su
.
addCommand
(
"iptables -t nat -F OUTPUT"
)
}
}
def
setupIptables
()
=
{
def
setupIptables
()
{
val
init_sb
=
new
ArrayBuffer
[
String
]
val
init_sb
=
new
ArrayBuffer
[
String
]
val
http_sb
=
new
ArrayBuffer
[
String
]
val
http_sb
=
new
ArrayBuffer
[
String
]
...
@@ -291,14 +288,14 @@ class ShadowsocksNatService extends BaseService {
...
@@ -291,14 +288,14 @@ class ShadowsocksNatService extends BaseService {
su
.
addCommand
((
init_sb
++
http_sb
).
toArray
)
su
.
addCommand
((
init_sb
++
http_sb
).
toArray
)
}
}
override
def
startRunner
(
profile
:
Profile
)
=
if
(
su
==
null
)
override
def
startRunner
(
profile
:
Profile
)
:
Unit
=
if
(
su
==
null
)
su
=
new
Shell
.
Builder
().
useSU
().
setWantSTDERR
(
true
).
setWatchdogTimeout
(
10
).
open
((
_
,
exitCode
,
_
)
=>
su
=
new
Shell
.
Builder
().
useSU
().
setWantSTDERR
(
true
).
setWatchdogTimeout
(
10
).
open
((
_
,
exitCode
,
_
)
=>
if
(
exitCode
==
0
)
super
.
startRunner
(
profile
)
else
{
if
(
exitCode
==
0
)
super
.
startRunner
(
profile
)
else
{
if
(
su
!=
null
)
{
if
(
su
!=
null
)
{
su
.
close
()
su
.
close
()
su
=
null
su
=
null
}
}
super
.
stopRunner
(
true
,
getString
(
R
.
string
.
nat_no_root
))
super
.
stopRunner
(
stopService
=
true
,
getString
(
R
.
string
.
nat_no_root
))
})
})
override
def
connect
()
{
override
def
connect
()
{
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksNotification.scala
View file @
a5df60ae
...
@@ -39,7 +39,7 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
...
@@ -39,7 +39,7 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
private
val
keyGuard
=
service
.
getSystemService
(
Context
.
KEYGUARD_SERVICE
).
asInstanceOf
[
KeyguardManager
]
private
val
keyGuard
=
service
.
getSystemService
(
Context
.
KEYGUARD_SERVICE
).
asInstanceOf
[
KeyguardManager
]
private
lazy
val
nm
=
service
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
).
asInstanceOf
[
NotificationManager
]
private
lazy
val
nm
=
service
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
).
asInstanceOf
[
NotificationManager
]
private
lazy
val
callback
=
new
Stub
{
private
lazy
val
callback
=
new
Stub
{
override
def
stateChanged
(
state
:
Int
,
profileName
:
String
,
msg
:
String
)
=
()
// ignore
override
def
stateChanged
(
state
:
Int
,
profileName
:
String
,
msg
:
String
)
:
Unit
=
()
// ignore
override
def
trafficUpdated
(
txRate
:
Long
,
rxRate
:
Long
,
txTotal
:
Long
,
rxTotal
:
Long
)
{
override
def
trafficUpdated
(
txRate
:
Long
,
rxRate
:
Long
,
txTotal
:
Long
,
rxTotal
:
Long
)
{
val
txr
=
TrafficMonitor
.
formatTraffic
(
txRate
)
val
txr
=
TrafficMonitor
.
formatTraffic
(
txRate
)
val
rxr
=
TrafficMonitor
.
formatTraffic
(
rxRate
)
val
rxr
=
TrafficMonitor
.
formatTraffic
(
rxRate
)
...
@@ -71,8 +71,8 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
...
@@ -71,8 +71,8 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
private
lazy
val
style
=
new
BigTextStyle
(
builder
)
private
lazy
val
style
=
new
BigTextStyle
(
builder
)
private
var
isVisible
=
true
private
var
isVisible
=
true
update
(
if
(
service
.
getSystemService
(
Context
.
POWER_SERVICE
).
asInstanceOf
[
PowerManager
].
isScreenOn
)
update
(
if
(
service
.
getSystemService
(
Context
.
POWER_SERVICE
).
asInstanceOf
[
PowerManager
].
isScreenOn
)
Intent
.
ACTION_SCREEN_ON
else
Intent
.
ACTION_SCREEN_OFF
,
true
)
Intent
.
ACTION_SCREEN_ON
else
Intent
.
ACTION_SCREEN_OFF
,
forceShow
=
true
)
lockReceiver
=
(
context
:
Context
,
intent
:
Intent
)
=>
update
(
intent
.
getAction
)
lockReceiver
=
(
_
:
Context
,
intent
:
Intent
)
=>
update
(
intent
.
getAction
)
val
screenFilter
=
new
IntentFilter
()
val
screenFilter
=
new
IntentFilter
()
screenFilter
.
addAction
(
Intent
.
ACTION_SCREEN_ON
)
screenFilter
.
addAction
(
Intent
.
ACTION_SCREEN_ON
)
screenFilter
.
addAction
(
Intent
.
ACTION_SCREEN_OFF
)
screenFilter
.
addAction
(
Intent
.
ACTION_SCREEN_OFF
)
...
@@ -83,33 +83,33 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
...
@@ -83,33 +83,33 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
if
(
forceShow
||
service
.
getState
==
State
.
CONNECTED
)
action
match
{
if
(
forceShow
||
service
.
getState
==
State
.
CONNECTED
)
action
match
{
case
Intent
.
ACTION_SCREEN_OFF
=>
case
Intent
.
ACTION_SCREEN_OFF
=>
setVisible
(
visible
&&
!
Utils
.
isLollipopOrAbove
,
forceShow
)
setVisible
(
visible
&&
!
Utils
.
isLollipopOrAbove
,
forceShow
)
unregisterCallback
// unregister callback to save battery
unregisterCallback
()
// unregister callback to save battery
case
Intent
.
ACTION_SCREEN_ON
=>
case
Intent
.
ACTION_SCREEN_ON
=>
setVisible
(
visible
&&
Utils
.
isLollipopOrAbove
&&
!
keyGuard
.
inKeyguardRestrictedInputMode
,
forceShow
)
setVisible
(
visible
&&
Utils
.
isLollipopOrAbove
&&
!
keyGuard
.
inKeyguardRestrictedInputMode
,
forceShow
)
service
.
binder
.
registerCallback
(
callback
)
service
.
binder
.
registerCallback
(
callback
)
callbackRegistered
=
true
callbackRegistered
=
true
case
Intent
.
ACTION_USER_PRESENT
=>
setVisible
(
true
,
forceShow
)
case
Intent
.
ACTION_USER_PRESENT
=>
setVisible
(
visible
=
true
,
forceShow
=
forceShow
)
}
}
private
def
unregisterCallback
=
if
(
callbackRegistered
)
{
private
def
unregisterCallback
()
=
if
(
callbackRegistered
)
{
service
.
binder
.
unregisterCallback
(
callback
)
service
.
binder
.
unregisterCallback
(
callback
)
callbackRegistered
=
false
callbackRegistered
=
false
}
}
def
setVisible
(
visible
:
Boolean
,
forceShow
:
Boolean
=
false
)
=
if
(
isVisible
!=
visible
)
{
def
setVisible
(
visible
:
Boolean
,
forceShow
:
Boolean
=
false
)
:
Unit
=
if
(
isVisible
!=
visible
)
{
isVisible
=
visible
isVisible
=
visible
builder
.
setPriority
(
if
(
visible
)
NotificationCompat
.
PRIORITY_LOW
else
NotificationCompat
.
PRIORITY_MIN
)
builder
.
setPriority
(
if
(
visible
)
NotificationCompat
.
PRIORITY_LOW
else
NotificationCompat
.
PRIORITY_MIN
)
show
()
show
()
}
else
if
(
forceShow
)
show
()
}
else
if
(
forceShow
)
show
()
def
show
()
=
service
.
startForeground
(
1
,
builder
.
build
)
def
show
()
:
Unit
=
service
.
startForeground
(
1
,
builder
.
build
)
def
destroy
()
{
def
destroy
()
{
if
(
lockReceiver
!=
null
)
{
if
(
lockReceiver
!=
null
)
{
service
.
unregisterReceiver
(
lockReceiver
)
service
.
unregisterReceiver
(
lockReceiver
)
lockReceiver
=
null
lockReceiver
=
null
}
}
unregisterCallback
unregisterCallback
()
service
.
stopForeground
(
true
)
service
.
stopForeground
(
true
)
nm
.
cancel
(
1
)
nm
.
cancel
(
1
)
}
}
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksQuickSwitchActivity.scala
View file @
a5df60ae
...
@@ -40,7 +40,7 @@ class ShadowsocksQuickSwitchActivity extends AppCompatActivity {
...
@@ -40,7 +40,7 @@ class ShadowsocksQuickSwitchActivity extends AppCompatActivity {
{
{
val
typedArray
=
obtainStyledAttributes
(
Array
(
android
.
R
.
attr
.
selectableItemBackground
))
val
typedArray
=
obtainStyledAttributes
(
Array
(
android
.
R
.
attr
.
selectableItemBackground
))
view
.
setBackgroundResource
(
typedArray
.
getResourceId
(
0
,
0
))
view
.
setBackgroundResource
(
typedArray
.
getResourceId
(
0
,
0
))
typedArray
.
recycle
typedArray
.
recycle
()
}
}
private
var
item
:
Profile
=
_
private
var
item
:
Profile
=
_
private
val
text
=
itemView
.
findViewById
(
android
.
R
.
id
.
text1
).
asInstanceOf
[
CheckedTextView
]
private
val
text
=
itemView
.
findViewById
(
android
.
R
.
id
.
text1
).
asInstanceOf
[
CheckedTextView
]
...
@@ -55,16 +55,16 @@ class ShadowsocksQuickSwitchActivity extends AppCompatActivity {
...
@@ -55,16 +55,16 @@ class ShadowsocksQuickSwitchActivity extends AppCompatActivity {
def
onClick
(
v
:
View
)
{
def
onClick
(
v
:
View
)
{
app
.
switchProfile
(
item
.
id
)
app
.
switchProfile
(
item
.
id
)
Utils
.
startSsService
(
ShadowsocksQuickSwitchActivity
.
this
)
Utils
.
startSsService
(
ShadowsocksQuickSwitchActivity
.
this
)
finish
finish
()
}
}
}
}
private
class
ProfilesAdapter
extends
RecyclerView
.
Adapter
[
ProfileViewHolder
]
{
private
class
ProfilesAdapter
extends
RecyclerView
.
Adapter
[
ProfileViewHolder
]
{
val
profiles
=
app
.
profileManager
.
getAllProfiles
.
getOrElse
(
List
.
empty
[
Profile
])
val
profiles
:
List
[
Profile
]
=
app
.
profileManager
.
getAllProfiles
.
getOrElse
(
List
.
empty
[
Profile
])
def
getItemCount
=
profiles
.
length
def
getItemCount
:
Int
=
profiles
.
length
def
onBindViewHolder
(
vh
:
ProfileViewHolder
,
i
:
Int
)
=
i
match
{
def
onBindViewHolder
(
vh
:
ProfileViewHolder
,
i
:
Int
)
:
Unit
=
i
match
{
case
_
=>
vh
.
bind
(
profiles
(
i
))
case
_
=>
vh
.
bind
(
profiles
(
i
))
}
}
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksRunnerActivity.scala
View file @
a5df60ae
...
@@ -25,7 +25,6 @@ import android.content.{BroadcastReceiver, Context, Intent, IntentFilter}
...
@@ -25,7 +25,6 @@ import android.content.{BroadcastReceiver, Context, Intent, IntentFilter}
import
android.net.VpnService
import
android.net.VpnService
import
android.os.
{
Bundle
,
Handler
}
import
android.os.
{
Bundle
,
Handler
}
import
android.util.Log
import
android.util.Log
import
com.github.shadowsocks.utils.ConfigUtils
import
com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.ShadowsocksApplication.app
object
ShadowsocksRunnerActivity
{
object
ShadowsocksRunnerActivity
{
...
@@ -65,7 +64,7 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
...
@@ -65,7 +64,7 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
val
locked
=
km
.
inKeyguardRestrictedInputMode
val
locked
=
km
.
inKeyguardRestrictedInputMode
if
(
locked
)
{
if
(
locked
)
{
val
filter
=
new
IntentFilter
(
Intent
.
ACTION_USER_PRESENT
)
val
filter
=
new
IntentFilter
(
Intent
.
ACTION_USER_PRESENT
)
receiver
=
(
context
:
Context
,
intent
:
Intent
)
=>
{
receiver
=
(
_
:
Context
,
intent
:
Intent
)
=>
{
if
(
intent
.
getAction
==
Intent
.
ACTION_USER_PRESENT
)
{
if
(
intent
.
getAction
==
Intent
.
ACTION_USER_PRESENT
)
{
attachService
()
attachService
()
}
}
...
@@ -74,7 +73,7 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
...
@@ -74,7 +73,7 @@ class ShadowsocksRunnerActivity extends Activity with ServiceBoundContext {
}
else
{
}
else
{
attachService
()
attachService
()
}
}
finish
finish
()
}
}
override
def
onDestroy
()
{
override
def
onDestroy
()
{
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksRunnerService.scala
View file @
a5df60ae
...
@@ -23,8 +23,7 @@ package com.github.shadowsocks
...
@@ -23,8 +23,7 @@ package com.github.shadowsocks
import
android.app.Service
import
android.app.Service
import
android.content.Intent
import
android.content.Intent
import
android.net.VpnService
import
android.net.VpnService
import
android.os.
{
IBinder
,
Handler
}
import
android.os.
{
Handler
,
IBinder
}
import
com.github.shadowsocks.utils.ConfigUtils
import
com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.ShadowsocksApplication.app
class
ShadowsocksRunnerService
extends
Service
with
ServiceBoundContext
{
class
ShadowsocksRunnerService
extends
Service
with
ServiceBoundContext
{
...
@@ -44,7 +43,7 @@ class ShadowsocksRunnerService extends Service with ServiceBoundContext {
...
@@ -44,7 +43,7 @@ class ShadowsocksRunnerService extends Service with ServiceBoundContext {
},
1000
)
},
1000
)
}
}
def
startBackgroundService
()
=
bgService
.
useSync
(
app
.
profileId
)
def
startBackgroundService
()
:
Unit
=
bgService
.
useSync
(
app
.
profileId
)
override
def
onCreate
()
{
override
def
onCreate
()
{
super
.
onCreate
()
super
.
onCreate
()
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksSettings.scala
View file @
a5df60ae
...
@@ -97,7 +97,7 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
...
@@ -97,7 +97,7 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
import
ShadowsocksSettings._
import
ShadowsocksSettings._
private
def
activity
=
getActivity
.
asInstanceOf
[
Shadowsocks
]
private
def
activity
=
getActivity
.
asInstanceOf
[
Shadowsocks
]
lazy
val
natSwitch
=
findPreference
(
Key
.
isNAT
).
asInstanceOf
[
SwitchPreference
]
lazy
val
natSwitch
:
SwitchPreference
=
findPreference
(
Key
.
isNAT
).
asInstanceOf
[
SwitchPreference
]
private
var
isProxyApps
:
SwitchPreference
=
_
private
var
isProxyApps
:
SwitchPreference
=
_
...
@@ -182,7 +182,7 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
...
@@ -182,7 +182,7 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
})
})
if
(
getPreferenceManager
.
getSharedPreferences
.
getBoolean
(
Key
.
isAutoConnect
,
false
))
{
if
(
getPreferenceManager
.
getSharedPreferences
.
getBoolean
(
Key
.
isAutoConnect
,
false
))
{
BootReceiver
.
setEnabled
(
activity
,
true
)
BootReceiver
.
setEnabled
(
activity
,
true
)
getPreferenceManager
.
getSharedPreferences
.
edit
.
remove
(
Key
.
isAutoConnect
).
apply
getPreferenceManager
.
getSharedPreferences
.
edit
.
remove
(
Key
.
isAutoConnect
).
apply
()
}
}
switch
.
setChecked
(
BootReceiver
.
getEnabled
(
activity
))
switch
.
setChecked
(
BootReceiver
.
getEnabled
(
activity
))
...
@@ -200,13 +200,13 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
...
@@ -200,13 +200,13 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
tfo
.
setSummary
(
getString
(
R
.
string
.
tcp_fastopen_summary_unsupported
,
java
.
lang
.
System
.
getProperty
(
"os.version"
)))
tfo
.
setSummary
(
getString
(
R
.
string
.
tcp_fastopen_summary_unsupported
,
java
.
lang
.
System
.
getProperty
(
"os.version"
)))
}
}
findPreference
(
"recovery"
).
setOnPreferenceClickListener
(
(
preference
:
Preference
)
=>
{
findPreference
(
"recovery"
).
setOnPreferenceClickListener
(
_
=>
{
app
.
track
(
TAG
,
"reset"
)
app
.
track
(
TAG
,
"reset"
)
activity
.
recovery
()
activity
.
recovery
()
true
true
})
})
findPreference
(
"about"
).
setOnPreferenceClickListener
(
(
preference
:
Preference
)
=>
{
findPreference
(
"about"
).
setOnPreferenceClickListener
(
_
=>
{
app
.
track
(
TAG
,
"about"
)
app
.
track
(
TAG
,
"about"
)
val
web
=
new
WebView
(
activity
)
val
web
=
new
WebView
(
activity
)
web
.
loadUrl
(
"file:///android_asset/pages/about.html"
)
web
.
loadUrl
(
"file:///android_asset/pages/about.html"
)
...
@@ -231,7 +231,7 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
...
@@ -231,7 +231,7 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
})
})
}
}
override
def
onDisplayPreferenceDialog
(
preference
:
Preference
)
=
preference
.
getKey
match
{
override
def
onDisplayPreferenceDialog
(
preference
:
Preference
)
:
Unit
=
preference
.
getKey
match
{
case
Key
.
kcpcli
=>
displayPreferenceDialog
(
Key
.
kcpcli
,
new
KcpCliPreferenceDialogFragment
())
case
Key
.
kcpcli
=>
displayPreferenceDialog
(
Key
.
kcpcli
,
new
KcpCliPreferenceDialogFragment
())
case
_
=>
super
.
onDisplayPreferenceDialog
(
preference
)
case
_
=>
super
.
onDisplayPreferenceDialog
(
preference
)
}
}
...
@@ -253,16 +253,16 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
...
@@ -253,16 +253,16 @@ class ShadowsocksSettings extends PreferenceFragment with OnSharedPreferenceChan
isProxyApps
.
setChecked
(
profile
.
proxyApps
)
isProxyApps
.
setChecked
(
profile
.
proxyApps
)
}
}
override
def
onDestroy
{
override
def
onDestroy
()
{
super
.
onDestroy
()
super
.
onDestroy
()
app
.
settings
.
unregisterOnSharedPreferenceChangeListener
(
this
)
app
.
settings
.
unregisterOnSharedPreferenceChangeListener
(
this
)
}
}
def
onSharedPreferenceChanged
(
pref
:
SharedPreferences
,
key
:
String
)
=
key
match
{
def
onSharedPreferenceChanged
(
pref
:
SharedPreferences
,
key
:
String
)
:
Unit
=
key
match
{
case
Key
.
isNAT
=>
case
Key
.
isNAT
=>
activity
.
handler
.
post
(()
=>
{
activity
.
handler
.
post
(()
=>
{
activity
.
detachService
activity
.
detachService
()
activity
.
attachService
activity
.
attachService
Callback
()
})
})
case
_
=>
case
_
=>
}
}
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksTileService.scala
View file @
a5df60ae
...
@@ -36,7 +36,7 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
...
@@ -36,7 +36,7 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
private
lazy
val
iconBusy
=
Icon
.
createWithResource
(
this
,
R
.
drawable
.
ic_start_busy
)
private
lazy
val
iconBusy
=
Icon
.
createWithResource
(
this
,
R
.
drawable
.
ic_start_busy
)
private
lazy
val
iconConnected
=
Icon
.
createWithResource
(
this
,
R
.
drawable
.
ic_start_connected
)
private
lazy
val
iconConnected
=
Icon
.
createWithResource
(
this
,
R
.
drawable
.
ic_start_connected
)
private
lazy
val
callback
=
new
IShadowsocksServiceCallback
.
Stub
{
private
lazy
val
callback
=
new
IShadowsocksServiceCallback
.
Stub
{
def
trafficUpdated
(
txRate
:
Long
,
rxRate
:
Long
,
txTotal
:
Long
,
rxTotal
:
Long
)
=
()
def
trafficUpdated
(
txRate
:
Long
,
rxRate
:
Long
,
txTotal
:
Long
,
rxTotal
:
Long
)
:
Unit
=
()
def
stateChanged
(
state
:
Int
,
profileName
:
String
,
msg
:
String
)
{
def
stateChanged
(
state
:
Int
,
profileName
:
String
,
msg
:
String
)
{
val
tile
=
getQsTile
val
tile
=
getQsTile
if
(
tile
!=
null
)
{
if
(
tile
!=
null
)
{
...
@@ -54,23 +54,23 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
...
@@ -54,23 +54,23 @@ final class ShadowsocksTileService extends TileService with ServiceBoundContext
tile
.
setLabel
(
getString
(
R
.
string
.
app_name
))
tile
.
setLabel
(
getString
(
R
.
string
.
app_name
))
tile
.
setState
(
Tile
.
STATE_UNAVAILABLE
)
tile
.
setState
(
Tile
.
STATE_UNAVAILABLE
)
}
}
tile
.
updateTile
tile
.
updateTile
()
}
}
}
}
}
}
override
def
onServiceConnected
()
=
callback
.
stateChanged
(
bgService
.
getState
,
bgService
.
getProfileName
,
null
)
override
def
onServiceConnected
()
:
Unit
=
callback
.
stateChanged
(
bgService
.
getState
,
bgService
.
getProfileName
,
null
)
override
def
onStartListening
{
override
def
onStartListening
()
{
super
.
onStartListening
super
.
onStartListening
()
attachService
(
callback
)
attachService
(
callback
)
}
}
override
def
onStopListening
{
override
def
onStopListening
()
{
super
.
onStopListening
super
.
onStopListening
()
detachService
// just in case the user switches to NAT mode, also saves battery
detachService
()
// just in case the user switches to NAT mode, also saves battery
}
}
override
def
onClick
()
=
if
(
isLocked
)
unlockAndRun
(
toggle
)
else
toggle
()
override
def
onClick
()
:
Unit
=
if
(
isLocked
)
unlockAndRun
(
toggle
)
else
toggle
()
private
def
toggle
()
=
if
(
bgService
!=
null
)
bgService
.
getState
match
{
private
def
toggle
()
=
if
(
bgService
!=
null
)
bgService
.
getState
match
{
case
State
.
STOPPED
=>
Utils
.
startSsService
(
this
)
case
State
.
STOPPED
=>
Utils
.
startSsService
(
this
)
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
View file @
a5df60ae
...
@@ -61,7 +61,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -61,7 +61,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
}
}
override
def
onRevoke
()
{
override
def
onRevoke
()
{
stopRunner
(
true
)
stopRunner
(
stopService
=
true
)
}
}
override
def
stopRunner
(
stopService
:
Boolean
,
msg
:
String
=
null
)
{
override
def
stopRunner
(
stopService
:
Boolean
,
msg
:
String
=
null
)
{
...
@@ -120,14 +120,14 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -120,14 +120,14 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val
i
=
new
Intent
(
this
,
classOf
[
ShadowsocksRunnerActivity
])
val
i
=
new
Intent
(
this
,
classOf
[
ShadowsocksRunnerActivity
])
i
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
)
i
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
)
startActivity
(
i
)
startActivity
(
i
)
stopRunner
(
true
)
stopRunner
(
stopService
=
true
)
return
return
}
}
super
.
startRunner
(
profile
)
super
.
startRunner
(
profile
)
}
}
override
def
connect
()
=
{
override
def
connect
()
{
super
.
connect
()
super
.
connect
()
vpnThread
=
new
ShadowsocksVpnThread
(
this
)
vpnThread
=
new
ShadowsocksVpnThread
(
this
)
...
@@ -253,7 +253,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -253,7 +253,7 @@ class ShadowsocksVpnService extends VpnService with BaseService {
sslocalProcess
=
new
GuardedProcess
(
cmd
).
start
()
sslocalProcess
=
new
GuardedProcess
(
cmd
).
start
()
}
}
def
startDnsTunnel
()
=
{
def
startDnsTunnel
()
{
val
conf
=
if
(
profile
.
kcp
)
{
val
conf
=
if
(
profile
.
kcp
)
{
ConfigUtils
ConfigUtils
.
SHADOWSOCKS
.
formatLocal
(
Locale
.
ENGLISH
,
"127.0.0.1"
,
profile
.
localPort
+
90
,
profile
.
localPort
+
63
,
.
SHADOWSOCKS
.
formatLocal
(
Locale
.
ENGLISH
,
"127.0.0.1"
,
profile
.
localPort
+
90
,
profile
.
localPort
+
63
,
...
@@ -291,20 +291,17 @@ class ShadowsocksVpnService extends VpnService with BaseService {
...
@@ -291,20 +291,17 @@ class ShadowsocksVpnService extends VpnService with BaseService {
val
reject
=
if
(
profile
.
ipv6
)
"224.0.0.0/3"
else
"224.0.0.0/3, ::/0"
val
reject
=
if
(
profile
.
ipv6
)
"224.0.0.0/3"
else
"224.0.0.0/3, ::/0"
val
protect
=
"protect = \""
+
protectPath
+
"\";"
val
protect
=
"protect = \""
+
protectPath
+
"\";"
val
conf
=
profile
.
route
match
{
val
conf
=
profile
.
route
match
{
case
Route
.
BYPASS_CHN
|
Route
.
BYPASS_LAN_CHN
|
Route
.
GFWLIST
=>
{
case
Route
.
BYPASS_CHN
|
Route
.
BYPASS_LAN_CHN
|
Route
.
GFWLIST
=>
ConfigUtils
.
PDNSD_DIRECT
.
formatLocal
(
Locale
.
ENGLISH
,
protect
,
getApplicationInfo
.
dataDir
,
ConfigUtils
.
PDNSD_DIRECT
.
formatLocal
(
Locale
.
ENGLISH
,
protect
,
getApplicationInfo
.
dataDir
,
"0.0.0.0"
,
profile
.
localPort
+
53
,
"114.114.114.114, 223.5.5.5, 1.2.4.8"
,
"0.0.0.0"
,
profile
.
localPort
+
53
,
"114.114.114.114, 223.5.5.5, 1.2.4.8"
,
getBlackList
,
reject
,
profile
.
localPort
+
63
,
reject
)
getBlackList
,
reject
,
profile
.
localPort
+
63
,
reject
)
}
case
Route
.
CHINALIST
=>
case
Route
.
CHINALIST
=>
{
ConfigUtils
.
PDNSD_DIRECT
.
formatLocal
(
Locale
.
ENGLISH
,
protect
,
getApplicationInfo
.
dataDir
,
ConfigUtils
.
PDNSD_DIRECT
.
formatLocal
(
Locale
.
ENGLISH
,
protect
,
getApplicationInfo
.
dataDir
,
"0.0.0.0"
,
profile
.
localPort
+
53
,
"8.8.8.8, 8.8.4.4, 208.67.222.222"
,
"0.0.0.0"
,
profile
.
localPort
+
53
,
"8.8.8.8, 8.8.4.4, 208.67.222.222"
,
""
,
reject
,
profile
.
localPort
+
63
,
reject
)
""
,
reject
,
profile
.
localPort
+
63
,
reject
)
}
case
_
=>
case
_
=>
{
ConfigUtils
.
PDNSD_LOCAL
.
formatLocal
(
Locale
.
ENGLISH
,
protect
,
getApplicationInfo
.
dataDir
,
ConfigUtils
.
PDNSD_LOCAL
.
formatLocal
(
Locale
.
ENGLISH
,
protect
,
getApplicationInfo
.
dataDir
,
"0.0.0.0"
,
profile
.
localPort
+
53
,
profile
.
localPort
+
63
,
reject
)
"0.0.0.0"
,
profile
.
localPort
+
53
,
profile
.
localPort
+
63
,
reject
)
}
}
}
Utils
.
printToFile
(
new
File
(
getApplicationInfo
.
dataDir
+
"/pdnsd-vpn.conf"
))(
p
=>
{
Utils
.
printToFile
(
new
File
(
getApplicationInfo
.
dataDir
+
"/pdnsd-vpn.conf"
))(
p
=>
{
p
.
println
(
conf
)
p
.
println
(
conf
)
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala
View file @
a5df60ae
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
package
com.github.shadowsocks
package
com.github.shadowsocks
import
java.io.
{
File
,
FileDescriptor
,
IOException
}
import
java.io.
{
File
,
FileDescriptor
,
IOException
}
import
java.lang.reflect.Method
import
java.util.concurrent.Executors
import
java.util.concurrent.Executors
import
android.net.
{
LocalServerSocket
,
LocalSocket
,
LocalSocketAddress
}
import
android.net.
{
LocalServerSocket
,
LocalSocket
,
LocalSocketAddress
}
...
@@ -28,14 +29,14 @@ import android.util.Log
...
@@ -28,14 +29,14 @@ import android.util.Log
import
com.github.shadowsocks.ShadowsocksApplication.app
import
com.github.shadowsocks.ShadowsocksApplication.app
object
ShadowsocksVpnThread
{
object
ShadowsocksVpnThread
{
val
getInt
=
classOf
[
FileDescriptor
].
getDeclaredMethod
(
"getInt$"
)
val
getInt
:
Method
=
classOf
[
FileDescriptor
].
getDeclaredMethod
(
"getInt$"
)
}
}
class
ShadowsocksVpnThread
(
vpnService
:
ShadowsocksVpnService
)
extends
Thread
{
class
ShadowsocksVpnThread
(
vpnService
:
ShadowsocksVpnService
)
extends
Thread
{
import
ShadowsocksVpnThread._
import
ShadowsocksVpnThread._
val
TAG
=
"ShadowsocksVpnService"
val
TAG
=
"ShadowsocksVpnService"
lazy
val
PATH
=
vpnService
.
getApplicationInfo
.
dataDir
+
"/protect_path"
lazy
val
PATH
:
String
=
vpnService
.
getApplicationInfo
.
dataDir
+
"/protect_path"
@volatile
var
isRunning
:
Boolean
=
true
@volatile
var
isRunning
:
Boolean
=
true
@volatile
var
serverSocket
:
LocalServerSocket
=
_
@volatile
var
serverSocket
:
LocalServerSocket
=
_
...
...
src/main/scala/com/github/shadowsocks/TaskerActivity.scala
View file @
a5df60ae
...
@@ -39,13 +39,13 @@ class TaskerActivity extends AppCompatActivity {
...
@@ -39,13 +39,13 @@ class TaskerActivity extends AppCompatActivity {
{
{
val
typedArray
=
obtainStyledAttributes
(
Array
(
android
.
R
.
attr
.
selectableItemBackground
))
val
typedArray
=
obtainStyledAttributes
(
Array
(
android
.
R
.
attr
.
selectableItemBackground
))
view
.
setBackgroundResource
(
typedArray
.
getResourceId
(
0
,
0
))
view
.
setBackgroundResource
(
typedArray
.
getResourceId
(
0
,
0
))
typedArray
.
recycle
typedArray
.
recycle
()
}
}
private
var
item
:
Profile
=
_
private
var
item
:
Profile
=
_
private
val
text
=
itemView
.
findViewById
(
android
.
R
.
id
.
text1
).
asInstanceOf
[
CheckedTextView
]
private
val
text
=
itemView
.
findViewById
(
android
.
R
.
id
.
text1
).
asInstanceOf
[
CheckedTextView
]
itemView
.
setOnClickListener
(
this
)
itemView
.
setOnClickListener
(
this
)
def
bindDefault
{
def
bindDefault
()
{
item
=
null
item
=
null
text
.
setText
(
R
.
string
.
profile_default
)
text
.
setText
(
R
.
string
.
profile_default
)
text
.
setChecked
(
taskerOption
.
profileId
<
0
)
text
.
setChecked
(
taskerOption
.
profileId
<
0
)
...
@@ -60,15 +60,15 @@ class TaskerActivity extends AppCompatActivity {
...
@@ -60,15 +60,15 @@ class TaskerActivity extends AppCompatActivity {
taskerOption
.
switchOn
=
switch
.
isChecked
taskerOption
.
switchOn
=
switch
.
isChecked
taskerOption
.
profileId
=
if
(
item
==
null
)
-
1
else
item
.
id
taskerOption
.
profileId
=
if
(
item
==
null
)
-
1
else
item
.
id
setResult
(
Activity
.
RESULT_OK
,
taskerOption
.
toIntent
(
TaskerActivity
.
this
))
setResult
(
Activity
.
RESULT_OK
,
taskerOption
.
toIntent
(
TaskerActivity
.
this
))
finish
finish
()
}
}
}
}
private
class
ProfilesAdapter
extends
RecyclerView
.
Adapter
[
ProfileViewHolder
]
{
private
class
ProfilesAdapter
extends
RecyclerView
.
Adapter
[
ProfileViewHolder
]
{
val
profiles
=
app
.
profileManager
.
getAllProfiles
.
getOrElse
(
List
.
empty
[
Profile
])
val
profiles
:
List
[
Profile
]
=
app
.
profileManager
.
getAllProfiles
.
getOrElse
(
List
.
empty
[
Profile
])
def
getItemCount
=
1
+
profiles
.
length
def
getItemCount
:
Int
=
1
+
profiles
.
length
def
onBindViewHolder
(
vh
:
ProfileViewHolder
,
i
:
Int
)
=
i
match
{
def
onBindViewHolder
(
vh
:
ProfileViewHolder
,
i
:
Int
)
:
Unit
=
i
match
{
case
0
=>
vh
.
bindDefault
case
0
=>
vh
.
bindDefault
()
case
_
=>
vh
.
bind
(
profiles
(
i
-
1
))
case
_
=>
vh
.
bind
(
profiles
(
i
-
1
))
}
}
private
val
name
=
"select_dialog_singlechoice_"
+
(
if
(
Build
.
VERSION
.
SDK_INT
>=
21
)
"material"
else
"holo"
)
private
val
name
=
"select_dialog_singlechoice_"
+
(
if
(
Build
.
VERSION
.
SDK_INT
>=
21
)
"material"
else
"holo"
)
...
...
src/main/scala/com/github/shadowsocks/TaskerReceiver.scala
View file @
a5df60ae
...
@@ -30,11 +30,9 @@ import com.github.shadowsocks.ShadowsocksApplication.app
...
@@ -30,11 +30,9 @@ import com.github.shadowsocks.ShadowsocksApplication.app
class
TaskerReceiver
extends
BroadcastReceiver
{
class
TaskerReceiver
extends
BroadcastReceiver
{
override
def
onReceive
(
context
:
Context
,
intent
:
Intent
)
{
override
def
onReceive
(
context
:
Context
,
intent
:
Intent
)
{
val
settings
=
TaskerSettings
.
fromIntent
(
intent
)
val
settings
=
TaskerSettings
.
fromIntent
(
intent
)
val
switched
=
app
.
profileManager
.
getProfile
(
settings
.
profileId
)
match
{
app
.
profileManager
.
getProfile
(
settings
.
profileId
)
match
{
case
Some
(
p
)
=>
case
Some
(
_
)
=>
app
.
switchProfile
(
settings
.
profileId
)
app
.
switchProfile
(
settings
.
profileId
)
case
_
=>
true
case
_
=>
false
}
}
if
(
settings
.
switchOn
)
Utils
.
startSsService
(
context
)
else
Utils
.
stopSsService
(
context
)
if
(
settings
.
switchOn
)
Utils
.
startSsService
(
context
)
else
Utils
.
stopSsService
(
context
)
}
}
...
...
src/main/scala/com/github/shadowsocks/database/DBHelper.scala
View file @
a5df60ae
...
@@ -36,9 +36,9 @@ object DBHelper {
...
@@ -36,9 +36,9 @@ object DBHelper {
final
val
PROFILE
=
"profile.db"
final
val
PROFILE
=
"profile.db"
private
var
apps
:
mutable.Buffer
[
ApplicationInfo
]
=
_
private
var
apps
:
mutable.Buffer
[
ApplicationInfo
]
=
_
def
isAllDigits
(
x
:
String
)
=
!
x
.
isEmpty
&&
(
x
forall
Character
.
isDigit
)
def
isAllDigits
(
x
:
String
)
:
Boolean
=
!
x
.
isEmpty
&&
(
x
forall
Character
.
isDigit
)
def
updateProxiedApps
(
context
:
Context
,
old
:
String
)
=
{
def
updateProxiedApps
(
context
:
Context
,
old
:
String
)
:
String
=
{
synchronized
(
if
(
apps
==
null
)
apps
=
context
.
getPackageManager
.
getInstalledApplications
(
0
).
asScala
)
synchronized
(
if
(
apps
==
null
)
apps
=
context
.
getPackageManager
.
getInstalledApplications
(
0
).
asScala
)
val
uidSet
=
old
.
split
(
'|'
).
filter
(
isAllDigits
).
map
(
_
.
toInt
).
toSet
val
uidSet
=
old
.
split
(
'|'
).
filter
(
isAllDigits
).
map
(
_
.
toInt
).
toSet
apps
.
filter
(
ai
=>
uidSet
.
contains
(
ai
.
uid
)).
map
(
_
.
packageName
).
mkString
(
"\n"
)
apps
.
filter
(
ai
=>
uidSet
.
contains
(
ai
.
uid
)).
map
(
_
.
packageName
).
mkString
(
"\n"
)
...
...
src/main/scala/com/github/shadowsocks/database/Profile.scala
View file @
a5df60ae
...
@@ -95,9 +95,9 @@ class Profile {
...
@@ -95,9 +95,9 @@ class Profile {
@DatabaseField
@DatabaseField
var
kcpcli
:
String
=
"--crypt none --mode normal --mtu 1200 --nocomp --dscp 46 --parityshard 0"
var
kcpcli
:
String
=
"--crypt none --mode normal --mtu 1200 --nocomp --dscp 46 --parityshard 0"
override
def
toString
=
"ss://"
+
Base64
.
encodeToString
(
"%s%s:%s@%s:%d"
.
formatLocal
(
Locale
.
ENGLISH
,
override
def
toString
:
String
=
"ss://"
+
Base64
.
encodeToString
(
"%s%s:%s@%s:%d"
.
formatLocal
(
Locale
.
ENGLISH
,
method
,
if
(
auth
)
"-auth"
else
""
,
password
,
host
,
remotePort
).
getBytes
,
Base64
.
NO_PADDING
|
Base64
.
NO_WRAP
)
+
method
,
if
(
auth
)
"-auth"
else
""
,
password
,
host
,
remotePort
).
getBytes
,
Base64
.
NO_PADDING
|
Base64
.
NO_WRAP
)
+
'#'
+
URLEncoder
.
encode
(
name
,
"utf-8"
)
'#'
+
URLEncoder
.
encode
(
name
,
"utf-8"
)
def
isMethodUnsafe
=
"table"
.
equalsIgnoreCase
(
method
)
||
"rc4"
.
equalsIgnoreCase
(
method
)
def
isMethodUnsafe
:
Boolean
=
"table"
.
equalsIgnoreCase
(
method
)
||
"rc4"
.
equalsIgnoreCase
(
method
)
}
}
src/main/scala/com/github/shadowsocks/database/ProfileManager.scala
View file @
a5df60ae
...
@@ -31,7 +31,7 @@ class ProfileManager(dbHelper: DBHelper) {
...
@@ -31,7 +31,7 @@ class ProfileManager(dbHelper: DBHelper) {
import
ProfileManager._
import
ProfileManager._
var
profileAddedListener
:
Profile
=>
Any
=
_
var
profileAddedListener
:
Profile
=>
Any
=
_
def
setProfileAddedListener
(
listener
:
Profile
=>
Any
)
=
this
.
profileAddedListener
=
listener
def
setProfileAddedListener
(
listener
:
Profile
=>
Any
)
:
Unit
=
this
.
profileAddedListener
=
listener
def
createProfile
(
p
:
Profile
=
null
)
:
Profile
=
{
def
createProfile
(
p
:
Profile
=
null
)
:
Profile
=
{
val
profile
=
if
(
p
==
null
)
new
Profile
else
p
val
profile
=
if
(
p
==
null
)
new
Profile
else
p
...
@@ -99,7 +99,7 @@ class ProfileManager(dbHelper: DBHelper) {
...
@@ -99,7 +99,7 @@ class ProfileManager(dbHelper: DBHelper) {
}
}
}
}
def
getFirstProfile
=
{
def
getFirstProfile
:
Option
[
Profile
]
=
{
try
{
try
{
val
result
=
dbHelper
.
profileDao
.
query
(
dbHelper
.
profileDao
.
queryBuilder
.
limit
(
1L
).
prepare
)
val
result
=
dbHelper
.
profileDao
.
query
(
dbHelper
.
profileDao
.
queryBuilder
.
limit
(
1L
).
prepare
)
if
(
result
.
size
==
1
)
Option
(
result
.
get
(
0
))
else
None
if
(
result
.
size
==
1
)
Option
(
result
.
get
(
0
))
else
None
...
...
src/main/scala/com/github/shadowsocks/job/AclSyncJob.scala
View file @
a5df60ae
...
@@ -36,7 +36,7 @@ import com.github.shadowsocks.utils.IOUtils
...
@@ -36,7 +36,7 @@ import com.github.shadowsocks.utils.IOUtils
object
AclSyncJob
{
object
AclSyncJob
{
final
val
TAG
=
"AclSyncJob"
final
val
TAG
=
"AclSyncJob"
def
schedule
(
route
:
String
)
=
new
JobRequest
.
Builder
(
AclSyncJob
.
TAG
+
':'
+
route
)
def
schedule
(
route
:
String
)
:
Int
=
new
JobRequest
.
Builder
(
AclSyncJob
.
TAG
+
':'
+
route
)
.
setExecutionWindow
(
1
,
TimeUnit
.
DAYS
.
toMillis
(
28
))
.
setExecutionWindow
(
1
,
TimeUnit
.
DAYS
.
toMillis
(
28
))
.
setRequirementsEnforced
(
true
)
.
setRequirementsEnforced
(
true
)
.
setRequiredNetworkType
(
JobRequest
.
NetworkType
.
UNMETERED
)
.
setRequiredNetworkType
(
JobRequest
.
NetworkType
.
UNMETERED
)
...
...
src/main/scala/com/github/shadowsocks/job/DonaldTrump.scala
View file @
a5df60ae
...
@@ -32,7 +32,7 @@ import com.evernote.android.job.JobCreator
...
@@ -32,7 +32,7 @@ import com.evernote.android.job.JobCreator
* @author !Mygod
* @author !Mygod
*/
*/
object
DonaldTrump
extends
JobCreator
{
object
DonaldTrump
extends
JobCreator
{
def
create
(
tag
:
String
)
=
{
def
create
(
tag
:
String
)
:
AclSyncJob
=
{
val
parts
=
tag
.
split
(
":"
)
val
parts
=
tag
.
split
(
":"
)
parts
(
0
)
match
{
parts
(
0
)
match
{
case
AclSyncJob
.
TAG
=>
new
AclSyncJob
(
parts
(
1
))
case
AclSyncJob
.
TAG
=>
new
AclSyncJob
(
parts
(
1
))
...
...
src/main/scala/com/github/shadowsocks/utils/CloseUtils.scala
View file @
a5df60ae
...
@@ -35,9 +35,9 @@ object CloseUtils {
...
@@ -35,9 +35,9 @@ object CloseUtils {
block
(
a
.
get
)
block
(
a
.
get
)
}
finally
if
(
a
.
nonEmpty
)
try
{
}
finally
if
(
a
.
nonEmpty
)
try
{
val
v
=
a
.
get
val
v
=
a
.
get
if
(
v
ne
null
)
v
.
close
if
(
v
ne
null
)
v
.
close
()
}
catch
{
}
catch
{
case
ignore
:
Exception
=>
case
_
:
Exception
=>
}
}
}
}
def
autoDisconnect
[
A
<:
Disconnectable
,
B
](
x
:
=>
A
)(
block
:
A
=>
B
)
:
B
=
{
def
autoDisconnect
[
A
<:
Disconnectable
,
B
](
x
:
=>
A
)(
block
:
A
=>
B
)
:
B
=
{
...
@@ -47,9 +47,9 @@ object CloseUtils {
...
@@ -47,9 +47,9 @@ object CloseUtils {
block
(
a
.
get
)
block
(
a
.
get
)
}
finally
if
(
a
.
nonEmpty
)
try
{
}
finally
if
(
a
.
nonEmpty
)
try
{
val
v
=
a
.
get
val
v
=
a
.
get
if
(
v
ne
null
)
v
.
disconnect
if
(
v
ne
null
)
v
.
disconnect
()
}
catch
{
}
catch
{
case
ignore
:
Exception
=>
case
_
:
Exception
=>
}
}
}
}
}
}
src/main/scala/com/github/shadowsocks/utils/IOUtils.scala
View file @
a5df60ae
...
@@ -47,5 +47,6 @@ object IOUtils {
...
@@ -47,5 +47,6 @@ object IOUtils {
null
null
}
}
def
writeString
(
file
:
String
,
content
:
String
)
=
autoClose
(
new
FileWriter
(
file
))(
writer
=>
writer
.
write
(
content
))
def
writeString
(
file
:
String
,
content
:
String
)
:
Unit
=
autoClose
(
new
FileWriter
(
file
))(
writer
=>
writer
.
write
(
content
))
}
}
src/main/scala/com/github/shadowsocks/utils/Parser.scala
View file @
a5df60ae
...
@@ -30,23 +30,23 @@ object Parser {
...
@@ -30,23 +30,23 @@ object Parser {
private
val
pattern
=
"(?i)ss://([A-Za-z0-9+-/=_]+)(#(.+))?"
.
r
private
val
pattern
=
"(?i)ss://([A-Za-z0-9+-/=_]+)(#(.+))?"
.
r
private
val
decodedPattern
=
"(?i)^((.+?)(-auth)??:(.*)@(.+?):(\\d+?))$"
.
r
private
val
decodedPattern
=
"(?i)^((.+?)(-auth)??:(.*)@(.+?):(\\d+?))$"
.
r
def
findAll
(
data
:
CharSequence
)
=
pattern
.
findAllMatchIn
(
if
(
data
==
null
)
""
else
data
).
map
(
m
=>
try
def
findAll
(
data
:
CharSequence
)
:
Iterator
[
Profile
]
=
decodedPattern
.
findFirstMatchIn
(
new
String
(
Base64
.
decode
(
m
.
group
(
1
),
Base64
.
NO_PADDING
),
"UTF-8"
))
match
{
pattern
.
findAllMatchIn
(
if
(
data
==
null
)
""
else
data
).
map
(
m
=>
try
case
Some
(
ss
)
=>
decodedPattern
.
findFirstMatchIn
(
new
String
(
Base64
.
decode
(
m
.
group
(
1
),
Base64
.
NO_PADDING
),
"UTF-8"
))
match
{
val
profile
=
new
Profile
case
Some
(
ss
)
=>
profile
.
method
=
ss
.
group
(
2
).
toLowerCas
e
val
profile
=
new
Profil
e
if
(
ss
.
group
(
3
)
!=
null
)
profile
.
auth
=
tru
e
profile
.
method
=
ss
.
group
(
2
).
toLowerCas
e
profile
.
password
=
ss
.
group
(
4
)
if
(
ss
.
group
(
3
)
!=
null
)
profile
.
auth
=
true
profile
.
name
=
ss
.
group
(
5
)
profile
.
password
=
ss
.
group
(
4
)
profile
.
host
=
profile
.
name
profile
.
name
=
ss
.
group
(
5
)
profile
.
remotePort
=
ss
.
group
(
6
).
toInt
profile
.
host
=
profile
.
name
if
(
m
.
group
(
2
)
!=
null
)
profile
.
name
=
URLDecoder
.
decode
(
m
.
group
(
3
),
"utf-8"
)
profile
.
remotePort
=
ss
.
group
(
6
).
toInt
profile
if
(
m
.
group
(
2
)
!=
null
)
profile
.
name
=
URLDecoder
.
decode
(
m
.
group
(
3
),
"utf-8"
)
case
_
=>
null
profile
}
case
_
=>
null
catch
{
}
catch
{
case
ex
:
Exception
=>
case
ex
:
Exception
=>
Log
.
e
(
TAG
,
"parser error: "
+
m
.
source
,
ex
)
// Ignore
Log
.
e
(
TAG
,
"parser error: "
+
m
.
source
,
ex
)
// Ignore
null
null
}).
filter
(
_
!=
null
)
}).
filter
(
_
!=
null
)
}
}
src/main/scala/com/github/shadowsocks/utils/TaskerSettings.scala
View file @
a5df60ae
...
@@ -37,10 +37,10 @@ object TaskerSettings {
...
@@ -37,10 +37,10 @@ object TaskerSettings {
class
TaskerSettings
(
bundle
:
Bundle
)
{
class
TaskerSettings
(
bundle
:
Bundle
)
{
import
TaskerSettings._
import
TaskerSettings._
var
switchOn
=
bundle
.
getBoolean
(
KEY_SWITCH_ON
,
true
)
var
switchOn
:
Boolean
=
bundle
.
getBoolean
(
KEY_SWITCH_ON
,
true
)
var
profileId
=
bundle
.
getInt
(
KEY_PROFILE_ID
,
-
1
)
var
profileId
:
Int
=
bundle
.
getInt
(
KEY_PROFILE_ID
,
-
1
)
def
toIntent
(
context
:
Context
)
=
{
def
toIntent
(
context
:
Context
)
:
Intent
=
{
val
bundle
=
new
Bundle
()
val
bundle
=
new
Bundle
()
if
(!
switchOn
)
bundle
.
putBoolean
(
KEY_SWITCH_ON
,
false
)
if
(!
switchOn
)
bundle
.
putBoolean
(
KEY_SWITCH_ON
,
false
)
if
(
profileId
>=
0
)
bundle
.
putInt
(
KEY_PROFILE_ID
,
profileId
)
if
(
profileId
>=
0
)
bundle
.
putInt
(
KEY_PROFILE_ID
,
profileId
)
...
...
src/main/scala/com/github/shadowsocks/utils/TcpFastOpen.scala
View file @
a5df60ae
...
@@ -33,7 +33,7 @@ object TcpFastOpen {
...
@@ -33,7 +33,7 @@ object TcpFastOpen {
/**
/**
* Is kernel version >= 3.7.1.
* Is kernel version >= 3.7.1.
*/
*/
lazy
val
supported
=
"^(\\d+)\\.(\\d+)\\.(\\d+)"
.
r
.
findFirstMatchIn
(
System
.
getProperty
(
"os.version"
))
match
{
lazy
val
supported
:
Boolean
=
"^(\\d+)\\.(\\d+)\\.(\\d+)"
.
r
.
findFirstMatchIn
(
System
.
getProperty
(
"os.version"
))
match
{
case
Some
(
m
)
=>
case
Some
(
m
)
=>
val
kernel
=
m
.
group
(
1
).
toInt
val
kernel
=
m
.
group
(
1
).
toInt
if
(
kernel
<
3
)
false
else
if
(
kernel
>
3
)
true
else
{
if
(
kernel
<
3
)
false
else
if
(
kernel
>
3
)
true
else
{
...
@@ -43,7 +43,7 @@ object TcpFastOpen {
...
@@ -43,7 +43,7 @@ object TcpFastOpen {
case
_
=>
false
case
_
=>
false
}
}
def
sendEnabled
=
{
def
sendEnabled
:
Boolean
=
{
val
file
=
new
File
(
"/proc/sys/net/ipv4/tcp_fastopen"
)
val
file
=
new
File
(
"/proc/sys/net/ipv4/tcp_fastopen"
)
file
.
canRead
&&
(
Utils
.
readAllLines
(
file
).
toInt
&
1
)
>
0
file
.
canRead
&&
(
Utils
.
readAllLines
(
file
).
toInt
&
1
)
>
0
}
}
...
...
src/main/scala/com/github/shadowsocks/utils/TrafficMonitor.scala
View file @
a5df60ae
...
@@ -53,7 +53,7 @@ object TrafficMonitor {
...
@@ -53,7 +53,7 @@ object TrafficMonitor {
else
numberFormat
.
format
(
n
)
+
' '
+
units
(
i
)
else
numberFormat
.
format
(
n
)
+
' '
+
units
(
i
)
}
}
def
updateRate
()
=
{
def
updateRate
()
:
Boolean
=
{
val
now
=
System
.
currentTimeMillis
()
val
now
=
System
.
currentTimeMillis
()
val
delta
=
now
-
timestampLast
val
delta
=
now
-
timestampLast
var
updated
=
false
var
updated
=
false
...
...
src/main/scala/com/github/shadowsocks/utils/TrafficMonitorThread.scala
View file @
a5df60ae
...
@@ -32,7 +32,7 @@ import com.github.shadowsocks.ShadowsocksApplication.app
...
@@ -32,7 +32,7 @@ import com.github.shadowsocks.ShadowsocksApplication.app
class
TrafficMonitorThread
(
context
:
Context
)
extends
Thread
{
class
TrafficMonitorThread
(
context
:
Context
)
extends
Thread
{
val
TAG
=
"TrafficMonitorThread"
val
TAG
=
"TrafficMonitorThread"
lazy
val
PATH
=
context
.
getApplicationInfo
.
dataDir
+
"/stat_path"
lazy
val
PATH
:
String
=
context
.
getApplicationInfo
.
dataDir
+
"/stat_path"
@volatile
var
serverSocket
:
LocalServerSocket
=
_
@volatile
var
serverSocket
:
LocalServerSocket
=
_
@volatile
var
isRunning
:
Boolean
=
true
@volatile
var
isRunning
:
Boolean
=
true
...
...
src/main/scala/com/github/shadowsocks/utils/Utils.scala
View file @
a5df60ae
...
@@ -66,7 +66,7 @@ object Utils {
...
@@ -66,7 +66,7 @@ object Utils {
*/
*/
// Based on: http://stackoverflow.com/a/21026866/2245107
// Based on: http://stackoverflow.com/a/21026866/2245107
def
positionToast
(
toast
:
Toast
,
view
:
View
,
window
:
Window
,
offsetX
:
Int
=
0
,
offsetY
:
Int
=
0
)
=
{
def
positionToast
(
toast
:
Toast
,
view
:
View
,
window
:
Window
,
offsetX
:
Int
=
0
,
offsetY
:
Int
=
0
)
:
Toast
=
{
val
rect
=
new
Rect
val
rect
=
new
Rect
window
.
getDecorView
.
getWindowVisibleDisplayFrame
(
rect
)
window
.
getDecorView
.
getWindowVisibleDisplayFrame
(
rect
)
val
viewLocation
=
new
Array
[
Int
](
2
)
val
viewLocation
=
new
Array
[
Int
](
2
)
...
@@ -88,11 +88,11 @@ object Utils {
...
@@ -88,11 +88,11 @@ object Utils {
to
.
setVisibility
(
View
.
VISIBLE
)
to
.
setVisibility
(
View
.
VISIBLE
)
to
.
animate
().
alpha
(
1
).
setDuration
(
shortAnimTime
)
to
.
animate
().
alpha
(
1
).
setDuration
(
shortAnimTime
)
from
.
animate
().
alpha
(
0
).
setDuration
(
shortAnimTime
).
setListener
(
new
AnimatorListenerAdapter
{
from
.
animate
().
alpha
(
0
).
setDuration
(
shortAnimTime
).
setListener
(
new
AnimatorListenerAdapter
{
override
def
onAnimationEnd
(
animation
:
Animator
)
=
from
.
setVisibility
(
View
.
GONE
)
override
def
onAnimationEnd
(
animation
:
Animator
)
:
Unit
=
from
.
setVisibility
(
View
.
GONE
)
})
})
}
}
def
readAllLines
(
f
:
File
)
=
{
def
readAllLines
(
f
:
File
)
:
String
=
{
val
scanner
=
new
Scanner
(
f
)
val
scanner
=
new
Scanner
(
f
)
try
{
try
{
scanner
.
useDelimiter
(
"\\Z"
)
scanner
.
useDelimiter
(
"\\Z"
)
...
@@ -168,40 +168,18 @@ object Utils {
...
@@ -168,40 +168,18 @@ object Utils {
}
}
}
}
}
catch
{
}
catch
{
case
e
:
Exception
=>
case
_
:
Exception
=>
}
}
None
None
}
}
def
resolve
(
host
:
String
)
:
Option
[
String
]
=
{
def
resolve
(
host
:
String
)
:
Option
[
String
]
=
try
Some
(
InetAddress
.
getByName
(
host
).
getHostAddress
)
catch
{
try
{
case
_:
UnknownHostException
=>
None
val
addr
=
InetAddress
.
getByName
(
host
)
Some
(
addr
.
getHostAddress
)
}
catch
{
case
e
:
UnknownHostException
=>
None
}
}
}
def
resolve
(
host
:
String
,
enableIPv6
:
Boolean
)
:
Option
[
String
]
=
{
def
resolve
(
host
:
String
,
enableIPv6
:
Boolean
)
:
Option
[
String
]
=
if
(
enableIPv6
&&
Utils
.
isIPv6Support
)
{
(
if
(
enableIPv6
&&
Utils
.
isIPv6Support
)
resolve
(
host
,
Type
.
AAAA
)
else
None
).
orElse
(
resolve
(
host
,
Type
.
A
))
resolve
(
host
,
Type
.
AAAA
)
match
{
.
orElse
(
resolve
(
host
))
case
Some
(
addr
)
=>
return
Some
(
addr
)
case
None
=>
}
}
resolve
(
host
,
Type
.
A
)
match
{
case
Some
(
addr
)
=>
return
Some
(
addr
)
case
None
=>
}
resolve
(
host
)
match
{
case
Some
(
addr
)
=>
return
Some
(
addr
)
case
None
=>
}
None
}
private
lazy
val
isNumericMethod
=
classOf
[
InetAddress
].
getMethod
(
"isNumeric"
,
classOf
[
String
])
private
lazy
val
isNumericMethod
=
classOf
[
InetAddress
].
getMethod
(
"isNumeric"
,
classOf
[
String
])
def
isNumeric
(
address
:
String
)
:
Boolean
=
isNumericMethod
.
invoke
(
null
,
address
).
asInstanceOf
[
Boolean
]
def
isNumeric
(
address
:
String
)
:
Boolean
=
isNumericMethod
.
invoke
(
null
,
address
).
asInstanceOf
[
Boolean
]
...
@@ -242,5 +220,5 @@ object Utils {
...
@@ -242,5 +220,5 @@ object Utils {
case
_
=>
case
_
=>
}
}
def
ThrowableFuture
[
T
](
f
:
=>
T
)
=
Future
(
f
)
onComplete
handleFailure
def
ThrowableFuture
[
T
](
f
:
=>
T
)
:
Unit
=
Future
(
f
)
onComplete
handleFailure
}
}
src/main/scala/com/github/shadowsocks/widget/FloatingActionMenuBehavior.scala
View file @
a5df60ae
...
@@ -42,10 +42,11 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
...
@@ -42,10 +42,11 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
private
var
fabTranslationYAnimator
:
ValueAnimator
=
_
private
var
fabTranslationYAnimator
:
ValueAnimator
=
_
private
var
fabTranslationY
:
Float
=
_
private
var
fabTranslationY
:
Float
=
_
override
def
layoutDependsOn
(
parent
:
CoordinatorLayout
,
child
:
FloatingActionMenu
,
dependency
:
View
)
=
override
def
layoutDependsOn
(
parent
:
CoordinatorLayout
,
child
:
FloatingActionMenu
,
dependency
:
View
)
:
Boolean
=
dependency
.
isInstanceOf
[
SnackbarLayout
]
dependency
.
isInstanceOf
[
SnackbarLayout
]
override
def
onDependentViewChanged
(
parent
:
CoordinatorLayout
,
child
:
FloatingActionMenu
,
dependency
:
View
)
=
{
override
def
onDependentViewChanged
(
parent
:
CoordinatorLayout
,
child
:
FloatingActionMenu
,
dependency
:
View
)
:
Boolean
=
{
dependency
match
{
dependency
match
{
case
_:
SnackbarLayout
=>
case
_:
SnackbarLayout
=>
var
targetTransY
=
parent
.
getDependencies
(
child
).
asScala
var
targetTransY
=
parent
.
getDependencies
(
child
).
asScala
...
@@ -54,7 +55,7 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
...
@@ -54,7 +55,7 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
if
(
targetTransY
>
0
)
targetTransY
=
0
if
(
targetTransY
>
0
)
targetTransY
=
0
if
(
fabTranslationY
!=
targetTransY
)
{
if
(
fabTranslationY
!=
targetTransY
)
{
val
currentTransY
=
child
.
getTranslationY
val
currentTransY
=
child
.
getTranslationY
if
(
fabTranslationYAnimator
!=
null
&&
fabTranslationYAnimator
.
isRunning
)
fabTranslationYAnimator
.
cancel
if
(
fabTranslationYAnimator
!=
null
&&
fabTranslationYAnimator
.
isRunning
)
fabTranslationYAnimator
.
cancel
()
if
(
child
.
isShown
&&
Math
.
abs
(
currentTransY
-
targetTransY
)
>
child
.
getHeight
*
0.667F
)
{
if
(
child
.
isShown
&&
Math
.
abs
(
currentTransY
-
targetTransY
)
>
child
.
getHeight
*
0.667F
)
{
if
(
fabTranslationYAnimator
==
null
)
{
if
(
fabTranslationYAnimator
==
null
)
{
fabTranslationYAnimator
=
new
ValueAnimator
fabTranslationYAnimator
=
new
ValueAnimator
...
@@ -63,7 +64,7 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
...
@@ -63,7 +64,7 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
child
.
setTranslationY
(
animation
.
getAnimatedValue
.
asInstanceOf
[
Float
]))
child
.
setTranslationY
(
animation
.
getAnimatedValue
.
asInstanceOf
[
Float
]))
}
}
fabTranslationYAnimator
.
setFloatValues
(
currentTransY
,
targetTransY
)
fabTranslationYAnimator
.
setFloatValues
(
currentTransY
,
targetTransY
)
fabTranslationYAnimator
.
start
fabTranslationYAnimator
.
start
()
}
else
child
.
setTranslationY
(
targetTransY
)
}
else
child
.
setTranslationY
(
targetTransY
)
fabTranslationY
=
targetTransY
fabTranslationY
=
targetTransY
}
}
...
@@ -74,7 +75,7 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
...
@@ -74,7 +75,7 @@ class FloatingActionMenuBehavior(context: Context, attrs: AttributeSet)
override
def
onStartNestedScroll
(
parent
:
CoordinatorLayout
,
child
:
FloatingActionMenu
,
directTargetChild
:
View
,
override
def
onStartNestedScroll
(
parent
:
CoordinatorLayout
,
child
:
FloatingActionMenu
,
directTargetChild
:
View
,
target
:
View
,
nestedScrollAxes
:
Int
)
=
true
target
:
View
,
nestedScrollAxes
:
Int
)
=
true
override
def
onNestedScroll
(
parent
:
CoordinatorLayout
,
child
:
FloatingActionMenu
,
target
:
View
,
dxConsumed
:
Int
,
override
def
onNestedScroll
(
parent
:
CoordinatorLayout
,
child
:
FloatingActionMenu
,
target
:
View
,
dxConsumed
:
Int
,
dyConsumed
:
Int
,
dxUnconsumed
:
Int
,
dyUnconsumed
:
Int
)
=
{
dyConsumed
:
Int
,
dxUnconsumed
:
Int
,
dyUnconsumed
:
Int
)
{
super
.
onNestedScroll
(
parent
,
child
,
target
,
dxConsumed
,
dyConsumed
,
dxUnconsumed
,
dyUnconsumed
)
super
.
onNestedScroll
(
parent
,
child
,
target
,
dxConsumed
,
dyConsumed
,
dxUnconsumed
,
dyUnconsumed
)
val
dy
=
dyConsumed
+
dyUnconsumed
val
dy
=
dyConsumed
+
dyUnconsumed
if
(
child
.
isMenuButtonHidden
)
{
if
(
child
.
isMenuButtonHidden
)
{
...
...
src/main/scala/com/github/shadowsocks/widget/UndoSnackbarManager.scala
View file @
a5df60ae
...
@@ -37,12 +37,12 @@ class UndoSnackbarManager[T](view: View, undo: Iterator[(Int, T)] => Unit,
...
@@ -37,12 +37,12 @@ class UndoSnackbarManager[T](view: View, undo: Iterator[(Int, T)] => Unit,
commit
:
Iterator
[(
Int
,
T
)]
=>
Unit
=
null
)
{
commit
:
Iterator
[(
Int
,
T
)]
=>
Unit
=
null
)
{
private
val
recycleBin
=
new
ArrayBuffer
[(
Int
,
T
)]
private
val
recycleBin
=
new
ArrayBuffer
[(
Int
,
T
)]
private
val
removedCallback
=
new
Snackbar
.
Callback
{
private
val
removedCallback
=
new
Snackbar
.
Callback
{
override
def
onDismissed
(
snackbar
:
Snackbar
,
event
:
Int
)
=
{
override
def
onDismissed
(
snackbar
:
Snackbar
,
event
:
Int
)
{
event
match
{
event
match
{
case
Snackbar
.
Callback
.
DISMISS_EVENT_SWIPE
|
Snackbar
.
Callback
.
DISMISS_EVENT_MANUAL
|
case
Snackbar
.
Callback
.
DISMISS_EVENT_SWIPE
|
Snackbar
.
Callback
.
DISMISS_EVENT_MANUAL
|
Snackbar
.
Callback
.
DISMISS_EVENT_TIMEOUT
=>
Snackbar
.
Callback
.
DISMISS_EVENT_TIMEOUT
=>
if
(
commit
!=
null
)
commit
(
recycleBin
.
iterator
)
if
(
commit
!=
null
)
commit
(
recycleBin
.
iterator
)
recycleBin
.
clear
recycleBin
.
clear
()
case
_
=>
case
_
=>
}
}
last
=
null
last
=
null
...
@@ -50,7 +50,7 @@ class UndoSnackbarManager[T](view: View, undo: Iterator[(Int, T)] => Unit,
...
@@ -50,7 +50,7 @@ class UndoSnackbarManager[T](view: View, undo: Iterator[(Int, T)] => Unit,
}
}
private
var
last
:
Snackbar
=
_
private
var
last
:
Snackbar
=
_
def
remove
(
index
:
Int
,
item
:
T
)
=
{
def
remove
(
index
:
Int
,
item
:
T
)
{
recycleBin
.
append
((
index
,
item
))
recycleBin
.
append
((
index
,
item
))
val
count
=
recycleBin
.
length
val
count
=
recycleBin
.
length
last
=
Snackbar
last
=
Snackbar
...
@@ -59,8 +59,8 @@ class UndoSnackbarManager[T](view: View, undo: Iterator[(Int, T)] => Unit,
...
@@ -59,8 +59,8 @@ class UndoSnackbarManager[T](view: View, undo: Iterator[(Int, T)] => Unit,
undo
(
recycleBin
.
reverseIterator
)
undo
(
recycleBin
.
reverseIterator
)
recycleBin
.
clear
recycleBin
.
clear
})
:
View.OnClickListener
)
})
:
View.OnClickListener
)
last
.
show
last
.
show
()
}
}
def
flush
=
if
(
last
!=
null
)
last
.
dismiss
def
flush
()
:
Unit
=
if
(
last
!=
null
)
last
.
dismiss
()
}
}
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