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
f345c7d7
Commit
f345c7d7
authored
Nov 19, 2015
by
Max Lv
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #433 from Mygod/master
Fix #432
parents
5ac7f2b9
9adf1171
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
119 additions
and
114 deletions
+119
-114
build.sbt
build.sbt
+4
-4
src/main/res/values-v21/styles.xml
src/main/res/values-v21/styles.xml
+2
-34
src/main/res/values-zh/strings.xml
src/main/res/values-zh/strings.xml
+4
-0
src/main/res/values/strings.xml
src/main/res/values/strings.xml
+6
-1
src/main/res/values/styles.xml
src/main/res/values/styles.xml
+7
-3
src/main/scala/com/github/shadowsocks/ParserActivity.scala
src/main/scala/com/github/shadowsocks/ParserActivity.scala
+1
-1
src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala
...scala/com/github/shadowsocks/ProfileManagerActivity.scala
+19
-4
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
+7
-10
src/main/scala/com/github/shadowsocks/database/DBHelper.scala
...main/scala/com/github/shadowsocks/database/DBHelper.scala
+30
-29
src/main/scala/com/github/shadowsocks/database/ProfileManager.scala
...cala/com/github/shadowsocks/database/ProfileManager.scala
+17
-9
src/main/scala/com/github/shadowsocks/utils/TrafficMonitor.scala
...n/scala/com/github/shadowsocks/utils/TrafficMonitor.scala
+22
-19
No files found.
build.sbt
View file @
f345c7d7
...
...
@@ -32,10 +32,10 @@ libraryDependencies ++= Seq(
"commons-net"
%
"commons-net"
%
"3.3"
,
"com.google.zxing"
%
"android-integration"
%
"3.2.1"
,
"net.glxn.qrgen"
%
"android"
%
"2.0"
,
"com.google.android.gms"
%
"play-services-base"
%
"8.
1
.0"
,
"com.google.android.gms"
%
"play-services-ads"
%
"8.
1
.0"
,
"com.google.android.gms"
%
"play-services-analytics"
%
"8.
1
.0"
,
"com.android.support"
%
"design"
%
"23.1.
0
"
,
"com.google.android.gms"
%
"play-services-base"
%
"8.
3
.0"
,
"com.google.android.gms"
%
"play-services-ads"
%
"8.
3
.0"
,
"com.google.android.gms"
%
"play-services-analytics"
%
"8.
3
.0"
,
"com.android.support"
%
"design"
%
"23.1.
1
"
,
"com.github.jorgecastilloprz"
%
"fabprogresscircle"
%
"1.01"
,
"com.j256.ormlite"
%
"ormlite-core"
%
"4.48"
,
"com.j256.ormlite"
%
"ormlite-android"
%
"4.48"
...
...
src/main/res/values-v21/styles.xml
View file @
f345c7d7
...
...
@@ -2,39 +2,7 @@
<resources>
<style
name=
"Toolbar.Logo"
parent=
"TextAppearance.Widget.AppCompat.Toolbar.Title"
>
<item
name=
"android:textSize"
>
24sp
</item>
</style>
<style
name=
"Theme.Material"
parent=
"Theme.AppCompat.Light.NoActionBar"
>
<item
name=
"android:alertDialogTheme"
>
@style/Theme.Material.Dialog.Alert
</item>
<item
name=
"android:dialogTheme"
>
@style/Theme.Material.Dialog
</item>
<item
name=
"android:navigationBarColor"
>
@color/material_accent_700
</item>
<item
name=
"colorAccent"
>
@color/material_accent_500
</item>
<item
name=
"colorButtonNormal"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimary"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimaryDark"
>
@color/material_accent_700
</item>
</style>
<style
name=
"Theme.Material.Dialog"
parent=
"Theme.AppCompat.Light.Dialog"
>
<item
name=
"colorAccent"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimary"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimaryDark"
>
@color/material_accent_700
</item>
</style>
<style
name=
"Theme.Material.Dialog.Alert"
parent=
"Theme.AppCompat.Light.Dialog.Alert"
>
<item
name=
"colorAccent"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimary"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimaryDark"
>
@color/material_accent_700
</item>
</style>
<style
name=
"PopupTheme"
parent=
"Theme.Material.Dialog"
>
<item
name=
"android:windowNoTitle"
>
true
</item>
<item
name=
"android:windowFrame"
>
@null
</item>
<item
name=
"android:windowIsFloating"
>
false
</item>
<item
name=
"android:windowContentOverlay"
>
@null
</item>
<item
name=
"android:windowAnimationStyle"
>
@android:style/Animation.Dialog
</item>
<item
name=
"android:windowSoftInputMode"
>
stateAlwaysHidden
</item>
<item
name=
"android:windowActionModeOverlay"
>
true
</item>
<item
name=
"android:colorBackgroundCacheHint"
>
@null
</item>
<item
name=
"android:windowIsTranslucent"
>
true
</item>
</style>
<style
name=
"Theme.Material.Dialog"
parent=
"Theme.Material.DialogBase"
/>
<style
name=
"Theme.Material.Dialog.Alert"
parent=
"Theme.Material.Dialog.AlertBase"
/>
</resources>
src/main/res/values-zh/strings.xml
View file @
f345c7d7
...
...
@@ -74,6 +74,10 @@
<string
name=
"stat"
>
网络流量
</string>
<string
name=
"stat_summary"
>
发送:\t%1$s\t|\t接收:\t%2$s\n上传:\t%3$s\t|\t下载:\t%4$s
</string>
<string
name=
"stat_profiles"
>
\n发送:\t%1$s\t|\t接收:\t%2$s
</string>
<plurals
name=
"bytes"
>
<item
quantity=
"other"
>
字节
</item>
</plurals>
<!-- profile -->
<string
name=
"add_profile_dialog"
>
为影梭添加此配置文件?
</string>
...
...
src/main/res/values/strings.xml
View file @
f345c7d7
...
...
@@ -13,7 +13,12 @@
<string
name=
"nat_summary"
>
Use NAT mode instead of VPN mode
</string>
<string
name=
"nat_summary_no_root"
>
NAT mode is disabled without root
</string>
<string
name=
"stat"
>
Network Traffic
</string>
<string
name=
"stat_summary"
>
Send:\t%1$s\t|\tReceive:\t%2$s\nUpload:\t%3$s\t|\tDownload:\t%4$s
</string>
<string
name=
"stat_summary"
>
Sent: \t%1$s\t|\tReceived: \t%2$s\nUpload: \t%3$s\t|\tDownload: \t%4$s
</string>
<string
name=
"stat_profiles"
>
\nSent: \t%1$s\t|\tReceived: \t%2$s
</string>
<plurals
name=
"bytes"
>
<item
quantity=
"one"
>
Byte
</item>
<item
quantity=
"other"
>
Bytes
</item>
</plurals>
<!-- proxy category -->
<string
name=
"proxy_cat"
>
Server Settings
</string>
...
...
src/main/res/values/styles.xml
View file @
f345c7d7
...
...
@@ -14,16 +14,20 @@
<item
name=
"colorPrimary"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimaryDark"
>
@color/material_accent_700
</item>
</style>
<style
name=
"Theme.Material.Dialog"
parent=
"Theme.AppCompat.Light.Dialog"
>
<style
name=
"Theme.Material.Dialog
Base
"
parent=
"Theme.AppCompat.Light.Dialog"
>
<item
name=
"colorAccent"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimary"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimaryDark"
>
@color/material_accent_700
</item>
<item
name=
"android:windowBackground"
>
@android:color/transparent
</item>
</style>
<style
name=
"Theme.Material.Dialog.Alert"
parent=
"Theme.AppCompat.Light.Dialog.Alert"
>
<style
name=
"Theme.Material.Dialog.Alert
Base
"
parent=
"Theme.AppCompat.Light.Dialog.Alert"
>
<item
name=
"colorAccent"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimary"
>
@color/material_accent_500
</item>
<item
name=
"colorPrimaryDark"
>
@color/material_accent_700
</item>
</style>
<style
name=
"Theme.Material.Dialog"
parent=
"Theme.Material.DialogBase"
>
<item
name=
"android:windowBackground"
>
@android:color/transparent
</item>
</style>
<style
name=
"Theme.Material.Dialog.Alert"
parent=
"Theme.Material.Dialog.AlertBase"
>
<item
name=
"android:windowBackground"
>
@android:color/transparent
</item>
</style>
...
...
src/main/scala/com/github/shadowsocks/ParserActivity.scala
View file @
f345c7d7
...
...
@@ -61,7 +61,7 @@ class ParserActivity extends Activity {
.
setTitle
(
R
.
string
.
add_profile_dialog
)
.
setCancelable
(
false
)
.
setPositiveButton
(
android
.
R
.
string
.
yes
,
((
dialog
:
DialogInterface
,
id
:
Int
)
=>
{
ShadowsocksApplication
.
profileManager
.
create
OrUpdate
Profile
(
profile
.
get
)
ShadowsocksApplication
.
profileManager
.
createProfile
(
profile
.
get
)
dialog
.
dismiss
()
})
:
DialogInterface.OnClickListener
)
.
setNegativeButton
(
android
.
R
.
string
.
no
,
((
dialog
:
DialogInterface
,
id
:
Int
)
=>
{
...
...
src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala
View file @
f345c7d7
...
...
@@ -10,11 +10,13 @@ import android.support.v7.widget.Toolbar.OnMenuItemClickListener
import
android.support.v7.widget.helper.ItemTouchHelper
import
android.support.v7.widget.helper.ItemTouchHelper.SimpleCallback
import
android.support.v7.widget.
{
DefaultItemAnimator
,
LinearLayoutManager
,
RecyclerView
,
Toolbar
}
import
android.text.style.TextAppearanceSpan
import
android.text.
{
Spanned
,
SpannableStringBuilder
}
import
android.view.View.
{
OnAttachStateChangeListener
,
OnClickListener
}
import
android.view.
{
LayoutInflater
,
MenuItem
,
View
,
ViewGroup
}
import
android.widget.
{
LinearLayout
,
ImageView
,
CheckedTextView
,
Toast
}
import
com.github.shadowsocks.database.Profile
import
com.github.shadowsocks.utils.
{
Parser
,
Utils
}
import
com.github.shadowsocks.utils.
{
TrafficMonitor
,
Parser
,
Utils
}
import
com.google.zxing.integration.android.IntentIntegrator
import
net.glxn.qrgen.android.QRCode
...
...
@@ -54,10 +56,23 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe
})
}
def
updateText
()
{
val
builder
=
new
SpannableStringBuilder
builder
.
append
(
item
.
name
)
if
(
item
.
tx
!=
0
||
item
.
rx
!=
0
)
{
val
start
=
builder
.
length
builder
.
append
(
getString
(
R
.
string
.
stat_profiles
,
TrafficMonitor
.
formatTraffic
(
item
.
tx
),
TrafficMonitor
.
formatTraffic
(
item
.
rx
)))
builder
.
setSpan
(
new
TextAppearanceSpan
(
ProfileManagerActivity
.
this
,
android
.
R
.
style
.
TextAppearance_Small
),
start
+
1
,
builder
.
length
,
Spanned
.
SPAN_EXCLUSIVE_EXCLUSIVE
)
}
text
.
setText
(
builder
)
}
def
bind
(
item
:
Profile
)
{
text
.
setText
(
item
.
name
)
text
.
setChecked
(
item
.
id
==
ShadowsocksApplication
.
profileId
)
this
.
item
=
item
updateText
()
text
.
setChecked
(
item
.
id
==
ShadowsocksApplication
.
profileId
)
}
def
onClick
(
v
:
View
)
=
{
...
...
@@ -153,7 +168,7 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe
override
def
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
data
:
Intent
)
{
val
scanResult
=
IntentIntegrator
.
parseActivityResult
(
requestCode
,
resultCode
,
data
)
if
(
scanResult
!=
null
)
Parser
.
parse
(
scanResult
.
getContents
)
match
{
case
Some
(
profile
)
=>
ShadowsocksApplication
.
profileManager
.
create
OrUpdate
Profile
(
profile
)
case
Some
(
profile
)
=>
ShadowsocksApplication
.
profileManager
.
createProfile
(
profile
)
case
_
=>
// ignore
}
}
...
...
src/main/scala/com/github/shadowsocks/Shadowsocks.scala
View file @
f345c7d7
...
...
@@ -138,7 +138,6 @@ object Shadowsocks {
case
Key
.
isUdpDns
=>
updateSwitchPreference
(
pref
,
profile
.
udpdns
)
case
Key
.
isAuth
=>
updateSwitchPreference
(
pref
,
profile
.
auth
)
case
Key
.
isIpv6
=>
updateSwitchPreference
(
pref
,
profile
.
ipv6
)
case
_
=>
}
}
}
...
...
@@ -476,17 +475,15 @@ class Shadowsocks
}
else
{
TrafficMonitor
.
reset
()
}
val
pm
=
getSystemService
(
Context
.
POWER_SERVICE
).
asInstanceOf
[
PowerManager
]
if
(
pm
.
isScreenOn
)
{
val
trafficStat
=
getString
(
R
.
string
.
stat_summary
).
formatLocal
(
Locale
.
ENGLISH
,
TrafficMonitor
.
getTxRate
,
TrafficMonitor
.
getRxRate
,
TrafficMonitor
.
getTxTotal
,
TrafficMonitor
.
getRxTotal
)
handler
.
post
(()
=>
{
preferences
.
findPreference
(
Key
.
stat
).
setSummary
(
trafficStat
)
})
}
val
trafficStat
=
getString
(
R
.
string
.
stat_summary
).
formatLocal
(
Locale
.
ENGLISH
,
TrafficMonitor
.
getTxRate
,
TrafficMonitor
.
getRxRate
,
TrafficMonitor
.
getTxTotal
,
TrafficMonitor
.
getRxTotal
)
handler
.
post
(()
=>
{
preferences
.
findPreference
(
Key
.
stat
).
setSummary
(
trafficStat
)
})
}
}
task
.
run
()
timer
=
new
Timer
(
true
)
timer
.
schedule
(
task
,
TIMER_INTERVAL
*
1000
,
TIMER_INTERVAL
*
1000
)
}
...
...
src/main/scala/com/github/shadowsocks/database/DBHelper.scala
View file @
f345c7d7
...
...
@@ -65,35 +65,36 @@ class DBHelper(val context: Context)
if
(
oldVersion
<
7
)
{
profileDao
.
executeRawNoArgs
(
"DROP TABLE IF EXISTS 'profile';"
)
onCreate
(
database
,
connectionSource
)
}
else
{
if
(
oldVersion
<
8
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN udpdns SMALLINT;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN route VARCHAR;"
)
}
if
(
oldVersion
<
9
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN route VARCHAR;"
)
}
if
(
oldVersion
<
10
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN auth SMALLINT;"
)
}
if
(
oldVersion
<
11
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN ipv6 SMALLINT;"
)
}
if
(
oldVersion
<
12
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` RENAME TO `tmp`;"
)
onCreate
(
database
,
connectionSource
)
profileDao
.
executeRawNoArgs
(
"INSERT INTO `profile`(id, name, host, localPort, remotePort, password, method, route, proxyApps, bypass,"
+
" udpdns, auth, ipv6, individual) "
+
"SELECT id, name, host, localPort, remotePort, password, method, route, 1 - global, bypass, udpdns, auth,"
+
" ipv6, individual FROM `tmp`;"
)
profileDao
.
executeRawNoArgs
(
"DROP TABLE `tmp`;"
)
}
if
(
oldVersion
<
13
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN tx LONG;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN rx LONG;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN date DATE;"
)
}
return
}
if
(
oldVersion
<
8
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN udpdns SMALLINT;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN route VARCHAR;"
)
}
if
(
oldVersion
<
9
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN route VARCHAR;"
)
}
if
(
oldVersion
<
10
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN auth SMALLINT;"
)
}
if
(
oldVersion
<
11
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN ipv6 SMALLINT;"
)
}
if
(
oldVersion
<
12
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` RENAME TO `tmp`;"
)
onCreate
(
database
,
connectionSource
)
profileDao
.
executeRawNoArgs
(
"INSERT INTO `profile`(id, name, host, localPort, remotePort, password, method, route, proxyApps, bypass,"
+
" udpdns, auth, ipv6, individual) "
+
"SELECT id, name, host, localPort, remotePort, password, method, route, 1 - global, bypass, udpdns, auth,"
+
" ipv6, individual FROM `tmp`;"
)
profileDao
.
executeRawNoArgs
(
"DROP TABLE `tmp`;"
)
return
}
if
(
oldVersion
<
13
)
{
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN tx LONG;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN rx LONG;"
)
profileDao
.
executeRawNoArgs
(
"ALTER TABLE `profile` ADD COLUMN date DATE;"
)
}
}
}
...
...
src/main/scala/com/github/shadowsocks/database/ProfileManager.scala
View file @
f345c7d7
...
...
@@ -49,15 +49,27 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
var
profileAddedListener
:
Profile
=>
Any
=
_
def
setProfileAddedListener
(
listener
:
Profile
=>
Any
)
=
this
.
profileAddedListener
=
listener
def
create
OrUpdateProfile
(
profile
:
Profile
)
:
Boolean
=
{
def
create
Profile
(
p
:
Profile
=
null
)
:
Profile
=
{
try
{
val
profile
=
if
(
p
==
null
)
new
Profile
else
p
profile
.
id
=
0
ShadowsocksApplication
.
currentProfile
match
{
case
Some
(
oldProfile
)
=>
// Copy Feature Settings from old profile
profile
.
route
=
oldProfile
.
route
profile
.
ipv6
=
oldProfile
.
ipv6
profile
.
proxyApps
=
oldProfile
.
proxyApps
profile
.
individual
=
oldProfile
.
individual
profile
.
udpdns
=
oldProfile
.
udpdns
case
_
=>
}
dbHelper
.
profileDao
.
createOrUpdate
(
profile
)
if
(
profileAddedListener
!=
null
)
profileAddedListener
(
profile
)
tru
e
profil
e
}
catch
{
case
ex
:
Exception
=>
Log
.
e
(
Shadowsocks
.
TAG
,
"addProfile"
,
ex
)
false
p
}
}
...
...
@@ -114,11 +126,7 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
def
load
(
id
:
Int
)
:
Profile
=
{
val
profile
=
getProfile
(
id
)
getOrElse
{
val
p
=
new
Profile
()
createOrUpdateProfile
(
p
)
p
}
val
profile
=
getProfile
(
id
)
getOrElse
createProfile
()
val
edit
=
settings
.
edit
()
edit
.
putBoolean
(
Key
.
isProxyApps
,
profile
.
proxyApps
)
...
...
@@ -175,7 +183,7 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
remotePort
=
443
password
=
"u1rRWTssNv0p"
}
create
OrUpdate
Profile
(
profile
)
createProfile
(
profile
)
profile
}
}
src/main/scala/com/github/shadowsocks/utils/TrafficMonitor.scala
View file @
f345c7d7
package
com.github.shadowsocks.utils
import
java.lang.
{
Math
,
System
}
import
java.text.DecimalFormat
import
android.net.TrafficStats
import
android.os.Process
import
java.lang.
{
String
,
System
,
Math
}
import
java.util.Locale
import
com.github.shadowsocks.
{
R
,
ShadowsocksApplication
}
case
class
Traffic
(
tx
:
Long
,
rx
:
Long
,
timestamp
:
Long
)
...
...
@@ -19,31 +21,33 @@ object TrafficMonitor {
var
txTotal
:
Long
=
0
var
rxTotal
:
Long
=
0
def
getTraffic
()
:
Traffic
=
{
def
getTraffic
:
Traffic
=
{
new
Traffic
(
Math
.
max
(
TrafficStats
.
getTotalTxBytes
-
TrafficStats
.
getUidTxBytes
(
uid
),
0
),
Math
.
max
(
TrafficStats
.
getTotalRxBytes
-
TrafficStats
.
getUidRxBytes
(
uid
),
0
),
System
.
currentTimeMillis
())
}
def
formatTraffic
(
n
:
Long
)
:
String
=
{
if
(
n
<=
1024
)
{
"%d KB"
.
formatLocal
(
Locale
.
ENGLISH
,
n
)
}
else
if
(
n
>
1024
)
{
"%d MB"
.
formatLocal
(
Locale
.
ENGLISH
,
n
/
1024
)
}
else
if
(
n
>
1024
*
1024
)
{
"%d GB"
.
formatLocal
(
Locale
.
ENGLISH
,
n
/
1024
/
1024
)
}
else
if
(
n
>
1024
*
1024
*
1024
)
{
"%d TB"
.
formatLocal
(
Locale
.
ENGLISH
,
n
/
1024
/
1024
/
1024
)
}
else
{
">1024 TB"
private
val
units
=
Array
(
"KB"
,
"MB"
,
"GB"
,
"TB"
,
"PB"
,
"EB"
,
"ZB"
,
"YB"
,
"BB"
,
"NB"
,
"DB"
,
"CB"
)
private
val
numberFormat
=
new
DecimalFormat
(
"0.00"
)
def
formatTraffic
(
size
:
Long
)
:
String
=
{
var
n
:
Double
=
size
var
i
=
-
1
while
(
n
>=
1024
)
{
n
/=
1024
i
=
i
+
1
}
if
(
i
<
0
)
size
+
" "
+
ShadowsocksApplication
.
instance
.
getResources
.
getQuantityString
(
R
.
plurals
.
bytes
,
size
.
toInt
)
else
numberFormat
.
format
(
n
)
+
' '
+
units
(
i
)
}
def
update
()
{
val
now
=
getTraffic
txRate
=
(
now
.
tx
-
last
.
tx
)
/
(
now
.
timestamp
-
last
.
timestamp
)
rxRate
=
(
now
.
rx
-
last
.
rx
)
/
(
now
.
timestamp
-
last
.
timestamp
)
txTotal
+=
(
now
.
tx
-
last
.
tx
)
/
1024
rxTotal
+=
(
now
.
rx
-
last
.
rx
)
/
1024
val
delta
=
now
.
timestamp
-
last
.
timestamp
if
(
delta
!=
0
)
{
txRate
=
(
now
.
tx
-
last
.
tx
)
/
delta
rxRate
=
(
now
.
rx
-
last
.
rx
)
/
delta
}
txTotal
+=
now
.
tx
-
last
.
tx
rxTotal
+=
now
.
rx
-
last
.
rx
last
=
now
}
...
...
@@ -80,4 +84,3 @@ object TrafficMonitor {
}
}
class
TrafficMonitor
()
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