From d8056a134b0021650cef914d0985e556802c095e Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Thu, 10 Nov 2022 23:26:24 +0100 Subject: ui,tunnel: add lastest handshake to peer details Signed-off-by: Mikael Magnusson --- .../android/fragment/TunnelDetailFragment.kt | 23 +++++++-- .../wireguard/android/util/QuantityFormatter.kt | 58 +++++++++++++++++++++- ui/src/main/res/layout/tunnel_detail_peer.xml | 28 +++++++++++ ui/src/main/res/values/strings.xml | 6 +++ 4 files changed, 110 insertions(+), 5 deletions(-) (limited to 'ui') diff --git a/ui/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.kt b/ui/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.kt index 8b155e24..2aec921a 100644 --- a/ui/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.kt +++ b/ui/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.kt @@ -23,6 +23,9 @@ import com.wireguard.android.model.ObservableTunnel import com.wireguard.android.util.QuantityFormatter import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import java.time.Duration +import java.time.LocalDateTime +import java.time.ZoneId /** * Fragment that shows details about a specific tunnel. @@ -106,6 +109,7 @@ class TunnelDetailFragment : BaseFragment(), MenuProvider { val state = tunnel.state if (state != Tunnel.State.UP && lastState == state) return lastState = state + var now = LocalDateTime.now(ZoneId.of("UTC")) try { val statistics = tunnel.getStatisticsAsync() for (i in 0 until binding.peersLayout.childCount) { @@ -117,11 +121,20 @@ class TunnelDetailFragment : BaseFragment(), MenuProvider { if (rx == 0L && tx == 0L) { peer.transferLabel.visibility = View.GONE peer.transferText.visibility = View.GONE - continue + } else { + peer.transferText.text = getString(R.string.transfer_rx_tx, QuantityFormatter.formatBytes(rx), QuantityFormatter.formatBytes(tx)) + peer.transferLabel.visibility = View.VISIBLE + peer.transferText.visibility = View.VISIBLE + } + val lastHandshake:LocalDateTime? = statistics.peerLastHandshake(publicKey) + if (lastHandshake == null) { + peer.lastHandshakeLabel.visibility = View.GONE + peer.lastHandshakeText.visibility = View.GONE + } else { + peer.lastHandshakeText.text = getString(R.string.last_handshake_ago, QuantityFormatter.formatDuration(Duration.between(lastHandshake, now))) + peer.lastHandshakeLabel.visibility = View.VISIBLE + peer.lastHandshakeText.visibility = View.VISIBLE } - peer.transferText.text = getString(R.string.transfer_rx_tx, QuantityFormatter.formatBytes(rx), QuantityFormatter.formatBytes(tx)) - peer.transferLabel.visibility = View.VISIBLE - peer.transferText.visibility = View.VISIBLE } } catch (e: Throwable) { for (i in 0 until binding.peersLayout.childCount) { @@ -129,6 +142,8 @@ class TunnelDetailFragment : BaseFragment(), MenuProvider { ?: continue peer.transferLabel.visibility = View.GONE peer.transferText.visibility = View.GONE + peer.lastHandshakeLabel.visibility = View.GONE + peer.lastHandshakeText.visibility = View.GONE } } } diff --git a/ui/src/main/java/com/wireguard/android/util/QuantityFormatter.kt b/ui/src/main/java/com/wireguard/android/util/QuantityFormatter.kt index 974fe530..f9abd590 100644 --- a/ui/src/main/java/com/wireguard/android/util/QuantityFormatter.kt +++ b/ui/src/main/java/com/wireguard/android/util/QuantityFormatter.kt @@ -8,6 +8,8 @@ package com.wireguard.android.util import com.wireguard.android.Application import com.wireguard.android.R +import java.time.Duration + object QuantityFormatter { fun formatBytes(bytes: Long): String { val context = Application.get().applicationContext @@ -19,4 +21,58 @@ object QuantityFormatter { else -> context.getString(R.string.transfer_tibibytes, bytes / (1024.0 * 1024.0 * 1024.0) / 1024.0) } } -} \ No newline at end of file + + fun formatDuration(duration: Duration): String { + val context = Application.get().applicationContext + val str = formatHours(duration.getSeconds()) + return when { + str != "" -> str + else -> context.getString(R.string.duration_seconds, 0) + } + } + + fun formatHours(seconds: Long): String { + val context = Application.get().applicationContext + val hours = seconds / 3600 + val restSeconds = seconds % 3600 + val str = formatMinutes(restSeconds) + + return when { + hours > 0 -> context.getString(R.string.duration_hours, hours) + if (str != "") ", " + str else "" + else -> str + } + } + + fun formatDays(seconds: Long): String { + val context = Application.get().applicationContext + val days = seconds / 3600 / 24 + val restSeconds = seconds % (3600 * 24) + val str = formatHours(restSeconds) + + return when { + days > 0 -> context.getString(R.string.duration_days, days) + if (str != "") ", " + str else "" + else -> str + } + } + + fun formatMinutes(seconds: Long): String { + val context = Application.get().applicationContext + val minutes = seconds / 60 + val restSeconds = seconds % 60 + val str = formatSeconds(restSeconds) + + return when { + minutes > 0 -> context.getString(R.string.duration_minutes, minutes) + if (str != "") ", " + str else "" + else -> str + } + } + + fun formatSeconds(seconds: Long): String { + val context = Application.get().applicationContext + + return when { + seconds > 0 -> context.getString(R.string.duration_seconds, seconds) + else -> "" + } + } +} diff --git a/ui/src/main/res/layout/tunnel_detail_peer.xml b/ui/src/main/res/layout/tunnel_detail_peer.xml index 0fbee8f1..f295bb13 100644 --- a/ui/src/main/res/layout/tunnel_detail_peer.xml +++ b/ui/src/main/res/layout/tunnel_detail_peer.xml @@ -194,6 +194,34 @@ app:layout_constraintTop_toBottomOf="@+id/transfer_label" tools:text="1024 MB" tools:visibility="visible" /> + + + + diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 85c55887..865c7f07 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -116,6 +116,10 @@ Disabling config exporting makes private keys less accessible DNS servers Search domains + %d days + %d hours + %d minutes + %d seconds Edit Endpoint Error bringing down tunnel: %s @@ -144,6 +148,8 @@ : WireGuard base64 keys must be 44 characters (32 bytes) : WireGuard keys must be 32 bytes : WireGuard hex keys must be 64 characters (32 bytes) + Latest handshake + %s ago Listen port Unable to export log: %s WireGuard Android Log File -- cgit v1.2.3