diff --git a/src/main/scala/com/github/shadowsocks/database/DBHelper.scala b/src/main/scala/com/github/shadowsocks/database/DBHelper.scala index d2ed5a4c..627d6b48 100644 --- a/src/main/scala/com/github/shadowsocks/database/DBHelper.scala +++ b/src/main/scala/com/github/shadowsocks/database/DBHelper.scala @@ -51,7 +51,7 @@ object DBHelper { } class DBHelper(val context: Context) - extends OrmLiteSqliteOpenHelper(context, DBHelper.PROFILE, null, 12) { + extends OrmLiteSqliteOpenHelper(context, DBHelper.PROFILE, null, 13) { lazy val profileDao: Dao[Profile, Int] = getDao(classOf[Profile]) @@ -89,6 +89,11 @@ class DBHelper(val context: Context) " 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;") + } } } } diff --git a/src/main/scala/com/github/shadowsocks/database/Profile.scala b/src/main/scala/com/github/shadowsocks/database/Profile.scala index 8be48264..66744357 100644 --- a/src/main/scala/com/github/shadowsocks/database/Profile.scala +++ b/src/main/scala/com/github/shadowsocks/database/Profile.scala @@ -83,4 +83,13 @@ class Profile { @DatabaseField(dataType = DataType.LONG_STRING) var individual: String = "" + + @DatabaseField + var tx: Long = 0 + + @DatabaseField + var rx: Long = 0 + + @DatabaseField + val date: java.util.Date = new java.util.Date() } diff --git a/src/main/scala/com/github/shadowsocks/utils/TrafficMonitor.scala b/src/main/scala/com/github/shadowsocks/utils/TrafficMonitor.scala new file mode 100644 index 00000000..eb715113 --- /dev/null +++ b/src/main/scala/com/github/shadowsocks/utils/TrafficMonitor.scala @@ -0,0 +1,83 @@ +package com.github.shadowsocks.utils + +import android.net.TrafficStats +import android.os.Process +import java.lang.{String, System} +import java.util.Locale + +case class Traffic(tx: Long, rx: Long, timestamp: Long) + +object TrafficMonitor { + val uid = Process.myUid + var last: Traffic = getTraffic + + // Kilo bytes per second + var txRate: Long = 0 + var rxRate: Long = 0 + + // Kilo bytes for the current session + var txTotal: Long = 0 + var rxTotal: Long = 0 + + def getTraffic(): Traffic = { + new Traffic(TrafficStats.getUidTxBytes(uid), + TrafficStats.getUidRxBytes(uid), 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" + } + } + + def updateTraffic() { + val now = getTraffic + txRate = ((now.tx - last.tx) / 1024 / (now.timestamp - last.timestamp)) + rxRate = ((now.rx - last.rx) / 1024 / (now.timestamp - last.timestamp)) + txTotal += (now.tx - last.tx) / 1024 + rxTotal += (now.rx - last.rx) / 1024 + last = now + } + + def resetTraffic() { + txRate = 0 + rxRate = 0 + txTotal = 0 + rxTotal = 0 + last = getTraffic + } + + def getTxTotal(): String = { + formatTraffic(txTotal) + } + + def getRxTotal(): String = { + formatTraffic(rxTotal) + } + + def getTotal(): String = { + formatTraffic(txTotal + rxTotal) + } + + def getTxRate(): String = { + formatTraffic(txRate) + "/s" + } + + def getTxRate(): String = { + formatTraffic(rxRate) + "/s" + } + + def getRate(): String = { + formatTraffic(txRate + rxRate) + "/s" + } +} + +class TrafficMonitor ()