Updated to WebRTC M71.

This commit is contained in:
Greyson Parrelli 2019-01-29 14:25:49 -08:00
parent e3b22dabce
commit c5114e2cb3
7 changed files with 71 additions and 42 deletions

View File

@ -90,7 +90,7 @@ dependencies {
compile 'com.google.android.exoplayer:exoplayer-ui:2.9.1' compile 'com.google.android.exoplayer:exoplayer-ui:2.9.1'
compile 'org.whispersystems:signal-service-android:2.12.7' 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 "me.leolin:ShortcutBadger:1.1.16"
compile 'se.emilsjolander:stickylistheaders:2.7.0' compile 'se.emilsjolander:stickylistheaders:2.7.0'
@ -188,7 +188,7 @@ dependencyVerification {
'com.google.android.exoplayer:exoplayer-ui:7a942afcc402ff01e9bf48e8d3942850986710f06562d50a1408aaf04a683151', 'com.google.android.exoplayer:exoplayer-ui:7a942afcc402ff01e9bf48e8d3942850986710f06562d50a1408aaf04a683151',
'com.google.android.exoplayer:exoplayer-core:b6ab34abac36bc2bc6934b7a50008162feca2c0fde91aaf1e8c1c22f2c16e2c0', 'com.google.android.exoplayer:exoplayer-core:b6ab34abac36bc2bc6934b7a50008162feca2c0fde91aaf1e8c1c22f2c16e2c0',
'org.whispersystems:signal-service-android:0afd2cb17ed920611dacc54385f3ed375847c10ecd7839a025d9c61c387f7678', 'org.whispersystems:signal-service-android:0afd2cb17ed920611dacc54385f3ed375847c10ecd7839a025d9c61c387f7678',
'org.whispersystems:webrtc-android:5493c92141ce884fc5ce8240d783232f4fe14bd17a8d0d7d1bd4944d0bd1682f', 'org.whispersystems:webrtc-android:0620880760976d78ef429dc8b383136981b9a72178e5d70f5affa681deffed69',
'me.leolin:ShortcutBadger:e3cb3e7625892129b0c92dd5e4bc649faffdd526d5af26d9c45ee31ff8851774', 'me.leolin:ShortcutBadger:e3cb3e7625892129b0c92dd5e4bc649faffdd526d5af26d9c45ee31ff8851774',
'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb', 'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb',
'com.jpardogo.materialtabstrip:library:c6ef812fba4f74be7dc4a905faa4c2908cba261a94c13d4f96d5e67e4aad4aaa', 'com.jpardogo.materialtabstrip:library:c6ef812fba4f74be7dc4a905faa4c2908cba261a94c13d4f96d5e67e4aad4aaa',

View File

@ -267,9 +267,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
WebRtcAudioManager.setBlacklistDeviceForOpenSLESUsage(true); WebRtcAudioManager.setBlacklistDeviceForOpenSLESUsage(true);
} }
PeerConnectionFactory.initialize(InitializationOptions.builder(this) PeerConnectionFactory.initialize(InitializationOptions.builder(this).createInitializationOptions());
.setEnableVideoHwAcceleration(true)
.createInitializationOptions());
} catch (UnsatisfiedLinkError e) { } catch (UnsatisfiedLinkError e) {
Log.w(TAG, e); Log.w(TAG, e);
} }

View File

@ -232,7 +232,7 @@ public class WebRtcCallActivity extends Activity {
private void handleCallConnected(@NonNull WebRtcViewModel event) { private void handleCallConnected(@NonNull WebRtcViewModel event) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES); 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) { private void handleRecipientUnavailable(@NonNull WebRtcViewModel event) {

View File

@ -101,9 +101,9 @@ public class WebRtcCallScreen extends FrameLayout implements RecipientModifiedLi
initialize(); 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); setCard(personInfo, message);
setConnected(WebRtcCallService.localRenderer, WebRtcCallService.remoteRenderer); setConnected(localRenderer, remoteRenderer);
incomingCallButton.stopRingingAnimation(); incomingCallButton.stopRingingAnimation();
incomingCallButton.setVisibility(View.GONE); incomingCallButton.setVisibility(View.GONE);
endCallButton.show(); endCallButton.show();

View File

@ -5,6 +5,7 @@ import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.webrtc.CameraState; import org.thoughtcrime.securesms.webrtc.CameraState;
import org.webrtc.SurfaceViewRenderer;
import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKey;
public class WebRtcViewModel { public class WebRtcViewModel {
@ -35,35 +36,45 @@ public class WebRtcViewModel {
private final boolean isBluetoothAvailable; private final boolean isBluetoothAvailable;
private final boolean isMicrophoneEnabled; 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, public WebRtcViewModel(@NonNull State state,
@NonNull Recipient recipient, @NonNull Recipient recipient,
@NonNull CameraState localCameraState, @NonNull CameraState localCameraState,
boolean remoteVideoEnabled, @NonNull SurfaceViewRenderer localRenderer,
boolean isBluetoothAvailable, @NonNull SurfaceViewRenderer remoteRenderer,
boolean isMicrophoneEnabled) boolean remoteVideoEnabled,
boolean isBluetoothAvailable,
boolean isMicrophoneEnabled)
{ {
this(state, this(state,
recipient, recipient,
null, null,
localCameraState, localCameraState,
localRenderer,
remoteRenderer,
remoteVideoEnabled, remoteVideoEnabled,
isBluetoothAvailable, isBluetoothAvailable,
isMicrophoneEnabled); isMicrophoneEnabled);
} }
public WebRtcViewModel(@NonNull State state, public WebRtcViewModel(@NonNull State state,
@NonNull Recipient recipient, @NonNull Recipient recipient,
@Nullable IdentityKey identityKey, @Nullable IdentityKey identityKey,
@NonNull CameraState localCameraState, @NonNull CameraState localCameraState,
boolean remoteVideoEnabled, @NonNull SurfaceViewRenderer localRenderer,
boolean isBluetoothAvailable, @NonNull SurfaceViewRenderer remoteRenderer,
boolean isMicrophoneEnabled) boolean remoteVideoEnabled,
boolean isBluetoothAvailable,
boolean isMicrophoneEnabled)
{ {
this.state = state; this.state = state;
this.recipient = recipient; this.recipient = recipient;
this.localCameraState = localCameraState; this.localCameraState = localCameraState;
this.localRenderer = localRenderer;
this.remoteRenderer = remoteRenderer;
this.identityKey = identityKey; this.identityKey = identityKey;
this.remoteVideoEnabled = remoteVideoEnabled; this.remoteVideoEnabled = remoteVideoEnabled;
this.isBluetoothAvailable = isBluetoothAvailable; this.isBluetoothAvailable = isBluetoothAvailable;
@ -98,6 +109,13 @@ public class WebRtcViewModel {
return isMicrophoneEnabled; return isMicrophoneEnabled;
} }
public SurfaceViewRenderer getLocalRenderer() {
return localRenderer;
}
public SurfaceViewRenderer getRemoteRenderer() {
return remoteRenderer;
}
public String toString() { public String toString() {
return "[State: " + state + ", recipient: " + recipient.getAddress() + ", identity: " + identityKey + ", remoteVideo: " + remoteVideoEnabled + ", localVideo: " + localCameraState.isEnabled() + "]"; return "[State: " + state + ", recipient: " + recipient.getAddress() + ", identity: " + identityKey + ", remoteVideo: " + remoteVideoEnabled + ", localVideo: " + localCameraState.isEnabled() + "]";

View File

@ -59,6 +59,8 @@ import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager;
import org.thoughtcrime.securesms.webrtc.locks.LockManager; import org.thoughtcrime.securesms.webrtc.locks.LockManager;
import org.webrtc.AudioTrack; import org.webrtc.AudioTrack;
import org.webrtc.DataChannel; import org.webrtc.DataChannel;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
import org.webrtc.EglBase; import org.webrtc.EglBase;
import org.webrtc.IceCandidate; import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints; import org.webrtc.MediaConstraints;
@ -68,6 +70,8 @@ import org.webrtc.PeerConnectionFactory;
import org.webrtc.RtpReceiver; import org.webrtc.RtpReceiver;
import org.webrtc.SessionDescription; import org.webrtc.SessionDescription;
import org.webrtc.SurfaceViewRenderer; import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoDecoderFactory;
import org.webrtc.VideoEncoderFactory;
import org.webrtc.VideoTrack; import org.webrtc.VideoTrack;
import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceAccountManager;
@ -91,6 +95,7 @@ import java.security.SecureRandom;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -179,9 +184,9 @@ public class WebRtcCallService extends Service implements InjectableType,
@Nullable private List<IceUpdateMessage> pendingOutgoingIceUpdates; @Nullable private List<IceUpdateMessage> pendingOutgoingIceUpdates;
@Nullable private List<IceCandidate> pendingIncomingIceUpdates; @Nullable private List<IceCandidate> pendingIncomingIceUpdates;
@Nullable public static SurfaceViewRenderer localRenderer; @Nullable private SurfaceViewRenderer localRenderer;
@Nullable public static SurfaceViewRenderer remoteRenderer; @Nullable private SurfaceViewRenderer remoteRenderer;
@Nullable private static EglBase eglBase; @Nullable private EglBase eglBase;
private ExecutorService serviceExecutor = Executors.newSingleThreadExecutor(); private ExecutorService serviceExecutor = Executors.newSingleThreadExecutor();
private ExecutorService networkExecutor = Executors.newSingleThreadExecutor(); private ExecutorService networkExecutor = Executors.newSingleThreadExecutor();
@ -285,9 +290,9 @@ public class WebRtcCallService extends Service implements InjectableType,
this.callState = CallState.STATE_IDLE; this.callState = CallState.STATE_IDLE;
this.lockManager = new LockManager(this); this.lockManager = new LockManager(this);
this.peerConnectionFactory = PeerConnectionFactory.builder().setOptions(new PeerConnectionFactoryOptions()).createPeerConnectionFactory();
this.audioManager = new SignalAudioManager(this); this.audioManager = new SignalAudioManager(this);
this.bluetoothStateManager = new BluetoothStateManager(this, this); this.bluetoothStateManager = new BluetoothStateManager(this, this);
this.messageSender.setSoTimeoutMillis(TimeUnit.SECONDS.toMillis(10)); this.messageSender.setSoTimeoutMillis(TimeUnit.SECONDS.toMillis(10));
this.accountManager.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); 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.localCameraState = WebRtcCallService.this.peerConnection.getCameraState();
WebRtcCallService.this.peerConnection.setRemoteDescription(new SessionDescription(SessionDescription.Type.OFFER, offer)); WebRtcCallService.this.peerConnection.setRemoteDescription(new SessionDescription(SessionDescription.Type.OFFER, offer));
WebRtcCallService.this.lockManager.updatePhoneState(LockManager.PhoneState.PROCESSING); WebRtcCallService.this.lockManager.updatePhoneState(LockManager.PhoneState.PROCESSING);
@ -435,7 +440,7 @@ public class WebRtcCallService extends Service implements InjectableType,
try { try {
boolean isAlwaysTurn = TextSecurePreferences.isTurnOnly(WebRtcCallService.this); 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.localCameraState = WebRtcCallService.this.peerConnection.getCameraState();
WebRtcCallService.this.dataChannel = WebRtcCallService.this.peerConnection.createDataChannel(DATA_CHANNEL_NAME); WebRtcCallService.this.dataChannel = WebRtcCallService.this.peerConnection.createDataChannel(DATA_CHANNEL_NAME);
WebRtcCallService.this.dataChannel.registerObserver(WebRtcCallService.this); WebRtcCallService.this.dataChannel.registerObserver(WebRtcCallService.this);
@ -911,19 +916,22 @@ public class WebRtcCallService extends Service implements InjectableType,
} }
private void initializeVideo() { private void initializeVideo() {
Util.runOnMainSync(new Runnable() { Util.runOnMainSync(() -> {
@Override eglBase = EglBase.create();
public void run() { localRenderer = new SurfaceViewRenderer(WebRtcCallService.this);
eglBase = EglBase.create(); remoteRenderer = new SurfaceViewRenderer(WebRtcCallService.this);
localRenderer = new SurfaceViewRenderer(WebRtcCallService.this);
remoteRenderer = new SurfaceViewRenderer(WebRtcCallService.this);
localRenderer.init(eglBase.getEglBaseContext(), null); localRenderer.init(eglBase.getEglBaseContext(), null);
remoteRenderer.init(eglBase.getEglBaseContext(), null); remoteRenderer.init(eglBase.getEglBaseContext(), null);
peerConnectionFactory.setVideoHwAccelerationOptions(eglBase.getEglBaseContext(), VideoEncoderFactory encoderFactory = new DefaultVideoEncoderFactory(eglBase.getEglBaseContext(), true, true);
eglBase.getEglBaseContext()); 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 bluetoothAvailable,
boolean microphoneEnabled) 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, private void sendMessage(@NonNull WebRtcViewModel.State state,
@ -984,7 +992,7 @@ public class WebRtcCallService extends Service implements InjectableType,
boolean bluetoothAvailable, boolean bluetoothAvailable,
boolean microphoneEnabled) 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<Boolean> sendMessage(@NonNull final Recipient recipient, private ListenableFutureTask<Boolean> sendMessage(@NonNull final Recipient recipient,

View File

@ -14,6 +14,7 @@ import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraEnumerator; import org.webrtc.CameraEnumerator;
import org.webrtc.CameraVideoCapturer; import org.webrtc.CameraVideoCapturer;
import org.webrtc.DataChannel; import org.webrtc.DataChannel;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate; import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints; import org.webrtc.MediaConstraints;
import org.webrtc.MediaStream; import org.webrtc.MediaStream;
@ -21,6 +22,7 @@ import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory; import org.webrtc.PeerConnectionFactory;
import org.webrtc.SdpObserver; import org.webrtc.SdpObserver;
import org.webrtc.SessionDescription; import org.webrtc.SessionDescription;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.VideoSink; import org.webrtc.VideoSink;
import org.webrtc.VideoSource; import org.webrtc.VideoSource;
import org.webrtc.VideoTrack; import org.webrtc.VideoTrack;
@ -52,6 +54,7 @@ public class PeerConnectionWrapper {
@NonNull VideoSink localRenderer, @NonNull VideoSink localRenderer,
@NonNull List<PeerConnection.IceServer> turnServers, @NonNull List<PeerConnection.IceServer> turnServers,
@NonNull CameraEventListener cameraEventListener, @NonNull CameraEventListener cameraEventListener,
@NonNull EglBase eglBase,
boolean hideIp) boolean hideIp)
{ {
List<PeerConnection.IceServer> iceServers = new LinkedList<>(); List<PeerConnection.IceServer> iceServers = new LinkedList<>();
@ -85,9 +88,11 @@ public class PeerConnectionWrapper {
this.camera = new Camera(context, cameraEventListener); this.camera = new Camera(context, cameraEventListener);
if (camera.capturer != null) { if (camera.capturer != null) {
this.videoSource = factory.createVideoSource(camera.capturer); this.videoSource = factory.createVideoSource(false);
this.videoTrack = factory.createVideoTrack("ARDAMSv0", videoSource); this.videoTrack = factory.createVideoTrack("ARDAMSv0", videoSource);
camera.capturer.initialize(SurfaceTextureHelper.create("WebRTC-SurfaceTextureHelper", eglBase.getEglBaseContext()), context, videoSource.getCapturerObserver());
this.videoTrack.addSink(localRenderer); this.videoTrack.addSink(localRenderer);
this.videoTrack.setEnabled(false); this.videoTrack.setEnabled(false);
mediaStream.addTrack(videoTrack); mediaStream.addTrack(videoTrack);