use stopwatch to keep track of jingle rtp session duration

This commit is contained in:
Daniel Gultsch 2021-11-11 16:52:18 +01:00
parent 9843b72f6f
commit 9c3f55bef2
3 changed files with 34 additions and 29 deletions

View file

@ -939,14 +939,11 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
this.binding.duration.setVisibility(View.GONE);
return;
}
final long rtpConnectionStarted = connection.getRtpConnectionStarted();
final long rtpConnectionEnded = connection.getRtpConnectionEnded();
if (rtpConnectionStarted != 0) {
final long ended = rtpConnectionEnded == 0 ? SystemClock.elapsedRealtime() : rtpConnectionEnded;
this.binding.duration.setText(TimeFrameUtils.formatTimePassed(rtpConnectionStarted, ended, false));
this.binding.duration.setVisibility(View.VISIBLE);
} else {
if (connection.zeroDuration()) {
this.binding.duration.setVisibility(View.GONE);
} else {
this.binding.duration.setText(TimeFrameUtils.formatElapsedTime(connection.getCallDuration(), false));
this.binding.duration.setVisibility(View.VISIBLE);
}
}

View file

@ -71,10 +71,14 @@ public class TimeFrameUtils {
public static String formatTimePassed(final long since, final long to, final boolean withMilliseconds) {
final long passed = (since < 0) ? 0 : (to - since);
final int hours = (int) (passed / 3600000);
final int minutes = (int) (passed / 60000) % 60;
final int seconds = (int) (passed / 1000) % 60;
final int milliseconds = (int) (passed / 100) % 10;
return formatElapsedTime(passed, withMilliseconds);
}
public static String formatElapsedTime(final long elapsed, final boolean withMilliseconds) {
final int hours = (int) (elapsed / 3600000);
final int minutes = (int) (elapsed / 60000) % 60;
final int seconds = (int) (elapsed / 1000) % 60;
final int milliseconds = (int) (elapsed / 100) % 10;
if (hours > 0) {
return String.format(Locale.ENGLISH, "%d:%02d:%02d", hours, minutes, seconds);
} else if (withMilliseconds) {

View file

@ -1,6 +1,5 @@
package eu.siacs.conversations.xmpp.jingle;
import android.os.SystemClock;
import android.util.Log;
import androidx.annotation.NonNull;
@ -8,6 +7,7 @@ import androidx.annotation.Nullable;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Stopwatch;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.Collections2;
@ -29,8 +29,10 @@ import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@ -147,8 +149,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
private Set<Media> proposedMedia;
private RtpContentMap initiatorRtpContentMap;
private RtpContentMap responderRtpContentMap;
private long rtpConnectionStarted = 0; //time of 'connected'
private long rtpConnectionEnded = 0;
private final Stopwatch sessionDuration = Stopwatch.createUnstarted();
private final Queue<PeerConnection.PeerConnectionState> stateHistory = new LinkedList<>();
private ScheduledFuture<?> ringingTimeoutFuture;
JingleRtpConnection(JingleConnectionManager jingleConnectionManager, Id id, Jid initiator) {
@ -1056,7 +1058,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
return RtpEndUserState.RETRACTED;
}
case TERMINATED_CONNECTIVITY_ERROR:
return rtpConnectionStarted == 0 ? RtpEndUserState.CONNECTIVITY_ERROR : RtpEndUserState.CONNECTIVITY_LOST_ERROR;
return zeroDuration() ? RtpEndUserState.CONNECTIVITY_ERROR : RtpEndUserState.CONNECTIVITY_LOST_ERROR;
case TERMINATED_APPLICATION_FAILURE:
return RtpEndUserState.APPLICATION_ERROR;
case TERMINATED_SECURITY_ERROR:
@ -1084,7 +1086,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
case CLOSED:
return RtpEndUserState.ENDING_CALL;
default:
return rtpConnectionStarted == 0 ? RtpEndUserState.CONNECTIVITY_ERROR : RtpEndUserState.RECONNECTING;
return zeroDuration() ? RtpEndUserState.CONNECTIVITY_ERROR : RtpEndUserState.RECONNECTING;
}
}
@ -1338,15 +1340,18 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
@Override
public void onConnectionChange(final PeerConnection.PeerConnectionState oldState, final PeerConnection.PeerConnectionState newState) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": PeerConnectionState changed: " + oldState + "->" + newState);
final boolean neverConnected = this.rtpConnectionStarted == 0;
if (newState == PeerConnection.PeerConnectionState.CONNECTED && this.rtpConnectionStarted == 0) {
this.rtpConnectionStarted = SystemClock.elapsedRealtime();
}
if (newState == PeerConnection.PeerConnectionState.CLOSED && this.rtpConnectionEnded == 0) {
this.rtpConnectionEnded = SystemClock.elapsedRealtime();
this.stateHistory.add(newState);
if (newState == PeerConnection.PeerConnectionState.CONNECTED) {
this.sessionDuration.start();
} else if (this.sessionDuration.isRunning()) {
this.sessionDuration.stop();
}
if (neverConnected && Arrays.asList(PeerConnection.PeerConnectionState.FAILED, PeerConnection.PeerConnectionState.DISCONNECTED).contains(newState)) {
final boolean neverConnected = !this.stateHistory.contains(PeerConnection.PeerConnectionState.CONNECTED);
final boolean failedOrDisconnected = Arrays.asList(PeerConnection.PeerConnectionState.FAILED, PeerConnection.PeerConnectionState.DISCONNECTED).contains(newState);
if (neverConnected && failedOrDisconnected) {
if (isTerminated()) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": not sending session-terminate after connectivity error because session is already in state " + this.state);
return;
@ -1375,12 +1380,12 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
}
}
public long getRtpConnectionStarted() {
return this.rtpConnectionStarted;
public boolean zeroDuration() {
return this.sessionDuration.elapsed(TimeUnit.NANOSECONDS) <= 0;
}
public long getRtpConnectionEnded() {
return this.rtpConnectionEnded;
public long getCallDuration() {
return this.sessionDuration.elapsed(TimeUnit.MILLISECONDS);
}
public AppRTCAudioManager getAudioManager() {
@ -1507,8 +1512,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
}
private void writeLogMessage(final State state) {
final long started = this.rtpConnectionStarted;
long duration = started <= 0 ? 0 : SystemClock.elapsedRealtime() - started;
final long duration = getCallDuration();
if (state == State.TERMINATED_SUCCESS || (state == State.TERMINATED_CONNECTIVITY_ERROR && duration > 0)) {
writeLogMessageSuccess(duration);
} else {