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
f111add4
Commit
f111add4
authored
Jan 02, 2019
by
Mygod
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prevent HTTPS test losing progress on configuration change
parent
28530d06
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
79 additions
and
28 deletions
+79
-28
build.gradle
build.gradle
+1
-0
core/build.gradle
core/build.gradle
+2
-0
core/src/main/java/com/github/shadowsocks/utils/HttpsTest.kt
core/src/main/java/com/github/shadowsocks/utils/HttpsTest.kt
+45
-14
mobile/src/main/java/com/github/shadowsocks/widget/StatsBar.kt
...e/src/main/java/com/github/shadowsocks/widget/StatsBar.kt
+19
-9
tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt
.../java/com/github/shadowsocks/tv/MainPreferenceFragment.kt
+12
-5
No files found.
build.gradle
View file @
f111add4
...
...
@@ -9,6 +9,7 @@ buildscript {
sdkVersion
=
28
compileSdkVersion
=
28
buildToolsVersion
=
'28.0.3'
lifecycleVersion
=
'2.0.0'
roomVersion
=
'2.0.0'
workVersion
=
'1.0.0-beta01'
preferencexVersion
=
'1.0.0'
...
...
core/build.gradle
View file @
f111add4
...
...
@@ -71,6 +71,8 @@ tasks.whenTaskAdded { task ->
dependencies
{
api
project
(
':plugin'
)
api
"android.arch.work:work-runtime-ktx:$workVersion"
api
"androidx.lifecycle:lifecycle-extensions:$lifecycleVersion"
api
"androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion"
api
"androidx.preference:preference:1.0.0"
api
"androidx.room:room-runtime:$roomVersion"
api
'com.crashlytics.sdk.android:crashlytics:2.9.8'
...
...
core/src/main/java/com/github/shadowsocks/utils/HttpsTest.kt
View file @
f111add4
...
...
@@ -21,6 +21,8 @@
package
com.github.shadowsocks.utils
import
android.os.SystemClock
import
androidx.lifecycle.MutableLiveData
import
androidx.lifecycle.ViewModel
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.Core.app
import
com.github.shadowsocks.acl.Acl
...
...
@@ -36,12 +38,46 @@ import java.net.URL
/**
* Based on: https://android.googlesource.com/platform/frameworks/base/+/b19a838/services/core/java/com/android/server/connectivity/NetworkMonitor.java#1071
*/
class
HttpsTest
(
private
val
setStatus
:
(
CharSequence
?)
->
Unit
,
private
val
errorCallback
:
(
CharSequence
)
->
Unit
)
{
class
HttpsTest
:
ViewModel
()
{
sealed
class
Status
{
protected
abstract
val
status
:
CharSequence
open
fun
retrieve
(
setStatus
:
(
CharSequence
)
->
Unit
,
errorCallback
:
(
String
)
->
Unit
)
=
setStatus
(
status
)
object
Idle
:
Status
()
{
override
val
status
get
()
=
app
.
getText
(
R
.
string
.
vpn_connected
)
}
object
Testing
:
Status
()
{
override
val
status
get
()
=
app
.
getText
(
R
.
string
.
connection_test_testing
)
}
class
Success
(
private
val
elapsed
:
Long
)
:
Status
()
{
override
val
status
get
()
=
app
.
getString
(
R
.
string
.
connection_test_available
,
elapsed
)
}
sealed
class
Error
:
Status
()
{
override
val
status
get
()
=
app
.
getText
(
R
.
string
.
connection_test_fail
)
protected
abstract
val
error
:
String
private
var
shown
=
false
override
fun
retrieve
(
setStatus
:
(
CharSequence
)
->
Unit
,
errorCallback
:
(
String
)
->
Unit
)
{
super
.
retrieve
(
setStatus
,
errorCallback
)
if
(
shown
)
return
shown
=
true
errorCallback
(
error
)
}
class
UnexpectedResponseCode
(
private
val
code
:
Int
)
:
Error
()
{
override
val
error
get
()
=
app
.
getString
(
R
.
string
.
connection_test_error_status_code
,
code
)
}
class
IOFailure
(
private
val
e
:
IOException
)
:
Error
()
{
override
val
error
get
()
=
app
.
getString
(
R
.
string
.
connection_test_error
,
e
.
message
)
}
}
}
private
var
testCount
=
0
val
status
=
MutableLiveData
<
Status
>().
apply
{
value
=
Status
.
Idle
}
fun
testConnection
()
{
++
testCount
s
etStatus
(
app
.
getText
(
R
.
string
.
connection_test_testing
))
s
tatus
.
value
=
Status
.
Testing
val
id
=
testCount
// it would change by other code
thread
(
"ConnectionTest"
)
{
val
url
=
URL
(
"https"
,
when
(
Core
.
currentProfile
!!
.
route
)
{
...
...
@@ -54,28 +90,23 @@ class HttpsTest(private val setStatus: (CharSequence?) -> Unit, private val erro
conn
.
setRequestProperty
(
"Connection"
,
"close"
)
conn
.
instanceFollowRedirects
=
false
conn
.
useCaches
=
false
val
(
success
,
result
)
=
try
{
val
result
=
try
{
val
start
=
SystemClock
.
elapsedRealtime
()
val
code
=
conn
.
responseCode
val
elapsed
=
SystemClock
.
elapsedRealtime
()
-
start
if
(
code
==
204
||
code
==
200
&&
conn
.
responseLength
==
0L
)
Pair
(
true
,
app
.
getString
(
R
.
string
.
connection_test_available
,
elapsed
))
else
throw
IOException
(
app
.
getString
(
R
.
string
.
connection_test_error_status_code
,
code
))
if
(
code
==
204
||
code
==
200
&&
conn
.
responseLength
==
0L
)
Status
.
Success
(
elapsed
)
else
Status
.
Error
.
UnexpectedResponseCode
(
code
)
}
catch
(
e
:
IOException
)
{
Pair
(
false
,
app
.
getString
(
R
.
string
.
connection_test_error
,
e
.
message
)
)
Status
.
Error
.
IOFailure
(
e
)
}
finally
{
conn
.
disconnect
()
}
if
(
testCount
==
id
)
Core
.
handler
.
post
{
if
(
success
)
setStatus
(
result
)
else
{
setStatus
(
app
.
getText
(
R
.
string
.
connection_test_fail
))
errorCallback
(
result
)
}
}
if
(
testCount
==
id
)
status
.
postValue
(
result
)
}
}
fun
invalidate
()
{
testCount
+=
1
++
testCount
status
.
value
=
Status
.
Idle
}
}
mobile/src/main/java/com/github/shadowsocks/widget/StatsBar.kt
View file @
f111add4
...
...
@@ -26,6 +26,10 @@ import android.util.AttributeSet
import
android.view.View
import
android.widget.TextView
import
androidx.coordinatorlayout.widget.CoordinatorLayout
import
androidx.fragment.app.FragmentActivity
import
androidx.lifecycle.Observer
import
androidx.lifecycle.ViewModelProviders
import
androidx.lifecycle.get
import
com.github.shadowsocks.MainActivity
import
com.github.shadowsocks.R
import
com.github.shadowsocks.bg.BaseService
...
...
@@ -40,7 +44,7 @@ class StatsBar @JvmOverloads constructor(context: Context, attrs: AttributeSet?
private
lateinit
var
rxText
:
TextView
private
lateinit
var
txRateText
:
TextView
private
lateinit
var
rxRateText
:
TextView
private
val
tester
by
lazy
{
HttpsTest
(
statusText
::
setText
)
{
(
context
as
MainActivity
).
snackbar
(
it
).
show
()
}
}
private
val
tester
=
ViewModelProviders
.
of
(
context
as
FragmentActivity
).
get
<
HttpsTest
>()
private
val
behavior
=
object
:
Behavior
()
{
val
threshold
=
context
.
resources
.
getDimensionPixelSize
(
R
.
dimen
.
stats_bar_scroll_threshold
)
override
fun
onNestedScroll
(
coordinatorLayout
:
CoordinatorLayout
,
child
:
BottomAppBar
,
target
:
View
,
...
...
@@ -62,16 +66,22 @@ class StatsBar @JvmOverloads constructor(context: Context, attrs: AttributeSet?
}
fun
changeState
(
state
:
Int
)
{
statusText
.
setText
(
when
(
state
)
{
BaseService
.
CONNECTING
->
R
.
string
.
connecting
BaseService
.
CONNECTED
->
R
.
string
.
vpn_connected
BaseService
.
STOPPING
->
R
.
string
.
stopping
else
->
R
.
string
.
not_connected
})
val
activity
=
context
as
MainActivity
if
(
state
!=
BaseService
.
CONNECTED
)
{
updateTraffic
(
0
,
0
,
0
,
0
)
tester
.
invalidate
()
}
else
behavior
.
slideUp
(
this
)
tester
.
status
.
removeObservers
(
activity
)
if
(
state
!=
BaseService
.
IDLE
)
tester
.
invalidate
()
statusText
.
setText
(
when
(
state
)
{
BaseService
.
CONNECTING
->
R
.
string
.
connecting
BaseService
.
STOPPING
->
R
.
string
.
stopping
else
->
R
.
string
.
not_connected
})
}
else
{
behavior
.
slideUp
(
this
)
tester
.
status
.
observe
(
activity
,
Observer
{
it
.
retrieve
(
statusText
::
setText
)
{
activity
.
snackbar
(
it
).
show
()
}
})
}
}
fun
updateTraffic
(
txRate
:
Long
,
rxRate
:
Long
,
txTotal
:
Long
,
rxTotal
:
Long
)
{
...
...
tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt
View file @
f111add4
...
...
@@ -30,7 +30,11 @@ import android.os.DeadObjectException
import
android.text.format.Formatter
import
android.util.Log
import
android.widget.Toast
import
androidx.fragment.app.FragmentActivity
import
androidx.leanback.preference.LeanbackPreferenceFragment
import
androidx.lifecycle.Observer
import
androidx.lifecycle.ViewModelProviders
import
androidx.lifecycle.get
import
androidx.preference.ListPreference
import
androidx.preference.Preference
import
androidx.preference.PreferenceDataStore
...
...
@@ -79,9 +83,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
portTransproxy
.
isEnabled
=
enabledTransproxy
true
}
private
val
tester
by
lazy
{
HttpsTest
(
stats
::
setTitle
)
{
Toast
.
makeText
(
activity
,
it
,
Toast
.
LENGTH_LONG
).
show
()
}
}
private
lateinit
var
tester
:
HttpsTest
// service
var
state
=
BaseService
.
IDLE
...
...
@@ -111,10 +113,14 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
})
stats
.
setTitle
(
R
.
string
.
connection_test_pending
)
stats
.
isVisible
=
state
==
BaseService
.
CONNECTED
val
owner
=
activity
as
FragmentActivity
// TODO: change to this when refactored to androidx
if
(
state
!=
BaseService
.
CONNECTED
)
{
serviceCallback
.
trafficUpdated
(
0
,
0
,
0
,
0
,
0
)
tester
.
invalidate
()
}
tester
.
status
.
removeObservers
(
owner
)
if
(
state
!=
BaseService
.
IDLE
)
tester
.
invalidate
()
}
else
tester
.
status
.
observe
(
owner
,
Observer
{
it
.
retrieve
(
stats
::
setTitle
)
{
Toast
.
makeText
(
activity
,
it
,
Toast
.
LENGTH_LONG
).
show
()
}
})
if
(
msg
!=
null
)
Toast
.
makeText
(
activity
,
getString
(
R
.
string
.
vpn_error
,
msg
),
Toast
.
LENGTH_SHORT
).
show
()
this
.
state
=
state
if
(
state
==
BaseService
.
STOPPED
)
{
...
...
@@ -198,6 +204,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
changeState
(
BaseService
.
IDLE
)
// reset everything to init state
connection
.
connect
()
DataStore
.
publicStore
.
registerChangeListener
(
this
)
tester
=
ViewModelProviders
.
of
(
activity
as
FragmentActivity
).
get
()
}
override
fun
onStart
()
{
...
...
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