diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-11-20 11:44:34 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-11-20 12:44:54 +0100 |
commit | 8b0123042f54d843301fbef458b249fcf12466d2 (patch) | |
tree | b3e7bd9f143568666d21014eafe544affb0a89b7 /app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java | |
parent | 16890a659e6d7877b86e870fe4f0ef9cc19aee5b (diff) |
Implement statistics
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java')
-rw-r--r-- | app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java b/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java index 8d2be476..f28a7b67 100644 --- a/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java +++ b/app/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.java @@ -7,6 +7,8 @@ package com.wireguard.android.fragment; import android.os.Bundle; import androidx.annotation.Nullable; +import androidx.databinding.DataBindingUtil; + import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -15,7 +17,13 @@ import android.view.ViewGroup; import com.wireguard.android.R; import com.wireguard.android.databinding.TunnelDetailFragmentBinding; +import com.wireguard.android.databinding.TunnelDetailPeerBinding; import com.wireguard.android.model.Tunnel; +import com.wireguard.android.model.Tunnel.State; +import com.wireguard.crypto.Key; + +import java.util.Timer; +import java.util.TimerTask; /** * Fragment that shows details about a specific tunnel. @@ -23,6 +31,20 @@ import com.wireguard.android.model.Tunnel; public class TunnelDetailFragment extends BaseFragment { @Nullable private TunnelDetailFragmentBinding binding; + @Nullable private Timer timer; + @Nullable private State lastState = State.TOGGLE; + + private static class StatsTimerTask extends TimerTask { + final TunnelDetailFragment tdf; + private StatsTimerTask(final TunnelDetailFragment tdf) { + this.tdf = tdf; + } + + @Override + public void run() { + tdf.updateStats(); + } + } @Override public void onCreate(@Nullable final Bundle savedInstanceState) { @@ -36,6 +58,22 @@ public class TunnelDetailFragment extends BaseFragment { } @Override + public void onStop() { + super.onStop(); + if (timer != null) { + timer.cancel(); + timer = null; + } + } + + @Override + public void onResume() { + super.onResume(); + timer = new Timer(); + timer.scheduleAtFixedRate(new StatsTimerTask(this), 0, 1000); + } + + @Override public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); @@ -59,6 +97,8 @@ public class TunnelDetailFragment extends BaseFragment { binding.setConfig(null); else newTunnel.getConfigAsync().thenAccept(binding::setConfig); + lastState = State.TOGGLE; + updateStats(); } @Override @@ -72,4 +112,52 @@ public class TunnelDetailFragment extends BaseFragment { super.onViewStateRestored(savedInstanceState); } + private String formatBytes(final long bytes) { + if (bytes < 1024) + return getContext().getString(R.string.transfer_bytes, bytes); + else if (bytes < 1024*1024) + return getContext().getString(R.string.transfer_kibibytes, bytes/1024.0); + else if (bytes < 1024*1024*1024) + return getContext().getString(R.string.transfer_mibibytes, bytes/(1024.0*1024.0)); + else if (bytes < 1024*1024*1024*1024) + return getContext().getString(R.string.transfer_gibibytes, bytes/(1024.0*1024.0*1024.0)); + return getContext().getString(R.string.transfer_tibibytes, bytes/(1024.0*1024.0*1024.0)/1024.0); + } + + private void updateStats() { + if (binding == null || !isResumed()) + return; + final State state = binding.getTunnel().getState(); + if (state != State.UP && lastState == state) + return; + lastState = state; + binding.getTunnel().getStatisticsAsync().whenComplete((statistics, throwable) -> { + if (throwable != null) { + for (int i = 0; i < binding.peersLayout.getChildCount(); ++i) { + final TunnelDetailPeerBinding peer = DataBindingUtil.getBinding(binding.peersLayout.getChildAt(i)); + if (peer == null) + continue; + peer.transferLabel.setVisibility(View.GONE); + peer.transferText.setVisibility(View.GONE); + } + return; + } + for (int i = 0; i < binding.peersLayout.getChildCount(); ++i) { + final TunnelDetailPeerBinding peer = DataBindingUtil.getBinding(binding.peersLayout.getChildAt(i)); + if (peer == null) + continue; + final Key publicKey = peer.getItem().getPublicKey(); + final long rx = statistics.peerRx(publicKey); + final long tx = statistics.peerTx(publicKey); + if (rx == 0 && tx == 0) { + peer.transferLabel.setVisibility(View.GONE); + peer.transferText.setVisibility(View.GONE); + continue; + } + peer.transferText.setText(getContext().getString(R.string.transfer_rx_tx, formatBytes(rx), formatBytes(tx))); + peer.transferLabel.setVisibility(View.VISIBLE); + peer.transferText.setVisibility(View.VISIBLE); + } + }); + } } |