better failure behaviour after direct init from jitsi

This commit is contained in:
Daniel Gultsch 2020-04-29 08:51:38 +02:00
parent daf234191b
commit 0d4b175760
2 changed files with 67 additions and 30 deletions

View File

@ -21,6 +21,7 @@ import android.view.WindowManager;
import android.widget.Toast; import android.widget.Toast;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -29,6 +30,7 @@ import org.webrtc.VideoTrack;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -315,7 +317,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
if (remoteVideo.isPresent()) { if (remoteVideo.isPresent()) {
remoteVideo.get().removeSink(binding.remoteVideo); remoteVideo.get().removeSink(binding.remoteVideo);
} }
final Optional<VideoTrack> localVideo = jingleRtpConnection.geLocalVideoTrack(); final Optional<VideoTrack> localVideo = jingleRtpConnection.getLocalVideoTrack();
if (localVideo.isPresent()) { if (localVideo.isPresent()) {
localVideo.get().removeSink(binding.localVideo); localVideo.get().removeSink(binding.localVideo);
} }
@ -385,6 +387,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
finish(); finish();
return true; return true;
} }
final Set<Media> media = getMedia();
if (currentState == RtpEndUserState.INCOMING_CALL) { if (currentState == RtpEndUserState.INCOMING_CALL) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} }
@ -393,16 +396,14 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
} }
binding.with.setText(getWith().getDisplayName()); binding.with.setText(getWith().getDisplayName());
updateVideoViews(currentState); updateVideoViews(currentState);
updateStateDisplay(currentState); updateStateDisplay(currentState, media);
updateButtonConfiguration(currentState); updateButtonConfiguration(currentState, media);
updateProfilePicture(currentState); updateProfilePicture(currentState);
return false; return false;
} }
private void reInitializeActivityWithRunningRapSession(final Account account, Jid with, String sessionId) { private void reInitializeActivityWithRunningRapSession(final Account account, Jid with, String sessionId) {
runOnUiThread(() -> { runOnUiThread(() -> initializeActivityWithRunningRtpSession(account, with, sessionId));
initializeActivityWithRunningRtpSession(account, with, sessionId);
});
final Intent intent = new Intent(Intent.ACTION_VIEW); final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra(EXTRA_ACCOUNT, account.getJid().toEscapedString()); intent.putExtra(EXTRA_ACCOUNT, account.getJid().toEscapedString());
intent.putExtra(EXTRA_WITH, with.toEscapedString()); intent.putExtra(EXTRA_WITH, with.toEscapedString());
@ -421,9 +422,14 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
} }
private void updateStateDisplay(final RtpEndUserState state) { private void updateStateDisplay(final RtpEndUserState state) {
updateStateDisplay(state, Collections.emptySet());
}
private void updateStateDisplay(final RtpEndUserState state, final Set<Media> media) {
switch (state) { switch (state) {
case INCOMING_CALL: 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); setTitle(R.string.rtp_state_incoming_video_call);
} else { } else {
setTitle(R.string.rtp_state_incoming_call); setTitle(R.string.rtp_state_incoming_call);
@ -467,11 +473,19 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
} }
private void updateProfilePicture(final RtpEndUserState state) { 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) { if (state == RtpEndUserState.INCOMING_CALL || state == RtpEndUserState.ACCEPTING_CALL) {
final boolean show = getResources().getBoolean(R.bool.show_avatar_incoming_call); final boolean show = getResources().getBoolean(R.bool.show_avatar_incoming_call);
if (show) { if (show) {
binding.contactPhoto.setVisibility(View.VISIBLE); 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 { } else {
binding.contactPhoto.setVisibility(View.GONE); binding.contactPhoto.setVisibility(View.GONE);
} }
@ -484,8 +498,12 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
return requireRtpConnection().getMedia(); return requireRtpConnection().getMedia();
} }
@SuppressLint("RestrictedApi")
private void updateButtonConfiguration(final RtpEndUserState state) { private void updateButtonConfiguration(final RtpEndUserState state) {
updateButtonConfiguration(state, Collections.emptySet());
}
@SuppressLint("RestrictedApi")
private void updateButtonConfiguration(final RtpEndUserState state, final Set<Media> media) {
if (state == RtpEndUserState.ENDING_CALL || isPictureInPicture()) { if (state == RtpEndUserState.ENDING_CALL || isPictureInPicture()) {
this.binding.rejectCall.setVisibility(View.INVISIBLE); this.binding.rejectCall.setVisibility(View.INVISIBLE);
this.binding.endCall.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.endCall.setVisibility(View.VISIBLE);
this.binding.acceptCall.setVisibility(View.INVISIBLE); this.binding.acceptCall.setVisibility(View.INVISIBLE);
} }
updateInCallButtonConfiguration(state); updateInCallButtonConfiguration(state, media);
} }
private boolean isPictureInPicture() { private boolean isPictureInPicture() {
@ -531,13 +549,14 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
} }
private void updateInCallButtonConfiguration() { private void updateInCallButtonConfiguration() {
updateInCallButtonConfiguration(requireRtpConnection().getEndUserState()); updateInCallButtonConfiguration(requireRtpConnection().getEndUserState(), requireRtpConnection().getMedia());
} }
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
private void updateInCallButtonConfiguration(final RtpEndUserState state) { private void updateInCallButtonConfiguration(final RtpEndUserState state, final Set<Media> media) {
if (state == RtpEndUserState.CONNECTED && !isPictureInPicture()) { 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()); updateInCallButtonConfigurationVideo(requireRtpConnection().isVideoEnabled());
} else { } else {
final AppRTCAudioManager audioManager = requireRtpConnection().getAudioManager(); final AppRTCAudioManager audioManager = requireRtpConnection().getAudioManager();
@ -655,7 +674,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
binding.pipLocalMicOffIndicator.setVisibility(View.GONE); binding.pipLocalMicOffIndicator.setVisibility(View.GONE);
return; return;
} }
final Optional<VideoTrack> localVideoTrack = requireRtpConnection().geLocalVideoTrack(); final Optional<VideoTrack> localVideoTrack = getLocalVideoTrack();
if (localVideoTrack.isPresent() && !isPictureInPicture()) { if (localVideoTrack.isPresent() && !isPictureInPicture()) {
ensureSurfaceViewRendererIsSetup(binding.localVideo); ensureSurfaceViewRendererIsSetup(binding.localVideo);
//paint local view over remote view //paint local view over remote view
@ -665,7 +684,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
} else { } else {
binding.localVideo.setVisibility(View.GONE); binding.localVideo.setVisibility(View.GONE);
} }
final Optional<VideoTrack> remoteVideoTrack = requireRtpConnection().getRemoteVideoTrack(); final Optional<VideoTrack> remoteVideoTrack = getRemoteVideoTrack();
if (remoteVideoTrack.isPresent()) { if (remoteVideoTrack.isPresent()) {
ensureSurfaceViewRendererIsSetup(binding.remoteVideo); ensureSurfaceViewRendererIsSetup(binding.remoteVideo);
remoteVideoTrack.get().addSink(binding.remoteVideo); remoteVideoTrack.get().addSink(binding.remoteVideo);
@ -688,6 +707,22 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
} }
} }
private Optional<VideoTrack> getLocalVideoTrack() {
final JingleRtpConnection connection = this.rtpConnectionReference != null ? this.rtpConnectionReference.get() : null;
if (connection == null) {
return Optional.absent();
}
return connection.getLocalVideoTrack();
}
private Optional<VideoTrack> 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) { private void disableMicrophone(View view) {
JingleRtpConnection rtpConnection = requireRtpConnection(); JingleRtpConnection rtpConnection = requireRtpConnection();
rtpConnection.setMicrophoneEnabled(false); rtpConnection.setMicrophoneEnabled(false);
@ -762,16 +797,18 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe
return; return;
} }
final AbstractJingleConnection.Id id = requireRtpConnection().getId(); final AbstractJingleConnection.Id id = requireRtpConnection().getId();
final Set<Media> media = getMedia();
final Contact contact = getWith();
if (account == id.account && id.with.equals(with) && id.sessionId.equals(sessionId)) { if (account == id.account && id.with.equals(with) && id.sessionId.equals(sessionId)) {
if (state == RtpEndUserState.ENDED) { if (state == RtpEndUserState.ENDED) {
finish(); finish();
return; return;
} }
runOnUiThread(() -> { runOnUiThread(() -> {
updateStateDisplay(state); updateStateDisplay(state, media);
updateButtonConfiguration(state); updateButtonConfiguration(state, media);
updateVideoViews(state); updateVideoViews(state);
updateProfilePicture(state); updateProfilePicture(state, contact);
}); });
if (END_CARD.contains(state)) { if (END_CARD.contains(state)) {
resetIntent(account, with, state, requireRtpConnection().getMedia()); resetIntent(account, with, state, requireRtpConnection().getMedia());

View File

@ -6,6 +6,7 @@ import android.util.Log;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.Collections2; import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@ -52,7 +53,6 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
public static final List<State> STATES_SHOWING_ONGOING_CALL = Arrays.asList( public static final List<State> STATES_SHOWING_ONGOING_CALL = Arrays.asList(
State.PROCEED, State.PROCEED,
State.SESSION_INITIALIZED,
State.SESSION_INITIALIZED_PRE_APPROVED, State.SESSION_INITIALIZED_PRE_APPROVED,
State.SESSION_ACCEPTED State.SESSION_ACCEPTED
); );
@ -369,8 +369,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
); );
try { try {
this.webRTCWrapper.setRemoteDescription(answer).get(); this.webRTCWrapper.setRemoteDescription(answer).get();
} catch (Exception e) { } catch (final Exception e) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": unable to set remote description after receiving session-accept", e); Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": unable to set remote description after receiving session-accept", Throwables.getRootCause(e));
webRTCWrapper.close(); webRTCWrapper.close();
sendSessionTerminate(Reason.FAILED_APPLICATION); sendSessionTerminate(Reason.FAILED_APPLICATION);
} }
@ -420,9 +420,10 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
final RtpContentMap respondingRtpContentMap = RtpContentMap.of(sessionDescription); final RtpContentMap respondingRtpContentMap = RtpContentMap.of(sessionDescription);
sendSessionAccept(respondingRtpContentMap); sendSessionAccept(respondingRtpContentMap);
this.webRTCWrapper.setLocalDescription(webRTCSessionDescription); this.webRTCWrapper.setLocalDescription(webRTCSessionDescription);
} catch (Exception e) { } catch (final Exception e) {
Log.d(Config.LOGTAG, "unable to send session accept", 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<Media> getMedia() { public Set<Media> getMedia() {
if (isInState(State.NULL)) { final State current = getState();
if (current == State.NULL) {
throw new IllegalStateException("RTP connection has not been initialized yet"); 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"); return Preconditions.checkNotNull(this.proposedMedia, "RTP connection has not been initialized properly");
} }
final RtpContentMap initiatorContentMap = initiatorRtpContentMap; final RtpContentMap initiatorContentMap = initiatorRtpContentMap;
@ -1028,9 +1030,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
private void updateEndUserState() { private void updateEndUserState() {
final RtpEndUserState endUserState = getEndUserState(); final RtpEndUserState endUserState = getEndUserState();
final RtpContentMap contentMap = initiatorRtpContentMap; jingleConnectionManager.toneManager.transition(isInitiator(), endUserState, getMedia());
final Set<Media> media = contentMap == null ? Collections.emptySet() : contentMap.getMedia();
jingleConnectionManager.toneManager.transition(isInitiator(), endUserState, media);
xmppConnectionService.notifyJingleRtpConnectionUpdate(id.account, id.with, id.sessionId, endUserState); 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); return TERMINATED.contains(this.state);
} }
public Optional<VideoTrack> geLocalVideoTrack() { public Optional<VideoTrack> getLocalVideoTrack() {
return webRTCWrapper.getLocalVideoTrack(); return webRTCWrapper.getLocalVideoTrack();
} }