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
32aa8007
Commit
32aa8007
authored
Jan 19, 2019
by
Mygod
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix memory leaks caused by writeStrongBinder
parent
fcdcbd14
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
159 additions
and
128 deletions
+159
-128
core/src/main/aidl/com/github/shadowsocks/aidl/IShadowsocksService.aidl
...aidl/com/github/shadowsocks/aidl/IShadowsocksService.aidl
+4
-4
core/src/main/aidl/com/github/shadowsocks/aidl/IShadowsocksServiceCallback.aidl
.../github/shadowsocks/aidl/IShadowsocksServiceCallback.aidl
+4
-4
core/src/main/java/com/github/shadowsocks/Core.kt
core/src/main/java/com/github/shadowsocks/Core.kt
+2
-1
core/src/main/java/com/github/shadowsocks/VpnRequestActivity.kt
...rc/main/java/com/github/shadowsocks/VpnRequestActivity.kt
+7
-9
core/src/main/java/com/github/shadowsocks/aidl/ShadowsocksConnection.kt
...java/com/github/shadowsocks/aidl/ShadowsocksConnection.kt
+52
-22
core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
+7
-9
core/src/main/java/com/github/shadowsocks/bg/ProxyService.kt
core/src/main/java/com/github/shadowsocks/bg/ProxyService.kt
+4
-0
core/src/main/java/com/github/shadowsocks/bg/TransproxyService.kt
.../main/java/com/github/shadowsocks/bg/TransproxyService.kt
+5
-0
core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
+7
-1
core/src/main/java/com/github/shadowsocks/utils/HttpsTest.kt
core/src/main/java/com/github/shadowsocks/utils/HttpsTest.kt
+1
-1
mobile/src/main/java/com/github/shadowsocks/MainActivity.kt
mobile/src/main/java/com/github/shadowsocks/MainActivity.kt
+16
-22
mobile/src/main/java/com/github/shadowsocks/QuickToggleShortcut.kt
...c/main/java/com/github/shadowsocks/QuickToggleShortcut.kt
+7
-2
mobile/src/main/java/com/github/shadowsocks/bg/TileService.kt
...le/src/main/java/com/github/shadowsocks/bg/TileService.kt
+29
-33
tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt
.../java/com/github/shadowsocks/tv/MainPreferenceFragment.kt
+14
-20
No files found.
core/src/main/aidl/com/github/shadowsocks/aidl/IShadowsocksService.aidl
View file @
32aa8007
...
...
@@ -6,8 +6,8 @@ interface IShadowsocksService {
int
getState
();
String
getProfileName
();
oneway
void
registerCallback
(
IShadowsocksServiceCallback
cb
);
oneway
void
startListeningForBandwidth
(
IShadowsocksServiceCallback
cb
);
oneway
void
stopListeningForBandwidth
(
IShadowsocksServiceCallback
cb
);
oneway
void
unregisterCallback
(
IShadowsocksServiceCallback
cb
);
void
registerCallback
(
in
IShadowsocksServiceCallback
cb
);
void
startListeningForBandwidth
(
in
IShadowsocksServiceCallback
cb
);
oneway
void
stopListeningForBandwidth
(
in
IShadowsocksServiceCallback
cb
);
oneway
void
unregisterCallback
(
in
IShadowsocksServiceCallback
cb
);
}
core/src/main/aidl/com/github/shadowsocks/aidl/IShadowsocksServiceCallback.aidl
View file @
32aa8007
...
...
@@ -2,9 +2,9 @@ package com.github.shadowsocks.aidl;
import
com
.
github
.
shadowsocks
.
aidl
.
TrafficStats
;
interface
IShadowsocksServiceCallback
{
oneway
void
stateChanged
(
int
state
,
String
profileName
,
String
msg
);
oneway
void
trafficUpdated
(
long
profileId
,
in
TrafficStats
stats
);
oneway
interface
IShadowsocksServiceCallback
{
void
stateChanged
(
int
state
,
String
profileName
,
String
msg
);
void
trafficUpdated
(
long
profileId
,
in
TrafficStats
stats
);
//
Traffic
data
has
persisted
to
database
,
listener
should
refetch
their
data
from
database
oneway
void
trafficPersisted
(
long
profileId
);
void
trafficPersisted
(
long
profileId
);
}
core/src/main/java/com/github/shadowsocks/Core.kt
View file @
32aa8007
...
...
@@ -42,6 +42,7 @@ import androidx.work.Configuration
import
androidx.work.WorkManager
import
com.crashlytics.android.Crashlytics
import
com.github.shadowsocks.acl.Acl
import
com.github.shadowsocks.aidl.ShadowsocksConnection
import
com.github.shadowsocks.bg.BaseService
import
com.github.shadowsocks.core.R
import
com.github.shadowsocks.database.Profile
...
...
@@ -140,7 +141,7 @@ object Core {
if
(
Build
.
VERSION
.
SDK_INT
>=
28
)
PackageManager
.
GET_SIGNING_CERTIFICATES
else
@Suppress
(
"DEPRECATION"
)
PackageManager
.
GET_SIGNATURES
)
!!
fun
startService
()
=
ContextCompat
.
startForegroundService
(
app
,
Intent
(
app
,
BaseService
.
serviceClass
.
java
))
fun
startService
()
=
ContextCompat
.
startForegroundService
(
app
,
Intent
(
app
,
ShadowsocksConnection
.
serviceClass
))
fun
reloadService
()
=
app
.
sendBroadcast
(
Intent
(
Action
.
RELOAD
))
fun
stopService
()
=
app
.
sendBroadcast
(
Intent
(
Action
.
CLOSE
))
...
...
core/src/main/java/com/github/shadowsocks/VpnRequestActivity.kt
View file @
32aa8007
...
...
@@ -31,33 +31,32 @@ import android.widget.Toast
import
androidx.appcompat.app.AppCompatActivity
import
androidx.core.content.getSystemService
import
com.crashlytics.android.Crashlytics
import
com.github.shadowsocks.aidl.IShadowsocksService
import
com.github.shadowsocks.bg.BaseService
import
com.github.shadowsocks.core.R
import
com.github.shadowsocks.preference.DataStore
import
com.github.shadowsocks.utils.Key
import
com.github.shadowsocks.utils.broadcastReceiver
class
VpnRequestActivity
:
AppCompatActivity
()
,
ShadowsocksConnection
.
Callback
{
class
VpnRequestActivity
:
AppCompatActivity
()
{
companion
object
{
private
const
val
TAG
=
"VpnRequestActivity"
private
const
val
REQUEST_CONNECT
=
1
}
private
val
connection
=
ShadowsocksConnection
(
this
)
private
var
receiver
:
BroadcastReceiver
?
=
null
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
if
(
!
BaseService
.
usingVpnMode
)
{
if
(
DataStore
.
serviceMode
!=
Key
.
modeVpn
)
{
finish
()
return
}
if
(
getSystemService
<
KeyguardManager
>()
!!
.
isKeyguardLocked
)
{
receiver
=
broadcastReceiver
{
_
,
_
->
connection
.
connect
(
this
)
}
receiver
=
broadcastReceiver
{
_
,
_
->
request
(
)
}
registerReceiver
(
receiver
,
IntentFilter
(
Intent
.
ACTION_USER_PRESENT
))
}
else
connection
.
connect
(
this
)
}
else
request
(
)
}
override
fun
onServiceConnected
(
service
:
IShadowsocksService
)
{
private
fun
request
(
)
{
val
intent
=
VpnService
.
prepare
(
this
)
if
(
intent
==
null
)
onActivityResult
(
REQUEST_CONNECT
,
RESULT_OK
,
null
)
else
startActivityForResult
(
intent
,
REQUEST_CONNECT
)
...
...
@@ -73,7 +72,6 @@ class VpnRequestActivity : AppCompatActivity(), ShadowsocksConnection.Callback {
override
fun
onDestroy
()
{
super
.
onDestroy
()
connection
.
disconnect
(
this
)
if
(
receiver
!=
null
)
unregisterReceiver
(
receiver
)
}
}
core/src/main/java/com/github/shadowsocks/ShadowsocksConnection.kt
→
core/src/main/java/com/github/shadowsocks/
aidl/
ShadowsocksConnection.kt
View file @
32aa8007
...
...
@@ -18,7 +18,7 @@
* *
*******************************************************************************/
package
com.github.shadowsocks
package
com.github.shadowsocks
.aidl
import
android.content.ComponentName
import
android.content.Context
...
...
@@ -27,15 +27,31 @@ import android.content.ServiceConnection
import
android.os.DeadObjectException
import
android.os.IBinder
import
android.os.RemoteException
import
com.github.shadowsocks.aidl.IShadowsocksService
import
com.github.shadowsocks.aidl.IShadowsocksServiceCallback
import
com.github.shadowsocks.bg.BaseService
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.bg.ProxyService
import
com.github.shadowsocks.bg.TransproxyService
import
com.github.shadowsocks.bg.VpnService
import
com.github.shadowsocks.preference.DataStore
import
com.github.shadowsocks.utils.Action
import
com.github.shadowsocks.utils.Key
/**
* This object should be compact as it will not get GC-ed.
*/
class
ShadowsocksConnection
(
private
var
listenForDeath
:
Boolean
=
false
)
:
ServiceConnection
,
IBinder
.
DeathRecipient
{
companion
object
{
val
serviceClass
get
()
=
when
(
DataStore
.
serviceMode
)
{
Key
.
modeProxy
->
ProxyService
::
class
Key
.
modeVpn
->
VpnService
::
class
Key
.
modeTransproxy
->
TransproxyService
::
class
else -> throw
UnknownError
()
}.
java
}
class
ShadowsocksConnection
(
private
val
callback
:
Callback
,
private
var
listenForDeath
:
Boolean
=
false
)
:
ServiceConnection
,
IBinder
.
DeathRecipient
{
interface
Callback
{
val
serviceCallback
:
IShadowsocksServiceCallback
?
get
()
=
null
fun
stateChanged
(
state
:
Int
,
profileName
:
String
?,
msg
:
String
?)
fun
trafficUpdated
(
profileId
:
Long
,
stats
:
TrafficStats
)
{
}
fun
trafficPersisted
(
profileId
:
Long
)
{
}
fun
onServiceConnected
(
service
:
IShadowsocksService
)
/**
...
...
@@ -47,14 +63,26 @@ class ShadowsocksConnection(private val callback: Callback, private var listenFo
private
var
connectionActive
=
false
private
var
callbackRegistered
=
false
private
var
callback
:
Callback
?
=
null
private
val
serviceCallback
=
object
:
IShadowsocksServiceCallback
.
Stub
()
{
override
fun
stateChanged
(
state
:
Int
,
profileName
:
String
?,
msg
:
String
?)
{
Core
.
handler
.
post
{
callback
!!
.
stateChanged
(
state
,
profileName
,
msg
)
}
}
override
fun
trafficUpdated
(
profileId
:
Long
,
stats
:
TrafficStats
)
{
Core
.
handler
.
post
{
callback
!!
.
trafficUpdated
(
profileId
,
stats
)
}
}
override
fun
trafficPersisted
(
profileId
:
Long
)
{
Core
.
handler
.
post
{
callback
!!
.
trafficPersisted
(
profileId
)
}
}
}
private
var
binder
:
IBinder
?
=
null
var
listeningForBandwidth
=
false
set
(
value
)
{
val
service
=
service
if
(
listeningForBandwidth
!=
value
&&
service
!=
null
&&
callback
.
serviceCallback
!=
null
)
if
(
value
)
service
.
startListeningForBandwidth
(
callback
.
serviceCallback
)
else
try
{
service
.
stopListeningForBandwidth
(
callback
.
serviceCallback
)
if
(
listeningForBandwidth
!=
value
&&
service
!=
null
)
if
(
value
)
service
.
startListeningForBandwidth
(
serviceCallback
)
else
try
{
service
.
stopListeningForBandwidth
(
serviceCallback
)
}
catch
(
_
:
DeadObjectException
)
{
}
field
=
value
}
...
...
@@ -65,51 +93,53 @@ class ShadowsocksConnection(private val callback: Callback, private var listenFo
if
(
listenForDeath
)
binder
.
linkToDeath
(
this
,
0
)
val
service
=
IShadowsocksService
.
Stub
.
asInterface
(
binder
)
!!
this
.
service
=
service
if
(
callback
.
serviceCallback
!=
null
&&
!
callbackRegistered
)
try
{
service
.
registerCallback
(
callback
.
serviceCallback
)
if
(!
callbackRegistered
)
try
{
service
.
registerCallback
(
serviceCallback
)
callbackRegistered
=
true
if
(
listeningForBandwidth
)
service
.
startListeningForBandwidth
(
callback
.
serviceCallback
)
if
(
listeningForBandwidth
)
service
.
startListeningForBandwidth
(
serviceCallback
)
}
catch
(
_
:
RemoteException
)
{
}
callback
.
onServiceConnected
(
service
)
callback
!!
.
onServiceConnected
(
service
)
}
override
fun
onServiceDisconnected
(
name
:
ComponentName
?)
{
unregisterCallback
()
callback
.
onServiceDisconnected
()
callback
!!
.
onServiceDisconnected
()
service
=
null
binder
=
null
}
override
fun
binderDied
()
{
service
=
null
callback
.
onBinderDied
()
callback
!!
.
onBinderDied
()
}
private
fun
unregisterCallback
()
{
val
service
=
service
if
(
service
!=
null
&&
callback
.
serviceCallback
!=
null
&&
callback
Registered
)
try
{
service
.
unregisterCallback
(
callback
.
serviceCallback
)
if
(
service
!=
null
&&
callbackRegistered
)
try
{
service
.
unregisterCallback
(
serviceCallback
)
}
catch
(
_
:
RemoteException
)
{
}
callbackRegistered
=
false
}
fun
connect
(
context
:
Context
)
{
fun
connect
(
context
:
Context
,
callback
:
Callback
)
{
if
(
connectionActive
)
return
connectionActive
=
true
val
intent
=
Intent
(
context
,
BaseService
.
serviceClass
.
java
).
setAction
(
Action
.
SERVICE
)
check
(
this
.
callback
==
null
)
this
.
callback
=
callback
val
intent
=
Intent
(
context
,
serviceClass
).
setAction
(
Action
.
SERVICE
)
context
.
bindService
(
intent
,
this
,
Context
.
BIND_AUTO_CREATE
)
}
fun
disconnect
(
context
:
Context
)
{
unregisterCallback
()
callback
.
onServiceDisconnected
()
if
(
connectionActive
)
try
{
context
.
unbindService
(
this
)
}
catch
(
_
:
IllegalArgumentException
)
{
}
// ignore
connectionActive
=
false
if
(
listenForDeath
)
binder
?.
unlinkToDeath
(
this
,
0
)
binder
=
null
if
(
callback
.
serviceCallback
!=
null
)
service
?.
stopListeningForBandwidth
(
callback
.
serviceCallback
)
service
?.
stopListeningForBandwidth
(
serviceCallback
)
service
=
null
callback
=
null
}
}
core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
View file @
32aa8007
...
...
@@ -59,7 +59,7 @@ object BaseService {
const
val
CONFIG_FILE
=
"shadowsocks.conf"
const
val
CONFIG_FILE_UDP
=
"shadowsocks-udp.conf"
class
Data
internal
constructor
(
private
val
service
:
Interface
)
{
class
Data
internal
constructor
(
private
val
service
:
Interface
)
:
AutoCloseable
{
@Volatile
var
state
=
STOPPED
val
processes
=
GuardedProcessPool
()
@Volatile
var
proxy
:
ProxyInstance
?
=
null
...
...
@@ -160,6 +160,8 @@ object BaseService {
}
state
=
s
}
override
fun
close
()
=
callbacks
.
kill
()
}
interface
Interface
{
val
tag
:
String
...
...
@@ -317,6 +319,10 @@ object BaseService {
}
return
Service
.
START_NOT_STICKY
}
fun
onDestroy
()
{
data
.
close
()
}
}
private
val
instances
=
WeakHashMap
<
Interface
,
Data
>()
...
...
@@ -324,12 +330,4 @@ object BaseService {
instances
[
instance
]
=
Data
(
instance
)
RemoteConfig
.
fetch
()
}
val
usingVpnMode
:
Boolean
get
()
=
DataStore
.
serviceMode
==
Key
.
modeVpn
val
serviceClass
get
()
=
when
(
DataStore
.
serviceMode
)
{
Key
.
modeProxy
->
ProxyService
::
class
Key
.
modeVpn
->
VpnService
::
class
Key
.
modeTransproxy
->
TransproxyService
::
class
else -> throw
UnknownError
()
}
}
core/src/main/java/com/github/shadowsocks/bg/ProxyService.kt
View file @
32aa8007
...
...
@@ -38,4 +38,8 @@ class ProxyService : Service(), BaseService.Interface {
override
fun
onBind
(
intent
:
Intent
)
=
super
.
onBind
(
intent
)
override
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
=
super
<
BaseService
.
Interface
>.
onStartCommand
(
intent
,
flags
,
startId
)
override
fun
onDestroy
()
{
super
<
Service
>.
onDestroy
()
super
<
BaseService
.
Interface
>.
onDestroy
()
}
}
core/src/main/java/com/github/shadowsocks/bg/TransproxyService.kt
View file @
32aa8007
...
...
@@ -77,4 +77,9 @@ redsocks {
super
.
startNativeProcesses
()
if
(
data
.
proxy
!!
.
profile
.
udpdns
)
startDNSTunnel
()
}
override
fun
onDestroy
()
{
super
<
Service
>.
onDestroy
()
super
<
LocalDnsService
.
Interface
>.
onDestroy
()
}
}
core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
View file @
32aa8007
...
...
@@ -35,6 +35,7 @@ import com.github.shadowsocks.VpnRequestActivity
import
com.github.shadowsocks.acl.Acl
import
com.github.shadowsocks.core.R
import
com.github.shadowsocks.preference.DataStore
import
com.github.shadowsocks.utils.Key
import
com.github.shadowsocks.utils.Subnet
import
com.github.shadowsocks.utils.parseNumericAddress
import
com.github.shadowsocks.utils.printLog
...
...
@@ -160,7 +161,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
}
override
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
{
if
(
BaseService
.
usingVpnMode
)
if
(
DataStore
.
serviceMode
==
Key
.
modeVpn
)
if
(
BaseVpnService
.
prepare
(
this
)
!=
null
)
startActivity
(
Intent
(
this
,
VpnRequestActivity
::
class
.
java
)
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
))
...
...
@@ -279,4 +280,9 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
tries
+=
1
}
}
override
fun
onDestroy
()
{
super
<
BaseVpnService
>.
onDestroy
()
super
<
LocalDnsService
.
Interface
>.
onDestroy
()
}
}
core/src/main/java/com/github/shadowsocks/utils/HttpsTest.kt
View file @
32aa8007
...
...
@@ -84,7 +84,7 @@ class HttpsTest : ViewModel() {
Acl
.
CHINALIST
->
"www.qualcomm.cn"
else
->
"www.google.com"
},
"/generate_204"
)
val
conn
=
(
if
(
BaseService
.
usingVpnMode
)
url
.
openConnection
()
else
val
conn
=
(
if
(
DataStore
.
serviceMode
==
Key
.
modeVpn
)
url
.
openConnection
()
else
url
.
openConnection
(
Proxy
(
Proxy
.
Type
.
SOCKS
,
InetSocketAddress
(
"127.0.0.1"
,
DataStore
.
portProxy
))))
as
HttpURLConnection
conn
.
setRequestProperty
(
"Connection"
,
"close"
)
...
...
mobile/src/main/java/com/github/shadowsocks/MainActivity.kt
View file @
32aa8007
...
...
@@ -45,7 +45,7 @@ import androidx.preference.PreferenceDataStore
import
com.crashlytics.android.Crashlytics
import
com.github.shadowsocks.acl.CustomRulesFragment
import
com.github.shadowsocks.aidl.IShadowsocksService
import
com.github.shadowsocks.aidl.
IShadowsocksServiceCallback
import
com.github.shadowsocks.aidl.
ShadowsocksConnection
import
com.github.shadowsocks.aidl.TrafficStats
import
com.github.shadowsocks.bg.BaseService
import
com.github.shadowsocks.bg.Executable
...
...
@@ -92,12 +92,8 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Callback, OnPref
// service
var
state
=
BaseService
.
IDLE
override
val
serviceCallback
=
object
:
IShadowsocksServiceCallback
.
Stub
()
{
override
fun
stateChanged
(
state
:
Int
,
profileName
:
String
?,
msg
:
String
?)
{
Core
.
handler
.
post
{
changeState
(
state
,
msg
,
true
)
}
}
override
fun
stateChanged
(
state
:
Int
,
profileName
:
String
?,
msg
:
String
?)
=
changeState
(
state
,
msg
,
true
)
override
fun
trafficUpdated
(
profileId
:
Long
,
stats
:
TrafficStats
)
{
Core
.
handler
.
post
{
if
(
profileId
==
0L
)
this
@MainActivity
.
stats
.
updateTraffic
(
stats
.
txRate
,
stats
.
rxRate
,
stats
.
txTotal
,
stats
.
rxTotal
)
if
(
state
!=
BaseService
.
STOPPING
)
{
...
...
@@ -105,10 +101,8 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Callback, OnPref
?.
onTrafficUpdated
(
profileId
,
stats
)
}
}
}
override
fun
trafficPersisted
(
profileId
:
Long
)
{
Core
.
handler
.
post
{
ProfilesFragment
.
instance
?.
onTrafficPersisted
(
profileId
)
}
}
ProfilesFragment
.
instance
?.
onTrafficPersisted
(
profileId
)
}
private
fun
changeState
(
state
:
Int
,
msg
:
String
?
=
null
,
animate
:
Boolean
=
false
)
{
...
...
@@ -122,7 +116,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Callback, OnPref
private
fun
toggle
()
=
when
{
state
==
BaseService
.
CONNECTED
->
Core
.
stopService
()
BaseService
.
usingVpnMode
->
{
DataStore
.
serviceMode
==
Key
.
modeVpn
->
{
val
intent
=
VpnService
.
prepare
(
this
)
if
(
intent
!=
null
)
startActivityForResult
(
intent
,
REQUEST_CONNECT
)
else
onActivityResult
(
REQUEST_CONNECT
,
Activity
.
RESULT_OK
,
null
)
...
...
@@ -130,7 +124,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Callback, OnPref
else
->
Core
.
startService
()
}
private
val
connection
=
ShadowsocksConnection
(
t
his
,
t
rue
)
private
val
connection
=
ShadowsocksConnection
(
true
)
override
fun
onServiceConnected
(
service
:
IShadowsocksService
)
=
changeState
(
try
{
service
.
state
}
catch
(
_
:
DeadObjectException
)
{
...
...
@@ -141,7 +135,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Callback, OnPref
Core
.
handler
.
post
{
connection
.
disconnect
(
this
)
Executable
.
killAll
()
connection
.
connect
(
this
)
connection
.
connect
(
this
,
this
)
}
}
...
...
@@ -173,7 +167,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Callback, OnPref
fab
.
setOnClickListener
{
toggle
()
}
changeState
(
BaseService
.
IDLE
)
// reset everything to init state
Core
.
handler
.
post
{
connection
.
connect
(
this
)
}
Core
.
handler
.
post
{
connection
.
connect
(
this
,
this
)
}
DataStore
.
publicStore
.
registerChangeListener
(
this
)
val
intent
=
this
.
intent
...
...
@@ -213,7 +207,7 @@ class MainActivity : AppCompatActivity(), ShadowsocksConnection.Callback, OnPref
when
(
key
)
{
Key
.
serviceMode
->
Core
.
handler
.
post
{
connection
.
disconnect
(
this
)
connection
.
connect
(
this
)
connection
.
connect
(
this
,
this
)
}
}
}
...
...
mobile/src/main/java/com/github/shadowsocks/QuickToggleShortcut.kt
View file @
32aa8007
...
...
@@ -30,10 +30,13 @@ import androidx.core.content.pm.ShortcutInfoCompat
import
androidx.core.content.pm.ShortcutManagerCompat
import
androidx.core.graphics.drawable.IconCompat
import
com.github.shadowsocks.aidl.IShadowsocksService
import
com.github.shadowsocks.aidl.ShadowsocksConnection
import
com.github.shadowsocks.bg.BaseService
@Suppress
(
"DEPRECATION"
)
@Deprecated
(
"This shortcut is inefficient and should be superseded by TileService for API 24+."
)
class
QuickToggleShortcut
:
Activity
(),
ShadowsocksConnection
.
Callback
{
private
val
connection
=
ShadowsocksConnection
(
this
)
private
val
connection
=
ShadowsocksConnection
()
override
fun
onCreate
(
savedInstanceState
:
Bundle
?)
{
super
.
onCreate
(
savedInstanceState
)
...
...
@@ -46,7 +49,7 @@ class QuickToggleShortcut : Activity(), ShadowsocksConnection.Callback {
.
build
()))
finish
()
}
else
{
connection
.
connect
(
this
)
connection
.
connect
(
this
,
this
)
if
(
Build
.
VERSION
.
SDK_INT
>=
25
)
getSystemService
<
ShortcutManager
>()
!!
.
reportShortcutUsed
(
"toggle"
)
}
}
...
...
@@ -59,6 +62,8 @@ class QuickToggleShortcut : Activity(), ShadowsocksConnection.Callback {
finish
()
}
override
fun
stateChanged
(
state
:
Int
,
profileName
:
String
?,
msg
:
String
?)
{
}
override
fun
onDestroy
()
{
connection
.
disconnect
(
this
)
super
.
onDestroy
()
...
...
mobile/src/main/java/com/github/shadowsocks/bg/TileService.kt
View file @
32aa8007
...
...
@@ -23,16 +23,14 @@ package com.github.shadowsocks.bg
import
android.app.KeyguardManager
import
android.graphics.drawable.Icon
import
android.service.quicksettings.Tile
import
android.service.quicksettings.TileService
as
BaseTileService
import
androidx.annotation.RequiresApi
import
androidx.core.content.getSystemService
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.R
import
com.github.shadowsocks.ShadowsocksConnection
import
com.github.shadowsocks.aidl.IShadowsocksService
import
com.github.shadowsocks.aidl.IShadowsocksServiceCallback
import
com.github.shadowsocks.aidl.TrafficStats
import
com.github.shadowsocks.aidl.ShadowsocksConnection
import
com.github.shadowsocks.preference.DataStore
import
android.service.quicksettings.TileService
as
BaseTileService
@RequiresApi
(
24
)
class
TileService
:
BaseTileService
(),
ShadowsocksConnection
.
Callback
{
...
...
@@ -42,35 +40,10 @@ class TileService : BaseTileService(), ShadowsocksConnection.Callback {
private
val
keyguard
by
lazy
{
getSystemService
<
KeyguardManager
>()
!!
}
private
var
tapPending
=
false
private
val
connection
=
ShadowsocksConnection
(
this
)
override
val
serviceCallback
=
object
:
IShadowsocksServiceCallback
.
Stub
()
{
override
fun
stateChanged
(
state
:
Int
,
profileName
:
String
?,
msg
:
String
?)
{
val
tile
=
qsTile
?:
return
var
label
:
String
?
=
null
when
(
state
)
{
BaseService
.
STOPPED
->
{
tile
.
icon
=
iconIdle
tile
.
state
=
Tile
.
STATE_INACTIVE
}
BaseService
.
CONNECTED
->
{
tile
.
icon
=
iconConnected
if
(!
keyguard
.
isDeviceLocked
)
label
=
profileName
tile
.
state
=
Tile
.
STATE_ACTIVE
}
else
->
{
tile
.
icon
=
iconBusy
tile
.
state
=
Tile
.
STATE_UNAVAILABLE
}
}
tile
.
label
=
label
?:
getString
(
R
.
string
.
app_name
)
tile
.
updateTile
()
}
override
fun
trafficUpdated
(
profileId
:
Long
,
stats
:
TrafficStats
)
{
}
override
fun
trafficPersisted
(
profileId
:
Long
)
{
}
}
private
val
connection
=
ShadowsocksConnection
()
override
fun
stateChanged
(
state
:
Int
,
profileName
:
String
?,
msg
:
String
?)
=
updateTile
(
state
)
{
profileName
}
override
fun
onServiceConnected
(
service
:
IShadowsocksService
)
{
serviceCallback
.
stateChanged
(
service
.
state
,
service
.
profileName
,
null
)
updateTile
(
service
.
state
)
{
service
.
profileName
}
if
(
tapPending
)
{
tapPending
=
false
onClick
()
...
...
@@ -79,7 +52,7 @@ class TileService : BaseTileService(), ShadowsocksConnection.Callback {
override
fun
onStartListening
()
{
super
.
onStartListening
()
connection
.
connect
(
this
)
connection
.
connect
(
this
,
this
)
}
override
fun
onStopListening
()
{
connection
.
disconnect
(
this
)
...
...
@@ -90,6 +63,29 @@ class TileService : BaseTileService(), ShadowsocksConnection.Callback {
if
(
isLocked
&&
!
DataStore
.
canToggleLocked
)
unlockAndRun
(
this
::
toggle
)
else
toggle
()
}
private
fun
updateTile
(
serviceState
:
Int
,
profileName
:
()
->
String
?)
{
qsTile
?.
apply
{
label
=
null
when
(
serviceState
)
{
BaseService
.
STOPPED
->
{
icon
=
iconIdle
state
=
Tile
.
STATE_INACTIVE
}
BaseService
.
CONNECTED
->
{
icon
=
iconConnected
if
(!
keyguard
.
isDeviceLocked
)
label
=
profileName
()
state
=
Tile
.
STATE_ACTIVE
}
else
->
{
icon
=
iconBusy
state
=
Tile
.
STATE_UNAVAILABLE
}
}
label
=
label
?:
getString
(
R
.
string
.
app_name
)
updateTile
()
}
}
private
fun
toggle
()
{
val
service
=
connection
.
service
if
(
service
==
null
)
tapPending
=
true
else
when
(
service
.
state
)
{
...
...
tv/src/main/java/com/github/shadowsocks/tv/MainPreferenceFragment.kt
View file @
32aa8007
...
...
@@ -42,9 +42,8 @@ import androidx.preference.SwitchPreference
import
com.crashlytics.android.Crashlytics
import
com.github.shadowsocks.BootReceiver
import
com.github.shadowsocks.Core
import
com.github.shadowsocks.ShadowsocksConnection
import
com.github.shadowsocks.aidl.IShadowsocksService
import
com.github.shadowsocks.aidl.
IShadowsocksServiceCallback
import
com.github.shadowsocks.aidl.
ShadowsocksConnection
import
com.github.shadowsocks.aidl.TrafficStats
import
com.github.shadowsocks.bg.BaseService
import
com.github.shadowsocks.bg.Executable
...
...
@@ -89,10 +88,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
// service
var
state
=
BaseService
.
IDLE
private
set
override
val
serviceCallback
=
object
:
IShadowsocksServiceCallback
.
Stub
()
{
override
fun
stateChanged
(
state
:
Int
,
profileName
:
String
?,
msg
:
String
?)
{
Core
.
handler
.
post
{
changeState
(
state
,
msg
)
}
}
override
fun
stateChanged
(
state
:
Int
,
profileName
:
String
?,
msg
:
String
?)
=
changeState
(
state
,
msg
)
override
fun
trafficUpdated
(
profileId
:
Long
,
stats
:
TrafficStats
)
{
if
(
profileId
==
0L
)
this
@MainPreferenceFragment
.
stats
.
summary
=
getString
(
R
.
string
.
stat_summary
,
getString
(
R
.
string
.
speed
,
Formatter
.
formatFileSize
(
activity
,
stats
.
txRate
)),
...
...
@@ -100,8 +96,6 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
Formatter
.
formatFileSize
(
activity
,
stats
.
txTotal
),
Formatter
.
formatFileSize
(
activity
,
stats
.
rxTotal
))
}
override
fun
trafficPersisted
(
profileId
:
Long
)
{
}
}
private
fun
changeState
(
state
:
Int
,
msg
:
String
?
=
null
)
{
fab
.
isEnabled
=
state
==
BaseService
.
STOPPED
||
state
==
BaseService
.
CONNECTED
...
...
@@ -115,7 +109,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
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
,
TrafficStats
())
trafficUpdated
(
0
,
TrafficStats
())
tester
.
status
.
removeObservers
(
owner
)
if
(
state
!=
BaseService
.
IDLE
)
tester
.
invalidate
()
}
else
tester
.
status
.
observe
(
owner
,
Observer
{
...
...
@@ -141,7 +135,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
}
}
private
val
connection
=
ShadowsocksConnection
(
t
his
,
t
rue
)
private
val
connection
=
ShadowsocksConnection
(
true
)
override
fun
onServiceConnected
(
service
:
IShadowsocksService
)
=
changeState
(
try
{
service
.
state
}
catch
(
_
:
DeadObjectException
)
{
...
...
@@ -152,7 +146,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
Core
.
handler
.
post
{
connection
.
disconnect
(
activity
)
Executable
.
killAll
()
connection
.
connect
(
activity
)
connection
.
connect
(
activity
,
this
)
}
}
...
...
@@ -202,7 +196,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
tester
=
ViewModelProviders
.
of
(
activity
as
FragmentActivity
).
get
()
changeState
(
BaseService
.
IDLE
)
// reset everything to init state
connection
.
connect
(
activity
)
connection
.
connect
(
activity
,
this
)
DataStore
.
publicStore
.
registerChangeListener
(
this
)
}
...
...
@@ -227,7 +221,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
fun
startService
()
{
when
{
state
!=
BaseService
.
STOPPED
->
return
BaseService
.
usingVpnMode
->
{
DataStore
.
serviceMode
==
Key
.
modeVpn
->
{
val
intent
=
VpnService
.
prepare
(
activity
)
if
(
intent
!=
null
)
startActivityForResult
(
intent
,
REQUEST_CONNECT
)
else
onActivityResult
(
REQUEST_CONNECT
,
Activity
.
RESULT_OK
,
null
)
...
...
@@ -240,7 +234,7 @@ class MainPreferenceFragment : LeanbackPreferenceFragment(), ShadowsocksConnecti
when
(
key
)
{
Key
.
serviceMode
->
Core
.
handler
.
post
{
connection
.
disconnect
(
activity
)
connection
.
connect
(
activity
)
connection
.
connect
(
activity
,
this
)
}
}
}
...
...
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