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
2641de43
Commit
2641de43
authored
Dec 27, 2015
by
Max Lv
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #494 from Mygod/master
Reduce battery usage
parents
6a0955c0
4d7bf8d7
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
194 additions
and
200 deletions
+194
-200
src/main/AndroidManifest.xml
src/main/AndroidManifest.xml
+0
-8
src/main/jni/shadowsocks-libev
src/main/jni/shadowsocks-libev
+1
-1
src/main/scala/com/github/shadowsocks/AppManager.scala
src/main/scala/com/github/shadowsocks/AppManager.scala
+70
-49
src/main/scala/com/github/shadowsocks/AppManagerReceiver.scala
...ain/scala/com/github/shadowsocks/AppManagerReceiver.scala
+0
-11
src/main/scala/com/github/shadowsocks/BaseService.scala
src/main/scala/com/github/shadowsocks/BaseService.scala
+32
-33
src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala
...scala/com/github/shadowsocks/ProfileManagerActivity.scala
+9
-0
src/main/scala/com/github/shadowsocks/ServiceBoundContext.scala
...in/scala/com/github/shadowsocks/ServiceBoundContext.scala
+17
-17
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
+5
-0
src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
.../scala/com/github/shadowsocks/ShadowsocksNatService.scala
+1
-13
src/main/scala/com/github/shadowsocks/ShadowsocksNotification.scala
...cala/com/github/shadowsocks/ShadowsocksNotification.scala
+7
-3
src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
.../scala/com/github/shadowsocks/ShadowsocksVpnService.scala
+1
-13
src/main/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala
...n/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala
+6
-4
src/main/scala/com/github/shadowsocks/utils/TrafficMonitor.scala
...n/scala/com/github/shadowsocks/utils/TrafficMonitor.scala
+40
-37
src/main/scala/com/github/shadowsocks/utils/TrafficMonitorThread.scala
...a/com/github/shadowsocks/utils/TrafficMonitorThread.scala
+5
-11
No files found.
src/main/AndroidManifest.xml
View file @
2641de43
...
...
@@ -108,14 +108,6 @@
</intent-filter>
</service>
<receiver
android:name=
".AppManagerReceiver"
>
<intent-filter>
<action
android:name=
"android.intent.action.PACKAGE_ADDED"
/>
<action
android:name=
"android.intent.action.PACKAGE_REMOVED"
/>
<data
android:scheme=
"package"
/>
</intent-filter>
</receiver>
<receiver
android:name=
".ShadowsocksReceiver"
>
<intent-filter>
<action
android:name=
"android.intent.action.BOOT_COMPLETED"
/>
...
...
shadowsocks-libev
@
68eaf3b1
Subproject commit
48a063ef1e1a886e274a0fbb797e88358deca35b
Subproject commit
68eaf3b12d385381130c046547163b81e1807ba4
src/main/scala/com/github/shadowsocks/AppManager.scala
View file @
2641de43
...
...
@@ -39,8 +39,11 @@
package
com.github.shadowsocks
import
java.util.concurrent.atomic.AtomicBoolean
import
android.Manifest.permission
import
android.content._
import
android.content.pm.PackageManager
import
android.content.
{
ClipData
,
ClipboardManager
,
Context
}
import
android.graphics.PixelFormat
import
android.graphics.drawable.Drawable
import
android.os.
{
Bundle
,
Handler
}
...
...
@@ -54,7 +57,6 @@ import android.view._
import
android.widget.AbsListView.OnScrollListener
import
android.widget.CompoundButton.OnCheckedChangeListener
import
android.widget._
import
android.Manifest.permission
import
com.github.shadowsocks.utils.
{
Key
,
Utils
}
import
scala.collection.JavaConversions._
...
...
@@ -65,13 +67,31 @@ object AppManager {
case
class
ProxiedApp
(
name
:
String
,
packageName
:
String
,
icon
:
Drawable
)
private
case
class
ListEntry
(
switch
:
Switch
,
text
:
TextView
,
icon
:
ImageView
)
var
cachedApps
:
Array
[
ProxiedApp
]
=
_
private
var
instance
:
AppManager
=
_
private
var
receiverRegistered
:
Boolean
=
_
private
var
cachedApps
:
Array
[
ProxiedApp
]
=
_
private
def
getApps
(
pm
:
PackageManager
)
=
{
if
(
cachedApps
==
null
)
cachedApps
=
pm
.
getInstalledPackages
(
PackageManager
.
GET_PERMISSIONS
)
.
filter
(
p
=>
p
.
requestedPermissions
!=
null
&&
p
.
requestedPermissions
.
contains
(
permission
.
INTERNET
))
.
map
(
p
=>
new
ProxiedApp
(
pm
.
getApplicationLabel
(
p
.
applicationInfo
).
toString
,
p
.
packageName
,
p
.
applicationInfo
.
loadIcon
(
pm
))).
toArray
cachedApps
if
(!
receiverRegistered
)
{
val
filter
=
new
IntentFilter
(
Intent
.
ACTION_PACKAGE_ADDED
)
filter
.
addAction
(
Intent
.
ACTION_PACKAGE_REMOVED
)
filter
.
addDataScheme
(
"package"
)
ShadowsocksApplication
.
instance
.
registerReceiver
((
context
:
Context
,
intent
:
Intent
)
=>
if
(
intent
.
getAction
!=
Intent
.
ACTION_PACKAGE_REMOVED
||
!
intent
.
getBooleanExtra
(
Intent
.
EXTRA_REPLACING
,
false
))
{
synchronized
(
cachedApps
=
null
)
val
instance
=
AppManager
.
instance
if
(
instance
!=
null
)
instance
.
reloadApps
()
},
filter
)
receiverRegistered
=
true
}
synchronized
{
if
(
cachedApps
==
null
)
cachedApps
=
pm
.
getInstalledPackages
(
PackageManager
.
GET_PERMISSIONS
)
.
filter
(
p
=>
p
.
requestedPermissions
!=
null
&&
p
.
requestedPermissions
.
contains
(
permission
.
INTERNET
))
.
map
(
p
=>
new
ProxiedApp
(
pm
.
getApplicationLabel
(
p
.
applicationInfo
).
toString
,
p
.
packageName
,
p
.
applicationInfo
.
loadIcon
(
pm
))).
toArray
cachedApps
}
}
}
...
...
@@ -86,43 +106,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
private
var
loadingView
:
View
=
_
private
var
overlay
:
TextView
=
_
private
var
adapter
:
ListAdapter
=
_
@volatile
private
var
appsLoading
:
Boolean
=
_
def
loadApps
()
{
appsLoading
=
true
proxiedApps
=
ShadowsocksApplication
.
settings
.
getString
(
Key
.
proxied
,
""
).
split
(
'\n'
).
to
[
mutable.HashSet
]
apps
=
getApps
(
getPackageManager
).
sortWith
((
a
,
b
)
=>
{
val
aProxied
=
proxiedApps
.
contains
(
a
.
packageName
)
if
(
aProxied
^
proxiedApps
.
contains
(
b
.
packageName
))
aProxied
else
a
.
name
.
compareToIgnoreCase
(
b
.
name
)
<
0
})
adapter
=
new
ArrayAdapter
[
ProxiedApp
](
this
,
R
.
layout
.
layout_apps_item
,
R
.
id
.
itemtext
,
apps
)
{
override
def
getView
(
position
:
Int
,
view
:
View
,
parent
:
ViewGroup
)
:
View
=
{
var
convertView
=
view
var
entry
:
ListEntry
=
null
if
(
convertView
==
null
)
{
convertView
=
getLayoutInflater
.
inflate
(
R
.
layout
.
layout_apps_item
,
parent
,
false
)
entry
=
new
ListEntry
(
convertView
.
findViewById
(
R
.
id
.
itemcheck
).
asInstanceOf
[
Switch
],
convertView
.
findViewById
(
R
.
id
.
itemtext
).
asInstanceOf
[
TextView
],
convertView
.
findViewById
(
R
.
id
.
itemicon
).
asInstanceOf
[
ImageView
])
convertView
.
setOnClickListener
(
AppManager
.
this
)
convertView
.
setTag
(
entry
)
entry
.
switch
.
setOnCheckedChangeListener
(
AppManager
.
this
)
}
else
{
entry
=
convertView
.
getTag
.
asInstanceOf
[
ListEntry
]
}
val
app
:
ProxiedApp
=
apps
(
position
)
entry
.
text
.
setText
(
app
.
name
)
entry
.
icon
.
setImageDrawable
(
app
.
icon
)
val
switch
=
entry
.
switch
switch
.
setTag
(
app
)
switch
.
setChecked
(
proxiedApps
.
contains
(
app
.
packageName
))
entry
.
text
.
setTag
(
switch
)
convertView
}
}
}
private
val
appsLoading
=
new
AtomicBoolean
private
def
setProxied
(
pn
:
String
,
proxied
:
Boolean
)
=
if
(
proxied
)
proxiedApps
.
add
(
pn
)
else
proxiedApps
.
remove
(
pn
)
...
...
@@ -145,6 +129,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
}
override
def
onDestroy
()
{
instance
=
null
super
.
onDestroy
()
if
(
handler
!=
null
)
{
handler
.
removeCallbacksAndMessages
(
null
)
...
...
@@ -186,7 +171,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
// Restart activity
appListView
.
setVisibility
(
View
.
GONE
)
loadingView
.
setVisibility
(
View
.
VISIBLE
)
if
(
appsLoading
)
appsLoading
=
false
else
loadAppsAsync
()
reloadApps
()
return
true
}
}
...
...
@@ -252,13 +237,49 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
}
}
})
instance
=
this
loadAppsAsync
()
}
def
reloadApps
()
=
if
(!
appsLoading
.
compareAndSet
(
true
,
false
))
loadAppsAsync
()
def
loadAppsAsync
()
{
if
(!
appsLoading
.
compareAndSet
(
false
,
true
))
return
ThrowableFuture
{
while
(!
appsLoading
)
loadApps
()
appsLoading
=
false
do
{
proxiedApps
=
ShadowsocksApplication
.
settings
.
getString
(
Key
.
proxied
,
""
).
split
(
'\n'
).
to
[
mutable.HashSet
]
appsLoading
.
set
(
true
)
apps
=
getApps
(
getPackageManager
).
sortWith
((
a
,
b
)
=>
{
val
aProxied
=
proxiedApps
.
contains
(
a
.
packageName
)
if
(
aProxied
^
proxiedApps
.
contains
(
b
.
packageName
))
aProxied
else
a
.
name
.
compareToIgnoreCase
(
b
.
name
)
<
0
})
adapter
=
new
ArrayAdapter
[
ProxiedApp
](
this
,
R
.
layout
.
layout_apps_item
,
R
.
id
.
itemtext
,
apps
)
{
override
def
getView
(
position
:
Int
,
view
:
View
,
parent
:
ViewGroup
)
:
View
=
{
var
convertView
=
view
var
entry
:
ListEntry
=
null
if
(
convertView
==
null
)
{
convertView
=
getLayoutInflater
.
inflate
(
R
.
layout
.
layout_apps_item
,
parent
,
false
)
entry
=
new
ListEntry
(
convertView
.
findViewById
(
R
.
id
.
itemcheck
).
asInstanceOf
[
Switch
],
convertView
.
findViewById
(
R
.
id
.
itemtext
).
asInstanceOf
[
TextView
],
convertView
.
findViewById
(
R
.
id
.
itemicon
).
asInstanceOf
[
ImageView
])
convertView
.
setOnClickListener
(
AppManager
.
this
)
convertView
.
setTag
(
entry
)
entry
.
switch
.
setOnCheckedChangeListener
(
AppManager
.
this
)
}
else
{
entry
=
convertView
.
getTag
.
asInstanceOf
[
ListEntry
]
}
val
app
:
ProxiedApp
=
apps
(
position
)
entry
.
text
.
setText
(
app
.
name
)
entry
.
icon
.
setImageDrawable
(
app
.
icon
)
val
switch
=
entry
.
switch
switch
.
setTag
(
app
)
switch
.
setChecked
(
proxiedApps
.
contains
(
app
.
packageName
))
entry
.
text
.
setTag
(
switch
)
convertView
}
}
}
while
(!
appsLoading
.
compareAndSet
(
true
,
false
))
handler
.
post
(()
=>
{
appListView
.
setAdapter
(
adapter
)
Utils
.
crossFade
(
AppManager
.
this
,
loadingView
,
appListView
)
...
...
@@ -267,7 +288,7 @@ class AppManager extends AppCompatActivity with OnCheckedChangeListener with OnC
}
def
saveAppSettings
(
context
:
Context
)
{
if
(!
appsLoading
)
ShadowsocksApplication
.
settings
.
edit
.
putString
(
Key
.
proxied
,
proxiedApps
.
mkString
(
"\n"
)).
apply
if
(!
appsLoading
.
get
)
ShadowsocksApplication
.
settings
.
edit
.
putString
(
Key
.
proxied
,
proxiedApps
.
mkString
(
"\n"
)).
apply
}
var
handler
:
Handler
=
null
...
...
src/main/scala/com/github/shadowsocks/AppManagerReceiver.scala
deleted
100644 → 0
View file @
6a0955c0
package
com.github.shadowsocks
import
android.content.
{
Intent
,
Context
,
BroadcastReceiver
}
/**
* @author Mygod
*/
class
AppManagerReceiver
extends
BroadcastReceiver
{
override
def
onReceive
(
context
:
Context
,
intent
:
Intent
)
=
if
(
intent
.
getAction
!=
Intent
.
ACTION_PACKAGE_REMOVED
||
!
intent
.
getBooleanExtra
(
Intent
.
EXTRA_REPLACING
,
false
))
AppManager
.
synchronized
(
AppManager
.
cachedApps
=
null
)
}
src/main/scala/com/github/shadowsocks/BaseService.scala
View file @
2641de43
...
...
@@ -42,7 +42,7 @@ package com.github.shadowsocks
import
java.util.
{
Timer
,
TimerTask
}
import
android.app.Service
import
android.content.
Context
import
android.content.
{
Intent
,
Context
}
import
android.os.
{
Handler
,
RemoteCallbackList
}
import
com.github.shadowsocks.aidl.
{
Config
,
IShadowsocksService
,
IShadowsocksServiceCallback
}
import
com.github.shadowsocks.utils.
{
State
,
TrafficMonitor
,
TrafficMonitorThread
}
...
...
@@ -50,7 +50,6 @@ import com.github.shadowsocks.utils.{State, TrafficMonitor, TrafficMonitorThread
trait
BaseService
extends
Service
{
@volatile
private
var
state
=
State
.
STOPPED
@volatile
private
var
callbackCount
=
0
@volatile
protected
var
config
:
Config
=
null
var
timer
:
Timer
=
null
...
...
@@ -70,32 +69,28 @@ trait BaseService extends Service {
override
def
unregisterCallback
(
cb
:
IShadowsocksServiceCallback
)
{
if
(
cb
!=
null
)
{
callbacks
.
unregister
(
cb
)
callbackCount
-=
1
}
if
(
callbackCount
==
0
&&
timer
!=
null
)
{
if
(
callback
s
.
getRegisteredCallback
Count
==
0
&&
timer
!=
null
)
{
timer
.
cancel
()
timer
=
null
}
if
(
callbackCount
==
0
&&
state
==
State
.
STOPPED
)
{
stopBackgroundService
()
}
}
override
def
registerCallback
(
cb
:
IShadowsocksServiceCallback
)
{
if
(
cb
!=
null
)
{
if
(
callbackCount
==
0
&&
timer
==
null
)
{
callbacks
.
register
(
cb
)
if
(
callbacks
.
getRegisteredCallbackCount
!=
0
&&
timer
==
null
)
{
val
task
=
new
TimerTask
{
def
run
{
TrafficMonitor
.
updateRate
()
updateTrafficRate
(
TrafficMonitor
.
getTxRate
,
TrafficMonitor
.
getRxRate
,
TrafficMonitor
.
getTxTotal
,
TrafficMonitor
.
getRxTotal
)
if
(
TrafficMonitor
.
updateRate
())
updateTrafficRate
()
}
}
timer
=
new
Timer
(
true
)
timer
.
schedule
(
task
,
1000
,
1000
)
}
callbacks
.
register
(
cb
)
callbackCount
+=
1
TrafficMonitor
.
updateRate
()
cb
.
trafficUpdated
(
TrafficMonitor
.
getTxRate
,
TrafficMonitor
.
getRxRate
,
TrafficMonitor
.
getTxTotal
,
TrafficMonitor
.
getRxTotal
)
}
}
...
...
@@ -115,6 +110,7 @@ trait BaseService extends Service {
def
startRunner
(
config
:
Config
)
{
this
.
config
=
config
startService
(
new
Intent
(
getContext
,
getClass
))
TrafficMonitor
.
reset
()
trafficMonitorThread
=
new
TrafficMonitorThread
()
trafficMonitorThread
.
start
()
...
...
@@ -122,39 +118,38 @@ trait BaseService extends Service {
def
stopRunner
()
{
// Make sure update total traffic when stopping the runner
updateTrafficTotal
(
TrafficMonitor
.
getDeltaTx
,
TrafficMonitor
.
getDeltaRx
)
updateTrafficTotal
(
TrafficMonitor
.
txTotal
,
TrafficMonitor
.
rxTotal
)
TrafficMonitor
.
reset
()
if
(
trafficMonitorThread
!=
null
)
{
trafficMonitorThread
.
stopThread
()
trafficMonitorThread
=
null
}
// change the state
changeState
(
State
.
STOPPED
)
// stop the service if nothing has bound to it
stopSelf
()
}
def
updateTrafficTotal
(
tx
:
Long
,
rx
:
Long
)
{
val
handler
=
new
Handler
(
getContext
.
getMainLooper
)
handler
.
post
(()
=>
{
val
config
=
this
.
config
// avoid race conditions without locking
if
(
config
!=
null
)
{
ShadowsocksApplication
.
profileManager
.
getProfile
(
config
.
profileId
)
match
{
case
Some
(
profile
)
=>
profile
.
tx
+=
tx
profile
.
rx
+=
rx
ShadowsocksApplication
.
profileManager
.
updateProfile
(
profile
)
case
None
=>
// Ignore
}
val
config
=
this
.
config
// avoid race conditions without locking
if
(
config
!=
null
)
{
ShadowsocksApplication
.
profileManager
.
getProfile
(
config
.
profileId
)
match
{
case
Some
(
profile
)
=>
profile
.
tx
+=
tx
profile
.
rx
+=
rx
ShadowsocksApplication
.
profileManager
.
updateProfile
(
profile
)
case
None
=>
// Ignore
}
}
)
}
}
def
stopBackgroundService
()
def
getServiceMode
:
Int
def
getTag
:
String
def
getContext
:
Context
def
getCallbackCount
:
Int
=
{
callbackCount
}
def
getState
:
Int
=
{
state
}
...
...
@@ -162,10 +157,14 @@ trait BaseService extends Service {
changeState
(
s
,
null
)
}
def
updateTrafficRate
(
txRate
:
String
,
rxRate
:
String
,
txTotal
:
String
,
rxTotal
:
String
)
{
def
updateTrafficRate
()
{
val
handler
=
new
Handler
(
getContext
.
getMainLooper
)
handler
.
post
(()
=>
{
if
(
callbackCount
>
0
)
{
if
(
callbacks
.
getRegisteredCallbackCount
>
0
)
{
val
txRate
=
TrafficMonitor
.
getTxRate
val
rxRate
=
TrafficMonitor
.
getRxRate
val
txTotal
=
TrafficMonitor
.
getTxTotal
val
rxTotal
=
TrafficMonitor
.
getRxTotal
val
n
=
callbacks
.
beginBroadcast
()
for
(
i
<-
0
until
n
)
{
try
{
...
...
@@ -182,7 +181,7 @@ trait BaseService extends Service {
protected
def
changeState
(
s
:
Int
,
msg
:
String
)
{
val
handler
=
new
Handler
(
getContext
.
getMainLooper
)
handler
.
post
(()
=>
if
(
state
!=
s
)
{
if
(
callbackCount
>
0
)
{
if
(
callback
s
.
getRegisteredCallback
Count
>
0
)
{
val
n
=
callbacks
.
beginBroadcast
()
for
(
i
<-
0
until
n
)
{
try
{
...
...
src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala
View file @
2641de43
...
...
@@ -218,6 +218,15 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe
}
}
override
def
onStart
()
{
super
.
onStart
()
registerCallback
}
override
def
onStop
()
{
super
.
onStop
()
unregisterCallback
}
override
def
onDestroy
{
deattachService
()
super
.
onDestroy
...
...
src/main/scala/com/github/shadowsocks/ServiceBoundContext.scala
View file @
2641de43
...
...
@@ -13,20 +13,12 @@ trait ServiceBoundContext extends Context {
class
ShadowsocksServiceConnection
extends
ServiceConnection
{
override
def
onServiceConnected
(
name
:
ComponentName
,
service
:
IBinder
)
{
bgService
=
IShadowsocksService
.
Stub
.
asInterface
(
service
)
if
(
callback
!=
null
)
try
{
bgService
.
registerCallback
(
callback
)
}
catch
{
case
ignored
:
RemoteException
=>
// Nothing
}
registerCallback
ServiceBoundContext
.
this
.
onServiceConnected
()
}
override
def
onServiceDisconnected
(
name
:
ComponentName
)
{
if
(
callback
!=
null
)
{
try
{
if
(
bgService
!=
null
)
bgService
.
unregisterCallback
(
callback
)
}
catch
{
case
ignored
:
RemoteException
=>
// Nothing
}
unregisterCallback
callback
=
null
}
ServiceBoundContext
.
this
.
onServiceDisconnected
()
...
...
@@ -34,11 +26,25 @@ trait ServiceBoundContext extends Context {
}
}
def
registerCallback
=
if
(
bgService
!=
null
&&
callback
!=
null
&&
!
callbackRegistered
)
try
{
bgService
.
registerCallback
(
callback
)
callbackRegistered
=
true
}
catch
{
case
ignored
:
RemoteException
=>
// Nothing
}
def
unregisterCallback
=
if
(
bgService
!=
null
&&
callback
!=
null
&&
callbackRegistered
)
try
{
bgService
.
unregisterCallback
(
callback
)
callbackRegistered
=
false
}
catch
{
case
ignored
:
RemoteException
=>
// Nothing
}
def
onServiceConnected
()
=
()
def
onServiceDisconnected
()
=
()
private
var
callback
:
IShadowsocksServiceCallback.Stub
=
_
private
var
connection
:
ShadowsocksServiceConnection
=
_
private
var
callbackRegistered
:
Boolean
=
_
// Variables
var
bgService
:
IShadowsocksService
=
_
...
...
@@ -54,19 +60,13 @@ trait ServiceBoundContext extends Context {
connection
=
new
ShadowsocksServiceConnection
()
bindService
(
intent
,
connection
,
Context
.
BIND_AUTO_CREATE
)
startService
(
new
Intent
(
this
,
s
))
}
}
def
deattachService
()
{
if
(
bgService
!=
null
)
{
if
(
callback
!=
null
)
{
try
{
bgService
.
unregisterCallback
(
callback
)
}
catch
{
case
ignored
:
RemoteException
=>
// Nothing
}
unregisterCallback
callback
=
null
}
if
(
connection
!=
null
)
{
...
...
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
View file @
2641de43
...
...
@@ -461,8 +461,13 @@ class Shadowsocks
preferences
.
update
(
profile
)
}
override
def
onStart
()
{
super
.
onStart
()
registerCallback
}
override
def
onStop
()
{
super
.
onStop
()
unregisterCallback
clearDialog
()
}
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksNatService.scala
View file @
2641de43
...
...
@@ -458,8 +458,6 @@ class ShadowsocksNatService extends BaseService {
override
def
stopRunner
()
{
super
.
stopRunner
()
// channge the state
changeState
(
State
.
STOPPING
)
...
...
@@ -476,17 +474,7 @@ class ShadowsocksNatService extends BaseService {
// reset NAT
killProcesses
()
// stop the service if no callback registered
if
(
getCallbackCount
==
0
)
{
stopSelf
()
}
// change the state
changeState
(
State
.
STOPPED
)
}
override
def
stopBackgroundService
()
{
stopSelf
()
super
.
stopRunner
()
}
override
def
getTag
=
TAG
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksNotification.scala
View file @
2641de43
...
...
@@ -2,7 +2,7 @@ package com.github.shadowsocks
import
java.util.Locale
import
android.app.
{
KeyguardManager
,
PendingIntent
}
import
android.app.
{
KeyguardManager
,
NotificationManager
,
PendingIntent
}
import
android.content.
{
BroadcastReceiver
,
Context
,
Intent
,
IntentFilter
}
import
android.os.PowerManager
import
android.support.v4.app.NotificationCompat
...
...
@@ -16,6 +16,7 @@ import com.github.shadowsocks.utils.{Action, State, Utils}
*/
class
ShadowsocksNotification
(
private
val
service
:
BaseService
,
profileName
:
String
,
visible
:
Boolean
=
false
)
{
private
lazy
val
keyGuard
=
service
.
getSystemService
(
Context
.
KEYGUARD_SERVICE
).
asInstanceOf
[
KeyguardManager
]
private
lazy
val
nm
=
service
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
).
asInstanceOf
[
NotificationManager
]
private
lazy
val
callback
=
new
Stub
{
override
def
stateChanged
(
state
:
Int
,
msg
:
String
)
=
()
// ignore
override
def
trafficUpdated
(
txRate
:
String
,
rxRate
:
String
,
txTotal
:
String
,
rxTotal
:
String
)
{
...
...
@@ -27,6 +28,7 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
}
private
var
lockReceiver
:
BroadcastReceiver
=
_
private
var
callbackRegistered
:
Boolean
=
_
private
var
started
:
Boolean
=
_
private
val
builder
=
new
NotificationCompat
.
Builder
(
service
)
.
setWhen
(
0
)
...
...
@@ -73,8 +75,10 @@ class ShadowsocksNotification(private val service: BaseService, profileName: Str
show
()
}
else
if
(
forceShow
)
show
()
def
notification
=
builder
.
build
()
def
show
()
=
service
.
startForeground
(
1
,
notification
)
def
show
()
=
if
(
started
)
nm
.
notify
(
1
,
builder
.
build
)
else
{
service
.
startForeground
(
1
,
builder
.
build
)
started
=
true
}
def
destroy
()
{
if
(
lockReceiver
!=
null
)
{
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksVpnService.scala
View file @
2641de43
...
...
@@ -113,8 +113,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
override
def
stopRunner
()
{
super
.
stopRunner
()
if
(
vpnThread
!=
null
)
{
vpnThread
.
stopThread
()
vpnThread
=
null
...
...
@@ -136,19 +134,13 @@ class ShadowsocksVpnService extends VpnService with BaseService {
conn
=
null
}
// stop the service if no callback registered
if
(
getCallbackCount
==
0
)
{
stopSelf
()
}
// clean up recevier
if
(
closeReceiver
!=
null
)
{
unregisterReceiver
(
closeReceiver
)
closeReceiver
=
null
}
// channge the state
changeState
(
State
.
STOPPED
)
super
.
stopRunner
()
}
def
getVersionName
:
String
=
{
...
...
@@ -458,10 +450,6 @@ class ShadowsocksVpnService extends VpnService with BaseService {
fd
}
override
def
stopBackgroundService
()
{
stopSelf
()
}
override
def
getTag
=
TAG
override
def
getServiceMode
=
Mode
.
VPN
...
...
src/main/scala/com/github/shadowsocks/ShadowsocksVpnThread.scala
View file @
2641de43
...
...
@@ -45,7 +45,12 @@ import java.util.concurrent.Executors
import
android.net.
{
LocalServerSocket
,
LocalSocket
,
LocalSocketAddress
}
import
android.util.Log
object
ShadowsocksVpnThread
{
val
getInt
=
classOf
[
FileDescriptor
].
getDeclaredMethod
(
"getInt$"
)
}
class
ShadowsocksVpnThread
(
vpnService
:
ShadowsocksVpnService
)
extends
Thread
{
import
ShadowsocksVpnThread._
val
TAG
=
"ShadowsocksVpnService"
val
PATH
=
"/data/data/com.github.shadowsocks/protect_path"
...
...
@@ -103,11 +108,8 @@ class ShadowsocksVpnThread(vpnService: ShadowsocksVpnService) extends Thread {
val
fds
=
socket
.
getAncillaryFileDescriptors
if
(
fds
.
nonEmpty
)
{
var
ret
=
false
val
getInt
=
classOf
[
FileDescriptor
].
getDeclaredMethod
(
"getInt$"
)
val
fd
=
getInt
.
invoke
(
fds
(
0
)).
asInstanceOf
[
Int
]
ret
=
vpnService
.
protect
(
fd
)
val
ret
=
vpnService
.
protect
(
fd
)
// Trick to close file decriptor
System
.
jniclose
(
fd
)
...
...
src/main/scala/com/github/shadowsocks/utils/TrafficMonitor.scala
View file @
2641de43
...
...
@@ -5,26 +5,20 @@ import java.text.DecimalFormat
import
com.github.shadowsocks.
{
R
,
ShadowsocksApplication
}
case
class
Traffic
(
tx
:
Long
,
rx
:
Long
,
timestamp
:
Long
)
object
TrafficMonitor
{
var
last
:
Traffic
=
getTraffic
(
0
,
0
)
// Bytes per second
var
txRate
:
Long
=
0
var
rxRate
:
Long
=
0
var
txRate
:
Long
=
_
var
rxRate
:
Long
=
_
// Bytes for the current session
var
txTotal
:
Long
=
0
var
rxTotal
:
Long
=
0
var
txTotal
:
Long
=
_
var
rxTotal
:
Long
=
_
// Bytes for the last query
var
txLast
:
Long
=
0
var
rxLast
:
Long
=
0
def
getTraffic
(
tx
:
Long
,
rx
:
Long
)
:
Traffic
=
{
new
Traffic
(
tx
,
rx
,
System
.
currentTimeMillis
())
}
var
txLast
:
Long
=
_
var
rxLast
:
Long
=
_
var
timestampLast
:
Long
=
_
@volatile
var
dirty
=
true
private
val
units
=
Array
(
"KB"
,
"MB"
,
"GB"
,
"TB"
,
"PB"
,
"EB"
,
"ZB"
,
"YB"
,
"BB"
,
"NB"
,
"DB"
,
"CB"
)
private
val
numberFormat
=
new
DecimalFormat
(
"@@@"
)
...
...
@@ -39,21 +33,42 @@ object TrafficMonitor {
else
numberFormat
.
format
(
n
)
+
' '
+
units
(
i
)
}
def
updateRate
()
{
val
now
=
getTraffic
(
txTotal
,
rxTotal
)
val
delta
=
now
.
timestamp
-
last
.
timestamp
val
deltaTx
=
now
.
tx
-
last
.
tx
val
deltaRx
=
now
.
rx
-
last
.
rx
def
updateRate
()
=
{
val
now
=
System
.
currentTimeMillis
()
val
delta
=
now
-
timestampLast
var
updated
=
false
if
(
delta
!=
0
)
{
txRate
=
deltaTx
*
1000
/
delta
rxRate
=
deltaRx
*
1000
/
delta
if
(
dirty
)
{
txRate
=
(
txTotal
-
txLast
)
*
1000
/
delta
rxRate
=
(
rxTotal
-
rxLast
)
*
1000
/
delta
txLast
=
txTotal
rxLast
=
rxTotal
dirty
=
false
updated
=
true
}
else
{
if
(
txRate
!=
0
)
{
txRate
=
0
updated
=
true
}
if
(
rxRate
!=
0
)
{
rxRate
=
0
updated
=
true
}
}
timestampLast
=
now
}
last
=
now
updated
}
def
update
(
tx
:
Long
,
rx
:
Long
)
{
txTotal
=
tx
rxTotal
=
rx
if
(
txTotal
!=
tx
)
{
txTotal
=
tx
dirty
=
true
}
if
(
rxTotal
!=
rx
)
{
rxTotal
=
rx
dirty
=
true
}
}
def
reset
()
{
...
...
@@ -63,7 +78,7 @@ object TrafficMonitor {
rxTotal
=
0
txLast
=
0
rxLast
=
0
last
=
getTraffic
(
0
,
0
)
dirty
=
true
}
def
getTxTotal
()
:
String
=
{
...
...
@@ -89,17 +104,5 @@ object TrafficMonitor {
def
getRate
()
:
String
=
{
formatTraffic
(
txRate
+
rxRate
)
}
def
getDeltaTx
()
:
Long
=
{
val
last
=
txLast
txLast
=
txTotal
txTotal
-
last
}
def
getDeltaRx
()
:
Long
=
{
val
last
=
rxLast
rxLast
=
rxTotal
rxTotal
-
last
}
}
src/main/scala/com/github/shadowsocks/utils/TrafficMonitorThread.scala
View file @
2641de43
...
...
@@ -40,11 +40,11 @@
package
com.github.shadowsocks.utils
import
java.io.
{
File
,
IOException
}
import
java.nio.
{
ByteBuffer
,
ByteOrder
}
import
java.util.concurrent.Executors
import
android.net.
{
LocalServerSocket
,
LocalSocket
,
LocalSocketAddress
}
import
android.util.Log
import
com.github.shadowsocks.BaseService
class
TrafficMonitorThread
()
extends
Thread
{
...
...
@@ -99,16 +99,10 @@ class TrafficMonitorThread() extends Thread {
val
input
=
socket
.
getInputStream
val
output
=
socket
.
getOutputStream
val
buffer
=
new
Array
[
Byte
](
256
)
val
size
=
input
.
read
(
buffer
)
val
array
=
new
Array
[
Byte
](
size
)
Array
.
copy
(
buffer
,
0
,
array
,
0
,
size
)
val
stat
=
new
String
(
array
,
"UTF-8"
).
split
(
"\\|"
)
if
(
stat
.
length
==
2
)
{
TrafficMonitor
.
update
(
stat
(
0
).
toLong
,
stat
(
1
).
toLong
)
}
val
buffer
=
new
Array
[
Byte
](
16
)
if
(
input
.
read
(
buffer
)
!=
16
)
throw
new
IOException
(
"Unexpected traffic stat length"
)
val
stat
=
ByteBuffer
.
wrap
(
buffer
).
order
(
ByteOrder
.
LITTLE_ENDIAN
)
TrafficMonitor
.
update
(
stat
.
getLong
(
0
),
stat
.
getLong
(
8
))
output
.
write
(
0
)
...
...
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