diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/CallQualitySurveyManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/CallQualitySurveyManager.java index 28b22b0df..056fd0391 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/CallQualitySurveyManager.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/CallQualitySurveyManager.java @@ -86,28 +86,48 @@ public class CallQualitySurveyManager { pubSubMessageBuilder.setDebugLogUrl(submitCallQualitySurveyRequest.getDebugLogUrl()); } - if (submitCallQualitySurveyRequest.hasRttMedianConnection()) { - pubSubMessageBuilder.setRttMedianConnection(submitCallQualitySurveyRequest.getRttMedianConnection()); + if (submitCallQualitySurveyRequest.hasConnectionRttMedian()) { + pubSubMessageBuilder.setConnectionRttMedian(submitCallQualitySurveyRequest.getConnectionRttMedian()); } - if (submitCallQualitySurveyRequest.hasRttMedianMedia()) { - pubSubMessageBuilder.setRttMedianMedia(submitCallQualitySurveyRequest.getRttMedianMedia()); + if (submitCallQualitySurveyRequest.hasAudioRttMedian()) { + pubSubMessageBuilder.setAudioRttMedian(submitCallQualitySurveyRequest.getAudioRttMedian()); } - if (submitCallQualitySurveyRequest.hasJitterMedianRecv()) { - pubSubMessageBuilder.setJitterMedianRecv(submitCallQualitySurveyRequest.getJitterMedianRecv()); + if (submitCallQualitySurveyRequest.hasVideoRttMedian()) { + pubSubMessageBuilder.setVideoRttMedian(submitCallQualitySurveyRequest.getVideoRttMedian()); } - if (submitCallQualitySurveyRequest.hasJitterMedianSend()) { - pubSubMessageBuilder.setJitterMedianSend(submitCallQualitySurveyRequest.getJitterMedianSend()); + if (submitCallQualitySurveyRequest.hasAudioRecvJitterMedian()) { + pubSubMessageBuilder.setAudioRecvJitterMedian(submitCallQualitySurveyRequest.getAudioRecvJitterMedian()); } - if (submitCallQualitySurveyRequest.hasPacketLossFractionRecv()) { - pubSubMessageBuilder.setPacketLossFractionRecv(submitCallQualitySurveyRequest.getPacketLossFractionRecv()); + if (submitCallQualitySurveyRequest.hasVideoRecvJitterMedian()) { + pubSubMessageBuilder.setVideoRecvJitterMedian(submitCallQualitySurveyRequest.getVideoRecvJitterMedian()); } - if (submitCallQualitySurveyRequest.hasPacketLossFractionSend()) { - pubSubMessageBuilder.setPacketLossFractionSend(submitCallQualitySurveyRequest.getPacketLossFractionSend()); + if (submitCallQualitySurveyRequest.hasAudioSendJitterMedian()) { + pubSubMessageBuilder.setAudioSendJitterMedian(submitCallQualitySurveyRequest.getAudioSendJitterMedian()); + } + + if (submitCallQualitySurveyRequest.hasVideoSendJitterMedian()) { + pubSubMessageBuilder.setVideoSendJitterMedian(submitCallQualitySurveyRequest.getVideoSendJitterMedian()); + } + + if (submitCallQualitySurveyRequest.hasAudioRecvPacketLossFraction()) { + pubSubMessageBuilder.setAudioRecvPacketLossFraction(submitCallQualitySurveyRequest.getAudioRecvPacketLossFraction()); + } + + if (submitCallQualitySurveyRequest.hasVideoRecvPacketLossFraction()) { + pubSubMessageBuilder.setVideoRecvPacketLossFraction(submitCallQualitySurveyRequest.getVideoRecvPacketLossFraction()); + } + + if (submitCallQualitySurveyRequest.hasAudioSendPacketLossFraction()) { + pubSubMessageBuilder.setAudioSendPacketLossFraction(submitCallQualitySurveyRequest.getAudioSendPacketLossFraction()); + } + + if (submitCallQualitySurveyRequest.hasVideoSendPacketLossFraction()) { + pubSubMessageBuilder.setVideoSendPacketLossFraction(submitCallQualitySurveyRequest.getVideoSendPacketLossFraction()); } if (submitCallQualitySurveyRequest.hasCallTelemetry()) { diff --git a/service/src/main/proto/CallQualitySurveyPubSub.proto b/service/src/main/proto/CallQualitySurveyPubSub.proto index f6268efcb..86a915ef5 100644 --- a/service/src/main/proto/CallQualitySurveyPubSub.proto +++ b/service/src/main/proto/CallQualitySurveyPubSub.proto @@ -73,32 +73,56 @@ message CallQualitySurveyResponsePubSubMessage { // The median round-trip time, measured in milliseconds, for STUN/ICE packets // (i.e. connection maintenance and establishment) - optional float rtt_median_connection = 16; + optional float connection_rtt_median = 16; // The median round-trip time, measured in milliseconds, for RTP/RTCP packets - // (i.e. call audio/video) - optional float rtt_median_media = 17; + // for audio streams + optional float audio_rtt_median = 17; - // The median jitter, measured in milliseconds, for the duration of the call - // as measured by the client submitting the survey - optional float jitter_median_recv = 18; + // The median round-trip time, measured in milliseconds, for RTP/RTCP packets + // for video streams + optional float video_rtt_median = 18; - // The median jitter, measured in milliseconds, for the duration of the call - // as measured by the remote endpoint in the call (either the peer of the - // client submitting the survey in a direct call or the SFU in a group call) - optional float jitter_median_send = 19; + // The median jitter for audio streams, measured in milliseconds, for the + // duration of the call as measured by the client submitting the survey + optional float audio_recv_jitter_median = 19; - // The fraction of all packets lost over the duration of the call as measured - // by the client submitting the survey - optional float packet_loss_fraction_recv = 20; + // The median jitter for video streams, measured in milliseconds, for the + // duration of the call as measured by the client submitting the survey + optional float video_recv_jitter_median = 20; - // The fraction of all packets lost over the duration of the call as measured - // by the remote endpoint in the call (either the peer of the client + // The median jitter for audio streams, measured in milliseconds, for the + // duration of the call as measured by the remote endpoint in the call (either + // the peer of the client submitting the survey in a direct call or the SFU in + // a group call) + optional float audio_send_jitter_median = 21; + + // The median jitter for video streams, measured in milliseconds, for the + // duration of the call as measured by the remote endpoint in the call (either + // the peer of the client submitting the survey in a direct call or the SFU in + // a group call) + optional float video_send_jitter_median = 22; + + // The fraction of audio packets lost over the duration of the call as + // measured by the client submitting the survey + optional float audio_recv_packet_loss_fraction = 23; + + // The fraction of video packets lost over the duration of the call as + // measured by the client submitting the survey + optional float video_recv_packet_loss_fraction = 24; + + // The fraction of audio packets lost over the duration of the call as + // measured by the remote endpoint in the call (either the peer of the client // submitting the survey in a direct call or the SFU in a group call) - optional float packet_loss_fraction_send = 21; + optional float audio_send_packet_loss_fraction = 25; + + // The fraction of video packets lost over the duration of the call as + // measured by the remote endpoint in the call (either the peer of the client + // submitting the survey in a direct call or the SFU in a group call) + optional float video_send_packet_loss_fraction = 26; // Technical, machine-generated data about the quality and mechanics of a // call; this is a serialized protobuf entity generated (and, critically, // explained to the user!) by the calling library - optional bytes call_telemetry = 22; + optional bytes call_telemetry = 27; } diff --git a/service/src/main/proto/org/signal/chat/call_quality.proto b/service/src/main/proto/org/signal/chat/call_quality.proto index e67a06a3e..dabcb9fab 100644 --- a/service/src/main/proto/org/signal/chat/call_quality.proto +++ b/service/src/main/proto/org/signal/chat/call_quality.proto @@ -59,34 +59,58 @@ message SubmitCallQualitySurveyRequest { // The median round-trip time, measured in milliseconds, for STUN/ICE packets // (i.e. connection maintenance and establishment) - optional float rtt_median_connection = 10; + optional float connection_rtt_median = 10; // The median round-trip time, measured in milliseconds, for RTP/RTCP packets - // (i.e. call audio/video) - optional float rtt_median_media = 11; + // for audio streams + optional float audio_rtt_median = 11; - // The median jitter, measured in milliseconds, for the duration of the call - // as measured by the client submitting the survey - optional float jitter_median_recv = 12; + // The median round-trip time, measured in milliseconds, for RTP/RTCP packets + // for video streams + optional float video_rtt_median = 12; - // The median jitter, measured in milliseconds, for the duration of the call - // as measured by the remote endpoint in the call (either the peer of the - // client submitting the survey in a direct call or the SFU in a group call) - optional float jitter_median_send = 13; + // The median jitter for audio streams, measured in milliseconds, for the + // duration of the call as measured by the client submitting the survey + optional float audio_recv_jitter_median = 13; - // The fraction of all packets lost over the duration of the call as measured - // by the client submitting the survey - optional float packet_loss_fraction_recv = 14; + // The median jitter for video streams, measured in milliseconds, for the + // duration of the call as measured by the client submitting the survey + optional float video_recv_jitter_median = 14; - // The fraction of all packets lost over the duration of the call as measured - // by the remote endpoint in the call (either the peer of the client + // The median jitter for audio streams, measured in milliseconds, for the + // duration of the call as measured by the remote endpoint in the call (either + // the peer of the client submitting the survey in a direct call or the SFU in + // a group call) + optional float audio_send_jitter_median = 15; + + // The median jitter for video streams, measured in milliseconds, for the + // duration of the call as measured by the remote endpoint in the call (either + // the peer of the client submitting the survey in a direct call or the SFU in + // a group call) + optional float video_send_jitter_median = 16; + + // The fraction of audio packets lost over the duration of the call as + // measured by the client submitting the survey + optional float audio_recv_packet_loss_fraction = 17; + + // The fraction of video packets lost over the duration of the call as + // measured by the client submitting the survey + optional float video_recv_packet_loss_fraction = 18; + + // The fraction of audio packets lost over the duration of the call as + // measured by the remote endpoint in the call (either the peer of the client // submitting the survey in a direct call or the SFU in a group call) - optional float packet_loss_fraction_send = 15; + optional float audio_send_packet_loss_fraction = 19; + + // The fraction of video packets lost over the duration of the call as + // measured by the remote endpoint in the call (either the peer of the client + // submitting the survey in a direct call or the SFU in a group call) + optional float video_send_packet_loss_fraction = 20; // Machine-generated telemetry from the call; this is a serialized protobuf // entity generated (and, critically, explained to the user!) by the calling // library - optional bytes call_telemetry = 16; + optional bytes call_telemetry = 21; } message SubmitCallQualitySurveyResponse { diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/metrics/CallQualitySurveyManagerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/metrics/CallQualitySurveyManagerTest.java index fb6f01e60..67328781c 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/metrics/CallQualitySurveyManagerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/metrics/CallQualitySurveyManagerTest.java @@ -62,12 +62,17 @@ class CallQualitySurveyManagerTest { final byte[] telemetryBytes = TestRandomUtil.nextBytes(32); - final float rttMedianConnection = ThreadLocalRandom.current().nextFloat(); - final float rttMedianMedia = ThreadLocalRandom.current().nextFloat(); - final float jitterMedianRecv = ThreadLocalRandom.current().nextFloat(); - final float jitterMedianSend = ThreadLocalRandom.current().nextFloat(); - final float packetLossFractionRecv = ThreadLocalRandom.current().nextFloat(); - final float packetLossFractionSend = ThreadLocalRandom.current().nextFloat(); + final float connectionRttMedian = ThreadLocalRandom.current().nextFloat(); + final float audioRttMedian = ThreadLocalRandom.current().nextFloat(); + final float videoRttMedian = ThreadLocalRandom.current().nextFloat(); + final float audioRecvJitterMedian = ThreadLocalRandom.current().nextFloat(); + final float videoRecvJitterMedian = ThreadLocalRandom.current().nextFloat(); + final float audioSendJitterMedian = ThreadLocalRandom.current().nextFloat(); + final float videoSendJitterMedian = ThreadLocalRandom.current().nextFloat(); + final float audioRecvPacketLossFraction = ThreadLocalRandom.current().nextFloat(); + final float videoRecvPacketLossFraction = ThreadLocalRandom.current().nextFloat(); + final float audioSendPacketLossFraction = ThreadLocalRandom.current().nextFloat(); + final float videoSendPacketLossFraction = ThreadLocalRandom.current().nextFloat(); when(asnInfoProvider.lookup(REMOTE_ADDRESS)).thenReturn(Optional.of(new AsnInfo(asn, asnRegion))); @@ -82,12 +87,17 @@ class CallQualitySurveyManagerTest { .setCallType("direct_video") .setSuccess(true) .setCallEndReason("caller_hang_up") - .setRttMedianConnection(rttMedianConnection) - .setRttMedianMedia(rttMedianMedia) - .setJitterMedianRecv(jitterMedianRecv) - .setJitterMedianSend(jitterMedianSend) - .setPacketLossFractionRecv(packetLossFractionRecv) - .setPacketLossFractionSend(packetLossFractionSend) + .setConnectionRttMedian(connectionRttMedian) + .setAudioRttMedian(audioRttMedian) + .setVideoRttMedian(videoRttMedian) + .setAudioRecvJitterMedian(audioRecvJitterMedian) + .setVideoRecvJitterMedian(videoRecvJitterMedian) + .setAudioSendJitterMedian(audioSendJitterMedian) + .setVideoSendJitterMedian(videoSendJitterMedian) + .setAudioRecvPacketLossFraction(audioRecvPacketLossFraction) + .setVideoRecvPacketLossFraction(videoRecvPacketLossFraction) + .setAudioSendPacketLossFraction(audioSendPacketLossFraction) + .setVideoSendPacketLossFraction(videoSendPacketLossFraction) .setCallTelemetry(ByteString.copyFrom(telemetryBytes)) .build(); @@ -117,12 +127,17 @@ class CallQualitySurveyManagerTest { assertEquals("direct_video", callQualitySurveyResponsePubSubMessage.getCallType()); assertTrue(callQualitySurveyResponsePubSubMessage.getSuccess()); assertEquals("caller_hang_up", callQualitySurveyResponsePubSubMessage.getCallEndReason()); - assertEquals(rttMedianConnection, callQualitySurveyResponsePubSubMessage.getRttMedianConnection()); - assertEquals(rttMedianMedia, callQualitySurveyResponsePubSubMessage.getRttMedianMedia()); - assertEquals(jitterMedianRecv, callQualitySurveyResponsePubSubMessage.getJitterMedianRecv()); - assertEquals(jitterMedianSend, callQualitySurveyResponsePubSubMessage.getJitterMedianSend()); - assertEquals(packetLossFractionRecv, callQualitySurveyResponsePubSubMessage.getPacketLossFractionRecv()); - assertEquals(packetLossFractionSend, callQualitySurveyResponsePubSubMessage.getPacketLossFractionSend()); + assertEquals(connectionRttMedian, callQualitySurveyResponsePubSubMessage.getConnectionRttMedian()); + assertEquals(audioRttMedian, callQualitySurveyResponsePubSubMessage.getAudioRttMedian()); + assertEquals(videoRttMedian, callQualitySurveyResponsePubSubMessage.getVideoRttMedian()); + assertEquals(audioRecvJitterMedian, callQualitySurveyResponsePubSubMessage.getAudioRecvJitterMedian()); + assertEquals(videoRecvJitterMedian, callQualitySurveyResponsePubSubMessage.getVideoRecvJitterMedian()); + assertEquals(audioSendJitterMedian, callQualitySurveyResponsePubSubMessage.getAudioSendJitterMedian()); + assertEquals(videoSendJitterMedian, callQualitySurveyResponsePubSubMessage.getVideoSendJitterMedian()); + assertEquals(audioRecvPacketLossFraction, callQualitySurveyResponsePubSubMessage.getAudioRecvPacketLossFraction()); + assertEquals(videoRecvPacketLossFraction, callQualitySurveyResponsePubSubMessage.getVideoRecvPacketLossFraction()); + assertEquals(audioSendPacketLossFraction, callQualitySurveyResponsePubSubMessage.getAudioSendPacketLossFraction()); + assertEquals(videoSendPacketLossFraction, callQualitySurveyResponsePubSubMessage.getVideoSendPacketLossFraction()); assertArrayEquals(telemetryBytes, callQualitySurveyResponsePubSubMessage.getCallTelemetry().toByteArray()); } }