Better support for building webrtc call view off of model

Fixes #6144
// FREEBIE
This commit is contained in:
Moxie Marlinspike
2017-02-02 18:34:51 -08:00
parent 8dc6f2b15b
commit 9a93a8b28d
7 changed files with 207 additions and 166 deletions

View File

@@ -27,7 +27,7 @@ import org.thoughtcrime.securesms.WebRtcCallActivity;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.dependencies.SignalCommunicationModule.SignalMessageSenderFactory;
import org.thoughtcrime.securesms.events.WebRtcCallEvent;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
import org.thoughtcrime.securesms.notifications.MessageNotifier;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
@@ -57,6 +57,7 @@ import org.webrtc.SessionDescription;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoRenderer;
import org.webrtc.VideoTrack;
import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
@@ -68,8 +69,8 @@ import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
import org.whispersystems.signalservice.api.messages.calls.TurnServerInfo;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
import org.whispersystems.signalservice.api.util.InvalidNumberException;
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -111,8 +112,8 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
public static final String EXTRA_ICE_SDP_MID = "ice_sdp_mid";
public static final String EXTRA_ICE_SDP_LINE_INDEX = "ice_sdp_line_index";
public static final String ACTION_INCOMING_CALL = "INCOMING_CALL";
public static final String ACTION_OUTGOING_CALL = "OUTGOING_CALL";
public static final String ACTION_INCOMING_CALL = "CALL_INCOMING";
public static final String ACTION_OUTGOING_CALL = "CALL_OUTGOING";
public static final String ACTION_ANSWER_CALL = "ANSWER_CALL";
public static final String ACTION_DENY_CALL = "DENY_CALL";
public static final String ACTION_LOCAL_HANGUP = "LOCAL_HANGUP";
@@ -129,10 +130,11 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
public static final String ACTION_REMOTE_VIDEO_MUTE = "REMOTE_VIDEO_MUTE";
public static final String ACTION_ICE_CONNECTED = "ICE_CONNECTED";
private CallState callState = CallState.STATE_IDLE;
private boolean audioEnabled = true;
private boolean videoEnabled = false;
private Handler serviceHandler = new Handler();
private CallState callState = CallState.STATE_IDLE;
private boolean audioEnabled = true;
private boolean localVideoEnabled = false;
private boolean remoteVideoEnabled = false;
private Handler serviceHandler = new Handler();
@Inject public SignalMessageSenderFactory messageSenderFactory;
@Inject public SignalServiceAccountManager accountManager;
@@ -289,7 +291,7 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
initializeVideo();
sendMessage(WebRtcCallEvent.Type.OUTGOING_CALL, recipient, null);
sendMessage(WebRtcViewModel.State.CALL_OUTGOING, recipient, localVideoEnabled, remoteVideoEnabled);
lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL);
outgoingRinger.playSonar();
@@ -317,10 +319,13 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
@Override
public void onFailureContinue(Throwable error) {
Log.w(TAG, error);
if (error instanceof IOException) {
sendMessage(WebRtcCallEvent.Type.SERVER_FAILURE, recipient, null);
} else if (error instanceof UntrustedIdentityException) {
sendMessage(WebRtcCallEvent.Type.UNTRUSTED_IDENTITY, recipient, ((UntrustedIdentityException)error).getIdentityKey());
if (error instanceof UntrustedIdentityException) {
sendMessage(WebRtcViewModel.State.UNTRUSTED_IDENTITY, recipient, ((UntrustedIdentityException)error).getIdentityKey(), localVideoEnabled, remoteVideoEnabled);
} else if (error instanceof UnregisteredUserException) {
sendMessage(WebRtcViewModel.State.NO_SUCH_USER, recipient, localVideoEnabled, remoteVideoEnabled);
} else if (error instanceof IOException) {
sendMessage(WebRtcViewModel.State.NETWORK_FAILURE, recipient, localVideoEnabled, remoteVideoEnabled);
}
terminate();
@@ -357,7 +362,7 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
@Override
public void onFailureContinue(Throwable error) {
Log.w(TAG, error);
sendMessage(WebRtcCallEvent.Type.SERVER_FAILURE, recipient, null);
sendMessage(WebRtcViewModel.State.NETWORK_FAILURE, recipient, localVideoEnabled, remoteVideoEnabled);
terminate();
}
@@ -406,7 +411,7 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
@Override
public void onFailureContinue(Throwable error) {
Log.w(TAG, error);
sendMessage(WebRtcCallEvent.Type.SERVER_FAILURE, recipient, null);
sendMessage(WebRtcViewModel.State.NETWORK_FAILURE, recipient, localVideoEnabled, remoteVideoEnabled);
terminate();
}
@@ -420,7 +425,7 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
this.callState = CallState.STATE_LOCAL_RINGING;
this.lockManager.updatePhoneState(LockManager.PhoneState.INTERACTIVE);
sendMessage(WebRtcCallEvent.Type.INCOMING_CALL, recipient, null);
sendMessage(WebRtcViewModel.State.CALL_INCOMING, recipient, localVideoEnabled, remoteVideoEnabled);
startCallCardActivity();
incomingRinger.start();
CallNotificationManager.setCallInProgress(this, TYPE_INCOMING_RINGING, recipient);
@@ -430,7 +435,7 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
this.callState = CallState.STATE_REMOTE_RINGING;
this.outgoingRinger.playRing();
sendMessage(WebRtcCallEvent.Type.CALL_RINGING, recipient, null);
sendMessage(WebRtcViewModel.State.CALL_RINGING, recipient, localVideoEnabled, remoteVideoEnabled);
}
}
@@ -455,17 +460,17 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
outgoingRinger.playComplete();
lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL);
sendMessage(WebRtcCallEvent.Type.CALL_CONNECTED, recipient, "un used");
sendMessage(WebRtcViewModel.State.CALL_CONNECTED, recipient, localVideoEnabled, remoteVideoEnabled);
CallNotificationManager.setCallInProgress(this, TYPE_ESTABLISHED, recipient);
this.peerConnection.setAudioEnabled(audioEnabled);
this.peerConnection.setVideoEnabled(videoEnabled);
this.peerConnection.setVideoEnabled(localVideoEnabled);
this.dataChannel.send(new DataChannel.Buffer(ByteBuffer.wrap(Data.newBuilder()
.setVideoStreamingStatus(WebRtcDataProtos.VideoStreamingStatus.newBuilder()
.setId(this.callId)
.setEnabled(videoEnabled))
.setEnabled(localVideoEnabled))
.build().toByteArray()), false));
}
@@ -488,7 +493,7 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
return;
}
sendMessage(WebRtcCallEvent.Type.CALL_BUSY, recipient, null);
sendMessage(WebRtcViewModel.State.CALL_BUSY, recipient, localVideoEnabled, remoteVideoEnabled);
outgoingRinger.playBusy();
serviceHandler.postDelayed(new Runnable() {
@@ -505,7 +510,7 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
this.callState != CallState.STATE_CONNECTED)
{
Log.w(TAG, "Timing out call: " + this.callId);
sendMessage(WebRtcCallEvent.Type.CALL_DISCONNECTED, this.recipient, null);
sendMessage(WebRtcViewModel.State.CALL_DISCONNECTED, this.recipient, localVideoEnabled, remoteVideoEnabled);
terminate();
}
}
@@ -580,9 +585,9 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
}
if (this.callState == CallState.STATE_DIALING || this.callState == CallState.STATE_REMOTE_RINGING) {
sendMessage(WebRtcCallEvent.Type.RECIPIENT_UNAVAILABLE, this.recipient, null);
sendMessage(WebRtcViewModel.State.RECIPIENT_UNAVAILABLE, this.recipient, localVideoEnabled, remoteVideoEnabled);
} else {
sendMessage(WebRtcCallEvent.Type.CALL_DISCONNECTED, this.recipient, null);
sendMessage(WebRtcViewModel.State.CALL_DISCONNECTED, this.recipient, localVideoEnabled, remoteVideoEnabled);
}
if (this.callState == CallState.STATE_ANSWERING || this.callState == CallState.STATE_LOCAL_RINGING) {
@@ -603,19 +608,21 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
private void handleSetMuteVideo(Intent intent) {
boolean muted = intent.getBooleanExtra(EXTRA_MUTE, false);
this.videoEnabled = !muted;
this.localVideoEnabled = !muted;
if (this.peerConnection != null) {
this.peerConnection.setVideoEnabled(this.videoEnabled);
this.peerConnection.setVideoEnabled(this.localVideoEnabled);
}
if (this.callId != null && this.dataChannel != null) {
this.dataChannel.send(new DataChannel.Buffer(ByteBuffer.wrap(Data.newBuilder()
.setVideoStreamingStatus(WebRtcDataProtos.VideoStreamingStatus.newBuilder()
.setId(this.callId)
.setEnabled(videoEnabled))
.setEnabled(localVideoEnabled))
.build().toByteArray()), false));
}
sendMessage(viewModelStateFor(callState), this.recipient, localVideoEnabled, remoteVideoEnabled);
}
private void handleRemoteVideoMute(Intent intent) {
@@ -627,11 +634,8 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
return;
}
if (muted) {
sendMessage(WebRtcCallEvent.Type.REMOTE_VIDEO_DISABLED, this.recipient, null);
} else {
sendMessage(WebRtcCallEvent.Type.REMOTE_VIDEO_ENABLED, this.recipient, null);
}
this.remoteVideoEnabled = !muted;
sendMessage(WebRtcViewModel.State.CALL_CONNECTED, this.recipient, localVideoEnabled, remoteVideoEnabled);
}
/// Helper Methods
@@ -709,21 +713,30 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
shutdownAudio();
this.callState = CallState.STATE_IDLE;
this.recipient = null;
this.callId = null;
this.audioEnabled = true;
this.videoEnabled = false;
this.pendingIceUpdates = null;
this.callState = CallState.STATE_IDLE;
this.recipient = null;
this.callId = null;
this.audioEnabled = true;
this.localVideoEnabled = false;
this.remoteVideoEnabled = false;
this.pendingIceUpdates = null;
lockManager.updatePhoneState(LockManager.PhoneState.IDLE);
}
private void sendMessage(@NonNull WebRtcCallEvent.Type type,
private void sendMessage(@NonNull WebRtcViewModel.State state,
@NonNull Recipient recipient,
@Nullable Object extra)
boolean localVideoEnabled, boolean remoteVideoEnabled)
{
EventBus.getDefault().postSticky(new WebRtcCallEvent(type, recipient, extra));
EventBus.getDefault().postSticky(new WebRtcViewModel(state, recipient, localVideoEnabled, remoteVideoEnabled));
}
private void sendMessage(@NonNull WebRtcViewModel.State state,
@NonNull Recipient recipient,
@NonNull IdentityKey identityKey,
boolean localVideoEnabled, boolean remoteVideoEnabled)
{
EventBus.getDefault().postSticky(new WebRtcViewModel(state, recipient, identityKey, localVideoEnabled, remoteVideoEnabled));
}
private ListenableFutureTask<Boolean> sendMessage(@NonNull final Recipient recipient,
@@ -952,6 +965,19 @@ public class WebRtcCallService extends Service implements InjectableType, CallSt
return futureTask;
}
private WebRtcViewModel.State viewModelStateFor(CallState state) {
switch (state) {
case STATE_CONNECTED: return WebRtcViewModel.State.CALL_CONNECTED;
case STATE_DIALING: return WebRtcViewModel.State.CALL_OUTGOING;
case STATE_REMOTE_RINGING: return WebRtcViewModel.State.CALL_RINGING;
case STATE_LOCAL_RINGING: return WebRtcViewModel.State.CALL_INCOMING;
case STATE_ANSWERING: return WebRtcViewModel.State.CALL_INCOMING;
case STATE_IDLE: return WebRtcViewModel.State.CALL_DISCONNECTED;
}
return WebRtcViewModel.State.CALL_DISCONNECTED;
}
private class TimeoutRunnable implements Runnable {
private final long callId;