TunnelDetailFragment: use kotlin coroutine for timer and rework nullability
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
d5c07374ff
commit
847da23300
@ -17,9 +17,8 @@ import com.wireguard.android.backend.Tunnel
|
|||||||
import com.wireguard.android.databinding.TunnelDetailFragmentBinding
|
import com.wireguard.android.databinding.TunnelDetailFragmentBinding
|
||||||
import com.wireguard.android.databinding.TunnelDetailPeerBinding
|
import com.wireguard.android.databinding.TunnelDetailPeerBinding
|
||||||
import com.wireguard.android.model.ObservableTunnel
|
import com.wireguard.android.model.ObservableTunnel
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.Timer
|
|
||||||
import java.util.TimerTask
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment that shows details about a specific tunnel.
|
* Fragment that shows details about a specific tunnel.
|
||||||
@ -27,16 +26,15 @@ import java.util.TimerTask
|
|||||||
class TunnelDetailFragment : BaseFragment() {
|
class TunnelDetailFragment : BaseFragment() {
|
||||||
private var binding: TunnelDetailFragmentBinding? = null
|
private var binding: TunnelDetailFragmentBinding? = null
|
||||||
private var lastState = Tunnel.State.TOGGLE
|
private var lastState = Tunnel.State.TOGGLE
|
||||||
private var timer: Timer? = null
|
private var timerActive = true
|
||||||
|
|
||||||
private fun formatBytes(bytes: Long): String {
|
private fun formatBytes(bytes: Long): String {
|
||||||
val context = requireContext()
|
|
||||||
return when {
|
return when {
|
||||||
bytes < 1024 -> context.getString(R.string.transfer_bytes, bytes)
|
bytes < 1024 -> getString(R.string.transfer_bytes, bytes)
|
||||||
bytes < 1024 * 1024 -> context.getString(R.string.transfer_kibibytes, bytes / 1024.0)
|
bytes < 1024 * 1024 -> getString(R.string.transfer_kibibytes, bytes / 1024.0)
|
||||||
bytes < 1024 * 1024 * 1024 -> context.getString(R.string.transfer_mibibytes, bytes / (1024.0 * 1024.0))
|
bytes < 1024 * 1024 * 1024 -> getString(R.string.transfer_mibibytes, bytes / (1024.0 * 1024.0))
|
||||||
bytes < 1024 * 1024 * 1024 * 1024L -> context.getString(R.string.transfer_gibibytes, bytes / (1024.0 * 1024.0 * 1024.0))
|
bytes < 1024 * 1024 * 1024 * 1024L -> getString(R.string.transfer_gibibytes, bytes / (1024.0 * 1024.0 * 1024.0))
|
||||||
else -> context.getString(R.string.transfer_tibibytes, bytes / (1024.0 * 1024.0 * 1024.0) / 1024.0)
|
else -> getString(R.string.transfer_tibibytes, bytes / (1024.0 * 1024.0 * 1024.0) / 1024.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,12 +62,13 @@ class TunnelDetailFragment : BaseFragment() {
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
timer = Timer()
|
timerActive = true
|
||||||
timer!!.scheduleAtFixedRate(object : TimerTask() {
|
lifecycleScope.launch {
|
||||||
override fun run() {
|
while (timerActive) {
|
||||||
updateStats()
|
updateStats()
|
||||||
|
delay(1000)
|
||||||
}
|
}
|
||||||
}, 0, 1000)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSelectedTunnelChanged(oldTunnel: ObservableTunnel?, newTunnel: ObservableTunnel?) {
|
override fun onSelectedTunnelChanged(oldTunnel: ObservableTunnel?, newTunnel: ObservableTunnel?) {
|
||||||
@ -83,15 +82,12 @@ class TunnelDetailFragment : BaseFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastState = Tunnel.State.TOGGLE
|
lastState = Tunnel.State.TOGGLE
|
||||||
updateStats()
|
lifecycleScope.launch { updateStats() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
|
timerActive = false
|
||||||
super.onStop()
|
super.onStop()
|
||||||
if (timer != null) {
|
|
||||||
timer!!.cancel()
|
|
||||||
timer = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
override fun onViewStateRestored(savedInstanceState: Bundle?) {
|
||||||
@ -101,37 +97,36 @@ class TunnelDetailFragment : BaseFragment() {
|
|||||||
super.onViewStateRestored(savedInstanceState)
|
super.onViewStateRestored(savedInstanceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateStats() {
|
private suspend fun updateStats() {
|
||||||
if (binding == null || !isResumed) return
|
val binding = binding ?: return
|
||||||
val tunnel = binding!!.tunnel ?: return
|
val tunnel = binding.tunnel ?: return
|
||||||
|
if (!isResumed) return
|
||||||
val state = tunnel.state
|
val state = tunnel.state
|
||||||
if (state != Tunnel.State.UP && lastState == state) return
|
if (state != Tunnel.State.UP && lastState == state) return
|
||||||
lastState = state
|
lastState = state
|
||||||
lifecycleScope.launch {
|
try {
|
||||||
try {
|
val statistics = tunnel.getStatisticsAsync()
|
||||||
val statistics = tunnel.getStatisticsAsync()
|
for (i in 0 until binding.peersLayout.childCount) {
|
||||||
for (i in 0 until binding!!.peersLayout.childCount) {
|
val peer: TunnelDetailPeerBinding = DataBindingUtil.getBinding(binding.peersLayout.getChildAt(i))
|
||||||
val peer: TunnelDetailPeerBinding = DataBindingUtil.getBinding(binding!!.peersLayout.getChildAt(i))
|
?: continue
|
||||||
?: continue
|
val publicKey = peer.item!!.publicKey
|
||||||
val publicKey = peer.item!!.publicKey
|
val rx = statistics.peerRx(publicKey)
|
||||||
val rx = statistics.peerRx(publicKey)
|
val tx = statistics.peerTx(publicKey)
|
||||||
val tx = statistics.peerTx(publicKey)
|
if (rx == 0L && tx == 0L) {
|
||||||
if (rx == 0L && tx == 0L) {
|
|
||||||
peer.transferLabel.visibility = View.GONE
|
|
||||||
peer.transferText.visibility = View.GONE
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
peer.transferText.text = requireContext().getString(R.string.transfer_rx_tx, formatBytes(rx), formatBytes(tx))
|
|
||||||
peer.transferLabel.visibility = View.VISIBLE
|
|
||||||
peer.transferText.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
for (i in 0 until binding!!.peersLayout.childCount) {
|
|
||||||
val peer: TunnelDetailPeerBinding = DataBindingUtil.getBinding(binding!!.peersLayout.getChildAt(i))
|
|
||||||
?: continue
|
|
||||||
peer.transferLabel.visibility = View.GONE
|
peer.transferLabel.visibility = View.GONE
|
||||||
peer.transferText.visibility = View.GONE
|
peer.transferText.visibility = View.GONE
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
peer.transferText.text = getString(R.string.transfer_rx_tx, formatBytes(rx), formatBytes(tx))
|
||||||
|
peer.transferLabel.visibility = View.VISIBLE
|
||||||
|
peer.transferText.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
for (i in 0 until binding.peersLayout.childCount) {
|
||||||
|
val peer: TunnelDetailPeerBinding = DataBindingUtil.getBinding(binding.peersLayout.getChildAt(i))
|
||||||
|
?: continue
|
||||||
|
peer.transferLabel.visibility = View.GONE
|
||||||
|
peer.transferText.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user