TunnelDetailFragment: use kotlin coroutine for timer and rework nullability

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2020-09-20 18:03:58 +02:00
parent d5c07374ff
commit 847da23300

View File

@ -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
} }
} }
} }