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
27589723
Commit
27589723
authored
Jan 19, 2019
by
Mygod
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix leaks after service switches
parent
24bd70a4
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
99 additions
and
114 deletions
+99
-114
core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
+90
-96
core/src/main/java/com/github/shadowsocks/bg/ProxyService.kt
core/src/main/java/com/github/shadowsocks/bg/ProxyService.kt
+3
-6
core/src/main/java/com/github/shadowsocks/bg/TransproxyService.kt
.../main/java/com/github/shadowsocks/bg/TransproxyService.kt
+3
-6
core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
+3
-6
No files found.
core/src/main/java/com/github/shadowsocks/bg/BaseService.kt
View file @
27589723
...
@@ -61,15 +61,12 @@ object BaseService {
...
@@ -61,15 +61,12 @@ object BaseService {
const
val
CONFIG_FILE
=
"shadowsocks.conf"
const
val
CONFIG_FILE
=
"shadowsocks.conf"
const
val
CONFIG_FILE_UDP
=
"shadowsocks-udp.conf"
const
val
CONFIG_FILE_UDP
=
"shadowsocks-udp.conf"
class
Data
internal
constructor
(
private
val
service
:
Interface
)
:
AutoCloseable
{
class
Data
internal
constructor
(
private
val
service
:
Interface
)
{
@Volatile
var
state
=
STOPPED
@Volatile
var
state
=
STOPPED
val
processes
=
GuardedProcessPool
()
val
processes
=
GuardedProcessPool
()
@Volatile
var
proxy
:
ProxyInstance
?
=
null
@Volatile
var
proxy
:
ProxyInstance
?
=
null
@Volatile
var
udpFallback
:
ProxyInstance
?
=
null
@Volatile
var
udpFallback
:
ProxyInstance
?
=
null
val
callbacks
=
RemoteCallbackList
<
IShadowsocksServiceCallback
>()
val
bandwidthListeners
=
HashSet
<
IBinder
>()
// the binder is the real identifier
var
notification
:
ServiceNotification
?
=
null
var
notification
:
ServiceNotification
?
=
null
val
closeReceiver
=
broadcastReceiver
{
_
,
intent
->
val
closeReceiver
=
broadcastReceiver
{
_
,
intent
->
when
(
intent
.
action
)
{
when
(
intent
.
action
)
{
...
@@ -79,94 +76,118 @@ object BaseService {
...
@@ -79,94 +76,118 @@ object BaseService {
}
}
var
closeReceiverRegistered
=
false
var
closeReceiverRegistered
=
false
val
binder
=
object
:
IShadowsocksService
.
Stub
()
{
val
binder
=
Binder
(
this
)
override
fun
getState
():
Int
=
this
@Data
.
state
override
fun
getProfileName
():
String
=
proxy
?.
profile
?.
name
?:
"Idle"
override
fun
registerCallback
(
cb
:
IShadowsocksServiceCallback
)
{
fun
changeState
(
s
:
Int
,
msg
:
String
?
=
null
)
{
callbacks
.
register
(
cb
)
if
(
state
==
s
&&
msg
==
null
)
return
binder
.
stateChanged
(
s
,
msg
)
state
=
s
}
init
{
RemoteConfig
.
fetch
()
}
}
class
Binder
(
private
var
data
:
Data
?
=
null
)
:
IShadowsocksService
.
Stub
(),
AutoCloseable
{
val
callbacks
=
RemoteCallbackList
<
IShadowsocksServiceCallback
>()
private
val
bandwidthListeners
=
HashSet
<
IBinder
>()
// the binder is the real identifier
override
fun
getState
():
Int
=
data
!!
.
state
override
fun
getProfileName
():
String
=
data
!!
.
proxy
?.
profile
?.
name
?:
"Idle"
override
fun
registerCallback
(
cb
:
IShadowsocksServiceCallback
)
{
callbacks
.
register
(
cb
)
}
private
fun
broadcast
(
work
:
(
IShadowsocksServiceCallback
)
->
Unit
)
{
val
n
=
callbacks
.
beginBroadcast
()
for
(
i
in
0
until
n
)
try
{
work
(
callbacks
.
getBroadcastItem
(
i
))
}
catch
(
e
:
Exception
)
{
printLog
(
e
)
}
}
callbacks
.
finishBroadcast
()
}
private
fun
registerTimeout
()
=
private
fun
registerTimeout
()
=
Core
.
handler
.
postAtTime
(
this
::
onTimeout
,
this
,
SystemClock
.
uptimeMillis
()
+
1000
)
Core
.
handler
.
postAtTime
(
this
::
onTimeout
,
this
,
SystemClock
.
uptimeMillis
()
+
1000
)
private
fun
onTimeout
()
{
private
fun
onTimeout
()
{
val
proxies
=
listOfNotNull
(
proxy
,
udpFallback
)
val
proxies
=
listOfNotNull
(
data
!!
.
proxy
,
data
!!
.
udpFallback
)
val
stats
=
proxies
val
stats
=
proxies
.
map
{
Pair
(
it
.
profile
.
id
,
it
.
trafficMonitor
?.
requestUpdate
())
}
.
map
{
Pair
(
it
.
profile
.
id
,
it
.
trafficMonitor
?.
requestUpdate
())
}
.
filter
{
it
.
second
!=
null
}
.
filter
{
it
.
second
!=
null
}
.
map
{
Triple
(
it
.
first
,
it
.
second
!!
.
first
,
it
.
second
!!
.
second
)
}
.
map
{
Triple
(
it
.
first
,
it
.
second
!!
.
first
,
it
.
second
!!
.
second
)
}
if
(
stats
.
any
{
it
.
third
}
&&
state
==
CONNECTED
&&
bandwidthListeners
.
isNotEmpty
())
{
if
(
stats
.
any
{
it
.
third
}
&&
state
==
CONNECTED
&&
bandwidthListeners
.
isNotEmpty
())
{
val
sum
=
stats
.
fold
(
TrafficStats
())
{
a
,
b
->
a
+
b
.
second
}
val
sum
=
stats
.
fold
(
TrafficStats
())
{
a
,
b
->
a
+
b
.
second
}
val
n
=
callbacks
.
beginBroadcast
()
broadcast
{
item
->
for
(
i
in
0
until
n
)
try
{
if
(
bandwidthListeners
.
contains
(
item
.
asBinder
()))
{
val
item
=
callbacks
.
getBroadcastItem
(
i
)
stats
.
forEach
{
(
id
,
stats
)
->
item
.
trafficUpdated
(
id
,
stats
)
}
if
(
bandwidthListeners
.
contains
(
item
.
asBinder
()))
{
item
.
trafficUpdated
(
0
,
sum
)
stats
.
forEach
{
(
id
,
stats
)
->
item
.
trafficUpdated
(
id
,
stats
)
}
item
.
trafficUpdated
(
0
,
sum
)
}
}
catch
(
e
:
Exception
)
{
printLog
(
e
)
}
}
callbacks
.
finishBroadcast
()
}
}
registerTimeout
()
}
}
registerTimeout
()
}
override
fun
startListeningForBandwidth
(
cb
:
IShadowsocksServiceCallback
)
{
override
fun
startListeningForBandwidth
(
cb
:
IShadowsocksServiceCallback
)
{
val
wasEmpty
=
bandwidthListeners
.
isEmpty
()
val
wasEmpty
=
bandwidthListeners
.
isEmpty
()
if
(
bandwidthListeners
.
add
(
cb
.
asBinder
()))
{
if
(
bandwidthListeners
.
add
(
cb
.
asBinder
()))
{
if
(
wasEmpty
)
registerTimeout
()
if
(
wasEmpty
)
registerTimeout
()
if
(
state
!=
CONNECTED
)
return
if
(
state
!=
CONNECTED
)
return
var
sum
=
TrafficStats
()
var
sum
=
TrafficStats
()
val
proxy
=
proxy
?:
return
val
proxy
=
data
!!
.
proxy
?:
return
proxy
.
trafficMonitor
?.
out
.
also
{
stats
->
proxy
.
trafficMonitor
?.
out
.
also
{
stats
->
cb
.
trafficUpdated
(
proxy
.
profile
.
id
,
if
(
stats
==
null
)
sum
else
{
cb
.
trafficUpdated
(
proxy
.
profile
.
id
,
if
(
stats
==
null
)
sum
else
{
sum
+=
stats
stats
})
}
data
!!
.
udpFallback
?.
also
{
udpFallback
->
udpFallback
.
trafficMonitor
?.
out
.
also
{
stats
->
cb
.
trafficUpdated
(
udpFallback
.
profile
.
id
,
if
(
stats
==
null
)
TrafficStats
()
else
{
sum
+=
stats
sum
+=
stats
stats
stats
})
})
}
}
udpFallback
?.
also
{
udpFallback
->
udpFallback
.
trafficMonitor
?.
out
.
also
{
stats
->
cb
.
trafficUpdated
(
udpFallback
.
profile
.
id
,
if
(
stats
==
null
)
TrafficStats
()
else
{
sum
+=
stats
stats
})
}
}
cb
.
trafficUpdated
(
0
,
sum
)
}
}
cb
.
trafficUpdated
(
0
,
sum
)
}
}
}
override
fun
stopListeningForBandwidth
(
cb
:
IShadowsocksServiceCallback
)
{
override
fun
stopListeningForBandwidth
(
cb
:
IShadowsocksServiceCallback
)
{
if
(
bandwidthListeners
.
remove
(
cb
.
asBinder
())
&&
bandwidthListeners
.
isEmpty
())
{
if
(
bandwidthListeners
.
remove
(
cb
.
asBinder
())
&&
bandwidthListeners
.
isEmpty
())
{
Core
.
handler
.
removeCallbacksAndMessages
(
this
)
Core
.
handler
.
removeCallbacksAndMessages
(
this
)
}
}
}
}
override
fun
unregisterCallback
(
cb
:
IShadowsocksServiceCallback
)
{
override
fun
unregisterCallback
(
cb
:
IShadowsocksServiceCallback
)
{
stopListeningForBandwidth
(
cb
)
// saves an RPC, and safer
stopListeningForBandwidth
(
cb
)
// saves an RPC, and safer
callbacks
.
unregister
(
cb
)
callbacks
.
unregister
(
cb
)
}
}
}
fun
changeState
(
s
:
Int
,
msg
:
String
?
=
null
)
{
fun
stateChanged
(
s
:
Int
,
msg
:
String
?)
{
if
(
state
==
s
&&
msg
==
null
)
return
val
profileName
=
profileName
if
(
callbacks
.
registeredCallbackCount
>
0
)
Core
.
handler
.
post
{
broadcast
{
it
.
stateChanged
(
s
,
profileName
,
msg
)
}
val
n
=
callbacks
.
beginBroadcast
()
}
for
(
i
in
0
until
n
)
try
{
callbacks
.
getBroadcastItem
(
i
).
stateChanged
(
s
,
binder
.
profileName
,
msg
)
fun
trafficPersisted
(
ids
:
List
<
Long
>)
{
}
catch
(
e
:
Exception
)
{
if
(
bandwidthListeners
.
isNotEmpty
()
&&
ids
.
isNotEmpty
())
broadcast
{
item
->
printLog
(
e
)
if
(
bandwidthListeners
.
contains
(
item
.
asBinder
()))
ids
.
forEach
(
item
::
trafficPersisted
)
}
callbacks
.
finishBroadcast
()
}
}
state
=
s
}
}
override
fun
close
()
=
callbacks
.
kill
()
override
fun
close
()
{
callbacks
.
kill
()
Core
.
handler
.
removeCallbacksAndMessages
(
this
)
data
=
null
}
}
}
interface
Interface
{
interface
Interface
{
val
data
:
Data
val
tag
:
String
val
tag
:
String
fun
createNotification
(
profileName
:
String
):
ServiceNotification
fun
onBind
(
intent
:
Intent
):
IBinder
?
=
if
(
intent
.
action
==
Action
.
SERVICE
)
data
.
binder
else
null
fun
onBind
(
intent
:
Intent
):
IBinder
?
=
if
(
intent
.
action
==
Action
.
SERVICE
)
data
.
binder
else
null
...
@@ -206,8 +227,6 @@ object BaseService {
...
@@ -206,8 +227,6 @@ object BaseService {
"-U"
)
"-U"
)
}
}
fun
createNotification
(
profileName
:
String
):
ServiceNotification
fun
startRunner
()
{
fun
startRunner
()
{
this
as
Context
this
as
Context
if
(
Build
.
VERSION
.
SDK_INT
>=
26
)
startForegroundService
(
Intent
(
this
,
javaClass
))
if
(
Build
.
VERSION
.
SDK_INT
>=
26
)
startForegroundService
(
Intent
(
this
,
javaClass
))
...
@@ -240,20 +259,7 @@ object BaseService {
...
@@ -240,20 +259,7 @@ object BaseService {
it
.
profile
.
id
it
.
profile
.
id
}
}
data
.
proxy
=
null
data
.
proxy
=
null
if
(
ids
.
isNotEmpty
())
Core
.
handler
.
post
{
data
.
binder
.
trafficPersisted
(
ids
)
if
(
data
.
bandwidthListeners
.
isNotEmpty
())
{
val
n
=
data
.
callbacks
.
beginBroadcast
()
for
(
i
in
0
until
n
)
{
try
{
val
item
=
data
.
callbacks
.
getBroadcastItem
(
i
)
if
(
data
.
bandwidthListeners
.
contains
(
item
.
asBinder
()))
ids
.
forEach
(
item
::
trafficPersisted
)
}
catch
(
e
:
Exception
)
{
printLog
(
e
)
}
}
data
.
callbacks
.
finishBroadcast
()
}
}
// change the state
// change the state
data
.
changeState
(
STOPPED
,
msg
)
data
.
changeState
(
STOPPED
,
msg
)
...
@@ -262,8 +268,6 @@ object BaseService {
...
@@ -262,8 +268,6 @@ object BaseService {
if
(
stopService
)
stopSelf
()
if
(
stopService
)
stopSelf
()
}
}
val
data
:
Data
get
()
=
instances
[
this
]
!!
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
{
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
{
val
data
=
data
val
data
=
data
if
(
data
.
state
!=
STOPPED
)
return
Service
.
START_NOT_STICKY
if
(
data
.
state
!=
STOPPED
)
return
Service
.
START_NOT_STICKY
...
@@ -320,15 +324,5 @@ object BaseService {
...
@@ -320,15 +324,5 @@ object BaseService {
}
}
return
Service
.
START_NOT_STICKY
return
Service
.
START_NOT_STICKY
}
}
fun
onDestroy
()
{
data
.
close
()
}
}
private
val
instances
=
WeakHashMap
<
Interface
,
Data
>()
internal
fun
register
(
instance
:
Interface
)
{
instances
[
instance
]
=
Data
(
instance
)
RemoteConfig
.
fetch
()
}
}
}
}
core/src/main/java/com/github/shadowsocks/bg/ProxyService.kt
View file @
27589723
...
@@ -27,10 +27,7 @@ import android.content.Intent
...
@@ -27,10 +27,7 @@ import android.content.Intent
* Shadowsocks service at its minimum.
* Shadowsocks service at its minimum.
*/
*/
class
ProxyService
:
Service
(),
BaseService
.
Interface
{
class
ProxyService
:
Service
(),
BaseService
.
Interface
{
init
{
override
val
data
=
BaseService
.
Data
(
this
)
BaseService
.
register
(
this
)
}
override
val
tag
:
String
get
()
=
"ShadowsocksProxyService"
override
val
tag
:
String
get
()
=
"ShadowsocksProxyService"
override
fun
createNotification
(
profileName
:
String
):
ServiceNotification
=
override
fun
createNotification
(
profileName
:
String
):
ServiceNotification
=
ServiceNotification
(
this
,
profileName
,
"service-proxy"
,
true
)
ServiceNotification
(
this
,
profileName
,
"service-proxy"
,
true
)
...
@@ -39,7 +36,7 @@ class ProxyService : Service(), BaseService.Interface {
...
@@ -39,7 +36,7 @@ class ProxyService : Service(), BaseService.Interface {
override
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
=
override
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
=
super
<
BaseService
.
Interface
>.
onStartCommand
(
intent
,
flags
,
startId
)
super
<
BaseService
.
Interface
>.
onStartCommand
(
intent
,
flags
,
startId
)
override
fun
onDestroy
()
{
override
fun
onDestroy
()
{
super
<
Service
>
.
onDestroy
()
super
.
onDestroy
()
super
<
BaseService
.
Interface
>.
onDestroy
()
data
.
binder
.
close
()
}
}
}
}
core/src/main/java/com/github/shadowsocks/bg/TransproxyService.kt
View file @
27589723
...
@@ -27,10 +27,7 @@ import com.github.shadowsocks.preference.DataStore
...
@@ -27,10 +27,7 @@ import com.github.shadowsocks.preference.DataStore
import
java.io.File
import
java.io.File
class
TransproxyService
:
Service
(),
LocalDnsService
.
Interface
{
class
TransproxyService
:
Service
(),
LocalDnsService
.
Interface
{
init
{
override
val
data
=
BaseService
.
Data
(
this
)
BaseService
.
register
(
this
)
}
override
val
tag
:
String
get
()
=
"ShadowsocksTransproxyService"
override
val
tag
:
String
get
()
=
"ShadowsocksTransproxyService"
override
fun
createNotification
(
profileName
:
String
):
ServiceNotification
=
override
fun
createNotification
(
profileName
:
String
):
ServiceNotification
=
ServiceNotification
(
this
,
profileName
,
"service-transproxy"
,
true
)
ServiceNotification
(
this
,
profileName
,
"service-transproxy"
,
true
)
...
@@ -79,7 +76,7 @@ redsocks {
...
@@ -79,7 +76,7 @@ redsocks {
}
}
override
fun
onDestroy
()
{
override
fun
onDestroy
()
{
super
<
Service
>
.
onDestroy
()
super
.
onDestroy
()
super
<
LocalDnsService
.
Interface
>.
onDestroy
()
data
.
binder
.
close
()
}
}
}
}
core/src/main/java/com/github/shadowsocks/bg/VpnService.kt
View file @
27589723
...
@@ -108,10 +108,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
...
@@ -108,10 +108,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
override
fun
getLocalizedMessage
()
=
getString
(
R
.
string
.
reboot_required
)
override
fun
getLocalizedMessage
()
=
getString
(
R
.
string
.
reboot_required
)
}
}
init
{
override
val
data
=
BaseService
.
Data
(
this
)
BaseService
.
register
(
this
)
}
override
val
tag
:
String
get
()
=
"ShadowsocksVpnService"
override
val
tag
:
String
get
()
=
"ShadowsocksVpnService"
override
fun
createNotification
(
profileName
:
String
):
ServiceNotification
=
override
fun
createNotification
(
profileName
:
String
):
ServiceNotification
=
ServiceNotification
(
this
,
profileName
,
"service-vpn"
)
ServiceNotification
(
this
,
profileName
,
"service-vpn"
)
...
@@ -282,7 +279,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
...
@@ -282,7 +279,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
}
}
override
fun
onDestroy
()
{
override
fun
onDestroy
()
{
super
<
BaseVpnService
>
.
onDestroy
()
super
.
onDestroy
()
super
<
LocalDnsService
.
Interface
>.
onDestroy
()
data
.
binder
.
close
()
}
}
}
}
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