From c5114e2cb3f6760faa70d851266fbe7fab25ba36 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 29 Jan 2019 14:25:49 -0800 Subject: [PATCH] Updated to WebRTC M71. --- build.gradle | 4 +- .../securesms/ApplicationContext.java | 4 +- .../securesms/WebRtcCallActivity.java | 2 +- .../components/webrtc/WebRtcCallScreen.java | 4 +- .../securesms/events/WebRtcViewModel.java | 46 +++++++++++++------ .../securesms/service/WebRtcCallService.java | 46 +++++++++++-------- .../webrtc/PeerConnectionWrapper.java | 7 ++- 7 files changed, 71 insertions(+), 42 deletions(-) diff --git a/build.gradle b/build.gradle index 61df2e7c3e..ec173a86dd 100644 --- a/build.gradle +++ b/build.gradle @@ -90,7 +90,7 @@ dependencies { compile 'com.google.android.exoplayer:exoplayer-ui:2.9.1' compile 'org.whispersystems:signal-service-android:2.12.7' - compile 'org.whispersystems:webrtc-android:M69' + compile 'org.whispersystems:webrtc-android:M71' compile "me.leolin:ShortcutBadger:1.1.16" compile 'se.emilsjolander:stickylistheaders:2.7.0' @@ -188,7 +188,7 @@ dependencyVerification { 'com.google.android.exoplayer:exoplayer-ui:7a942afcc402ff01e9bf48e8d3942850986710f06562d50a1408aaf04a683151', 'com.google.android.exoplayer:exoplayer-core:b6ab34abac36bc2bc6934b7a50008162feca2c0fde91aaf1e8c1c22f2c16e2c0', 'org.whispersystems:signal-service-android:0afd2cb17ed920611dacc54385f3ed375847c10ecd7839a025d9c61c387f7678', - 'org.whispersystems:webrtc-android:5493c92141ce884fc5ce8240d783232f4fe14bd17a8d0d7d1bd4944d0bd1682f', + 'org.whispersystems:webrtc-android:0620880760976d78ef429dc8b383136981b9a72178e5d70f5affa681deffed69', 'me.leolin:ShortcutBadger:e3cb3e7625892129b0c92dd5e4bc649faffdd526d5af26d9c45ee31ff8851774', 'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb', 'com.jpardogo.materialtabstrip:library:c6ef812fba4f74be7dc4a905faa4c2908cba261a94c13d4f96d5e67e4aad4aaa', diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 1f0580ec9e..7722b646f8 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -267,9 +267,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc WebRtcAudioManager.setBlacklistDeviceForOpenSLESUsage(true); } - PeerConnectionFactory.initialize(InitializationOptions.builder(this) - .setEnableVideoHwAcceleration(true) - .createInitializationOptions()); + PeerConnectionFactory.initialize(InitializationOptions.builder(this).createInitializationOptions()); } catch (UnsatisfiedLinkError e) { Log.w(TAG, e); } diff --git a/src/org/thoughtcrime/securesms/WebRtcCallActivity.java b/src/org/thoughtcrime/securesms/WebRtcCallActivity.java index ef44371e1f..ffc6348e42 100644 --- a/src/org/thoughtcrime/securesms/WebRtcCallActivity.java +++ b/src/org/thoughtcrime/securesms/WebRtcCallActivity.java @@ -232,7 +232,7 @@ public class WebRtcCallActivity extends Activity { private void handleCallConnected(@NonNull WebRtcViewModel event) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES); - callScreen.setActiveCall(event.getRecipient(), getString(R.string.RedPhone_connected), ""); + callScreen.setActiveCall(event.getRecipient(), getString(R.string.RedPhone_connected), "", event.getLocalRenderer(), event.getRemoteRenderer()); } private void handleRecipientUnavailable(@NonNull WebRtcViewModel event) { diff --git a/src/org/thoughtcrime/securesms/components/webrtc/WebRtcCallScreen.java b/src/org/thoughtcrime/securesms/components/webrtc/WebRtcCallScreen.java index 7db63b4a8e..a605aa9c08 100644 --- a/src/org/thoughtcrime/securesms/components/webrtc/WebRtcCallScreen.java +++ b/src/org/thoughtcrime/securesms/components/webrtc/WebRtcCallScreen.java @@ -101,9 +101,9 @@ public class WebRtcCallScreen extends FrameLayout implements RecipientModifiedLi initialize(); } - public void setActiveCall(@NonNull Recipient personInfo, @NonNull String message, @Nullable String sas) { + public void setActiveCall(@NonNull Recipient personInfo, @NonNull String message, @Nullable String sas, SurfaceViewRenderer localRenderer, SurfaceViewRenderer remoteRenderer) { setCard(personInfo, message); - setConnected(WebRtcCallService.localRenderer, WebRtcCallService.remoteRenderer); + setConnected(localRenderer, remoteRenderer); incomingCallButton.stopRingingAnimation(); incomingCallButton.setVisibility(View.GONE); endCallButton.show(); diff --git a/src/org/thoughtcrime/securesms/events/WebRtcViewModel.java b/src/org/thoughtcrime/securesms/events/WebRtcViewModel.java index aeeb78c749..20149cf08d 100644 --- a/src/org/thoughtcrime/securesms/events/WebRtcViewModel.java +++ b/src/org/thoughtcrime/securesms/events/WebRtcViewModel.java @@ -5,6 +5,7 @@ import android.support.annotation.Nullable; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.webrtc.CameraState; +import org.webrtc.SurfaceViewRenderer; import org.whispersystems.libsignal.IdentityKey; public class WebRtcViewModel { @@ -35,35 +36,45 @@ public class WebRtcViewModel { private final boolean isBluetoothAvailable; private final boolean isMicrophoneEnabled; - private final CameraState localCameraState; + private final CameraState localCameraState; + private final SurfaceViewRenderer localRenderer; + private final SurfaceViewRenderer remoteRenderer; - public WebRtcViewModel(@NonNull State state, - @NonNull Recipient recipient, - @NonNull CameraState localCameraState, - boolean remoteVideoEnabled, - boolean isBluetoothAvailable, - boolean isMicrophoneEnabled) + public WebRtcViewModel(@NonNull State state, + @NonNull Recipient recipient, + @NonNull CameraState localCameraState, + @NonNull SurfaceViewRenderer localRenderer, + @NonNull SurfaceViewRenderer remoteRenderer, + boolean remoteVideoEnabled, + boolean isBluetoothAvailable, + boolean isMicrophoneEnabled) { this(state, recipient, null, localCameraState, + localRenderer, + remoteRenderer, remoteVideoEnabled, isBluetoothAvailable, isMicrophoneEnabled); } - public WebRtcViewModel(@NonNull State state, - @NonNull Recipient recipient, - @Nullable IdentityKey identityKey, - @NonNull CameraState localCameraState, - boolean remoteVideoEnabled, - boolean isBluetoothAvailable, - boolean isMicrophoneEnabled) + public WebRtcViewModel(@NonNull State state, + @NonNull Recipient recipient, + @Nullable IdentityKey identityKey, + @NonNull CameraState localCameraState, + @NonNull SurfaceViewRenderer localRenderer, + @NonNull SurfaceViewRenderer remoteRenderer, + boolean remoteVideoEnabled, + boolean isBluetoothAvailable, + boolean isMicrophoneEnabled) { this.state = state; this.recipient = recipient; this.localCameraState = localCameraState; + this.localRenderer = localRenderer; + this.remoteRenderer = remoteRenderer; this.identityKey = identityKey; this.remoteVideoEnabled = remoteVideoEnabled; this.isBluetoothAvailable = isBluetoothAvailable; @@ -98,6 +109,13 @@ public class WebRtcViewModel { return isMicrophoneEnabled; } + public SurfaceViewRenderer getLocalRenderer() { + return localRenderer; + } + + public SurfaceViewRenderer getRemoteRenderer() { + return remoteRenderer; + } public String toString() { return "[State: " + state + ", recipient: " + recipient.getAddress() + ", identity: " + identityKey + ", remoteVideo: " + remoteVideoEnabled + ", localVideo: " + localCameraState.isEnabled() + "]"; diff --git a/src/org/thoughtcrime/securesms/service/WebRtcCallService.java b/src/org/thoughtcrime/securesms/service/WebRtcCallService.java index 7b9b7894c0..0459dc3a67 100644 --- a/src/org/thoughtcrime/securesms/service/WebRtcCallService.java +++ b/src/org/thoughtcrime/securesms/service/WebRtcCallService.java @@ -59,6 +59,8 @@ import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager; import org.thoughtcrime.securesms.webrtc.locks.LockManager; import org.webrtc.AudioTrack; import org.webrtc.DataChannel; +import org.webrtc.DefaultVideoDecoderFactory; +import org.webrtc.DefaultVideoEncoderFactory; import org.webrtc.EglBase; import org.webrtc.IceCandidate; import org.webrtc.MediaConstraints; @@ -68,6 +70,8 @@ import org.webrtc.PeerConnectionFactory; import org.webrtc.RtpReceiver; import org.webrtc.SessionDescription; import org.webrtc.SurfaceViewRenderer; +import org.webrtc.VideoDecoderFactory; +import org.webrtc.VideoEncoderFactory; import org.webrtc.VideoTrack; import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.signalservice.api.SignalServiceAccountManager; @@ -91,6 +95,7 @@ import java.security.SecureRandom; import java.util.LinkedList; import java.util.List; import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -179,9 +184,9 @@ public class WebRtcCallService extends Service implements InjectableType, @Nullable private List pendingOutgoingIceUpdates; @Nullable private List pendingIncomingIceUpdates; - @Nullable public static SurfaceViewRenderer localRenderer; - @Nullable public static SurfaceViewRenderer remoteRenderer; - @Nullable private static EglBase eglBase; + @Nullable private SurfaceViewRenderer localRenderer; + @Nullable private SurfaceViewRenderer remoteRenderer; + @Nullable private EglBase eglBase; private ExecutorService serviceExecutor = Executors.newSingleThreadExecutor(); private ExecutorService networkExecutor = Executors.newSingleThreadExecutor(); @@ -285,9 +290,9 @@ public class WebRtcCallService extends Service implements InjectableType, this.callState = CallState.STATE_IDLE; this.lockManager = new LockManager(this); - this.peerConnectionFactory = PeerConnectionFactory.builder().setOptions(new PeerConnectionFactoryOptions()).createPeerConnectionFactory(); this.audioManager = new SignalAudioManager(this); this.bluetoothStateManager = new BluetoothStateManager(this, this); + this.messageSender.setSoTimeoutMillis(TimeUnit.SECONDS.toMillis(10)); this.accountManager.setSoTimeoutMillis(TimeUnit.SECONDS.toMillis(10)); } @@ -371,7 +376,7 @@ public class WebRtcCallService extends Service implements InjectableType, boolean isAlwaysTurn = TextSecurePreferences.isTurnOnly(WebRtcCallService.this); - WebRtcCallService.this.peerConnection = new PeerConnectionWrapper(WebRtcCallService.this, peerConnectionFactory, WebRtcCallService.this, localRenderer, result, WebRtcCallService.this, !isSystemContact || isAlwaysTurn); + WebRtcCallService.this.peerConnection = new PeerConnectionWrapper(WebRtcCallService.this, peerConnectionFactory, WebRtcCallService.this, localRenderer, result, WebRtcCallService.this, eglBase, !isSystemContact || isAlwaysTurn); WebRtcCallService.this.localCameraState = WebRtcCallService.this.peerConnection.getCameraState(); WebRtcCallService.this.peerConnection.setRemoteDescription(new SessionDescription(SessionDescription.Type.OFFER, offer)); WebRtcCallService.this.lockManager.updatePhoneState(LockManager.PhoneState.PROCESSING); @@ -435,7 +440,7 @@ public class WebRtcCallService extends Service implements InjectableType, try { boolean isAlwaysTurn = TextSecurePreferences.isTurnOnly(WebRtcCallService.this); - WebRtcCallService.this.peerConnection = new PeerConnectionWrapper(WebRtcCallService.this, peerConnectionFactory, WebRtcCallService.this, localRenderer, result, WebRtcCallService.this, isAlwaysTurn); + WebRtcCallService.this.peerConnection = new PeerConnectionWrapper(WebRtcCallService.this, peerConnectionFactory, WebRtcCallService.this, localRenderer, result, WebRtcCallService.this, eglBase, isAlwaysTurn); WebRtcCallService.this.localCameraState = WebRtcCallService.this.peerConnection.getCameraState(); WebRtcCallService.this.dataChannel = WebRtcCallService.this.peerConnection.createDataChannel(DATA_CHANNEL_NAME); WebRtcCallService.this.dataChannel.registerObserver(WebRtcCallService.this); @@ -911,19 +916,22 @@ public class WebRtcCallService extends Service implements InjectableType, } private void initializeVideo() { - Util.runOnMainSync(new Runnable() { - @Override - public void run() { - eglBase = EglBase.create(); - localRenderer = new SurfaceViewRenderer(WebRtcCallService.this); - remoteRenderer = new SurfaceViewRenderer(WebRtcCallService.this); + Util.runOnMainSync(() -> { + eglBase = EglBase.create(); + localRenderer = new SurfaceViewRenderer(WebRtcCallService.this); + remoteRenderer = new SurfaceViewRenderer(WebRtcCallService.this); - localRenderer.init(eglBase.getEglBaseContext(), null); - remoteRenderer.init(eglBase.getEglBaseContext(), null); + localRenderer.init(eglBase.getEglBaseContext(), null); + remoteRenderer.init(eglBase.getEglBaseContext(), null); - peerConnectionFactory.setVideoHwAccelerationOptions(eglBase.getEglBaseContext(), - eglBase.getEglBaseContext()); - } + VideoEncoderFactory encoderFactory = new DefaultVideoEncoderFactory(eglBase.getEglBaseContext(), true, true); + VideoDecoderFactory decoderFactory = new DefaultVideoDecoderFactory(eglBase.getEglBaseContext()); + + peerConnectionFactory = PeerConnectionFactory.builder() + .setOptions(new PeerConnectionFactoryOptions()) + .setVideoEncoderFactory(encoderFactory) + .setVideoDecoderFactory(decoderFactory) + .createPeerConnectionFactory(); }); } @@ -973,7 +981,7 @@ public class WebRtcCallService extends Service implements InjectableType, boolean bluetoothAvailable, boolean microphoneEnabled) { - EventBus.getDefault().postSticky(new WebRtcViewModel(state, recipient, localCameraState, remoteVideoEnabled, bluetoothAvailable, microphoneEnabled)); + EventBus.getDefault().postSticky(new WebRtcViewModel(state, recipient, localCameraState, localRenderer, remoteRenderer, remoteVideoEnabled, bluetoothAvailable, microphoneEnabled)); } private void sendMessage(@NonNull WebRtcViewModel.State state, @@ -984,7 +992,7 @@ public class WebRtcCallService extends Service implements InjectableType, boolean bluetoothAvailable, boolean microphoneEnabled) { - EventBus.getDefault().postSticky(new WebRtcViewModel(state, recipient, identityKey, localCameraState, remoteVideoEnabled, bluetoothAvailable, microphoneEnabled)); + EventBus.getDefault().postSticky(new WebRtcViewModel(state, recipient, identityKey, localCameraState, localRenderer, remoteRenderer, remoteVideoEnabled, bluetoothAvailable, microphoneEnabled)); } private ListenableFutureTask sendMessage(@NonNull final Recipient recipient, diff --git a/src/org/thoughtcrime/securesms/webrtc/PeerConnectionWrapper.java b/src/org/thoughtcrime/securesms/webrtc/PeerConnectionWrapper.java index 427e6eaf2e..a4bb08dc48 100644 --- a/src/org/thoughtcrime/securesms/webrtc/PeerConnectionWrapper.java +++ b/src/org/thoughtcrime/securesms/webrtc/PeerConnectionWrapper.java @@ -14,6 +14,7 @@ import org.webrtc.Camera2Enumerator; import org.webrtc.CameraEnumerator; import org.webrtc.CameraVideoCapturer; import org.webrtc.DataChannel; +import org.webrtc.EglBase; import org.webrtc.IceCandidate; import org.webrtc.MediaConstraints; import org.webrtc.MediaStream; @@ -21,6 +22,7 @@ import org.webrtc.PeerConnection; import org.webrtc.PeerConnectionFactory; import org.webrtc.SdpObserver; import org.webrtc.SessionDescription; +import org.webrtc.SurfaceTextureHelper; import org.webrtc.VideoSink; import org.webrtc.VideoSource; import org.webrtc.VideoTrack; @@ -52,6 +54,7 @@ public class PeerConnectionWrapper { @NonNull VideoSink localRenderer, @NonNull List turnServers, @NonNull CameraEventListener cameraEventListener, + @NonNull EglBase eglBase, boolean hideIp) { List iceServers = new LinkedList<>(); @@ -85,9 +88,11 @@ public class PeerConnectionWrapper { this.camera = new Camera(context, cameraEventListener); if (camera.capturer != null) { - this.videoSource = factory.createVideoSource(camera.capturer); + this.videoSource = factory.createVideoSource(false); this.videoTrack = factory.createVideoTrack("ARDAMSv0", videoSource); + camera.capturer.initialize(SurfaceTextureHelper.create("WebRTC-SurfaceTextureHelper", eglBase.getEglBaseContext()), context, videoSource.getCapturerObserver()); + this.videoTrack.addSink(localRenderer); this.videoTrack.setEnabled(false); mediaStream.addTrack(videoTrack);