Fix crash when handling call messaging failures.
This commit is contained in:
parent
2b4a4d6109
commit
349a2f72cb
6 changed files with 61 additions and 22 deletions
|
@ -451,7 +451,8 @@ public class WebRtcCallActivity extends AppCompatActivity implements SafetyNumbe
|
|||
public void onSendAnywayAfterSafetyNumberChange() {
|
||||
Intent intent = new Intent(WebRtcCallActivity.this, WebRtcCallService.class);
|
||||
intent.setAction(WebRtcCallService.ACTION_OUTGOING_CALL)
|
||||
.putExtra(WebRtcCallService.EXTRA_REMOTE_PEER, new RemotePeer(viewModel.getRecipient().getId()));
|
||||
.putExtra(WebRtcCallService.EXTRA_REMOTE_PEER, new RemotePeer(viewModel.getRecipient().getId()))
|
||||
.putExtra(WebRtcCallService.EXTRA_OFFER_TYPE, OfferMessage.Type.AUDIO_CALL.getCode());
|
||||
|
||||
startService(intent);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,14 @@ public class WebRtcViewModel {
|
|||
// Multiring Hangup States
|
||||
CALL_ACCEPTED_ELSEWHERE,
|
||||
CALL_DECLINED_ELSEWHERE,
|
||||
CALL_ONGOING_ELSEWHERE
|
||||
CALL_ONGOING_ELSEWHERE;
|
||||
|
||||
public boolean isErrorState() {
|
||||
return this == NETWORK_FAILURE ||
|
||||
this == RECIPIENT_UNAVAILABLE ||
|
||||
this == NO_SUCH_USER ||
|
||||
this == UNTRUSTED_IDENTITY;
|
||||
}
|
||||
}
|
||||
|
||||
private final @NonNull State state;
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.signal.ringrtc.IceCandidate;
|
|||
import org.signal.ringrtc.Remote;
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.WebRtcCallActivity;
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
|
@ -52,9 +53,11 @@ import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
|||
import org.whispersystems.libsignal.util.Pair;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
import org.whispersystems.signalservice.api.messages.calls.HangupMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -97,7 +100,8 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
|
|||
public static final String EXTRA_ENABLE = "enable_value";
|
||||
public static final String EXTRA_BROADCAST = "broadcast";
|
||||
public static final String EXTRA_ANSWER_WITH_VIDEO = "enable_video";
|
||||
public static final String EXTRA_ERROR = "error";
|
||||
public static final String EXTRA_ERROR_CALL_STATE = "error_call_state";
|
||||
public static final String EXTRA_ERROR_IDENTITY_KEY = "remote_identity_key";
|
||||
public static final String EXTRA_CAMERA_STATE = "camera_state";
|
||||
public static final String EXTRA_IS_ALWAYS_TURN = "is_always_turn";
|
||||
public static final String EXTRA_TURN_SERVER_INFO = "turn_server_info";
|
||||
|
@ -580,10 +584,22 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
|
|||
|
||||
@Override
|
||||
public void onFailureContinue(@Nullable Throwable error) {
|
||||
Log.i(TAG, "onFailureContinue: ", error);
|
||||
|
||||
Intent intent = new Intent(WebRtcCallService.this, WebRtcCallService.class);
|
||||
intent.setAction(ACTION_MESSAGE_SENT_ERROR)
|
||||
.putExtra(EXTRA_CALL_ID, getCallId().longValue())
|
||||
.putExtra(EXTRA_ERROR, error);
|
||||
.putExtra(EXTRA_CALL_ID, getCallId().longValue());
|
||||
|
||||
WebRtcViewModel.State state = WebRtcViewModel.State.NETWORK_FAILURE;
|
||||
|
||||
if (error instanceof UntrustedIdentityException) {
|
||||
intent.putExtra(EXTRA_ERROR_IDENTITY_KEY, new IdentityKeyParcelable(((UntrustedIdentityException) error).getIdentityKey()));
|
||||
state = WebRtcViewModel.State.UNTRUSTED_IDENTITY;
|
||||
} else if (error instanceof UnregisteredUserException) {
|
||||
state = WebRtcViewModel.State.NO_SUCH_USER;
|
||||
}
|
||||
|
||||
intent.putExtra(EXTRA_ERROR_CALL_STATE, state);
|
||||
|
||||
startService(intent);
|
||||
}
|
||||
|
@ -603,7 +619,6 @@ public class WebRtcCallService extends Service implements CallManager.Observer,
|
|||
if (serviceState.getCallInfoState().getPeer(remotePeer.hashCode()) == null) {
|
||||
Log.w(TAG, "remotePeer not found in map with key: " + remotePeer.hashCode() + "! Dropping.");
|
||||
try {
|
||||
//noinspection ConstantConditions
|
||||
callManager.drop(callId);
|
||||
} catch (CallException e) {
|
||||
serviceState = serviceState.getActionProcessor().callFailure(serviceState, "callManager.drop() failed: ", e);
|
||||
|
|
|
@ -232,7 +232,7 @@ public class ActiveCallActionProcessorDelegate extends WebRtcActionProcessor {
|
|||
protected @NonNull WebRtcServiceState handleEnded(@NonNull WebRtcServiceState currentState, @NonNull String action, @NonNull RemotePeer remotePeer) {
|
||||
Log.i(tag, "handleEnded(): call_id: " + remotePeer.getCallId() + " action: " + action);
|
||||
|
||||
if (remotePeer.callIdEquals(currentState.getCallInfoState().getActivePeer())) {
|
||||
if (remotePeer.callIdEquals(currentState.getCallInfoState().getActivePeer()) && !currentState.getCallInfoState().getCallState().isErrorState()) {
|
||||
currentState = currentState.builder()
|
||||
.changeCallInfoState()
|
||||
.callState(WebRtcViewModel.State.NETWORK_FAILURE)
|
||||
|
|
|
@ -26,15 +26,14 @@ import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder
|
|||
import org.thoughtcrime.securesms.util.TelephonyUtil;
|
||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
||||
import org.webrtc.PeerConnection;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.calls.BusyMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.HangupMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
@ -92,7 +91,6 @@ import static org.thoughtcrime.securesms.service.WebRtcCallService.ACTION_WIRED_
|
|||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_ANSWER_WITH_VIDEO;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_BLUETOOTH;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_CAMERA_STATE;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_ERROR;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_IS_ALWAYS_TURN;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_MUTE;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_RESULT_RECEIVER;
|
||||
|
@ -104,6 +102,8 @@ import static org.thoughtcrime.securesms.service.webrtc.WebRtcIntentParser.getAv
|
|||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcIntentParser.getBroadcastFlag;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcIntentParser.getCallId;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcIntentParser.getEnable;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcIntentParser.getErrorCallState;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcIntentParser.getErrorIdentityKey;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcIntentParser.getIceCandidates;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcIntentParser.getIceServers;
|
||||
import static org.thoughtcrime.securesms.service.webrtc.WebRtcIntentParser.getOfferMessageType;
|
||||
|
@ -173,7 +173,7 @@ public abstract class WebRtcActionProcessor {
|
|||
case ACTION_LOCAL_HANGUP: return handleLocalHangup(currentState);
|
||||
case ACTION_SEND_HANGUP: return handleSendHangup(currentState, CallMetadata.fromIntent(intent), HangupMetadata.fromIntent(intent), getBroadcastFlag(intent));
|
||||
case ACTION_MESSAGE_SENT_SUCCESS: return handleMessageSentSuccess(currentState, getCallId(intent));
|
||||
case ACTION_MESSAGE_SENT_ERROR: return handleMessageSentError(currentState, getCallId(intent), (Throwable) intent.getSerializableExtra(EXTRA_ERROR));
|
||||
case ACTION_MESSAGE_SENT_ERROR: return handleMessageSentError(currentState, getCallId(intent), getErrorCallState(intent), getErrorIdentityKey(intent));
|
||||
|
||||
// Call Setup Actions
|
||||
case ACTION_RECEIVE_ICE_CANDIDATES: return handleReceivedIceCandidates(currentState, CallMetadata.fromIntent(intent), getIceCandidates(intent));
|
||||
|
@ -453,8 +453,11 @@ public abstract class WebRtcActionProcessor {
|
|||
return currentState;
|
||||
}
|
||||
|
||||
protected @NonNull WebRtcServiceState handleMessageSentError(@NonNull WebRtcServiceState currentState, @NonNull CallId callId, @Nullable Throwable error) {
|
||||
Log.w(tag, error);
|
||||
protected @NonNull WebRtcServiceState handleMessageSentError(@NonNull WebRtcServiceState currentState,
|
||||
@NonNull CallId callId,
|
||||
@NonNull WebRtcViewModel.State errorCallState,
|
||||
@NonNull Optional<IdentityKey> identityKey) {
|
||||
Log.w(tag, "handleMessageSentError():");
|
||||
|
||||
try {
|
||||
webRtcInteractor.getCallManager().messageSendFailure(callId);
|
||||
|
@ -469,21 +472,17 @@ public abstract class WebRtcActionProcessor {
|
|||
|
||||
WebRtcServiceStateBuilder builder = currentState.builder();
|
||||
|
||||
if (error instanceof UntrustedIdentityException) {
|
||||
if (errorCallState == WebRtcViewModel.State.UNTRUSTED_IDENTITY) {
|
||||
CallParticipant participant = Objects.requireNonNull(currentState.getCallInfoState().getRemoteParticipant(activePeer.getRecipient()));
|
||||
CallParticipant untrusted = participant.withIdentityKey(((UntrustedIdentityException) error).getIdentityKey());
|
||||
CallParticipant untrusted = participant.withIdentityKey(identityKey.get());
|
||||
|
||||
builder.changeCallInfoState()
|
||||
.callState(WebRtcViewModel.State.UNTRUSTED_IDENTITY)
|
||||
.putParticipant(activePeer.getRecipient(), untrusted)
|
||||
.commit();
|
||||
} else if (error instanceof UnregisteredUserException) {
|
||||
} else {
|
||||
builder.changeCallInfoState()
|
||||
.callState(WebRtcViewModel.State.NO_SUCH_USER)
|
||||
.commit();
|
||||
} else if (error instanceof IOException) {
|
||||
builder.changeCallInfoState()
|
||||
.callState(WebRtcViewModel.State.NETWORK_FAILURE)
|
||||
.callState(errorCallState)
|
||||
.commit();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.signal.ringrtc.CallId;
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable;
|
||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.ringrtc.IceCandidateParcel;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
|
@ -13,6 +15,8 @@ import org.thoughtcrime.securesms.ringrtc.TurnServerInfoParcel;
|
|||
import org.thoughtcrime.securesms.service.WebRtcCallService;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.webrtc.PeerConnection;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -26,6 +30,8 @@ import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_AVAILAB
|
|||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_BROADCAST;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_CALL_ID;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_ENABLE;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_ERROR_CALL_STATE;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_ERROR_IDENTITY_KEY;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_ICE_CANDIDATES;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_MULTI_RING;
|
||||
import static org.thoughtcrime.securesms.service.WebRtcCallService.EXTRA_OFFER_OPAQUE;
|
||||
|
@ -143,4 +149,15 @@ public final class WebRtcIntentParser {
|
|||
return intent.getBooleanExtra(EXTRA_ENABLE, false);
|
||||
}
|
||||
|
||||
public static @NonNull WebRtcViewModel.State getErrorCallState(@NonNull Intent intent) {
|
||||
return (WebRtcViewModel.State) Objects.requireNonNull(intent.getSerializableExtra(EXTRA_ERROR_CALL_STATE));
|
||||
}
|
||||
|
||||
public static @NonNull Optional<IdentityKey> getErrorIdentityKey(@NonNull Intent intent) {
|
||||
IdentityKeyParcelable identityKeyParcelable = (IdentityKeyParcelable) intent.getParcelableExtra(EXTRA_ERROR_IDENTITY_KEY);
|
||||
if (identityKeyParcelable != null) {
|
||||
return Optional.fromNullable(identityKeyParcelable.get());
|
||||
}
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue