From 0d4b1757607157492e4491a127f7700292fe6bc6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 29 Apr 2020 08:51:38 +0200 Subject: [PATCH] better failure behaviour after direct init from jitsi --- .../conversations/ui/RtpSessionActivity.java | 73 ++++++++++++++----- .../xmpp/jingle/JingleRtpConnection.java | 24 +++--- 2 files changed, 67 insertions(+), 30 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index acd9d151e..2cdba2d0c 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -21,6 +21,7 @@ import android.view.WindowManager; import android.widget.Toast; import com.google.common.base.Optional; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -29,6 +30,7 @@ import org.webrtc.VideoTrack; import java.lang.ref.WeakReference; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -315,7 +317,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe if (remoteVideo.isPresent()) { remoteVideo.get().removeSink(binding.remoteVideo); } - final Optional localVideo = jingleRtpConnection.geLocalVideoTrack(); + final Optional localVideo = jingleRtpConnection.getLocalVideoTrack(); if (localVideo.isPresent()) { localVideo.get().removeSink(binding.localVideo); } @@ -385,6 +387,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe finish(); return true; } + final Set media = getMedia(); if (currentState == RtpEndUserState.INCOMING_CALL) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } @@ -393,16 +396,14 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } binding.with.setText(getWith().getDisplayName()); updateVideoViews(currentState); - updateStateDisplay(currentState); - updateButtonConfiguration(currentState); + updateStateDisplay(currentState, media); + updateButtonConfiguration(currentState, media); updateProfilePicture(currentState); return false; } private void reInitializeActivityWithRunningRapSession(final Account account, Jid with, String sessionId) { - runOnUiThread(() -> { - initializeActivityWithRunningRtpSession(account, with, sessionId); - }); + runOnUiThread(() -> initializeActivityWithRunningRtpSession(account, with, sessionId)); final Intent intent = new Intent(Intent.ACTION_VIEW); intent.putExtra(EXTRA_ACCOUNT, account.getJid().toEscapedString()); intent.putExtra(EXTRA_WITH, with.toEscapedString()); @@ -421,9 +422,14 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } private void updateStateDisplay(final RtpEndUserState state) { + updateStateDisplay(state, Collections.emptySet()); + } + + private void updateStateDisplay(final RtpEndUserState state, final Set media) { switch (state) { case INCOMING_CALL: - if (getMedia().contains(Media.VIDEO)) { + Preconditions.checkArgument(media.size() > 0, "Media must not be empty"); + if (media.contains(Media.VIDEO)) { setTitle(R.string.rtp_state_incoming_video_call); } else { setTitle(R.string.rtp_state_incoming_call); @@ -467,11 +473,19 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } private void updateProfilePicture(final RtpEndUserState state) { + updateProfilePicture(state, null); + } + + private void updateProfilePicture(final RtpEndUserState state, final Contact contact) { if (state == RtpEndUserState.INCOMING_CALL || state == RtpEndUserState.ACCEPTING_CALL) { final boolean show = getResources().getBoolean(R.bool.show_avatar_incoming_call); if (show) { binding.contactPhoto.setVisibility(View.VISIBLE); - AvatarWorkerTask.loadAvatar(getWith(), binding.contactPhoto, R.dimen.publish_avatar_size); + if (contact == null) { + AvatarWorkerTask.loadAvatar(getWith(), binding.contactPhoto, R.dimen.publish_avatar_size); + } else { + AvatarWorkerTask.loadAvatar(contact, binding.contactPhoto, R.dimen.publish_avatar_size); + } } else { binding.contactPhoto.setVisibility(View.GONE); } @@ -484,8 +498,12 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe return requireRtpConnection().getMedia(); } - @SuppressLint("RestrictedApi") private void updateButtonConfiguration(final RtpEndUserState state) { + updateButtonConfiguration(state, Collections.emptySet()); + } + + @SuppressLint("RestrictedApi") + private void updateButtonConfiguration(final RtpEndUserState state, final Set media) { if (state == RtpEndUserState.ENDING_CALL || isPictureInPicture()) { this.binding.rejectCall.setVisibility(View.INVISIBLE); this.binding.endCall.setVisibility(View.INVISIBLE); @@ -519,7 +537,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe this.binding.endCall.setVisibility(View.VISIBLE); this.binding.acceptCall.setVisibility(View.INVISIBLE); } - updateInCallButtonConfiguration(state); + updateInCallButtonConfiguration(state, media); } private boolean isPictureInPicture() { @@ -531,13 +549,14 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } private void updateInCallButtonConfiguration() { - updateInCallButtonConfiguration(requireRtpConnection().getEndUserState()); + updateInCallButtonConfiguration(requireRtpConnection().getEndUserState(), requireRtpConnection().getMedia()); } @SuppressLint("RestrictedApi") - private void updateInCallButtonConfiguration(final RtpEndUserState state) { + private void updateInCallButtonConfiguration(final RtpEndUserState state, final Set media) { if (state == RtpEndUserState.CONNECTED && !isPictureInPicture()) { - if (getMedia().contains(Media.VIDEO)) { + Preconditions.checkArgument(media.size() > 0, "Media must not be empty"); + if (media.contains(Media.VIDEO)) { updateInCallButtonConfigurationVideo(requireRtpConnection().isVideoEnabled()); } else { final AppRTCAudioManager audioManager = requireRtpConnection().getAudioManager(); @@ -655,7 +674,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe binding.pipLocalMicOffIndicator.setVisibility(View.GONE); return; } - final Optional localVideoTrack = requireRtpConnection().geLocalVideoTrack(); + final Optional localVideoTrack = getLocalVideoTrack(); if (localVideoTrack.isPresent() && !isPictureInPicture()) { ensureSurfaceViewRendererIsSetup(binding.localVideo); //paint local view over remote view @@ -665,7 +684,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } else { binding.localVideo.setVisibility(View.GONE); } - final Optional remoteVideoTrack = requireRtpConnection().getRemoteVideoTrack(); + final Optional remoteVideoTrack = getRemoteVideoTrack(); if (remoteVideoTrack.isPresent()) { ensureSurfaceViewRendererIsSetup(binding.remoteVideo); remoteVideoTrack.get().addSink(binding.remoteVideo); @@ -688,6 +707,22 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } } + private Optional getLocalVideoTrack() { + final JingleRtpConnection connection = this.rtpConnectionReference != null ? this.rtpConnectionReference.get() : null; + if (connection == null) { + return Optional.absent(); + } + return connection.getLocalVideoTrack(); + } + + private Optional getRemoteVideoTrack() { + final JingleRtpConnection connection = this.rtpConnectionReference != null ? this.rtpConnectionReference.get() : null; + if (connection == null) { + return Optional.absent(); + } + return connection.getRemoteVideoTrack(); + } + private void disableMicrophone(View view) { JingleRtpConnection rtpConnection = requireRtpConnection(); rtpConnection.setMicrophoneEnabled(false); @@ -762,16 +797,18 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe return; } final AbstractJingleConnection.Id id = requireRtpConnection().getId(); + final Set media = getMedia(); + final Contact contact = getWith(); if (account == id.account && id.with.equals(with) && id.sessionId.equals(sessionId)) { if (state == RtpEndUserState.ENDED) { finish(); return; } runOnUiThread(() -> { - updateStateDisplay(state); - updateButtonConfiguration(state); + updateStateDisplay(state, media); + updateButtonConfiguration(state, media); updateVideoViews(state); - updateProfilePicture(state); + updateProfilePicture(state, contact); }); if (END_CARD.contains(state)) { resetIntent(account, with, state, requireRtpConnection().getMedia()); diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 7817c2d2e..4dce736a8 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -6,6 +6,7 @@ import android.util.Log; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.google.common.base.Throwables; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -52,7 +53,6 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web public static final List STATES_SHOWING_ONGOING_CALL = Arrays.asList( State.PROCEED, - State.SESSION_INITIALIZED, State.SESSION_INITIALIZED_PRE_APPROVED, State.SESSION_ACCEPTED ); @@ -369,8 +369,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web ); try { this.webRTCWrapper.setRemoteDescription(answer).get(); - } catch (Exception e) { - Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": unable to set remote description after receiving session-accept", e); + } catch (final Exception e) { + Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": unable to set remote description after receiving session-accept", Throwables.getRootCause(e)); webRTCWrapper.close(); sendSessionTerminate(Reason.FAILED_APPLICATION); } @@ -420,9 +420,10 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web final RtpContentMap respondingRtpContentMap = RtpContentMap.of(sessionDescription); sendSessionAccept(respondingRtpContentMap); this.webRTCWrapper.setLocalDescription(webRTCSessionDescription); - } catch (Exception e) { - Log.d(Config.LOGTAG, "unable to send session accept", e); - + } catch (final Exception e) { + Log.d(Config.LOGTAG, "unable to send session accept", Throwables.getRootCause(e)); + webRTCWrapper.close(); + sendSessionTerminate(Reason.FAILED_APPLICATION); } } @@ -791,10 +792,11 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web } public Set getMedia() { - if (isInState(State.NULL)) { + final State current = getState(); + if (current == State.NULL) { throw new IllegalStateException("RTP connection has not been initialized yet"); } - if (isInState(State.PROPOSED, State.PROCEED)) { + if (Arrays.asList(State.PROPOSED, State.PROCEED).contains(current)) { return Preconditions.checkNotNull(this.proposedMedia, "RTP connection has not been initialized properly"); } final RtpContentMap initiatorContentMap = initiatorRtpContentMap; @@ -1028,9 +1030,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web private void updateEndUserState() { final RtpEndUserState endUserState = getEndUserState(); - final RtpContentMap contentMap = initiatorRtpContentMap; - final Set media = contentMap == null ? Collections.emptySet() : contentMap.getMedia(); - jingleConnectionManager.toneManager.transition(isInitiator(), endUserState, media); + jingleConnectionManager.toneManager.transition(isInitiator(), endUserState, getMedia()); xmppConnectionService.notifyJingleRtpConnectionUpdate(id.account, id.with, id.sessionId, endUserState); } @@ -1147,7 +1147,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web return TERMINATED.contains(this.state); } - public Optional geLocalVideoTrack() { + public Optional getLocalVideoTrack() { return webRTCWrapper.getLocalVideoTrack(); }