Skip to content

Commit

Permalink
Add speed test
Browse files Browse the repository at this point in the history
  • Loading branch information
YouROK committed Nov 14, 2023
1 parent 4aaf363 commit 44673df
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 0 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ dependencies {
implementation 'com.google.firebase:firebase-analytics:19.0.2'
//noinspection GradleDependency firebase-crashlytics:18.2.5 is last api17 compatible
implementation 'com.google.firebase:firebase-crashlytics:18.2.5'
// speed test
implementation 'com.github.anastr:speedviewlib:1.6.0'
}

repositories {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import ru.yourok.torrserve.ui.fragments.main.servfinder.ServerFinderFragment
import ru.yourok.torrserve.ui.fragments.main.servsets.ServerSettingsFragment
import ru.yourok.torrserve.ui.fragments.main.update.apk.ApkUpdateFragment
import ru.yourok.torrserve.ui.fragments.main.update.apk.UpdaterApk
import ru.yourok.torrserve.ui.fragments.speedtest.SpeedTest
import ru.yourok.torrserve.utils.Accessibility


Expand Down Expand Up @@ -90,6 +91,13 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
}

findPreference<Preference>("speedtest")?.apply {
setOnPreferenceClickListener {
SpeedTest().show(requireActivity(), R.id.container, true)
true
}
}

findPreference<Preference>("server_settings")?.setOnPreferenceClickListener {
ServerSettingsFragment().show(requireActivity(), R.id.container, true)
true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package ru.yourok.torrserve.ui.fragments.speedtest

import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import com.github.anastr.speedviewlib.TubeSpeedometer
import com.github.anastr.speedviewlib.components.Section
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.yourok.torrserve.R
import ru.yourok.torrserve.ui.fragments.TSFragment
import ru.yourok.torrserve.utils.Http
import ru.yourok.torrserve.utils.Net


class SpeedTest : TSFragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val vi = inflater.inflate(R.layout.speedtest_fragment, container, false)

val speedometer = vi.findViewById<TubeSpeedometer>(R.id.tubeSpeedometer)

speedometer.unit = "MBit/Sec"
speedometer.minSpeed = 0f
speedometer.maxSpeed = 500f
speedometer.withTremble = false
speedometer.clearSections()
speedometer.addSections(
Section(0f, getPrcSpeed(50f, speedometer.maxSpeed), Color.RED),
Section(getPrcSpeed(50f, speedometer.maxSpeed), getPrcSpeed(70f, speedometer.maxSpeed), Color.YELLOW),
Section(getPrcSpeed(70f, speedometer.maxSpeed), getPrcSpeed(100f, speedometer.maxSpeed), Color.GREEN),
Section(getPrcSpeed(100f, speedometer.maxSpeed), 1f, Color.BLUE)
)
// lifecycleScope.launch(Dispatchers.IO) {
// setSpeedometer(501f)
// }

vi.findViewById<Button>(R.id.btnTestSpeed)?.setOnClickListener {
it.isEnabled = false
speedTest()
}

return vi
}

private fun speedTest() {
lifecycleScope.launch(Dispatchers.IO) {
showProgress()
val link = Net.getHostUrl("/download/1024")
val http = Http(Uri.parse(link))
try {
http.connect()
} catch (e: Exception) {
setStatus(e.message ?: "Error connect to server")
hideProgress()
return@launch
}

val stream = http.getInputStream()
stream ?: let {
setStatus("Error connect to server")
hideProgress()
return@launch
}

val b = ByteArray(1024 * 1024)
val allSize = http.getSize()
var readed = 0L
try {
while (readed < allSize) {
val sz = http.read(b)
readed += sz
calcSpeed(readed)
showProgress((readed * 100 / allSize).toInt())
if (!this@SpeedTest.isVisible)
break
}
} catch (e: Exception) {
setStatus(e.message ?: "Error read from server")
}

hideProgress()

withContext(Dispatchers.Main) {
view?.findViewById<TubeSpeedometer>(R.id.tubeSpeedometer)?.speedTo(0.0f)
view?.findViewById<Button>(R.id.btnTestSpeed)?.isEnabled = true
}
}
}

private suspend fun setStatus(st: String) {
withContext(Dispatchers.Main) {
val status = view?.findViewById<TextView>(R.id.tvSPStatus) ?: return@withContext
status.text = st
}
}

private var lastCheck = System.currentTimeMillis()
private var lastReaded = 0L

private suspend fun calcSpeed(readed: Long) {
val time = System.currentTimeMillis() - lastCheck
if (time > 1000) {
val dReaded = readed - lastReaded

val speed = dReaded.toFloat() / time.toFloat() * 0.008f // MBit / sec
setSpeed(speed)
setSpeedometer(speed)

lastCheck = System.currentTimeMillis()
lastReaded = readed
}
}

private var maxSpeed = 0f

private suspend fun setSpeed(speed: Float) {
if (speed > maxSpeed)
maxSpeed = speed
withContext(Dispatchers.Main) {
val ms = String.format("%.1f MBit/Sec", maxSpeed)
view?.findViewById<TextView>(R.id.tvSPStatus)?.text = ms
view?.findViewById<TubeSpeedometer>(R.id.tubeSpeedometer)?.speedTo(speed)
}
}


private suspend fun setSpeedometer(speed: Float) {
withContext(Dispatchers.Main) {
val speedometer = view?.findViewById<TubeSpeedometer>(R.id.tubeSpeedometer) ?: return@withContext
if (speed > speedometer.maxSpeed) {
if (speed < 100f) {
// speedometer.maxSpeed = 100f
setMaxSpeed(speedometer.maxSpeed, 100f) {
speedometer.clearSections()
speedometer.addSections(
Section(0f, getPrcSpeed(50f, speedometer.maxSpeed), Color.RED),
Section(getPrcSpeed(50f, speedometer.maxSpeed), getPrcSpeed(70f, speedometer.maxSpeed), Color.YELLOW),
Section(getPrcSpeed(70f, speedometer.maxSpeed), 1f, Color.GREEN)
)
}
}
if (speed > 100f && speed < 300f) {
// speedometer.maxSpeed = 300f
setMaxSpeed(speedometer.maxSpeed, 300f) {
speedometer.clearSections()
speedometer.addSections(
Section(0f, getPrcSpeed(50f, speedometer.maxSpeed), Color.RED),
Section(getPrcSpeed(50f, speedometer.maxSpeed), getPrcSpeed(70f, speedometer.maxSpeed), Color.YELLOW),
Section(getPrcSpeed(70f, speedometer.maxSpeed), getPrcSpeed(100f, speedometer.maxSpeed), Color.GREEN),
Section(getPrcSpeed(100f, speedometer.maxSpeed), 1f, Color.BLUE)
)
}
}
if (speed > 300f && speed < 500f) {
speedometer.maxSpeed = 500f
setMaxSpeed(speedometer.maxSpeed, 500f) {
speedometer.clearSections()
speedometer.addSections(
Section(0f, getPrcSpeed(50f, speedometer.maxSpeed), Color.RED),
Section(getPrcSpeed(50f, speedometer.maxSpeed), getPrcSpeed(70f, speedometer.maxSpeed), Color.YELLOW),
Section(getPrcSpeed(70f, speedometer.maxSpeed), getPrcSpeed(100f, speedometer.maxSpeed), Color.GREEN),
Section(getPrcSpeed(100f, speedometer.maxSpeed), 1f, Color.BLUE)
)
}
}
if (speed > 500f && speed < 1000f) {
// speedometer.maxSpeed = 1000f
setMaxSpeed(speedometer.maxSpeed, 1000f) {
speedometer.clearSections()
speedometer.addSections(
Section(0f, getPrcSpeed(50f, speedometer.maxSpeed), Color.RED),
Section(getPrcSpeed(50f, speedometer.maxSpeed), getPrcSpeed(70f, speedometer.maxSpeed), Color.YELLOW),
Section(getPrcSpeed(70f, speedometer.maxSpeed), getPrcSpeed(100f, speedometer.maxSpeed), Color.GREEN),
Section(getPrcSpeed(100f, speedometer.maxSpeed), 1f, Color.BLUE)
)
}
}
if (speed > 1000f) {
setMaxSpeed(speedometer.maxSpeed, 5000f) {
speedometer.clearSections()
speedometer.addSections(
Section(0f, getPrcSpeed(50f, speedometer.maxSpeed), Color.RED),
Section(getPrcSpeed(50f, speedometer.maxSpeed), getPrcSpeed(70f, speedometer.maxSpeed), Color.YELLOW),
Section(getPrcSpeed(70f, speedometer.maxSpeed), getPrcSpeed(100f, speedometer.maxSpeed), Color.GREEN),
Section(getPrcSpeed(100f, speedometer.maxSpeed), 1f, Color.BLUE)
)
}
}
}
}
}

private suspend fun setMaxSpeed(oldSpeed: Float, maxSpeed: Float, onEnd: () -> Unit) {
lifecycleScope.launch(Dispatchers.IO) {
for (i in oldSpeed.toInt()..maxSpeed.toInt() step 10) {
withContext(Dispatchers.Main) {
view?.findViewById<TubeSpeedometer>(R.id.tubeSpeedometer)?.maxSpeed = i.toFloat()
}
delay(50)
}
withContext(Dispatchers.Main) {
view?.findViewById<TubeSpeedometer>(R.id.tubeSpeedometer)?.maxSpeed = maxSpeed
}
withContext(Dispatchers.Main) {
onEnd()
}
}
}

private fun getPrcSpeed(sp: Float, max: Float): Float {
return sp / max
}
}
38 changes: 38 additions & 0 deletions app/src/main/res/layout/speedtest_fragment.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginTop="30dp"
android:orientation="vertical"
android:gravity="center_horizontal"
android:padding="16dp">

<com.github.anastr.speedviewlib.TubeSpeedometer
android:id="@+id/tubeSpeedometer"
app:sv_unitUnderSpeedText="false"
app:sv_speedTextColor="?attr/colorPrimary"
app:sv_textColor="?attr/colorPrimary"
app:sv_unitTextColor="?attr/colorPrimary"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<TextView
android:id="@+id/tvSPStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="16.0dip"
android:text=""
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
android:textColor="?attr/colorPrimary"
android:textSize="16sp" />

<Button
android:id="@+id/btnTestSpeed"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:text="@string/test_title"
android:textSize="14sp" />
</LinearLayout>
2 changes: 2 additions & 0 deletions app/src/main/res/values-bg/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
<string name="app_settings">Настройки</string>
<string name="app_version">Версия</string>
<string name="host_title">Задайте URL адрес на TorrServer</string>
<string name="speedtest_title">Тест на скоростта към TorrServer</string>
<string name="host_authorization">Оторизация към сървъра</string>
<string name="host_authorization_desc">Въведете потребителско име и парола, разделени с двоеточие (потребител:парола), оставете празно за липса на удостоверяване.</string>
<string name="local_auth_title">Локален TorrServer с оторизация</string>
Expand Down Expand Up @@ -207,4 +208,5 @@
<string name="no_updates">Не са намерени ъпдейти</string>
<string name="not_used">Не се използва</string>
<string name="not_installed">Не е инсталирано</string>
<string name="test_title">Тест</string>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
<string name="app_settings">Настройки приложения</string>
<string name="app_version">Версия приложения</string>
<string name="host_title">Установить URL-адрес TorrServer</string>
<string name="speedtest_title">Тест скорости до TorrServer</string>
<string name="host_authorization">Авторизация на сервере</string>
<string name="host_authorization_desc">Введите имя и пароль через «:» (user:pass)</string>
<string name="local_auth_title">Локальный TorrServer с авторизацией</string>
Expand Down Expand Up @@ -207,4 +208,5 @@
<string name="no_updates">Нет обновлений</string>
<string name="not_used">Не используется</string>
<string name="not_installed">Не установлен</string>
<string name="test_title">Тест</string>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values-uk/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
<string name="app_settings">Налаштування додатку</string>
<string name="app_version">Версія додатка</string>
<string name="host_title">Встановити URL-адресу TorrServer</string>
<string name="speedtest_title">Тест швидкості до TorrServer</string>
<string name="host_authorization">Авторизація на сервері</string>
<string name="host_authorization_desc">Введіть логін та пароль через «:» (user:pass)</string>
<string name="local_auth_title">Локальний TorrServer з авторизацією</string>
Expand Down Expand Up @@ -207,4 +208,5 @@
<string name="install_ffprobe">Встановіть FFProbe</string>
<string name="delete_ffprobe">Видалити FFProbe</string>
<string name="ffprobe_summary">Завантажте FFProbe, щоб отримати додаткові відеоканчини, такі як тривалість, бітрейт тощо.</string>
<string name="test_title">Тест</string>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@

<string name="host_title">设置 TorrServer url 地址</string>

<string name="speedtest_title">TorrServer 速度测试</string>
<string name="host_authorization">服务端授权</string>
<string name="host_authorization_desc">通过“:”分别填写用户名和密码(user:pass)</string>
<string name="local_auth_title">具有授权的本地 TorrServer</string>
Expand Down Expand Up @@ -248,5 +249,6 @@
<string name="install_ffprobe">安裝FFProbe</string>
<string name="delete_ffprobe">刪除FFProbe</string>
<string name="ffprobe_summary">下載FFProbe以獲取其他視頻數據,例如持續時間,比特率等。</string>
<string name="test_title">测试</string>

</resources>
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@

<string name="host_title">Set TorrServer URL</string>

<string name="speedtest_title">Speed test to TorrServer</string>
<string name="test_title">Test</string>

<string name="host_authorization">Server Authorization</string>
<string name="host_authorization_desc">Enter username and password separated by a colon (user:password), leave blank for no auth.</string>
<string name="local_auth_title">Local TorrServer with Authorization</string>
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
app:summary="@string/host_title"
app:title="@string/host_title" />

<Preference
app:key="speedtest"
app:summary="@string/speedtest_title"
app:title="@string/speedtest_title" />

<Preference
app:key="server_settings"
app:summary="@string/torserver_summary"
Expand Down

0 comments on commit 44673df

Please sign in to comment.